197 lines
9.1 KiB
HTML
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>
|