From aaa953f38b8f33726c6cd7eda473ac232f7fcc87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pr=C3=A9nom=20Nom?= <adresse@mail.com>
Date: Sat, 22 Feb 2025 02:21:01 +0100
Subject: [PATCH] fusion avec main + correction popup

---
 src/assets/lexicon_icon.js               |  21 +-
 src/background/background.js             | 225 ++++---
 src/context_menu/browser_context_menu.js |  63 +-
 src/context_menu/custom_context_menu.js  |  19 +-
 src/popup/popup.html                     | 132 ++--
 src/popup/popup.js                       | 807 +++++++++++++----------
 src/sidebar/sidebar.html                 |  45 +-
 src/sidebar/sidebar.js                   | 385 +++++++----
 src/utils/api.js                         |  78 +--
 src/utils/definitions.js                 | 148 ++---
 src/utils/highlighting.js                | 526 +++++++++++++++
 src/utils/logger.js                      |  35 +-
 src/utils/stats.js                       |  88 +--
 src/workers/pyodide_worker.js            |  65 +-
 14 files changed, 1750 insertions(+), 887 deletions(-)
 create mode 100644 src/utils/highlighting.js

diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
index 69833f8..1247bcf 100644
--- a/src/assets/lexicon_icon.js
+++ b/src/assets/lexicon_icon.js
@@ -19,7 +19,7 @@ async function getLexiconsColors(authToken) {
     log("✅ Couleurs des lexiques récupérées :", colors);
     return colors;
   } catch (error) {
-    console.error("❌ Erreur lors de la récupération des couleurs des lexiques :", error);
+    log("❌ Erreur lors de la récupération des couleurs des lexiques :", error);
     return {};
   }
 }
@@ -87,7 +87,7 @@ async function getOrCreateLexiconColor(lexiconId) {
         }
       }
     } catch (error) {
-      console.error("Erreur lors de la récupération des couleurs via l'API :", error);
+      log("Erreur lors de la récupération des couleurs via l'API :", error);
     }
   }
   // Si aucune couleur n'est associée, on la génère et on la sauvegarde
@@ -133,7 +133,7 @@ async function updateLexiconColors(authToken) {
     await browser.storage.local.set({ lexiconColors: colorMapping });
     return colorMapping;
   } catch (error) {
-    console.error("❌ Erreur lors de la mise à jour des couleurs :", error);
+    log("❌ Erreur lors de la mise à jour des couleurs :", error);
     return {};
   }
 }
@@ -147,6 +147,19 @@ async function getColorForLexicon(lexiconId) {
   const { lexiconColors } = await browser.storage.local.get("lexiconColors");
   return (lexiconColors && lexiconColors[String(lexiconId)]) || "#cccccc";
 }
+/**
+ * Convertit une couleur hexadécimale en une couleur RGBA.
+ * @param {string} hex - La couleur en hexadécimal.
+ * @param {number} opacity - La transparence (0-1).
+ * @returns {string} La couleur RGBA.
+ */
+function hexToRgba(hex, opacity) {
+  const bigint = parseInt(hex.replace('#', ''), 16);
+  const r = (bigint >> 16) & 255;
+  const g = (bigint >> 8) & 255;
+  const b = bigint & 255;
+  return `rgba(${r}, ${g}, ${b}, ${opacity})`;
+}
 
 window.updateLexiconColors = updateLexiconColors;
 window.getColorForLexicon = getColorForLexicon;
@@ -155,4 +168,4 @@ window.convertColor = convertColor;
 window.getOrCreateLexiconColor = getOrCreateLexiconColor;
 window.createColorCircle = createColorCircle;
 window.getLexiconsColors = getLexiconsColors;
-
+window.hexToRgba = hexToRgba;
diff --git a/src/background/background.js b/src/background/background.js
index 66eb60a..b41da8b 100644
--- a/src/background/background.js
+++ b/src/background/background.js
@@ -10,7 +10,7 @@ const AUTH_LOGIN_URL = "https://prisms.lezinter.net/fr/login";
 const AUTH_BALEX_URL = "https://prisms.lezinter.net/fr/headquarters/balex";
 
 // ─────────────────────────────────────────────────────────────────────────────
-// Logs de démarrage
+// Logs de démarrage et initialisation
 // ─────────────────────────────────────────────────────────────────────────────
 log("🚀 ff2BaLex (background) chargé.");
 
@@ -22,6 +22,11 @@ browser.runtime.onStartup.addListener(() => {
   log("🔄 Extension démarrée (onStartup).");
 });
 
+browser.runtime.onInstalled.addListener(() => {
+  browser.storage.local.set({ extensionActive: false });
+  log("🔔 Extension installée, état initialisé à désactivé.");
+});
+
 // ─────────────────────────────────────────────────────────────────────────────
 // Suivi des changements dans le stockage
 // ─────────────────────────────────────────────────────────────────────────────
