Files
html/v83-dark-scout-enriched.html
opus 477ae48166
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
auto-sync via WEVIA git_sync_all intent 2026-04-20T04:29:18+02:00
2026-04-20 04:29:18 +02:00

197 lines
9.1 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>V83 Dark Scout Enriched — SearXNG Market Intel</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{--bg:#0a0e17;--bg2:#111827;--bg3:#1a2234;--bd:#1e293b;--wh:#f1f5f9;--mu:#64748b;--mu2:#94a3b8;--ac:#fbbf24;--cy:#22d3ee;--pk:#ec4899;--vi:#8b5cf6;--gn:#22c55e;--or:#f97316;--font:'Plus Jakarta Sans',sans-serif;--mono:'JetBrains Mono',monospace}
body{background:var(--bg);color:var(--wh);font-family:var(--font);padding:20px 32px;min-height:100vh}
a{color:var(--cy);text-decoration:none}a:hover{text-decoration:underline}
h1{font-size:22px;font-weight:800;margin-bottom:6px}h1 span{color:var(--ac)}
.sub{font-size:12px;color:var(--mu);margin-bottom:20px;font-family:var(--mono)}
.btns{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap}
.btn{padding:8px 16px;border:1px solid var(--bd);background:var(--bg2);color:var(--wh);border-radius:6px;font-size:12px;font-weight:600;text-decoration:none}
.btn:hover{border-color:var(--ac)}
.sec-title{font-size:14px;font-weight:700;margin:18px 0 10px;color:var(--ac);display:flex;align-items:center;gap:8px}
.sec-title::before{content:'';display:block;width:3px;height:14px;background:var(--ac);border-radius:2px}
.presets{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;margin-bottom:18px}
.preset{background:var(--bg2);border:1px solid var(--bd);border-radius:8px;padding:10px 14px;cursor:pointer;transition:.2s}
.preset:hover{border-color:var(--ac);transform:translateY(-1px)}
.preset.active{border-color:var(--ac);background:var(--bg3)}
.p-emoji{font-size:18px;margin-bottom:4px}
.p-name{font-family:var(--mono);font-weight:700;font-size:11px;margin-bottom:2px}
.p-query{font-size:10px;color:var(--mu);font-family:var(--mono)}
.search-box{display:flex;gap:8px;margin-bottom:16px}
.search-box input{flex:1;background:var(--bg2);border:1px solid var(--bd);color:var(--wh);border-radius:6px;padding:10px 14px;font-family:var(--mono);font-size:12px;outline:none}
.search-box input:focus{border-color:var(--ac)}
.btn-scan{background:linear-gradient(135deg,var(--ac),var(--or));color:#000;border:none;padding:10px 22px;border-radius:6px;font-weight:700;cursor:pointer;font-family:var(--font)}
.cats-filter{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px}
.cat-pill{padding:5px 12px;border-radius:20px;background:var(--bg3);border:1px solid var(--bd);color:var(--mu2);font-size:10px;font-weight:700;cursor:pointer;font-family:var(--mono)}
.cat-pill.active{background:var(--ac);color:#000;border-color:var(--ac)}
.cat-pill .cnt{margin-left:6px;opacity:.7}
.results{display:flex;flex-direction:column;gap:8px}
.result{background:var(--bg2);border:1px solid var(--bd);border-radius:8px;padding:12px 14px;cursor:pointer;transition:.2s}
.result:hover{border-color:var(--cy)}
.r-cat{display:inline-block;font-size:9px;padding:2px 8px;border-radius:10px;font-family:var(--mono);font-weight:700;margin-bottom:6px;text-transform:uppercase}
.r-cat.sap{background:rgba(236,72,153,.15);color:var(--pk)}
.r-cat.pharma{background:rgba(34,197,94,.15);color:var(--gn)}
.r-cat.ai{background:rgba(139,92,246,.15);color:var(--vi)}
.r-cat.lead{background:rgba(249,115,22,.15);color:var(--or)}
.r-cat.competitor{background:rgba(239,68,68,.15);color:#ef4444}
.r-cat.cloud{background:rgba(34,211,238,.15);color:var(--cy)}
.r-cat.vistex{background:rgba(251,191,36,.15);color:var(--ac)}
.r-cat.general{background:rgba(148,163,184,.15);color:var(--mu2)}
.r-title{font-weight:700;font-size:14px;margin-bottom:4px}
.r-url{font-family:var(--mono);color:var(--cy);font-size:10px;margin-bottom:4px;word-break:break-all}
.r-snippet{font-size:12px;color:var(--mu2);line-height:1.4}
.r-meta{display:flex;gap:10px;font-size:10px;color:var(--mu);margin-top:6px;font-family:var(--mono)}
.loading{text-align:center;padding:30px;color:var(--mu)}
.stats{display:flex;gap:16px;flex-wrap:wrap;margin-bottom:14px;font-size:11px;color:var(--mu);font-family:var(--mono)}
.stats b{color:var(--wh);font-size:14px}
</style>
</head>
<body>
<h1><span>V83</span> Dark Scout — SearXNG Market Intel <span style="font-size:12px;color:var(--gn);background:rgba(34,197,94,.15);padding:3px 9px;border-radius:4px;font-family:var(--mono);margin-left:8px">LIVE</span></h1>
<div class="sub">Enriched · 9 presets · multi-engine · classification auto · intel history 50 queries · doctrine 4 honest</div>
<div class="btns">
<a class="btn" href="/weval-technology-platform.html">← WTP</a>
<a class="btn" href="/growth-engine-v2.html">🚀 Growth Engine</a>
<a class="btn" href="/v82-unified-status.html">📊 V82 Status</a>
<a class="btn" href="/api/v83-dark-scout-enriched.php" target="_blank">🔧 JSON</a>
</div>
<div class="sec-title">🎯 Presets rapides (1-click)</div>
<div class="presets" id="presets"></div>
<div class="sec-title">🔍 Recherche custom</div>
<div class="search-box">
<input type="text" id="q" placeholder="ex: consulting SAP Maroc Casablanca, pharma digital MENA..." value="consulting SAP Maroc">
<button class="btn-scan" onclick="scan()">🔎 Scan</button>
</div>
<div class="stats" id="stats"></div>
<div class="sec-title">📊 Catégories (filter)</div>
<div class="cats-filter" id="cats-filter"></div>
<div class="sec-title">📋 Résultats</div>
<div class="results" id="results"><div class="loading">Clique un preset ou tape une requête pour scanner...</div></div>
<script>
const PRESETS_EMOJI = {
sap_maroc: '🏭',
pharma_intel: '💊',
erp_migration: '🔄',
devops_jobs: '👨‍💻',
ai_consulting: '🤖',
vistex_deals: '📋',
huawei_cloud: '☁️',
abbott_pharma: '🧬',
competitor_moroc: '🏢',
};
let PRESETS = {};
let ALL_RESULTS = [];
let ACTIVE_CAT = 'all';
async function loadPresets() {
const r = await fetch('/api/v83-dark-scout-enriched.php?preset=x').catch(()=>null);
// Just get preset list
const tmp = await fetch('/api/v83-dark-scout-enriched.php').then(r=>r.json()).catch(()=>({}));
PRESETS = tmp.presets_available || {};
const el = document.getElementById('presets');
el.innerHTML = Object.entries(PRESETS).map(([k,v]) => `
<div class="preset" onclick="scanPreset('${k}')">
<div class="p-emoji">${PRESETS_EMOJI[k]||'🔍'}</div>
<div class="p-name">${k.replace(/_/g,' ')}</div>
<div class="p-query">${v.slice(0,40)}...</div>
</div>
`).join('');
}
async function scanPreset(p) {
document.querySelectorAll('.preset').forEach(x => x.classList.remove('active'));
event?.currentTarget?.classList.add('active');
document.getElementById('q').value = PRESETS[p] || '';
await doScan('preset=' + encodeURIComponent(p));
}
async function scan() {
const q = document.getElementById('q').value.trim();
if (!q) return;
await doScan('q=' + encodeURIComponent(q));
}
async function doScan(params) {
document.getElementById('results').innerHTML = '<div class="loading">🔎 SearXNG en cours...</div>';
try {
const r = await fetch('/api/v83-dark-scout-enriched.php?' + params);
const d = await r.json();
ALL_RESULTS = d.results || [];
// Stats
document.getElementById('stats').innerHTML = `
<div>query: <b>${d.query}</b></div>
<div>results: <b>${d.count}</b></div>
<div>engines: <b>${d.engines}</b></div>
<div>intel history: <b>${d.intel_history_count}</b></div>
`;
// Categories
const cats = d.categories || {};
document.getElementById('cats-filter').innerHTML =
`<div class="cat-pill active" onclick="filterCat('all')">All <span class="cnt">${d.count}</span></div>` +
Object.entries(cats).map(([k,v]) =>
`<div class="cat-pill" onclick="filterCat('${k}')">${k} <span class="cnt">${v}</span></div>`
).join('');
renderResults();
} catch(e) {
document.getElementById('results').innerHTML = `<div class="loading" style="color:#ef4444">Error: ${e.message}</div>`;
}
}
function filterCat(c) {
ACTIVE_CAT = c;
document.querySelectorAll('.cat-pill').forEach(p => p.classList.remove('active'));
event?.currentTarget?.classList.add('active');
renderResults();
}
function renderResults() {
const filtered = ACTIVE_CAT === 'all' ? ALL_RESULTS : ALL_RESULTS.filter(r => r.category === ACTIVE_CAT);
const el = document.getElementById('results');
if (!filtered.length) {
el.innerHTML = '<div class="loading">Aucun résultat pour cette catégorie</div>';
return;
}
el.innerHTML = filtered.map(r => `
<div class="result" onclick="window.open('${r.url}','_blank')">
<span class="r-cat ${r.category}">${r.category}</span>
<div class="r-title">${r.title || '—'}</div>
<div class="r-url">${r.url || ''}</div>
<div class="r-snippet">${r.snippet || ''}</div>
<div class="r-meta">
<span>engine: ${r.engine || '?'}</span>
<span>score: ${r.score?.toFixed?.(3) || '—'}</span>
</div>
</div>
`).join('');
}
document.getElementById('q').addEventListener('keydown', e => { if (e.key === 'Enter') scan(); });
loadPresets();
</script>
</body>
</html>