D Ф m i И i q ц e L Ф y e r commited on
Commit ·
3d19c67
1
Parent(s): 78b2787
Feature: Explainability dashboard + Google Fact Check API
Browse files- syscred/.env +15 -0
- syscred/static/index.html +363 -2
syscred/.env
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SysCRED Environment Configuration
|
| 2 |
+
# (c) Dominique S. Loyer
|
| 3 |
+
|
| 4 |
+
# === Google Fact Check API ===
|
| 5 |
+
SYSCRED_GOOGLE_API_KEY=AIzaSyBiuY4AxuPgHcrViQJQ6BcKs1wOIqsiz74
|
| 6 |
+
|
| 7 |
+
# === Server Configuration ===
|
| 8 |
+
SYSCRED_PORT=5001
|
| 9 |
+
SYSCRED_HOST=127.0.0.1
|
| 10 |
+
|
| 11 |
+
# === Environment Mode ===
|
| 12 |
+
SYSCRED_ENV=development
|
| 13 |
+
|
| 14 |
+
# === ML Models ===
|
| 15 |
+
SYSCRED_LOAD_ML_MODELS=true
|
syscred/static/index.html
CHANGED
|
@@ -396,6 +396,143 @@
|
|
| 396 |
}
|
| 397 |
.backend-status.local { color: #22c55e; }
|
| 398 |
.backend-status.remote { color: #a855f7; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 399 |
</style>
|
| 400 |
</head>
|
| 401 |
|
|
@@ -436,9 +573,10 @@
|
|
| 436 |
|
| 437 |
<div class="results" id="results">
|
| 438 |
<div class="score-card">
|
| 439 |
-
<div class="score-label">Score de
|
| 440 |
-
<div class="score-value" id="scoreValue">0.00</div>
|
| 441 |
<div class="credibility-badge" id="credibilityBadge">-</div>
|
|
|
|
| 442 |
</div>
|
| 443 |
|
| 444 |
<div class="summary-box">
|
|
@@ -459,6 +597,19 @@
|
|
| 459 |
</div>
|
| 460 |
</div>
|
| 461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
<footer>
|
| 463 |
<p>SysCRED v2.0 - Prototype de recherche doctorale</p>
|
| 464 |
<p>© Dominique S. Loyer - UQAM | <a href="https://doi.org/10.5281/zenodo.17943226" target="_blank">DOI:
|
|
@@ -943,6 +1094,216 @@
|
|
| 943 |
analyzeUrl();
|
| 944 |
}
|
| 945 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 946 |
</script>
|
| 947 |
</body>
|
| 948 |
|
|
|
|
| 396 |
}
|
| 397 |
.backend-status.local { color: #22c55e; }
|
| 398 |
.backend-status.remote { color: #a855f7; }
|
| 399 |
+
|
| 400 |
+
/* === EXPLAINABILITY MODAL === */
|
| 401 |
+
.explainer-modal {
|
| 402 |
+
position: fixed;
|
| 403 |
+
top: 0;
|
| 404 |
+
left: 0;
|
| 405 |
+
width: 100%;
|
| 406 |
+
height: 100%;
|
| 407 |
+
background: rgba(0, 0, 0, 0.8);
|
| 408 |
+
backdrop-filter: blur(10px);
|
| 409 |
+
display: none;
|
| 410 |
+
justify-content: center;
|
| 411 |
+
align-items: center;
|
| 412 |
+
z-index: 1000;
|
| 413 |
+
}
|
| 414 |
+
.explainer-modal.visible { display: flex; }
|
| 415 |
+
.explainer-content {
|
| 416 |
+
background: linear-gradient(135deg, #1a1a3e 0%, #0f0f23 100%);
|
| 417 |
+
border: 1px solid rgba(124, 58, 237, 0.5);
|
| 418 |
+
border-radius: 20px;
|
| 419 |
+
max-width: 600px;
|
| 420 |
+
width: 90%;
|
| 421 |
+
max-height: 80vh;
|
| 422 |
+
overflow-y: auto;
|
| 423 |
+
padding: 2rem;
|
| 424 |
+
animation: slideUp 0.3s ease;
|
| 425 |
+
}
|
| 426 |
+
@keyframes slideUp {
|
| 427 |
+
from { transform: translateY(50px); opacity: 0; }
|
| 428 |
+
to { transform: translateY(0); opacity: 1; }
|
| 429 |
+
}
|
| 430 |
+
.explainer-header {
|
| 431 |
+
display: flex;
|
| 432 |
+
justify-content: space-between;
|
| 433 |
+
align-items: center;
|
| 434 |
+
margin-bottom: 1.5rem;
|
| 435 |
+
border-bottom: 1px solid rgba(255,255,255,0.1);
|
| 436 |
+
padding-bottom: 1rem;
|
| 437 |
+
}
|
| 438 |
+
.explainer-title {
|
| 439 |
+
font-size: 1.5rem;
|
| 440 |
+
font-weight: 700;
|
| 441 |
+
color: #fff;
|
| 442 |
+
}
|
| 443 |
+
.explainer-close {
|
| 444 |
+
background: none;
|
| 445 |
+
border: none;
|
| 446 |
+
color: #8b8ba7;
|
| 447 |
+
font-size: 2rem;
|
| 448 |
+
cursor: pointer;
|
| 449 |
+
padding: 0;
|
| 450 |
+
line-height: 1;
|
| 451 |
+
}
|
| 452 |
+
.explainer-close:hover { color: #fff; transform: none; box-shadow: none; }
|
| 453 |
+
.metric-explain {
|
| 454 |
+
background: rgba(255,255,255,0.03);
|
| 455 |
+
border-radius: 12px;
|
| 456 |
+
padding: 1.25rem;
|
| 457 |
+
margin-bottom: 1rem;
|
| 458 |
+
border-left: 4px solid #7c3aed;
|
| 459 |
+
}
|
| 460 |
+
.metric-explain-header {
|
| 461 |
+
display: flex;
|
| 462 |
+
align-items: center;
|
| 463 |
+
gap: 0.75rem;
|
| 464 |
+
margin-bottom: 0.75rem;
|
| 465 |
+
}
|
| 466 |
+
.metric-explain-icon {
|
| 467 |
+
font-size: 1.5rem;
|
| 468 |
+
}
|
| 469 |
+
.metric-explain-name {
|
| 470 |
+
font-weight: 600;
|
| 471 |
+
color: #fff;
|
| 472 |
+
font-size: 1.1rem;
|
| 473 |
+
}
|
| 474 |
+
.metric-explain-value {
|
| 475 |
+
background: rgba(124, 58, 237, 0.2);
|
| 476 |
+
padding: 0.25rem 0.5rem;
|
| 477 |
+
border-radius: 6px;
|
| 478 |
+
font-weight: 700;
|
| 479 |
+
color: #a855f7;
|
| 480 |
+
margin-left: auto;
|
| 481 |
+
}
|
| 482 |
+
.metric-explain-simple {
|
| 483 |
+
color: #e0e0e0;
|
| 484 |
+
font-size: 1rem;
|
| 485 |
+
line-height: 1.6;
|
| 486 |
+
margin-bottom: 0.5rem;
|
| 487 |
+
}
|
| 488 |
+
.metric-explain-detail {
|
| 489 |
+
color: #8b8ba7;
|
| 490 |
+
font-size: 0.85rem;
|
| 491 |
+
font-style: italic;
|
| 492 |
+
}
|
| 493 |
+
.score-clickable {
|
| 494 |
+
cursor: pointer;
|
| 495 |
+
transition: transform 0.2s ease;
|
| 496 |
+
}
|
| 497 |
+
.score-clickable:hover {
|
| 498 |
+
transform: scale(1.05);
|
| 499 |
+
}
|
| 500 |
+
.help-icon {
|
| 501 |
+
display: inline-block;
|
| 502 |
+
width: 18px;
|
| 503 |
+
height: 18px;
|
| 504 |
+
background: rgba(124, 58, 237, 0.3);
|
| 505 |
+
border-radius: 50%;
|
| 506 |
+
text-align: center;
|
| 507 |
+
line-height: 18px;
|
| 508 |
+
font-size: 12px;
|
| 509 |
+
color: #a855f7;
|
| 510 |
+
cursor: pointer;
|
| 511 |
+
margin-left: 0.5rem;
|
| 512 |
+
vertical-align: middle;
|
| 513 |
+
}
|
| 514 |
+
.help-icon:hover {
|
| 515 |
+
background: rgba(124, 58, 237, 0.6);
|
| 516 |
+
color: #fff;
|
| 517 |
+
}
|
| 518 |
+
.verdict-bar {
|
| 519 |
+
height: 8px;
|
| 520 |
+
background: rgba(255,255,255,0.1);
|
| 521 |
+
border-radius: 4px;
|
| 522 |
+
overflow: hidden;
|
| 523 |
+
margin: 0.5rem 0;
|
| 524 |
+
}
|
| 525 |
+
.verdict-fill {
|
| 526 |
+
height: 100%;
|
| 527 |
+
border-radius: 4px;
|
| 528 |
+
transition: width 0.5s ease;
|
| 529 |
+
}
|
| 530 |
+
.verdict-labels {
|
| 531 |
+
display: flex;
|
| 532 |
+
justify-content: space-between;
|
| 533 |
+
font-size: 0.75rem;
|
| 534 |
+
color: #6b6b8a;
|
| 535 |
+
}
|
| 536 |
</style>
|
| 537 |
</head>
|
| 538 |
|
|
|
|
| 573 |
|
| 574 |
<div class="results" id="results">
|
| 575 |
<div class="score-card">
|
| 576 |
+
<div class="score-label">Score de Crédibilité <span class="help-icon" onclick="event.stopPropagation(); openExplainer()">?</span></div>
|
| 577 |
+
<div class="score-value score-clickable" id="scoreValue" onclick="openExplainer()" title="Cliquez pour comprendre ce score">0.00</div>
|
| 578 |
<div class="credibility-badge" id="credibilityBadge">-</div>
|
| 579 |
+
<small style="color: #6b6b8a; margin-top: 0.5rem; display: block;">👆 Cliquez sur le score pour comprendre</small>
|
| 580 |
</div>
|
| 581 |
|
| 582 |
<div class="summary-box">
|
|
|
|
| 597 |
</div>
|
| 598 |
</div>
|
| 599 |
|
| 600 |
+
<!-- EXPLAINER MODAL -->
|
| 601 |
+
<div class="explainer-modal" id="explainerModal" onclick="if(event.target === this) closeExplainer()">
|
| 602 |
+
<div class="explainer-content">
|
| 603 |
+
<div class="explainer-header">
|
| 604 |
+
<div class="explainer-title">🔍 Comprendre votre score</div>
|
| 605 |
+
<button class="explainer-close" onclick="closeExplainer()">×</button>
|
| 606 |
+
</div>
|
| 607 |
+
<div id="explainerBody">
|
| 608 |
+
<!-- Content filled dynamically -->
|
| 609 |
+
</div>
|
| 610 |
+
</div>
|
| 611 |
+
</div>
|
| 612 |
+
|
| 613 |
<footer>
|
| 614 |
<p>SysCRED v2.0 - Prototype de recherche doctorale</p>
|
| 615 |
<p>© Dominique S. Loyer - UQAM | <a href="https://doi.org/10.5281/zenodo.17943226" target="_blank">DOI:
|
|
|
|
| 1094 |
analyzeUrl();
|
| 1095 |
}
|
| 1096 |
});
|
| 1097 |
+
|
| 1098 |
+
// === EXPLAINABILITY DASHBOARD ===
|
| 1099 |
+
let lastAnalysisData = null; // Store last analysis for explainer
|
| 1100 |
+
|
| 1101 |
+
// Store data after analysis
|
| 1102 |
+
const originalDisplayResults = displayResults;
|
| 1103 |
+
displayResults = function(data) {
|
| 1104 |
+
lastAnalysisData = data;
|
| 1105 |
+
originalDisplayResults(data);
|
| 1106 |
+
};
|
| 1107 |
+
|
| 1108 |
+
function openExplainer() {
|
| 1109 |
+
if (!lastAnalysisData) {
|
| 1110 |
+
alert('Analysez d\'abord une URL pour voir les explications.');
|
| 1111 |
+
return;
|
| 1112 |
+
}
|
| 1113 |
+
|
| 1114 |
+
const modal = document.getElementById('explainerModal');
|
| 1115 |
+
const body = document.getElementById('explainerBody');
|
| 1116 |
+
|
| 1117 |
+
const score = lastAnalysisData.scoreCredibilite || 0;
|
| 1118 |
+
const ruleResults = lastAnalysisData.reglesAppliquees || {};
|
| 1119 |
+
const nlpAnalysis = lastAnalysisData.analyseNLP || {};
|
| 1120 |
+
const sourceAnalysis = ruleResults.source_analysis || {};
|
| 1121 |
+
|
| 1122 |
+
// Determine verdict color and message
|
| 1123 |
+
let verdictColor, verdictText, verdictEmoji;
|
| 1124 |
+
if (score >= 0.7) {
|
| 1125 |
+
verdictColor = '#22c55e';
|
| 1126 |
+
verdictText = 'Vous pouvez faire confiance à cette source.';
|
| 1127 |
+
verdictEmoji = '✅';
|
| 1128 |
+
} else if (score >= 0.4) {
|
| 1129 |
+
verdictColor = '#eab308';
|
| 1130 |
+
verdictText = 'Soyez prudent, vérifiez avec d\'autres sources.';
|
| 1131 |
+
verdictEmoji = '⚠️';
|
| 1132 |
+
} else {
|
| 1133 |
+
verdictColor = '#ef4444';
|
| 1134 |
+
verdictText = 'Méfiez-vous, cette source semble peu fiable.';
|
| 1135 |
+
verdictEmoji = '❌';
|
| 1136 |
+
}
|
| 1137 |
+
|
| 1138 |
+
let html = `
|
| 1139 |
+
<!-- Score Global -->
|
| 1140 |
+
<div class="metric-explain" style="border-left-color: ${verdictColor}; background: rgba(${verdictColor === '#22c55e' ? '34,197,94' : verdictColor === '#eab308' ? '234,179,8' : '239,68,68'}, 0.1);">
|
| 1141 |
+
<div class="metric-explain-header">
|
| 1142 |
+
<span class="metric-explain-icon">${verdictEmoji}</span>
|
| 1143 |
+
<span class="metric-explain-name">Score Global</span>
|
| 1144 |
+
<span class="metric-explain-value" style="color: ${verdictColor}; font-size: 1.5rem;">${(score * 100).toFixed(0)}%</span>
|
| 1145 |
+
</div>
|
| 1146 |
+
<div class="metric-explain-simple">
|
| 1147 |
+
<strong>${verdictText}</strong><br><br>
|
| 1148 |
+
C'est comme une note à l'école :<br>
|
| 1149 |
+
• <span style="color:#22c55e">70-100%</span> = Excellent, source fiable<br>
|
| 1150 |
+
• <span style="color:#eab308">40-69%</span> = Moyen, à vérifier<br>
|
| 1151 |
+
• <span style="color:#ef4444">0-39%</span> = Faible, méfiance recommandée
|
| 1152 |
+
</div>
|
| 1153 |
+
<div class="verdict-bar">
|
| 1154 |
+
<div class="verdict-fill" style="width: ${score * 100}%; background: ${verdictColor};"></div>
|
| 1155 |
+
</div>
|
| 1156 |
+
<div class="verdict-labels">
|
| 1157 |
+
<span>⚠️ Pas fiable</span>
|
| 1158 |
+
<span>✅ Très fiable</span>
|
| 1159 |
+
</div>
|
| 1160 |
+
</div>
|
| 1161 |
+
`;
|
| 1162 |
+
|
| 1163 |
+
// Reputation
|
| 1164 |
+
if (sourceAnalysis.reputation) {
|
| 1165 |
+
const rep = sourceAnalysis.reputation;
|
| 1166 |
+
const repEmoji = rep === 'High' ? '🏆' : rep === 'Medium' ? '👍' : rep === 'Low' ? '⚠️' : '❓';
|
| 1167 |
+
const repText = rep === 'High' ? 'Source reconnue et respectée (ex: Le Monde, BBC)'
|
| 1168 |
+
: rep === 'Medium' ? 'Source correcte mais à vérifier'
|
| 1169 |
+
: rep === 'Low' ? 'Source peu fiable ou inconnue'
|
| 1170 |
+
: 'Nous ne connaissons pas cette source';
|
| 1171 |
+
|
| 1172 |
+
html += `
|
| 1173 |
+
<div class="metric-explain">
|
| 1174 |
+
<div class="metric-explain-header">
|
| 1175 |
+
<span class="metric-explain-icon">${repEmoji}</span>
|
| 1176 |
+
<span class="metric-explain-name">Réputation de la Source</span>
|
| 1177 |
+
<span class="metric-explain-value">${rep}</span>
|
| 1178 |
+
</div>
|
| 1179 |
+
<div class="metric-explain-simple">
|
| 1180 |
+
${repText}
|
| 1181 |
+
</div>
|
| 1182 |
+
<div class="metric-explain-detail">
|
| 1183 |
+
Nous comparons le site à une base de données de médias connus et vérifions s'il est cité par des journalistes.
|
| 1184 |
+
</div>
|
| 1185 |
+
</div>
|
| 1186 |
+
`;
|
| 1187 |
+
}
|
| 1188 |
+
|
| 1189 |
+
// Coherence
|
| 1190 |
+
if (nlpAnalysis.coherence_score !== undefined) {
|
| 1191 |
+
const coh = nlpAnalysis.coherence_score;
|
| 1192 |
+
const cohPercent = (coh * 100).toFixed(0);
|
| 1193 |
+
const cohEmoji = coh >= 0.6 ? '📝' : coh >= 0.4 ? '📄' : '❓';
|
| 1194 |
+
|
| 1195 |
+
html += `
|
| 1196 |
+
<div class="metric-explain">
|
| 1197 |
+
<div class="metric-explain-header">
|
| 1198 |
+
<span class="metric-explain-icon">${cohEmoji}</span>
|
| 1199 |
+
<span class="metric-explain-name">Cohérence du Texte</span>
|
| 1200 |
+
<span class="metric-explain-value">${cohPercent}%</span>
|
| 1201 |
+
</div>
|
| 1202 |
+
<div class="metric-explain-simple">
|
| 1203 |
+
Le texte est-il logique et bien écrit ?<br>
|
| 1204 |
+
Un texte bien structuré avec des phrases claires est généralement plus fiable.
|
| 1205 |
+
</div>
|
| 1206 |
+
<div class="metric-explain-detail">
|
| 1207 |
+
Notre intelligence artificielle analyse si les phrases sont cohérentes entre elles et si le texte suit une logique.
|
| 1208 |
+
</div>
|
| 1209 |
+
</div>
|
| 1210 |
+
`;
|
| 1211 |
+
}
|
| 1212 |
+
|
| 1213 |
+
// PageRank
|
| 1214 |
+
if (lastAnalysisData.pageRankEstimation && lastAnalysisData.pageRankEstimation.estimatedPR) {
|
| 1215 |
+
const pr = lastAnalysisData.pageRankEstimation.estimatedPR;
|
| 1216 |
+
const prEmoji = pr >= 0.4 ? '🌟' : pr >= 0.2 ? '⭐' : '💫';
|
| 1217 |
+
|
| 1218 |
+
html += `
|
| 1219 |
+
<div class="metric-explain">
|
| 1220 |
+
<div class="metric-explain-header">
|
| 1221 |
+
<span class="metric-explain-icon">${prEmoji}</span>
|
| 1222 |
+
<span class="metric-explain-name">PageRank (Popularité)</span>
|
| 1223 |
+
<span class="metric-explain-value">${pr.toFixed(3)}</span>
|
| 1224 |
+
</div>
|
| 1225 |
+
<div class="metric-explain-simple">
|
| 1226 |
+
Plus un site est populaire et cité par d'autres sites importants, plus il est probablement fiable.<br>
|
| 1227 |
+
C'est comme le bouche-à-oreille : si beaucoup de gens recommandent quelqu'un, c'est bon signe.
|
| 1228 |
+
</div>
|
| 1229 |
+
<div class="metric-explain-detail">
|
| 1230 |
+
Nous estimons combien de sites importants font des liens vers cette page (algorithme inspiré de Google).
|
| 1231 |
+
</div>
|
| 1232 |
+
</div>
|
| 1233 |
+
`;
|
| 1234 |
+
}
|
| 1235 |
+
|
| 1236 |
+
// SEO
|
| 1237 |
+
if (lastAnalysisData.seoAnalysis && lastAnalysisData.seoAnalysis.seoScore) {
|
| 1238 |
+
const seo = parseFloat(lastAnalysisData.seoAnalysis.seoScore);
|
| 1239 |
+
const seoEmoji = seo >= 0.7 ? '🔧' : seo >= 0.5 ? '🛠️' : '⚙️';
|
| 1240 |
+
|
| 1241 |
+
html += `
|
| 1242 |
+
<div class="metric-explain">
|
| 1243 |
+
<div class="metric-explain-header">
|
| 1244 |
+
<span class="metric-explain-icon">${seoEmoji}</span>
|
| 1245 |
+
<span class="metric-explain-name">Qualité Technique (SEO)</span>
|
| 1246 |
+
<span class="metric-explain-value">${seo.toFixed(2)}</span>
|
| 1247 |
+
</div>
|
| 1248 |
+
<div class="metric-explain-simple">
|
| 1249 |
+
Le site est-il bien construit ?<br>
|
| 1250 |
+
Un site professionnel bien structuré inspire plus confiance qu'un site mal fait.
|
| 1251 |
+
</div>
|
| 1252 |
+
<div class="metric-explain-detail">
|
| 1253 |
+
Nous vérifions si le site a un titre, une description, des balises correctes, etc.
|
| 1254 |
+
</div>
|
| 1255 |
+
</div>
|
| 1256 |
+
`;
|
| 1257 |
+
}
|
| 1258 |
+
|
| 1259 |
+
// Fact-Checks
|
| 1260 |
+
const factChecks = ruleResults.fact_checking || [];
|
| 1261 |
+
html += `
|
| 1262 |
+
<div class="metric-explain" style="border-left-color: #f472b6;">
|
| 1263 |
+
<div class="metric-explain-header">
|
| 1264 |
+
<span class="metric-explain-icon">🕵️</span>
|
| 1265 |
+
<span class="metric-explain-name">Vérification des Faits</span>
|
| 1266 |
+
<span class="metric-explain-value">${factChecks.length} trouvé(s)</span>
|
| 1267 |
+
</div>
|
| 1268 |
+
<div class="metric-explain-simple">
|
| 1269 |
+
Nous cherchons si des fact-checkers professionnels ont déjà vérifié des informations similaires.<br>
|
| 1270 |
+
${factChecks.length > 0
|
| 1271 |
+
? '✅ Des vérifications existent - consultez-les !'
|
| 1272 |
+
: 'Aucune vérification trouvée - cela ne veut pas dire que c\'est faux.'}
|
| 1273 |
+
</div>
|
| 1274 |
+
<div class="metric-explain-detail">
|
| 1275 |
+
Source : Google Fact Check Tools API - vérifie auprès de PolitiFact, Snopes, AFP, etc.
|
| 1276 |
+
</div>
|
| 1277 |
+
</div>
|
| 1278 |
+
`;
|
| 1279 |
+
|
| 1280 |
+
// How it's calculated
|
| 1281 |
+
html += `
|
| 1282 |
+
<div style="margin-top: 1.5rem; padding: 1rem; background: rgba(124, 58, 237, 0.1); border-radius: 12px; border: 1px dashed rgba(124, 58, 237, 0.3);">
|
| 1283 |
+
<strong style="color: #a855f7;">📊 Comment le score est calculé ?</strong>
|
| 1284 |
+
<p style="margin-top: 0.5rem; color: #8b8ba7; font-size: 0.9rem;">
|
| 1285 |
+
Le score combine plusieurs facteurs :<br>
|
| 1286 |
+
• Réputation de la source (22%)<br>
|
| 1287 |
+
• Cohérence du texte (12%)<br>
|
| 1288 |
+
• Qualité technique (15%)<br>
|
| 1289 |
+
• Vérifications de faits (17%)<br>
|
| 1290 |
+
• Âge du domaine et autres (34%)
|
| 1291 |
+
</p>
|
| 1292 |
+
</div>
|
| 1293 |
+
`;
|
| 1294 |
+
|
| 1295 |
+
body.innerHTML = html;
|
| 1296 |
+
modal.classList.add('visible');
|
| 1297 |
+
}
|
| 1298 |
+
|
| 1299 |
+
function closeExplainer() {
|
| 1300 |
+
document.getElementById('explainerModal').classList.remove('visible');
|
| 1301 |
+
}
|
| 1302 |
+
|
| 1303 |
+
// Close modal with Escape key
|
| 1304 |
+
document.addEventListener('keydown', function(e) {
|
| 1305 |
+
if (e.key === 'Escape') closeExplainer();
|
| 1306 |
+
});
|
| 1307 |
</script>
|
| 1308 |
</body>
|
| 1309 |
|