diff --git a/README.md b/README.md
index 9d96e439e918111c0cdc797150d730977de55f35..435b323a3866364c6335a1e05904d90bd546fb7d 100644
--- a/README.md
+++ b/README.md
@@ -24,4 +24,3 @@ Source : [Luciole Vision](https://luciole-vision.com/)
 **Icônes**  
 Création des icônes d'options sur [icones8](https://icones8.fr/icons)
 
-
diff --git a/manifest.json b/manifest.json
index 5817a844c640730cf92f218f1a8d4ba04e8302a2..0d06a6f6d9be2633c0feb0fbaea7f7e334fcb466 100644
--- a/manifest.json
+++ b/manifest.json
@@ -24,7 +24,8 @@
       "src/background/background.js", 
       "src/utils/definitions.js",
       "src/utils/api.js",
-      "src/context_menu/browser_context_menu.js"
+      "src/context_menu/browser_context_menu.js",
+      "src/utils/stats.js"
     ],
     "persistent": true
   },
diff --git a/src/background/background.js b/src/background/background.js
index 965e1d09cb9fdb40f83357daddf29c715dfe79c3..98054e48151f5a2f390eb3056285e7c8f257ee46 100644
--- a/src/background/background.js
+++ b/src/background/background.js
@@ -43,18 +43,18 @@ browser.storage.onChanged.addListener((changes) => {
 });
 
 browser.storage.onChanged.addListener((changes, area) => {
-  // Vérifie si les changements concernent le stockage local et le token d'accès
+    // Vérifie si les changements concernent le stockage local et le token d'accès
   if (area === "local" && changes.accessToken) {
     const newToken = changes.accessToken.newValue; // Récupère la nouvelle valeur du token
     if (newToken) {
-      // Vérifie l'état de l'extension dans le stockage local
+    // Vérifie l'état de l'extension dans le stockage local
       browser.storage.local.get("extensionActive").then(({ extensionActive }) => {
-        // Si l'extension n'est pas active, l'active automatiquement
+      // Si l'extension n'est pas active, l'active automatiquement
         if (!extensionActive) {
           log("Token ajouté, activation automatique de l'extension.");
           browser.storage.local.set({ extensionActive: true }); // Met à jour l'état de l'extension
           updateExtension(); // Met à jour les fonctionnalités de l'extension
-          // Envoie un message pour mettre à jour l'interface utilisateur
+         // Envoie un message pour mettre à jour l'interface utilisateur
           browser.runtime.sendMessage({
             action: "updateUI",
             extensionActive: true,
@@ -191,7 +191,7 @@ async function saveToken(token) {
   const { extensionActive } = await browser.storage.local.get("extensionActive");
   if (!extensionActive) {
     await browser.storage.local.set({ extensionActive: true }); // Met à jour l'état de l'extension
-    updateExtension(); // Met à jour les fonctionnalités de l'extension
+    updateExtension(); // Met à jour les fonctionnalités de l'extension    
     browser.runtime.sendMessage({
       action: "updateUI",
       extensionActive: true,
@@ -508,10 +508,6 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
     const { isActive } = message;
     // Met à jour l'état du suivi des statistiques dans le stockage local
     await browser.storage.local.set({ isTrackingActive: isActive });
-    // Si les statistiques sont désactivées, désactive également l'ajout automatique
-    if (!isActive) {
-      await browser.storage.local.set({ autoAdd: false });
-    }
     // Vérifie et met à jour l'état du suivi des statistiques
     checkAndUpdateTracking();
   }
@@ -525,6 +521,113 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
   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 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) {
+    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();
+  }
+});
+
+// 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)
+    });
+
+  // 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;
+  }
+  log("Envoi du token au Worker...");
+  worker.postMessage({ command: "update-auth-token", accessToken });
+}
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Stoplists : Chargement et envoi au Worker
+// ─────────────────────────────────────────────────────────────────────────────
+async function loadStoplistsForLanguages(languages) {
+  const stoplists = {};
+  // Charger toutes les stoplists en parallèle
+  await Promise.all(
+    languages.map(async (lang) => {
+      const stoplistPath = `src/stoplists/stoplist_${lang}.txt`;
+      try {
+        const response = await fetch(browser.runtime.getURL(stoplistPath));
+        const text = await response.text();
+        stoplists[lang] = text.split("\n").map(word => word.trim());
+        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) {
+  log("[Background] Envoi des stoplists au Worker...");
+  worker.postMessage({ command: "update-stoplist", stoplists });
+}
+
+// Charger les stoplists uniquement quand les lexiques sont disponibles
+browser.runtime.onStartup.addListener(sendLexiconsToWorker);
+browser.runtime.onInstalled.addListener(sendLexiconsToWorker);
 
 // ─────────────────────────────────────────────────────────────────────────────
 // Chargement et sauvegarde des fréquences stockées
@@ -608,6 +711,16 @@ browser.storage.onChanged.addListener(async (changes, area) => {
       autoAdd: autoAdd || false
     });
   }
+
+  //Écoute sur le bouton d'inclusion des mots outils
+  if (area === "local" && changes.includeStopwords) {
+    const includeStopwords = changes.includeStopwords.newValue;
+    log(`[Background] Inclusion des mots outils activé/désactivé: ${includeStopwords}`);
+
+    if (worker) {
+      worker.postMessage({ command: "update-include-stopwords", includeStopwords });
+    }
+  }
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -649,38 +762,6 @@ browser.runtime.onConnect.addListener((port) => {
   }
 });
 
-// ─────────────────────────────────────────────────────────────────────────────
-// Stoplists : Chargement et envoi au Worker
-// ─────────────────────────────────────────────────────────────────────────────
-let stoplistFr = [];
-
-/**
- * Charge la stoplist depuis un fichier et l'envoie au Worker.
- * @returns {void}
- */
-function loadStoplist() {
-  fetch(browser.runtime.getURL("stoplist_fr.txt"))
-    .then(response => response.text())
-    .then(text => {
-      stoplistFr = text.split("\n").map(word => word.trim());
-      log("[Background] Stoplist chargée :", stoplistFr);
-      sendStoplistToWorker();
-    })
-    .catch(error => log("[Background] Erreur lors du chargement de la stoplist :", error));
-}
-
-/**
- * Envoie la stoplist au Worker.
- * @returns {void}
- */
-function sendStoplistToWorker() {
-  log("[Background] Envoi de la stoplist au Worker...");
-  worker.postMessage({ command: "update-stoplist", stoplist: stoplistFr });
-}
-
-browser.runtime.onStartup.addListener(loadStoplist);
-browser.runtime.onInstalled.addListener(loadStoplist);
-
 // ─────────────────────────────────────────────────────────────────────────────
 // Surlignage 
 // ─────────────────────────────────────────────────────────────────────────────
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index 85cad9f0cf8c1fe8d1377e45f981ee8ce9489961..50d28753ba96da1c7e8cb2cf584991c4dad10a2d 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -384,11 +384,23 @@ function hideLexiconPicker() {
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Écouteurs d'événements
 // ─────────────────────────────────────────────────────────────────────────────
-// Écoute globale pour la sélection de texte
+// Écouteur global pour la sélection de texte et la gestion des clics
 document.addEventListener("mouseup", (event) => {
+  const customContextMenu = document.getElementById(CUSTOM_CONTEXT_MENU); // Récupère le menu contextuel
+  const picker = document.getElementById("lexiconPicker"); // Récupère le sélecteur de lexique
+
   // Vérifie si le clic est à l'intérieur du menu contextuel, si oui, ne fait rien
   if (event.target.closest("#customContextMenu")) return;
 
+  // Masque le menu contextuel si le clic est en dehors de celui-ci
+  if (customContextMenu && !customContextMenu.contains(event.target)) {
+    hideCustomContextMenu();
+  }
+  // Masque le sélecteur si le clic est en dehors de celui-ci
+  if (picker && !picker.contains(event.target)) {
+    hideLexiconPicker();
+  }
+
   // Récupère le texte sélectionné
   const selectedText = window.getSelection().toString().trim();
   if (selectedText) {
@@ -426,31 +438,4 @@ browser.storage.onChanged.addListener((changes) => {
     log("Token modifié dans le stockage, mise à jour du menu contextuel.");
     loadAuthToken().then(updateMenuVisibility); // Recharge le token et met à jour la visibilité
   }
-});
-
-// Écouteur pour masquer le menu contextuel et le sélecteur
-document.addEventListener("mouseup", (event) => {
-  const customContextMenu = document.getElementById(CUSTOM_CONTEXT_MENU); // Récupère le menu contextuel
-  const picker = document.getElementById("lexiconPicker"); // Récupère le sélecteur de lexique
-
-  // Masque le menu contextuel si le clic est en dehors de celui-ci
-  if (customContextMenu && !customContextMenu.contains(event.target)) {
-    hideCustomContextMenu();
-  }
-  // Masque le sélecteur si le clic est en dehors de celui-ci
-  if (picker && !picker.contains(event.target)) {
-    hideLexiconPicker();
-  }
-  
-  // Récupère le texte sélectionné
-  const selectedText = window.getSelection().toString().trim();
-  if (selectedText) {
-    log("Texte sélectionné :", selectedText);
-    showCustomContextMenu(event, selectedText);
-    // Envoie un message au runtime avec le texte sélectionné
-    browser.runtime.sendMessage({
-      action: "mot_selectionne",
-      selectedText,
-    });
-  }
 });
\ No newline at end of file
diff --git a/src/css/sidebar.css b/src/css/sidebar.css
index 76e6dc47dca1b3ee394a2140d59132ae7a59df7e..4c445fbda34d04fe6fae713d999f54bd9ddf10e2 100644
--- a/src/css/sidebar.css
+++ b/src/css/sidebar.css
@@ -231,11 +231,17 @@ button.lexique-highlight-toggle:hover .tooltip {
   margin-bottom: 10px;
 }
 .lexicon-header {
-  font-weight: bold;
-  cursor: pointer;
+  position: relative;         
   padding: 5px;
+  padding-right: 20px;        
   background-color: #8d5c70;
   border-radius: 5px;
+  cursor: pointer;
+}
+.lexicon-header span {
+  display: block;
+  font-size: 13px;
+  line-height: 1.2;
   text-align: center;
 }
 .lexicon-header:hover {
@@ -244,6 +250,7 @@ button.lexique-highlight-toggle:hover .tooltip {
 }
 .lexicon-content {
   margin-top: 5px;
+  width: auto;
 }
 .lexicon-option {
   margin-right: -10px;
@@ -256,6 +263,17 @@ button.lexique-highlight-toggle:hover .tooltip {
 #mesLexiquesContainer h4 {
   margin-bottom: 5px;
 }
+#wiktionnaireContainer h4 {
+  margin-bottom: 2px !important;
+}
+.balex-icon {
+  position: absolute;
+  top: 50%;
+  right: 10px;                
+  transform: translateY(-50%);
+  cursor: zoom-in;            
+  flex-shrink: 0;
+}
 
 /* Cases à cocher pour les lexiques */
 .lexique-checkbox {
@@ -336,6 +354,10 @@ button.lexique-highlight-toggle:hover .tooltip {
 }
 
 /* Section Définitions */
+.definition-item {
+  font-size: 13px;
+  padding-left: 10px;
+}
 #definitionContainer {
   background-color: #444;
   padding: 10px;
@@ -344,7 +366,7 @@ button.lexique-highlight-toggle:hover .tooltip {
 }
 #definitionsList {
   list-style: none;
-  padding: 0;
+  padding: 2px;
 }
 #definitionsList li {
   margin-bottom: 10px;
@@ -358,6 +380,14 @@ button.lexique-highlight-toggle:hover .tooltip {
   color: red !important;
   font-weight: bold;
 }
+#wiktionnaireList .definition-item {
+  font-size: 13px;
+  padding-left: 2px;
+  padding-top: 0;
+}
+#wiktionnaireList {
+  padding-left: 2px;
+}
 
 /* Modal de définition */
 .modal-overlay {
diff --git a/src/plugin/displayStats.js b/src/plugin/displayStats.js
new file mode 100644
index 0000000000000000000000000000000000000000..cc949856424e2b7c38170150ab2076b9428d1749
--- /dev/null
+++ b/src/plugin/displayStats.js
@@ -0,0 +1,145 @@
+// stats.js
+document.addEventListener("DOMContentLoaded", async () => {
+  // Fonction pour recalculer et stocker le résumé des statistiques
+  async function updateStatsSummary() {
+    console.log("[Stats Page] Mise à jour du résumé des statistiques...");
+    
+    const { 
+      lemmaFrequencies = {}, 
+      trackedLanguages = [], 
+      wordsAdded = {} 
+    } = await browser.storage.local.get([
+      "lemmaFrequencies",
+      "trackedLanguages",
+      "wordsAdded"
+    ]);
+  
+    let totalWords = 0, totalUniqueWords = 0;
+    const languages = {};
+  
+    for (const [lang, words] of Object.entries(lemmaFrequencies)) {
+      if (!trackedLanguages.length || trackedLanguages.includes(lang)) {
+        let wordCount = 0;
+        let uniqueWordCount = 0;
+        for (const count of Object.values(words)) {
+          wordCount += count;
+          uniqueWordCount++;
+        }
+        languages[lang] = { totalWords: wordCount, uniqueWords: uniqueWordCount };
+        totalWords += wordCount;
+        totalUniqueWords += uniqueWordCount;
+      }
+    }
+  
+    const summary = {
+      totalWords,
+      totalUniqueWords,
+      languages,
+      wordsAdded
+    };
+  
+    console.log("[Stats Page] Résumé des statistiques mis à jour:", summary);
+    await browser.storage.local.set({ statsSummary: summary });
+    return { summary, lemmaFrequencies, trackedLanguages };
+  }
+  
+  // Générer le HTML du résumé global
+  function generateSummaryHTML(summary) {
+    if (summary.totalWords === 0) {
+      return `<h2>Résumé des statistiques</h2>
+              <p>Aucune statistique disponible pour le moment.</p>`;
+    }
+    return `
+      <h2>Résumé des statistiques</h2>
+      <p>Date : ${new Date().toLocaleDateString()}</p>
+      <p>Total de mots analysés : ${summary.totalWords}</p>
+      <p>Total de mots uniques : ${summary.totalUniqueWords}</p>
+    `;
+  }
+  
+  // Générer le contrôle de tri (placé juste au-dessus des tableaux)
+  function generateSortControlHTML(currentSortOrder) {
+    return `
+      <div id="sort-container">
+        <label for="sort-order">Trier par fréquence : </label>
+        <select id="sort-order">
+          <option value="desc" ${currentSortOrder === "desc" ? "selected" : ""}>Décroissante</option>
+          <option value="asc" ${currentSortOrder === "asc" ? "selected" : ""}>Croissante</option>
+        </select>
+      </div>
+    `;
+  }
+  
+  // Générer le HTML détaillé pour chaque langue avec le total par langue
+  function generateDetailedFrequenciesHTML(lemmaFrequencies, trackedLanguages, sortOrder) {
+    let detailsHTML = `<div id="detailed-frequencies">`;
+    let hasData = false;
+  
+    for (const [lang, words] of Object.entries(lemmaFrequencies)) {
+      if (!trackedLanguages.length || trackedLanguages.includes(lang)) {
+        let wordEntries = Object.entries(words);
+        if (wordEntries.length === 0) {
+          detailsHTML += `<h4>${lang.toUpperCase()}</h4>
+                          <p>Aucune donnée pour cette langue.</p>`;
+        } else {
+          hasData = true;
+          // Calculer le total pour cette langue
+          const totalForLang = wordEntries.reduce((acc, curr) => acc + curr[1], 0);
+          // Trier les mots par fréquence
+          wordEntries.sort((a, b) => sortOrder === "asc" ? a[1] - b[1] : b[1] - a[1]);
+          detailsHTML += `<h4>${lang.toUpperCase()} (Total: ${totalForLang} mots)</h4>`;
+          detailsHTML += `<div class="table-container">
+                          <table>
+                            <tr>
+                              <th>Mot</th>
+                              <th>Fréquence</th>
+                            </tr>`;
+          for (const [word, freq] of wordEntries) {
+            detailsHTML += `<tr>
+                              <td>${word}</td>
+                              <td>${freq}</td>
+                            </tr>`;
+          }
+          // // Ligne de récapitulation pour le total de mots de la langue
+          // detailsHTML += `<tr>
+          //                   <td colspan="2" style="text-align:right; font-weight:bold;">
+          //                     AJOUT: Total 
+          //                     : ${totalForLang}
+          //                   </td>
+          //                 </tr>`;
+          detailsHTML += `</table>
+                          </div>`;
+        }
+      }
+    }
+  
+    if (!hasData) {
+      detailsHTML += `<p>Aucune donnée de fréquence à afficher.</p>`;
+    }
+    detailsHTML += `</div>`;
+    return detailsHTML;
+  }
+  
+  const container = document.getElementById("stats-container");
+  let currentSortOrder = "desc";
+  
+  const { summary, lemmaFrequencies, trackedLanguages } = await updateStatsSummary();
+  container.innerHTML = generateSummaryHTML(summary) +
+                        generateSortControlHTML(currentSortOrder) +
+                        generateDetailedFrequenciesHTML(lemmaFrequencies, trackedLanguages, currentSortOrder);
+  
+  // Écouteur pour mettre à jour l'affichage lorsque l'utilisateur change l'ordre de tri
+  document.getElementById("sort-order").addEventListener("change", async (e) => {
+    currentSortOrder = e.target.value;
+    const data = await updateStatsSummary();
+    const detailedHTML = generateDetailedFrequenciesHTML(data.lemmaFrequencies, data.trackedLanguages, currentSortOrder);
+    const detailedContainer = document.getElementById("detailed-frequencies");
+    if (detailedContainer) {
+      detailedContainer.outerHTML = detailedHTML;
+    } else {
+      container.innerHTML = generateSummaryHTML(data.summary) +
+                            generateSortControlHTML(currentSortOrder) +
+                            detailedHTML;
+    }
+  });
+});
diff --git a/src/plugin/plugin.html b/src/plugin/plugin.html
index 98cb1c18abfeeac6e7fa50a33c7fb66b1c1dc9a3..ca17e78d592e801a20fe1145af7ac348e654abf3 100644
--- a/src/plugin/plugin.html
+++ b/src/plugin/plugin.html
@@ -9,7 +9,7 @@
 </head>
 <body>
   <div id="extension-name">Extension BaLex</div>
-
+  
   <!-- Section de connexion -->
   <div id="auth-section">
     <button id="auth-button">
@@ -26,9 +26,9 @@
   <button id="toggleExtensionBtn">Activer/Désactiver</button>
   <button id="toggleStatsBtn">Statistiques</button>
   <button id="open-stats">Afficher les statistiques</button>
-  <!-- Indicateur de chargement de Pyodide -->
+    <!-- Indicateur de chargement de Pyodide -->
   <div id="pyodide-loading"></div>
-  
+
   <!-- Section des options d'ajout automatique -->
   <div id="stats-options" class="option-container">
     <div id="auto-add-container" class="option-row auto-add-row">
@@ -38,30 +38,30 @@
         <span class="slider"></span>
       </label>
     </div>
-    <div id="auto-add-options" class="hidden">
-      <div class="option-row stopwords">
-        <span>Inclure mots outils</span>
-        <label class="toggle-switch">
-          <input type="checkbox" id="include-stopwords" />
-          <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 id="auto-add-options" class="hidden">
+    <div class="option-row stopwords">
+      <span>Inclure mots outils</span>
+      <label class="toggle-switch">
+        <input type="checkbox" id="include-stopwords" />
+        <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 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>
+      <p>Veuillez sélectionner une ou plusieurs langue(s).</p>
+    </div>      
+    <button id="save-options" class="hidden">Valider</button>
+  </div>
   </div>
 
   <!-- Notification de l'extension -->
diff --git a/src/plugin/plugin.js b/src/plugin/plugin.js
index f95ae3890bded642a9276209a4c33485b8ae581b..91d6795a4b750df0fe112b2890cca74412785c17 100644
--- a/src/plugin/plugin.js
+++ b/src/plugin/plugin.js
@@ -11,25 +11,245 @@ async function getAccessToken() {
   return accessToken;
 }
 
-// ─────────────────────────────────────────────────────────────────────────────
-// ▌ Gestion de la connexion
-// ─────────────────────────────────────────────────────────────────────────────
-/**
- * Met à jour le bouton de connexion en fonction de l'état de connexion.
- */
+// =========
+// 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
+}
+
+// =========
+// 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 
+  };
+}
+
+// =========
+// 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);
+}
+
+
+
+// ====================================================================================
+// 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);
+
+  // Bouton activer l'extension
+  document.getElementById("toggleExtensionBtn")?.addEventListener("click", handleToggleExtension);
+
+  // Bouton de gestion des statistiques
+  document.getElementById("toggleStatsBtn")?.addEventListener("click", handleStatsToggle);
+
+  // Gestion de l'ajout automatique
+  document.getElementById("auto-add")?.addEventListener("change", handleAutoAddToggle);
+  
+  //Activation/désactivation des stopwords
+  document.getElementById("include-stopwords")?.addEventListener("change", handleStopwordsToggle);
+  
+  // Sauvegarde des options
+  document.getElementById("save-options")?.addEventListener("click", handleSaveOptions);
+
+  // Ouverture de la page des statistiques
+  // TODO : ajouter l'évènement
+  document.getElementById("open-stats")?.addEventListener("click", () => {
+    window.open("stats.html", "_blank");
+  });
+}
+
+// ===========
+//Description de chaque évènement
+
+//Connexion / Déconnexion
+async function handleAuthToggle() {
+  const accessToken = await getAccessToken();
+  if (!accessToken) {
+    console.log("🔓 Connexion demandée...");
+    await browser.runtime.sendMessage({ action: "toggleAuth" });
+  } else {
+    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();
+}
+
+//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 });
+  // Ouvrir la page des statistiques si désactivé
+  if (!newState) {
+    openStatsPage(); 
+  }
+  // Exécution de Pyodide si nécessaire
+  if (newState) {
+    browser.runtime.sendMessage({ command: "pyodide-simplemma" });
+  }
+
+//   if (isUpdatingLexicons) return; 
+//   isUpdatingLexicons = true;
+//   await updateLexiconsDisplay(); 
+//   isUpdatingLexicons = false;
+//   await updateExtension();
+}
+
+// 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 });
+
+  if (!newState) {
+    await browser.storage.local.set({ isTrackingActive: false });
+    if (isTrackingActive) window.open("stats.html", "_blank");
+    browser.runtime.sendMessage({ action: "closeSidebarBlocks" });
+  }
+
+  browser.runtime.sendMessage({ action: "toggleExtension", isActive: newState });
+  await updateExtension();
+}
+
+
+//Ajout automatique
+function handleAutoAddToggle() {
+  const autoAddCheckbox = document.getElementById("auto-add");
+  const autoAddOptions = document.getElementById("auto-add-options");
+  const saveOptionsBtn = document.getElementById("save-options");
+
+  if (!autoAddCheckbox || !autoAddOptions || !saveOptionsBtn) return;
+
+  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;
+    console.log("Ajout automatique désactivé → Stopwords désactivés immédiatement.");
+  }
+}
+
+
+// Gestion de l'activation/désactivation des stopwords
+function handleStopwordsToggle() {
+  const stopwordsCheckbox = document.getElementById("include-stopwords");
+  if (!stopwordsCheckbox) return;
+
+  // 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
+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 errorMessage = document.getElementById("error-message");
+
+  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: autoAddCheckbox.checked,
+    includeStopwords: stopwordsCheckbox.checked,
+    threshold,
+    trackedLanguages: selectedLanguages
+  });
+
+  browser.runtime.sendMessage({
+    command: "update-preferences",
+    autoAdd: autoAddCheckbox.checked,
+    includeStopwords: stopwordsCheckbox.checked
+  });
+
+  await updateExtension();
+  console.log("✅ Options sauvegardées.");
+}
+
+
+//Ouverture de la page des statistiques
+
+// ====================================================================================
+// Fonction actualisation UI des boutons
+// ====================================================================================
+
+// Gestion de la connexion
 async function updateConnectionButton() {
-  // Récupération du token d'accès
   const accessToken = await getAccessToken();
-  // Sélection du bouton de connexion
+  //Vérification du bouton de connexion
   const button = document.getElementById("auth-button");
-
-  // Vérification si le bouton existe
   if (!button) {
-    log("Le bouton de connexion n'a pas été trouvé.");
+    console.error("❌ Le bouton de connexion n'a pas été trouvé.");
     return;
   }
-
-  // Mise à jour du bouton en fonction de l'état de connexion
   if (accessToken) {
     button.textContent = "Se déconnecter";
     button.style.position = "relative";
@@ -65,27 +285,33 @@ async function updateLanguageSelection() {
   const languageSelection = document.getElementById("language-selection");
   languageSelection.innerHTML = "<p id='loading-languages' style='color: gray;'>Chargement...</p>";
 
-  const accessToken = await getAccessToken();
-  // Vérification si l'utilisateur est connecté
-  if (!accessToken) {
-    languageSelection.innerHTML = "<p style='color: red;'>Veuillez vous connecter.</p>";
+  const storedData = await browser.storage.local.get("lexicons");
+  const lexicons = storedData.lexicons || []; // Ne pas utiliser JSON.parse()
+
+  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>";
+
+    // É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;
   }
 
-  // Récupération des lexiques et langues de l'utilisateur
-  const lexicons = await getLexicons(accessToken);
+  // Extraire les langues uniques
   const userLanguages = [...new Set(lexicons.map(lex => lex.language))];
 
-  // Récupération des langues suivies depuis le stockage local
-  const { trackedLanguages } = await browser.storage.local.get("trackedLanguages") || { trackedLanguages: [] };
+  // 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 = "";
-  if (userLanguages.length === 0) {
-    languageSelection.innerHTML = "<p style='color: red;'>Aucun lexique personnel trouvé.</p>"; // Message d'erreur si aucun lexique
-    return; 
-  }
-
-  // Création des boutons pour chaque langue
   userLanguages.forEach(lang => {
     const langButton = document.createElement("div");
     langButton.classList.add("lang-option");
@@ -105,54 +331,22 @@ async function updateLanguageSelection() {
   log("Sélection des langues mise à jour avec :", userLanguages);
 }
 
-// ─────────────────────────────────────────────────────────────────────────────
-// ▌ Gestion principale de l'extension
-// ─────────────────────────────────────────────────────────────────────────────
-/**
- * Met à jour l'extension.
- */
-async function updateExtension() {
-  // Récupération de tous les états nécessaires
-  const accessToken = await getAccessToken();
-  const { 
-    extensionActive, 
-    isTrackingActive, 
-    autoAdd, 
-    threshold,
-    pyodideSimplemmaReady 
-  } = await browser.storage.local.get([
-    "extensionActive",
-    "isTrackingActive",
-    "autoAdd",
-    "threshold",
-    "pyodideSimplemmaReady"
-  ]) || { 
-    extensionActive: false, 
-    isTrackingActive: false,
-    autoAdd: false,
-    threshold: 10,
-    pyodideSimplemmaReady: false
-  };
-
-  // Vérification si l'utilisateur est connecté
-  const isLoggedIn = !!accessToken;
-
-  // Mise à jour du bouton d'activation de l'extension
+// =========
+// Gestion bouton d'activation de l'extension
+async function updateToggleExtensionButton(isLoggedIn, extensionActive, autoAdd, isTrackingActive, pyodideSimplemmaReady, includeStopwords) {
   const toggleExtensionBtn = document.getElementById("toggleExtensionBtn");
+
   if (toggleExtensionBtn) {
-    // Mise à jour du texte du bouton en fonction de l'état de l'extension
     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";
 
-    // Suppression de l'ancien tooltip s'il existe
     const existingTooltipExt = toggleExtensionBtn.querySelector('.tooltip');
     if (existingTooltipExt) {
       existingTooltipExt.remove();
     }
-    // Création d'un nouveau tooltip
     const tooltipExt = document.createElement("span");
     tooltipExt.className = "tooltip";
     tooltipExt.style.opacity = "1 !important";
@@ -166,16 +360,12 @@ async function updateExtension() {
       tooltipExt.style.display = "none";
     }
     toggleExtensionBtn.appendChild(tooltipExt);
-    
-    toggleExtensionBtn.onclick = handleToggleExtension;
   }
 
   // Mise à jour des options de statistiques
   const statsOptions = document.getElementById("stats-options");
   const toggleStatsBtn = document.getElementById("toggleStatsBtn");
   const openStats = document.getElementById("open-stats");
-
-  // Affichage ou masquage des options de statistiques
   if (statsOptions) {
     statsOptions.style.display = (isLoggedIn && extensionActive) ? "block" : "none";
   }
@@ -188,12 +378,8 @@ async function updateExtension() {
     toggleStatsBtn.disabled = !isEnabled;
     toggleStatsBtn.style.position = "relative";
     toggleStatsBtn.className = "tooltip-container";
-    
-    // Suppression de l'ancien tooltip s'il existe
     const existingTooltipStats = toggleStatsBtn.querySelector('.tooltip');
     if (existingTooltipStats) { existingTooltipStats.remove(); }
-    
-    // Création d'un nouveau tooltip pour les statistiques
     const tooltipStats = document.createElement("span");
     tooltipStats.className = "tooltip";
     tooltipStats.style.opacity = "1 !important";
@@ -208,8 +394,6 @@ async function updateExtension() {
     }
     toggleStatsBtn.appendChild(tooltipStats);
   }
-
-  // Affichage ou masquage du bouton pour ouvrir les statistiques
   if (openStats) {
     openStats.style.display = (isLoggedIn && extensionActive && isTrackingActive) ? "block" : "none";
   }
@@ -265,170 +449,40 @@ async function updateExtension() {
     extensionActive,
     isTrackingActive,
     autoAdd,
-    pyodideSimplemmaReady
+    pyodideSimplemmaReady,
+    includeStopwords
   });
 }
 
-/**
- * Gère le clic sur le bouton d'activation de l'extension (analyse).
- */
-async function handleToggleExtension() {
-  const accessToken = await getAccessToken();
-  if (!accessToken) return;
-  await proceedToggleExtension();
-  await updateConnectionButton();
-}
-
-/**
- * Effectue le changement d'état de l'extension (analyse).
- */
-async function proceedToggleExtension() {
-  // Récupération de l'état actuel de l'extension et du suivi
-  const { extensionActive, isTrackingActive } = await browser.storage.local.get({
-    extensionActive: false, // Valeur par défaut si non trouvée
-    isTrackingActive: false // Valeur par défaut si non trouvée
-  });
-  log("État actuel de extensionActive avant changement :", extensionActive);
-
-  const newState = !extensionActive;
-  // Mise à jour de l'état de l'extension dans le stockage local
-  await browser.storage.local.set({ extensionActive: newState });
-  log("Nouvel état de extensionActive :", newState);
-
-  // Envoi d'un message pour mettre à jour l'interface utilisateur
-  browser.runtime.sendMessage({ action: "updateUI", extensionActive: newState });
-
-  // Si l'extension est désactivée
-  if (!newState) {
-    // Désactivation du suivi
-    await browser.storage.local.set({ isTrackingActive: false });
-    // Ouverture de la page des statistiques si le suivi était actif
-    if (isTrackingActive) window.open("stats.html", "_blank");
-    // Envoi d'un message pour fermer les blocs de la barre latérale
-    browser.runtime.sendMessage({ action: "closeSidebarBlocks" });
+//Activer/désactiver les stoplists
+async function updateStopwordsOption(includeStopwords) {
+  const stopwordsCheckbox = document.getElementById("include-stopwords");
+  if (stopwordsCheckbox) {
+    stopwordsCheckbox.checked = includeStopwords;
   }
-
-  // Envoi d'un message pour changer l'état de l'extension
-  browser.runtime.sendMessage({ action: "toggleExtension", isActive: newState });
-  // Mise à jour de l'extension après le changement d'état
-  await updateExtension();
 }
 
-// ─────────────────────────────────────────────────────────────────────────────
-// ▌ Écouteurs d'événements
-// ─────────────────────────────────────────────────────────────────────────────
-/**
- * Met à jour le bouton de connexion et l'extension lorsque le DOM est chargé.
- */
-document.addEventListener("DOMContentLoaded", async () => {
-  await updateConnectionButton();
-  await updateExtension();
-});
 
-/**
- * Gère le clic sur le bouton des statistiques.
- */
-document.getElementById("toggleStatsBtn")?.addEventListener("click", async () => {
-  const accessToken = await getAccessToken();
-  if (!accessToken) return;
 
-  // Récupération de l'état actuel du suivi
-  const current = await browser.storage.local.get("isTrackingActive");
-  const newState = !current.isTrackingActive;
-  await browser.storage.local.set({ isTrackingActive: newState });
-
-  // Si le suivi est désactivé, désactiver également l'ajout automatique
-  if (!newState) {
-    await browser.storage.local.set({ autoAdd: false });
-  }
-
-  // Envoi d'un message pour changer l'état des statistiques
-  browser.runtime.sendMessage({ command: "toggle-stats", isActive: newState });
-  // Si le suivi est activé, envoyer un message pour pyodide-simplemma
-  if (newState) {
-    browser.runtime.sendMessage({ command: "pyodide-simplemma" });
-  }
-  
-  // Mise à jour de l'affichage des lexiques
-  if (isUpdatingLexicons) return; 
-  isUpdatingLexicons = true;
-  await updateLexiconsDisplay(); 
-  isUpdatingLexicons = false;
-  await updateExtension();
-});
-
-/**
- * Gère le changement de l'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);
-  
-  // Si l'ajout automatique est désactivé, mettre à jour l'état
-  if (!isChecked) {
-    await browser.storage.local.set({ autoAdd: false });
-    await updateExtension();
-  }
-});
-
-/**
- * Sauvegarde des options.
- */
-document.getElementById("save-options")?.addEventListener("click", async () => {
-  const autoAdd = document.getElementById("auto-add").checked;
-  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 errorMessage = document.getElementById("error-message");
-  // Vérification si l'ajout automatique est activé sans langues sélectionnées
-  if (autoAdd && selectedLanguages.length === 0) {
-    errorMessage?.classList.remove("hidden"); // Affichage du message d'erreur
-    return; 
-  }
-  errorMessage?.classList.add("hidden");
-
-  // Sauvegarde des options dans le stockage local
-  await browser.storage.local.set({
-    autoAdd,
-    threshold,
-    trackedLanguages: selectedLanguages
-  });
-  
-  await updateExtension();
-  log("Options sauvegardées et interface mise à jour");
-});
-
-/**
- * Ouvre la page des statistiques.
- */
-document.getElementById("open-stats")?.addEventListener("click", () => {
-  window.open("stats.html", "_blank");
-});
-
-/**
- * Affiche le message d'information sur les langues suivies.
- */
-document.addEventListener("DOMContentLoaded", () => {
-  const optionRows = document.querySelectorAll('.option-row label');
-  optionRows.forEach(label => {
-    if (label.textContent.trim() === "Langues suivies") {
-      label.classList.add("tooltip-container");
-
-      const tooltip = document.createElement("span");
-      tooltip.className = "tooltip tooltip-langues-suivies";
-      tooltip.textContent = "Choisissez une ou plusieurs langues parmi celles de vos lexiques personnels";
-      label.appendChild(tooltip);
-    }
-  });
+// ✅ 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
 });
 
-// ─────────────────────────────────────────────────────────────────────────────
-// ▌ Gestion des messages 
-// ─────────────────────────────────────────────────────────────────────────────
+// !! 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();
+//   }
+// });
+
+// ==========================
+// Gestion des messages et du stockage
+// ==========================
 browser.runtime.onMessage.addListener(async (message) => {
-  log("Message reçu dans plugin.js :", message);
+  log("📩 Message reçu dans popup.js :", message);
   if (message.action === "updateUI") {
     await updateExtension();
   } else if (message.action === "notify") {
@@ -474,6 +528,21 @@ function handleWorkerMessage(event) {
       message: data.message
     });
     return;
-  }
+  }}
+
+
+// ==========================
+// Affichage des statistiques
+// ==========================
+
+// Bouton pour ouvrir la page des statistiques
+document.getElementById("open-stats")?.addEventListener("click", async () => {
+  openStatsPage();
+});
+
+function openStatsPage() {
+  browser.tabs.create({
+    url: browser.runtime.getURL("stats.html")
+  });
 }
 
diff --git a/src/plugin/stats.html b/src/plugin/stats.html
new file mode 100644
index 0000000000000000000000000000000000000000..9cbe36c42ed0932f25ce5b80748ab5014ad2cd07
--- /dev/null
+++ b/src/plugin/stats.html
@@ -0,0 +1,56 @@
+<!-- stats.html -->
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+  <meta charset="UTF-8">
+  <title>Résumé des statistiques</title>
+  <script src="displayStats.js"></script>
+  <style>
+    /* Style global pour une présentation compacte et lisible */
+    body {
+      font-family: Arial, sans-serif;
+      margin: 20px;
+      padding: 0;
+    }
+    #stats-container {
+      max-width: 600px;
+      margin: 0 auto;
+    }
+    /* Contrôle de tri centré et espacé */
+    #sort-container {
+      margin: 20px 0;
+      text-align: center;
+    }
+    /* Tableaux compacts */
+    table {
+      width: 100%;
+      border-collapse: collapse;
+      font-size: 0.85em;
+      margin-bottom: 15px;
+    }
+    table, th, td {
+      border: 1px solid #ddd;
+    }
+    th, td {
+      padding: 6px 8px;
+      text-align: left;
+    }
+    th {
+      background-color: #ae8bac;
+    }
+    h4 {
+      margin-bottom: 5px;
+    }
+    /* Optionnel : encadrer les tableaux dans un conteneur avec défilement si trop de lignes */
+    .table-container {
+      max-height: 300px;
+      overflow-y: auto;
+    }
+  </style>
+</head>
+<body>
+  <div id="stats-container">
+    <p>Chargement des statistiques…</p>
+  </div>
+</body>
+</html>
diff --git a/src/sidebar/sidebar.html b/src/sidebar/sidebar.html
index fce4745e7dfc2f650699a92c3bf1825bb17fd33e..62bba510c550df4a77156adbc34494cb79e8f338 100644
--- a/src/sidebar/sidebar.html
+++ b/src/sidebar/sidebar.html
@@ -32,7 +32,7 @@
       <button class="toggle-btn">+</button> <!-- Bouton pour afficher/masquer le bloc -->
     </div>
     <div id="menuContent" class="block-content hidden">
-      <div id="lexiques">Chargement...</div> 
+      <div id="lexiques">Chargement...</div>
     </div>
   </div>
 
@@ -42,8 +42,8 @@
       <h3>Mot sélectionné</h3>
       <button class="toggle-btn"></button>
     </div>
-    <div id="etatContent" class="block-content hidden"> 
-      <p id="motSelectionne">Aucun mot sélectionné</p> 
+    <div id="etatContent" class="block-content hidden">
+      <p id="motSelectionne">Aucun mot sélectionné</p>
       <p id="lexiconResult"></p>
       <div id="add-to-lexiques" style="display: none;">
         <button id="add-word-button">Ajouter le mot sélectionné</button>
@@ -63,7 +63,7 @@
       <!-- Définitions des lexiques de l'utilisateur -->
       <div id="mesLexiquesContainer">
         <h4>📚 Mes lexiques</h4>
-        <label style="font-size: small;">
+        <label style="font-size: 12px;">
           <input type="checkbox" id="toggle-definitions">
           Afficher toutes les définitions
         </label>
diff --git a/src/stoplists/stoplist_en.txt b/src/stoplists/stoplist_en.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0
--- /dev/null
+++ b/src/stoplists/stoplist_en.txt
@@ -0,0 +1 @@
+hello
\ No newline at end of file
diff --git a/src/stoplists/stoplist_fr.txt b/src/stoplists/stoplist_fr.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3a98580e221f3b4416ab3bfe9863941ae1951e34
--- /dev/null
+++ b/src/stoplists/stoplist_fr.txt
@@ -0,0 +1,117 @@
+chat
+alors
+au
+aucuns
+aussi
+autre
+avant
+avec
+avoir
+bon
+car
+ce
+cela
+ces
+ceux
+chaque
+ci
+comme
+comment
+dans
+des
+du
+dedans
+dehors
+depuis
+devrait
+doit
+donc
+dos
+début
+elle
+elles
+en
+encore
+essai
+est
+et
+eu
+fait
+faites
+fois
+font
+hors
+ici
+il
+ils
+je
+juste
+la
+le
+les
+leur
+là
+ma
+maintenant
+mais
+mes
+mien
+moins
+mon
+mot
+même
+ni
+nommés
+notre
+nous
+ou
+où
+par
+parce
+pas
+peut
+peu
+plupart
+pour
+pourquoi
+quand
+que
+quel
+quelle
+quelles
+quels
+qui
+sa
+sans
+ses
+seulement
+si
+sien
+son
+sont
+sous
+soyez
+sujet
+sur
+ta
+tandis
+tellement
+tels
+tes
+ton
+tous
+tout
+trop
+très
+tu
+voient
+vont
+votre
+vous
+vu
+ça
+étaient
+état
+étions
+été
+être
\ No newline at end of file
diff --git a/src/utils/api.js b/src/utils/api.js
index efcd5749ab1841bcde21902e6142c221a7067bfa..bf833a23530ef542724ba837c32b667943f39916 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -96,45 +96,45 @@ async function getAllLexiconWords(authToken) {
   try {
     // 1) Récupération de la liste des lexiques
     const lexicons = await getLexicons(authToken);
-    
-    // Vérification si la liste des lexiques est valide
-    if (!Array.isArray(lexicons) || lexicons.length === 0) {
-      console.warn("⚠️ Aucun lexique retourné par l'API pour ces paramètres.");
-      return {};
-    }
 
-    // 2) Pour chaque lexique, on récupère ses entrées via /api/lexicon/entries/{id}
-    const allGraphiesByLexicon = {};
+        // Vérification si la liste des lexiques est valide
+        if (!Array.isArray(lexicons) || lexicons.length === 0) {
+          console.warn("⚠️ Aucun lexique retourné par l'API pour ces paramètres.");
+          return {};
+        }
+    
+        // 2) Pour chaque lexique, on récupère ses entrées via /api/lexicon/entries/{id}
+        const allGraphiesByLexicon = {};
+        
+        for (const lexicon of lexicons) {
+          // Récupération des entrées pour le lexique actuel
+          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;
+          }
+          // Extraction des graphies des entrées
+          const allGraphies = entries.map(entry => entry.graphy);
+          
+          // Création d'un libellé unique pour le lexique
+          const lexiconName =
+            lexicon.category === "User"
+              ? `Lexique personnel (${lexicon.user?.pseudo || "Inconnu"}) [${lexicon.id}]`
+              : `Lexique de groupe (${lexicon.group?.name || "Inconnu"}) [${lexicon.id}]`;
+          
+          // Stockage des graphies par lexique
+          allGraphiesByLexicon[lexiconName] = allGraphies;
+        }
     
-    for (const lexicon of lexicons) {
-      // Récupération des entrées pour le lexique actuel
-      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;
+        log("Toutes les graphies récupérées :", allGraphiesByLexicon);
+        return allGraphiesByLexicon;
+      } catch (error) {
+        log("Erreur lors de la récupération des graphies des lexiques :", error);
+        return {};
       }
-      // Extraction des graphies des entrées
-      const allGraphies = entries.map(entry => entry.graphy);
-      
-      // Création d'un libellé unique pour le lexique
-      const lexiconName =
-        lexicon.category === "User"
-          ? `Lexique personnel (${lexicon.user?.pseudo || "Inconnu"}) [${lexicon.id}]`
-          : `Lexique de groupe (${lexicon.group?.name || "Inconnu"}) [${lexicon.id}]`;
-      
-      // Stockage des graphies par lexique
-      allGraphiesByLexicon[lexiconName] = allGraphies;
     }
-
-    log("Toutes les graphies récupérées :", allGraphiesByLexicon);
-    return allGraphiesByLexicon;
-  } catch (error) {
-    log("Erreur lors de la récupération des graphies des lexiques :", error);
-    return {};
-  }
-}
-
+    
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Récupération de définition du Wiktionnaire
 // ─────────────────────────────────────────────────────────────────────────────
diff --git a/src/utils/definitions.js b/src/utils/definitions.js
index 881ed5152af74d776f828132c832a4a737057147..d8ff193d60da2a0cbceb271731b6b58b08dfd646 100644
--- a/src/utils/definitions.js
+++ b/src/utils/definitions.js
@@ -1,5 +1,5 @@
 // ─────────────────────────────────────────────────────────────────────────────
-// ▌ Récupération des définitions (lexiques + Wiktionnaire)
+// ▌ Fonctions pour récupérer/afficher les définitions
 // ─────────────────────────────────────────────────────────────────────────────
 
 window.lexiconMap = new Map();
@@ -27,7 +27,7 @@ async function fetchLexiconDefinitions(word) {
       throw new Error(`❌ Erreur API lors de la récupération des lexiques: ${lexResponse.statusText}`);
     }
     const userLexicons = await lexResponse.json();
-    log("🗂️ Lexiques de l'utilisateur :", userLexicons);
+    log("Lexiques de l'utilisateur :", userLexicons);
 
     if (!Array.isArray(userLexicons) || userLexicons.length === 0) {
       console.warn("⚠️ Aucun lexique trouvé pour cet utilisateur.");
@@ -72,7 +72,7 @@ async function fetchLexiconDefinitions(word) {
 
     const results = await Promise.all(definitionsPromises);
 
-    // 3) Parcourir les résultats et extraire les définitions
+    // 3) Parcourir les résultats et extraire les définitions + prononciations
     let allDefinitions = [];
     results.forEach(result => {
       log(`Pour le lexique ${result.lexiconId}, entrées filtrées :`, result.entries);
@@ -91,8 +91,17 @@ async function fetchLexiconDefinitions(word) {
           }
         }
 
+        const balexId = entry.balex_id || null;
+
         items.forEach(item => {
           const definitionsArray = item.Sense?.Definitions;
+          const pronunciationsArray = item.Sense?.Pronunciations;
+
+          let pronunciations = [];
+          if (Array.isArray(pronunciationsArray)) {
+            pronunciations = pronunciationsArray.map(p => p.Transcription).filter(p => p);
+          }
+
           if (!Array.isArray(definitionsArray)) return;
 
           definitionsArray.forEach(defObj => {
@@ -100,6 +109,8 @@ async function fetchLexiconDefinitions(word) {
               allDefinitions.push({
                 source: sourceName,
                 text: defObj.Def,
+                balex_id: balexId,  
+                pronunciations: pronunciations,
                 lexiconId: lexiconId
               });
             }
@@ -107,31 +118,36 @@ async function fetchLexiconDefinitions(word) {
         });
       });
     });
-
-    log("Résultat final filtré :", allDefinitions);
-    return allDefinitions;
-  } catch (error) {
-    log("Erreur générale lors de la récupération des définitions :", error);
-    return [];
-  }
-}
+    log("Résultats filtré depuis les lexiques utilisateurs :", allDefinitions);
+        return allDefinitions;
+      } catch (error) {
+        log("❌ Erreur générale lors de la récupération des définitions :", error);
+        return [];
+      }
+    }
 
 /**
- * Récupère la définition d'un mot depuis le Wiktionnaire (fr).
- * Retourne un tableau d'objets : [{ source: 'Wiktionnaire', text: '...' }]
- * @param {string} word - Le mot dont on veut la définition.
- * @returns {Promise<object[]>} - Un tableau d'objets contenant la définition.
- */
+* 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 {
     const result = await browser.storage.local.get("accessToken");
     authToken = result.accessToken;
 
+    // 🔹 Initialisation d'une structure vide pour éviter les erreurs
+    let formattedData = {
+      definitions: [],
+      pronunciations: [],
+      definitionsByPOS: {}  // Pour stocker les définitions triées par POS
+    };
+
     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) {
@@ -142,17 +158,19 @@ async function fetchWiktionaryDefinition(word) {
 
       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);
+      formattedData.definitions = page && page.extract
+        ? [page.extract.trim()]
+        : ["Aucune définition trouvée sur le Wiktionnaire."];
+
+      log("Définition Wiktionnaire extraite :", formattedData.definitions);
 
       return [
         {
           source: "Wiktionnaire",
-          text: definitionText
+          text: formattedData.definitions.join(" | "),
+          pronunciations: formattedData.pronunciations,
+          definitionsByPOS: formattedData.definitionsByPOS
         }
       ];
     } else {
@@ -163,32 +181,47 @@ async function fetchWiktionaryDefinition(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
+        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);
+      // 🛠 Formatage des données récupérées
+      formattedData = formatDefinitionData(apiResponse);
+      log(" Données formatées :", formattedData);
+
+      // Vérification avant retour
+      if (!formattedData.definitions) {
+        formattedData.definitions = []; //
+      }
+      if (!formattedData.pronunciations) {
+        formattedData.pronunciations = []; //
+      }
+      if (!formattedData.definitionsByPOS) {
+        formattedData.definitionsByPOS = {}; //
+      }
 
       return [
-          {
-              source: "Wiktionnaire",
-              text: formattedData.definitions.length > 0 ? formattedData.definitions.join(" | ") : "⚠️ Aucune définition disponible."
-          }
+        {
+          source: "Wiktionnaire",
+          text: formattedData.definitions.length > 0 ? formattedData.definitions.join(" | ") : "Aucune définition disponible.",
+          pronunciations: formattedData.pronunciations,
+          definitionsByPOS: formattedData.definitionsByPOS
+        }
       ];
     }
   } 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." }];
