diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/content.js b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/content.js
index 1e782cd..223096c 100644
--- a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/content.js
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/content.js
@@ -1,1431 +1,102 @@
// Plugin DIMA - content.js - Version finale consolidée
// Détection de manipulation cognitive - M82 Project
-// Version: 2.0 Enhanced Keywords
-
-// ===== BASE DE DONNÉES DES MOTS-CLÉS AMÉLIORÉS =====
-const DIMA_ENHANCED_KEYWORDS = {
- "TE0111": {
- core: ["exemple", "cas", "témoignage", "example", "case", "testimony"],
- variants: {
- formal: ["illustration", "démonstration", "spécimen"],
- informal: ["histoire", "vécu", "expérience"],
- intensity: {
- weak: ["petit exemple", "simple cas"],
- strong: ["exemple frappant", "cas édifiant", "témoignage bouleversant"]
- }
- },
- patterns: [
- /(?:par\s+exemple|for\s+example|comme\s+dans\s+le\s+cas)/i,
- /(?:prenons\s+l'exemple|take\s+the\s+example)/i
- ]
- },
-
- "TE0500": {
- core: ["secret", "choquant", "incroyable", "shocking", "amazing"],
- variants: {
- clickbait_formulas: [
- "vous ne croirez pas", "ce qui arrive ensuite", "you won't believe",
- "what happens next", "les experts détestent", "un truc simple",
- "cette astuce", "révélation choc", "doctors hate this"
- ],
- emotional_hooks: [
- "ça va vous surprendre", "préparez-vous", "attention",
- "exclusif", "urgent", "will shock you", "prepare yourself"
- ],
- curiosity_gaps: [
- "la raison va vous étonner", "voici pourquoi", "découvrez comment",
- "la vérité sur", "the reason will amaze you", "here's why"
- ]
- },
- patterns: [
- /\d+\s+(?:choses|façons|méthodes|secrets|things|ways|methods)\s+(?:que|pour|de|to|that)/i,
- /(?:voici|découvrez|here's|discover)\s+(?:comment|pourquoi|ce que|how|why|what)/i,
- /(?:cette|cette|this)\s+\w+\s+va\s+vous\s+(?:\w+|will)/i,
- /(?:shocking|amazing|incredible)\s+(?:secret|truth|fact)/i
- ]
- },
-
- "TE0132": {
- core: ["catastrophe", "panique", "chaos", "disaster", "danger", "menace", "threat", "risque", "risk", "grave", "serious", "crise", "crisis"],
- variants: {
- intensity: {
- weak: ["problème", "difficulté", "souci", "issue", "concern"],
- strong: ["catastrophe majeure", "crise grave", "danger mortel", "major catastrophe", "deadly danger"]
- },
- temporal: ["imminent", "proche", "bientôt", "soon", "approaching"]
- },
- patterns: [
- /(?:alerte|alert|warning|attention)\s+(?:rouge|red|maximum)/i,
- /(?:situation|crisis|problem)\s+(?:critique|critical|dramatique|dramatic)/i
- ]
- },
-
- "TE0501": {
- core: ["ne ratez pas", "don't miss", "dernière chance", "last chance", "limité", "limited", "exclusif", "exclusive"],
- variants: {
- urgency: ["dépêchez-vous", "hurry up", "vite", "quickly", "maintenant ou jamais", "now or never"],
- scarcity: ["stock limité", "places limitées", "limited stock", "limited seats", "offre limitée"]
- },
- patterns: [
- /(?:seulement|only)\s+\d+\s+(?:jours?|heures?|minutes?|days?|hours?|minutes?)/i,
- /(?:expire|ends?)\s+(?:bientôt|soon|today|demain|tomorrow)/i
- ]
- }
-};
-
-// ===== PATTERNS CONTEXTUELS =====
-const CONTEXT_PATTERNS = {
- urgency: {
- patterns: [
- /(?:urgent|rapidement|vite|immédiatement|maintenant|now|quickly|immediately)/i,
- /(?:dernière\s+chance|temps\s+limité|offre\s+limitée|last\s+chance|limited\s+time)/i,
- /(?:dépêchez-vous|ne\s+ratez\s+pas|hurry|don't\s+miss)/i
- ],
- boost: 1.3,
- techniques: ['TE0501', 'TE0500']
- },
- authority: {
- patterns: [
- /(?:selon\s+(?:les\s+)?(?:experts?|spécialistes?|docteurs?|doctors?|experts?))/i,
- /(?:étude\s+(?:révèle|montre|démontre|shows?|reveals?))/i,
- /(?:recherche\s+(?:scientifique|universitaire|scientific|university))/i
- ],
- boost: 1.4,
- techniques: ['TE0422', 'TE0212']
- },
- social_proof: {
- patterns: [
- /(?:\d+(?:\.\d+)?[km]?\s+personnes?\s+(?:utilisent|font|pensent|people\s+(?:use|do|think)))/i,
- /(?:tout\s+le\s+monde|la\s+plupart\s+des\s+gens|everyone|most\s+people)/i,
- /(?:viral|tendance|populaire|trending|popular)/i
- ],
- boost: 1.2,
- techniques: ['TE0251', 'TE0221']
- }
-};
-
-// ===== BASE DIMA COMPLÈTE =====
-const DIMA_TECHNIQUES = [
- // PHASE DETECTER - TACTIQUES
- {
- index: "TA0011",
- nom: "Information préexistante",
- phase: "Detect",
- description: "Exploitation d'informations déjà connues ou familières",
- mots_cles: ["déjà", "connu", "already", "known", "familier", "familiar", "habituel", "usual", "précédemment", "previously"],
- weight: 1.1,
- type: "tactic"
- },
- {
- index: "TA0012",
- nom: "Information à exposition répétée",
- phase: "Detect",
- description: "Répétition d'informations pour créer une familiarité artificielle",
- mots_cles: ["encore", "again", "répéter", "repeat", "redire", "retell", "rappel", "reminder", "à nouveau", "once again"],
- weight: 1.2,
- type: "tactic"
- },
- {
- index: "TA0013",
- nom: "Information clivante",
- phase: "Detect",
- description: "Utilisation d'informations polarisantes pour attirer l'attention",
- mots_cles: ["polémique", "controversial", "scandaleux", "outrageous", "choquant", "shocking", "divise", "divides", "clivant"],
- weight: 1.4,
- type: "tactic"
- },
- {
- index: "TA0014",
- nom: "Écart à la norme",
- phase: "Detect",
- description: "Mise en avant d'éléments sortant de l'ordinaire",
- mots_cles: ["inhabituel", "unusual", "anormal", "abnormal", "exception", "extraordinary", "hors norme", "atypique"],
- weight: 1.3,
- type: "tactic"
- },
- {
- index: "TA0015",
- nom: "Détail signifiant",
- phase: "Detect",
- description: "Focus sur des détails pour donner une impression de précision",
- mots_cles: ["précisément", "exactly", "détail", "detail", "spécifiquement", "specifically", "en particulier", "particularly"],
- weight: 1.1,
- type: "tactic"
- },
-
- // PHASE DETECTER - TECHNIQUES
- {
- index: "TE0111",
- nom: "Heuristique de disponibilité",
- phase: "Detect",
- description: "Surreprésentation d'exemples facilement mémorisables",
- mots_cles: ["récent","disponible", "recently", "exemple", "example", "cas", "case", "témoignage", "testimony"],
- weight: 1.0,
- type: "technique",
- tactic: "TA0011"
- },
- {
- index: "TE0112",
- nom: "Effet de simple exposition",
- phase: "Detect",
- description: "Répétition pour créer une familiarité artificielle",
- mots_cles: ["encore", "again", "toujours", "always", "répétition", "repetition", "familier", "familiar"],
- weight: 1.2,
- type: "technique",
- tactic: "TA0011"
- },
- {
- index: "TE0121",
- nom: "Illusion de la fréquence",
- phase: "Detect",
- description: "Impression exagérée de fréquence d'un phénomène",
- mots_cles: ["partout", "everywhere", "de plus en plus", "more and more", "fréquent", "frequent", "épidémie", "epidemic"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0012"
- },
- {
- index: "TE0122",
- nom: "Effet de contexte",
- phase: "Detect",
- description: "Utilisation du contexte pour influencer la perception",
- mots_cles: ["similaire", "same as", "cela rappelle", "déjà vu", "par ailleurs", "contexte"],
- weight: 0.9,
- type: "technique",
- tactic: "TA0012"
- },
- {
- index: "TE0131",
- nom: "Effet de bizarrerie",
- phase: "Detect",
- description: "Mise en avant d'éléments inhabituels pour attirer l'attention",
- mots_cles: ["étrange", "strange", "bizarre", "weird", "incroyable", "incredible", "choquant", "shocking", "inhabituel", "unusual"],
- weight: 1.3,
- type: "technique",
- tactic: "TA0013"
- },
- {
- index: "TE0132",
- nom: "Biais de négativité",
- phase: "Detect",
- description: "Accent mis sur les aspects négatifs pour capter l'attention",
- mots_cles: ["catastrophe", "chaos","disaster", "danger", "menace", "threat", "risque", "risk", "grave", "serious", "crise", "crisis"],
- weight: 1.4,
- type: "technique",
- tactic: "TA0013"
- },
- {
- index: "TE0141",
- nom: "Effet von Restorff",
- phase: "Detect",
- description: "Mise en avant de l'unicité pour marquer les esprits",
- mots_cles: ["unique", "seul", "only", "exclusif", "exclusive", "spécial", "special", "exceptionnel", "exceptional", "rare"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0014"
- },
- {
- index: "TE0142",
- nom: "Biais d'ancrage",
- phase: "Detect",
- description: "Première information comme point de référence",
- mots_cles: ["première fois", "first time", "jamais vu", "never seen", "inédit", "unprecedented", "révélation", "revelation"],
- weight: 1.2,
- type: "technique",
- tactic: "TA0015"
- },
- {
- index: "TE0143",
- nom: "Effet de contraste",
- phase: "Detect",
- description: "Comparaisons pour influencer la perception relative",
- mots_cles: ["par rapport à", "compare with", "différence", "difference", "comparaison", "delta", "distinction"],
- weight: 0.8,
- type: "technique",
- tactic: "TA0015"
- },
- {
- index: "TE0500",
- nom: "Clickbait",
- phase: "Detect",
- description: "Titres accrocheurs pour générer des clics",
- mots_cles: ["vous ne croirez pas", "you won't believe", "ce qui arrive ensuite", "what happens next", "secret", "shocking", "mind-blowing", "amazing"],
- weight: 1.5,
- type: "technique",
- tactic: "TA0013"
- },
-
- // PHASE INFORMER - TACTIQUES
- {
- index: "TA0021",
- nom: "Création d'un motif",
- phase: "Informer",
- description: "Construction artificielle de patterns ou de tendances",
- mots_cles: ["motif", "pattern", "tendance", "trend", "récurrent", "recurrent", "régulier", "regular", "systématique"],
- weight: 1.3,
- type: "tactic"
- },
- {
- index: "TA0022",
- nom: "Généralisation et renforcement de stéréotypes",
- phase: "Informer",
- description: "Utilisation et amplification de clichés pour simplifier",
- mots_cles: ["stéréotype", "stereotype", "cliché", "caricature", "généralement", "generally", "typique", "typical"],
- weight: 1.6,
- type: "tactic"
- },
- {
- index: "TA0023",
- nom: "Supériorité familière",
- phase: "Informer",
- description: "Valorisation de ce qui est connu et familier",
- mots_cles: ["mieux", "better", "supérieur", "superior", "préférable", "preferable", "notre", "our", "familier", "familiar"],
- weight: 1.2,
- type: "tactic"
- },
- {
- index: "TA0024",
- nom: "Simplification",
- phase: "Informer",
- description: "Réduction excessive de la complexité",
- mots_cles: ["simple", "simple", "facile", "easy", "évident", "obvious", "clair", "clear", "suffit", "enough"],
- weight: 1.3,
- type: "tactic"
- },
- {
- index: "TA0025",
- nom: "Auto-référence",
- phase: "Informer",
- description: "Utilisation de références internes pour créer une cohérence artificielle",
- mots_cles: ["comme nous", "like us", "notre", "our", "nous-mêmes", "ourselves", "chez nous", "among us"],
- weight: 1.2,
- type: "tactic"
- },
- {
- index: "TA0026",
- nom: "Projection temporelle",
- phase: "Informer",
- description: "Manipulation de la perception du temps",
- mots_cles: ["bientôt", "soon", "déjà", "already", "encore", "still", "toujours", "always", "jamais", "never"],
- weight: 1.1,
- type: "tactic"
- },
-
-// PHASE INFORMER - TECHNIQUES
- {
- index: "TE0211",
- nom: "Corrélation illusoire",
- phase: "Informer",
- description: "Présentation de corrélations trompeuses",
- mots_cles: ["corrélation", "similaire", "pareil", "comparaison", "lien", "relation"],
- weight: 1.3,
- type: "technique",
- tactic: "TA0021"
- },
- {
- index: "TE0212",
- nom: "Biais de la preuve anecdotique",
- phase: "Informer",
- description: "Généralisation basée sur des cas particuliers",
- mots_cles: ["cette histoire démontre", "anecdote", "exemple", "illustration","selon une étude","un témoignage","un témoin"],
- weight: 1.4,
- type: "technique",
- tactic: "TA0021"
- },
- {
- index: "TE0213",
- nom: "Illusion des séries",
- phase: "Informer",
- description: "Perception de motifs dans des données aléatoires",
- mots_cles: ["coïncidences", "motif", "données démontrent", "statistiques", "tendance"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0021"
- },
- {
- index: "TE0221",
- nom: "Stéréotypes",
- phase: "Informer",
- description: "Généralisation excessive de groupes",
- mots_cles: ["stéréotype", "les étrangers", "les immigrants", "all the", "toujours", "always", "jamais", "never", "en général", "in general", "les français", "americans"],
- weight: 1.6,
- type: "technique",
- tactic: "TA0022"
- },
- {
- index: "TE0231",
- nom: "Biais d'homogénéité",
- phase: "Informer",
- description: "Perception que tous les membres d'un groupe sont similaires",
- mots_cles: ["tous les", "Homogène", "tous pareil", "toutes choses égales par ailleurs"],
- weight: 1.2,
- type: "technique",
- tactic: "TA0022"
- },
- {
- index: "TE0232",
- nom: "Biais de la route connue",
- phase: "Informer",
- description: "Préférence pour les solutions familières",
- mots_cles: ["comme avant", "habitude", "habituel", "conserver", "rassurant"],
- weight: 0.9,
- type: "technique",
- tactic: "TA0023"
- },
- {
- index: "TE0241",
- nom: "Simplification excessive",
- phase: "Informer",
- description: "Réduction de problèmes complexes à des solutions simples",
- mots_cles: ["simple", "évident", "obvious", "clair", "clear", "facile", "easy", "suffit de", "just need to", "solution"],
- weight: 1.3,
- type: "technique",
- tactic: "TA0024"
- },
- {
- index: "TE0251",
- nom: "Faux consensus",
- phase: "Informer",
- description: "Illusion d'un accord général inexistant",
- mots_cles: ["tout le monde", "consensus", "convergence","everyone", "la plupart", "most people", "nous pensons", "we think", "accord"],
- weight: 1.4,
- type: "technique",
- tactic: "TA0025"
- },
- {
- index: "TE0261",
- nom: "Biais rétrospectif",
- phase: "Informer",
- description: "Illusion d'avoir prévu un événement après coup",
- mots_cles: ["j'avais dit", "nous étions prévenus", "on le savait","i told you", "prévisible", "predictable", "on aurait dû", "should have", "signes", "signs"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0026"
- },
-
- // PHASE MEMORISER - TACTIQUES
- {
- index: "TA0031",
- nom: "Renforcement indirect",
- phase: "Mémoriser",
- description: "Consolidation subtile d'informations par répétition indirecte",
- mots_cles: ["renforce", "reinforces", "confirme", "confirms", "soutient", "supports", "appuie", "backs"],
- weight: 1.2,
- type: "tactic"
- },
- {
- index: "TA0032",
- nom: "Renforcement pré-existant",
- phase: "Mémoriser",
- description: "Activation de croyances déjà établies",
- mots_cles: ["comme prévu", "as expected", "j'avais raison", "I was right", "évident", "obvious", "logique", "logical"],
- weight: 1.3,
- type: "tactic"
- },
- {
- index: "TA0033",
- nom: "Exposition de contenus",
- phase: "Mémoriser",
- description: "Présentation répétée de contenus pour ancrage mémoriel",
- mots_cles: ["exposition", "exposure", "présentation", "presentation", "affichage", "display", "montrer", "show"],
- weight: 1.1,
- type: "tactic"
- },
-
- // PHASE MEMORISER - TECHNIQUES
- {
- index: "TE0312",
- nom: "Biais de la confusion des sources",
- phase: "Mémoriser",
- description: "Difficulté à distinguer les sources d'information",
- mots_cles: ["des sources affirment", "sources confirment", "rien ne démontre", "hasard ?", "les faits"],
- weight: 1.2,
- type: "technique",
- tactic: "TA0031"
- },
- {
- index: "TE0313",
- nom: "Effet d'espacement",
- phase: "Mémoriser",
- description: "Répétition espacée pour renforcer la mémorisation",
- mots_cles: ["comme déjà", "dans un article précédent", "rappelons", "comme nous l'avons vu"],
- weight: 1.0,
- type: "technique",
- tactic: "TA0033"
- },
- {
- index: "TE0314",
- nom: "Effet de suggestion",
- phase: "Mémoriser",
- description: "Implantation d'idées par suggestion indirecte",
- mots_cles: ["et si", "cela évoque", "évoquer", "image", "imaginez", "supposons"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0031"
- },
- {
- index: "TE0321",
- nom: "Biais de confirmation",
- phase: "Mémoriser",
- description: "Recherche d'informations confirmant les croyances existantes",
- mots_cles: ["confirme", "cela démontre", "démontrer", "confirms", "prouve", "proves", "comme prévu", "as expected", "j'avais raison", "i was right", "évident", "obvious"],
- weight: 1.5,
- type: "technique",
- tactic: "TA0032"
- },
- {
- index: "TE0331",
- nom: "Effet de récence",
- phase: "Mémoriser",
- description: "Surpondération des informations récentes",
- mots_cles: ["récent", "recent", "nouveauté", "dernier", "last", "nouveau", "new", "frais", "fresh", "actuel", "current"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0033"
- },
- {
- index: "TE0333",
- nom: "Effet de primauté",
- phase: "Mémoriser",
- description: "Surpondération des premières informations reçues",
- mots_cles: ["premier", "first", "initial", "début", "beginning", "origine", "origin", "primordial"],
- weight: 1.0,
- type: "technique",
- tactic: "TA0033"
- },
-
- // PHASE AGIR - TACTIQUES
- {
- index: "TA0041",
- nom: "Valorisation individuelle",
- phase: "Act",
- description: "Mise en avant des bénéfices personnels pour motiver l'action",
- mots_cles: ["vous bénéficiez", "you benefit", "votre avantage", "your advantage", "pour vous", "for you", "personnel", "personal"],
- weight: 1.3,
- type: "tactic"
- },
- {
- index: "TA0042",
- nom: "Renforcement escalatoire",
- phase: "Act",
- description: "Augmentation progressive de l'engagement demandé",
- mots_cles: ["progressivement", "progressively", "étape par étape", "step by step", "graduellement", "gradually", "petit à petit"],
- weight: 1.4,
- type: "tactic"
- },
- {
- index: "TA0043",
- nom: "Ozaekomi waza (contrôle par immobilisation)",
- phase: "Act",
- description: "Blocage des alternatives pour forcer une décision",
- mots_cles: ["seule option", "only option", "pas le choix", "no choice", "obligé", "forced", "contrainte", "constraint"],
- weight: 1.5,
- type: "tactic"
- },
-
- // PHASE AGIR - TECHNIQUES
- {
- index: "TE0411",
- nom: "Excès de confiance",
- phase: "Act",
- description: "Surestimation de ses propres capacités ou connaissances",
- mots_cles: ["confiant", "confident", "sûr", "sure", "certain", "capable", "expert", "maîtrise", "mastery"],
- weight: 1.2,
- type: "technique",
- tactic: "TA0041"
- },
- {
- index: "TE0421",
- nom: "Coûts irrécupérables",
- phase: "Act",
- description: "Persistance dans une voie du fait d'investissements passés",
- mots_cles: ["continuer", "continue", "persister", "persist", "investir plus", "invest more", "ne pas abandonner", "don't give up"],
- weight: 1.1,
- type: "technique",
- tactic: "TA0042"
- },
- {
- index: "TE0422",
- nom: "Biais d'autorité",
- phase: "Act",
- description: "Influence excessive des figures d'autorité",
- mots_cles: ["autorité", "authority", "expert", "spécialiste", "specialist", "professeur", "professor", "docteur", "doctor", "officiel"],
- weight: 1.3,
- type: "technique",
- tactic: "TA0041"
- },
- {
- index: "TE0432",
- nom: "Biais du statu quo",
- phase: "Act",
- description: "Préférence pour maintenir l'état actuel",
- mots_cles: ["rester", "stay", "maintenir", "maintain", "ne pas changer", "don't change", "status quo", "comme ça", "as is"],
- weight: 1.0,
- type: "technique",
- tactic: "TA0043"
- },
- {
- index: "TE0501",
- nom: "FOMO",
- phase: "Act",
- description: "Peur de rater une opportunité",
- mots_cles: ["ne ratez pas", "don't miss", "dernière chance", "last chance", "limité", "limited", "exclusif", "exclusive", "hurry", "urgent"],
- weight: 1.4,
- type: "technique",
- tactic: "TA0041"
- }
-];
+// Version: 3.0 Refactored with ContentExtractor
+// Note: All dependencies are loaded via manifest.json in correct order
// ===== CLASSE PRINCIPALE DIMA =====
class DIMAAnalyzer {
- constructor() {
- this.analysisResults = null;
- this.buttonCreated = false;
- this.cache = new Map();
- this.settings = {
- maxContentLength: 5000,
- minKeywordLength: 3,
- analysisDelay: 2000,
- debugMode: false,
- enhancedKeywords: true
- };
- this.pageType = this.detectPageType();
- this.init();
+ constructor() {
+ this.analysisResults = null;
+ this.cache = new Map();
+ this.settings = {
+ maxContentLength: 5000,
+ minKeywordLength: 3,
+ analysisDelay: 2000,
+ debugMode: false,
+ enhancedKeywords: true,
+ }; // Initialize ContentExtractor with settings
+ this.contentExtractor = new window.ContentExtractor(this.settings);
+ this.pageType = this.contentExtractor.detectPageType();
+
+ // Initialize TechniqueAnalyzer with dependencies
+ this.techniqueAnalyzer = new window.TechniqueAnalyzer(
+ this.settings,
+ window.DIMA_ENHANCED_KEYWORDS,
+ window.CONTEXT_PATTERNS,
+ window.DIMA_TECHNIQUES,
+ this.pageType
+ );
+
+ // Initialize UIManager
+ this.uiManager = new window.UIManager(this.settings);
+ this.uiManager.setPageType(this.pageType);
+
+ this.init();
+ }
+
+ init() {
+ this.log("Initialisation DIMA avec mots-clés améliorés...");
+
+ if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", () => {
+ this.delayedInit();
+ });
+ } else {
+ this.delayedInit();
}
+ }
- detectPageType() {
- const url = window.location.href.toLowerCase();
- if (url.includes('news') || url.includes('article') || url.includes('actualit')) return 'news';
- if (url.includes('blog')) return 'blog';
- if (url.includes('facebook') || url.includes('twitter') || url.includes('instagram')) return 'social';
- if (url.includes('shop') || url.includes('buy') || url.includes('product') || url.includes('commerce')) return 'commerce';
- return 'general';
+ delayedInit() {
+ setTimeout(() => {
+ try {
+ this.analyzeCurrentPage();
+ } catch (error) {
+ console.error("DIMA: Erreur lors de l'analyse:", error);
+ }
+ }, this.settings.analysisDelay);
+ }
+
+ log(message, data = null) {
+ if (this.settings.debugMode) {
+ console.log(`DIMA: ${message}`, data || "");
}
+ }
- init() {
- this.log('Initialisation DIMA avec mots-clés améliorés...');
-
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', () => {
- this.delayedInit();
- });
- } else {
- this.delayedInit();
- }
- }
-
- delayedInit() {
- setTimeout(() => {
- try {
- this.analyzeCurrentPage();
- } catch (error) {
- console.error('DIMA: Erreur lors de l\'analyse:', error);
- }
- }, this.settings.analysisDelay);
- }
-
- log(message, data = null) {
- if (this.settings.debugMode) {
- console.log(`DIMA: ${message}`, data || '');
- }
- }
-analyzeCurrentPage() {
- try {
- this.log('Analyse de la page...');
-
- const cacheKey = window.location.href + document.title;
- if (this.cache.has(cacheKey)) {
- this.analysisResults = this.cache.get(cacheKey);
- this.createButton();
- return;
- }
-
- const title = this.extractTitle();
- const content = this.extractContent();
-
- this.log('Titre extrait:', title);
- this.log('Contenu extrait:', `${content.length} caractères`);
-
- this.analysisResults = this.performAnalysis(title, content);
- this.cache.set(cacheKey, this.analysisResults);
-
- this.log('Analyse terminée, score:', this.analysisResults.globalScore);
- this.createButton();
-
- } catch (error) {
- console.error('DIMA: Erreur dans analyzeCurrentPage:', error);
- }
- }
-
- extractTitle() {
- const titleSources = [
- () => document.title,
- () => document.querySelector('meta[property="og:title"]')?.content,
- () => document.querySelector('meta[name="twitter:title"]')?.content,
- () => document.querySelector('h1')?.textContent?.trim(),
- () => document.querySelector('.title, .headline, [class*="title"]')?.textContent?.trim()
- ];
-
- return titleSources
- .map(fn => fn())
- .filter(Boolean)
- .join(' ')
- .substring(0, 500)
- .trim();
- }
-
- extractContent() {
- this.log('Début extraction de contenu...');
-
- const extractedTexts = new Set();
- let content = '';
-
- // Sélecteurs prioritaires pour le contenu principal
- const contentSelectors = [
- 'article',
- '[role="main"]',
- 'main',
- '.article-content, .post-content, .entry-content',
- '.content, .story-body, .article-body',
- '#article-body, .post-body, .text-content'
- ];
-
- // Extraction du contenu principal
- for (const selector of contentSelectors) {
- const elements = document.querySelectorAll(selector);
- if (elements.length > 0) {
- this.log(`Contenu trouvé avec: ${selector}`);
- content += this.extractTextFromElements(elements, extractedTexts);
- if (content.length > 1000) break;
- }
- }
-
- // Fallback si contenu insuffisant
- if (content.length < 300) {
- this.log('Contenu insuffisant, utilisation de fallbacks...');
- const fallbackSelectors = [
- 'p, h1, h2, h3, h4, h5, h6',
- '.text, .description, .summary',
- '[class*="content"], [class*="text"]',
- 'blockquote, figcaption'
- ];
-
- for (const selector of fallbackSelectors) {
- const elements = document.querySelectorAll(selector);
- content += this.extractTextFromElements(elements, extractedTexts, 30);
- if (content.length > 1500) break;
- }
- }
-
- // Dernier recours
- if (content.length < 200) {
- this.log('Dernier recours - texte visible');
- const bodyText = this.cleanText(document.body.innerText);
- content = bodyText.substring(0, this.settings.maxContentLength);
- }
-
- const finalContent = content.substring(0, this.settings.maxContentLength).trim();
- this.log(`Extraction terminée: ${finalContent.length} caractères`);
-
- return finalContent;
- }
-
- extractTextFromElements(elements, extractedTexts, maxElements = 100) {
- let text = '';
- const elementsArray = Array.from(elements).slice(0, maxElements);
-
- for (const element of elementsArray) {
- if (this.shouldSkipElement(element)) continue;
-
- const elementText = this.cleanText(element.textContent || element.innerText);
- if (elementText &&
- elementText.length > 15 &&
- !extractedTexts.has(elementText)) {
- extractedTexts.add(elementText);
- text += elementText + ' ';
-
- if (text.length > this.settings.maxContentLength) break;
- }
- }
-
- return text;
- }
-
- shouldSkipElement(element) {
- const skipClasses = ['nav', 'menu', 'footer', 'header', 'sidebar', 'ad', 'advertisement', 'social', 'share'];
- const skipIds = ['nav', 'menu', 'footer', 'header', 'sidebar', 'comments'];
-
- const className = element.className?.toLowerCase() || '';
- const id = element.id?.toLowerCase() || '';
-
- return skipClasses.some(skip => className.includes(skip)) ||
- skipIds.some(skip => id.includes(skip)) ||
- element.getAttribute('aria-hidden') === 'true' ||
- getComputedStyle(element).display === 'none';
- }
-
- cleanText(text) {
- if (!text) return '';
-
- return text
- .replace(/\s+/g, ' ')
- .replace(/[\r\n\t]/g, ' ')
- .replace(/[^\w\s\.,!?;:()\-'"%àâäéèêëïîôöùûüÿç]/gi, '')
- .trim();
- }
-
- performAnalysis(title, content) {
- const fullText = (title + ' ' + content).toLowerCase();
- const detected = [];
- let totalScore = 0;
- const phaseScores = {};
-
- this.log('Analyse du texte...', fullText.substring(0, 200));
-
- // Analyser SEULEMENT les techniques (TE), pas les tactiques (TA)
- const techniques = DIMA_TECHNIQUES.filter(item => item.type === 'technique');
-
- for (const technique of techniques) {
- const analysis = this.analyzeTechnique(technique, fullText);
-
- if (analysis.score > 0) {
- detected.push(analysis);
- totalScore += analysis.weightedScore;
-
- // Calcul par phase
- if (!phaseScores[technique.phase]) {
- phaseScores[technique.phase] = 0;
- }
- phaseScores[technique.phase] += analysis.weightedScore;
-
- this.log(`Technique détectée: ${technique.index} (${analysis.score})`);
- }
- }
-
- // Score global avec normalisation améliorée
- const globalScore = Math.min(Math.round(totalScore * 3), 100);
-
- return {
- globalScore,
- detectedTechniques: detected.sort((a, b) => b.weightedScore - a.weightedScore),
- phaseScores,
- riskLevel: this.calculateRiskLevel(globalScore),
- riskColor: this.getColor(globalScore),
- url: window.location.href,
- title: title.substring(0, 200),
- contentLength: content.length,
- analyzedText: fullText.length,
- timestamp: new Date().toISOString()
- };
- }
-
- // ===== ANALYSE AMÉLIORÉE DES TECHNIQUES =====
- analyzeTechnique(technique, fullText) {
- // Utiliser le système amélioré si disponible et activé
- if (this.settings.enhancedKeywords && DIMA_ENHANCED_KEYWORDS[technique.index]) {
- return this.analyzeEnhancedTechnique(technique, fullText);
- }
-
- // Fallback vers l'ancienne méthode
- return this.analyzeBasicTechnique(technique, fullText);
- }
-
- analyzeEnhancedTechnique(technique, fullText) {
- const enhancedData = DIMA_ENHANCED_KEYWORDS[technique.index];
- const results = {
- matches: [],
- score: 0,
- contextBoosts: []
- };
-
- // 1. Analyse des mots-clés de base
- if (enhancedData.core) {
- const coreMatches = this.findKeywordMatches(fullText, enhancedData.core, 1.0);
- results.matches.push(...coreMatches);
- }
-
- // 2. Analyse des variantes
- if (enhancedData.variants) {
- for (const [category, variants] of Object.entries(enhancedData.variants)) {
- if (Array.isArray(variants)) {
- const weight = this.getVariantWeight(category);
- const variantMatches = this.findKeywordMatches(fullText, variants, weight);
- results.matches.push(...variantMatches.map(m => ({...m, category})));
- } else if (typeof variants === 'object') {
- // Variantes avec sous-catégories (ex: intensity.strong)
- for (const [subcat, subvariants] of Object.entries(variants)) {
- const weight = this.getIntensityWeight(subcat);
- const subMatches = this.findKeywordMatches(fullText, subvariants, weight);
- results.matches.push(...subMatches.map(m => ({...m, category: `${category}.${subcat}`})));
- }
- }
- }
- }
-
- // 3. Analyse des patterns regex
- if (enhancedData.patterns) {
- for (const pattern of enhancedData.patterns) {
- const patternMatches = this.findPatternMatches(fullText, pattern);
- results.matches.push(...patternMatches);
- }
- }
-
- // 4. Analyse contextuelle
- const contextBoosts = this.analyzeContext(fullText, technique.index);
- results.contextBoosts = contextBoosts;
-
- // 5. Calcul du score
- results.score = results.matches.reduce((sum, match) => sum + match.weight, 0);
-
- // 6. Application des boosts contextuels
- let finalScore = results.score;
- for (const boost of contextBoosts) {
- finalScore *= boost.boost;
- }
-
- // 7. Pondération contextuelle et dynamique
- let contextualWeight = this.calculateContextualWeight(technique, this.pageType);
- let dynamicWeight = this.calculateDynamicWeight(technique, finalScore);
-
- const totalWeight = (technique.weight || 1.0) * contextualWeight * dynamicWeight;
- const weightedScore = finalScore * totalWeight;
-
- const confidence = Math.min(Math.round(results.score * 15 + results.matches.length * 10), 100);
-
- return {
- index: technique.index,
- nom: technique.nom,
- phase: technique.phase,
- description: technique.description || '',
- score: Math.round(finalScore),
- weightedScore,
- finalWeight: totalWeight,
- contextualWeight,
- dynamicWeight,
- confidence,
- matchedKeywords: this.formatEnhancedMatches(results.matches),
- enhancedAnalysis: {
- coreMatches: results.matches.filter(m => m.type === 'core').length,
- variantMatches: results.matches.filter(m => m.type === 'variant').length,
- patternMatches: results.matches.filter(m => m.type === 'pattern').length,
- contextBoosts: results.contextBoosts
- }
- };
- }
-
- analyzeBasicTechnique(technique, fullText) {
- let score = 0;
- const matchedKeywords = [];
-
- for (const keyword of technique.mots_cles) {
- if (keyword.length < this.settings.minKeywordLength) continue;
-
- const keywordLower = keyword.toLowerCase();
- const matches = this.findKeywordMatches(fullText, [keywordLower], 1.0);
-
- if (matches.length > 0) {
- score += matches.length;
- matchedKeywords.push({
- keyword,
- count: matches.length,
- type: 'basic'
- });
- }
- }
-
- // Pondération contextuelle et dynamique
- let contextualWeight = this.calculateContextualWeight(technique, this.pageType);
- let dynamicWeight = this.calculateDynamicWeight(technique, score);
-
- const finalWeight = (technique.weight || 1.0) * contextualWeight * dynamicWeight;
- const weightedScore = score * finalWeight;
-
- const confidence = Math.min(Math.round(score * 15 + weightedScore * 5), 100);
-
- return {
- index: technique.index,
- nom: technique.nom,
- phase: technique.phase,
- description: technique.description || '',
- score,
- weightedScore,
- finalWeight,
- contextualWeight,
- dynamicWeight,
- confidence,
- matchedKeywords
- };
- }
- // ===== MÉTHODES UTILITAIRES POUR L'ANALYSE =====
- findKeywordMatches(text, keywords, weight = 1.0) {
- const matches = [];
-
- for (const keyword of keywords) {
- const keywordLower = keyword.toLowerCase();
- let regex;
-
- if (keywordLower.includes(' ')) {
- // Expression avec espaces
- regex = new RegExp(this.escapeRegex(keywordLower), 'gi');
- } else {
- // Mot simple avec frontières
- regex = new RegExp('\\b' + this.escapeRegex(keywordLower) + '\\b', 'gi');
- }
-
- let match;
- while ((match = regex.exec(text)) !== null) {
- matches.push({
- type: 'core',
- keyword: keyword,
- position: match.index,
- weight: weight
- });
- }
- }
-
- return matches;
- }
-
- findPatternMatches(text, pattern) {
- const matches = [];
- let match;
-
- // Réinitialiser le regex pour éviter les problèmes de state
- pattern.lastIndex = 0;
-
- while ((match = pattern.exec(text)) !== null) {
- matches.push({
- type: 'pattern',
- keyword: match[0],
- position: match.index,
- weight: 1.5 // Les patterns ont un poids plus élevé
- });
-
- // Éviter les boucles infinies
- if (!pattern.global) break;
- }
-
- return matches;
- }
-
- analyzeContext(text, techniqueId) {
- const boosts = [];
-
- for (const [contextType, contextData] of Object.entries(CONTEXT_PATTERNS)) {
- if (contextData.techniques.includes(techniqueId)) {
- for (const pattern of contextData.patterns) {
- if (pattern.test(text)) {
- boosts.push({
- type: contextType,
- boost: contextData.boost,
- pattern: pattern.source
- });
- }
- }
- }
- }
-
- return boosts;
- }
-
- getVariantWeight(category) {
- const weights = {
- 'formal': 0.9,
- 'informal': 1.1,
- 'clickbait_formulas': 1.6,
- 'emotional_hooks': 1.4,
- 'curiosity_gaps': 1.5,
- 'urgency': 1.3,
- 'scarcity': 1.4,
- 'temporal': 1.2
- };
- return weights[category] || 1.0;
- }
-
- getIntensityWeight(intensity) {
- const weights = {
- 'weak': 0.7,
- 'strong': 1.5
- };
- return weights[intensity] || 1.0;
- }
-
- formatEnhancedMatches(matches) {
- const grouped = {};
-
- for (const match of matches) {
- const key = match.keyword;
- if (!grouped[key]) {
- grouped[key] = {
- keyword: key,
- count: 0,
- type: match.type,
- category: match.category,
- totalWeight: 0
- };
- }
- grouped[key].count++;
- grouped[key].totalWeight += match.weight;
- }
-
- return Object.values(grouped);
- }
-
- escapeRegex(string) {
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
- }
-
- calculateRiskLevel(score) {
- if (score < 15) return 'Faible';
- if (score < 30) return 'Modéré';
- if (score < 50) return 'Élevé';
- if (score < 75) return 'Très Élevé';
- return 'Critique';
- }
-
- // ===== PONDÉRATION CONTEXTUELLE =====
- calculateContextualWeight(technique, pageType) {
- let contextualWeight = 1.0;
-
- switch (pageType) {
- case 'news':
- if (technique.index === 'TE0500') contextualWeight = 1.4; // Clickbait très grave
- if (technique.index === 'TE0132') contextualWeight = 1.3; // Biais négativité plus suspect
- if (technique.index === 'TE0221') contextualWeight = 1.5; // Stéréotypes inacceptables
- if (technique.index === 'TE0212') contextualWeight = 1.3; // Preuves anecdotiques problématiques
- if (technique.index === 'TE0261') contextualWeight = 0.8; // Biais rétrospectif plus normal
- break;
-
- case 'social':
- if (technique.index === 'TE0132') contextualWeight = 0.9; // Négativité plus courante
- if (technique.index === 'TE0131') contextualWeight = 0.8; // Bizarrerie normale
- if (technique.index === 'TE0501') contextualWeight = 1.3; // FOMO plus manipulatoire
- if (technique.index === 'TE0221') contextualWeight = 1.6; // Stéréotypes très graves
- if (technique.index === 'TE0251') contextualWeight = 1.2; // Faux consensus suspect
- break;
-
- case 'commerce':
- if (technique.index === 'TE0501') contextualWeight = 0.9; // FOMO plus normale
- if (technique.index === 'TE0141') contextualWeight = 0.8; // Effet Restorff marketing normal
- if (technique.index === 'TE0143') contextualWeight = 0.7; // Comparaisons normales
- if (technique.index === 'TE0422') contextualWeight = 1.2; // Fausse autorité problématique
- if (technique.index === 'TE0411') contextualWeight = 1.1; // Excès confiance suspect
- break;
-
- case 'blog':
- if (technique.index === 'TE0212') contextualWeight = 0.8; // Anecdotes plus normales
- if (technique.index === 'TE0314') contextualWeight = 0.9; // Suggestions plus acceptables
- if (technique.index === 'TE0261') contextualWeight = 0.7; // Biais rétrospectif courant
- if (technique.index === 'TE0321') contextualWeight = 1.1; // Biais confirmation suspect
- break;
- }
-
- this.log(`Poids contextuel pour ${technique.index} sur ${pageType}: ${contextualWeight}`);
- return contextualWeight;
- }
-
- // ===== PONDÉRATION DYNAMIQUE =====
- calculateDynamicWeight(technique, occurrences) {
- let dynamicWeight = 1.0;
-
- // Plus une technique apparaît, plus elle devient suspecte
- if (occurrences >= 10) {
- dynamicWeight = 1.4; // Très suspect si >10 occurrences
- } else if (occurrences >= 7) {
- dynamicWeight = 1.3; // Suspect si 7-9 occurrences
- } else if (occurrences >= 5) {
- dynamicWeight = 1.2; // Légèrement suspect si 5-6 occurrences
- } else if (occurrences >= 3) {
- dynamicWeight = 1.1; // Un peu suspect si 3-4 occurrences
- }
-
- // Cas spéciaux : certaines techniques sont plus graves même avec peu d'occurrences
- const criticalTechniques = ['TE0221', 'TE0500', 'TE0132', 'TE0501'];
- if (criticalTechniques.includes(technique.index) && occurrences >= 2) {
- dynamicWeight *= 1.1; // Bonus de gravité pour techniques critiques
- }
-
- // Réduire le poids si technique très fréquente mais bénigne
- const benignTechniques = ['TE0143', 'TE0232', 'TE0333'];
- if (benignTechniques.includes(technique.index) && occurrences >= 5) {
- dynamicWeight *= 0.9; // Réduction pour techniques bénignes trop fréquentes
- }
-
- this.log(`Poids dynamique pour ${technique.index} (${occurrences} occ.): ${dynamicWeight}`);
- return dynamicWeight;
- }
-
- getColor(score) {
- if (score < 15) return '#27ae60'; // Vert
- if (score < 30) return '#f39c12'; // Orange clair
- if (score < 50) return '#e67e22'; // Orange
- if (score < 75) return '#d35400'; // Rouge-orange
- return '#c0392b'; // Rouge foncé
- }
-
- // ===== INTERFACE UTILISATEUR =====
- createButton() {
- try {
- // Supprimer bouton existant
- document.getElementById('dima-btn')?.remove();
-
- if (this.buttonCreated) return;
-
- const button = document.createElement('div');
- button.id = 'dima-btn';
-
- button.innerHTML = `
-
- 🧠
- ${this.analysisResults.globalScore}
- ${this.analysisResults.riskLevel}
-
- `;
-
- button.style.cssText = `
- position: fixed !important;
- top: 20px !important;
- right: 20px !important;
- z-index: 999999 !important;
- background: linear-gradient(135deg, ${this.analysisResults.riskColor}, ${this.adjustColor(this.analysisResults.riskColor, -20)}) !important;
- color: white !important;
- padding: 12px 16px !important;
- border-radius: 25px !important;
- cursor: pointer !important;
- font-family: 'Segoe UI', Arial, sans-serif !important;
- font-size: 14px !important;
- box-shadow: 0 4px 15px rgba(0,0,0,0.2), 0 2px 5px rgba(0,0,0,0.1) !important;
- border: 2px solid rgba(255,255,255,0.2) !important;
- user-select: none !important;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
- backdrop-filter: blur(10px) !important;
- `;
-
- button.title = this.generateTooltip();
-
- // Événements
- button.addEventListener('click', () => this.showModal());
- button.addEventListener('mouseenter', () => {
- button.style.transform = 'scale(1.05) translateY(-2px)';
- button.style.boxShadow = '0 6px 20px rgba(0,0,0,0.3), 0 4px 8px rgba(0,0,0,0.2)';
- });
- button.addEventListener('mouseleave', () => {
- button.style.transform = 'scale(1) translateY(0)';
- button.style.boxShadow = '0 4px 15px rgba(0,0,0,0.2), 0 2px 5px rgba(0,0,0,0.1)';
- });
-
- document.body?.appendChild(button);
- this.buttonCreated = true;
- this.log('Bouton créé avec succès');
-
- } catch (error) {
- console.error('DIMA: Erreur création bouton:', error);
- }
- }
-
- adjustColor(color, amount) {
- const num = parseInt(color.replace("#", ""), 16);
- const amt = Math.round(2.55 * amount);
- const R = (num >> 16) + amt;
- const G = (num >> 8 & 0x00FF) + amt;
- const B = (num & 0x0000FF) + amt;
- return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
- (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
- (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
- }
-
- generateTooltip() {
- const techniques = this.analysisResults.detectedTechniques.slice(0, 3);
- return `DIMA Score: ${this.analysisResults.globalScore} (${this.analysisResults.riskLevel})
-${this.analysisResults.detectedTechniques.length} techniques détectées
-${techniques.map(t => `• ${t.nom}`).join('\n')}
-Contenu: ${this.analysisResults.contentLength} caractères`;
- }
-
- showModal() {
- try {
- this.log('Affichage du modal');
-
- document.getElementById('dima-modal')?.remove();
-
- const modal = document.createElement('div');
- modal.id = 'dima-modal';
-
- modal.style.cssText = `
- position: fixed !important;
- top: 0 !important;
- left: 0 !important;
- width: 100% !important;
- height: 100% !important;
- background: rgba(0,0,0,0.75) !important;
- backdrop-filter: blur(5px) !important;
- z-index: 9999999 !important;
- display: flex !important;
- align-items: center !important;
- justify-content: center !important;
- font-family: 'Segoe UI', Arial, sans-serif !important;
- animation: fadeIn 0.3s ease-out !important;
- `;
- // Récupérer l'URL du logo
- const logoUrl = chrome.runtime.getURL('m82-logo-16.png');
-
- modal.innerHTML = `
-
-
-
-
-
-

-
Analyse DIMA
-
-
- Détection de techniques de manipulation cognitive par
- M82 Project
-
-
-
-
-
-
-
${this.analysisResults.globalScore}
-
Score Global
-
-
-
${this.analysisResults.detectedTechniques.length}
-
Techniques
-
-
-
${this.analysisResults.riskLevel}
-
Niveau Risque
-
-
-
${this.analysisResults.contentLength}
-
Caractères
-
-
-
-
-
-
📄 Page analysée
-
${this.analysisResults.title}
-
${this.analysisResults.url}
-
- Analysé le ${new Date(this.analysisResults.timestamp).toLocaleString('fr-FR')} •
- ${this.analysisResults.analyzedText} caractères traités • Type: ${this.pageType}
-
-
-
-
- ${this.analysisResults.detectedTechniques.length === 0 ? `
-
-
✅
-
Aucune manipulation détectée
-
Le contenu analysé semble exempt de techniques de manipulation cognitive manifestes
-
- ` : `
-
-
⚠️ Techniques de manipulation détectées
-
- ${this.analysisResults.detectedTechniques.slice(0, 8).map(technique => `
-
-
-
-
- ${technique.phase === 'Detect' ? '👁️' : technique.phase === 'Informer' ? '📢' : technique.phase === 'Mémoriser' ? '🧠' : '⚡'} ${technique.index}: ${technique.nom}
-
- ${technique.tactic ? `
↳ Tactique: ${technique.tactic}
` : ''}
- ${technique.description ? `
${technique.description}
` : ''}
-
-
- ${technique.confidence}%
-
-
-
-
-
- ${technique.phase}
-
-
-
Score pondéré: ${technique.weightedScore?.toFixed(1) || technique.score}
-
-
-
- ${technique.matchedKeywords?.length > 0 ? `
-
-
- 🔍 Mots-clés détectés:
-
-
- ${technique.matchedKeywords.slice(0, 4).map(keyword =>
- `
- ${keyword.keyword} ${(keyword.count > 1) ? `(×${keyword.count})` : ''}
- `
- ).join('')}
- ${technique.matchedKeywords.length > 4 ?
- `+${technique.matchedKeywords.length - 4} autres...`
- : ''
- }
-
-
- ` : ''}
-
- `).join('')}
-
-
- `}
-
-
-
-
-
-
-
-
-
-
-
- `;
-
- modal.addEventListener('click', (e) => {
- if (e.target === modal) modal.remove();
- });
-
- document.body.appendChild(modal);
- this.log('Modal affiché');
-
- } catch (error) {
- console.error('DIMA: Erreur modal:', error);
- }
+ analyzeCurrentPage() {
+ try {
+ this.log("Analyse de la page...");
+
+ const cacheKey = window.location.href + document.title;
+ if (this.cache.has(cacheKey)) {
+ this.analysisResults = this.cache.get(cacheKey);
+ this.uiManager.createButton(this.analysisResults);
+ return;
+ }
+
+ const title = this.contentExtractor.extractTitle();
+ const content = this.contentExtractor.extractContent();
+
+ this.log("Titre extrait:", title);
+ this.log("Contenu extrait:", `${content.length} caractères`);
+
+ this.analysisResults = this.techniqueAnalyzer.performAnalysis(
+ title,
+ content
+ );
+ this.cache.set(cacheKey, this.analysisResults);
+
+ this.log("Analyse terminée, score:", this.analysisResults.globalScore);
+ this.uiManager.createButton(this.analysisResults);
+ } catch (error) {
+ console.error("DIMA: Erreur dans analyzeCurrentPage:", error);
}
+ }
}
// ===== INITIALISATION ET STYLES =====
// CSS pour les animations
-const style = document.createElement('style');
+const style = document.createElement("style");
style.textContent = `
@keyframes dimaFadeIn {
from { opacity: 0; transform: scale(0.9); }
@@ -1439,11 +110,37 @@ style.textContent = `
document.head.appendChild(style);
// Initialisation sécurisée avec gestion d'erreurs améliorée
-console.log('DIMA: Script chargé - Version complète avec mots-clés améliorés');
+console.log("DIMA: Script chargé - Version complète avec mots-clés améliorés");
-try {
- const analyzer = new DIMAAnalyzer();
- console.log(`DIMA: Analyseur initialisé pour page de type: ${analyzer.pageType}`);
-} catch (error) {
- console.error('DIMA: Erreur d\'initialisation critique:', error);
+// Vérifier que toutes les dépendances sont chargées
+function checkDependencies() {
+ return (
+ window.DIMA_TECHNIQUES &&
+ window.DIMA_ENHANCED_KEYWORDS &&
+ window.CONTEXT_PATTERNS &&
+ window.ContentExtractor &&
+ window.TechniqueAnalyzer &&
+ window.UIManager
+ );
}
+
+// Initialiser avec retry si nécessaire
+function initializeDIMA() {
+ if (!checkDependencies()) {
+ console.log("DIMA: Attente du chargement des dépendances...");
+ setTimeout(initializeDIMA, 100);
+ return;
+ }
+
+ try {
+ const analyzer = new DIMAAnalyzer();
+ console.log(
+ `DIMA: Analyseur initialisé pour page de type: ${analyzer.pageType}`
+ );
+ } catch (error) {
+ console.error("DIMA: Erreur d'initialisation critique:", error);
+ }
+}
+
+// Démarrer l'initialisation
+initializeDIMA();
diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/data/keywords.js b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/data/keywords.js
new file mode 100644
index 0000000..76fda44
--- /dev/null
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/data/keywords.js
@@ -0,0 +1,163 @@
+// DIMA Enhanced Keywords Database
+// Enhanced keyword patterns for manipulation technique detection
+
+const DIMA_ENHANCED_KEYWORDS = {
+ TE0111: {
+ core: ["exemple", "cas", "témoignage", "example", "case", "testimony"],
+ variants: {
+ formal: ["illustration", "démonstration", "spécimen"],
+ informal: ["histoire", "vécu", "expérience"],
+ intensity: {
+ weak: ["petit exemple", "simple cas"],
+ strong: ["exemple frappant", "cas édifiant", "témoignage bouleversant"],
+ },
+ },
+ patterns: [
+ /(?:par\s+exemple|for\s+example|comme\s+dans\s+le\s+cas)/i,
+ /(?:prenons\s+l'exemple|take\s+the\s+example)/i,
+ ],
+ },
+
+ TE0500: {
+ core: ["secret", "choquant", "incroyable", "shocking", "amazing"],
+ variants: {
+ clickbait_formulas: [
+ "vous ne croirez pas",
+ "ce qui arrive ensuite",
+ "you won't believe",
+ "what happens next",
+ "les experts détestent",
+ "un truc simple",
+ "cette astuce",
+ "révélation choc",
+ "doctors hate this",
+ ],
+ emotional_hooks: [
+ "ça va vous surprendre",
+ "préparez-vous",
+ "attention",
+ "exclusif",
+ "urgent",
+ "will shock you",
+ "prepare yourself",
+ ],
+ curiosity_gaps: [
+ "la raison va vous étonner",
+ "voici pourquoi",
+ "découvrez comment",
+ "la vérité sur",
+ "the reason will amaze you",
+ "here's why",
+ ],
+ },
+ patterns: [
+ /\d+\s+(?:choses|façons|méthodes|secrets|things|ways|methods)\s+(?:que|pour|de|to|that)/i,
+ /(?:voici|découvrez|here's|discover)\s+(?:comment|pourquoi|ce que|how|why|what)/i,
+ /(?:cette|cette|this)\s+\w+\s+va\s+vous\s+(?:\w+|will)/i,
+ /(?:shocking|amazing|incredible)\s+(?:secret|truth|fact)/i,
+ ],
+ },
+
+ TE0132: {
+ core: [
+ "catastrophe",
+ "panique",
+ "chaos",
+ "disaster",
+ "danger",
+ "menace",
+ "threat",
+ "risque",
+ "risk",
+ "grave",
+ "serious",
+ "crise",
+ "crisis",
+ ],
+ variants: {
+ intensity: {
+ weak: ["problème", "difficulté", "souci", "issue", "concern"],
+ strong: [
+ "catastrophe majeure",
+ "crise grave",
+ "danger mortel",
+ "major catastrophe",
+ "deadly danger",
+ ],
+ },
+ temporal: ["imminent", "proche", "bientôt", "soon", "approaching"],
+ },
+ patterns: [
+ /(?:alerte|alert|warning|attention)\s+(?:rouge|red|maximum)/i,
+ /(?:situation|crisis|problem)\s+(?:critique|critical|dramatique|dramatic)/i,
+ ],
+ },
+
+ TE0501: {
+ core: [
+ "ne ratez pas",
+ "don't miss",
+ "dernière chance",
+ "last chance",
+ "limité",
+ "limited",
+ "exclusif",
+ "exclusive",
+ ],
+ variants: {
+ urgency: [
+ "dépêchez-vous",
+ "hurry up",
+ "vite",
+ "quickly",
+ "maintenant ou jamais",
+ "now or never",
+ ],
+ scarcity: [
+ "stock limité",
+ "places limitées",
+ "limited stock",
+ "limited seats",
+ "offre limitée",
+ ],
+ },
+ patterns: [
+ /(?:seulement|only)\s+\d+\s+(?:jours?|heures?|minutes?|days?|hours?|minutes?)/i,
+ /(?:expire|ends?)\s+(?:bientôt|soon|today|demain|tomorrow)/i,
+ ],
+ },
+};
+
+const CONTEXT_PATTERNS = {
+ urgency: {
+ patterns: [
+ /(?:urgent|rapidement|vite|immédiatement|maintenant|now|quickly|immediately)/i,
+ /(?:dernière\s+chance|temps\s+limité|offre\s+limitée|last\s+chance|limited\s+time)/i,
+ /(?:dépêchez-vous|ne\s+ratez\s+pas|hurry|don't\s+miss)/i,
+ ],
+ boost: 1.3,
+ techniques: ["TE0501", "TE0500"],
+ },
+ authority: {
+ patterns: [
+ /(?:selon\s+(?:les\s+)?(?:experts?|spécialistes?|docteurs?|doctors?|experts?))/i,
+ /(?:étude\s+(?:révèle|montre|démontre|shows?|reveals?))/i,
+ /(?:recherche\s+(?:scientifique|universitaire|scientific|university))/i,
+ ],
+ boost: 1.4,
+ techniques: ["TE0422", "TE0212"],
+ },
+ social_proof: {
+ patterns: [
+ /(?:\d+(?:\.\d+)?[km]?\s+personnes?\s+(?:utilisent|font|pensent|people\s+(?:use|do|think)))/i,
+ /(?:tout\s+le\s+monde|la\s+plupart\s+des\s+gens|everyone|most\s+people)/i,
+ /(?:viral|tendance|populaire|trending|popular)/i,
+ ],
+ boost: 1.2,
+ techniques: ["TE0251", "TE0221"],
+ },
+};
+
+// Make keywords and patterns available globally for Chrome extension
+window.DIMA_ENHANCED_KEYWORDS = DIMA_ENHANCED_KEYWORDS;
+window.CONTEXT_PATTERNS = CONTEXT_PATTERNS;
diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/data/techniques.js b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/data/techniques.js
new file mode 100644
index 0000000..d1cad77
--- /dev/null
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/data/techniques.js
@@ -0,0 +1,922 @@
+// DIMA Techniques Database
+// Complete database of manipulation techniques and tactics
+
+const DIMA_TECHNIQUES = [
+ // PHASE DETECTER - TACTIQUES
+ {
+ index: "TA0011",
+ nom: "Information préexistante",
+ phase: "Detect",
+ description: "Exploitation d'informations déjà connues ou familières",
+ mots_cles: [
+ "déjà",
+ "connu",
+ "already",
+ "known",
+ "familier",
+ "familiar",
+ "habituel",
+ "usual",
+ "précédemment",
+ "previously",
+ ],
+ weight: 1.1,
+ type: "tactic",
+ },
+ {
+ index: "TA0012",
+ nom: "Information à exposition répétée",
+ phase: "Detect",
+ description:
+ "Répétition d'informations pour créer une familiarité artificielle",
+ mots_cles: [
+ "encore",
+ "again",
+ "répéter",
+ "repeat",
+ "redire",
+ "retell",
+ "rappel",
+ "reminder",
+ "à nouveau",
+ "once again",
+ ],
+ weight: 1.2,
+ type: "tactic",
+ },
+ {
+ index: "TA0013",
+ nom: "Information clivante",
+ phase: "Detect",
+ description:
+ "Utilisation d'informations polarisantes pour attirer l'attention",
+ mots_cles: [
+ "polémique",
+ "controversial",
+ "scandaleux",
+ "outrageous",
+ "choquant",
+ "shocking",
+ "divise",
+ "divides",
+ "clivant",
+ ],
+ weight: 1.4,
+ type: "tactic",
+ },
+ {
+ index: "TA0014",
+ nom: "Écart à la norme",
+ phase: "Detect",
+ description: "Mise en avant d'éléments sortant de l'ordinaire",
+ mots_cles: [
+ "inhabituel",
+ "unusual",
+ "anormal",
+ "abnormal",
+ "exception",
+ "extraordinary",
+ "hors norme",
+ "atypique",
+ ],
+ weight: 1.3,
+ type: "tactic",
+ },
+ {
+ index: "TA0015",
+ nom: "Détail signifiant",
+ phase: "Detect",
+ description:
+ "Focus sur des détails pour donner une impression de précision",
+ mots_cles: [
+ "précisément",
+ "exactly",
+ "détail",
+ "detail",
+ "spécifiquement",
+ "specifically",
+ "en particulier",
+ "particularly",
+ ],
+ weight: 1.1,
+ type: "tactic",
+ },
+
+ // PHASE DETECTER - TECHNIQUES
+ {
+ index: "TE0111",
+ nom: "Heuristique de disponibilité",
+ phase: "Detect",
+ description: "Surreprésentation d'exemples facilement mémorisables",
+ mots_cles: [
+ "récent",
+ "disponible",
+ "recently",
+ "exemple",
+ "example",
+ "cas",
+ "case",
+ "témoignage",
+ "testimony",
+ ],
+ weight: 1.0,
+ type: "technique",
+ tactic: "TA0011",
+ },
+ {
+ index: "TE0112",
+ nom: "Effet de simple exposition",
+ phase: "Detect",
+ description: "Répétition pour créer une familiarité artificielle",
+ mots_cles: [
+ "encore",
+ "again",
+ "toujours",
+ "always",
+ "répétition",
+ "repetition",
+ "familier",
+ "familiar",
+ ],
+ weight: 1.2,
+ type: "technique",
+ tactic: "TA0011",
+ },
+ {
+ index: "TE0121",
+ nom: "Illusion de la fréquence",
+ phase: "Detect",
+ description: "Impression exagérée de fréquence d'un phénomène",
+ mots_cles: [
+ "partout",
+ "everywhere",
+ "de plus en plus",
+ "more and more",
+ "fréquent",
+ "frequent",
+ "épidémie",
+ "epidemic",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0012",
+ },
+ {
+ index: "TE0122",
+ nom: "Effet de contexte",
+ phase: "Detect",
+ description: "Utilisation du contexte pour influencer la perception",
+ mots_cles: [
+ "similaire",
+ "same as",
+ "cela rappelle",
+ "déjà vu",
+ "par ailleurs",
+ "contexte",
+ ],
+ weight: 0.9,
+ type: "technique",
+ tactic: "TA0012",
+ },
+ {
+ index: "TE0131",
+ nom: "Effet de bizarrerie",
+ phase: "Detect",
+ description:
+ "Mise en avant d'éléments inhabituels pour attirer l'attention",
+ mots_cles: [
+ "étrange",
+ "strange",
+ "bizarre",
+ "weird",
+ "incroyable",
+ "incredible",
+ "choquant",
+ "shocking",
+ "inhabituel",
+ "unusual",
+ ],
+ weight: 1.3,
+ type: "technique",
+ tactic: "TA0013",
+ },
+ {
+ index: "TE0132",
+ nom: "Biais de négativité",
+ phase: "Detect",
+ description: "Accent mis sur les aspects négatifs pour capter l'attention",
+ mots_cles: [
+ "catastrophe",
+ "chaos",
+ "disaster",
+ "danger",
+ "menace",
+ "threat",
+ "risque",
+ "risk",
+ "grave",
+ "serious",
+ "crise",
+ "crisis",
+ ],
+ weight: 1.4,
+ type: "technique",
+ tactic: "TA0013",
+ },
+ {
+ index: "TE0141",
+ nom: "Effet von Restorff",
+ phase: "Detect",
+ description: "Mise en avant de l'unicité pour marquer les esprits",
+ mots_cles: [
+ "unique",
+ "seul",
+ "only",
+ "exclusif",
+ "exclusive",
+ "spécial",
+ "special",
+ "exceptionnel",
+ "exceptional",
+ "rare",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0014",
+ },
+ {
+ index: "TE0142",
+ nom: "Biais d'ancrage",
+ phase: "Detect",
+ description: "Première information comme point de référence",
+ mots_cles: [
+ "première fois",
+ "first time",
+ "jamais vu",
+ "never seen",
+ "inédit",
+ "unprecedented",
+ "révélation",
+ "revelation",
+ ],
+ weight: 1.2,
+ type: "technique",
+ tactic: "TA0015",
+ },
+ {
+ index: "TE0143",
+ nom: "Effet de contraste",
+ phase: "Detect",
+ description: "Comparaisons pour influencer la perception relative",
+ mots_cles: [
+ "par rapport à",
+ "compare with",
+ "différence",
+ "difference",
+ "comparaison",
+ "delta",
+ "distinction",
+ ],
+ weight: 0.8,
+ type: "technique",
+ tactic: "TA0015",
+ },
+ {
+ index: "TE0500",
+ nom: "Clickbait",
+ phase: "Detect",
+ description: "Titres accrocheurs pour générer des clics",
+ mots_cles: [
+ "vous ne croirez pas",
+ "you won't believe",
+ "ce qui arrive ensuite",
+ "what happens next",
+ "secret",
+ "shocking",
+ "mind-blowing",
+ "amazing",
+ ],
+ weight: 1.5,
+ type: "technique",
+ tactic: "TA0013",
+ },
+
+ // PHASE INFORMER - TACTIQUES
+ {
+ index: "TA0021",
+ nom: "Création d'un motif",
+ phase: "Informer",
+ description: "Construction artificielle de patterns ou de tendances",
+ mots_cles: [
+ "motif",
+ "pattern",
+ "tendance",
+ "trend",
+ "récurrent",
+ "recurrent",
+ "régulier",
+ "regular",
+ "systématique",
+ ],
+ weight: 1.3,
+ type: "tactic",
+ },
+ {
+ index: "TA0022",
+ nom: "Généralisation et renforcement de stéréotypes",
+ phase: "Informer",
+ description: "Utilisation et amplification de clichés pour simplifier",
+ mots_cles: [
+ "stéréotype",
+ "stereotype",
+ "cliché",
+ "caricature",
+ "généralement",
+ "generally",
+ "typique",
+ "typical",
+ ],
+ weight: 1.6,
+ type: "tactic",
+ },
+ {
+ index: "TA0023",
+ nom: "Supériorité familière",
+ phase: "Informer",
+ description: "Valorisation de ce qui est connu et familier",
+ mots_cles: [
+ "mieux",
+ "better",
+ "supérieur",
+ "superior",
+ "préférable",
+ "preferable",
+ "notre",
+ "our",
+ "familier",
+ "familiar",
+ ],
+ weight: 1.2,
+ type: "tactic",
+ },
+ {
+ index: "TA0024",
+ nom: "Simplification",
+ phase: "Informer",
+ description: "Réduction excessive de la complexité",
+ mots_cles: [
+ "simple",
+ "simple",
+ "facile",
+ "easy",
+ "évident",
+ "obvious",
+ "clair",
+ "clear",
+ "suffit",
+ "enough",
+ ],
+ weight: 1.3,
+ type: "tactic",
+ },
+ {
+ index: "TA0025",
+ nom: "Auto-référence",
+ phase: "Informer",
+ description:
+ "Utilisation de références internes pour créer une cohérence artificielle",
+ mots_cles: [
+ "comme nous",
+ "like us",
+ "notre",
+ "our",
+ "nous-mêmes",
+ "ourselves",
+ "chez nous",
+ "among us",
+ ],
+ weight: 1.2,
+ type: "tactic",
+ },
+ {
+ index: "TA0026",
+ nom: "Projection temporelle",
+ phase: "Informer",
+ description: "Manipulation de la perception du temps",
+ mots_cles: [
+ "bientôt",
+ "soon",
+ "déjà",
+ "already",
+ "encore",
+ "still",
+ "toujours",
+ "always",
+ "jamais",
+ "never",
+ ],
+ weight: 1.1,
+ type: "tactic",
+ },
+
+ // PHASE INFORMER - TECHNIQUES
+ {
+ index: "TE0211",
+ nom: "Corrélation illusoire",
+ phase: "Informer",
+ description: "Présentation de corrélations trompeuses",
+ mots_cles: [
+ "corrélation",
+ "similaire",
+ "pareil",
+ "comparaison",
+ "lien",
+ "relation",
+ ],
+ weight: 1.3,
+ type: "technique",
+ tactic: "TA0021",
+ },
+ {
+ index: "TE0212",
+ nom: "Biais de la preuve anecdotique",
+ phase: "Informer",
+ description: "Généralisation basée sur des cas particuliers",
+ mots_cles: [
+ "cette histoire démontre",
+ "anecdote",
+ "exemple",
+ "illustration",
+ "selon une étude",
+ "un témoignage",
+ "un témoin",
+ ],
+ weight: 1.4,
+ type: "technique",
+ tactic: "TA0021",
+ },
+ {
+ index: "TE0213",
+ nom: "Illusion des séries",
+ phase: "Informer",
+ description: "Perception de motifs dans des données aléatoires",
+ mots_cles: [
+ "coïncidences",
+ "motif",
+ "données démontrent",
+ "statistiques",
+ "tendance",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0021",
+ },
+ {
+ index: "TE0221",
+ nom: "Stéréotypes",
+ phase: "Informer",
+ description: "Généralisation excessive de groupes",
+ mots_cles: [
+ "stéréotype",
+ "les étrangers",
+ "les immigrants",
+ "all the",
+ "toujours",
+ "always",
+ "jamais",
+ "never",
+ "en général",
+ "in general",
+ "les français",
+ "americans",
+ ],
+ weight: 1.6,
+ type: "technique",
+ tactic: "TA0022",
+ },
+ {
+ index: "TE0231",
+ nom: "Biais d'homogénéité",
+ phase: "Informer",
+ description: "Perception que tous les membres d'un groupe sont similaires",
+ mots_cles: [
+ "tous les",
+ "Homogène",
+ "tous pareil",
+ "toutes choses égales par ailleurs",
+ ],
+ weight: 1.2,
+ type: "technique",
+ tactic: "TA0022",
+ },
+ {
+ index: "TE0232",
+ nom: "Biais de la route connue",
+ phase: "Informer",
+ description: "Préférence pour les solutions familières",
+ mots_cles: [
+ "comme avant",
+ "habitude",
+ "habituel",
+ "conserver",
+ "rassurant",
+ ],
+ weight: 0.9,
+ type: "technique",
+ tactic: "TA0023",
+ },
+ {
+ index: "TE0241",
+ nom: "Simplification excessive",
+ phase: "Informer",
+ description: "Réduction de problèmes complexes à des solutions simples",
+ mots_cles: [
+ "simple",
+ "évident",
+ "obvious",
+ "clair",
+ "clear",
+ "facile",
+ "easy",
+ "suffit de",
+ "just need to",
+ "solution",
+ ],
+ weight: 1.3,
+ type: "technique",
+ tactic: "TA0024",
+ },
+ {
+ index: "TE0251",
+ nom: "Faux consensus",
+ phase: "Informer",
+ description: "Illusion d'un accord général inexistant",
+ mots_cles: [
+ "tout le monde",
+ "consensus",
+ "convergence",
+ "everyone",
+ "la plupart",
+ "most people",
+ "nous pensons",
+ "we think",
+ "accord",
+ ],
+ weight: 1.4,
+ type: "technique",
+ tactic: "TA0025",
+ },
+ {
+ index: "TE0261",
+ nom: "Biais rétrospectif",
+ phase: "Informer",
+ description: "Illusion d'avoir prévu un événement après coup",
+ mots_cles: [
+ "j'avais dit",
+ "nous étions prévenus",
+ "on le savait",
+ "i told you",
+ "prévisible",
+ "predictable",
+ "on aurait dû",
+ "should have",
+ "signes",
+ "signs",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0026",
+ },
+
+ // PHASE MEMORISER - TACTIQUES
+ {
+ index: "TA0031",
+ nom: "Renforcement indirect",
+ phase: "Mémoriser",
+ description:
+ "Consolidation subtile d'informations par répétition indirecte",
+ mots_cles: [
+ "renforce",
+ "reinforces",
+ "confirme",
+ "confirms",
+ "soutient",
+ "supports",
+ "appuie",
+ "backs",
+ ],
+ weight: 1.2,
+ type: "tactic",
+ },
+ {
+ index: "TA0032",
+ nom: "Renforcement pré-existant",
+ phase: "Mémoriser",
+ description: "Activation de croyances déjà établies",
+ mots_cles: [
+ "comme prévu",
+ "as expected",
+ "j'avais raison",
+ "I was right",
+ "évident",
+ "obvious",
+ "logique",
+ "logical",
+ ],
+ weight: 1.3,
+ type: "tactic",
+ },
+ {
+ index: "TA0033",
+ nom: "Exposition de contenus",
+ phase: "Mémoriser",
+ description: "Présentation répétée de contenus pour ancrage mémoriel",
+ mots_cles: [
+ "exposition",
+ "exposure",
+ "présentation",
+ "presentation",
+ "affichage",
+ "display",
+ "montrer",
+ "show",
+ ],
+ weight: 1.1,
+ type: "tactic",
+ },
+
+ // PHASE MEMORISER - TECHNIQUES
+ {
+ index: "TE0312",
+ nom: "Biais de la confusion des sources",
+ phase: "Mémoriser",
+ description: "Difficulté à distinguer les sources d'information",
+ mots_cles: [
+ "des sources affirment",
+ "sources confirment",
+ "rien ne démontre",
+ "hasard ?",
+ "les faits",
+ ],
+ weight: 1.2,
+ type: "technique",
+ tactic: "TA0031",
+ },
+ {
+ index: "TE0313",
+ nom: "Effet d'espacement",
+ phase: "Mémoriser",
+ description: "Répétition espacée pour renforcer la mémorisation",
+ mots_cles: [
+ "comme déjà",
+ "dans un article précédent",
+ "rappelons",
+ "comme nous l'avons vu",
+ ],
+ weight: 1.0,
+ type: "technique",
+ tactic: "TA0033",
+ },
+ {
+ index: "TE0314",
+ nom: "Effet de suggestion",
+ phase: "Mémoriser",
+ description: "Implantation d'idées par suggestion indirecte",
+ mots_cles: [
+ "et si",
+ "cela évoque",
+ "évoquer",
+ "image",
+ "imaginez",
+ "supposons",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0031",
+ },
+ {
+ index: "TE0321",
+ nom: "Biais de confirmation",
+ phase: "Mémoriser",
+ description: "Recherche d'informations confirmant les croyances existantes",
+ mots_cles: [
+ "confirme",
+ "cela démontre",
+ "démontrer",
+ "confirms",
+ "prouve",
+ "proves",
+ "comme prévu",
+ "as expected",
+ "j'avais raison",
+ "i was right",
+ "évident",
+ "obvious",
+ ],
+ weight: 1.5,
+ type: "technique",
+ tactic: "TA0032",
+ },
+ {
+ index: "TE0331",
+ nom: "Effet de récence",
+ phase: "Mémoriser",
+ description: "Surpondération des informations récentes",
+ mots_cles: [
+ "récent",
+ "recent",
+ "nouveauté",
+ "dernier",
+ "last",
+ "nouveau",
+ "new",
+ "frais",
+ "fresh",
+ "actuel",
+ "current",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0033",
+ },
+ {
+ index: "TE0333",
+ nom: "Effet de primauté",
+ phase: "Mémoriser",
+ description: "Surpondération des premières informations reçues",
+ mots_cles: [
+ "premier",
+ "first",
+ "initial",
+ "début",
+ "beginning",
+ "origine",
+ "origin",
+ "primordial",
+ ],
+ weight: 1.0,
+ type: "technique",
+ tactic: "TA0033",
+ },
+
+ // PHASE AGIR - TACTIQUES
+ {
+ index: "TA0041",
+ nom: "Valorisation individuelle",
+ phase: "Act",
+ description: "Mise en avant des bénéfices personnels pour motiver l'action",
+ mots_cles: [
+ "vous bénéficiez",
+ "you benefit",
+ "votre avantage",
+ "your advantage",
+ "pour vous",
+ "for you",
+ "personnel",
+ "personal",
+ ],
+ weight: 1.3,
+ type: "tactic",
+ },
+ {
+ index: "TA0042",
+ nom: "Renforcement escalatoire",
+ phase: "Act",
+ description: "Augmentation progressive de l'engagement demandé",
+ mots_cles: [
+ "progressivement",
+ "progressively",
+ "étape par étape",
+ "step by step",
+ "graduellement",
+ "gradually",
+ "petit à petit",
+ ],
+ weight: 1.4,
+ type: "tactic",
+ },
+ {
+ index: "TA0043",
+ nom: "Ozaekomi waza (contrôle par immobilisation)",
+ phase: "Act",
+ description: "Blocage des alternatives pour forcer une décision",
+ mots_cles: [
+ "seule option",
+ "only option",
+ "pas le choix",
+ "no choice",
+ "obligé",
+ "forced",
+ "contrainte",
+ "constraint",
+ ],
+ weight: 1.5,
+ type: "tactic",
+ },
+
+ // PHASE AGIR - TECHNIQUES
+ {
+ index: "TE0411",
+ nom: "Excès de confiance",
+ phase: "Act",
+ description: "Surestimation de ses propres capacités ou connaissances",
+ mots_cles: [
+ "confiant",
+ "confident",
+ "sûr",
+ "sure",
+ "certain",
+ "capable",
+ "expert",
+ "maîtrise",
+ "mastery",
+ ],
+ weight: 1.2,
+ type: "technique",
+ tactic: "TA0041",
+ },
+ {
+ index: "TE0421",
+ nom: "Coûts irrécupérables",
+ phase: "Act",
+ description: "Persistance dans une voie du fait d'investissements passés",
+ mots_cles: [
+ "continuer",
+ "continue",
+ "persister",
+ "persist",
+ "investir plus",
+ "invest more",
+ "ne pas abandonner",
+ "don't give up",
+ ],
+ weight: 1.1,
+ type: "technique",
+ tactic: "TA0042",
+ },
+ {
+ index: "TE0422",
+ nom: "Biais d'autorité",
+ phase: "Act",
+ description: "Influence excessive des figures d'autorité",
+ mots_cles: [
+ "autorité",
+ "authority",
+ "expert",
+ "spécialiste",
+ "specialist",
+ "professeur",
+ "professor",
+ "docteur",
+ "doctor",
+ "officiel",
+ ],
+ weight: 1.3,
+ type: "technique",
+ tactic: "TA0041",
+ },
+ {
+ index: "TE0432",
+ nom: "Biais du statu quo",
+ phase: "Act",
+ description: "Préférence pour maintenir l'état actuel",
+ mots_cles: [
+ "rester",
+ "stay",
+ "maintenir",
+ "maintain",
+ "ne pas changer",
+ "don't change",
+ "status quo",
+ "comme ça",
+ "as is",
+ ],
+ weight: 1.0,
+ type: "technique",
+ tactic: "TA0043",
+ },
+ {
+ index: "TE0501",
+ nom: "FOMO",
+ phase: "Act",
+ description: "Peur de rater une opportunité",
+ mots_cles: [
+ "ne ratez pas",
+ "don't miss",
+ "dernière chance",
+ "last chance",
+ "limité",
+ "limited",
+ "exclusif",
+ "exclusive",
+ "hurry",
+ "urgent",
+ ],
+ weight: 1.4,
+ type: "technique",
+ tactic: "TA0041",
+ },
+];
+
+// Make DIMA_TECHNIQUES available globally for Chrome extension
+window.DIMA_TECHNIQUES = DIMA_TECHNIQUES;
diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/manifest.json b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/manifest.json
index c655011..5e19395 100644
--- a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/manifest.json
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/manifest.json
@@ -1,23 +1,34 @@
{
"manifest_version": 3,
"name": "Analyseur DIMA - M82 Project",
- "version": "1.0",
+ "version": "1.1",
"description": "Plugin d'analyse de manipulation cognitive selon la matrice DIMA par M82 Project",
"permissions": ["activeTab", "storage"],
- "content_scripts": [{
- "matches": [""],
- "js": ["content.js"]
- }],
+ "content_scripts": [
+ {
+ "matches": [""],
+ "js": [
+ "data/techniques.js",
+ "data/keywords.js",
+ "modules/contentExtractor.js",
+ "modules/techniqueAnalyzer.js",
+ "modules/uiManager.js",
+ "content.js"
+ ]
+ }
+ ],
"action": {
"default_title": "Analyse DIMA - M82 Project"
},
"icons": {
- "16": "m82-logo-16.png",
- "48": "m82-logo-48.png",
- "128": "m82-logo-128.png"
+ "16": "M82-logo-16.png",
+ "48": "M82-logo-48.png",
+ "128": "M82-logo-128.png"
},
- "web_accessible_resources": [{
- "resources": ["m82-logo-16.png"],
- "matches": [""]
- }]
-}
\ No newline at end of file
+ "web_accessible_resources": [
+ {
+ "resources": ["M82-logo-16.png"],
+ "matches": [""]
+ }
+ ]
+}
diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/contentExtractor.js b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/contentExtractor.js
new file mode 100644
index 0000000..15ea1db
--- /dev/null
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/contentExtractor.js
@@ -0,0 +1,184 @@
+// Content Extractor Module
+// Responsible for extracting and cleaning content from web pages
+
+class ContentExtractor {
+ constructor(settings) {
+ this.settings = settings || {
+ maxContentLength: 5000,
+ minKeywordLength: 3,
+ debugMode: false,
+ };
+ }
+
+ log(message, data = null) {
+ if (this.settings.debugMode) {
+ console.log(`ContentExtractor: ${message}`, data || "");
+ }
+ }
+
+ extractTitle() {
+ const titleSources = [
+ () => document.title,
+ () => document.querySelector('meta[property="og:title"]')?.content,
+ () => document.querySelector('meta[name="twitter:title"]')?.content,
+ () => document.querySelector("h1")?.textContent?.trim(),
+ () =>
+ document
+ .querySelector('.title, .headline, [class*="title"]')
+ ?.textContent?.trim(),
+ ];
+
+ return titleSources
+ .map((fn) => fn())
+ .filter(Boolean)
+ .join(" ")
+ .substring(0, 500)
+ .trim();
+ }
+
+ extractContent() {
+ this.log("Début extraction de contenu...");
+
+ const extractedTexts = new Set();
+ let content = "";
+
+ // Sélecteurs prioritaires pour le contenu principal
+ const contentSelectors = [
+ "article",
+ '[role="main"]',
+ "main",
+ ".article-content, .post-content, .entry-content",
+ ".content, .story-body, .article-body",
+ "#article-body, .post-body, .text-content",
+ ];
+
+ // Extraction du contenu principal
+ for (const selector of contentSelectors) {
+ const elements = document.querySelectorAll(selector);
+ if (elements.length > 0) {
+ this.log(`Contenu trouvé avec: ${selector}`);
+ content += this.extractTextFromElements(elements, extractedTexts);
+ if (content.length > 1000) break;
+ }
+ }
+
+ // Fallback si contenu insuffisant
+ if (content.length < 300) {
+ this.log("Contenu insuffisant, utilisation de fallbacks...");
+ const fallbackSelectors = [
+ "p, h1, h2, h3, h4, h5, h6",
+ ".text, .description, .summary",
+ '[class*="content"], [class*="text"]',
+ "blockquote, figcaption",
+ ];
+
+ for (const selector of fallbackSelectors) {
+ const elements = document.querySelectorAll(selector);
+ content += this.extractTextFromElements(elements, extractedTexts, 30);
+ if (content.length > 1500) break;
+ }
+ }
+
+ // Dernier recours
+ if (content.length < 200) {
+ this.log("Dernier recours - texte visible");
+ const bodyText = this.cleanText(document.body.innerText);
+ content = bodyText.substring(0, this.settings.maxContentLength);
+ }
+
+ const finalContent = content
+ .substring(0, this.settings.maxContentLength)
+ .trim();
+ this.log(`Extraction terminée: ${finalContent.length} caractères`);
+
+ return finalContent;
+ }
+
+ extractTextFromElements(elements, extractedTexts, maxElements = 100) {
+ let text = "";
+ const elementsArray = Array.from(elements).slice(0, maxElements);
+
+ for (const element of elementsArray) {
+ if (this.shouldSkipElement(element)) continue;
+
+ const elementText = this.cleanText(
+ element.textContent || element.innerText
+ );
+ if (
+ elementText &&
+ elementText.length > 15 &&
+ !extractedTexts.has(elementText)
+ ) {
+ extractedTexts.add(elementText);
+ text += elementText + " ";
+
+ if (text.length > this.settings.maxContentLength) break;
+ }
+ }
+
+ return text;
+ }
+
+ shouldSkipElement(element) {
+ const skipClasses = [
+ "nav",
+ "menu",
+ "footer",
+ "header",
+ "sidebar",
+ "ad",
+ "advertisement",
+ "social",
+ "share",
+ ];
+ const skipIds = ["nav", "menu", "footer", "header", "sidebar", "comments"];
+
+ const className = element.className?.toLowerCase() || "";
+ const id = element.id?.toLowerCase() || "";
+
+ return (
+ skipClasses.some((skip) => className.includes(skip)) ||
+ skipIds.some((skip) => id.includes(skip)) ||
+ element.getAttribute("aria-hidden") === "true" ||
+ getComputedStyle(element).display === "none"
+ );
+ }
+
+ cleanText(text) {
+ if (!text) return "";
+
+ return text
+ .replace(/\s+/g, " ")
+ .replace(/[\r\n\t]/g, " ")
+ .replace(/[^\w\s\.,!?;:()\-'"%àâäéèêëïîôöùûüÿç]/gi, "")
+ .trim();
+ }
+
+ detectPageType() {
+ const url = window.location.href.toLowerCase();
+ if (
+ url.includes("news") ||
+ url.includes("article") ||
+ url.includes("actualit")
+ )
+ return "news";
+ if (url.includes("blog")) return "blog";
+ if (
+ url.includes("facebook") ||
+ url.includes("twitter") ||
+ url.includes("instagram")
+ )
+ return "social";
+ if (
+ url.includes("shop") ||
+ url.includes("buy") ||
+ url.includes("product") ||
+ url.includes("commerce")
+ )
+ return "commerce";
+ return "general";
+ }
+}
+
+// Make ContentExtractor available globally for Chrome extension
+window.ContentExtractor = ContentExtractor;
diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/techniqueAnalyzer.js b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/techniqueAnalyzer.js
new file mode 100644
index 0000000..81b369d
--- /dev/null
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/techniqueAnalyzer.js
@@ -0,0 +1,473 @@
+// Technique Analyzer Module
+// Responsible for analyzing manipulation techniques in text
+
+class TechniqueAnalyzer {
+ constructor(
+ settings,
+ enhancedKeywords,
+ contextPatterns,
+ techniques,
+ pageType = "general"
+ ) {
+ this.settings = settings || {
+ enhancedKeywords: true,
+ minKeywordLength: 3,
+ debugMode: false,
+ };
+ this.enhancedKeywords = enhancedKeywords;
+ this.contextPatterns = contextPatterns;
+ this.techniques = techniques;
+ this.pageType = pageType;
+ }
+
+ log(message, data = null) {
+ if (this.settings.debugMode) {
+ console.log(`TechniqueAnalyzer: ${message}`, data || "");
+ }
+ }
+
+ performAnalysis(title, content) {
+ const fullText = (title + " " + content).toLowerCase();
+ const detected = [];
+ let totalScore = 0;
+ const phaseScores = {};
+
+ this.log("Analyse du texte...", fullText.substring(0, 200));
+
+ // Analyser SEULEMENT les techniques (TE), pas les tactiques (TA)
+ const techniques = this.techniques.filter(
+ (item) => item.type === "technique"
+ );
+
+ for (const technique of techniques) {
+ const analysis = this.analyzeTechnique(technique, fullText);
+
+ if (analysis.score > 0) {
+ detected.push(analysis);
+ totalScore += analysis.weightedScore;
+
+ // Calcul par phase
+ if (!phaseScores[technique.phase]) {
+ phaseScores[technique.phase] = 0;
+ }
+ phaseScores[technique.phase] += analysis.weightedScore;
+
+ this.log(`Technique détectée: ${technique.index} (${analysis.score})`);
+ }
+ }
+
+ // Score global avec normalisation améliorée
+ const globalScore = Math.min(Math.round(totalScore * 3), 100);
+
+ return {
+ globalScore,
+ detectedTechniques: detected.sort(
+ (a, b) => b.weightedScore - a.weightedScore
+ ),
+ phaseScores,
+ riskLevel: this.calculateRiskLevel(globalScore),
+ riskColor: this.getColor(globalScore),
+ url: window.location.href,
+ title: title.substring(0, 200),
+ contentLength: content.length,
+ analyzedText: fullText.length,
+ timestamp: new Date().toISOString(),
+ };
+ }
+
+ analyzeTechnique(technique, fullText) {
+ // Utiliser le système amélioré si disponible et activé
+ if (
+ this.settings.enhancedKeywords &&
+ this.enhancedKeywords[technique.index]
+ ) {
+ return this.analyzeEnhancedTechnique(technique, fullText);
+ }
+
+ // Fallback vers l'ancienne méthode
+ return this.analyzeBasicTechnique(technique, fullText);
+ }
+
+ analyzeEnhancedTechnique(technique, fullText) {
+ const enhancedData = this.enhancedKeywords[technique.index];
+ const results = {
+ matches: [],
+ score: 0,
+ contextBoosts: [],
+ };
+
+ // 1. Analyse des mots-clés de base
+ if (enhancedData.core) {
+ const coreMatches = this.findKeywordMatches(
+ fullText,
+ enhancedData.core,
+ 1.0
+ );
+ results.matches.push(...coreMatches);
+ }
+
+ // 2. Analyse des variantes
+ if (enhancedData.variants) {
+ for (const [category, variants] of Object.entries(
+ enhancedData.variants
+ )) {
+ if (Array.isArray(variants)) {
+ const weight = this.getVariantWeight(category);
+ const variantMatches = this.findKeywordMatches(
+ fullText,
+ variants,
+ weight
+ );
+ results.matches.push(
+ ...variantMatches.map((m) => ({ ...m, category }))
+ );
+ } else if (typeof variants === "object") {
+ // Variantes avec sous-catégories (ex: intensity.strong)
+ for (const [subcat, subvariants] of Object.entries(variants)) {
+ const weight = this.getIntensityWeight(subcat);
+ const subMatches = this.findKeywordMatches(
+ fullText,
+ subvariants,
+ weight
+ );
+ results.matches.push(
+ ...subMatches.map((m) => ({
+ ...m,
+ category: `${category}.${subcat}`,
+ }))
+ );
+ }
+ }
+ }
+ }
+
+ // 3. Analyse des patterns regex
+ if (enhancedData.patterns) {
+ for (const pattern of enhancedData.patterns) {
+ const patternMatches = this.findPatternMatches(fullText, pattern);
+ results.matches.push(...patternMatches);
+ }
+ }
+
+ // 4. Analyse contextuelle
+ const contextBoosts = this.analyzeContext(fullText, technique.index);
+ results.contextBoosts = contextBoosts;
+
+ // 5. Calcul du score
+ results.score = results.matches.reduce(
+ (sum, match) => sum + match.weight,
+ 0
+ );
+
+ // 6. Application des boosts contextuels
+ let finalScore = results.score;
+ for (const boost of contextBoosts) {
+ finalScore *= boost.boost;
+ }
+
+ // 7. Pondération contextuelle et dynamique
+ let contextualWeight = this.calculateContextualWeight(
+ technique,
+ this.pageType
+ );
+ let dynamicWeight = this.calculateDynamicWeight(technique, finalScore);
+
+ const totalWeight =
+ (technique.weight || 1.0) * contextualWeight * dynamicWeight;
+ const weightedScore = finalScore * totalWeight;
+
+ const confidence = Math.min(
+ Math.round(results.score * 15 + results.matches.length * 10),
+ 100
+ );
+
+ return {
+ index: technique.index,
+ nom: technique.nom,
+ phase: technique.phase,
+ description: technique.description || "",
+ score: Math.round(finalScore),
+ weightedScore,
+ finalWeight: totalWeight,
+ contextualWeight,
+ dynamicWeight,
+ confidence,
+ matchedKeywords: this.formatEnhancedMatches(results.matches),
+ enhancedAnalysis: {
+ coreMatches: results.matches.filter((m) => m.type === "core").length,
+ variantMatches: results.matches.filter((m) => m.type === "variant")
+ .length,
+ patternMatches: results.matches.filter((m) => m.type === "pattern")
+ .length,
+ contextBoosts: results.contextBoosts,
+ },
+ };
+ }
+
+ analyzeBasicTechnique(technique, fullText) {
+ let score = 0;
+ const matchedKeywords = [];
+
+ for (const keyword of technique.mots_cles) {
+ if (keyword.length < this.settings.minKeywordLength) continue;
+
+ const keywordLower = keyword.toLowerCase();
+ const matches = this.findKeywordMatches(fullText, [keywordLower], 1.0);
+
+ if (matches.length > 0) {
+ score += matches.length;
+ matchedKeywords.push({
+ keyword,
+ count: matches.length,
+ type: "basic",
+ });
+ }
+ }
+
+ // Pondération contextuelle et dynamique
+ let contextualWeight = this.calculateContextualWeight(
+ technique,
+ this.pageType
+ );
+ let dynamicWeight = this.calculateDynamicWeight(technique, score);
+
+ const finalWeight =
+ (technique.weight || 1.0) * contextualWeight * dynamicWeight;
+ const weightedScore = score * finalWeight;
+
+ const confidence = Math.min(
+ Math.round(score * 15 + weightedScore * 5),
+ 100
+ );
+
+ return {
+ index: technique.index,
+ nom: technique.nom,
+ phase: technique.phase,
+ description: technique.description || "",
+ score,
+ weightedScore,
+ finalWeight,
+ contextualWeight,
+ dynamicWeight,
+ confidence,
+ matchedKeywords,
+ };
+ }
+
+ findKeywordMatches(text, keywords, weight = 1.0) {
+ const matches = [];
+
+ for (const keyword of keywords) {
+ const keywordLower = keyword.toLowerCase();
+ let regex;
+
+ if (keywordLower.includes(" ")) {
+ // Expression avec espaces
+ regex = new RegExp(this.escapeRegex(keywordLower), "gi");
+ } else {
+ // Mot simple avec frontières
+ regex = new RegExp(
+ "\\b" + this.escapeRegex(keywordLower) + "\\b",
+ "gi"
+ );
+ }
+
+ let match;
+ while ((match = regex.exec(text)) !== null) {
+ matches.push({
+ type: "core",
+ keyword: keyword,
+ position: match.index,
+ weight: weight,
+ });
+ }
+ }
+
+ return matches;
+ }
+
+ findPatternMatches(text, pattern) {
+ const matches = [];
+ let match;
+
+ // Réinitialiser le regex pour éviter les problèmes de state
+ pattern.lastIndex = 0;
+
+ while ((match = pattern.exec(text)) !== null) {
+ matches.push({
+ type: "pattern",
+ keyword: match[0],
+ position: match.index,
+ weight: 1.5, // Les patterns ont un poids plus élevé
+ });
+
+ // Éviter les boucles infinies
+ if (!pattern.global) break;
+ }
+
+ return matches;
+ }
+
+ analyzeContext(text, techniqueId) {
+ const boosts = [];
+
+ for (const [contextType, contextData] of Object.entries(
+ this.contextPatterns
+ )) {
+ if (contextData.techniques.includes(techniqueId)) {
+ for (const pattern of contextData.patterns) {
+ if (pattern.test(text)) {
+ boosts.push({
+ type: contextType,
+ boost: contextData.boost,
+ pattern: pattern.source,
+ });
+ }
+ }
+ }
+ }
+
+ return boosts;
+ }
+
+ getVariantWeight(category) {
+ const weights = {
+ formal: 0.9,
+ informal: 1.1,
+ clickbait_formulas: 1.6,
+ emotional_hooks: 1.4,
+ curiosity_gaps: 1.5,
+ urgency: 1.3,
+ scarcity: 1.4,
+ temporal: 1.2,
+ };
+ return weights[category] || 1.0;
+ }
+
+ getIntensityWeight(intensity) {
+ const weights = {
+ weak: 0.7,
+ strong: 1.5,
+ };
+ return weights[intensity] || 1.0;
+ }
+
+ formatEnhancedMatches(matches) {
+ const grouped = {};
+
+ for (const match of matches) {
+ const key = match.keyword;
+ if (!grouped[key]) {
+ grouped[key] = {
+ keyword: key,
+ count: 0,
+ type: match.type,
+ category: match.category,
+ totalWeight: 0,
+ };
+ }
+ grouped[key].count++;
+ grouped[key].totalWeight += match.weight;
+ }
+
+ return Object.values(grouped);
+ }
+
+ escapeRegex(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+ }
+
+ calculateRiskLevel(score) {
+ if (score < 15) return "Faible";
+ if (score < 30) return "Modéré";
+ if (score < 50) return "Élevé";
+ if (score < 75) return "Très Élevé";
+ return "Critique";
+ }
+
+ calculateContextualWeight(technique, pageType) {
+ let contextualWeight = 1.0;
+
+ switch (pageType) {
+ case "news":
+ if (technique.index === "TE0500") contextualWeight = 1.4;
+ if (technique.index === "TE0132") contextualWeight = 1.3;
+ if (technique.index === "TE0221") contextualWeight = 1.5;
+ if (technique.index === "TE0212") contextualWeight = 1.3;
+ if (technique.index === "TE0261") contextualWeight = 0.8;
+ break;
+
+ case "social":
+ if (technique.index === "TE0132") contextualWeight = 0.9;
+ if (technique.index === "TE0131") contextualWeight = 0.8;
+ if (technique.index === "TE0501") contextualWeight = 1.3;
+ if (technique.index === "TE0221") contextualWeight = 1.6;
+ if (technique.index === "TE0251") contextualWeight = 1.2;
+ break;
+
+ case "commerce":
+ if (technique.index === "TE0501") contextualWeight = 0.9;
+ if (technique.index === "TE0141") contextualWeight = 0.8;
+ if (technique.index === "TE0143") contextualWeight = 0.7;
+ if (technique.index === "TE0422") contextualWeight = 1.2;
+ if (technique.index === "TE0411") contextualWeight = 1.1;
+ break;
+
+ case "blog":
+ if (technique.index === "TE0212") contextualWeight = 0.8;
+ if (technique.index === "TE0314") contextualWeight = 0.9;
+ if (technique.index === "TE0261") contextualWeight = 0.7;
+ if (technique.index === "TE0321") contextualWeight = 1.1;
+ break;
+ }
+
+ this.log(
+ `Poids contextuel pour ${technique.index} sur ${pageType}: ${contextualWeight}`
+ );
+ return contextualWeight;
+ }
+
+ calculateDynamicWeight(technique, occurrences) {
+ let dynamicWeight = 1.0;
+
+ // Plus une technique apparaît, plus elle devient suspecte
+ if (occurrences >= 10) {
+ dynamicWeight = 1.4;
+ } else if (occurrences >= 7) {
+ dynamicWeight = 1.3;
+ } else if (occurrences >= 5) {
+ dynamicWeight = 1.2;
+ } else if (occurrences >= 3) {
+ dynamicWeight = 1.1;
+ }
+
+ // Cas spéciaux : certaines techniques sont plus graves même avec peu d'occurrences
+ const criticalTechniques = ["TE0221", "TE0500", "TE0132", "TE0501"];
+ if (criticalTechniques.includes(technique.index) && occurrences >= 2) {
+ dynamicWeight *= 1.1;
+ }
+
+ // Réduire le poids si technique très fréquente mais bénigne
+ const benignTechniques = ["TE0143", "TE0232", "TE0333"];
+ if (benignTechniques.includes(technique.index) && occurrences >= 5) {
+ dynamicWeight *= 0.9;
+ }
+
+ this.log(
+ `Poids dynamique pour ${technique.index} (${occurrences} occ.): ${dynamicWeight}`
+ );
+ return dynamicWeight;
+ }
+
+ getColor(score) {
+ if (score < 15) return "#27ae60"; // Vert
+ if (score < 30) return "#f39c12"; // Orange clair
+ if (score < 50) return "#e67e22"; // Orange
+ if (score < 75) return "#d35400"; // Rouge-orange
+ return "#c0392b"; // Rouge foncé
+ }
+}
+
+// Make TechniqueAnalyzer available globally for Chrome extension
+window.TechniqueAnalyzer = TechniqueAnalyzer;
diff --git a/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/uiManager.js b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/uiManager.js
new file mode 100644
index 0000000..c753733
--- /dev/null
+++ b/plugin/plugin_chrome/fichiers à télécharger/Plugin-dima/modules/uiManager.js
@@ -0,0 +1,290 @@
+// UI Manager Module
+// Responsible for creating and managing the user interface elements
+
+class UIManager {
+ constructor(settings) {
+ this.settings = settings || {
+ debugMode: false,
+ };
+ this.buttonCreated = false;
+ this.analysisResults = null;
+ this.pageType = 'general';
+ }
+
+ log(message, data = null) {
+ if (this.settings.debugMode) {
+ console.log(`UIManager: ${message}`, data || "");
+ }
+ }
+
+ setPageType(pageType) {
+ this.pageType = pageType;
+ }
+
+ createButton(analysisResults = null) {
+ if (analysisResults) {
+ this.analysisResults = analysisResults;
+ }
+
+ if (!this.analysisResults) {
+ console.error('DIMA: Aucun résultat d\'analyse disponible pour créer le bouton');
+ return;
+ }
+ try {
+ // Supprimer bouton existant
+ document.getElementById('dima-btn')?.remove();
+
+ if (this.buttonCreated) return;
+
+ const button = document.createElement('div');
+ button.id = 'dima-btn';
+
+ button.innerHTML = `
+
+ 🧠
+ ${this.analysisResults.globalScore}
+ ${this.analysisResults.riskLevel}
+
+ `;
+
+ button.style.cssText = `
+ position: fixed !important;
+ top: 20px !important;
+ right: 20px !important;
+ z-index: 999999 !important;
+ background: linear-gradient(135deg, ${this.analysisResults.riskColor}, ${this.adjustColor(this.analysisResults.riskColor, -20)}) !important;
+ color: white !important;
+ padding: 12px 16px !important;
+ border-radius: 25px !important;
+ cursor: pointer !important;
+ font-family: 'Segoe UI', Arial, sans-serif !important;
+ font-size: 14px !important;
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2), 0 2px 5px rgba(0,0,0,0.1) !important;
+ border: 2px solid rgba(255,255,255,0.2) !important;
+ user-select: none !important;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
+ backdrop-filter: blur(10px) !important;
+ `;
+
+ button.title = this.generateTooltip();
+
+ // Événements
+ button.addEventListener('click', () => this.showModal());
+ button.addEventListener('mouseenter', () => {
+ button.style.transform = 'scale(1.05) translateY(-2px)';
+ button.style.boxShadow = '0 6px 20px rgba(0,0,0,0.3), 0 4px 8px rgba(0,0,0,0.2)';
+ });
+ button.addEventListener('mouseleave', () => {
+ button.style.transform = 'scale(1) translateY(0)';
+ button.style.boxShadow = '0 4px 15px rgba(0,0,0,0.2), 0 2px 5px rgba(0,0,0,0.1)';
+ });
+
+ document.body?.appendChild(button);
+ this.buttonCreated = true;
+ this.log('Bouton créé avec succès');
+
+ } catch (error) {
+ console.error('DIMA: Erreur création bouton:', error);
+ }
+ }
+
+ adjustColor(color, amount) {
+ const num = parseInt(color.replace("#", ""), 16);
+ const amt = Math.round(2.55 * amount);
+ const R = (num >> 16) + amt;
+ const G = (num >> 8 & 0x00FF) + amt;
+ const B = (num & 0x0000FF) + amt;
+ return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
+ (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
+ (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
+ }
+
+ generateTooltip() {
+ const techniques = this.analysisResults.detectedTechniques.slice(0, 3);
+ return `DIMA Score: ${this.analysisResults.globalScore} (${this.analysisResults.riskLevel})
+${this.analysisResults.detectedTechniques.length} techniques détectées
+${techniques.map(t => `• ${t.nom}`).join('\n')}
+Contenu: ${this.analysisResults.contentLength} caractères`;
+ }
+
+ showModal() {
+ try {
+ this.log('Affichage du modal');
+
+ document.getElementById('dima-modal')?.remove();
+
+ const modal = document.createElement('div');
+ modal.id = 'dima-modal';
+
+ modal.style.cssText = `
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ width: 100% !important;
+ height: 100% !important;
+ background: rgba(0,0,0,0.75) !important;
+ backdrop-filter: blur(5px) !important;
+ z-index: 9999999 !important;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ font-family: 'Segoe UI', Arial, sans-serif !important;
+ animation: fadeIn 0.3s ease-out !important;
+ `;
+ // Récupérer l'URL du logo
+ const logoUrl = chrome.runtime.getURL('M82-logo-16.png');
+
+ modal.innerHTML = `
+
+
+
+
+
+

+
Analyse DIMA
+
+
+ Détection de techniques de manipulation cognitive par
+ M82 Project
+
+
+
+
+
+
+
${this.analysisResults.globalScore}
+
Score Global
+
+
+
${this.analysisResults.detectedTechniques.length}
+
Techniques
+
+
+
${this.analysisResults.riskLevel}
+
Niveau Risque
+
+
+
${this.analysisResults.contentLength}
+
Caractères
+
+
+
+
+
+
📄 Page analysée
+
${this.analysisResults.title}
+
${this.analysisResults.url}
+
+ Analysé le ${new Date(this.analysisResults.timestamp).toLocaleString('fr-FR')} •
+ ${this.analysisResults.analyzedText} caractères traités • Type: ${this.pageType}
+
+
+
+
+ ${this.analysisResults.detectedTechniques.length === 0 ? `
+
+
✅
+
Aucune manipulation détectée
+
Le contenu analysé semble exempt de techniques de manipulation cognitive manifestes
+
+ ` : `
+
+
⚠️ Techniques de manipulation détectées
+
+ ${this.analysisResults.detectedTechniques.slice(0, 8).map(technique => `
+
+
+
+
+ ${technique.phase === 'Detect' ? '👁️' : technique.phase === 'Informer' ? '📢' : technique.phase === 'Mémoriser' ? '🧠' : '⚡'} ${technique.index}: ${technique.nom}
+
+ ${technique.tactic ? `
↳ Tactique: ${technique.tactic}
` : ''}
+ ${technique.description ? `
${technique.description}
` : ''}
+
+
+ ${technique.confidence}%
+
+
+
+
+
+ ${technique.phase}
+
+
+
Score pondéré: ${technique.weightedScore?.toFixed(1) || technique.score}
+
+
+
+ ${technique.matchedKeywords?.length > 0 ? `
+
+
+ 🔍 Mots-clés détectés:
+
+
+ ${technique.matchedKeywords.slice(0, 4).map(keyword =>
+ `
+ ${keyword.keyword} ${(keyword.count > 1) ? `(×${keyword.count})` : ''}
+ `
+ ).join('')}
+ ${technique.matchedKeywords.length > 4 ?
+ `+${technique.matchedKeywords.length - 4} autres...`
+ : ''
+ }
+
+
+ ` : ''}
+
+ `).join('')}
+
+
+ `}
+
+
+
+
+
+
+
+
+
+
+
+ `;
+
+ modal.addEventListener('click', (e) => {
+ if (e.target === modal) modal.remove();
+ });
+
+ document.body.appendChild(modal);
+ this.log('Modal affiché');
+
+ } catch (error) {
+ console.error('DIMA: Erreur modal:', error);
+ }
+ }
+}
+// Make UIManager available globally for Chrome extension
+window.UIManager = UIManager;