@@ -45,7 +50,6 @@ browser.storage.onChanged.addListener((changes, area) => {
         if (!extensionActive) {
           log("Token ajouté, activation automatique de l'extension.");
           browser.storage.local.set({ extensionActive: true });
-          enableExtensionFeatures();
           browser.runtime.sendMessage({
             action: "updateUI",
             extensionActive: true,
@@ -68,7 +72,11 @@ async function isUserConnected() {
 
 async function refreshAllUI() {
   log("🔄 Rafraîchissement global de l'UI...");
-  browser.runtime.sendMessage({ action: "refreshUI" });
+  try {
+    await browser.runtime.sendMessage({ action: "refreshUI" });
+  } catch (error) {
+    console.warn("Aucun récepteur pour 'refreshUI' :", error);
+  }
 }
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -155,7 +163,6 @@ async function saveToken(token) {
   const { extensionActive } = await browser.storage.local.get("extensionActive");
   if (!extensionActive) {
     await browser.storage.local.set({ extensionActive: true });
-    enableExtensionFeatures();
     browser.runtime.sendMessage({
       action: "updateUI",
       extensionActive: true,
@@ -167,7 +174,7 @@ async function saveToken(token) {
 }
 
 // ─────────────────────────────────────────────────────────────────────────────
-// Gestion des messages reçus (depuis popup, etc.)
+// Gestion des messages reçus
 // ─────────────────────────────────────────────────────────────────────────────
 browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
   log("📩 Message reçu dans background.js :", message);
@@ -217,6 +224,34 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
       }
       break;
     }
+    case "toggleLexiconHighlight": {
+      const tabs = await browser.tabs.query({active: true, currentWindow: true});
+      if (tabs[0]) {
+        try {
+          // S'assurer que le script est injecté
+          await browser.scripting.executeScript({
+              target: { tabId: tabs[0].id },
+              files: ["src/utils/highlighting.js"]
+          });
+
+          // Envoyer le message d'activation
+          await browser.tabs.sendMessage(tabs[0].id, {
+            command: message.isActive ? "activate-highlighting" : "deactivate-highlighting",
+            lexiconId: message.lexiconId
+          });
+          log(`✅ Message de surlignage transmis à l'onglet ${tabs[0].id}`);
+        } catch (error) {
+          log("❌ Erreur lors de la gestion du surlignage:", error);
+        }
+      }
+      break;
+    }
+
+    case "register-highlighting-script": {
+      log("📝 Script de surlignage enregistré pour l'onglet", sender.tab.id);
+      break;
+    }
+
     default:
       break;
   }
@@ -249,14 +284,14 @@ browser.webNavigation.onCompleted.addListener(async (details) => {
               log("🔐 Token détecté :", token);
               browser.runtime.sendMessage({ action: "saveToken", token });
             } else {
-              console.error("❌ Token introuvable.");
+              log("❌ Token introuvable.");
             }
             return null;
           })();
         `
       });
     } catch (error) {
-      console.error("❌ Erreur lors de la récupération du token :", error);
+      log("❌ Erreur lors de la récupération du token :", error);
     }
   }
 }, { url: [{ hostContains: "prisms.lezinter.net" }] });
@@ -290,25 +325,25 @@ function showInstructionPopup(details) {
         popup.style.transform = "translate(-50%, -50%)";
         popup.style.backgroundColor = "#a08e9f";
         popup.style.color = "#323046";
-        popup.style.padding = "20px";
+        popup.style.padding = "12px";
         popup.style.borderRadius = "10px";
         popup.style.boxShadow = "0 2px 10px rgba(0, 0, 0, 0.3)";
         popup.style.zIndex = "10000";
         popup.style.fontFamily = "Luciole";
-        popup.style.fontSize = "14px";
+        popup.style.fontSize = "16px";
         popup.style.width = "300px";
         popup.style.textAlign = "center";
   
         popup.innerHTML = \`
-          <h5 style="color: #fff; font-weight: bold; margin-top: 0;">🔑 Connexion à l'extension</h5>
-          <p style="margin: 15px 0;">
-            Après avoir renseigné vos identifiants, cliquez sur 
+          <h5 style="color: #fff; font-weight: bold; margin-top: 2px;">Connexion à l'extension</h5>
+          <p style="margin: 8px 0;">
+            Après avoir renseigné vos identifiants, veuillez cliquer sur 
             <strong>"Se connecter avec BaLex"</strong>.
           </p>
           <button id="close-popup-btn" style="
             width: 100%;
             margin-top: 15px;
-            padding: 10px;
+            padding: 8px;
             border: none;
             background-color: #8d5c70;
             color: #fbfcfc;
@@ -334,44 +369,52 @@ let worker = null;
 
 function initWorker() {
   if (!worker) {
-    console.log("[Background] Initialisation du WebWorker...");
+    log("[Background] Initialisation du WebWorker...");
     try {
       worker = new Worker(browser.runtime.getURL("src/workers/pyodide_worker.js"));
       // Centralisation de l'écoute des messages et erreurs du Worker
       worker.addEventListener("message", handleWorkerMessage);
       worker.addEventListener("error", handleWorkerError);
-      console.log("[Background] WebWorker initialisé avec succès.");
+      log("[Background] WebWorker initialisé avec succès.");
     } catch (error) {
-      console.error("[Background] Échec de l'initialisation du WebWorker :", error);
+      log("[Background] Échec de l'initialisation du WebWorker :", error);
     }
   }
 }
 
+function handleWorkerError(error) {
+  log("Erreur du WebWorker :", error.message);
+}
+
 function handleWorkerMessage(event) {
   const data = event.data;
-  console.log("[Background] Message du WebWorker :", data);
+  log("[Background] Message du WebWorker :", data);
 
   switch (data.type) {
     case "pyodide-simplemma":
       if (data.status === "success") {
-        console.log("[Background] Pyodide et Simplemma prêts. Mise à jour de l'état.");
+        log("[Background] Pyodide et Simplemma prêts. Mise à jour de l'état.");
         browser.storage.local.set({ pyodideSimplemmaReady: true });
         checkAndUpdateTracking();
+      } else if (data.status === "error") {
+          log("[Background] Erreur lors du chargement :", data.message);
+        } else if (data.status === "already_loaded") {
+          log("[Background] Pyodide et Simplemma déjà chargés.");
       }
       break;
     case "update-frequencies":
-      console.log("[Background] Mise à jour des fréquences :", data.frequencies);
+      log("[Background] Mise à jour des fréquences :", data.frequencies);
       notifyAllTabs({ command: "update-frequencies", frequencies: data.frequencies });
       // Si un port stats est connecté, vous pouvez lui transmettre également :
       // port.postMessage({ command: "update-frequencies", frequencies: data.frequencies });
       browser.storage.local.set({ lemmaFrequencies: data.frequencies });
       break;
     case "threshold-exceeded":
-      console.log("[Background] Mots dépassant le seuil :", data.wordsAboveThreshold);
+      log("[Background] Mots dépassant le seuil :", data.wordsAboveThreshold);
       notifyAllTabs({ command: "threshold-exceeded", wordsAboveThreshold: data.wordsAboveThreshold });
       break;
     case "word-added":
-      console.log(`[Background] Mot ajouté : '${data.word}' dans '${data.language}' (Lexiques: ${data.lexicons})`);
+      log(`[Background] Mot ajouté : '${data.word}' dans '${data.language}' (Lexiques: ${data.lexicons})`);
       break;
     default:
       console.warn("[Background] Message non traité du Worker :", data);
@@ -379,10 +422,6 @@ function handleWorkerMessage(event) {
   }
 }
 
-function handleWorkerError(error) {
-  console.error("[Background] Erreur dans le WebWorker :", error);
-}
-
 // Initialisation du worker dès le démarrage
 initWorker();
 
@@ -390,118 +429,112 @@ initWorker();
 // Écoute des messages de la popup et transmission au WebWorker
 // ─────────────────────────────────────────────────────────────────────────────
 browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
-  console.log("[Background] Message reçu :", message);
+  log("[Background] Message reçu :", message);
 
   if (!worker) {
     initWorker();
   }
 
   if (message.command === "toggle-stats") {
-    console.log(`[Background] Statistiques ${message.isActive ? "activées" : "désactivées"}`);
+    log(`[Background] Statistiques ${message.isActive ? "activées" : "désactivées"}`);
     const { isActive } = message;
     await browser.storage.local.set({ isTrackingActive: isActive });
-    if (!isActive) {
-      await browser.storage.local.set({ autoAdd: false });
-    }
+    // if (!isActive) {
+    //   await browser.storage.local.set({ autoAdd: false });
+    // }
     checkAndUpdateTracking();
   }
 
   if (message.command === "pyodide-simplemma") {
-    console.log("[Background] Demande d'initialisation de Pyodide et Simplemma...");
+    log("[Background] Demande d'initialisation de Pyodide et Simplemma...");
     worker.postMessage({ command: "pyodide-simplemma" });
   }
 
   return true;
 });
 
+// ─────────────────────────────────────────────────────────────────────────────
+// Fonction : Chargement des lexiques personnels dans le local storage
+// ─────────────────────────────────────────────────────────────────────────────
+async function saveUserLexicons() {
+  const { accessToken } = await browser.storage.local.get("accessToken");
+  if (!accessToken) {
+    console.warn("Aucun token disponible, impossible de récupérer les lexiques.");
+    return;
+  }
+  log("Récupération des lexiques...");
+  const lexicons = await getLexicons(accessToken);
+  const userLexicons = lexicons.filter(lexicon => lexicon.category === "User");
+  if (userLexicons.length > 0) {
+    await browser.storage.local.set({ lexicons: userLexicons });
+    log("Lexiques enregistrés dans le local storage :", userLexicons);
+  } else {
+    log("Aucun lexique utilisateur trouvé.");
+  }
+  
+}
 
 
 // ─────────────────────────────────────────────────────────────────────────────
-// Envoi des données au WebWorker : lexiques personnels
+// Envoi des données au WebWorker : lexiques personnels et token
 // ─────────────────────────────────────────────────────────────────────────────
 
 // Charger et envoyer les lexiques au worker à la connexion + les stoplists associées 
 browser.storage.onChanged.addListener(async (changes, area) => {
   if (area === "local" && changes.accessToken) {
-    console.log("Token mis à jour, récupération des lexiques...");
-    sendLexiconsToWorker();
+    log("Token mis à jour, récupération des lexiques...");
+    const userLexicons = await saveUserLexicons();  // Récupérer les lexiques
+    sendLexiconsToWorker(userLexicons); // Envoyer les lexiques au Worker après une connexion
     sendAuthTokenToWorker();
   }
 });
 
-async function sendLexiconsToWorker() {
-  const { accessToken } = await browser.storage.local.get("accessToken");
-  if (!accessToken) {
-    console.warn("Aucun token disponible, impossible de récupérer les lexiques.");
+// Envoyer les lexiques et stoplists au Worker
+async function sendLexiconsToWorker(userLexicons = null) { 
+  if (!userLexicons) {
+    const storedData = await browser.storage.local.get("lexicons");
+    userLexicons = storedData.lexicons || [];
+  }
+  if (!Array.isArray(userLexicons) || userLexicons.length === 0) {
+    console.warn("[Background] Aucun lexique à envoyer au Worker.");
     return;
   }
+  log("[Background] Envoi des lexiques au Worker...");
+  if (worker) {
+    worker.postMessage({
+      command: "update-lexicons",
+      lexicons: JSON.stringify(userLexicons)
+    });
 
-  console.log("Récupération des lexiques de l'utilisateur...");
-  const lexicons = await getLexicons(accessToken);
-  
-  // Filtrage : Ne garder que les lexiques de catégorie "User"
-  const userLexicons = lexicons.filter(lexicon => lexicon.category === "User");
-
-  if (Array.isArray(userLexicons) && userLexicons.length > 0) {
-    await browser.storage.local.set({ lexicons: userLexicons });
-    console.log("Lexiques utilisateur stockés :", userLexicons);
-
-    console.log("[Background] Envoi des lexiques utilisateur au Worker...");
-    if (worker) {
-      worker.postMessage({ command: "update-lexicons", lexicons: userLexicons });
-      console.log("[Background] Envoi des lexiques utilisateur réussi !");
-    }
-    // Charger et envoyer uniquement les stoplists des langues des lexiques utilisateur
-    const languages = [...new Set(userLexicons.map(lexicon => lexicon.language))];
-    console.log("[Background] Langues détectées :", languages);
-    loadStoplistsForLanguages(languages);
-
-  } else {
-    console.warn("Aucun lexique utilisateur trouvé.");
+  // Charger et envoyer uniquement les stoplists des langues des lexiques utilisateur
+  const languages = [...new Set(userLexicons.map(lexicon => lexicon.language))];
+  log("[Background] Langues détectées :", languages);
+  loadStoplistsForLanguages(languages);
+  log("Lexiques envoyés au WebWorker !");
   }
 }
 
+
 // Charger et envoyer le token au worker à la connexion 
 async function sendAuthTokenToWorker() {
   if (!worker) {
     console.warn("Worker non initialisé. Impossible d'envoyer le token.");
     return;
   }
-
   const { accessToken } = await browser.storage.local.get("accessToken");
   if (!accessToken) {
     console.warn("Aucun token disponible. Le worker ne pourra pas interagir avec l’API.");
     return;
   }
-
-  console.log("🔑 Envoi du token au Worker...");
+  log("Envoi du token au Worker...");
   worker.postMessage({ command: "update-auth-token", accessToken });
 }
 
 // ─────────────────────────────────────────────────────────────────────────────
 // Stoplists : Chargement et envoi au Worker
 // ─────────────────────────────────────────────────────────────────────────────
-// let stoplistFr = [];
-
-// function loadStoplist() {
-//   fetch(browser.runtime.getURL("src/stoplists/stoplist_fr.txt"))
-//     .then(response => response.text())
-//     .then(text => {
-//       stoplistFr = text.split("\n").map(word => word.trim());
-//       console.log("[Background] Stoplist chargée :", stoplistFr);
-//       sendStoplistToWorker();
-//     })
-//     .catch(error => console.error("[Background] Erreur lors du chargement de la stoplist :", error));
-// }
-
-// function sendStoplistToWorker() {
-//   console.log("[Background] Envoi de la stoplist au Worker...");
-//   worker.postMessage({ command: "update-stoplist", stoplist: stoplistFr });
-// }
-
 async function loadStoplistsForLanguages(languages) {
   const stoplists = {};
-  
   // Charger toutes les stoplists en parallèle
   await Promise.all(
     languages.map(async (lang) => {
@@ -510,18 +543,17 @@ async function loadStoplistsForLanguages(languages) {
         const response = await fetch(browser.runtime.getURL(stoplistPath));
         const text = await response.text();
         stoplists[lang] = text.split("\n").map(word => word.trim());
-        console.log(`[Background] ✅ Stoplist chargée pour '${lang}' : ${stoplists[lang].length} mots`);
+        log(`[Background] ✅ Stoplist chargée pour '${lang}' : ${stoplists[lang].length} mots`);
       } catch (error) {
         console.warn(`[Background] ⚠ Stoplist introuvable pour '${lang}', aucun filtrage ne sera appliqué.`);
       }
     })
   );
-
   sendStoplistsToWorker(stoplists);
 }
 
 function sendStoplistsToWorker(stoplists) {
-  console.log("[Background] Envoi des stoplists au Worker...");
+  log("[Background] Envoi des stoplists au Worker...");
   worker.postMessage({ command: "update-stoplist", stoplists });
 }
 
@@ -541,7 +573,7 @@ let storedFrequencies = {};
 
 loadStoredFrequencies().then(frequencies => {
   storedFrequencies = frequencies;
-  console.log("[Background] Fréquences initialisées :", storedFrequencies);
+  log("[Background] Fréquences initialisées :", storedFrequencies);
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -550,10 +582,10 @@ loadStoredFrequencies().then(frequencies => {
 async function checkAndUpdateTracking() {
   const { isTrackingActive, pyodideSimplemmaReady } = await browser.storage.local.get(["isTrackingActive", "pyodideSimplemmaReady"]);
   if (isTrackingActive && pyodideSimplemmaReady) {
-    console.log("[Background] Activation du tracking.");
+    log("[Background] Activation du tracking.");
     notifyAllTabs({ command: "activate-stats" });
   } else {
-    console.log("[Background] Désactivation du tracking.");
+    log("[Background] Désactivation du tracking.");
     notifyAllTabs({ command: "deactivate-stats" });
   }
 }
@@ -571,20 +603,17 @@ async function notifyAllTabs(message) {
 }
 
 // ─────────────────────────────────────────────────────────────────────────────
-// Écoute du changement des préférences et envoi des valeurs au Worker
+// Statistiques : Écoute des modifications du stockage et mise à jour du tracking
 // ─────────────────────────────────────────────────────────────────────────────
 browser.storage.onChanged.addListener(async (changes, area) => {
-
   if (area === "local" && (changes.isTrackingActive || changes.pyodideSimplemmaReady)) {
     checkAndUpdateTracking();
   }
-
   if (area === "local" && (changes.accessToken || changes.threshold || changes.trackedLanguages || changes.autoAdd)) {
-    console.log("[Background] Mise à jour des préférences détectée.");
+    log("[Background] Mise à jour des préférences détectée.");
     const { accessToken, trackedLanguages, threshold, autoAdd} = await browser.storage.local.get([
       "accessToken", "trackedLanguages", "threshold", "autoAdd"
     ]);
-
     const isAuthenticated = !!accessToken;
     worker.postMessage({
       command: "update-preferences",
@@ -597,14 +626,12 @@ browser.storage.onChanged.addListener(async (changes, area) => {
 
   if (area === "local" && changes.includeStopwords) {
     const includeStopwords = changes.includeStopwords.newValue;
-    console.log(`[Background] Inclusion des mots outils activé/désactivé: ${includeStopwords}`);
+    log(`[Background] Inclusion des mots outils activé/désactivé: ${includeStopwords}`);
 
     if (worker) {
       worker.postMessage({ command: "update-include-stopwords", includeStopwords });
     }
   }
-
-
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -612,7 +639,7 @@ browser.storage.onChanged.addListener(async (changes, area) => {
 // ─────────────────────────────────────────────────────────────────────────────
 browser.runtime.onMessage.addListener(async (message, sender) => {
   if (message.command === "register-stats-script") {
-    console.log("[Background] stats.js s'est enregistré.");
+    log("[Background] stats.js s'est enregistré.");
     const { isTrackingActive, pyodideSimplemmaReady } = await browser.storage.local.get(["isTrackingActive", "pyodideSimplemmaReady"]);
     if (isTrackingActive && pyodideSimplemmaReady) {
       browser.tabs.sendMessage(sender.tab.id, { command: "activate-stats" })
@@ -625,11 +652,11 @@ browser.runtime.onMessage.addListener(async (message, sender) => {
 // Connexion entre stats.js et le Worker via un port dédié
 // ─────────────────────────────────────────────────────────────────────────────
 browser.runtime.onConnect.addListener((port) => {
-  console.log("[Background] Connexion établie :", port.name);
+  log("[Background] Connexion établie :", port.name);
   if (port.name === "stats-worker-port") {
     // Redirige les messages de stats.js vers le Worker
     port.onMessage.addListener((message) => {
-      console.log("[Background] Message reçu de stats.js :", message);
+      log("[Background] Message reçu de stats.js :", message);
       worker.postMessage(message);
     });
 
diff --git a/src/context_menu/browser_context_menu.js b/src/context_menu/browser_context_menu.js
index 9211233..cd98a6f 100644
--- a/src/context_menu/browser_context_menu.js
+++ b/src/context_menu/browser_context_menu.js
@@ -12,7 +12,7 @@ async function loadAuthToken() {
     authToken = result.accessToken;
     log("🔑 Token chargé au démarrage :", authToken);
   } catch (error) {
-    console.error("❌ Erreur lors de la récupération du token :", error);
+    log("❌ Erreur lors de la récupération du token :", error);
   }
 }
 
@@ -25,8 +25,10 @@ async function loadAuthToken() {
 async function createContextMenu() {
   await browser.contextMenus.removeAll();
 
-  if (authToken) {
-    // Item 1 : Recherche dans les lexiques de l’utilisateur
+  const { extensionActive } = await browser.storage.local.get("extensionActive");
+  log("État de l'extension :", extensionActive);
+
+  if (extensionActive) {
     browser.contextMenus.create({
       id: "searchInLexicons",
       title: "Rechercher dans mes lexiques",
@@ -34,37 +36,29 @@ async function createContextMenu() {
       icons: { "16": "src/assets/icons/quel_lexique.png" },
     });
 
-    // Item 2 : Ajouter le mot au(x) lexique(s) de l’utilisateur
     browser.contextMenus.create({
       id: "addToLexicon",
       title: "Ajouter ce mot à mes lexiques",
       contexts: ["selection"],
       icons: { "16": "src/assets/icons/ajout_lexique.png" },
     });
-  }
 
-  // Séparateur
-  browser.contextMenus.create({
-    id: "separatorExtension",
-    type: "separator",
-    contexts: ["all"],
-  });
+    browser.contextMenus.create({
+      id: "getDefinition",
+      title: "Obtenir une définition",
+      contexts: ["selection"],
+      icons: { "16": "src/assets/icons/definition.png" },
+    });
 
-  // Item 3 : Recherche globale de définition (Lexiques + Wiktionnaire)
-  browser.contextMenus.create({
-    id: "getDefinition",
-    title: "Obtenir une définition",
-    contexts: ["selection"],
-    icons: { "16": "src/assets/icons/definition.png" },
-  });
+    browser.contextMenus.create({
+      id: "separatorExtension",
+      type: "separator",
+      contexts: ["all"],
+    });
+  } else {
+    log("⚠️ L'extension est désactivée, aucune option d'analyse ne sera affichée.");
+  }
 
-  browser.contextMenus.create({
-    id: "separatorAfterExtension",
-    type: "separator",
-    contexts: ["all"],
-  });
-  
-  // Item de connexion/déconnexion
   browser.contextMenus.create({
     id: "login",
     title: authToken ? "Se déconnecter de BaLex" : "Se connecter à BaLex",
@@ -72,10 +66,11 @@ async function createContextMenu() {
   });
 }
 
+
 loadAuthToken().then(createContextMenu);
 
 browser.runtime.onMessage.addListener((message) => {
-  if (message.action === "refreshUI") {
+  if (message.action === "refreshUI" || message.action === "updateUI") {
     log("🔄 refreshUI reçu dans browser_context_menu.js");
     loadAuthToken().then(createContextMenu);
   }
@@ -97,10 +92,14 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
   // Action pour le bouton de connexion/déconnexion
   if (info.menuItemId === "login") {
     log("🔄 Action login/déconnexion demandée.");
-    if (typeof actuallyOpenLoginPage === "function") {
-      actuallyOpenLoginPage();
+    if (authToken) {
+      await disconnectFromLexicalDB();
     } else {
-      console.error("La fonction actuallyOpenLoginPage n'est pas accessible.");
+      if (typeof actuallyOpenLoginPage === "function") {
+        actuallyOpenLoginPage();
+      } else {
+        log("La fonction actuallyOpenLoginPage n'est pas accessible.");
+      }
     }
     return;
   }
@@ -146,7 +145,7 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
       break;
     }
   
-  console.error(`❌ Action inconnue : ${info.menuItemId}`);
+  log(`❌ Action inconnue : ${info.menuItemId}`);
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -167,7 +166,7 @@ async function getDefinition(selectedText) {
       definitions: allDefinitions,
     });
   } catch (error) {
-    console.error("❌ Erreur lors de la recherche combinée des définitions :", error);
+    log("❌ Erreur lors de la recherche combinée des définitions :", error);
   }
 }
 
@@ -201,7 +200,7 @@ async function searchInLexicons(selectedText) {
       selectedText,
     });
   } catch (error) {
-    console.error("❌ Erreur lors de la recherche dans les lexiques :", error);
+    log("❌ Erreur lors de la recherche dans les lexiques :", error);
     browser.runtime.sendMessage({
       action: "showLexiconResult",
       lexicons: [],
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index a4cb929..0c74f17 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -20,7 +20,7 @@ async function loadAuthToken() {
     authToken = result.accessToken || null;
     log("🔑 Token chargé :", authToken);
   } catch (error) {
-    console.error("❌ Erreur lors de la récupération du token :", error);
+    log("❌ Erreur lors de la récupération du token :", error);
     authToken = null;
   }
 }
@@ -141,6 +141,7 @@ function updateMenuVisibility() {
     getDefinitionBtn.style.display = "inline-block";
     loginBtn.style.display = "none";
   } else {
+    hideWhiteBox();
     addLexiconBtn.style.display = "none";
     getDefinitionBtn.style.display = "inline-block";
     loginBtn.style.display = "inline-block";
@@ -158,7 +159,12 @@ function getSelectedWord() {
 /**
  * Affiche le menu contextuel à la position du clic.
  */
-function showWhiteBox(event, selectedText) {
+async function showWhiteBox(event, selectedText) {
+  const { extensionActive } = await browser.storage.local.get("extensionActive") || { extensionActive: false };
+  if (!extensionActive || !authToken) {
+    hideWhiteBox();
+    return;
+  }
   const whiteBox = getOrCreateWhiteBox();
   const selectedWordElement = document.getElementById("selectedWord");
   selectedWordElement.textContent = selectedText;
@@ -297,7 +303,7 @@ async function showPicker(event, selectedText) {
         try {
           definitions = await fetchLexiconDefinitions(selectedText);
         } catch (error) {
-          console.error("Erreur lors de la récupération des définitions :", error);
+          log("Erreur lors de la récupération des définitions :", error);
         }
         const existingLexiconIds = new Set();
         if (Array.isArray(definitions)) {
@@ -308,11 +314,10 @@ async function showPicker(event, selectedText) {
           }
         }
         if (existingLexiconIds.size > 0) {
-          alert(`⚠️ Le mot "${selectedText}" existe déjà dans les lexiques suivants : ${Array.from(existingLexiconIds).join(", ")}`);
+          alert(`Le mot "${selectedText}" existe déjà dans les lexiques suivants : ${Array.from(existingLexiconIds).map(id => lexiconDescriptions[id]).join(", ")}`);
         }
         const lexiconsToAdd = [...selectedLexicons].filter(id => !existingLexiconIds.has(id));
         if (lexiconsToAdd.length === 0) {
-          alert(`✅ Le mot "${selectedText}" est déjà présent dans tous les lexiques sélectionnés.`);
           return;
         }
         try {
@@ -329,7 +334,7 @@ async function showPicker(event, selectedText) {
             lexicons: successMsg
           });
         } catch (error) {
-          console.error("❌ Erreur lors de l'ajout du mot :", error);
+          log("❌ Erreur lors de l'ajout du mot :", error);
           const errorMsg = `❌ Erreur lors de l'ajout du mot : ${error.message}`;
           picker.innerHTML = `<p style="color: red;">${errorMsg}</p>`;
           setTimeout(() => picker.style.display = "none", 3000);
@@ -351,7 +356,7 @@ async function showPicker(event, selectedText) {
     picker.style.top = event.pageY + "px";
     picker.style.display = "flex";
   } catch (error) {
-    console.error("❌ Erreur lors de la récupération des lexiques :", error);
+    log("❌ Erreur lors de la récupération des lexiques :", error);
     picker.innerHTML = "<p style='color:#333;'>Erreur lors du chargement des lexiques.</p>";
     picker.style.display = "block";
   }
diff --git a/src/popup/popup.html b/src/popup/popup.html
index b9c17fd..e4b7b95 100644
--- a/src/popup/popup.html
+++ b/src/popup/popup.html
@@ -28,10 +28,9 @@
       max-width: 250px;
       z-index: 1000;
       box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
-      transition: opacity 0.3s ease, visibility 0.3s ease;
+      transition: visibility 0.3s ease;
     }
     #extension-notification.hidden {
-      opacity: 0;
       visibility: hidden;
     }
 
@@ -45,7 +44,6 @@
       border-radius: 5px;
       font-weight: bold;
     }
-
     #close-notification:hover {
       background-color: #dddedd;
       color: #8d5c70;
@@ -83,7 +81,7 @@
       width: auto;
       display: inline-flex;
       padding: 6px 12px;
-      font-size: 18px;
+      font-size: 16px;
       font-family: Luciole;
       background: none;
       border: none;
@@ -124,10 +122,8 @@
     }
     .option-container {
       background: #444;
-      padding: 12px;
+      padding: 8px;
       border-radius: 10px;
-      margin-top: 4px;
-      margin-bottom: 4px;
       box-shadow: 0 2px 6px rgba(0,0,0,0.2);
     }
     .option-row {
@@ -136,11 +132,9 @@
       justify-content: space-between;
       flex-wrap: nowrap;
       padding: 12px;
-      margin-bottom: 4px;
       border-radius: 6px;
       background-color: #444;
       color: white;
-      font-size: 0.6rem;
       transition: transform 0.2s, box-shadow 0.2s;
     }
     .option-row:hover {
@@ -151,10 +145,9 @@
       font-weight: lighter;
       flex: 1;
       margin: 0;
-      font-size: 0.9rem;
+      font-size: 13px;
       align-items: center;
     }
-
     .option-row input[type="checkbox"],
     .option-row input[type="number"] {
       appearance: none;
@@ -166,12 +159,10 @@
       cursor: pointer;
       transition: background-color 0.3s, border-color 0.3s;
     }
-
     .option-row input[type="checkbox"]:checked {
       background-color: #8d5c70;
       border-color: #8d5c70;
     }
-
     .toggle-switch {
       position: absolute;
       display: inline-block;
@@ -191,7 +182,6 @@
       transition: 0.4s;
       border-radius: 50%;
     }
-
     .toggle-switch input {
       opacity: 0;
       width: 0;
@@ -208,15 +198,12 @@
       transition: 0.4s;
       border-radius: 24px;
     }
-
     input:checked + .slider {
       background-color: #8d5c70;
     }
-
     input:checked + .slider:before {
       transform: translateX(14px);
     }
-
     .threshold-container input[type="number"] {
       width: 45px;   
       height: 45px;
@@ -224,19 +211,18 @@
       text-align: center;
       border-radius: 50%;    
       border: 2px solid #8d5c70;
-      font-size: 0.8rem;
+      font-size: 13px;
       box-sizing: border-box;
       background: #fff;
       color: #333;
     }
-
     #save-options {
       border: none;
       background: #8d5c70;
       border-radius: 6px;
       color: white;
       padding: 8px 12px;
-      font-size: 0.9rem;
+      font-size: 14px;
       cursor: pointer;
       transition: background 0.3s, transform 0.2s;
     }
@@ -270,13 +256,6 @@
       color: white;
       border-color: #8d5c70;
     }
-
-    /* #stats-options {
-      border: 1px solid #555;
-      border-radius: 8px;
-      align-items: center;
-    } */
-
     .option-row.auto-add-row {
       position: relative;
       display: flex;
@@ -288,41 +267,24 @@
       border-bottom: 1px solid #555;    
     }
     .option-row.auto-add-row span {
-      font-size: 16px;
+      font-size: 14px;
       font-weight: lighter;
     }
-
     .option-row.stopwords {
       position: relative;
       display: flex;
       align-items: center;
       justify-content: space-between;
-      font-size: 0.9rem;
+      font-size: 13px;
       font-weight: lighter;
     }
-
-    /* .option-row.auto-add-row input[type="checkbox"] {
-      appearance: none;
-      width: 24px;
-      margin-left: 10px;
-      height: 24px;
-      border: 2px solid #8d5c70;
-      border-radius: 4px;
-      background: #fff;
-      cursor: pointer;
-      transition: background 0.3s;
-    } */
-
-    /* .option-row.auto-add-row input[type="checkbox"]:checked {
-      background: #8d5c70;
-    } */
-    
     #open-stats {
       padding: 6px;
       font-weight: lighter;
       width: auto;
       display: block;
       margin: 0 auto;
+      margin-bottom: 10px;
       background-color: #525877;
       color: white;
       border: 2px solid #8d5c70;
@@ -331,6 +293,65 @@
     .hidden {
       display: none;
     }
+    #error-message {
+      font-size: 13px;
+      font-style: italic;
+      text-align: center;
+      color: white;
+    }
+    .tooltip-container {
+      position: relative;
+      display: inline-block;
+      pointer-events: auto !important;
+    }
+    .tooltip {
+      all: unset;
+      display: block;
+      box-sizing: border-box;
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      color: #fff !important;
+      font-size: 12px !important;
+      font-weight: lighter !important;
+      padding: 6px 10px;
+      border-radius: 5px;
+      white-space: normal;
+      overflow-wrap: break-word;
+      width: 200px;
+      text-align: center;
+      visibility: hidden;
+      transition: visibility 0.3s ease-in-out, transform 0.3s ease-in-out;
+      pointer-events: none;
+      z-index: 1000;
+      line-height: normal;
+    }
+    /* Règle générique pour les tooltips */
+    .tooltip-container .tooltip {
+      bottom: 120%;
+      transform: translateX(-50%);
+      background-color: rgba(0,0,0,0.9) !important;
+      visibility: hidden;
+      pointer-events: auto !important;
+    }
+    .tooltip-container:hover .tooltip {
+      visibility: visible !important;
+      transform: translateX(-50%) translateY(-5px);
+      pointer-events: auto !important;
+    }
+    /* Style spécifique pour le bouton de connexion */
+    #auth-button .tooltip {
+      top: 120%;
+      bottom: auto;
+    }
+    #auth-button.tooltip-container:hover .tooltip {
+      visibility: visible !important;
+      transform: translateX(-50%) translateY(5px);
+    }
+    /* Permettre l'interaction avec les tooltips même sur les boutons désactivés */
+    button:disabled .tooltip {
+      pointer-events: auto !important;
+    }
   </style>
 </head>
 <body>
@@ -348,16 +369,16 @@
   <button id="toggleExtensionBtn">Activer/Désactiver</button>
   <button id="toggleStatsBtn">Statistiques</button>
   <button id="open-stats">Afficher les statistiques</button>
-  
+  <div id="pyodide-loading"></div>
+
   <div id="stats-options" class="option-container">
-    <div class="option-row auto-add-row">
+    <div id="auto-add-container" class="option-row auto-add-row">
       <span>Ajout automatique</span>
       <label class="toggle-switch">
         <input type="checkbox" id="auto-add">
         <span class="slider"></span>
       </label>
     </div>