+    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.", 
+      pronunciations: [],
+      definitionsByPOS: {} 
+    }];
   }
 }
 
-/**
- * Récupère la définition d'un mot depuis l'API de BaLex (Wiktionnaire).
- * @param {string} word - Le mot dont on veut la définition.
- * @returns {Promise<object[]>} - Un tableau d'objets contenant la réponse de l'API.
- */
+
+
 async function wikiApiResponse(word) {
   const result = await browser.storage.local.get("accessToken");
   authToken = result.accessToken;
@@ -218,173 +251,340 @@ async function wikiApiResponse(word) {
   }
 }
 
-/**
- * Formate les données de la réponse de l'API de BaLex (Wiktionnaire).
- * @param {object[]} apiResponse - La réponse de l'API de BaLex (Wiktionnaire).
- * @returns {object} - Un objet contenant les données formatées.
- */
 function formatDefinitionData(apiResponse) {
   let formattedData = {
       word: apiResponse[0]?.id.split("-").slice(2).join("-") || "",
-      pronunciations: [],
-      definitions: [],
-      examples: [],
-      translations: {},
+      pronunciations: new Set(),  //  Utilisation d'un Set pour éviter les doublons
+      definitionsByPOS: {}  //  Organisation par catégorie grammaticale
   };
 
   apiResponse.forEach(entry => {
-      const wordData = entry[entry.id.split(".").slice(-1)[0]]; // Accéder aux données via la clé dynamique
+      const wordData = entry[entry.id.split(".").slice(-1)[0]]; // Accès aux données via clé dynamique
+      const pos = wordData.pos || "Autre";  // Définit le POS ou "Autre" si absent
+
+      if (!formattedData.definitionsByPOS[pos]) {
+          formattedData.definitionsByPOS[pos] = {
+              definitions: [],
+              examples: [],
+              pronunciations: new Set()
+          };
+      }
+
+      // Ajout des prononciations globales en extrayant les transcriptions valides
+      if (wordData.pronunciations) {
+          wordData.pronunciations.forEach(pron => {
+              if (pron.transcript) {
+                  formattedData.pronunciations.add(pron.transcript);
+              }
+          });
+      }
 
-      // Ajout des prononciations
+      // Ajout des prononciations spécifiques au POS
       if (wordData.pronunciations) {
-          formattedData.pronunciations.push(...wordData.pronunciations);
+          wordData.pronunciations.forEach(pron => {
+              if (pron.transcript) {
+                  formattedData.definitionsByPOS[pos].pronunciations.add(pron.transcript);
+              }
+          });
       }
 
-      // Ajout des définitions
+      // Ajout des définitions et des exemples
       if (wordData.senses) {
           for (let senseKey in wordData.senses) {
               let sense = wordData.senses[senseKey];
+
               if (sense.Definitions) {
-                  formattedData.definitions.push(...sense.Definitions.map(d => d.definition));
+                  formattedData.definitionsByPOS[pos].definitions.push(
+                      ...sense.Definitions.map(d => d.definition)
+                  );
               }
               if (sense.Examples) {
-                  formattedData.examples.push(...sense.Examples.map(e => e.example));
+                  formattedData.definitionsByPOS[pos].examples.push(
+                      ...sense.Examples.map(e => e.example)
+                  );
               }
           }
       }
+  });
 
-      // Ajout des traductions
-      if (entry.translations) {
-          entry.translations.forEach(translation => {
-              if (!formattedData.translations[translation.lang_name]) {
-                  formattedData.translations[translation.lang_name] = [];
-              }
-              formattedData.translations[translation.lang_name].push(translation.sense);
-          });
-      }
+  //  Convertir les Sets en Arrays
+  formattedData.pronunciations = [...formattedData.pronunciations];
+  Object.keys(formattedData.definitionsByPOS).forEach(pos => {
+      formattedData.definitionsByPOS[pos].pronunciations = [...formattedData.definitionsByPOS[pos].pronunciations];
   });
 
   return formattedData;
 }
 
