Modify the below code to provide only single word meanings or synonyms seperated by semicolons if no matches are found in the four words below:

// content.js

// Cache to store fetched data and prevent redundant API calls
const dataCache = {};

// Variable to keep track of the currently hovered word
let currentWord = null;

// Variable to keep the tooltip element
let tooltip = null;

// Listen for mouseover events
document.addEventListener('mouseover', handleMouseOver);

// Listen for mouseout events to remove tooltip
document.addEventListener('mouseout', handleMouseOut);

// Function to handle mouseover events
function handleMouseOver(event) {
  const result = getWordUnderCursor(event);
  if (!result) return;

  const word = result.word;
  const range = result.range;

  // If there's a word and it's different from the current word
  if (word && word !== currentWord) {
    currentWord = word;

    // Get the next four words
    const nextWords = getNextWords(range, 4);

    // Check if data is already cached
    if (dataCache[word]) {
      processSimilarWordsData(event.pageX, event.pageY, word, nextWords, dataCache[word]);
    } else {
      // Fetch similar words for the hovered word
      fetchSimilarWords(word)
        .then(similarWordsData => {
          dataCache[word] = similarWordsData; // Cache the data
          processSimilarWordsData(event.pageX, event.pageY, word, nextWords, similarWordsData);
        })
        .catch(error => {
          console.error('Error:', error);
        });
    }
  }
}

// Function to process similar words data
function processSimilarWordsData(x, y, word, nextWords, similarWordsData) {
  const similarWords = similarWordsData.map(obj => obj.word.toLowerCase());

  // For each of the four words, check if it appears in the similar words list
  let closestWord = null;
  let highestScore = -Infinity;

  nextWords.forEach(nextWord => {
    const index = similarWords.indexOf(nextWord.toLowerCase());
    if (index !== -1) {
      // Get the score from similarWordsData
      const score = similarWordsData[index].score;
      if (score > highestScore) {
        highestScore = score;
        closestWord = nextWord;
      }
    }
  });

  if (closestWord) {
    showTooltip(x, y, `Closest word: ${closestWord}`);
  } else {
    // Fetch synonyms or definitions for the hovered word
    fetchDefinitions(word)
      .then(definitions => {
        let content = '';
        if (definitions.length > 0) {
          content = `Synonyms or Meanings of "${word}":\n- ${definitions.join('\n- ')}`;
        } else {
          content = `No synonyms or meanings found for "${word}".`;
        }
        showTooltip(x, y, content);
      })
      .catch(error => {
        console.error('Error fetching definitions:', error);
        showTooltip(x, y, `No similar words found among the next four words.\nNo definitions found for "${word}".`);
      });
  }
}

// Function to handle mouseout events
function handleMouseOut(event) {
  const relatedTarget = event.relatedTarget;

  // If moving to a child element, do not remove tooltip
  if (tooltip && (!relatedTarget || !tooltip.contains(relatedTarget))) {
    removeExistingTooltip();
    currentWord = null;
  }
}

// Modified function to get the word under the cursor along with its range
function getWordUnderCursor(event) {
  let range;
  if (document.caretRangeFromPoint) {
    range = document.caretRangeFromPoint(event.clientX, event.clientY);
  } else if (document.caretPositionFromPoint) {
    const pos = document.caretPositionFromPoint(event.clientX, event.clientY);
    range = document.createRange();
    range.setStart(pos.offsetNode, pos.offset);
    range.setEnd(pos.offsetNode, pos.offset);
  } else {
    return null;
  }

  if (!range) return null;

  const node = range.startContainer;

  if (node.nodeType !== Node.TEXT_NODE) return null;

  const text = node.textContent;
  const offset = range.startOffset;

  // Use regex to find word boundaries
  const left = text.slice(0, offset).search(/\S+$/);
  const right = text.slice(offset).search(/\s/);

  const start = left === -1 ? 0 : left;
  const end = right === -1 ? text.length : offset + right;

  const word = text.slice(start, end).trim();

  // Validate that it's a single word (no spaces)
  if (word && !/\s/.test(word)) {
    range.setStart(node, start);
    range.setEnd(node, end);
    return { word: word, range: range };
  }

  return null;
}

// Function to get the next words after a given Range
function getNextWords(range, count) {
  const words = [];
  let currentNode = range.endContainer;
  let offset = range.endOffset;

  while (words.length < count) {
    if (currentNode.nodeType === Node.TEXT_NODE) {
      const text = currentNode.textContent.slice(offset);
      const regex = /\b(\w+)\b/g;
      let match;

      while ((match = regex.exec(text)) !== null) {
        words.push(match[1]);
        if (words.length === count) break;
      }
      // Reset offset after the first text node
      offset = 0;
    }

    // Move to next node
    currentNode = getNextNode(currentNode);
    if (!currentNode) break;
  }

  return words;
}

// Helper function to get the next node in the DOM tree
function getNextNode(node) {
  if (node.firstChild) {
    return node.firstChild;
  } else {
    while (node && !node.nextSibling) {
      node = node.parentNode;
    }
    if (!node) {
      return null;
    }
    return node.nextSibling;
  }
}

// Function to fetch similar words (meanings) from the Datamuse API
function fetchSimilarWords(word) {
  return fetch(`https://api.datamuse.com/words?ml=${encodeURIComponent(word)}&max=100`)
    .then(response => response.json())
    .then(data => data);
}

// Function to fetch definitions or synonyms using the Datamuse API
function fetchDefinitions(word) {
  // Use the 'rel_syn' parameter for synonyms and 'md=d' to get definitions
  return fetch(`https://api.datamuse.com/words?rel_syn=${encodeURIComponent(word)}&md=d&max=5`)
    .then(response => response.json())
    .then(data => {
      const definitions = [];
      data.forEach(item => {
        if (item.defs) {
          item.defs.forEach(def => {
            // Defs are in the format "pos\tdefinition"
            const definition = def.split('\t')[1];
            definitions.push(`${item.word}: ${definition}`);
          });
        } else {
          definitions.push(item.word);
        }
      });
      return definitions;
    });
}

// Function to display a tooltip near the hovered word
function showTooltip(x, y, text) {
  removeExistingTooltip(); // Ensure no duplicate tooltips

  tooltip = document.createElement('div');
  tooltip.id = 'word-meaning-tooltip';
  tooltip.innerText = text;

  // Style the tooltip
  Object.assign(tooltip.style, {
    position: 'absolute',
    top: (y + 15) + 'px',
    left: (x + 15) + 'px',
    backgroundColor: '#fffbea',
    border: '1px solid #ccc',
    padding: '5px',
    zIndex: 10000,
    boxShadow: '2px 2px 6px rgba(0,0,0,0.2)',
    borderRadius: '4px',
    fontSize: '14px',
    color: '#333',
    maxWidth: '300px',
    whiteSpace: 'pre-wrap',
    wordWrap: 'break-word',
    pointerEvents: 'none' // Allows mouse events to pass through
  });

  document.body.appendChild(tooltip);
}

// Function to remove existing tooltip
function removeExistingTooltip() {
  if (tooltip) {
    tooltip.remove();
    tooltip = null;
  }
}