-    
   <div id="auto-add-options" class="hidden">
     <div class="option-row stopwords">
       <span>Inclure mots outils</span>
@@ -366,27 +387,22 @@
         <span class="slider"></span>
       </label>
     </div>
-    
-      
     <div class="option-row threshold-container">
       <label for="threshold">Seuil d'ajout d'un mot</label>
       <input type="number" id="threshold" value="10" min="1" />
     </div>
-      
     <div class="option-row">
       <label>Langues suivies</label>
       <div id="language-selection" class="language-selection">
         <p id="loading-languages" style="color: gray;">Chargement...</p>
       </div>
     </div>
-
-    <!-- Message d'erreur si on ne sélectionne pas une langue à suivre-->
-    <div id="error-message" class="hidden">
-      <p>Veuillez sélectionner au moins une langue avant de sauvegarder.</p>
+      <!-- Message d'erreur si aucune langue sélectionnée -->
+      <div id="error-message" class="hidden">
+      <p>Veuillez sélectionner une ou plusieurs langue(s).</p>
     </div>      
     <button id="save-options" class="hidden">Valider</button>
   </div>
-
   </div>
 
   <div id="extension-notification" class="hidden">
diff --git a/src/popup/popup.js b/src/popup/popup.js
index 13cb644..6cc4015 100644
--- a/src/popup/popup.js
+++ b/src/popup/popup.js
@@ -1,443 +1,487 @@
 log("✅ popup.js chargé avec succès !");
+// fetchExtensionState() : fonction qui se charge de récupérer les valeurs du local storage
+// updateUI(): utilise les états récupérés par fetchExtensionState pour appeler d'autres fonctions
+// ex. actualisation du bouton de connexion, bouton activer l'extension, les stats...
+// setupEventListeners() : fonction qui regroupe les écouteurs d'évènement
+// handleEvent() : une description de chaque évènement avec les changements de valeur du local storage
 
-// ==========================
+
+// ====================================================================================
 // Fonctions utilitaires
-// ==========================
+// ====================================================================================
+
+//Obtenir le token
 async function getAccessToken() {
   const { accessToken } = await browser.storage.local.get("accessToken");
   return accessToken;
 }
 