+
+
+
 // ─────────────────────────────────────────────────────────────────────────────
-// ▌ Affichage des définitions dans la barre latérale (lexiques + Wiktionnaire)
+// ▌ Affichage des définitions dans la barre latérale
 // ─────────────────────────────────────────────────────────────────────────────
 
-const MAX_LENGTH = 200;
+const MAX_LENGTH = 300;
 
 /**
- * Affiche les définitions dans la barre latérale.
- * @param {object[]} definitions - Les définitions à afficher.
- */
+* Affiche les définitions dans la barre latérale.
+*/
 function displayDefinitions(definitions) {
   log("Affichage des définitions reçues :", definitions);
   if (!Array.isArray(definitions)) return;
-
   const mesLexiquesList = document.getElementById("mesLexiquesList");
   const wiktionnaireList = document.getElementById("wiktionnaireList");
   const noLexiconDefinitionsContainer = document.getElementById("noLexiconDefinitionsContainer");
   const noWiktionaryDefinitionsContainer = document.getElementById("noWiktionaryDefinitionsContainer");
 
+  const balexIdMap = new Map();  // Dictionnaire pour stocker balex_id par lexique
+
+  // Nettoyage des listes existantes
   mesLexiquesList.innerHTML = "";
   wiktionnaireList.innerHTML = "";
 
+  // Masquer les sections vides par défaut
   if (noLexiconDefinitionsContainer) noLexiconDefinitionsContainer.style.display = "none";
   if (noWiktionaryDefinitionsContainer) noWiktionaryDefinitionsContainer.style.display = "none";
+
   let hasLexiconDefinitions = false;
   let hasWiktionaryDefinitions = false;
-
   const lexiconGroups = {};
 
-  definitions.forEach(({ source, text }) => {
-    if (!source || !text) return;
-    
-    const li = document.createElement("li");
-    let displayedText = text;
-
-    if (text.length > MAX_LENGTH) {
-      displayedText = text.slice(0, MAX_LENGTH) + "... ";
-      const readMoreLink = document.createElement("a");
-      readMoreLink.href = "#";
-      readMoreLink.textContent = "[Lire la suite]";
-      readMoreLink.style.marginLeft = "5px";
-      readMoreLink.style.color = "#8d5c70";
-      readMoreLink.style.textDecoration = "underline";
-      readMoreLink.style.cursor = "pointer";
-      readMoreLink.addEventListener("click", (event) => {
-        event.preventDefault();
-        openDefinitionPopup(text);
-      });
-      li.appendChild(document.createTextNode(displayedText));
-      li.appendChild(readMoreLink);
-    } else {
-      li.textContent = displayedText;
-    }
+  definitions.forEach(({ source, text, balex_id, definitionsByPOS }) => {
+        if (!source || !text) return;
+        log(`Traitement de ${source}, balex_id:`, balex_id);
 
-    // Vérifier la source : Wiktionnaire/Lexiques
-    if (source === "Wiktionnaire") {
-      wiktionnaireList.appendChild(li);
-      hasWiktionaryDefinitions = true;
-    } else {
-      if (!lexiconGroups[source]) {
-        lexiconGroups[source] = [];
+        const definitionContainer = document.createElement("div");
+        definitionContainer.classList.add("definition-item");
+
+        // Gestion des définitions des lexiques
+        if (!definitionsByPOS) {
+            // C'est une définition provenant des lexiques utilisateur
+            const li = document.createElement("li");
+            li.textContent = text;
+            definitionContainer.appendChild(li);
+
+            // Stocker le premier `balex_id` trouvé pour chaque lexique
+            if (!balexIdMap.has(source) && balex_id) {
+              balexIdMap.set(source, balex_id);
+            }
+            // Ajout dans le bon groupe
+            if (!lexiconGroups[source]) {
+                lexiconGroups[source] = [];
+            }
+            lexiconGroups[source].push(definitionContainer);
+            hasLexiconDefinitions = true;
+
+        } else {
+            // C'est une définition provenant du Wiktionnaire
+            log(`Traitement des définitions du Wiktionnaire pour "${source}"`);
+
+            // 2. Affichage des prononciations globales si disponibles
+            const allPronunciations = new Set();
+            Object.values(definitionsByPOS).forEach(posData => {
+                posData.pronunciations.forEach(pron => allPronunciations.add(pron));
+            });
+
+            if (allPronunciations.size > 0) {
+                const pronDiv = document.createElement("div");
+                pronDiv.style.marginBottom = "5px";
+                pronDiv.style.fontSize = "13px";
+                pronDiv.textContent = "Prononciations possibles :";
+                pronDiv.style.marginBottom = "10px";
+                definitionContainer.appendChild(pronDiv);
+
+                // Création d'un conteneur pour les prononciations
+                const pronContainer = document.createElement("div");
+                pronContainer.style.display = "flex";
+                pronContainer.style.justifyContent = "center";
+                pronContainer.style.flexWrap = "wrap";
+                allPronunciations.forEach(pron => {
+                    const pronSpan = document.createElement("span");
+                    pronSpan.textContent = pron;
+                    pronSpan.style.marginRight = "25px"; 
+                    pronSpan.style.fontSize = "15px";
+                    pronSpan.style.alignItems = "center";
+                    pronSpan.style.justifyContent = "center";
+                    pronContainer.appendChild(pronSpan);
+                });
+                definitionContainer.appendChild(pronContainer);
+            }
+            
+
+            // 3. Affichage des définitions triées par POS
+            Object.entries(definitionsByPOS).forEach(([pos, posData]) => {
+              if (posData.definitions.length === 0) return;  // Évite les POS vides
+          
+              // Création d'un conteneur dédié pour ce POS
+              const posContainer = document.createElement("div");
+          
+              // Titre du POS
+              const posTitle = document.createElement("h4");
+              posTitle.style.marginTop = "10px";
+              posTitle.style.color = "#FFFFFF";
+              posTitle.textContent = pos.toUpperCase();
+              posContainer.appendChild(posTitle);
+          
+              // Prononciations spécifiques au POS
+              if (posData.pronunciations.length > 0) {
+                  const posPronDiv = document.createElement("div");
+                  posPronDiv.style.fontStyle = "italic";
+                  posPronDiv.style.color = "#94608a";
+                  // posPronDiv.textContent = posData.pronunciations.join(", ");
+                  posContainer.appendChild(posPronDiv);
+              }
+              // Récupération des définitions complètes
+              const fullDefinitions = posData.definitions.map(def => def.trim());
+              // Concaténation de toutes les définitions dans un seul texte (séparées par un espace)
+              const concatenatedText = fullDefinitions.join(" ");
+              
+              // Création de la liste des définitions pour ce POS
+              const defList = document.createElement("ul");
+              defList.style.margin = "0";
+              defList.style.paddingLeft = "20px";
+              
+              const li = document.createElement("li");
+              if (concatenatedText.length > MAX_LENGTH) {
+                  // Affichage tronqué pour l'ensemble du bloc de définitions
+                  const truncatedText = concatenatedText.slice(0, MAX_LENGTH) + "... ";
+                  li.textContent = truncatedText;
+                  
+                  // Bouton "Lire la suite" pour afficher le contenu complet
+                  const readMoreLink = document.createElement("a");
+                  readMoreLink.href = "#";
+                  readMoreLink.textContent = "[Lire la suite]";
+                  readMoreLink.style.marginLeft = "5px";
+                  readMoreLink.style.color = "#8d5c70";
+                  readMoreLink.style.textDecoration = "underline";
+                  readMoreLink.style.cursor = "pointer";
+                  readMoreLink.addEventListener("click", (event) => {
+                      event.preventDefault();
+                      // Construction du contenu complet pour ce POS en préservant la structure
+                      let popupContent = `<h4 style="margin-top:10px; color:#FFFFFF;">${pos.toUpperCase()}</h4>`;
+                      if (posData.pronunciations.length > 0) {
+                          popupContent += `<div style="font-style:italic; color:#94608a;">${posData.pronunciations.join(", ")}</div>`;
+                      }
+                      popupContent += "<ul style='margin:0; padding-left:20px;'>";
+                      fullDefinitions.forEach(text => {
+                          popupContent += `<li>${text}</li>`;
+                      });
+                      popupContent += "</ul>";
+                      openDefinitionPopup(popupContent);
+                  });
+                  li.appendChild(readMoreLink);
+              } else {
+                  li.textContent = concatenatedText;
+              }
+              
+              defList.appendChild(li);
+              posContainer.appendChild(defList);
+              definitionContainer.appendChild(posContainer);
+          });
+          
+          wiktionnaireList.appendChild(definitionContainer);
+          hasWiktionaryDefinitions = true;
       }
-      lexiconGroups[source].push(li);
-      hasLexiconDefinitions = true;
-    }
   });
 
+  // 5. Gestion des groupes de lexiques personnels
   Object.entries(lexiconGroups).forEach(([lexiconName, definitionItems]) => {
     const lexiconContainer = document.createElement("div");
     lexiconContainer.className = "lexicon-section";
-
+  
+    // Création d'un conteneur pour l'en-tête et l'icône (l'icône est en dehors de l'en-tête)
+    const headerContainer = document.createElement("div");
+    headerContainer.className = "header-container";
+    headerContainer.style.position = "relative"; // Pour positionner l'icône absolument
+    headerContainer.style.cursor = "pointer";
+  
+    // Création de l'en-tête qui contiendra le titre seul
     const lexiconHeader = document.createElement("div");
     lexiconHeader.className = "lexicon-header";
-    lexiconHeader.textContent = lexiconName;
-    lexiconHeader.addEventListener("click", () => {
+    
+    // Ajout du titre
+    const titleSpan = document.createElement("span");
+    titleSpan.textContent = lexiconName;
+    lexiconHeader.appendChild(titleSpan);
+  
+    // Ajout de l'en-tête dans le conteneur
+    headerContainer.appendChild(lexiconHeader);
+  
+    // Création de l'icône BaLex en dehors de l'en-tête
+    const balexButton = createBaLexButton(lexiconName, balexIdMap);
+    if (balexButton) {
+      // Positionnement absolu pour que l'icône reste à droite du conteneur
+      balexButton.style.position = "absolute";
+      balexButton.style.top = "50%";
+      balexButton.style.transform = "translateY(-50%)";
+      balexButton.style.right = "5px"; // Ajustez cet espace si besoin
+  
+      // Empêche que le clic sur l'icône ne déclenche le toggle du contenu
+      balexButton.addEventListener("click", (e) => e.stopPropagation());
+      headerContainer.appendChild(balexButton);
+    }
+  
+    // Clic sur le conteneur pour dérouler ou masquer les définitions
+    headerContainer.addEventListener("click", () => {
       lexiconContent.classList.toggle("hidden");
     });
-
-    const lexiconContent = document.createElement("ul");
+  
+    // Création du conteneur pour les définitions (contenu déroulant)
+    const lexiconContent = document.createElement("div");
     lexiconContent.className = "lexicon-content hidden";
-
-    definitionItems.forEach(li => lexiconContent.appendChild(li));
-
-    lexiconContainer.appendChild(lexiconHeader);
+    definitionItems.forEach(item => lexiconContent.appendChild(item));
+  
+    lexiconContainer.appendChild(headerContainer);
     lexiconContainer.appendChild(lexiconContent);
     mesLexiquesList.appendChild(lexiconContainer);
   });
+    
 
+  // 6. Gestion des sections vides
   if (!hasLexiconDefinitions && noLexiconDefinitionsContainer) {
-    if (!authToken) {
-      noLexiconDefinitionsContainer.textContent = "Veuillez vous connecter pour accéder aux définitions de vos lexiques.";
-      noLexiconDefinitionsContainer.style.textAlign = "center";
-      noLexiconDefinitionsContainer.style.fontStyle = "italic";
-    } else {
-      noLexiconDefinitionsContainer.textContent = "Aucune définition trouvée dans les lexiques.";
-    }
-    noLexiconDefinitionsContainer.style.display = "block";
+      noLexiconDefinitionsContainer.style.display = "block";
   }
   if (!hasWiktionaryDefinitions && noWiktionaryDefinitionsContainer) {
-    noWiktionaryDefinitionsContainer.style.display = "block";
+      noWiktionaryDefinitionsContainer.style.display = "block";
   }
+}
 
-  const mesLexiquesContainer = document.getElementById("mesLexiquesContainer");
-  if (mesLexiquesContainer) {
-    mesLexiquesContainer.style.display = hasLexiconDefinitions ? "block" : "none";
-  }
-  const wiktionnaireContainer = document.getElementById("wiktionnaireContainer");
-  if (wiktionnaireContainer) {
-    wiktionnaireContainer.style.display = hasWiktionaryDefinitions ? "block" : "none";
+
+// ─────────────────────────────────────────────────────────────────────────────
+// ▌ Gestion du popup pour afficher la définition complète du Wiktionnaire
+// ─────────────────────────────────────────────────────────────────────────────
+
+function openDefinitionPopup(fullText) {
+  const modalOverlay = document.getElementById("modalOverlay");
+  const modalFullText = document.getElementById("modalFullText");
+  if (!modalOverlay || !modalFullText) {
+    log("Modal elements not found!");
+    return;
   }
+  modalFullText.innerHTML = "<p>" + fullText.replace(/\n/g, "<br>") + "</p>";
+  modalOverlay.style.display = "flex";
 }
 
 /**
- * Récupère en parallèle :
- *   - les définitions des lexiques de l'utilisateur (fetchLexiconDefinitions)
- *   - la définition Wiktionnaire (fetchWiktionaryDefinition)
- * Puis fusionne les résultats.
- */
+* Ferme le popup et nettoie le contenu
+*/
+function closeDefinitionPopup() {
+  const modalOverlay = document.getElementById("modalOverlay");
+  const modalFullText = document.getElementById("modalFullText");
+  if (!modalOverlay || !modalFullText) return;
+  modalOverlay.style.display = "none";
+  modalFullText.innerHTML = "";
+}
+
+// ─────────────────────────────────────────────────────────────────────────────
+// ▌ Affichage des définitions Babalex + Wiktionnaire
+// ─────────────────────────────────────────────────────────────────────────────
+
+/**
+* Récupère en parallèle :
+*   - les définitions des lexiques de l'utilisateur (fetchLexiconDefinitions)
+*   - la définition Wiktionnaire (fetchWiktionaryDefinition)
+* Puis fusionne les résultats.
+*/
 async function combineDefinitions(word) {
   log(`[combineDefinitions] Récupération des définitions pour "${word}"...`);
 
@@ -517,54 +717,61 @@ function displayLexiconResults(lexicons) {
     li.innerHTML = `<strong>${lexiconName}</strong>`;
     ul.appendChild(li);
 
-    log(`✅ Lexique ajouté : ${lexiconName} (ID: ${lexicon.id})`);
+    log(`Lexique ajouté : ${lexiconName} (ID: ${lexicon.id})`);
   });
 
   resultDiv.appendChild(ul);
 }
 
-// ─────────────────────────────────────────────────────────────────────────────
-// ▌ Gestion de la boîte modale pour afficher la définition complète du Wiktionnaire
-// ─────────────────────────────────────────────────────────────────────────────
 /**
- * Ouvre la boîte modale pour afficher la définition complète du Wiktionnaire.
- * @param {string} fullText - La définition complète du mot.
+ * Crée un bouton permettant d'ouvrir une entrée dans BaLex.
+ * @param {string} lexiconName - Le nom du lexique.
+ * @param {Map} balexIdMap - Une Map contenant les balex_id associés aux lexiques.
+ * @returns {HTMLElement|null} - Un bouton HTML ou null si `balex_id` est manquant.
  */
-function openDefinitionPopup(fullText) {
-  const modalOverlay = document.getElementById("modalOverlay");
-  const modalFullText = document.getElementById("modalFullText");
-  if (!modalOverlay || !modalFullText) {
-    log("Modal elements not found!");
-    return;
+function createBaLexButton(lexiconName, balexIdMap) {
+  const balexServ = "babalex.lezinter.net";  
+  const balex_id = balexIdMap.get(lexiconName) || null;
+
+  log(`ID BaLex trouvé pour "${lexiconName}" :`, balex_id);
+
+  // Vérifie si `balex_id` est valide
+  if (!balex_id) {
+      console.warn(`⚠️ Aucun balex_id trouvé pour "${lexiconName}". Bouton non créé.`);
+      return null;
   }
-  modalFullText.innerHTML = "<p>" + fullText.replace(/\n/g, "<br>") + "</p>";
-  modalOverlay.style.display = "flex";
-}
 
-/**
- * Ferme la boîte modale et nettoie le contenu
- * @returns {void}
- */
-function closeDefinitionPopup() {
-  const modalOverlay = document.getElementById("modalOverlay");
-  const modalFullText = document.getElementById("modalFullText");
-  if (!modalOverlay || !modalFullText) return;
-  modalOverlay.style.display = "none";
-  modalFullText.innerHTML = "";
+  const balexUrl = `https://${balexServ}/entry/${balex_id}/show`;
+
+  // Création du bouton
+  const balexButton = document.createElement("img");
+  balexButton.src = "../assets/icons/Link_to_balex.svg";
+  balexButton.classList.add("balex-icon");
+  balexButton.alt = "Icône BaLex";
+  balexButton.style.cursor = "help";
+  balexButton.style.width = "15px"; 
+  balexButton.style.height = "15px";
+  balexButton.style.marginLeft = "10px";
+
+  // Ajout du lien
+  balexButton.addEventListener("click", (event) => {
+    event.stopPropagation(); // Pour éviter de déclencher le clic sur le conteneur parent
+    window.open(balexUrl, "_blank");
+  });
+
+  return balexButton;
 }
 
 // ─────────────────────────────────────────────────────────────────────────────
-// ▌ Exposition des fonctions pour un usage global
+// ▌ Utilisation des fonctions dans d'autres scripts
 // ─────────────────────────────────────────────────────────────────────────────
 
 window.fetchLexiconDefinitions = fetchLexiconDefinitions;
 window.fetchWiktionaryDefinition = fetchWiktionaryDefinition;
-window.wikiApiResponse = wikiApiResponse;
-window.formatDefinitionData = formatDefinitionData;
 window.displayDefinitions = displayDefinitions;
+window.openDefinitionPopup = openDefinitionPopup;
+window.closeDefinitionPopup = closeDefinitionPopup;
 window.combineDefinitions = combineDefinitions;
 window.showDefinitions = showDefinitions;
 window.fetchDefinition = fetchDefinition;
 window.displayLexiconResults = displayLexiconResults;
-window.openDefinitionPopup = openDefinitionPopup;
-window.closeDefinitionPopup = closeDefinitionPopup;
diff --git a/src/utils/highlighting.js b/src/utils/highlighting.js
index 1851fda0fdb44aac5f4f59bb3d4aee12d48209c0..6391763a890f1b149bec182845e403574d205273 100644
--- a/src/utils/highlighting.js
+++ b/src/utils/highlighting.js
@@ -84,11 +84,11 @@ log("Initialisation de highlighting.js");
 // ─────────────────────────────────────────────────────────────
 (function () {
     try {
-        if (window.hasRun) {
+        if (window.hasRunHighlighting) {
             log("⚠️ highlighting.js déjà chargé");
             return;
         }
-        window.hasRun = true;
+        window.hasRunHighlighting = true;        
         
         // Variables internes
         let lexiconWordsCache = new Map();
diff --git a/src/utils/stats.js b/src/utils/stats.js
index 114c53ed90c7abbafefe5521fe129f64c856bfff..1ced5bf503bc3e4db1bb694775e9176af4bc88b0 100644
--- a/src/utils/stats.js
+++ b/src/utils/stats.js
@@ -1,10 +1,8 @@
-log("Stats.js chargé.");
 (function () {
-
-    if (window.hasRun) {
+    if (window.hasRunStats) {
         return;
     }
-    window.hasRun = true;
+    window.hasRunStats = true;
     let workerPort = null; // Port unique vers le WebWorker
     // ─────────────────────────────────────────────────────────────────────────────
     // Connexion/Transmission des données avec le WebWorker
@@ -22,9 +20,17 @@ log("Stats.js chargé.");
                 if (message.command === "threshold-exceeded") {
                     log("[Stats] Mots dépassant le seuil :", message.wordsAboveThreshold);
                     let alertMessage = "Nouveaux mots dépassant le seuil :\n";
-                    for (const [lang, words] of Object.entries(message.wordsAboveThreshold)) {
+                    if (typeof message.wordsAboveThreshold !== "object" || message.wordsAboveThreshold === null) {
+                        return;
+                    }
+                        for (const [lang, words] of Object.entries(message.wordsAboveThreshold)) {
+                            if (!Array.isArray(words)) {
+                                continue;
+                            }
+            
                         alertMessage += `\n🔹 ${lang.toUpperCase()} : ${words.join(", ")}`;
                     }
+            
                     alert(alertMessage);
                 }
             });
@@ -125,9 +131,9 @@ log("Stats.js chargé.");
      */
     function startReadingTimer(element, text, minReadTime) {
         if (!readingTimers.has(element)) {
-          let elapsedTime = 0;
-          let counter = null;
-      
+            let elapsedTime = 0;
+            let counter = null;
+
           // Créer l'indicateur uniquement si on est en mode debug
           if (DEBUG) {
             counter = document.createElement("div");
@@ -141,31 +147,31 @@ log("Stats.js chargé.");
             counter.style.zIndex = "9999";
             document.body.appendChild(counter);
           }
-      
+
           let interval = setInterval(() => {
-            elapsedTime += 1000;
-      
-            // Vérifie si l'utilisateur est actif et si le temps minimum est atteint
-            if (userIsActive && elapsedTime >= minReadTime) {
-              log(`[Stats] Élément lu : ${text}`);
-              readContent.add(text);
-              sendTextToWorker(text);
-              stopReadingTimer(element, text);
-            }
-      
+                elapsedTime += 1000;
+    
+                // Vérifie si l'utilisateur est actif et si le temps minimum est atteint
+                if (userIsActive && elapsedTime >= minReadTime) {
+                    log(`[Stats] Élément lu : ${text}`);
+                    readContent.add(text);
+                    sendTextToWorker(text);
+                    stopReadingTimer(element, text);
+                }
+    
             // 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 });
+                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
@@ -175,8 +181,8 @@ log("Stats.js chargé.");
             let { interval, counter } = readingTimers.get(element);
             clearInterval(interval);
             if (counter) {
-                counter.remove();
-            }
+            counter.remove();
+        }
             readingTimers.delete(element);
         }
     }
@@ -198,7 +204,7 @@ log("Stats.js chargé.");
      */
     function removeReadingIndicator(element) {
         if (readingTimers.has(element)) {
-            let { counter } = readingTimers.get(element);
+            let { counter } = readingTimers.get(element);            
             if (counter) {
                 counter.remove();
             }
diff --git a/src/workers/pyodide_worker.js b/src/workers/pyodide_worker.js
index 469b419bd92c1bbd643390131deec98763ec0722..8131c19d0c0bfe3000271d0f01b2a70122d9a2aa 100644
--- a/src/workers/pyodide_worker.js
+++ b/src/workers/pyodide_worker.js
@@ -10,238 +10,337 @@ let pyodide = null;
 let pyodideLoaded = false;      // Indique si Pyodide est chargé
 let simplemmaLoaded = false;    // Indique si simplemma est installé
 let storedFrequencies = {};     // Stockage des fréquences accumulées
-
 // Préférences et configuration utilisateur
 let autoAddEnabled = false;     // Ajout automatique désactivé par défaut
 let isAuthenticated = false;    // Non connecté par défaut
 let userThreshold = 10;         // Seuil par défaut
 let trackedLanguages = [];      // Aucune langue suivie par défaut
 let notifiedWords = {};         // Mots déjà notifiés (pour éviter les doublons)
-let stoplistFr = new Set();     // Stoplist pour le français
+let includeStopwords = false;   // Stocker l'état de l'inclusion des mots outils
+let stoplistsByLang = {};       // Objet stockant les stoplists par langue
+let userLexicons = [] //Contient les lexiques et leurs ID (lexiques personnels)
+let authToken = null; // Stockage local du token
 
-// ─────────────────────────────────────────────────────────────
-// ▌ Fonction de chargement de Pyodide et installation de simplemma
-// ─────────────────────────────────────────────────────────────
-async function loadPyodideAndSimplemma() {
-  // Chargement de Pyodide
-  if (!pyodideLoaded) {
-    log("[Worker] Chargement de Pyodide...");
-    try {
-      importScripts(`${LATEST_BASE_URL}pyodide.js`);
-      pyodide = await loadPyodide({ indexURL: LATEST_BASE_URL });
-      await pyodide.loadPackage("lzma");
-      await pyodide.loadPackage("micropip");
-      pyodideLoaded = true;
-      log("[Worker] Pyodide chargé avec succès !");
-    } catch (err) {
-      log("[Worker] Erreur lors de l'import de pyodide.js :", err);
-      throw err;
-    }
+// --- Attente de la mise à jour de la stoplist ---
+let stoplistsReady = new Promise((resolve) => resolve()); 
+
+// Écouteur des messages reçus du background script
+self.onmessage = async (event) => {
+  const { command, ...data } = event.data;
+  log("[WebWorker] Message reçu du Background:", command, data);
+
+  switch (command) {
+
+    case "pyodide-simplemma":
+      if (pyodideLoaded && simplemmaLoaded) {
+        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) {
+          log("[Worker] Chargement de Pyodide...");
+          try {
+            importScripts(`${LATEST_BASE_URL}pyodide.js`);
+          } catch (err) {
+            console.error("[Worker] Erreur lors de l'import de pyodide.js :", err);
+            self.postMessage({ type: "pyodide-simplemma", status: "error", message: err.toString() });
+            return;
+          }
+          pyodide = await loadPyodide({ indexURL: LATEST_BASE_URL });
+          await pyodide.loadPackage("lzma");
+          await pyodide.loadPackage("micropip");
+          pyodideLoaded = true;
+          log("[Worker] Pyodide chargé avec succès !");
+        }
+
+        if (!simplemmaLoaded) {
+          log("[Worker] Installation de simplemma...");
+          await pyodide.runPythonAsync(`
+          import micropip
+          import asyncio
+
+          async def main():
+              print("Installation de simplemma...")
+              await micropip.install("simplemma")
+              print("Installation réussie.")
+              import simplemma
+              print("simplemma importé avec succès.")
+              # Test simple : extraction de tokens et lemmatisation
+              import re
+              def tokenize(text):
+                  return re.findall(r"\\b\\w+\\b", text.lower())
+              phrase = "Simplemma est prêt"
+              tokens = tokenize(phrase)
+              print("Tokens extraits :", tokens)
+              lemmatized_tokens = [simplemma.lemmatize(token, lang="fr") for token in tokens]
+              print("Tokens lemmatisés :", lemmatized_tokens)
+              return lemmatized_tokens
+
+          await main()
+          `);
+          simplemmaLoaded = true;
+          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" });
+      } catch (error) {
+        console.error("[Worker] Erreur lors du chargement de Pyodide ou Simplemma :", error);
+        self.postMessage({ type: "pyodide-simplemma", status: "error", message: error.toString() });
+      }
+      break;
+
+    case "process-text":
+      if (!pyodideLoaded) {
+        log("[Worker] Pyodide non chargé.");
+        self.postMessage({ type: "process-text", status: "error", message: "Pyodide pas encore chargé" });
+        return;
+      }
+
+      log("[Worker] Texte reçu pour analyse :", data.text);
+      try {
+        const result = await pyodide.runPythonAsync(`
+        import json
+        import re
+        import simplemma
+        from simplemma import langdetect
+        
+        def detect_language(text):
+            lang_scores = simplemma.langdetect(text, lang=("fr", "en", "es", "de", "it", "pt"))
+            return lang_scores[0][0] if lang_scores else "unk"
+        
+        def tokenize(text):
+            return re.findall(r"\\b[a-zA-ZÀ-ÿ'-]+\\b", text.lower())
+        
+        text = """${data.text.replace(/\"/g, '\\"')}"""
+        detected_lang = detect_language(text)
+        if detected_lang == "unk":
+            detected_lang = "other"
+        
+        tokens = tokenize(text)
+        lemmatized_tokens = [simplemma.lemmatize(token, lang=detected_lang) for token in tokens]
+        
+        freq = {}
+        for token in lemmatized_tokens:
+            freq[token] = freq.get(token, 0) + 1
+        
+        json.dumps({"lang": detected_lang, "frequencies": freq}, ensure_ascii=False)
+        `);
+          const parsedResult = JSON.parse(result);
+          const detectedLang = parsedResult.lang;
+          if (!storedFrequencies[detectedLang]) {
+            storedFrequencies[detectedLang] = {};
+          }
+          for (const [word, count] of Object.entries(parsedResult.frequencies)) {
+            storedFrequencies[detectedLang][word] = (storedFrequencies[detectedLang][word] || 0) + count;
+          }
+          self.postMessage({ type: "update-frequencies", frequencies: storedFrequencies });
+          if (autoAddEnabled) {
+            checkThreshold(detectedLang);
+          }
+      } catch (error) {
+        console.error("[Worker] Erreur dans l'analyse du texte :", error);
+      }
+      break;
+
+    case "update-preferences":
+      userThreshold = data.threshold;
+      trackedLanguages = data.trackedLanguages;
+      autoAddEnabled = data.autoAdd;
+      isAuthenticated = data.isAuthenticated;
+      log("[Worker] Mise à jour des préférences :", { userThreshold, trackedLanguages, autoAddEnabled, isAuthenticated });
+      break;
+    
+    case "update-lexicons":
+      userLexicons = JSON.parse(data.lexicons)
+      log("[Worker] Lexiques mis à jour :", userLexicons);
+      break;
+    
+    case "update-auth-token":
+      authToken = data.accessToken;
+      log("[Worker] Token mis à jour :", authToken ? "Disponible" : "Aucun token reçu");
+      break;
+
+    case "update-stoplist":
+      stoplistsReady = new Promise((resolve) => {
+        if (data.stoplists && typeof data.stoplists === "object") {
+          stoplistsByLang = {};
+          for (const [lang, words] of Object.entries(data.stoplists)) {
+            stoplistsByLang[lang] = new Set(words.map(word => word.toLowerCase().trim()));
+            log(`[Worker] Stoplist mise à jour pour '${lang}' : ${stoplistsByLang[lang].size} mots.`);
+          }
+        } else {
+          log("[Worker] ⚠ Stoplists reçues incorrectes ou vides.");
+        }
+        resolve(); // Stoplist prête
+      });
+      break;
+
+    case "update-include-stopwords":
+      includeStopwords = data.includeStopwords;
+      log(`[Worker] Mise à jour de includeStopwords : ${includeStopwords}`);
+      break;
   }
+};
+
+
+// --- Vérification du seuil et notification ---
+let pendingWords = {}; // Stocker temporairement les mots en attente d'ajout
+let addWordTimeout = null; // Timer pour regrouper les ajouts
+
+async function checkThreshold(lang) {
+  await stoplistsReady; // Attendre que les stoplists soient chargées
+  
+  if (!autoAddEnabled || !isAuthenticated) {
+    log("[Worker] ⚠ Auto-Add désactivé ou utilisateur non connecté.");
+  } else if (!trackedLanguages.includes(lang)) {
+    log(`[Worker] âš  La langue '${lang}' n'est pas suivie.`);
+  } else {
+    log(`[Worker] Vérification des fréquences pour la langue '${lang}'...`);
+  
+    const stoplist = stoplistsByLang[lang] || new Set();
+    const shouldFilterStopwords = stoplist.size > 0 && includeStopwords;
+
+    log(`[Worker] 📝 Stoplist pour '${lang}' : ${shouldFilterStopwords ? "Appliquée" : "Non appliquée"}`);
+
+    const wordsFrequencies = storedFrequencies[lang] || {};
+    const notifiedSet = new Set(notifiedWords[lang] || []);
 
-  // Installation de simplemma
-  if (!simplemmaLoaded) {
-    log("[Worker] Installation de simplemma...");
-    try {
-      await pyodide.runPythonAsync(`
-import micropip
-import asyncio
-
-async def main():
-    print("Installation de simplemma...")
-    await micropip.install("simplemma")
-    print("Installation réussie.")
-    import simplemma
-    print("simplemma importé avec succès.")
-    # Test simple : extraction de tokens et lemmatisation
-    import re
-    def tokenize(text):
-        return re.findall(r"\\b\\w+\\b", text.lower())
-    phrase = "Le chat mange la pomme"
-    tokens = tokenize(phrase)
-    print("Tokens extraits :", tokens)
-    lemmatized_tokens = [simplemma.lemmatize(token, lang="fr") for token in tokens]
-    print("Tokens lemmatisés :", lemmatized_tokens)
-    return lemmatized_tokens
-
-await main()
-      `);
-      simplemmaLoaded = true;
-      log("[Worker] Simplemma installé avec succès !");
-    } catch (err) {
-      log("[Worker] Erreur lors de l'installation de simplemma :", err);
-      throw err;
+    // Filtrer les mots qui dépassent le seuil
+    const exceededWords = Object.entries(wordsFrequencies)
+      .filter(([word, count]) => count >= userThreshold && !notifiedSet.has(word))
+      .map(([word]) => word);
+
+    if (exceededWords.length === 0) {
+      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) log(`[Worker] Mot "${word}" exclu (stoplist)`);
+            return !isInStoplist;
+          })
+        : exceededWords;
+
+      if (finalWords.length === 0) {
+        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));
+
+        log("Mots dépassant le seuil :", finalWords);
+        self.postMessage({ type: "threshold-exceeded", wordsAboveThreshold: finalWords });
+
+        // Ajout aux mots en attente pour un envoi groupé
+        if (!pendingWords[lang]) pendingWords[lang] = [];
+        pendingWords[lang].push(...finalWords);
+
+        // Regrouper les ajouts en une seule tâche différée
+        if (!addWordTimeout) {
+          addWordTimeout = setTimeout(processPendingWords, 3000);
+        }
+      }
     }
   }
 }
 
-// ─────────────────────────────────────────────────────────────
-// ▌ Gestion des messages reçus du background
-// ─────────────────────────────────────────────────────────────
-self.onmessage = async (event) => {
-  const data = event.data;
-  log("[WebWorker] Message reçu du Background:", data);
-
-  // ───────────────
-  //  Commande : Chargement de Pyodide et Simplemma
-  // ───────────────
-  if (data.command === "pyodide-simplemma") {
-    if (pyodideLoaded && simplemmaLoaded) {
-      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 {
-      await loadPyodideAndSimplemma();
-      self.postMessage({
-        type: "pyodide-simplemma",
-        status: "success",
-        message: "Pyodide et Simplemma chargés"
-      });
-    } catch (error) {
-      log("[Worker] Erreur lors du chargement de Pyodide ou Simplemma :", error);
-      self.postMessage({
-        type: "pyodide-simplemma",
-        status: "error",
-        message: error.toString()
-      });
+//Traiter les ajouts groupés
+async function processPendingWords() {
+  log("Traitement des mots à ajouter en lot...");
+
+  for (const lang in pendingWords) {
+    const words = pendingWords[lang];
+    for (const word of words) {
+      await addWordToLexicon(lang, word);
     }
-    return;
   }
 
-  // ───────────────
-  //  Commande : Traitement du texte
-  // ───────────────
-  if (data.command === "process-text") {
-    if (!pyodideLoaded || !simplemmaLoaded) {
-      const errorMessage = "Les statistiques ne sont pas encore activées. Veuillez patienter...";
-      log("[Worker] Pyodide non chargé.");
-      self.postMessage({
-        type: "process-text",
-        status: "error",
-        message: errorMessage
-      });
-      return;
-    }
-    log("[Worker] Texte reçu pour analyse :", data.text);
-    try {
-      const stoplistArray = Array.from(stoplistFr);
-      log("Stoplist utilisée :", stoplistArray);
-      const result = await pyodide.runPythonAsync(`
-import json
-import re
-import simplemma
-from simplemma import langdetect
-
-def detect_language(text):
-    lang_scores = simplemma.langdetect(text, lang=("fr", "en", "es", "de", "it", "pt"))
-    return lang_scores[0][0] if lang_scores else "unk"
-
-def tokenize(text):
-    return re.findall(r"\\b[a-zA-ZÀ-ÿ'-]+\\b", text.lower())
-
-# Chargement de la stoplist
-stoplist = set(json.loads('${JSON.stringify(stoplistArray)}'))
-
-text = """${data.text.replace(/\"/g, '\\"')}"""
-detected_lang = detect_language(text)
-if detected_lang == "unk":
-    detected_lang = "other"
-
-tokens = tokenize(text)
-if detected_lang == "fr":
-    tokens = [token.lower().strip() for token in tokens if token.lower().strip() not in stoplist]
-
-lemmatized_tokens = [simplemma.lemmatize(token, lang=detected_lang) for token in tokens]
-
-freq = {}
-for token in lemmatized_tokens:
-    if token not in stoplist:
-        freq[token] = freq.get(token, 0) + 1
-
-json.dumps({"lang": detected_lang, "frequencies": freq}, ensure_ascii=False)
-      `);
-      const parsedResult = JSON.parse(result);
-      const detectedLang = parsedResult.lang;
-      if (!storedFrequencies[detectedLang]) {
-        storedFrequencies[detectedLang] = {};
-      }
-      for (const [word, count] of Object.entries(parsedResult.frequencies)) {
-        storedFrequencies[detectedLang][word] = (storedFrequencies[detectedLang][word] || 0) + count;
-      }
-      self.postMessage({
-        type: "update-frequencies",
-        frequencies: storedFrequencies
-      });
-      if (autoAddEnabled) {
-        checkThreshold(detectedLang);
-      }
-    } catch (error) {
-      log("[Worker] Erreur dans l'analyse du texte :", error);
-    }
+  // Réinitialiser la file d'attente et le timeout
+  pendingWords = {};
+  addWordTimeout = null;
+}
+
+async function addWordToLexicon(lang, word) {
+  if (!authToken) {
+    log("Impossible d'ajouter le mot : Aucun token d’authentification.");
     return;
   }
 
-  // ───────────────
-  //  Commande : Mise à jour des préférences utilisateur
-  // ───────────────
-  if (data.command === "update-preferences") {
-    userThreshold = data.threshold;
-    trackedLanguages = data.trackedLanguages;
-    autoAddEnabled = data.autoAdd;
-    isAuthenticated = data.isAuthenticated;
-    log("[Worker] Mise à jour des préférences :", { userThreshold, trackedLanguages, autoAddEnabled, isAuthenticated });
+  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
+  const shouldFilterStopwords = stoplist.size > 0 && !includeStopwords;
+
+  // Si le filtrage est activé et que le mot est un stopword, on ne l'ajoute pas
+  if (shouldFilterStopwords && stoplist.has(word)) {
+    log(`Mot '${word}' ignoré car présent dans la stoplist.`);
     return;
   }
 
-  // ───────────────
-  //  Commande : Mise à jour de la stoplist
-  // ───────────────
-  if (data.command === "update-stoplist") {
-    stoplistFr = new Set(data.stoplist.map(word => word.toLowerCase().trim()));
-    log("[Worker] Stoplist FR mise à jour :", stoplistFr);
+  // Trouver les lexiques correspondant à la langue détectée
+  const targetLexicons = userLexicons
+    .filter(lexicon => lexicon.language === lang && lexicon.category === "User")
+    .map(lexicon => lexicon.id);
+
+  if (targetLexicons.length === 0) {
+    log(`Aucun lexique trouvé pour la langue '${lang}'. Impossible d'ajouter '${word}'.`);
     return;
   }
-};
 
-// ─────────────────────────────────────────────────────────────
-// ▌ Vérification du seuil et notification
-// ─────────────────────────────────────────────────────────────
-function checkThreshold(lang) {
-  if (!autoAddEnabled || !isAuthenticated) {
-    log("[Worker] Auto-Add désactivé ou utilisateur non connecté. Aucune vérification de seuil.");
+  try {
+    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 });
+  } catch (error) {
+    console.error(`Erreur lors de l'ajout du mot '${word}':`, error);
+  }
+}
+
+//TODO : trouver un moyen d'accéder à cette fonction depuis api.js
+async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
+  if (!authToken) {
+    console.error("Aucun token d’authentification fourni.");
     return;
   }
-  if (!trackedLanguages.includes(lang)) {
-    log(`[Worker] La langue ${lang} n'est pas suivie.`);
+  if (!selectedWord) {
+    console.error("Aucun mot spécifié pour l’ajout.");
     return;
   }
-  log(`[Worker] Vérification des fréquences pour la langue ${lang}...`);
-  let wordsAboveThreshold = {};
-  if (storedFrequencies[lang]) {
-    const exceededWords = Object.entries(storedFrequencies[lang])
-      .filter(([word, count]) => count >= userThreshold &&
-             !(notifiedWords[lang] && notifiedWords[lang].includes(word)))
-      .map(([word]) => word);
-    if (exceededWords.length > 0) {
-      if (!notifiedWords[lang]) {
-        notifiedWords[lang] = [];
-      }
-      notifiedWords[lang].push(...exceededWords);
-      wordsAboveThreshold[lang] = exceededWords;
-    }
+  if (!Array.isArray(lexiconIds) || lexiconIds.length === 0) {
+    console.error("Aucun lexique sélectionné pour l’ajout.");
+    return;
   }
-  if (Object.keys(wordsAboveThreshold).length > 0) {
-    log("[Worker] Nouveaux mots dépassant le seuil :", wordsAboveThreshold);
-    self.postMessage({
-      type: "threshold-exceeded",
-      wordsAboveThreshold: wordsAboveThreshold
+
+  const url = "https://babalex.lezinter.net/api/entry/create"; 
+  const body = {
+    graphy: selectedWord,
+    force,
+    target_lex: lexiconIds
+  };
+
+  log("Envoi de la requête API AddWord :", body);
+
+  try {
+    const response = await fetch(url, {
+      method: "POST",
+      headers: {
+        "Content-Type": "application/json",
+        "Authorization": `Bearer ${authToken}`
+      },
+      body: JSON.stringify(body)
     });
-  } else {
-    log("[Worker] Aucun nouveau mot n'a dépassé le seuil.");
+
+    if (!response.ok) {
+      throw new Error(`Erreur API (${response.status}): ${response.statusText}`);
+    }
+
+    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);
   }
 }