diff --git a/api.js b/api.js index e74bfef7189afb72988bbd3b37d61478bb4f63a5..c465a009dd9536020decd445318689266e078369 100644 --- a/api.js +++ b/api.js @@ -24,8 +24,41 @@ async function getUserLexicons(authToken) { } } -// Fonction pour récupérer les graphies d'un lexique donné +// Fonction pour récupérer les entrées d'un lexique donné (simple liste des mots) async function getLexiconEntries(authToken, idLexicon) { + const entriesApiUrl = `https://babalex.lezinter.net/api/lexicon/extract/0?lexiconId=${idLexicon}`; + + try { + const response = await fetch(entriesApiUrl, { + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`Erreur lors de la récupération des entrées du lexique : ${response.statusText}`); + } + + const data = await response.json(); + if (Array.isArray(data)) { + console.log(`Entrées récupérées pour le lexique ID ${idLexicon} :`, data); + return data; // Retourne un tableau de mots ex. ["raquette", "chat", "science"] + } else { + console.warn('Le format des données retournées est inattendu.', data); + return []; + } + } catch (error) { + console.error('Erreur lors de la récupération des entrées du lexique :', error); + throw error; + } +} + + + +// Fonction pour récupérer les graphies et leurs ID +async function getLexiconEntriesID(authToken, idLexicon) { const entriesApiUrl = `https://babalex.lezinter.net/api/lexicon/entries/${idLexicon}`; try { @@ -48,6 +81,38 @@ async function getLexiconEntries(authToken, idLexicon) { } } +// Fonction pour récupérer les mots d'un lexique donné +async function getLexiconEntries(authToken, idLexicon) { + const entriesApiUrl = `https://babalex.lezinter.net/api/lexicon/extract/0?lexiconId=${idLexicon}`; + + try { + const response = await fetch(entriesApiUrl, { + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`Erreur lors de la récupération des entrées du lexique : ${response.statusText}`); + } + + const data = await response.json(); + if (Array.isArray(data)) { + console.log(`Entrées récupérées pour le lexique ID ${idLexicon} :`, data); + return data; // Retourne un tableau de mots ex. ["raquette", "chat", "science"] + } else { + console.warn('Le format des données retournées est inattendu.', data); + return []; + } + } catch (error) { + console.error('Erreur lors de la récupération des entrées du lexique :', error); + throw error; + } +} + + // Fonction pour obtenir les informations d'une graphie async function getWordInfo(authToken, word) { const definitionApiUrl = `https://babalex.lezinter.net/api/entry/search?graphy=${encodeURIComponent(word)}&language=fr&target_lex=3&target_lex=4`; @@ -153,6 +218,7 @@ async function getWiktionaryDefinition(authToken, word) { // METTRE LES FONCTIONS GLOBALES window.getUserLexicons = getUserLexicons; window.getLexiconEntries = getLexiconEntries; +window.getLexiconEntriesID = getLexiconEntriesID; window.getWordInfo = getWordInfo; window.getDefinition = getDefinition; -window.getWiktionaryDefinition = getWiktionaryDefinition; \ No newline at end of file +window.getWiktionaryDefinition = getWiktionaryDefinition; diff --git "a/barre_lat\303\251rale/content.js" "b/barre_lat\303\251rale/content.js" index 36935497e7058602efb25790d6746db38f52b52f..da428ce66fc6bc6ab1f6a4fb9930abf82d7e96d8 100644 --- "a/barre_lat\303\251rale/content.js" +++ "b/barre_lat\303\251rale/content.js" @@ -1,18 +1,19 @@ // Écouteur d'événement qui se déclenche lorsqu'un utilisateur relâche le bouton de la souris document.addEventListener('mouseup', () => { - // Récupère le texte sélectionné par l'utilisateur et supprime les espaces inutiles - const selection = window.getSelection().toString().trim(); - - // Vérifie si une sélection de texte a bien été effectuée - if (selection) { - // Affiche dans la console le mot ou texte sélectionné pour le débogage - console.log("Mot sélectionné :", selection); - - // Envoie un message au script de la barre latérale pour lui transmettre le mot sélectionné - browser.runtime.sendMessage({ - action: "mot_selectionne", // Action identifiant le type de message - mot: selection // Le texte sélectionné - }); - } -}); + // Récupère le texte sélectionné par l'utilisateur et supprime les espaces inutiles + const selection = window.getSelection().toString().trim(); + + // Vérifie si une sélection de texte a bien été effectuée + if (selection) { + // Affiche dans la console le mot ou texte sélectionné pour le débogage + console.log("Mot sélectionné :", selection); + + // Envoie un message au script de la barre latérale pour lui transmettre le mot sélectionné + browser.runtime.sendMessage({ + action: "mot_selectionne", // Action identifiant le type de message + mot: selection // Le texte sélectionné + }); + } + }); + \ No newline at end of file diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js" index dbb8788c323e8cefc4dca9622a8b04b6c067914c..8f645db3a5501e57386408bbf9e24b3416c1a896 100644 --- "a/barre_lat\303\251rale/sidebar.js" +++ "b/barre_lat\303\251rale/sidebar.js" @@ -84,3 +84,32 @@ async function chargerLexiques() { // Chargement des lexiques dès l'ouverture de la barre latérale chargerLexiques(); + +browser.runtime.onMessage.addListener((message) => { + if (message.action === "mot_et_lexiques") { + const { mot, lexiques } = message; + console.log("Mot reçu :", mot); + console.log("Liste des lexiques :", lexiques); + + // Mettre à jour l'affichage du mot sélectionné + document.getElementById('motSelectionne').textContent = mot; + + // Mettre à jour la liste des lexiques dans la barre latérale + const container = document.getElementById('lexiques'); + container.innerHTML = ''; //On supprime le contenu existant + + lexiques.forEach(({ lexiconName, lexiconId, isPresent }) => { + const div = document.createElement('div'); + div.className = 'lexique-item'; + + const status = isPresent ? 'Présent' : 'Non présent'; + + div.innerHTML = ` + <div>${lexiconName} (ID: ${lexiconId})</div> + <div>${status}</div> + `; + + container.appendChild(div); + }); + } +}); diff --git a/menu_contextuel/context_menu.css b/menu_contextuel/context_menu.css index 5bddfd50ee59badc3ba817cb136f4737754c3a17..17e41f539c8e115c076928176fcd6d0c0d370fe8 100644 --- a/menu_contextuel/context_menu.css +++ b/menu_contextuel/context_menu.css @@ -1,35 +1,34 @@ #whiteBox { - position: absolute; /* Permet un positionnement dynamique */ - display: none; /* Caché par défaut */ - background-color: rgb(255, 255, 255); - border: 5px solid rgb(0, 0, 0); - padding: 10px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); - z-index: 10000; - } - - #selectedWord { - margin: 0; - font-size: 14px; - line-height: 1.5; - color: black; - font-weight: bold; - } - - .searchButton { - margin-top: 10px; - padding: 8px 12px; - background-color: #4CAF50; - color: white; - border: none; - cursor: pointer; - font-size: 14px; - border-radius: 5px; - display: block; - width: 100%; - } - - .searchButton:hover { - background-color: #45a049; - } - \ No newline at end of file + position: absolute; /* Permet un positionnement dynamique */ + display: none; /* Caché par défaut */ + background-color: rgb(255, 255, 255); + border: 5px solid rgb(0, 0, 0); + padding: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + z-index: 10000; +} + +#selectedWord { + margin: 0; + font-size: 14px; + line-height: 1.5; + color: black; + font-weight: bold; +} + +.searchButton { + margin-top: 10px; + padding: 8px 12px; + background-color: #4CAF50; + color: white; + border: none; + cursor: pointer; + font-size: 14px; + border-radius: 5px; + display: block; + width: 100%; +} + +.searchButton:hover { + background-color: #45a049; +} diff --git a/menu_contextuel/context_menu.js b/menu_contextuel/context_menu.js index 7537f1aff665cd500c3bef13adbd5ad35ec8bb48..447c2af44a2cf3a2920a9969b879744cffc35191 100644 --- a/menu_contextuel/context_menu.js +++ b/menu_contextuel/context_menu.js @@ -15,14 +15,21 @@ readTokenFile() // Création de la zone blanche // TODO : BOUTONS A REMPLACER AVEC UN PICTOGRAMME-------------------------------------------------------------------------// // TODO : VERIFIER SI L'UTILISATEUR EST CONNECTÉ ET AFFICHER LES BOUTONS POSSIBLES ex. lexiques perso / utilisateurs-----// +// TODO : PRENDRE EN COMPTE LES LEXIQUES DE GROUPE -----// function createWhiteBox() { const whiteBox = document.createElement('div'); whiteBox.id = 'whiteBox'; whiteBox.style.display = 'none'; // Cachée par défaut whiteBox.innerHTML = + + //searchLexiconButton marche uniquement pour le lexique utilisateur avec api/user/lexicons + //returnLexicon marche uniquement pour l'utilisateur n°52 (compte de test) avec api/lexicon/search?user_id=52&language=fr + //getDefinitionButton + //getDefinitionWikiButton ` <p id="selectedWord">Mot sélectionné</p> - <input id="searchLexiconButton" type="button" class="searchButton" value="Rechercher dans le lexique personnel" /> + <input id="searchLexiconButton" type="button" class="searchButton" value="Vérifier si le mot est dans le lexique personnel" /> + <input id="checkLexiconButton" type="button" class="searchButton" value="Afficher dans quels lexiques le mot est présent" /> <input id="getDefinitionButton" type="button" class="searchButton" value="Obtenir une définition" /> <input id="getDefinitionWikiButton" type="button" class="searchButton" value="Rechercher sur le Wiktionnaire" /> @@ -71,7 +78,10 @@ document.addEventListener('contextmenu', (event) => { whiteBox.style.top = `${event.pageY}px`; whiteBox.style.display = 'block'; // Afficher la zone + + // Bouton de recherche dans le lexique perso + // Ne marche que pour la langue française const searchLexiconButton = document.getElementById('searchLexiconButton'); searchLexiconButton.onclick = async () => { @@ -79,8 +89,9 @@ document.addEventListener('contextmenu', (event) => { try { const lexicons = await getUserLexicons(authToken); - console.log('Lexiques de l’utilisateur :', lexicons); + console.log('Lexiques (personnels) de l’utilisateur :', lexicons); + // TODO: intégrer la variable lang const frenchLexicon = lexicons.find((lexicon) => lexicon.language === 'fr'); if (!frenchLexicon) { alert('Aucun lexique pour la langue française trouvé.'); @@ -90,27 +101,100 @@ document.addEventListener('contextmenu', (event) => { const idLexicon = frenchLexicon.id; console.log('ID du lexique français :', idLexicon); - const entries = await getLexiconEntries(authToken, idLexicon); - console.log('Graphies dans le lexique français :', entries); + const entries = await getLexiconEntriesID(authToken, idLexicon); + console.log('Graphies et ID dans le lexique français :', entries); - const isWordPresent = entries.some((entry) => entry.graphy === selectedText); - if (isWordPresent) { - alert(`Mot présent dans le lexique : "${selectedText}"`); + const isWordPresent = entries.some((entry) => entry.graphy.toLowerCase() === selectedText.toLowerCase()); if (isWordPresent) { + alert(`Mot présent dans le lexique personnel français n°"${idLexicon}": "${selectedText}"`); } else { - alert(`Le mot "${selectedText}" n'est pas présent dans le lexique.`); + alert(`Le mot "${selectedText}" n'est pas présent dans le lexique personnel français.`); } } catch (error) { console.error('Erreur lors de la recherche dans le lexique :', error); } }; + + + // Bouton pour afficher dans quels lexiques le mot est présent + const checkLexiconButton = document.getElementById('checkLexiconButton'); + checkLexiconButton.onclick = async () => { + console.log('Vérification dans quels lexiques le mot est présent :', selectedText); + + try { + // Récupérer les lexiques de l'utilisateur du compte de test (id = 52) + const lexiconsApiUrl = 'https://babalex.lezinter.net/api/lexicon/search?user_id=52&language=fr'; + const response = await fetch(lexiconsApiUrl, { + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`Erreur lors de la récupération des lexiques : ${response.statusText}`); + } + + // Récupérer les données des lexiques + const lexicons = await response.json(); + console.log('Lexiques récupérés pour l’utilisateur 52 :', lexicons); + + const results = []; + + // On parcours les lexiques de l'utilisateur pour vérifier si le mot y est présent + for (const lexicon of lexicons) { + //getLexiconEntriesID pour récupérer les détails des mots du lexique + const lexiconEntries = await getLexiconEntriesID(authToken, lexicon.id); + // Vérifier si le mot sélectionné est présent dans ce lexique + const isWordPresent = lexiconEntries.some((entry) => entry.graphy.toLowerCase() === selectedText.toLowerCase()); + //Nom du lexique + const lexiconName = lexicon.category === 'User' + ? `Lexique personnel (${lexicon.user.pseudo || 'Inconnu'})` + : `Lexique de groupe (${lexicon.group?.name || 'Inconnu'})`; + + // Ajouter les résultats pour ce lexique dans le tableau + results.push({ + lexiconName, + lexiconId: lexicon.id, + isPresent: isWordPresent, + }); + } + + //Envoi des résultats à la barre latérale + browser.runtime.sendMessage({ + action: "mot_et_lexiques", + mot: selectedText, + lexiques: results, + }); + console.log('Résultats envoyés à la barre latérale :', results); + + // Message contenant les résultats pour chaque lexique + let resultMessage = `Résultats pour le mot sélectionné :\n\n`; + + results.forEach(({ lexiconName, lexiconId, isPresent }) => { + resultMessage += `- Lexique : ${lexiconName}\n`; + resultMessage += ` ID du lexique : ${lexiconId}\n`; + resultMessage += ` Statut : ${isPresent ? 'Mot présent dans ce lexique' : 'Mot non présent dans ce lexique'}\n\n`; + }); + + // Résultats + alert(`Résultats pour "${selectedText}" :\n\n${resultMessage}`); + } catch (error) { + console.error('Erreur lors de la vérification des lexiques :', error); + alert('Une erreur est survenue lors de la vérification des lexiques. Consultez la console pour plus de détails.'); + } + }; + + + // Bouton pour obtenir une définition const getDefinitionButton = document.getElementById('getDefinitionButton'); getDefinitionButton.onclick = async () => { console.log('Recherche de la définition pour :', selectedText); try { - //Obtenir les informations sur le mot + //Obtenir les informations disponibles sur le mot const wordInfo = await getWordInfo(authToken, selectedText); console.log('Résultat complet de la recherche :', wordInfo); diff --git a/menu_extension/background.js b/menu_extension/background.js deleted file mode 100644 index 2c13d9651ffc0f112c557d5aa77f49a451d08740..0000000000000000000000000000000000000000 --- a/menu_extension/background.js +++ /dev/null @@ -1,20 +0,0 @@ -let isExtensionActive = true; -let areStatsActive = false; - -console.log("ff2BaLex est chargé."); - -browser.runtime.onInstalled.addListener(() => { - console.log("ff2BaLex est installé."); -}); - -browser.storage.onChanged.addListener((changes) => { - if (changes.extensionActive) { - isExtensionActive = changes.extensionActive.newValue; - console.log("Extension activée :", isExtensionActive); - } - - if (changes.statsActive) { - areStatsActive = changes.statsActive.newValue; - console.log("Statistiques activées :", areStatsActive); - } -}); diff --git a/menu_extension/options.html b/menu_extension/options.html deleted file mode 100644 index c9491e14ccca3a582c965ec79951a593ec129da4..0000000000000000000000000000000000000000 --- a/menu_extension/options.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE html> -<html lang="fr"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Paramètres ff2BaLex</title> - <style> - body { - font-family: Arial, sans-serif; - padding: 20px; - background-color: #323046; - color: white; - } - button { - width: 100%; - padding: 10px; - margin-bottom: 10px; - font-size: 15px; - color: #94608a; - font-weight: bold; - border: none; - cursor: pointer; - } - button:hover { - background-color: #94608a; - color: white; - } - </style> -</head> -<body> - <h3>Paramètres BaLex</h3> - <button id="connectBtn">Se connecter</button> - <button id="toggleExtensionBtn">Activer/Désactiver l'extension</button> - <button id="toggleStatsBtn">Activer/Désactiver les statistiques</button> - <script src="options.js"></script> -</body> -</html> diff --git a/menu_extension/options.js b/menu_extension/options.js deleted file mode 100644 index e80617fb5ca83a8a6b9919124fe95147d4dbf3aa..0000000000000000000000000000000000000000 --- a/menu_extension/options.js +++ /dev/null @@ -1,18 +0,0 @@ -document.getElementById("connectBtn").addEventListener("click", () => { - alert("Fonctionnalité de connexion non encore implémentée."); - }); - - document.getElementById("toggleExtensionBtn").addEventListener("click", async () => { - const { extensionActive } = await browser.storage.local.get("extensionActive"); - const newState = !extensionActive; - await browser.storage.local.set({ extensionActive: newState }); - alert(`Extension ${newState ? "activée" : "désactivée"}.`); - }); - - document.getElementById("toggleStatsBtn").addEventListener("click", async () => { - const { statsActive } = await browser.storage.local.get("statsActive"); - const newState = !statsActive; - await browser.storage.local.set({ statsActive: newState }); - alert(`Statistiques ${newState ? "activées" : "désactivées"}.`); - }); - diff --git a/menu_extension/popup.html b/menu_extension/popup.html deleted file mode 100644 index 3c45bee873b39f4faa06584872d2763a65045f78..0000000000000000000000000000000000000000 --- a/menu_extension/popup.html +++ /dev/null @@ -1,39 +0,0 @@ -<!DOCTYPE html> -<html lang="fr"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Extension BaLex</title> - <style> - body { - font-family: Arial, sans-serif; - margin: 20px; - width: 200px; - background-color: #323046; - color: white; - text-align: center; - } - button { - width: 100%; - padding: 10px; - margin-bottom: 10px; - font-size: 15px; - color: #94608a; - font-weight: bold; - border: none; - cursor: pointer; - } - button:hover { - background-color: #94608a; - color: white; - } - </style> -</head> -<body> - <h3>Extension BaLex</h3> - <button id="connectBtn">Se connecter</button> - <button id="toggleExtensionBtn">Activer/Désactiver l'extension</button> - <button id="toggleStatsBtn">Activer les statistiques</button> - <script src="popup.js"></script> -</body> -</html> diff --git a/menu_extension/popup.js b/menu_extension/popup.js deleted file mode 100644 index e80617fb5ca83a8a6b9919124fe95147d4dbf3aa..0000000000000000000000000000000000000000 --- a/menu_extension/popup.js +++ /dev/null @@ -1,18 +0,0 @@ -document.getElementById("connectBtn").addEventListener("click", () => { - alert("Fonctionnalité de connexion non encore implémentée."); - }); - - document.getElementById("toggleExtensionBtn").addEventListener("click", async () => { - const { extensionActive } = await browser.storage.local.get("extensionActive"); - const newState = !extensionActive; - await browser.storage.local.set({ extensionActive: newState }); - alert(`Extension ${newState ? "activée" : "désactivée"}.`); - }); - - document.getElementById("toggleStatsBtn").addEventListener("click", async () => { - const { statsActive } = await browser.storage.local.get("statsActive"); - const newState = !statsActive; - await browser.storage.local.set({ statsActive: newState }); - alert(`Statistiques ${newState ? "activées" : "désactivées"}.`); - }); - diff --git a/sidebar.js b/sidebar.js new file mode 100644 index 0000000000000000000000000000000000000000..8f645db3a5501e57386408bbf9e24b3416c1a896 --- /dev/null +++ b/sidebar.js @@ -0,0 +1,115 @@ +// Confirme le chargement du script dans la console +console.log("sidebar.js chargé avec succès !"); + +// Écoute les messages envoyés par le script de contenu pour afficher le mot sélectionné dans la barre latérale +browser.runtime.onMessage.addListener((message) => { + if (message.action === "mot_selectionne") { + // Met à jour l'affichage du mot sélectionné + document.getElementById('motSelectionne').textContent = message.mot; + console.log("Mot reçu dans la barre latérale :", message.mot); + } +}); + +// Recherche la définition d'un mot sur le Wiktionnaire +async function chercherDefinition(mot) { + const url = `https://fr.wiktionary.org/api/rest_v1/page/summary/${encodeURIComponent(mot)}`; + console.log("URL de la requête :", url); + + try { + // Effectue la requête API vers le Wiktionnaire + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Erreur HTTP : ${response.status}`); + } + + // Récupère et affiche la définition si elle existe + const data = await response.json(); + const definitionDiv = document.getElementById('definition'); + + if (data.extract) { + definitionDiv.innerHTML = `<strong>Définition de ${mot} :</strong><p>${data.extract}</p>`; + } else { + definitionDiv.innerHTML = `<p>Aucune définition trouvée pour : ${mot}</p>`; + } + } catch (error) { + console.error("Erreur lors de la récupération de la définition :", error); + document.getElementById('definition').innerHTML = "<p>Erreur lors de la recherche de la définition.</p>"; + } +} + +// Lance la recherche de la définition lorsque le bouton est cliqué +document.getElementById('chercherDef').addEventListener('click', () => { + const mot = document.getElementById('motSelectionne').textContent; + if (mot && mot !== "Aucun mot sélectionné") { + chercherDefinition(mot); + } else { + alert("Veuillez sélectionner un mot avant de rechercher sa définition."); + } +}); + +// Charge dynamiquement les lexiques de l'utilisateur avec des cases à cocher +async function chargerLexiques() { + const lexiques = ["Lexique 1", "Lexique 2", "Lexique 3"]; + const container = document.getElementById('lexiques'); + container.innerHTML = ''; + + lexiques.forEach(lexique => { + const div = document.createElement('div'); + div.className = 'lexique-item'; + + // Pictogramme + const icon = document.createElement('div'); + icon.className = 'lexique-icon'; + icon.id = `icon_${lexique.replace(/\s/g, '_')}`; + + // Nom du lexique + const label = document.createElement('label'); + label.htmlFor = `chk_${lexique}`; + label.className = 'lexique-label'; + label.textContent = lexique; + + // Case à cocher + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.id = `chk_${lexique}`; + checkbox.className = 'lexique-checkbox'; + + // Ordre : Pictogramme → Nom → Case à cocher + div.appendChild(icon); + div.appendChild(label); + div.appendChild(checkbox); + container.appendChild(div); + }); +} + +// Chargement des lexiques dès l'ouverture de la barre latérale +chargerLexiques(); + +browser.runtime.onMessage.addListener((message) => { + if (message.action === "mot_et_lexiques") { + const { mot, lexiques } = message; + console.log("Mot reçu :", mot); + console.log("Liste des lexiques :", lexiques); + + // Mettre à jour l'affichage du mot sélectionné + document.getElementById('motSelectionne').textContent = mot; + + // Mettre à jour la liste des lexiques dans la barre latérale + const container = document.getElementById('lexiques'); + container.innerHTML = ''; //On supprime le contenu existant + + lexiques.forEach(({ lexiconName, lexiconId, isPresent }) => { + const div = document.createElement('div'); + div.className = 'lexique-item'; + + const status = isPresent ? 'Présent' : 'Non présent'; + + div.innerHTML = ` + <div>${lexiconName} (ID: ${lexiconId})</div> + <div>${status}</div> + `; + + container.appendChild(div); + }); + } +}); diff --git a/token.txt b/token.txt index 4f846471b50d3f1b92b12b4e553ecd372bc5399d..5547e7a8a246efb5cf5b7939c4417594cd824cac 100644 --- a/token.txt +++ b/token.txt @@ -1 +1 @@ -eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJwcmlzbXMiLCJqdGkiOiJlMjk1ZmI0N2E4NGM4Y2Y2YTZmNDM2M2QxMGU0ZDMwNmU4NGYwOWQ1MDVkOTcxNzNkNzg1NTI4MWQxYzE3NjYyMzJkMGRjNmQ2ZGVkNWMyYSIsImlhdCI6MTczNzA4Njk5Ny4xMjcxMDgsIm5iZiI6MTczNzA4Njk5Ny4xMjcxMjksImV4cCI6MTczNzA5MDU5Ny4xMDEzMiwic3ViIjoiYXNvdW5hbGF0aCIsInNjb3BlcyI6WyJlbWFpbCIsInBzZXVkbyIsInV1aWQiXSwia2lkIjoiMSIsImN1c3RvbSI6eyJmb28iOiJiYXIifX0.E0ApQUZLsJShxq94jZOyt5XHZS4C-1xx4Nabzp5jUw0W7GE2FpzRhrUSC2DVXIu5oCw_LOh_uuv0kkBRD2YjsdFeCn3NBoJP_2sz8vJLzutfeR7Fl4MF166IM8RPYAT14werTQy82MUUXcvKli8E12y7SGM7qwwq5c7I_C3eNr2NJ_S-ivj_1JKZIv4vqsCR4NHk4MJC8Wmt0VDXBJuX5LUgAnvHBSxiEFdrQm7vuKg-nXk33biGYjMQAFepJhr-Oax2lvs-OwC-UuNOV87vpmr79umX4fRdA2USFOV8B_ro25LqJq6vugXAYCCLjXD4e0fLwDUhjzkFfXXslAqX7A \ No newline at end of file +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJwcmlzbXMiLCJqdGkiOiI4OWE4MjY4MjBkMmIzZmU5MzM0ODY5YmMyZDlhMzY0MGFmY2IxMmJmNmIzMzBjMzZjZjMwOWYxY2JmZDI2MDNiZGMzYzRkODFjMWYyZDMyZiIsImlhdCI6MTczNzE2NzcxMS4yODU3ODYsIm5iZiI6MTczNzE2NzcxMS4yODU3OTIsImV4cCI6MTczNzE3MTMxMS4yODE2MzQsInN1YiI6ImFzb3VuYWxhdGgiLCJzY29wZXMiOlsiZW1haWwiLCJwc2V1ZG8iLCJ1dWlkIl0sImtpZCI6IjEiLCJjdXN0b20iOnsiZm9vIjoiYmFyIn19.XLqGm4O0Ir6mdMEtob-gHdO2MFMjxBnwgudbBxaOM0L7TixK3NmkToJZ-yjflLwsAlposzXAGDn21RhPUgXdFK5Rp5wFiD1qoeIgI5XLi8Arp0J2kciCGKoDbIHHTc9bj0tNR4XW1SEgTT2CgKHSVaBNB5ktrpjrph8Wvstwo44u8LNB-yn34iUUqaScp3q3KI0qtS-lyTuOBb55KoUnXQZv4IUtjyBGBvIsU1QCTOYy0GPVOFxn6ZXc4mELZ6uFEvdF57mJyP4CIE3DRcldCOzti_aiGSoe_KDl96ywhHjqEnhIH3MXLneUZiEKgBnkNWuiLhQpCLD8lf_0UPWgpA \ No newline at end of file