-// ==========================
-// Gestion de la connexion
-// ==========================
-async function updateConnectionButton() {
-  const accessToken = await getAccessToken();
-  const button = document.getElementById("auth-button");
-
-  if (!button) {
-    console.error("❌ Le bouton de connexion n'a pas été trouvé.");
-    return;
-  }
-
-  if (accessToken) {
-    button.textContent = "Se déconnecter";
-    button.title = "En vous déconnectant, vous perdrez l'accès à vos lexiques personnels, ainsi que les fonctionnalités d'ajout automatique et de statistiques d'utilisation.";
-  } else {
-    button.textContent = "Se connecter";
-    button.title = "En vous connectant, vous pourrez accéder à vos lexiques personnels, ainsi qu'aux fonctionnalités d'ajout automatique et de statistiques d'utilisation.";
-  }
-
-  button.onclick = async () => {
-    const isConnected = !!accessToken;
-    
-    // Gestion de la déconnexion
-    if (isConnected) {
-      console.log("[Popup] Déconnexion détectée, réinitialisation des options...");
-
-      await browser.storage.local.set({
-        accessToken: null,
-        autoAdd: false,
-        includeStopwords: false,
-        isTrackingActive: false
-      });
-
-      // Envoyer les mises à jour au worker
-      browser.runtime.sendMessage({
-        command: "update-preferences",
-        autoAdd: false,
-        includeStopwords: false,
-        isTrackingActive: false
-      });
-
-      console.log("✅ Paramètres réinitialisés après déconnexion.");
-
-      // Mettre à jour l'interface
-      await updateOptionsUI();
-      await updateLanguageSelection();
-      await updateExtensionToggleButton();
-    }
+// =========
+// Fonction d'actualisation générale de la popup : 1. Récupération des valeurs 2. Màj UI
+async function updateExtension() {
+  states = await fetchExtensionState(); //Récupérer les valeurs 
+  updateUI(states); // Selon les valeurs, mettre à jour l'UI
+}
 
-    // Envoyer le message pour basculer l'authentification
-    await browser.runtime.sendMessage({ action: "toggleAuth" });
+// =========
+// 1. Récupérer les valeurs du local storage
+async function fetchExtensionState() {
+  const accessToken = await getAccessToken();
+  const storedValues = await browser.storage.local.get([
+      "extensionActive",
+      "isTrackingActive",
+      "autoAdd",
+      "threshold",
+      "pyodideSimplemmaReady",
+      "includeStopwords"
+  ]);
+  return {
+      isLoggedIn: !!accessToken,
+      extensionActive: storedValues.extensionActive ?? false,
+      isTrackingActive: storedValues.isTrackingActive ?? false,
+      autoAdd: storedValues.autoAdd ?? false,
+      threshold: storedValues.threshold ?? 10,
+      pyodideSimplemmaReady: storedValues.pyodideSimplemmaReady ?? false,
+      includeStopwords: storedValues.includeStopwords ?? false 
   };
 }
 
-// ==========================
-// Gestion de la sélection des langues
-// ==========================
-async function updateLanguageSelection() {
-  const languageSelection = document.getElementById("language-selection");
-  languageSelection.innerHTML = "<p id='loading-languages' style='color: gray;'>Chargement...</p>";
-
-  const accessToken = await getAccessToken();
-  if (!accessToken) {
-    languageSelection.innerHTML = "<p style='color: red;'>Veuillez vous connecter.</p>";
-    return;
-  }
+// =========
+// 2.Fonction de mise à jour de l'UI
+async function updateUI(states) {
+  await updateConnectionButton(states.isLoggedIn); //Actualisation du bouton de connexion
+  await updateToggleExtensionButton(states.isLoggedIn, states.extensionActive, states.autoAdd, states.isTrackingActive,  states.pyodideSimplemmaReady,  states.includeStopwords);
+  // éventuellement ajouter des fonctions issues du toggleExtensionButton pour la lisibilité :
+  //await updateStatsButtons(states.isLoggedIn, states.extensionActive, states.isTrackingActive);
+  // await updateAutoAddOptions(states.isLoggedIn, states.extensionActive, states.autoAdd);
+  // await updatePyodideStatus(states.isLoggedIn, states.extensionActive, states.isTrackingActive, state.pyodideSimplemmaReady);
+  await updateLanguageSelection();
+  await updateStopwordsOption(states.includeStopwords);
+  console.log("✅ Interface mise à jour :", states);
+}
 
-  // Utilisation de la fonction de récupération de lexiques
-  // Choisissez ici entre getLexicons et getUserLexicons en fonction de votre implémentation
-  const lexicons = await getLexicons(accessToken);
-  const userLanguages = [...new Set(lexicons.map(lex => lex.language))];
 
-  // Récupérer les langues suivies depuis le stockage
-  const { trackedLanguages } = await browser.storage.local.get("trackedLanguages") || { trackedLanguages: [] };
 
-  languageSelection.innerHTML = "";
-  if (userLanguages.length === 0) {
-    languageSelection.innerHTML = "<p style='color: red;'>Aucun lexique personnel trouvé.</p>";
-    return;
-  }
+// ====================================================================================
+// Fonction contenant les écouteurs d'évènements et gestion des valeurs du local storage
+// ====================================================================================
+function setupEventListeners() {
+  // Bouton Connexion / Déconnexion
+  document.getElementById("auth-button")?.addEventListener("click", handleAuthToggle);
 
-  userLanguages.forEach(lang => {
-    const langButton = document.createElement("div");
-    langButton.classList.add("lang-option");
-    langButton.textContent = lang.toUpperCase();
-    langButton.dataset.value = lang;
-    if (trackedLanguages && trackedLanguages.includes(lang)) {
-      langButton.classList.add("selected");
-    }
-    langButton.addEventListener("click", () => {
-      langButton.classList.toggle("selected");
-    });
-    languageSelection.appendChild(langButton);
-  });
+  // Bouton activer l'extension
+  document.getElementById("toggleExtensionBtn")?.addEventListener("click", handleToggleExtension);
 
-  log("✅ Sélection des langues mise à jour avec :", userLanguages);
-}
+  // Bouton de gestion des statistiques
+  document.getElementById("toggleStatsBtn")?.addEventListener("click", handleStatsToggle);
 
-// ==========================
-// Gestion des options et des statistiques
-// ==========================
-async function updateOptionsUI() {
-  const accessToken = await getAccessToken();
-  const isLoggedIn = !!accessToken;
-  const statsOptions = document.getElementById("stats-options");
-  const autoAddContainer = document.getElementById("auto-add")?.parentElement;
-  const autoAddCheckbox = document.getElementById("auto-add");
-  const autoAddOptions = document.getElementById("auto-add-options");
-  const thresholdInput = document.getElementById("threshold");
-  const saveOptionsBtn = document.getElementById("save-options");
-  const toggleStatsBtn = document.getElementById("toggleStatsBtn");
-  const openStats = document.getElementById("open-stats");
-  const includeStopwordsCheckbox = document.getElementById("include-stopwords");
+  // Gestion de l'ajout automatique
+  document.getElementById("auto-add")?.addEventListener("change", handleAutoAddToggle);
   
-  // Affichage de l'option "Ajout automatique" selon la connexion
-  if (autoAddContainer) {
-    autoAddContainer.style.display = isLoggedIn ? "block" : "none";
-  }
-
-  // Chargement des préférences
-  const { isTrackingActive, autoAdd, threshold, includeStopwords} = await browser.storage.local.get([
-    "isTrackingActive",
-    "autoAdd",
-    "threshold",
-    "includeStopwords"
-  ]) || { isTrackingActive: false, includeStopwords: false };
-
-  // Gestion du bouton de statistiques
-  if (toggleStatsBtn) {
-    if (!isLoggedIn) {
-      toggleStatsBtn.style.opacity = "0.5";
-      toggleStatsBtn.title = "Connectez-vous pour activer les statistiques";
-      if (openStats) openStats.style.display = "none";
-    } else {
-      toggleStatsBtn.style.opacity = "1";
-      toggleStatsBtn.title = "";
-      if (openStats) openStats.style.display = "block";
-    }
-    toggleStatsBtn.textContent = isTrackingActive ? "Désactiver les statistiques" : "Activer les statistiques";
-  }
+  //Activation/désactivation des stopwords
+  document.getElementById("include-stopwords")?.addEventListener("change", handleStopwordsToggle);
+  
+  // Sauvegarde des options
+  document.getElementById("save-options")?.addEventListener("click", handleSaveOptions);
 
-  // Gestion des boutons d'options de statistiques
-  if (statsOptions) {
-    statsOptions.classList.toggle("hidden", !isTrackingActive);
-  }
-  //Si l'utilsateur est connecté : afficher les options
-  if (isLoggedIn) {
-    if (autoAddCheckbox) {
-      autoAddCheckbox.checked = autoAdd || false;
-    }
-    if (includeStopwordsCheckbox) {
-      includeStopwordsCheckbox.checked = includeStopwords || false;
-    }
-    if (thresholdInput && threshold !== undefined) {
-      thresholdInput.value = threshold;
-    }
-    if (autoAddOptions) {
-      autoAddOptions.classList.toggle("hidden", !autoAdd);
-    }
-    if (saveOptionsBtn) {
-      saveOptionsBtn.classList.toggle("hidden", !autoAdd);
-    }
-  //Si l'utilsateur n'est connecté : masquer les options
-  } else {
-    if (autoAddCheckbox) {
-      autoAddCheckbox.checked = false;
-    }
-    if (includeStopwordsCheckbox) {
-      includeStopwordsCheckbox.checked = false;
-    }
-    if (autoAddOptions) {
-      autoAddOptions.classList.add("hidden");
-    }
-    if (saveOptionsBtn) {
-      saveOptionsBtn.classList.add("hidden");
-    }
-  }
+  // Ouverture de la page des statistiques
+  // TODO : ajouter l'évènement
+  document.getElementById("open-stats")?.addEventListener("click", () => {
+    window.open("stats.html", "_blank");
+  });
 }
 
-// ==========================
-// Gestion des stoplists
-// ==========================
-document.getElementById("include-stopwords")?.addEventListener("change", async () => {
-  const includeStopwords = document.getElementById("include-stopwords").checked;
-
-  // Si on décoche, on met immédiatement à jour le stockage
-  if (!includeStopwords) {
-    await browser.storage.local.set({ includeStopwords: false });
-    console.log("[Popup] Option 'Inclure mots outils' désactivée immédiatement.");
-    
-    browser.runtime.sendMessage({ command: "update-include-stopwords", includeStopwords: false });
-  }
-});
-
-
-// ==========================
-// Gestion de l'activation/désactivation de l'extension
-// ==========================
-async function updateExtensionToggleButton() {
-  const { accessToken, extensionActive } = await browser.storage.local.get(["accessToken", "extensionActive"]);
-  const toggleButton = document.getElementById("toggleExtensionBtn");
-
-  if (!toggleButton) {
-    console.error("❌ Le bouton d'activation de l'analyse n'a pas été trouvé.");
-    return;
-  }
+// ===========
+//Description de chaque évènement
 
+//Connexion / Déconnexion
+async function handleAuthToggle() {
+  const accessToken = await getAccessToken();
   if (!accessToken) {
-    toggleButton.textContent = "Activer l'analyse";
-    toggleButton.style.opacity = "0.5";
-    toggleButton.title = "Connectez-vous pour activer l'analyse";
+    console.log("🔓 Connexion demandée...");
+    await browser.runtime.sendMessage({ action: "toggleAuth" });
   } else {
-    toggleButton.style.opacity = "1";
-    toggleButton.textContent = extensionActive ? "Désactiver l'analyse" : "Activer l'analyse";
-    toggleButton.title = "";
+    console.log("🔒 Déconnexion demandée...");
+    await browser.storage.local.set({
+      accessToken: null,
+      autoAdd: false,
+      includeStopwords: false,
+      isTrackingActive: false
+    });
+    browser.runtime.sendMessage({
+      command: "update-preferences",
+      autoAdd: false,
+      includeStopwords: false,
+      isTrackingActive: false
+    });
+    console.log("✅ Paramètres réinitialisés après déconnexion.");
   }
+  await updateExtension();
+}
 
-  // Ajout d'un écouteur unique
-  if (!toggleButton.dataset.listenerAdded) {
-    toggleButton.addEventListener("click", handleToggleExtension);
-    toggleButton.dataset.listenerAdded = "true";
+//Statistiques
+async function handleStatsToggle() {
+  const accessToken = await getAccessToken();
+  if (!accessToken) return;
+  // Récupérer l'état actuel des statistiques
+  const { isTrackingActive } = await browser.storage.local.get({ isTrackingActive: false });
+  const newState = !isTrackingActive;
+  // Mise à jour uniquement de `isTrackingActive`
+  await browser.storage.local.set({ isTrackingActive: newState });
+  console.log("📊 Nouvel état des statistiques :", newState);
+  // Envoi du message de mise à jour
+  browser.runtime.sendMessage({ command: "toggle-stats", isActive: newState });
+  // Exécution de Pyodide si nécessaire
+  if (newState) {
+    browser.runtime.sendMessage({ command: "pyodide-simplemma" });
   }
-}
 
-function handleToggleExtension() {
-  getAccessToken().then(accessToken => {
-    if (!accessToken) return;
-    proceedToggleExtension();
-  });
+  if (isUpdatingLexicons) return; 
+  isUpdatingLexicons = true;
+  await updateLexiconsDisplay(); 
+  isUpdatingLexicons = false;
+  await updateExtension();
 }
 
-async function proceedToggleExtension() {
-  const { extensionActive, isTrackingActive } = await browser.storage.local.get({
-    extensionActive: false,
-    isTrackingActive: false
-  });
+// Activer l'extension
+async function handleToggleExtension() {
+  const accessToken = await getAccessToken();
+  if (!accessToken) return;
+
+  const { extensionActive, isTrackingActive } = await browser.storage.local.get({ extensionActive: false, isTrackingActive: false });
   const newState = !extensionActive;
-  await browser.storage.local.set({ extensionActive: newState });
 
-  const toggleButton = document.getElementById("toggleExtensionBtn");
-  if (toggleButton) {
-    toggleButton.textContent = newState ? "Désactiver l'analyse" : "Activer l'analyse";
-  }
+  await browser.storage.local.set({ extensionActive: newState });
 
-  browser.runtime.sendMessage({ action: "toggleExtension", isActive: newState });
-  
   if (!newState) {
     await browser.storage.local.set({ isTrackingActive: false });
-    // Si les statistiques étaient activées, ouvrir la page stats
     if (isTrackingActive) window.open("stats.html", "_blank");
     browser.runtime.sendMessage({ action: "closeSidebarBlocks" });
   }
 
-  await updateOptionsUI();
+  browser.runtime.sendMessage({ action: "toggleExtension", isActive: newState });
+  await updateExtension();
 }
 
-// ==========================
-// Écouteurs d'événements
-// ==========================
-document.addEventListener("DOMContentLoaded", async () => {
-  await updateConnectionButton();
-  await updateOptionsUI();
-  await updateLanguageSelection();
-  await updateExtensionToggleButton();
-});
 
-// Gestion des statistiques et options
-document.getElementById("toggleStatsBtn")?.addEventListener("click", async () => {
-  const accessToken = await getAccessToken();
-  if (!accessToken) return;
+//Ajout automatique
+function handleAutoAddToggle() {
+  const autoAddCheckbox = document.getElementById("auto-add");
+  const autoAddOptions = document.getElementById("auto-add-options");
+  const saveOptionsBtn = document.getElementById("save-options");
 
-  const current = await browser.storage.local.get("isTrackingActive");
-  const newState = !current.isTrackingActive;
-  await browser.storage.local.set({ isTrackingActive: newState });
+  if (!autoAddCheckbox || !autoAddOptions || !saveOptionsBtn) return;
 
-  // Si désactivation, désactiver aussi l'ajout automatique
-  if (!newState) {
-    // Si désactivation, désactiver aussi l'ajout automatique et includeStopwords
-    await browser.storage.local.set({ 
-      autoAdd: false,
-      includeStopwords: false
-    });
-    document.getElementById("auto-add").checked = false;
+  const isAutoAddEnabled = autoAddCheckbox.checked;
+
+  // Juste afficher ou cacher les options, mais ne pas sauvegarder dans le local storage
+  autoAddOptions.classList.toggle("hidden", !isAutoAddEnabled);
+  saveOptionsBtn.classList.toggle("hidden", !isAutoAddEnabled);
+
+  // Si on décoche, désactiver immédiatement et forcer la sauvegarde
+  if (!isAutoAddEnabled) {
+    browser.storage.local.set({ autoAdd: false, includeStopwords: false });
     document.getElementById("include-stopwords").checked = false;
-    document.getElementById("auto-add-options").classList.add("hidden");
-    document.getElementById("save-options").classList.add("hidden");
+    console.log("Ajout automatique désactivé → Stopwords désactivés immédiatement.");
   }
+}
 
-  document.getElementById("toggleStatsBtn").textContent = newState ? "Désactiver les statistiques" : "Activer les statistiques";
-  document.getElementById("stats-options").classList.toggle("hidden", !newState);
 
-  // Envoi du message au background pour le changement de tracking
-  browser.runtime.sendMessage({ command: "toggle-stats", isActive: newState });
-  if (newState) {
-    log("[Popup] Demande d'initialisation de Pyodide et Simplemma");
-    // Garder la commande de file 2 pour l'initialisation de Pyodide/Simplemma
-    browser.runtime.sendMessage({ command: "pyodide-simplemma" });
-  }
-});
+// Gestion de l'activation/désactivation des stopwords
+function handleStopwordsToggle() {
+  const stopwordsCheckbox = document.getElementById("include-stopwords");
+  if (!stopwordsCheckbox) return;
 
-// Gestion du changement de l'option d'ajout automatique
-document.getElementById("auto-add")?.addEventListener("change", async () => {
-  const isChecked = document.getElementById("auto-add").checked;
-  document.getElementById("auto-add-options").classList.toggle("hidden", !isChecked);
-  document.getElementById("save-options").classList.toggle("hidden", !isChecked);
-  if (!isChecked) {
-    log("[Popup] Désactivation de l'ajout automatique -> Désactivation des options");
-    await browser.storage.local.set({ 
-      autoAdd: false,   //Désactiver  l'ajout automatique
-      includeStopwords: false  // Désactiver  includeStopwords
-    });
-    // Mettre à jour l'affichage du bouton
-    document.getElementById("include-stopwords").checked = false;
+  // Si décoché, forcer immédiatement la mise à jour du local storage
+  if (!stopwordsCheckbox.checked) {
+    browser.storage.local.set({ includeStopwords: false });
+    console.log("Stopwords désactivés immédiatement.");
   }
-});
+}
+
+
 
 // Sauvegarde des options utilisateur
-document.getElementById("save-options")?.addEventListener("click", async () => {
-  const autoAdd = document.getElementById("auto-add").checked;
+async function handleSaveOptions() {
+  const autoAddCheckbox = document.getElementById("auto-add");
+  const stopwordsCheckbox = document.getElementById("include-stopwords");
   const threshold = parseInt(document.getElementById("threshold").value, 10);
   const selectedLanguages = Array.from(document.querySelectorAll("#language-selection .lang-option.selected"))
-                                .map(option => option.dataset.value);
-  const includeStopwords = document.getElementById("include-stopwords").checked;
-  
-  // Vérification : si auto-add est activé, au moins une langue doit être sélectionnée
+    .map(option => option.dataset.value);
+
   const errorMessage = document.getElementById("error-message");
-  if (autoAdd && selectedLanguages.length === 0) {
+
+  if (autoAddCheckbox.checked && selectedLanguages.length === 0) {
     errorMessage?.classList.remove("hidden");
     return;
   }
   errorMessage?.classList.add("hidden");
 
+  // Seule la validation met à jour le stockage local
   await browser.storage.local.set({
-    autoAdd,
+    autoAdd: autoAddCheckbox.checked,
+    includeStopwords: stopwordsCheckbox.checked,
     threshold,
-    trackedLanguages: selectedLanguages,
-    includeStopwords
+    trackedLanguages: selectedLanguages
   });
-  log("Options sauvegardées :", { autoAdd, threshold, trackedLanguages: selectedLanguages, includeStopwords});
 
-  // Envoyer les nouvelles préférences au Worker
   browser.runtime.sendMessage({
     command: "update-preferences",
-    autoAdd,
-    threshold,
-    trackedLanguages: selectedLanguages,
-    includeStopwords
+    autoAdd: autoAddCheckbox.checked,
+    includeStopwords: stopwordsCheckbox.checked
   });
 
-});
+  await updateExtension();
+  console.log("✅ Options sauvegardées.");
+}
 
-// Bouton pour ouvrir la page des statistiques
-document.getElementById("open-stats")?.addEventListener("click", async () => {
-  await displayStatsSummary();//résumé dans la console
-  window.open("stats.html", "_blank");
-});
 
-async function displayStatsSummary() {
-  console.log("[Popup] Préparation du résumé des statistiques...");
+//Ouverture de la page des statistiques
 
-  // Récupérer les données stockées
-  const { lemmaFrequencies, trackedLanguages, wordsAdded } = await browser.storage.local.get([
-    "lemmaFrequencies",
-    "trackedLanguages",
-    "wordsAdded"
-  ]);
+// ====================================================================================
+// Fonction actualisation UI des boutons
+// ====================================================================================
 
-  // Initialisation du résumé
-  let summary = {
-    totalWords: 0,           // Nombre total de mots analysés
-    totalUniqueWords: 0,     // Nombre total de mots uniques
-    languages: {},           // Nombre de mots analysés par langue
-    wordsAdded: wordsAdded || {} // Mots ajoutés classés par langue
-  };
+// Gestion de la connexion
+async function updateConnectionButton() {
+  const accessToken = await getAccessToken();
+  //Vérification du bouton de connexion
+  const button = document.getElementById("auth-button");
+  if (!button) {
+    console.error("❌ Le bouton de connexion n'a pas été trouvé.");
+    return;
+  }
+  if (accessToken) {
+    button.textContent = "Se déconnecter";
+    button.style.position = "relative";
+    button.className = "tooltip-container";
+    const tooltip = document.createElement("span");
+    tooltip.className = "tooltip";
+    tooltip.textContent = "En vous déconnectant, vous perdrez l'accès à vos lexiques personnels, ainsi qu'aux fonctionnalités d'ajout automatique et de statistiques d'utilisation.";
+    button.appendChild(tooltip);
+  } else {
+    button.textContent = "Se connecter";
+    button.style.position = "relative";
+    button.className = "tooltip-container";
+    const tooltip = document.createElement("span");
+    tooltip.className = "tooltip";
+    tooltip.textContent = "En vous connectant, vous pourrez accéder à vos lexiques personnels, ainsi qu'aux fonctionnalités d'ajout automatique et de statistiques d'utilisation.";
+    button.appendChild(tooltip);
+  }
+}
 
-  if (lemmaFrequencies) {
-    Object.entries(lemmaFrequencies).forEach(([lang, words]) => {
-      const wordCount = Object.values(words).reduce((sum, count) => sum + count, 0);
-      const uniqueWordCount = Object.keys(words).length;
+// Gestion de la sélection des langues
+async function updateLanguageSelection() {
+  const languageSelection = document.getElementById("language-selection");
+  languageSelection.innerHTML = "<p id='loading-languages' style='color: gray;'>Chargement...</p>";
+
+  const storedData = await browser.storage.local.get("lexicons");
+  const lexicons = storedData.lexicons || []; // Ne pas utiliser JSON.parse()
 
-      // Vérifier si la langue doit être suivie
-      if (!trackedLanguages || trackedLanguages.includes(lang)) {
-        summary.languages[lang] = {
-          totalWords: wordCount,
-          uniqueWords: uniqueWordCount
-        };
+  if (!Array.isArray(lexicons) || lexicons.length === 0) {
+    log("Lexiques non trouvés, attente de la mise à jour...");
+    languageSelection.innerHTML = "<p style='color: gray;'>En attente des lexiques...</p>";
 
-        summary.totalWords += wordCount;
-        summary.totalUniqueWords += uniqueWordCount;
+    // Écouteur pour détecter quand les lexiques sont stockés
+    const listener = (changes, area) => {
+      if (area === "local" && changes.lexicons) {
+        log("Lexiques détectés dans le stockage, mise à jour de la sélection !");
+        browser.storage.onChanged.removeListener(listener);
+        updateLanguageSelection(); // Recharger l'affichage des langues
       }
+    };
+    browser.storage.onChanged.addListener(listener);
+    return;
+  }
+
+  // Extraire les langues uniques
+  const userLanguages = [...new Set(lexicons.map(lex => lex.language))];
+
+  // Récupérer les langues suivies depuis le stockage
+  const { trackedLanguages } = (await browser.storage.local.get("trackedLanguages")) || { trackedLanguages: [] };
+
+  // Affichage des langues sous forme de boutons
+  languageSelection.innerHTML = "";
+  userLanguages.forEach(lang => {
+    const langButton = document.createElement("div");
+    langButton.classList.add("lang-option");
+    langButton.textContent = lang.toUpperCase();
+    langButton.dataset.value = lang;
+
+    if (trackedLanguages && trackedLanguages.includes(lang)) {
+      langButton.classList.add("selected");
+    }
+
+    langButton.addEventListener("click", () => {
+      langButton.classList.toggle("selected");
     });
+
+    languageSelection.appendChild(langButton);
+  });
+
+  log("Sélection des langues mise à jour avec :", userLanguages);
+}
+
+// =========
+// Gestion bouton d'activation de l'extension
+async function updateToggleExtensionButton(isLoggedIn, extensionActive, autoAdd, isTrackingActive, pyodideSimplemmaReady, includeStopwords) {
+  const toggleExtensionBtn = document.getElementById("toggleExtensionBtn");
+
+  if (toggleExtensionBtn) {
+    toggleExtensionBtn.textContent = extensionActive ? "Désactiver l'analyse" : "Activer l'analyse";
+    toggleExtensionBtn.style.pointerEvents = isLoggedIn ? "auto" : "none";
+    toggleExtensionBtn.disabled = !isLoggedIn;
+    toggleExtensionBtn.style.position = "relative";
+    toggleExtensionBtn.className = "tooltip-container";
+
+    const existingTooltipExt = toggleExtensionBtn.querySelector('.tooltip');
+    if (existingTooltipExt) {
+      existingTooltipExt.remove();
+    }
+    const tooltipExt = document.createElement("span");
+    tooltipExt.className = "tooltip";
+    tooltipExt.style.opacity = "1 !important";
+    if (!isLoggedIn) {
+      tooltipExt.textContent = "Connectez-vous pour activer l'analyse";
+      tooltipExt.style.display = "block";
+    } else if (!extensionActive) {
+      tooltipExt.textContent = "Activer les fonctionnalités de l'extension : affichage des mots et des définitions de vos lexiques, ajout de mots, etc.";
+      tooltipExt.style.display = "block";
+    } else {
+      tooltipExt.style.display = "none";
+    }
+    toggleExtensionBtn.appendChild(tooltipExt);
+  }
+
+  // Mise à jour des options de statistiques
+  const statsOptions = document.getElementById("stats-options");
+  const toggleStatsBtn = document.getElementById("toggleStatsBtn");
+  const openStats = document.getElementById("open-stats");
+  if (statsOptions) {
+    statsOptions.style.display = (isLoggedIn && extensionActive) ? "block" : "none";
+  }
+
+  // Mise à jour du bouton des statistiques
+  if (toggleStatsBtn) {
+    const isEnabled = isLoggedIn && extensionActive;
+    toggleStatsBtn.textContent = isEnabled && isTrackingActive ? "Désactiver les statistiques" : "Activer les statistiques";
+    toggleStatsBtn.style.pointerEvents = isEnabled ? "auto" : "none";
+    toggleStatsBtn.disabled = !isEnabled;
+    toggleStatsBtn.style.position = "relative";
+    toggleStatsBtn.className = "tooltip-container";
+    const existingTooltipStats = toggleStatsBtn.querySelector('.tooltip');
+    if (existingTooltipStats) { existingTooltipStats.remove(); }
+    const tooltipStats = document.createElement("span");
+    tooltipStats.className = "tooltip";
+    tooltipStats.style.opacity = "1 !important";
+    if (!isLoggedIn) {
+      tooltipStats.textContent = "Connectez-vous pour accéder aux statistiques";
+      tooltipStats.style.display = "block";
+    } else if (!extensionActive) {
+      tooltipStats.textContent = "Veuillez activer l'analyse pour utiliser les statistiques";
+      tooltipStats.style.display = "block";
+    } else {
+      tooltipStats.style.display = "none";
+    }
+    toggleStatsBtn.appendChild(tooltipStats);
+  }
+  if (openStats) {
+    openStats.style.display = (isLoggedIn && extensionActive && isTrackingActive) ? "block" : "none";
+  }
+
+  // Mise à jour des options d'ajout automatique
+  const autoAddContainer = document.getElementById("auto-add")?.parentElement;
+  const autoAddCheckbox = document.getElementById("auto-add");
+  const autoAddOptions = document.getElementById("auto-add-options");
+  const saveOptionsBtn = document.getElementById("save-options");
+
+  if (autoAddContainer) {
+    autoAddContainer.style.display = (isLoggedIn && extensionActive) ? "block" : "none";
+  }
+  if (autoAddCheckbox && isLoggedIn) {
+    autoAddCheckbox.checked = autoAdd;
+  }
+  if (autoAddOptions) {
+    autoAddOptions.classList.toggle("hidden", !autoAdd);
+  }
+  if (saveOptionsBtn) {
+    saveOptionsBtn.classList.toggle("hidden", !autoAdd);
+  }
+
+  // Mise à jour du message de chargement Pyodide
+  const statusContainer = document.getElementById('pyodide-loading');
+  if (statusContainer) {
+    if (!isLoggedIn) {
+      statusContainer.innerHTML = "";
+    } else if (!pyodideSimplemmaReady && extensionActive && isTrackingActive) {
+      statusContainer.innerHTML = "<p style='color: black; text-align: center; font-size: 11px;'>Chargement de l'extension en cours, veuillez patienter...</p>";
+    } else if (pyodideSimplemmaReady && extensionActive && isTrackingActive) {
+      statusContainer.innerHTML = "<p style='color: black; text-align: center; font-size: 11px;'>C'est prêt !</p>";
+      setTimeout(() => {
+        statusContainer.innerHTML = "";
+      }, 2000);
+    } else {
+      statusContainer.innerHTML = "";
+    }
   }
 
-  console.log("[Popup] Résumé des statistiques mis à jour:", summary);
+  // Mise à jour de la sélection des langues
+  await updateLanguageSelection();
+
+  log("Interface mise à jour complètement", {
+    isLoggedIn,
+    extensionActive,
+    isTrackingActive,
+    autoAdd,
+    pyodideSimplemmaReady,
+    includeStopwords
+  });
+}
 
-  // Résumé dans le local storage
-  await browser.storage.local.set({ statsSummary: summary });
+//Activer/désactiver les stoplists
+async function updateStopwordsOption(includeStopwords) {
+  const stopwordsCheckbox = document.getElementById("include-stopwords");
+  if (stopwordsCheckbox) {
+    stopwordsCheckbox.checked = includeStopwords;
+  }
 }
 
 
 
+// ✅ Actualisation de l'UI au chargement de la page
+document.addEventListener("DOMContentLoaded", async () => {
+  await updateExtension(); // Mise à jour de l'extension selon les valeurs du local storage
+  setupEventListeners(); // Configuration des écouteurs d'événements
+});
+
+// !! boucle infinie ???
+// // Actualisation de l'UI en cas de changement dans le stockage local : ça c'est dans background qu'il faut le mettre xd
+// browser.storage.onChanged.addListener((changes, area) => {
+//   if (area === "local" && changes.accessToken) {
+//     updateExtension();
+//   }
+// });
+
 // ==========================
-// Réception des messages du background
+// Gestion des messages et du stockage
 // ==========================
 browser.runtime.onMessage.addListener(async (message) => {
   log("📩 Message reçu dans popup.js :", message);
-
   if (message.action === "updateUI") {
-    log("🔄 Mise à jour de l'UI du popup...");
-    await updateConnectionButton();
-    await updateOptionsUI();
-    await updateLanguageSelection();
-    // Possibilité de mettre à jour d'autres éléments via le message
-  } else if (message.action === "showNotification") {
-    // Gestion des notifications si besoin
-    showNotification(message.text);
+    await updateExtension();
+  } else if (message.action === "notify") {
+    alert(message.message);
   }
 });
 
-// Actualisation de l'UI en cas de changement dans le stockage local
 browser.storage.onChanged.addListener((changes, area) => {
-  if (area === "local" && changes.accessToken) {
-    updateConnectionButton();
-    updateExtensionToggleButton();
+  if (area === "local") {
+    updateExtension();
   }
 });
 
 // ==========================
-// Gestion de l'affichage de notifications (optionnelle)
+// Gestion des notifications
 // ==========================
 function showNotification(message) {
   const notificationBox = document.getElementById("extension-notification");
@@ -451,6 +495,83 @@ function showNotification(message) {
       notificationBox.classList.add("hidden");
     }, { once: true });
   } else {
-    console.error("❌ Impossible d'afficher la notification : élément manquant.");
+    log("❌ Impossible d'afficher la notification : élément manquant.");
   }
 }
+
+function handleWorkerMessage(event) {
+  const data = event.data;
+  log("[Background] Message du WebWorker :", data);
+  
+  if (data.type === "process-text" && data.status === "error") {
+    browser.runtime.sendMessage({
+      action: "notify",
+      message: data.message
+    });
+    return;
+  }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// // Bouton pour ouvrir la page des statistiques
+// document.getElementById("open-stats")?.addEventListener("click", async () => {
+//   await displayStatsSummary();//résumé dans la console
+//   window.open("stats.html", "_blank");
+// });
+
+// async function displayStatsSummary() {
+//   console.log("[Popup] Préparation du résumé des statistiques...");
+
+//   // Récupérer les données stockées
+//   const { lemmaFrequencies, trackedLanguages, wordsAdded } = await browser.storage.local.get([
+//     "lemmaFrequencies",
+//     "trackedLanguages",
+//     "wordsAdded"
+//   ]);
+
+//   // Initialisation du résumé
+//   let summary = {
+//     totalWords: 0,           // Nombre total de mots analysés
+//     totalUniqueWords: 0,     // Nombre total de mots uniques
+//     languages: {},           // Nombre de mots analysés par langue
+//     wordsAdded: wordsAdded || {} // Mots ajoutés classés par langue
+//   };
+
+//   if (lemmaFrequencies) {
+//     Object.entries(lemmaFrequencies).forEach(([lang, words]) => {
+//       const wordCount = Object.values(words).reduce((sum, count) => sum + count, 0);
+//       const uniqueWordCount = Object.keys(words).length;
+
+//       // Vérifier si la langue doit être suivie
+//       if (!trackedLanguages || trackedLanguages.includes(lang)) {
+//         summary.languages[lang] = {
+//           totalWords: wordCount,
+//           uniqueWords: uniqueWordCount
+//         };
+
+//         summary.totalWords += wordCount;
+//         summary.totalUniqueWords += uniqueWordCount;
+//       }
+//     });
+//   }
+
+//   console.log("[Popup] Résumé des statistiques mis à jour:", summary);
+
+//   // Résumé dans le local storage
+//   await browser.storage.local.set({ statsSummary: summary });
+// }
diff --git a/src/sidebar/sidebar.html b/src/sidebar/sidebar.html
index daea55d..99ef99e 100644
--- a/src/sidebar/sidebar.html
+++ b/src/sidebar/sidebar.html
@@ -54,7 +54,7 @@
       width: auto;
       display: inline-flex;
       padding: 6px 12px;
-      font-size: 18px;
+      font-size: 16px;
       font-family: Luciole;
       background: none;
       border: none;
@@ -150,7 +150,7 @@
       font-weight: bold;
       color: #323046;
       flex-grow: 1;
-      font-size: 15px;
+      font-size: 12px;
       text-align: center;
     }
 
@@ -183,7 +183,7 @@
       transform: translateX(-50%);
       background-color: rgba(0,0,0,0.75);
       color: #fff;
-      font-size: 14px !important;
+      font-size: 12px !important;
       font-weight: lighter !important;
       padding: 6px 10px;
       border-radius: 5px;
@@ -259,6 +259,8 @@
       transition: filter 0.3s ease-in-out;
     }
 
+    /* Ajout de la classe active */
+    .lexique-highlight-toggle.active .feutre-icon,
     .lexique-highlight-toggle[data-active="true"] .feutre-icon {
       filter: brightness(0) saturate(100%) invert(83%) sepia(89%) saturate(588%) hue-rotate(360deg);
     }
@@ -293,6 +295,31 @@
       transform: translateX(-50%) translateY(-5px);
     }
 
+    .lexicon-highlight {
+      position: relative;           /* Pour positionner le conteneur de bandes en absolu */
+      display: inline-block;        /* Pour que le span prenne en compte les dimensions */
+      padding-bottom: 4px;          /* Laisser de l'espace pour les bandes */
+      border-bottom: 1px dashed #666; /* Vous pouvez conserver votre bordure si besoin */
+      transition: background-color 0.3s;
+      background-color: rgba(255, 255, 0, 0.15);
+
+    }
+
+    .color-bands {
+      position: absolute;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      height: 3px;      /* Ajustez la hauteur des bandes */
+      display: flex;    /* Pour répartir équitablement les bandes */
+    }
+
+    .color-bands div {
+      flex: 1;          /* Chaque bande occupe une part égale */
+      height: 100%;
+    }
+
+
     .lexicon-section {
       margin-bottom: 10px;
     }
@@ -379,6 +406,11 @@
       color: red !important;
       font-weight: bold;
     }
+    #messageContainer {
+      display: none;
+      text-align: center;
+      color: #323046;
+    }
   </style>
 </head>
 <body>
@@ -452,7 +484,7 @@
         <h4>🌍 Wiktionnaire</h4>
         <ul id="wiktionnaireList"></ul>
       </div>
-
+      
       <!-- Fenêtre modale cachée -->
       <div id="modalOverlay" class="modal-overlay">
         <div class="modal-content">
@@ -463,5 +495,10 @@
     </div>
   </div>
 
+  <!-- Bloc 4 : Message d'analyse désactivée -->
+  <div id="messageContainer">
+    <p id="analysisMessage"></p>
+  </div>
+
 </body>
 </html>
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index 48b3e37..fd75670 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -10,6 +10,7 @@ log(
 // ─────────────────────────────────────────────────────────────────────────────
 let authToken = window.authToken;
 window.authToken = authToken;
+let isUpdatingLexicons = false;
 
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Fonctions liées au token
@@ -37,17 +38,12 @@ function updateAuthButton(isLoggedIn) {
   const authButton = document.getElementById("auth-button");
   if (authButton) {
     authButton.textContent = isLoggedIn ? "Se déconnecter" : "Se connecter";
-    authButton.title = isLoggedIn
-      ? "En vous déconnectant, vous perdrez l'accès à vos lexiques personnels ainsi qu'aux fonctionnalités d'ajout automatique et de statistiques d'utilisation."
-      : "En vous connectant, vous pourrez accéder à vos lexiques personnels ainsi qu'aux fonctionnalités d'ajout automatique et de statistiques d'utilisation.";
     log("🔄 Bouton d'authentification mis à jour :", authButton.textContent);
   } else {
     console.warn("⚠️ Bouton d'authentification (#auth-button) introuvable.");
   }
 }
 
-
-
 function toggleElementsVisibility(isLoggedIn) {
   const elementsToShowOrHide = [
     { id: "add-to-lexiques", shouldShow: isLoggedIn },
@@ -85,7 +81,11 @@ async function refreshSidebarState() {
   toggleElementsVisibility(isLoggedIn);
   toggleHighlightMessage(isLoggedIn);
 
+  const isAnalysisEnabled = await checkAnalysisStatus();
+
   if (isLoggedIn) {
+    hideBlocks(!isAnalysisEnabled);
+
     if (!window.lexiconColorsUpdated) {
       await updateLexiconColors(authToken);
       window.lexiconColorsUpdated = true;
@@ -93,18 +93,8 @@ async function refreshSidebarState() {
     await fetchLexicons();
   } else {
     // Si l'utilisateur n'est pas connecté, on ferme tous les blocs
-    document.querySelectorAll('.block-content').forEach(block => {
-      block.classList.add('hidden');
-      // Mise à jour des boutons de bascule associés pour afficher le symbole "+"
-      const header = block.previousElementSibling;
-      if (header) {
-        const toggleBtn = header.querySelector(".toggle-btn");
-        if (toggleBtn) {
-          toggleBtn.textContent = '+';
-        }
-      }
-    });
-    
+    hideBlocks(true); // Masquer tous les blocs
+
     const lexiquesContainer = document.getElementById("lexiques");
     if (lexiquesContainer) {
       lexiquesContainer.textContent = "Veuillez vous connecter pour voir vos lexiques.";
@@ -117,12 +107,30 @@ async function refreshSidebarState() {
     }
   }
 
+  // Afficher un message d'activation de l'analyse selon le statut de connexion
+  const messageContainer = document.getElementById("messageContainer");
+  if (!isLoggedIn) {
+    if (messageContainer) {
+      messageContainer.style.display = "block";
+      messageContainer.innerHTML = "Veuillez vous connecter pour utiliser l'extension.";
+    }
+  } else if (!isAnalysisEnabled) {
+    if (messageContainer) {
+      messageContainer.style.display = "block";
+      messageContainer.innerHTML = "L'analyse est <strong>désactivée</strong>.<br>Pour utiliser l'extension, cliquez sur le bouton <strong>Activer l'analyse</strong> dans le menu d'extension.";
+    }
+  } else {
+    if (messageContainer) {
+      messageContainer.style.display = "none"; 
+    }
+  }
+
   log("✅ Barre latérale actualisée. Utilisateur connecté :", isLoggedIn);
 }
 
 /**
- * Bascule l’affichage d’un bloc.
- * @param {string} blockId - L’ID du conteneur à basculer.
+ * Bascule l'affichage d'un bloc.
+ * @param {string} blockId - L'ID du conteneur à basculer.
  * @param {HTMLElement} btn - Le bouton qui déclenche la bascule, pour mettre à jour son texte.
  */
 function toggleBlock(blockId, btn) {
@@ -139,8 +147,8 @@ function toggleBlock(blockId, btn) {
 }
 
 /**
- * Ouvre un bloc s’il est fermé et met à jour le bouton de bascule.
- * @param {string} blockId - L’ID du conteneur à ouvrir.
+ * Ouvre un bloc s'il est fermé et met à jour le bouton de bascule.
+ * @param {string} blockId - L'ID du conteneur à ouvrir.
  * @param {HTMLElement} [btn] - (Optionnel) Le bouton de bascule à mettre à jour.
  */
 function openBlock(blockId, btn) {
@@ -181,6 +189,19 @@ function closeBlock(blockId, btn) {
   }
 }
 
+function hideBlocks(shouldHide) {
+  const blockIds = ["menu", "etat", "definitionContainer"];
+  blockIds.forEach(blockId => {
+    const block = document.getElementById(blockId);
+    if (block) {
+      if (shouldHide) {
+        block.classList.add("hidden"); // Masquer le bloc
+      } else {
+        block.classList.remove("hidden"); // Afficher le bloc
+      }
+    }
+  });
+}
 
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Gestion des lexiques (Affichage)
@@ -222,7 +243,7 @@ async function fetchLexicons() {
       lexiconMap.set(lex.id, lexiconName);
     });
 
-    displayLexiconsWithCheckbox(lexicons.map((lex) => ({
+    await displayLexiconsWithCheckbox(lexicons.map((lex) => ({
       lexiconName:
         lex.category === "User"
           ? DEBUG
@@ -234,8 +255,11 @@ async function fetchLexicons() {
       lexiconId: lex.id,
       active: lex.active || false,
     })));
+    
+    // Restaurer l'état des boutons après l'affichage
+    await restoreHighlightingState();
   } catch (error) {
-    console.error("❌ Erreur lors du chargement des lexiques :", error.message);
+    log("❌ Erreur lors du chargement des lexiques :", error.message);
     const lexiquesContainer = document.getElementById("lexiques");
     if (lexiquesContainer) {
       lexiquesContainer.textContent = error.message || "Erreur lors du chargement des lexiques.";
@@ -261,6 +285,10 @@ async function displayLexiconsWithCheckbox(lexicons) {
   }
   
   for (const { lexiconName, lexiconId, active } of lexicons) {
+    if (lexiquesContainer.querySelector(`div[data-lexicon-id="${lexiconId}"]`)) {
+      continue; // Si oui, passez à l'itération suivante
+    }
+    
     const lexiqueDiv = document.createElement("div");
     lexiqueDiv.className = "lexique-item";
     
@@ -291,6 +319,9 @@ async function displayLexiconsWithCheckbox(lexicons) {
     // Conteneur pour le bouton de surlignage (avec tooltip)
     const highlightButton = document.createElement("button");
     highlightButton.className = "tooltip-container lexique-highlight-toggle";
+    if (active) {
+      highlightButton.classList.add('active');
+    }
     highlightButton.dataset.lexiconId = lexiconId;
     highlightButton.dataset.active = active ? "true" : "false";
     const feutreIcon = document.createElement("img");
@@ -301,19 +332,21 @@ async function displayLexiconsWithCheckbox(lexicons) {
     highlightTooltip.className = "tooltip";
     highlightTooltip.textContent = "Activer/Désactiver le surlignage des mots du lexique";
     
-    // Gestion du clic pour activer/désactiver le surlignage
+    // Mise à jour du gestionnaire d'événements
     highlightButton.addEventListener("click", async () => {
       let currentState = highlightButton.dataset.active === "true";
       let newState = !currentState;
       try {
-        await browser.runtime.sendMessage({
-          action: "toggleLexiconHighlight",
-          lexiconId,
-          isActive: newState,
-        });
+        await toggleLexiconHighlight(lexiconId, newState);
         highlightButton.dataset.active = newState ? "true" : "false";
+        highlightButton.classList.toggle("active", newState);
+        
+        // Sauvegarder l'état dans le storage local
+        const activeLexicons = Array.from(document.querySelectorAll('.lexique-highlight-toggle[data-active="true"]'))
+          .map(btn => parseInt(btn.dataset.lexiconId));
+        await browser.storage.local.set({ activeLexicons });
       } catch (error) {
-        console.error("Erreur lors du toggle de surlignage pour le lexique", lexiconId, ":", error);
+        log("Erreur lors du toggle de surlignage pour le lexique", lexiconId, ":", error);
       }
     });
     
@@ -323,7 +356,6 @@ async function displayLexiconsWithCheckbox(lexicons) {
     lexiqueDiv.appendChild(labelSpan);
     lexiqueDiv.appendChild(checkboxContainer);
     lexiqueDiv.appendChild(highlightButton);
-    
     lexiquesContainer.appendChild(lexiqueDiv);
   }
   
@@ -351,6 +383,35 @@ async function displayLexiconsWithCheckbox(lexicons) {
   }, 100);
 }
 
+async function updateLexiconsDisplay() {
+  const token = await getAuthTokenFromStorage(); // Récupérer le token d'authentification
+  if (!token) {
+    console.warn("⚠️ Aucun token d'authentification disponible.");
+    return;
+  }
+
+  const lexicons = await getLexicons(token); // Récupérer les lexiques
+  await displayLexiconsWithCheckbox(lexicons); // Mettre à jour l'affichage des lexiques
+}
+
+// Ajouter une fonction pour restaurer l'état des boutons au chargement
+async function restoreHighlightingState() {
+  try {
+    const { activeLexicons } = await browser.storage.local.get("activeLexicons");
+    if (activeLexicons && Array.isArray(activeLexicons)) {
+      const buttons = document.querySelectorAll('.lexique-highlight-toggle');
+      buttons.forEach(button => {
+        const lexiconId = parseInt(button.dataset.lexiconId);
+        const isActive = activeLexicons.includes(lexiconId);
+        button.dataset.active = isActive ? "true" : "false";
+        button.classList.toggle("active", isActive);
+      });
+    }
+  } catch (error) {
+    log("Erreur lors de la restauration de l'état des boutons:", error);
+  }
+}
+
 function initModal() {
   log("initModal appelé");
   const modalOverlay = document.getElementById("modalOverlay");
@@ -360,7 +421,7 @@ function initModal() {
   log("closeModalBtn =", closeModalBtn);
 
   if (!modalOverlay || !modalFullText || !closeModalBtn) {
-    console.error("Les éléments modaux ne sont pas trouvés !");
+    log("Les éléments modaux ne sont pas trouvés !");
     return;
   }
 
@@ -381,6 +442,11 @@ document.addEventListener("DOMContentLoaded", initModal);
 async function handleAuthButtonClick() {
   await browser.runtime.sendMessage({ action: "toggleAuth" });
   await refreshSidebarState();
+  const messageContainer = document.getElementById("messageContainer");
+  if (messageContainer) {
+    messageContainer.style.display = "block";
+    messageContainer.innerHTML = "Veuillez vous connecter pour utiliser l'extension.";
+  }
 }
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -418,12 +484,12 @@ async function handleAddWordClick() {
     return;
   }
 
-  // 3) Vérifier si le mot existe déjà dans l’un des lexiques sélectionnés
+  // 3) Vérifier si le mot existe déjà dans l'un des lexiques sélectionnés
   let definitions = [];
   try {
     definitions = await fetchLexiconDefinitions(selectedWord);
   } catch (error) {
-    console.error("Erreur lors de la récupération des définitions pour vérification :", error);
+    log("Erreur lors de la récupération des définitions pour vérification :", error);
   }
 
   const existingLexiconIds = new Set();
@@ -435,22 +501,31 @@ async function handleAddWordClick() {
     }
   }
 
-  // 4) Si le mot existe déjà dans certains lexiques, on les affiche
+  // 4) Déterminer les lexiques où ajouter le mot (ceux qui n'ont pas déjà le mot)
+  const lexiconsToAdd = selectedLexiconIds.filter(id => !existingLexiconIds.has(id));
+
+  // Si le mot existe déjà dans certains lexiques, on affiche le message
   if (existingLexiconIds.size > 0) {
+    const existingLexiconsNames = Array.from(existingLexiconIds)
+      .map(id => lexiconMap.get(id) || id)
+      .join(", ");
     if (lexiconResultElement) {
       lexiconResultElement.innerHTML =
         "Le mot <strong>" + selectedWord + "</strong> existe déjà dans le(s) lexique(s) : " +
-        Array.from(existingLexiconIds).join(", ") + ".";
+        "<strong>" + existingLexiconsNames + "</strong>.";
     }
   }
 
-  // 5) Déterminer les lexiques où ajouter le mot
-  const lexiconsToAdd = selectedLexiconIds.filter(id => !existingLexiconIds.has(id));
   if (lexiconsToAdd.length === 0) {
     return; 
   }
 
-  // 6) Envoi d’une seule requête pour tous les lexiques restants
+  // Construction du message de succès avec les noms des lexiques où le mot va être ajouté
+  const lexiconsNames = lexiconsToAdd
+    .map(id => lexiconMap.get(id) || id)
+    .join(", ");
+
+  // 5) Envoi d'une seule requête pour tous les lexiques restants
   try {
     log(`📡 Envoi de l'ajout du mot "${selectedWord}" dans les lexiques :`, lexiconsToAdd);
     const result = await window.AddWord(authToken, selectedWord, lexiconsToAdd, false);
@@ -461,115 +536,158 @@ async function handleAddWordClick() {
     await new Promise(resolve => setTimeout(resolve, 300));
     browser.runtime.sendMessage({ action: "refreshUI" });
 
-    // 7) Affichage du message de succès
+    // 6) Affichage du message de succès
     if (lexiconResultElement) {
       lexiconResultElement.innerHTML +=
         "<br>✅ Mot <strong>" + selectedWord + "</strong> ajouté avec succès dans : " +
-        lexiconsToAdd.join(", ") + ".";
+        lexiconsNames + ".";
     }
 
   } catch (error) {
-    console.error("Erreur lors de l’ajout du mot :", error);
+    log("Erreur lors de l'ajout du mot :", error);
     if (lexiconResultElement) {
-      lexiconResultElement.textContent = "Erreur lors de l’ajout : " + error.message;
+      lexiconResultElement.textContent = "Erreur lors de l'ajout : " + error.message;
     }
   }
 }
 
+
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Réception des messages
 // ─────────────────────────────────────────────────────────────────────────────
 browser.runtime.onMessage.addListener(async (message) => {
   log("📩 Message reçu dans sidebar.js :", message);
-  switch (message.action) {
-    case "refreshUI":
-      log("🔄 Demande de rafraîchissement de la barre latérale.");
-      await refreshSidebarState();
-      break;
-
-    case "mot_selectionne":
-      if (message.selectedText) {
-        log("🖋️ Mot sélectionné :", message.selectedText);
-        const selectedWordElement = document.getElementById("motSelectionne");
-        if (selectedWordElement) {
-          selectedWordElement.textContent = message.selectedText;
-        } else {
-          console.warn("⚠️ Élément #motSelectionne introuvable.");
-        }
-        const lexiconResultElement = document.getElementById("lexiconResult");
-        if (lexiconResultElement) {
-          lexiconResultElement.innerHTML = "";
+  
+  if (message.action)
+    switch (message.action) {
+      case "refreshUI":
+        log("🔄 Demande de rafraîchissement de la barre latérale.");
+        await refreshSidebarState();
+        break;
+
+      case "mot_selectionne":
+        if (message.selectedText) {
+          log("🖋️ Mot sélectionné :", message.selectedText);
+          const selectedWordElement = document.getElementById("motSelectionne");
+          if (selectedWordElement) {
+            selectedWordElement.textContent = message.selectedText;
+          } else {
+            console.warn("⚠️ Élément #motSelectionne introuvable.");
+          }
+          const lexiconResultElement = document.getElementById("lexiconResult");
+          if (lexiconResultElement) {
+            lexiconResultElement.innerHTML = "";
+          }
+          openBlock("etatContent");
         }
-        openBlock("etatContent");
-      }
-      break;
+        break;
 
-    case "getDefinition":
-      if (message.selectedText) {
-        log("📖 Recherche des définitions pour :", message.selectedText);
-        openBlock("definitionContent");
-        await window.showDefinitions(message.selectedText);
-      }
-      break;
+      case "getDefinition":
+        if (message.selectedText) {
+          log("📖 Recherche des définitions pour :", message.selectedText);
+          openBlock("definitionContent");
+          await window.showDefinitions(message.selectedText);
+        }
+        break;
 
-    case "showDefinitions":
-      if (Array.isArray(message.definitions)) {
-        window.displayDefinitions(message.definitions);
-      }
-      break;
+      case "showDefinitions":
+        if (Array.isArray(message.definitions)) {
+          window.displayDefinitions(message.definitions);
+        }
+        break;
 
-    case "fetchWiktionaryDefinitionResponse":
-      if (message.selectedText) {
-        log(`📖 Réception de la définition du Wiktionnaire pour '${message.selectedText}'`);
-        window.displayDefinitions(message.definitions);
-      }
-      break;
+      case "fetchWiktionaryDefinitionResponse":
+        if (message.selectedText) {
+          log(`📖 Réception de la définition du Wiktionnaire pour '${message.selectedText}'`);
+          window.displayDefinitions(message.definitions);
+        }
+        break;
 
-    case "showLexiconResult":
-      log("📚 Résultat des lexiques reçus :", message.lexicons);
-      window.displayLexiconResults(message.lexicons);
-      break;
-    
-    case "addWordResult":
-      const lexiconResultElement = document.getElementById("lexiconResult");
-      if (lexiconResultElement) {
-        lexiconResultElement.innerHTML = message.lexicons;
-      }
-      break;
+      case "showLexiconResult":
+        log("📚 Résultat des lexiques reçus :", message.lexicons);
+        window.displayLexiconResults(message.lexicons);
+        break;
+      
+      case "addWordResult":
+        const lexiconResultElement = document.getElementById("lexiconResult");
+        if (lexiconResultElement) {
+          lexiconResultElement.innerHTML = message.lexicons;
+        }
+        break;
 
-    case "addToLexicon":
-      handleAddWordClick();
-      break;
-    
-    case "openLexiconBlock":
-      openBlock("menuContent");
-      break;
+      case "addToLexicon":
+        handleAddWordClick();
+        break;
       
-    case "toggleAuth":
-      break;
+      case "openLexiconBlock":
+        openBlock("menuContent");
+        break;
+        
+      case "toggleAuth":
+        break;
+
+      case "authStatusChanged":
+        break;
+
+      case "updateUI":
+        if (!message.extensionActive) {
+          // Fermer tous les blocs
+          hideBlocks(true);
+        } else {
+          hideBlocks(false);
+          await refreshSidebarState();
+        }
+        break;
 
-    case "authStatusChanged":
-      break;
+      case "pyodide-simplemma-ready":
+        return;
 
-    case "updateUI":
-      await refreshSidebarState();
-      break;
+      case "saveToken":
+        authToken = message.token;
+        break;
 
-    case "pyodide-simplemma-ready":
-      return;
+      case "closeSidebarBlocks":
+        hideBlocks(true);
+        break;
+    }
 
-    case "saveToken":
-      authToken = message.token;
-      break;
+  if (message.command) {
+    switch (message.command) {
+      case "activate-highlighting":
+        const highlightButton = document.querySelector(`button[data-lexicon-id="${message.lexiconId}"]`);
+        if (highlightButton) {
+          highlightButton.dataset.active = "true";
+          highlightButton.classList.add("active");
+        }
+        break;
+        
+      case "deactivate-highlighting":
+        const highlightButtonOff = document.querySelector(`button[data-lexicon-id="${message.lexiconId}"]`);
+        if (highlightButtonOff) {
+          highlightButtonOff.dataset.active = "false";
+          highlightButtonOff.classList.remove("active");
+        }
+        break;
 
-    case "closeSidebarBlocks":
-      closeBlock("menuContent");
-      closeBlock("etatContent");
-      closeBlock("definitionContent")
-      break;
+      case "register-stats-script":
+        break;
 
-    default:
-      console.warn("⚠️ Action inconnue reçue :", message.action);
+      case "register-highlighting-script":
+        log("✅ Script de surlignage enregistré");
+        browser.runtime.sendMessage({ 
+          command: "updateAuthToken", 
+          token: authToken 
+        });
+        break;
+
+      case "updateAuthToken":
+        authToken = message.token;
+        window.authToken = message.token;
+        break;
+
+      default:
+        console.warn("⚠️ Action inconnue reçue :", message.command);
+    }
   }
 });
 
@@ -578,7 +696,6 @@ browser.runtime.onMessage.addListener(async (message) => {
 // ─────────────────────────────────────────────────────────────────────────────
 document.addEventListener("DOMContentLoaded", async () => {
   log("📦 DOM entièrement chargé. Initialisation de la sidebar.");
-  
   authToken = await getAuthTokenFromStorage();
   window.authToken = authToken;
   await refreshSidebarState();
@@ -606,7 +723,7 @@ document.addEventListener("DOMContentLoaded", async () => {
     chercherDefButton.style.visibility = "visible";
     chercherDefButton.disabled = false;
   } else {
-    console.error("❌ ERREUR : Bouton #chercherDef introuvable.");
+    log("❌ ERREUR : Bouton #chercherDef introuvable.");
   }
 
   // Écouteur pour la case à cocher "toggle-definitions"
@@ -683,3 +800,29 @@ document.addEventListener("DOMContentLoaded", async () => {
       }
     });
   });
+
+async function toggleLexiconHighlight(lexiconId, isActive) {
+  try {
+    const button = document.querySelector(`button[data-lexicon-id="${lexiconId}"]`);
+    if (button) {
+      button.dataset.active = isActive.toString();
+      button.classList.toggle('active', isActive);
+    }
+
+    await browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
+      browser.tabs.sendMessage(tabs[0].id, {
+        command: isActive ? "activate-highlighting" : "deactivate-highlighting",
+        lexiconId: lexiconId
+      });
+    });
+
+    log(`✅ Surlignage ${isActive ? 'activé' : 'désactivé'} pour le lexique ${lexiconId}`);
+  } catch (error) {
+    log(`❌ Erreur lors du toggle du surlignage pour le lexique ${lexiconId}:`, error);
+  }
+}
+
+async function checkAnalysisStatus() {
+    const { extensionActive } = await browser.storage.local.get("extensionActive");
+    return extensionActive; // Retourne true si l'analyse est activée, sinon false
+}
diff --git a/src/utils/api.js b/src/utils/api.js
index e32d858..5869525 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -15,7 +15,7 @@ document.addEventListener("mouseup", () => {
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
-// ▌ Fonction utilitaire pour appeler l’API
+// ▌ Fonction utilitaire pour appeler l'API
 // ─────────────────────────────────────────────────────────────────────────────
 /**
  * Effectue une requête API (GET, POST, etc.) avec ou sans body JSON
@@ -44,7 +44,7 @@ async function callApi(url, authToken = null, method = 'GET', data = null) {
     }
     return await response.json();
   } catch (error) {
-    console.error(`🚨 Erreur lors de l'appel API [${url}]:`, error);
+    log(`🚨 Erreur lors de l'appel API [${url}]:`, error);
     throw error;
   }
 }
@@ -54,69 +54,17 @@ async function callApi(url, authToken = null, method = 'GET', data = null) {
 // ─────────────────────────────────────────────────────────────────────────────
 
 /**
- * Récupère les lexiques de l’utilisateur,
- * en langue par défaut "fr".
+ * Récupère les lexiques de l'utilisateur
  * 
  * @param {string} authToken - Le token d'authentification.
  * @returns {Promise<any[]>} - Liste des lexiques trouvés.
  */
 async function getLexicons(authToken) {
-  // Vérifier si les lexiques sont déjà en cache
-  const { lexicons } = await browser.storage.local.get("lexicons");
-  if (Array.isArray(lexicons) && lexicons.length > 0) {
-    //console.log("Lexiques récupérés depuis le cache local :", lexicons); todo: ajouter condition car elle renvoie plusieurs fois la réponse dans la console
-    return lexicons; // Retourne les lexiques en cache pour éviter une requête API inutile
-  }
-
   const url = "https://babalex.lezinter.net/api/lexicon/search";
 
-  try {
-    const response = await callApi(url, authToken);
-    console.log("✅ Réponse de getLexicons :", response);
-
-    if (Array.isArray(response) && response.length > 0) {
-      await browser.storage.local.set({ lexicons: response }); // Stocker en cache
-    }
-
-    return response;
-  } catch (error) {
-    return [];
-  }
-}
-
-
-
-/**
- * Récupère tous les lexiques (catégories) de l’utilisateur
- */
-async function getAllCategoriesLexicons(authToken) {
-  const categories = ["User", "Group", "Zero", "New words"];
-
-  const promises = categories.map(async (category) => {
-    const baseUrl = "https://babalex.lezinter.net/api/lexicon/search";
-    const url = `${baseUrl}?&category=${encodeURIComponent(category)}&language=fr`;
-
-    try {
-      return await callApi(url, authToken);
-    } catch (error) {
-      console.warn(`⚠️ Aucune donnée trouvée (ou accès refusé) pour la catégorie "${category}" :`, error.message);
-      return [];
-    }
-  });
-
-  try {
-    const resultsByCategory = await Promise.all(promises);
-    const combined = resultsByCategory.flat();
-
-    log("✅ Lexiques récupérés (toutes catégories confondues) :", combined);
-    return combined;
-  } catch (error) {
-    console.error("❌ Erreur lors de la récupération multi-catégories :", error);
-    return [];
-  }
+  return callApi(url, authToken);
 }
 
-
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Récupération des entrées d'un lexique
 // ─────────────────────────────────────────────────────────────────────────────
@@ -138,7 +86,7 @@ async function getAllLexiconWords(authToken) {
     const lexicons = await getLexicons(authToken);
     
     if (!Array.isArray(lexicons) || lexicons.length === 0) {
-      console.warn("⚠️ Aucun lexique retourné par l’API pour ces paramètres.");
+      console.warn("⚠️ Aucun lexique retourné par l'API pour ces paramètres.");
       return {};
     }
 
@@ -147,6 +95,11 @@ async function getAllLexiconWords(authToken) {
     
     for (const lexicon of lexicons) {
       const entries = await getLexiconEntries(authToken, lexicon.id);
+      // Vérification que entries est bien un tableau
+      if (!Array.isArray(entries)) {
+        console.warn(`⚠️ Format invalide pour les entrées du lexique ${lexicon.id}:`, entries);
+        continue;
+      }
       const allGraphies = entries.map(entry => entry.graphy);
       
       // Création d'un libellé unique pour le lexique
@@ -161,7 +114,7 @@ async function getAllLexiconWords(authToken) {
     log("✅ Toutes les graphies récupérées :", allGraphiesByLexicon);
     return allGraphiesByLexicon;
   } catch (error) {
-    console.error("❌ Erreur lors de la récupération des graphies des lexiques :", error);
+    log("❌ Erreur lors de la récupération des graphies des lexiques :", error);
     return {};
   }
 }
@@ -189,7 +142,7 @@ async function getWiktionaryDefinition(word) {
     log(`📖 Définition trouvée pour '${word}':`, definition);
     return [definition];
   } catch (error) {
-    console.error("Erreur lors de la récupération du Wiktionnaire :", error);
+    log("Erreur lors de la récupération du Wiktionnaire :", error);
     return ["Erreur : " + error.message];
   }
 }
@@ -207,13 +160,13 @@ async function getWiktionaryDefinition(word) {
  */
 async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
   if (!authToken) {
-    throw new Error("Aucun token d’authentification fourni.");
+    throw new Error("Aucun token d'authentification fourni.");
   }
   if (!selectedWord) {
-    throw new Error("Aucun mot n’a été spécifié pour l’ajout.");
+    throw new Error("Aucun mot n'a été spécifié pour l'ajout.");
   }
   if (!Array.isArray(lexiconIds) || lexiconIds.length === 0) {
-    throw new Error("Aucun lexique sélectionné pour l’ajout.");
+    throw new Error("Aucun lexique sélectionné pour l'ajout.");
   }
 
   const url = "https://babalex.lezinter.net/api/entry/create"; 
@@ -234,7 +187,6 @@ async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
 
 window.callApi = callApi;
 window.getLexicons = getLexicons;
-window.getAllCategoriesLexicons = getAllCategoriesLexicons;
 window.getLexiconEntries = getLexiconEntries;
 window.getAllLexiconWords = getAllLexiconWords;
 window.getWiktionaryDefinition = getWiktionaryDefinition;
diff --git a/src/utils/definitions.js b/src/utils/definitions.js
index fd57303..ca0a070 100644
--- a/src/utils/definitions.js
+++ b/src/utils/definitions.js
@@ -116,7 +116,7 @@ async function fetchLexiconDefinitions(word) {
     log("Résultat final filtré :", allDefinitions);
     return allDefinitions;
   } catch (error) {
-    console.error("❌ Erreur générale lors de la récupération des définitions :", error);
+    log("❌ Erreur générale lors de la récupération des définitions :", error);
     return [];
   }
 }
@@ -125,45 +125,67 @@ async function fetchLexiconDefinitions(word) {
 * Récupère la définition d'un mot depuis le Wiktionnaire (fr).
 * Retourne un tableau d'objets : [{ source: 'Wiktionnaire', text: '...' }]
 */
-// async function fetchWiktionaryDefinition(word) {
-//   try {
-//     log(`🔍 Requête Wiktionnaire pour "${word}"...`);
-//     if (!word || word.trim() === "") {
-//       throw new Error("⚠️ Mot vide, impossible d'envoyer la requête.");
-//     }
-//     const wiktionaryURL = `https://fr.wiktionary.org/w/api.php?action=query&format=json&origin=*&prop=extracts&explaintext=true&redirects=1&titles=${encodeURIComponent(word)}`;
-//     const response = await fetch(wiktionaryURL);
-//     if (!response.ok) {
-//       throw new Error(`❌ Erreur API Wiktionnaire: ${response.statusText}`);
-//     }
-//     const data = await response.json();
-//     log("📖 Réponse API (Wiktionnaire) :", data);
-
-//     const pages = data.query?.pages;
-//     const page = pages ? Object.values(pages)[0] : null;
-    
-//     const definitionText = page && page.extract
-//       ? page.extract.trim()
-//       : "⚠️ Aucune définition trouvée sur le Wiktionnaire.";
-
-//     log("🌍 Définition Wiktionnaire extraite :", definitionText);
-
-//     return [
-//       {
-//         source: "Wiktionnaire",
-//         text: definitionText
-//       }
-//     ];
-//   } catch (error) {
-//     console.error("❌ Erreur Wiktionnaire :", error);
-//     return [
-//       {
-//         source: "Wiktionnaire",
-//         text: "⚠️ Erreur lors de la récupération sur le Wiktionnaire."
-//       }
-//     ];
-//   }
-// }
+async function fetchWiktionaryDefinition(word) {
+  try {
+    const result = await browser.storage.local.get("accessToken");
+    authToken = result.accessToken;
+
+    if (!authToken) {
+      log(`🔍 Requête Wiktionnaire pour "${word}"...`);
+      if (!word || word.trim() === "") {
+        throw new Error("⚠️ Mot vide, impossible d'envoyer la requête.");
+      }
+      const wiktionaryURL = `https://fr.wiktionary.org/w/api.php?action=query&format=json&origin=*&prop=extracts&explaintext=true&redirects=1&titles=${encodeURIComponent(word)}`;
+      const response = await fetch(wiktionaryURL);
+      if (!response.ok) {
+        throw new Error(`❌ Erreur API Wiktionnaire: ${response.statusText}`);
+      }
+      const data = await response.json();
+      log("📖 Réponse API (Wiktionnaire) :", data);
+
+      const pages = data.query?.pages;
+      const page = pages ? Object.values(pages)[0] : null;
+      
+      const definitionText = page && page.extract
+        ? page.extract.trim()
+        : "⚠️ Aucune définition trouvée sur le Wiktionnaire.";
+
+      log("🌍 Définition Wiktionnaire extraite :", definitionText);
+
+      return [
+        {
+          source: "Wiktionnaire",
+          text: definitionText
+        }
+      ];
+    } else {
+      log(` Recherche de la définition pour : ${word}`);
+
+      // Récupération des données depuis l'API
+      const apiResponse = await wikiApiResponse(word);
+      log("Réponse brute de l'API :", apiResponse);
+
+      if (!Array.isArray(apiResponse) || apiResponse.length === 0) {
+          console.warn(`Aucune définition trouvée pour "${word}"`);
+          return [];  // Retourne un tableau vide si aucune définition
+      }
+
+      // Formatage des données
+      const formattedData = formatDefinitionData(apiResponse);
+      log("Données formatées :", formattedData);
+
+      return [
+          {
+              source: "Wiktionnaire",
+              text: formattedData.definitions.length > 0 ? formattedData.definitions.join(" | ") : "⚠️ Aucune définition disponible."
+          }
+      ];
+    }
+  } catch (error) {
+    log("❌ Erreur lors de la récupération de la définition :", error);
+    return [{ source: "Wiktionnaire", text: "Erreur lors de la récupération sur le Wiktionnaire." }];
+  }
+}
 
 async function wikiApiResponse(word) {
   const result = await browser.storage.local.get("accessToken");
@@ -186,10 +208,10 @@ async function wikiApiResponse(word) {
 
     
     const data = await response.json();
-    console.log(`Résultats du Wiktionnaire pour le mot "${word}" :`, data);
+    log(`Résultats du Wiktionnaire pour le mot "${word}" :`, data);
     return data;
   } catch (error) {
-    console.error('Erreur lors de la récupération de la définition depuis le Wiktionnaire :', error);
+    log('Erreur lors de la récupération de la définition depuis le Wiktionnaire :', error);
     throw error; 
   }
 }
@@ -238,36 +260,6 @@ function formatDefinitionData(apiResponse) {
   return formattedData;
 }
 
-async function fetchWiktionaryDefinition(word) {
-  try {
-      console.log(` Recherche de la définition pour : ${word}`);
-
-      // Récupération des données depuis l'API
-      const apiResponse = await wikiApiResponse(word);
-      console.log("Réponse brute de l'API :", apiResponse);
-
-      if (!Array.isArray(apiResponse) || apiResponse.length === 0) {
-          console.warn(`Aucune définition trouvée pour "${word}"`);
-          return [];  // Retourne un tableau vide si aucune définition
-      }
-
-      // Formatage des données
-      const formattedData = formatDefinitionData(apiResponse);
-      console.log("Données formatées :", formattedData);
-
-      return [
-          {
-              source: "Wiktionnaire",
-              text: formattedData.definitions.length > 0 ? formattedData.definitions.join(" | ") : "⚠️ Aucune définition disponible."
-          }
-      ];
-  } catch (error) {
-      console.error("Erreur lors de la récupération de la définition :", error);
-      return [{ source: "Wiktionnaire", text: "Erreur lors de la récupération sur le Wiktionnaire." }];
-  }
-}
-
-
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Affichage des définitions dans la barre latérale
 // ─────────────────────────────────────────────────────────────────────────────
@@ -387,7 +379,7 @@ function openDefinitionPopup(fullText) {
   const modalOverlay = document.getElementById("modalOverlay");
   const modalFullText = document.getElementById("modalFullText");
   if (!modalOverlay || !modalFullText) {
-    console.error("Modal elements not found!");
+    log("Modal elements not found!");
     return;
   }
   modalFullText.innerHTML = "<p>" + fullText.replace(/\n/g, "<br>") + "</p>";
@@ -467,7 +459,7 @@ async function showDefinitions(word) {
     return allDefinitions;
 
   } catch (error) {
-    console.error("❌ [showDefinitions] Erreur : ", error);
+    log("❌ [showDefinitions] Erreur : ", error);
 
     if (noDefinitionsContainer) {
       noDefinitionsContainer.textContent =
@@ -479,15 +471,15 @@ async function showDefinitions(word) {
 }
 
 /**
-* Appel direct pour récupérer les définitions d’un mot uniquement via l’API
-* (sans Wiktionnaire), puis gérer l’affichage d’erreur ou non.
+* Appel direct pour récupérer les définitions d'un mot uniquement via l'API
+* (sans Wiktionnaire), puis gérer l'affichage d'erreur ou non.
 */
 async function fetchDefinition(word) {
   log(`🔍 Recherche de la définition pour '${word}'...`);
 
   const noDefinitionsContainer = document.getElementById("noDefinitionsContainer");
   if (!noDefinitionsContainer) {
-    console.error("❌ Élément #noDefinitionsContainer introuvable.");
+    log("❌ Élément #noDefinitionsContainer introuvable.");
     return;
   }
 
@@ -503,7 +495,7 @@ async function fetchDefinition(word) {
 
     noDefinitionsContainer.style.display = "none";
   } catch (error) {
-    console.error("❌ Erreur lors de la récupération de la définition :", error);
+    log("❌ Erreur lors de la récupération de la définition :", error);
     noDefinitionsContainer.style.display = "block";
   }
 }
diff --git a/src/utils/highlighting.js b/src/utils/highlighting.js
new file mode 100644
index 0000000..4a673e9
--- /dev/null
+++ b/src/utils/highlighting.js
@@ -0,0 +1,526 @@
+// Variables globales
+window.activeLexiconIds = window.activeLexiconIds || new Set();
+
+// Logs immédiats
+log("🔵 DÉBUT DU FICHIER highlighting.js");
+try {
+    log("✅ highlighting.js chargé");
+} catch (e) {
+    log("❌ Erreur avec la fonction log:", e);
+}
+
+// Vérification de l'environnement
+log("🔍 Vérification de l'environnement:", {
+    hasBrowser: typeof browser !== 'undefined',
+    windowLocation: window.location.href
+});
+
+// Gestion globale des erreurs
+window.onerror = function(msg, url, line, col, error) {
+    log("🔴 Erreur globale:", { message: msg, url: url, line: line, col: col, error: error });
+    return false;
+};
+
+// Fonction d'initialisation du token depuis le stockage local
+async function initAuthToken() {
+    try {
+        const { accessToken } = await browser.storage.local.get("accessToken");
+        if (accessToken) {
+            window.authToken = accessToken;
+            authToken = accessToken;
+            log("🔑 Token récupéré depuis le stockage local");
+            return true;
+        } else {
+            log("⚠️ Aucun token trouvé dans le stockage local");
+            return false;
+        }
+    } catch (error) {
+        log("❌ Erreur lors de la récupération du token:", error);
+        return false;
+    }
+}
+initAuthToken();
+
+// Écoute de mise à jour du token
+browser.runtime.onMessage.addListener((message) => {
+    if (message.command === "updateAuthToken" && message.token) {
+        window.authToken = message.token;
+        authToken = message.token;
+        log("🔑 Token mis à jour via message:", !!message.token);
+    }
+});
+
+(function () {
+    try {
+        if (window.hasRun) {
+            log("⚠️ highlighting.js déjà chargé");
+            return;
+        }
+        window.hasRun = true;
+        
+        // Variables internes
+        let lexiconWordsCache = new Map();
+        let highlightingActive = false;
+        window.highlightingActive = false;
+        let observer = null;
+        
+        // Gestion de la visibilité/page show pour réappliquer le surlignage
+        document.addEventListener('visibilitychange', async () => {
+            if (document.visibilityState === 'visible' && window.highlightingActive && activeLexiconIds.size > 0) {
+                log("📄 Page redevenue visible, réinitialisation du surlignage");
+                removeAllHighlights();
+                await updateLexiconCache();
+                highlightVisibleContent();
+                attachMutationObserver();
+            }
+        });
+        window.addEventListener('pageshow', async () => {
+            if (window.highlightingActive && activeLexiconIds.size > 0) {
+                log("📄 Page affichée (pageshow), réinitialisation du surlignage");
+                removeAllHighlights();
+                await updateLexiconCache();
+                highlightVisibleContent();
+                attachMutationObserver();
+            }
+        });
+        
+        // Gestion des messages reçus du background
+        browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
+            log("📨 Message reçu:", message, "Context:", {
+                highlightingActive,
+                activeLexiconIds: Array.from(activeLexiconIds),
+                hasAuthToken: !!window.authToken,
+                hasGetAllLexiconWords: !!window.getAllLexiconWords
+            });
+            
+            if (message.command === "activate-highlighting") {
+                log(`🎯 Activation du surlignage pour le lexique ${message.lexiconId}`);
+                startHighlighting(message.lexiconId)
+                    .then(() => {
+                        window.highlightingActive = true;
+                        sendResponse(true);
+                    })
+                    .catch(error => {
+                        log("❌ Erreur lors de l'activation:", error);
+                        sendResponse(false);
+                    });
+                return true;
+            }
+            
+            if (message.command === "deactivate-highlighting") {
+                log(`🚫 Désactivation du surlignage pour le lexique ${message.lexiconId}`);
+                stopHighlighting(message.lexiconId)
+                    .then(() => {
+                        if (activeLexiconIds.size === 0) {
+                            window.highlightingActive = false;
+                        }
+                        sendResponse(true);
+                    })
+                    .catch(error => {
+                        log("❌ Erreur lors de la désactivation:", error);
+                        sendResponse(false);
+                    });
+                return true;
+            }
+            
+            return false;
+        });
+        
+        log("📡 Enregistrement du script auprès du background");
+        browser.runtime.sendMessage({ command: "register-highlighting-script" });
+        
+        log("🚀 Initialisation de highlighting.js");
+        
+        // Fonction asynchrone pour mettre à jour le style d'un élément surligné en fonction des lexiques qui le concernent
+        async function updateHighlightStyle(span, lexIds) {
+            if (!lexIds || lexIds.length === 0) {
+                span.style.backgroundColor = "rgba(255, 255, 0, 0.3)";
+                span.style.backgroundImage = "";
+                return;
+            }
+            if (lexIds.length === 1) {
+                const hexColor = await getColorForLexicon(lexIds[0]);
+                const rgbaColor = hexToRgba(hexColor, 0.3);
+                span.style.backgroundColor = rgbaColor;
+                span.style.backgroundImage = "";
+            } else {
+                const hexColors = await Promise.all(lexIds.map(id => getColorForLexicon(id)));
+                const colors = hexColors.map(hex => hexToRgba(hex, 0.3));
+                const n = colors.length;
+                let stops = [];
+                for (let i = 0; i < n; i++) {
+                    const start = ((100 * i) / n).toFixed(2) + '%';
+                    const end = ((100 * (i + 1)) / n).toFixed(2) + '%';
+                    stops.push(`${colors[i]} ${start}, ${colors[i]} ${end}`);
+                }
+                const gradient = `linear-gradient(90deg, ${stops.join(', ')})`;
+                span.style.backgroundImage = gradient;
+                
+            }
+        }
+        
+        // Vérifier si un mot appartient à un lexique (à l'aide de la cache)
+        function wordIsInLexicon(lexiconId, word) {
+            const wordsSet = lexiconWordsCache.get(String(lexiconId));
+            return wordsSet ? wordsSet.has(word.toLowerCase()) : false;
+        }
+        
+        // Mise à jour incrémentale des éléments déjà surlignés lorsqu'un nouveau lexique est ajouté
+        async function updateHighlightsForNewLexicon(newLexiconId) {
+            const spans = document.querySelectorAll('.lexicon-highlight');
+            for (let span of spans) {
+                const word = span.textContent;
+                if (wordIsInLexicon(newLexiconId, word)) {
+                    let lexIds = [];
+                    try {
+                        lexIds = JSON.parse(span.getAttribute('data-lexicons'));
+                    } catch (e) {
+                        lexIds = [];
+                    }
+                    if (!lexIds.includes(newLexiconId)) {
+                        lexIds.push(newLexiconId);
+                        span.setAttribute('data-lexicons', JSON.stringify(lexIds));
+                        await updateHighlightStyle(span, lexIds);
+                    }
+                }
+            }
+        }
+        
+        // Fonction startHighlighting modifiée pour intégrer la mise à jour incrémentale
+        async function startHighlighting(lexiconId) {
+            try {
+                await initAuthToken();
+                if (!window.authToken) {
+                    throw new Error("❌ Pas de token d'authentification disponible");
+                }
+                if (lexiconId) {
+                    if (!activeLexiconIds.has(lexiconId)) {
+                        activeLexiconIds.add(lexiconId);
+                        const activeLexicons = Array.from(activeLexiconIds);
+                        await browser.storage.local.set({ activeLexicons });
+                        log("📊 Lexiques actifs sauvegardés:", activeLexicons);
+                        // Mise à jour de la cache pour inclure le nouveau lexique
+                        await updateLexiconCache();
+                        // Mise à jour immédiate des éléments surlignés pour intégrer le nouveau lexique
+                        await updateHighlightsForNewLexicon(lexiconId);
+                    }
+                }
+                window.highlightingActive = true;
+                highlightingActive = true;
+                highlightVisibleContent();
+                attachMutationObserver();
+                return true;
+            } catch (error) {
+                log("❌ Erreur lors du démarrage du surlignage:", error);
+                window.highlightingActive = false;
+                highlightingActive = false;
+                throw error;
+            }
+        }
+        
+        async function stopHighlighting(lexiconId) {
+            try {
+                if (lexiconId) {
+                    activeLexiconIds.delete(lexiconId);
+                    const activeLexicons = Array.from(activeLexiconIds);
+                    await browser.storage.local.set({ activeLexicons });
+                    if (activeLexiconIds.size === 0) {
+                        window.highlightingActive = false;
+                        highlightingActive = false;
+                        removeAllHighlights();
+                        detachMutationObserver();
+                    } else {
+                        removeAllHighlights();
+                        await updateLexiconCache();
+                        highlightVisibleContent();
+                    }
+                } else {
+                    window.highlightingActive = false;
+                    highlightingActive = false;
+                    activeLexiconIds.clear();
+                    removeAllHighlights();
+                    detachMutationObserver();
+                }
+                return true;
+            } catch (error) {
+                log("❌ Erreur lors de l'arrêt du surlignage:", error);
+                throw error;
+            }
+        }
+        
+        // Mise à jour du cache des lexiques
+        async function updateLexiconCache() {
+            log("📥 updateLexiconCache - Début avec context:", {
+                authToken: !!window.authToken,
+                getAllLexiconWords: !!window.getAllLexiconWords,
+                activeLexiconIds: Array.from(activeLexiconIds)
+            });
+            let allWords;
+            try {
+                if (!window.authToken) {
+                    throw new Error("Pas de token d'authentification");
+                }
+                if (typeof window.getAllLexiconWords !== 'function') {
+                    log("⚠️ getAllLexiconWords n'est pas une fonction");
+                    log("Type de getAllLexiconWords:", typeof window.getAllLexiconWords);
+                    log("Contenu de window.getAllLexiconWords:", window.getAllLexiconWords);
+                    throw new Error("getAllLexiconWords n'est pas disponible");
+                }
+                log("📥 Appel de getAllLexiconWords...");
+                allWords = await window.getAllLexiconWords(window.authToken);
+                log("📝 Réponse de getAllLexiconWords:", allWords);
+                if (!allWords || typeof allWords !== 'object') {
+                    throw new Error(`Format de données invalide: ${JSON.stringify(allWords)}`);
+                }
+                lexiconWordsCache.clear();
+                if (Object.keys(allWords).length === 0) {
+                    log("⚠️ Aucun lexique reçu de getAllLexiconWords");
+                    return false;
+                }
+                for (const [lexiconName, words] of Object.entries(allWords)) {
+                    if (!Array.isArray(words)) {
+                        console.warn(`⚠️ Format invalide pour le lexique ${lexiconName}:`, words);
+                        continue;
+                    }
+                    const lexiconId = lexiconName.match(/\[(\d+)\]$/)?.[1];
+                    if (!lexiconId) {
+                        console.warn(`⚠️ Impossible d'extraire l'ID du lexique depuis: ${lexiconName}`);
+                        continue;
+                    }
+                    log(`📎 Traitement du lexique ${lexiconName} (ID: ${lexiconId})`);
+                    if (activeLexiconIds.has(Number(lexiconId))) {
+                        lexiconWordsCache.set(lexiconId, new Set(words));
+                        log(`📖 Lexique ${lexiconId} chargé avec ${words.length} mots`);
+                    }
+                }
+                log("✅ Cache des lexiques mis à jour:",
+                    Object.fromEntries([...lexiconWordsCache.entries()].map(([id, words]) => [id, [...words]])));
+                return true;
+            } catch (error) {
+                log("❌ Erreur dans updateLexiconCache:", {
+                    message: error.message,
+                    stack: error.stack,
+                    authTokenExists: !!window.authToken,
+                    getAllLexiconWordsType: typeof window.getAllLexiconWords,
+                    response: allWords
+                });
+                throw error;
+            }
+        }
+        
+        // Surlignage du contenu visible
+        function highlightVisibleContent() {
+            if (!highlightingActive) {
+                log("⏸️ Surlignage inactif, sortie");
+                return;
+            }
+            log("🔍 Début du surlignage du contenu visible");
+            const BATCH_SIZE = 100;
+            const BATCH_DELAY = 10; // ms
+            const textNodes = [];
+            const walker = document.createTreeWalker(
+                document.body,
+                NodeFilter.SHOW_TEXT,
+                {
+                    acceptNode: (node) => {
+                        const parent = node.parentElement;
+                        if (!parent || parent.closest('script, style, .lexicon-highlight') || !node.textContent.trim() || getComputedStyle(parent).display === 'none') {
+                            return NodeFilter.FILTER_REJECT;
+                        }
+                        return NodeFilter.FILTER_ACCEPT;
+                    }
+                }
+            );
+            let node;
+            while (node = walker.nextNode()) {
+                textNodes.push(node);
+            }
+            log(`🔤 ${textNodes.length} nœuds de texte trouvés à traiter`);
+            const processNextBatch = (startIndex) => {
+                if (!highlightingActive || startIndex >= textNodes.length) {
+                    return;
+                }
+                const endIndex = Math.min(startIndex + BATCH_SIZE, textNodes.length);
+                const batch = textNodes.slice(startIndex, endIndex);
+                batch.forEach(processTextNode);
+                if (endIndex < textNodes.length) {
+                    setTimeout(() => processNextBatch(endIndex), BATCH_DELAY);
+                }
+            };
+            processNextBatch(0);
+        }
+        
+        // Traitement d'un nœud de texte
+        function processTextNode(textNode) {
+            if (activeLexiconIds.size === 0) {
+                log("⚠️ Aucun lexique actif, sortie du processTextNode");
+                return;
+            }
+            const text = textNode.textContent;
+            log(`🔍 Traitement du texte: "${text.substring(0, 50)}..."`);
+            let lastIndex = 0;
+            let fragments = [];
+            const allWords = new Set();
+            const matchedLexiconIdsMap = new Map();
+            for (const [lexiconId, words] of lexiconWordsCache.entries()) {
+                const numericId = parseInt(lexiconId);
+                log(`🔄 Vérification du lexique ${lexiconId} (ID: ${numericId})`);
+                if (activeLexiconIds.has(numericId)) {
+                    log(`✅ Lexique ${lexiconId} actif, ajout de ${words.size} mots`);
+                    words.forEach(word => allWords.add(word));
+                    words.forEach(word => {
+                        const lowerCaseWord = word.toLowerCase();
+                        if (!matchedLexiconIdsMap.has(lowerCaseWord)) {  // Correction ici !
+                            matchedLexiconIdsMap.set(lowerCaseWord, []);
+                        }
+                        matchedLexiconIdsMap.get(lowerCaseWord).push(lexiconId);
+                    });
+                }
+            }
+            log(`🔤 Nombre total de mots à rechercher: ${allWords.size}`);
+            if (allWords.size === 0) {
+                log("⚠️ Aucun mot à rechercher dans les lexiques actifs");
+                return;
+            }
+            const wordsPattern = Array.from(allWords)
+                .sort((a, b) => b.length - a.length)
+                .map(escapeRegExp)
+                .join("|");
+            if (!wordsPattern) {
+                log("⚠️ Aucun mot à rechercher, sortie");
+                return;
+            }
+            const regex = new RegExp(`\\b(${wordsPattern})\\b`, "gi");
+            let match;
+            let matchCount = 0;
+            while ((match = regex.exec(text)) !== null) {
+                matchCount++;
+                if (match.index > lastIndex) {
+                    fragments.push(document.createTextNode(text.slice(lastIndex, match.index)));
+                }
+                const span = document.createElement("span");
+                span.textContent = match[0];
+                span.className = "lexicon-highlight";
+                span.style.display = "inline-block";
+                
+                const matchedLexiconIds = matchedLexiconIdsMap.get(match[0].toLowerCase()) || [];
+                span.setAttribute('data-lexicons', JSON.stringify(matchedLexiconIds));
+                
+                if (matchedLexiconIds.length === 0) {
+                    span.style.backgroundColor = "rgba(255, 255, 0, 0.3)";
+                } else {
+                    updateHighlightStyle(span, matchedLexiconIds);
+                }
+                fragments.push(span);
+                lastIndex = regex.lastIndex;
+            }
+            if (matchCount > 0) {
+                log(`✨ ${matchCount} correspondances trouvées dans le nœud`);
+            }
+            if (lastIndex < text.length) {
+                fragments.push(document.createTextNode(text.slice(lastIndex)));
+            }
+            if (fragments.length > 0) {
+                const parent = textNode.parentNode;
+                fragments.forEach(fragment => parent.insertBefore(fragment, textNode));
+                parent.removeChild(textNode);
+            }
+        }
+        
+        // Suppression de tous les surlignages
+        function removeAllHighlights() {
+            log("🧹 Suppression de tous les surlignages");
+            const highlights = document.querySelectorAll('.lexicon-highlight');
+            log(`📊 ${highlights.length} surlignages à supprimer`);
+            highlights.forEach(highlight => {
+                const text = highlight.textContent;
+                const textNode = document.createTextNode(text);
+                highlight.parentNode.replaceChild(textNode, highlight);
+            });
+        }
+        
+        // Gestion des mutations DOM
+        function attachMutationObserver() {
+            log("👀 Attachement de l'observateur de mutations");
+            let debounceTimer = null;
+            const DEBOUNCE_DELAY = 250; // ms
+            observer = new MutationObserver((mutations) => {
+                if (debounceTimer) {
+                    clearTimeout(debounceTimer);
+                }
+                debounceTimer = setTimeout(() => {
+                    log(`🔄 Traitement groupé de ${mutations.length} mutations DOM`);
+                    let shouldHighlight = false;
+                    for (const mutation of mutations) {
+                        if (mutation.type === 'childList') {
+                            for (const node of mutation.addedNodes) {
+                                if (node.nodeType === Node.ELEMENT_NODE && 
+                                    !node.closest('.lexicon-highlight') && 
+                                    node.textContent.trim()) {
+                                    shouldHighlight = true;
+                                    break;
+                                }
+                            }
+                        }
+                        if (shouldHighlight) break;
+                    }
+                    if (shouldHighlight) {
+                        highlightVisibleContent();
+                    }
+                }, DEBOUNCE_DELAY);
+            });
+            observer.observe(document.body, {
+                childList: true,
+                subtree: true
+            });
+        }
+        
+        function detachMutationObserver() {
+            if (observer) {
+                log("👋 Détachement de l'observateur de mutations");
+                observer.disconnect();
+                observer = null;
+            }
+        }
+        
+        function escapeRegExp(string) {
+            return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+        }
+        
+        function getLexiconIdFromName(lexiconName) {
+            const match = lexiconName.match(/\[(\d+)\]$/);
+            const id = match ? parseInt(match[1]) : null;
+            log(`🏷️ Extraction de l'ID depuis '${lexiconName}': ${id}`);
+            return id;
+        }
+        
+        log("🔍 Vérification des dépendances au chargement:", {
+            authToken: !!window.authToken,
+            getAllLexiconWords: typeof window.getAllLexiconWords
+        });
+        
+        async function checkAndRestoreHighlightingState() {
+            try {
+                const { activeLexicons } = await browser.storage.local.get("activeLexicons");
+                if (!activeLexicons || !Array.isArray(activeLexicons) || activeLexicons.length === 0) {
+                    window.highlightingActive = false;
+                    highlightingActive = false;
+                    return;
+                }
+                log("🔄 État des lexiques trouvé:", activeLexicons);
+                for (const lexiconId of activeLexicons) {
+                    await startHighlighting(lexiconId);
+                }
+            } catch (error) {
+                log("❌ Erreur lors de la restauration de l'état:", error);
+                window.highlightingActive = false;
+                highlightingActive = false;
+            }
+        }
+        
+        checkAndRestoreHighlightingState();
+        
+    } catch (error) {
+        log("🔴 Erreur critique dans l'IIFE:", error);
+    }
+})();
diff --git a/src/utils/logger.js b/src/utils/logger.js
index 8b3f55e..3d3891c 100644
--- a/src/utils/logger.js
+++ b/src/utils/logger.js
@@ -1,12 +1,31 @@
-
 /**
  * Mode debug : affiche les logs dans la console
- * Mode prod : masque les logs
+ * Mode prod : masque les logs ainsi que les identifiants des lexiques
 */
-const DEBUG = false; // false en prod
-
-function log(...args) {
-  if (DEBUG) {
-    console.log(...args);
+(function () {
+  if (typeof window !== 'undefined') {
+    if (typeof window.DEBUG === 'undefined') {
+      window.DEBUG = true; // true en debug
+    }
+    if (!window.log) {
+      function log(...args) {
+        if (window.DEBUG) {
+          console.log(...args);
+        }
+      }
+      window.log = log;
+    }
+  } else if (typeof self !== 'undefined') {
+    if (typeof self.DEBUG === 'undefined') {
+      self.DEBUG = true; // true en debug
+    }
+    if (!self.log) {
+      function log(...args) {
+        if (self.DEBUG) {
+          console.log(...args);
+        }
+      }
+      self.log = log;
+    }
   }
-}
+})();
diff --git a/src/utils/stats.js b/src/utils/stats.js
index 1f7b799..3ee90b9 100644
--- a/src/utils/stats.js
+++ b/src/utils/stats.js
@@ -10,15 +10,15 @@
     //Connexion au port
     function connectToWorker() {
         if (!workerPort) {
-            // console.log("[Stats] Connexion au WebWorker...");
+            // log("[Stats] Connexion au WebWorker...");
             workerPort = browser.runtime.connect({ name: "stats-worker-port" });
             workerPort.onMessage.addListener((message) => {
-                console.log("[Stats] Message reçu du Worker :", message);
+                log("[Stats] Message reçu du Worker :", message);
                 if (message.command === "update-frequencies") {
-                    console.log("[Stats] Fréquences mises à jour :", message.frequencies);
+                    log("[Stats] Fréquences mises à jour :", message.frequencies);
                 }
                 if (message.command === "threshold-exceeded") {
-                    console.log("[Stats] Mots dépassant le seuil :", message.wordsAboveThreshold);
+                    log("[Stats] Mots dépassant le seuil :", message.wordsAboveThreshold);
                     let alertMessage = "Nouveaux mots dépassant le seuil :\n";
                     if (typeof message.wordsAboveThreshold !== "object" || message.wordsAboveThreshold === null) {
                         return;
@@ -35,7 +35,7 @@
                 }
             });
             workerPort.onDisconnect.addListener(() => {
-                // console.log("[Stats] Déconnexion du WebWorker.");
+                // log("[Stats] Déconnexion du WebWorker.");
                 workerPort = null;
             });
         }
@@ -46,7 +46,7 @@
             connectToWorker();
         }
         if (workerPort) {
-            console.log("[Stats] Envoi du texte au Worker :", text);
+            log("[Stats] Envoi du texte au Worker :", text);
             workerPort.postMessage({ command: "process-text", text: text });
         }
     }
@@ -55,7 +55,7 @@
     // Gestion des messages envoyés depuis le background 
     // ─────────────────────────────────────────────────────────────────────────────
     browser.runtime.onMessage.addListener((message) => {
-        console.log("[Stats] Message reçu :", message);
+        log("[Stats] Message reçu :", message);
         if (message.command === "activate-stats") {
             startTracking();
         }
@@ -85,7 +85,7 @@
     // Arrête tous les chronomètres lorsque l'utilisateur change d'onglet
     document.addEventListener("visibilitychange", () => {
         if (document.hidden) {
-            // console.log("[Stats] Changement d'onglet détecté");
+            // log("[Stats] Changement d'onglet détecté");
             resetAllTimers();
         }
     });
@@ -119,25 +119,25 @@
                 if (!readContent.has(text)) {
                     startReadingTimer(element, text, minReadTime);
                 }
-                highlightElement(element, true);
+                // highlightElement(element, true);
             } else {
                 stopReadingTimer(element, text);
-                highlightElement(element, false);
+                // highlightElement(element, false);
             }
         });
     }
     
-    /**
-     * Ajoute une bordure rouge autour de l'élément
-     */
-    function highlightElement(element, shouldHighlight) {
-        if (shouldHighlight) {
-            element.style.outline = "3px solid red";
-        } else {
-            element.style.outline = "";
-            removeReadingIndicator(element);
-        }
-    }
+    // /**
+    //  * Ajoute une bordure rouge autour de l'élément
+    //  */
+    // function highlightElement(element, shouldHighlight) {
+    //     if (shouldHighlight) {
+    //         element.style.outline = "3px solid red";
+    //     } else {
+    //         element.style.outline = "";
+    //         removeReadingIndicator(element);
+    //     }
+    // }
     
     /**
      * Démarre un chronomètre pour vérifier si l'élément est lu
@@ -145,7 +145,11 @@
     function startReadingTimer(element, text, minReadTime) {
         if (!readingTimers.has(element)) {
             let elapsedTime = 0;
-            let counter = document.createElement("div");
+            let counter = null;
+
+          // Créer l'indicateur uniquement si on est en mode debug
+          if (DEBUG) {
+            counter = document.createElement("div");
             counter.classList.add("reading-counter");
             counter.style.position = "absolute";
             counter.style.background = "black";
@@ -154,31 +158,33 @@
             counter.style.borderRadius = "5px";
             counter.style.fontSize = "12px";
             counter.style.zIndex = "9999";
-    
             document.body.appendChild(counter);
-    
-            let interval = setInterval(() => {
+          }
+
+          let interval = setInterval(() => {
                 elapsedTime += 1000;
     
                 // Vérifie si l'utilisateur est actif et si le temps minimum est atteint
                 if (userIsActive && elapsedTime >= minReadTime) {
-                    console.log(`[Stats] Élément lu : ${text}`);
+                    log(`[Stats] Élément lu : ${text}`);
                     readContent.add(text);
                     sendTextToWorker(text);
                     stopReadingTimer(element, text);
                 }
     
-                // Mise à jour de la position du compteur
+            // Mise à jour de la position et du contenu du compteur si en debug
+            if (DEBUG && counter) {
                 let rect = element.getBoundingClientRect();
                 counter.style.top = `${rect.top + window.scrollY - 20}px`;
                 counter.style.left = `${rect.left + window.scrollX + rect.width + 10}px`;
                 counter.innerText = `⏳ ${Math.floor(elapsedTime / 1000)}s`;
-    
+              }
             }, 1000);
-    
+        
             readingTimers.set(element, { interval, counter, elapsedTime });
+          }
         }
-    }
+
     
     /**
      * Arrête le chronomètre et supprime l'affichage du temps de lecture
@@ -187,7 +193,9 @@
         if (readingTimers.has(element)) {
             let { interval, counter } = readingTimers.get(element);
             clearInterval(interval);
+            if (counter) {
             counter.remove();
+        }
             readingTimers.delete(element);
         }
     }
@@ -197,7 +205,9 @@
     function resetAllTimers() {
         for (let [element, { interval, counter }] of readingTimers) {
             clearInterval(interval);
-            counter.remove();
+            if (counter) {
+                counter.remove();
+            }
         }
         readingTimers.clear();
     }
@@ -207,8 +217,10 @@
      */
     function removeReadingIndicator(element) {
         if (readingTimers.has(element)) {
-            let { counter } = readingTimers.get(element);
-            counter.remove();
+            let { counter } = readingTimers.get(element);            
+            if (counter) {
+                counter.remove();
+            }
         }
     }
     /**
@@ -228,13 +240,13 @@
     // Gestion de l'activation/désactivation des statistiques
     // ─────────────────────────────────────────────────────────────────────────────
     function startTracking() {
-            console.log("[Stats] Suivi des statistiques activé.");
+            log("[Stats] Suivi des statistiques activé.");
             addViewportBorder();
             attachScrollListener();
         }
 
     function stopTracking() {
-        console.log("[Stats] Suivi des statistiques désactivé.");
+        log("[Stats] Suivi des statistiques désactivé.");
         removeViewportBorder();
         detachScrollListener();
     }
@@ -243,7 +255,7 @@
         if (!scrollListenerAttached) {
             window.addEventListener("scroll", trackVisibleContent);
             scrollListenerAttached = true;
-            console.log("[Stats] Écouteur de défilement attaché.");
+            log("[Stats] Écouteur de défilement attaché.");
         }
     }
 
@@ -251,7 +263,7 @@
         if (scrollListenerAttached) {
             window.removeEventListener("scroll", trackVisibleContent);
             scrollListenerAttached = false;
-            console.log("[Stats] Écouteur de défilement détaché.");
+            log("[Stats] Écouteur de défilement détaché.");
         }
     }
 
@@ -319,7 +331,7 @@
         rect.setAttribute("stroke-width", "0.5");
         rect.setAttribute("stroke-dasharray", "200 200");
         rect.setAttribute("stroke-dashoffset", "400");
-        rect.style.animation = "dashAnimation 8s ease-in-out infinite";
+        rect.style.animation = "dashAnimation 6s ease-in-out infinite";
     
         svg.appendChild(rect);
         document.body.appendChild(svg);
diff --git a/src/workers/pyodide_worker.js b/src/workers/pyodide_worker.js
index e5f7872..ebd2b0b 100644
--- a/src/workers/pyodide_worker.js
+++ b/src/workers/pyodide_worker.js
@@ -1,4 +1,5 @@
-console.log("pyodide_worker.js chargé avec succès !");
+importScripts("../utils/logger.js");
+log("pyodide_worker.js chargé avec succès !");
 
 // URL de la version Pyodide la plus récente
 const LATEST_BASE_URL = "https://cdn.jsdelivr.net/pyodide/v0.27.2/full/";
@@ -24,19 +25,19 @@ let stoplistsReady = new Promise((resolve) => resolve());
 // Écouteur des messages reçus du background script
 self.onmessage = async (event) => {
   const { command, ...data } = event.data;
-  console.log("[WebWorker] Message reçu du Background:", command, data);
+  log("[WebWorker] Message reçu du Background:", command, data);
 
   switch (command) {
 
     case "pyodide-simplemma":
       if (pyodideLoaded && simplemmaLoaded) {
-        console.log("[Worker] Pyodide et Simplemma déjà chargés.");
+        log("[Worker] Pyodide et Simplemma déjà chargés.");
         self.postMessage({ type: "pyodide-simplemma", status: "already_loaded", message: "Pyodide et Simplemma déjà en mémoire" });
         return;
       }
       try {
         if (!pyodideLoaded) {
-          console.log("[Worker] Chargement de Pyodide...");
+          log("[Worker] Chargement de Pyodide...");
           try {
             importScripts(`${LATEST_BASE_URL}pyodide.js`);
           } catch (err) {
@@ -48,11 +49,11 @@ self.onmessage = async (event) => {
           await pyodide.loadPackage("lzma");
           await pyodide.loadPackage("micropip");
           pyodideLoaded = true;
-          console.log("[Worker] Pyodide chargé avec succès !");
+          log("[Worker] Pyodide chargé avec succès !");
         }
 
         if (!simplemmaLoaded) {
-          console.log("[Worker] Installation de simplemma...");
+          log("[Worker] Installation de simplemma...");
           await pyodide.runPythonAsync(`
           import micropip
           import asyncio
@@ -77,7 +78,7 @@ self.onmessage = async (event) => {
           await main()
           `);
           simplemmaLoaded = true;
-          console.log("[Worker] Simplemma installé avec succès !");
+          log("[Worker] Simplemma installé avec succès !");
         }
         // Envoyer confirmation au background script
         self.postMessage({ type: "pyodide-simplemma", status: "success", message: "Pyodide et Simplemma chargés" });
@@ -89,12 +90,12 @@ self.onmessage = async (event) => {
 
     case "process-text":
       if (!pyodideLoaded) {
-        console.log("[Worker] Pyodide non chargé.");
+        log("[Worker] Pyodide non chargé.");
         self.postMessage({ type: "process-text", status: "error", message: "Pyodide pas encore chargé" });
         return;
       }
 
-      console.log("[Worker] Texte reçu pour analyse :", data.text);
+      log("[Worker] Texte reçu pour analyse :", data.text);
       try {
         const result = await pyodide.runPythonAsync(`
         import json
@@ -145,17 +146,17 @@ self.onmessage = async (event) => {
       trackedLanguages = data.trackedLanguages;
       autoAddEnabled = data.autoAdd;
       isAuthenticated = data.isAuthenticated;
-      console.log("[Worker] Mise à jour des préférences :", { userThreshold, trackedLanguages, autoAddEnabled, isAuthenticated });
+      log("[Worker] Mise à jour des préférences :", { userThreshold, trackedLanguages, autoAddEnabled, isAuthenticated });
       break;
     
     case "update-lexicons":
-      userLexicons = data.lexicons;
-      console.log("[Worker] Lexiques mis à jour :", userLexicons);
+      userLexicons = JSON.parse(data.lexicons)
+      log("[Worker] Lexiques mis à jour :", userLexicons);
       break;
     
     case "update-auth-token":
       authToken = data.accessToken;
-      console.log("[Worker] Token mis à jour :", authToken ? "Disponible" : "Aucun token reçu");
+      log("[Worker] Token mis à jour :", authToken ? "Disponible" : "Aucun token reçu");
       break;
 
     case "update-stoplist":
@@ -164,10 +165,10 @@ self.onmessage = async (event) => {
           stoplistsByLang = {};
           for (const [lang, words] of Object.entries(data.stoplists)) {
             stoplistsByLang[lang] = new Set(words.map(word => word.toLowerCase().trim()));
-            console.log(`[Worker] Stoplist mise à jour pour '${lang}' : ${stoplistsByLang[lang].size} mots.`);
+            log(`[Worker] Stoplist mise à jour pour '${lang}' : ${stoplistsByLang[lang].size} mots.`);
           }
         } else {
-          console.warn("[Worker] ⚠ Stoplists reçues incorrectes ou vides.");
+          log("[Worker] ⚠ Stoplists reçues incorrectes ou vides.");
         }
         resolve(); // Stoplist prête
       });
@@ -175,7 +176,7 @@ self.onmessage = async (event) => {
 
     case "update-include-stopwords":
       includeStopwords = data.includeStopwords;
-      console.log(`[Worker] Mise à jour de includeStopwords : ${includeStopwords}`);
+      log(`[Worker] Mise à jour de includeStopwords : ${includeStopwords}`);
       break;
   }
 };
@@ -189,16 +190,16 @@ async function checkThreshold(lang) {
   await stoplistsReady; // Attendre que les stoplists soient chargées
   
   if (!autoAddEnabled || !isAuthenticated) {
-    console.log("[Worker] ⚠ Auto-Add désactivé ou utilisateur non connecté.");
+    log("[Worker] ⚠ Auto-Add désactivé ou utilisateur non connecté.");
   } else if (!trackedLanguages.includes(lang)) {
-    console.log(`[Worker] âš  La langue '${lang}' n'est pas suivie.`);
+    log(`[Worker] âš  La langue '${lang}' n'est pas suivie.`);
   } else {
-    console.log(`[Worker] Vérification des fréquences pour la langue '${lang}'...`);
+    log(`[Worker] Vérification des fréquences pour la langue '${lang}'...`);
   
     const stoplist = stoplistsByLang[lang] || new Set();
     const shouldFilterStopwords = stoplist.size > 0 && includeStopwords;
 
-    console.log(`[Worker] 📝 Stoplist pour '${lang}' : ${shouldFilterStopwords ? "Appliquée" : "Non appliquée"}`);
+    log(`[Worker] 📝 Stoplist pour '${lang}' : ${shouldFilterStopwords ? "Appliquée" : "Non appliquée"}`);
 
     const wordsFrequencies = storedFrequencies[lang] || {};
     const notifiedSet = new Set(notifiedWords[lang] || []);
@@ -209,25 +210,25 @@ async function checkThreshold(lang) {
       .map(([word]) => word);
 
     if (exceededWords.length === 0) {
-      console.log(`[Worker] Aucun mot dépassant le seuil pour '${lang}'.`);
+      log(`[Worker] Aucun mot dépassant le seuil pour '${lang}'.`);
     } else {
       // Filtrer selon la stoplist si nécessaire
       const finalWords = shouldFilterStopwords 
         ? exceededWords.filter(word => {
             const isInStoplist = stoplist.has(word);
-            if (isInStoplist) console.log(`[Worker] Mot "${word}" exclu (stoplist)`);
+            if (isInStoplist) log(`[Worker] Mot "${word}" exclu (stoplist)`);
             return !isInStoplist;
           })
         : exceededWords;
 
       if (finalWords.length === 0) {
-        console.log(`[Worker] Tous les mots dépassant le seuil pour '${lang}' sont dans la stoplist.`);
+        log(`[Worker] Tous les mots dépassant le seuil pour '${lang}' sont dans la stoplist.`);
       } else {
         // Ajouter les mots aux sets et logs
         notifiedWords[lang] = notifiedSet;
         finalWords.forEach(word => notifiedSet.add(word));
 
-        console.log("Mots dépassant le seuil :", finalWords);
+        log("Mots dépassant le seuil :", finalWords);
         self.postMessage({ type: "threshold-exceeded", wordsAboveThreshold: finalWords });
 
         // Ajout aux mots en attente pour un envoi groupé
@@ -245,7 +246,7 @@ async function checkThreshold(lang) {
 
 //Traiter les ajouts groupés
 async function processPendingWords() {
-  console.log("Traitement des mots à ajouter en lot...");
+  log("Traitement des mots à ajouter en lot...");
 
   for (const lang in pendingWords) {
     const words = pendingWords[lang];
@@ -261,11 +262,11 @@ async function processPendingWords() {
 
 async function addWordToLexicon(lang, word) {
   if (!authToken) {
-    console.warn("Impossible d'ajouter le mot : Aucun token d’authentification.");
+    log("Impossible d'ajouter le mot : Aucun token d’authentification.");
     return;
   }
 
-  console.log(`Tentative d'ajout du mot '${word}' pour la langue '${lang}'`);
+  log(`Tentative d'ajout du mot '${word}' pour la langue '${lang}'`);
 
   const stoplist = stoplistsByLang[lang] || new Set();
   // Vérifier si on a une stoplist et si l'utilisateur veut exclure les stopwords
@@ -273,7 +274,7 @@ async function addWordToLexicon(lang, word) {
 
   // Si le filtrage est activé et que le mot est un stopword, on ne l'ajoute pas
   if (shouldFilterStopwords && stoplist.has(word)) {
-    console.log(`Mot '${word}' ignoré car présent dans la stoplist.`);
+    log(`Mot '${word}' ignoré car présent dans la stoplist.`);
     return;
   }
 
@@ -283,12 +284,12 @@ async function addWordToLexicon(lang, word) {
     .map(lexicon => lexicon.id);
 
   if (targetLexicons.length === 0) {
-    console.warn(`Aucun lexique trouvé pour la langue '${lang}'. Impossible d'ajouter '${word}'.`);
+    log(`Aucun lexique trouvé pour la langue '${lang}'. Impossible d'ajouter '${word}'.`);
     return;
   }
 
   try {
-    console.log(`Envoi de '${word}' aux lexiques ${targetLexicons}...`);
+    log(`Envoi de '${word}' aux lexiques ${targetLexicons}...`);
     await AddWord(authToken, word, targetLexicons);
     // Notifier le background de l'ajout réussi
     self.postMessage({ type: "word-added", word, language: lang, lexicons: targetLexicons });
@@ -319,7 +320,7 @@ async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
     target_lex: lexiconIds
   };
 
-  console.log("Envoi de la requête API AddWord :", body);
+  log("Envoi de la requête API AddWord :", body);
 
   try {
     const response = await fetch(url, {
@@ -335,7 +336,7 @@ async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
       throw new Error(`Erreur API (${response.status}): ${response.statusText}`);
     }
 
-    console.log(`Mot '${selectedWord}' ajouté avec succès aux lexiques ${lexiconIds}`);
+    log(`Mot '${selectedWord}' ajouté avec succès aux lexiques ${lexiconIds}`);
     return await response.json();
   } catch (error) {
     console.error(`Erreur lors de l'ajout du mot '${selectedWord}':`, error);
-- 
GitLab