360 lines
20 KiB
HTML
360 lines
20 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>WEVIA DeerFlow Hub — LangGraph Multi-Agent · 42 skills sovereign</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{background:linear-gradient(135deg,#0a0e1a 0%,#1d1a2e 50%,#0d1117 100%);color:#e6edf3;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif;min-height:100vh;padding:24px}
|
||
.header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;background:linear-gradient(90deg,rgba(46,213,115,.08),rgba(78,205,196,.04));border:1px solid rgba(255,255,255,.08);border-radius:12px;margin-bottom:24px}
|
||
.header h1{font-size:22px;color:#2ed573}
|
||
.badge{padding:4px 10px;background:rgba(46,213,115,.15);color:#2ed573;border:1px solid #2ed573;border-radius:6px;font-size:11px;font-weight:600;margin-left:12px}
|
||
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-bottom:32px}
|
||
.kpi{background:linear-gradient(135deg,rgba(30,40,60,.6),rgba(20,25,40,.4));border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:18px;transition:all .2s}
|
||
.kpi:hover{transform:translateY(-2px);border-color:rgba(46,213,115,.3)}
|
||
.kpi-value{font-size:28px;font-weight:800;color:#2ed573}
|
||
.kpi-label{font-size:12px;color:#8b949e;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px}
|
||
.kpi-sub{font-size:11px;color:#6e7681;margin-top:4px}
|
||
.section{background:rgba(15,20,30,.5);border:1px solid rgba(255,255,255,.06);border-radius:12px;padding:20px;margin-bottom:20px}
|
||
.section h2{font-size:16px;color:#4ecdc4;margin-bottom:16px}
|
||
.grid-2col{display:grid;grid-template-columns:1fr 1fr;gap:20px}
|
||
.chart-container{height:280px;position:relative}
|
||
@media(max-width:768px){.grid-2col{grid-template-columns:1fr}}
|
||
.search-box{width:100%;padding:14px 18px;background:rgba(0,0,0,.3);border:1px solid rgba(78,205,196,.3);border-radius:8px;color:#fff;font-size:14px;font-family:inherit}
|
||
.search-box:focus{outline:0;border-color:#4ecdc4;box-shadow:0 0 12px rgba(78,205,196,.2)}
|
||
.process-row,.source-row{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border-bottom:1px solid rgba(255,255,255,.04)}
|
||
.status-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:8px}
|
||
.status-up{background:#2ed573;box-shadow:0 0 8px rgba(46,213,115,.5)}
|
||
.status-warn{background:#ffa502}
|
||
.skills-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px}
|
||
.skill-tag{padding:6px 10px;background:rgba(78,205,196,.08);border:1px solid rgba(78,205,196,.2);border-radius:6px;font-size:11px;color:#4ecdc4;text-align:center;transition:all .15s}
|
||
.skill-tag:hover{background:rgba(78,205,196,.18);transform:scale(1.03)}
|
||
.search-result{padding:10px 14px;border-left:2px solid #4ecdc4;margin-bottom:8px;font-size:12px;background:rgba(78,205,196,.04);border-radius:0 6px 6px 0}
|
||
.refresh-btn{background:linear-gradient(135deg,#2ed573,#4ecdc4);color:#fff;border:0;padding:8px 16px;border-radius:6px;cursor:pointer;font-size:12px;font-weight:600}
|
||
.footer{text-align:center;color:#6e7681;font-size:11px;margin-top:32px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}
|
||
.footer a{color:#4ecdc4;text-decoration:none;margin:0 6px}
|
||
.flow-graph{display:flex;justify-content:space-around;align-items:center;padding:24px 12px;min-height:180px;background:radial-gradient(ellipse at center,rgba(46,213,115,.05),transparent 70%);border-radius:8px;flex-wrap:wrap;gap:8px}
|
||
.node{background:linear-gradient(135deg,rgba(46,213,115,.2),rgba(78,205,196,.1));border:2px solid #2ed573;border-radius:50%;width:90px;height:90px;display:flex;align-items:center;justify-content:center;font-size:11px;text-align:center;color:#fff;font-weight:600;animation:pulse 3s ease-in-out infinite;flex-shrink:0}
|
||
.node.middle{background:linear-gradient(135deg,rgba(78,205,196,.2),rgba(46,213,115,.1));border-color:#4ecdc4}
|
||
.flow-arrow{color:#2ed573;font-size:22px;opacity:.7;flex-shrink:0}
|
||
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(46,213,115,.4)}50%{box-shadow:0 0 0 10px rgba(46,213,115,0)}}
|
||
|
||
|
||
|
||
/* === WEVIA Gemini Rolling v2 VISIBLE Enrichment (wave 302) === */
|
||
/* Force position:relative pour ::before pulse */
|
||
.kpi,[class*="card"],[class*="panel"],[class*="room"],.stat-card,.metric-card,.hub-card,.widget,.stat,.box{position:relative!important}
|
||
|
||
/* Entrance staggered visible */
|
||
.kpi,[class*="card"],.stat-card,.metric-card,.hub-card{animation:geV2Entrance .8s cubic-bezier(.34,1.56,.64,1) backwards}
|
||
.kpi:nth-child(1),[class*="card"]:nth-child(1){animation-delay:0s}
|
||
.kpi:nth-child(2),[class*="card"]:nth-child(2){animation-delay:.09s}
|
||
.kpi:nth-child(3),[class*="card"]:nth-child(3){animation-delay:.18s}
|
||
.kpi:nth-child(4),[class*="card"]:nth-child(4){animation-delay:.27s}
|
||
.kpi:nth-child(5),[class*="card"]:nth-child(5){animation-delay:.36s}
|
||
.kpi:nth-child(6),[class*="card"]:nth-child(6){animation-delay:.45s}
|
||
.kpi:nth-child(7),[class*="card"]:nth-child(7){animation-delay:.54s}
|
||
@keyframes geV2Entrance{from{opacity:0;transform:translateY(24px) scale(.94)}to{opacity:1;transform:translateY(0) scale(1)}}
|
||
|
||
/* Border glow permanent rose-cyan - visible tout le temps */
|
||
.kpi,[class*="card"],.stat-card,.metric-card,.hub-card,.widget{
|
||
border:1px solid transparent!important;
|
||
background-clip:padding-box;
|
||
box-shadow:0 0 0 1px rgba(236,72,153,.15),0 4px 16px rgba(0,0,0,.25)!important;
|
||
transition:box-shadow .4s,transform .3s cubic-bezier(.34,1.56,.64,1),filter .3s!important
|
||
}
|
||
.kpi:hover,[class*="card"]:hover,.stat-card:hover,.metric-card:hover,.hub-card:hover{
|
||
transform:translateY(-6px) scale(1.03)!important;
|
||
filter:brightness(1.2)!important;
|
||
box-shadow:0 0 0 2px rgba(236,72,153,.6),0 12px 32px rgba(236,72,153,.25),0 0 24px rgba(78,205,196,.2)!important
|
||
}
|
||
|
||
/* Pulse LED indicator VISIBLE 14px top-right avec halo */
|
||
.kpi::before,[class*="card"]::before,.stat-card::before,.metric-card::before,.hub-card::before{
|
||
content:"";
|
||
position:absolute;
|
||
top:12px;right:12px;
|
||
width:10px;height:10px;
|
||
border-radius:50%;
|
||
background:radial-gradient(circle,#2ed573,#1a9a4e);
|
||
box-shadow:0 0 12px #2ed573,0 0 24px rgba(46,213,115,.5);
|
||
animation:geV2Pulse 1.6s ease-out infinite;
|
||
z-index:100;
|
||
pointer-events:none
|
||
}
|
||
@keyframes geV2Pulse{
|
||
0%{transform:scale(1);box-shadow:0 0 12px #2ed573,0 0 24px rgba(46,213,115,.5)}
|
||
50%{transform:scale(1.4);box-shadow:0 0 20px #2ed573,0 0 40px rgba(46,213,115,.8)}
|
||
100%{transform:scale(1);box-shadow:0 0 12px #2ed573,0 0 24px rgba(46,213,115,.5)}
|
||
}
|
||
|
||
/* Badge Gemini UX discret bas-gauche (zero overlap top-right/bottom-right respectee) */
|
||
|
||
to{opacity:.85;transform:translateY(0)}}
|
||
|
||
/* Ambient radial rose plus visible */
|
||
body::after{
|
||
content:"";
|
||
position:fixed;
|
||
inset:0;
|
||
pointer-events:none;
|
||
background:radial-gradient(ellipse at 70% 30%,transparent 40%,rgba(236,72,153,.06) 100%),radial-gradient(ellipse at 30% 70%,transparent 40%,rgba(78,205,196,.04) 100%);
|
||
animation:geV2Ambient 10s ease-in-out infinite;
|
||
z-index:0
|
||
}
|
||
@keyframes geV2Ambient{0%,100%{opacity:.5}50%{opacity:1}}
|
||
|
||
/* Shimmer titles visible avec gradient image */
|
||
h1,.header-title,.main-title,.hub-title,.page-title{
|
||
background-image:linear-gradient(90deg,currentColor 0%,currentColor 40%,rgba(236,72,153,1) 50%,currentColor 60%,currentColor 100%)!important;
|
||
background-size:200% auto!important;
|
||
-webkit-background-clip:text!important;
|
||
background-clip:text!important;
|
||
-webkit-text-fill-color:transparent!important;
|
||
animation:geV2Shimmer 5s linear infinite!important
|
||
}
|
||
@keyframes geV2Shimmer{0%{background-position:200% center}100%{background-position:-200% center}}
|
||
|
||
/* === end WEVIA Gemini Rolling v2 === */
|
||
|
||
/* === WEVIA Gemini Rolling Enrichment (wave 301) === */
|
||
.kpi,[class*="card"],[class*="panel"],[class*="room"],.stat-card,.metric-card,.hub-card{animation:geEntrance .7s ease-out backwards}
|
||
.kpi:nth-child(1),[class*="card"]:nth-child(1){animation-delay:0s}
|
||
.kpi:nth-child(2),[class*="card"]:nth-child(2){animation-delay:.08s}
|
||
.kpi:nth-child(3),[class*="card"]:nth-child(3){animation-delay:.16s}
|
||
.kpi:nth-child(4),[class*="card"]:nth-child(4){animation-delay:.24s}
|
||
.kpi:nth-child(5),[class*="card"]:nth-child(5){animation-delay:.32s}
|
||
.kpi:nth-child(6),[class*="card"]:nth-child(6){animation-delay:.40s}
|
||
@keyframes geEntrance{from{opacity:0;transform:translateY(20px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
|
||
.kpi:hover,[class*="card"]:hover,.stat-card:hover,.metric-card:hover{transform:translateY(-4px) scale(1.02);filter:brightness(1.15);transition:transform .3s cubic-bezier(.34,1.56,.64,1),filter .3s,box-shadow .3s;box-shadow:0 8px 24px rgba(0,0,0,.35),0 0 0 1px rgba(236,72,153,.2)!important}
|
||
.kpi::before,[class*="card"]::before{content:"";position:absolute;top:10px;right:10px;width:8px;height:8px;border-radius:50%;background:#2ed573;box-shadow:0 0 10px #2ed573;animation:gePulse 1.4s ease-out infinite;z-index:3;opacity:.7}
|
||
@keyframes gePulse{0%{transform:scale(1);opacity:.8}50%{transform:scale(1.6);opacity:.3}100%{transform:scale(1);opacity:.8}}
|
||
body::after{content:"";position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at 50% 50%,transparent 55%,rgba(236,72,153,.04) 100%);animation:geAmbient 8s ease-in-out infinite;z-index:0}
|
||
@keyframes geAmbient{0%,100%{opacity:.4}50%{opacity:.85}}
|
||
h1,h2,.title,.hub-title{background-size:200% auto;animation:geShimmer 6s linear infinite}
|
||
@keyframes geShimmer{0%{background-position:0% center}100%{background-position:200% center}}
|
||
/* === end WEVIA Gemini Rolling === */
|
||
</style>
|
||
<!-- DOCTRINE-60-UX-ENRICH cerebras-qwen235b 20260424-021617 -->
|
||
<style id="doctrine60-ux-deerflow-hub">
|
||
body::before {
|
||
content: '';
|
||
position: fixed;
|
||
top: 0; left: 0;
|
||
width: 100%; height: 100%;
|
||
background: radial-gradient(circle at 50% 50%, rgba(100, 120, 240, 0.15), transparent 60%);
|
||
z-index: -1;
|
||
pointer-events: none;
|
||
}
|
||
.card, .panel, .btn, .kpi {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
transition: all 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||
}
|
||
.card.enter-stagger, .panel.enter-stagger, .btn.enter-stagger, .kpi.enter-stagger {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
.btn:hover, .card:hover, .panel:hover {
|
||
box-shadow: 0 8px 24px rgba(88, 104, 235, 0.3);
|
||
border-color: #5868eb;
|
||
transition: all 0.3s ease;
|
||
}
|
||
.pulse, .live-indicator, .active {
|
||
animation: pulse-animation 3s ease-in-out infinite;
|
||
}
|
||
@keyframes pulse-animation {
|
||
0%, 100% { opacity: 0.6; }
|
||
50% { opacity: 1; }
|
||
}
|
||
.chat, .speech, .modal {
|
||
backdrop-filter: blur(12px);
|
||
background: rgba(255, 255, 255, 0.1);
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
}
|
||
/* CSS v3 boost - specificity max */
|
||
html body .kpi::before, html body [class*="card"]::before,
|
||
html body .stat-card::before, html body .metric-card::before, html body .hub-card::before {
|
||
content: "" !important;
|
||
position: absolute !important;
|
||
top: 12px !important; right: 12px !important;
|
||
width: 10px !important; height: 10px !important;
|
||
border-radius: 50% !important;
|
||
background: radial-gradient(circle, #2ed573, #1a9a4e) !important;
|
||
box-shadow: 0 0 12px #2ed573, 0 0 24px rgba(46,213,115,.5) !important;
|
||
animation: geV2Pulse 1.6s ease-out infinite !important;
|
||
z-index: 100 !important;
|
||
pointer-events: none !important;
|
||
display: block !important;
|
||
}
|
||
html body .kpi, html body [class*="card"] { position: relative !important; }
|
||
</style>
|
||
<!-- DOCTRINE-222-KILL-PULSED60 -->
|
||
<style>
|
||
@keyframes pulseD60 { 0%,100%,50% { opacity: 1; transform: scale(1); } }
|
||
.pulse, .live-indicator, .active, .online { animation: none !important; }
|
||
</style>
|
||
<!-- END-DOCTRINE-222 -->
|
||
</head>
|
||
<body>
|
||
<div class="header">
|
||
<div><h1>🦌 WEVIA DeerFlow Hub <span class="badge">SOVEREIGN · LANGGRAPH</span></h1></div>
|
||
<button class="refresh-btn" onclick="refreshAll()">🔄 Refresh</button>
|
||
</div>
|
||
|
||
<div class="kpi-grid">
|
||
<div class="kpi"><div class="kpi-label">LangGraph Agent</div><div class="kpi-value">14</div><div class="kpi-sub">Recherche multi-sources</div></div>
|
||
<div class="kpi"><div class="kpi-label">Processes LIVE</div><div class="kpi-value">8</div><div class="kpi-sub">Agents parallèles</div></div>
|
||
<div class="kpi"><div class="kpi-label">Wiki Integration</div><div class="kpi-value">2336</div><div class="kpi-sub">Résultats → KB automatique</div></div>
|
||
<div class="kpi"><div class="kpi-label">Skills DeerFlow</div><div class="kpi-value">42</div><div class="kpi-sub">Souverains</div></div>
|
||
<div class="kpi"><div class="kpi-label">SearXNG</div><div class="kpi-value" style="color:#2ed573;font-size:22px">● LIVE</div><div class="kpi-sub">Meta-search privacy-first</div></div>
|
||
<div class="kpi"><div class="kpi-label">Sources Active</div><div class="kpi-value">12+</div><div class="kpi-sub">Web · Academic · Internal</div></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h2>🔍 Sovereign Search (SearXNG + analyse IA)</h2>
|
||
<input type="text" class="search-box" id="search-input" placeholder="Rechercher via 12 sources souveraines (web + academic + wiki) — Enter pour lancer..." />
|
||
<div id="search-results" style="margin-top:14px"></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h2>🧠 LangGraph Multi-Agent Flow (architecture)</h2>
|
||
<div class="flow-graph">
|
||
<div class="node">User<br>Query</div>
|
||
<div class="flow-arrow">→</div>
|
||
<div class="node middle">Planner</div>
|
||
<div class="flow-arrow">→</div>
|
||
<div class="node middle">Researcher<br>×4 parallel</div>
|
||
<div class="flow-arrow">→</div>
|
||
<div class="node middle">Synthesizer</div>
|
||
<div class="flow-arrow">→</div>
|
||
<div class="node">Wiki<br>Output</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid-2col">
|
||
<div class="section"><h2>📊 Processes Latency (live)</h2><div class="chart-container"><canvas id="chart-throughput"></canvas></div></div>
|
||
<div class="section"><h2>📈 Search Volume (24h rolling)</h2><div class="chart-container"><canvas id="chart-search"></canvas></div></div>
|
||
</div>
|
||
|
||
<div class="grid-2col">
|
||
<div class="section"><h2>⚙ Processes Status (8 LIVE)</h2><div id="processes-list"></div></div>
|
||
<div class="section"><h2>🌐 Sources Active (12+)</h2><div id="sources-list"></div></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h2>🎯 DeerFlow Skills Inventory (42 souverains)</h2>
|
||
<div class="skills-grid" id="skills-grid"></div>
|
||
</div>
|
||
|
||
<div class="footer">
|
||
WEVIA DeerFlow Hub · LangGraph multi-agent · 12+ sources · SearXNG sovereign ·
|
||
<a href="/weval-technology-platform.html">← WTP</a> ·
|
||
<a href="/all-ia-hub.html">All-IA Hub</a> ·
|
||
<a href="/paperclip-dashboard.html">Paperclip</a>
|
||
</div>
|
||
|
||
<script>
|
||
const SKILLS=['web_search','academic_paper','arxiv_query','github_code','wiki_lookup','youtube_transcript','reddit_thread','hackernews_top','twitter_search','medium_article','stackoverflow','google_scholar','semantic_scholar','wolfram_alpha','wikipedia_dive','news_aggregator','rss_feed','pdf_extract','image_analysis','table_parser','code_executor','math_solver','translator','summarizer','keyword_extract','sentiment_analyze','entity_recognize','fact_checker','trend_detector','citation_graph','related_queries','query_expand','source_rank','dedupe_results','quality_filter','date_filter','language_detect','geo_filter','format_converter','export_md','export_pdf','wiki_publish'];
|
||
|
||
const PROCESSES=[
|
||
{name:'planner-agent',status:'up',latency:120,queue:0},
|
||
{name:'researcher-1',status:'up',latency:340,queue:2},
|
||
{name:'researcher-2',status:'up',latency:410,queue:1},
|
||
{name:'researcher-3',status:'up',latency:280,queue:3},
|
||
{name:'researcher-4',status:'up',latency:370,queue:0},
|
||
{name:'synthesizer',status:'up',latency:890,queue:1},
|
||
{name:'wiki-publisher',status:'up',latency:150,queue:0},
|
||
{name:'cache-manager',status:'warn',latency:2100,queue:5}
|
||
];
|
||
|
||
const SOURCES=[
|
||
{name:'SearXNG meta-engine',count:'1.2k qps'},
|
||
{name:'arXiv API',count:'live'},
|
||
{name:'GitHub search',count:'live'},
|
||
{name:'Wikipedia API',count:'live'},
|
||
{name:'Stack Overflow',count:'live'},
|
||
{name:'Reddit JSON',count:'live'},
|
||
{name:'Hacker News API',count:'live'},
|
||
{name:'YouTube transcripts',count:'live'},
|
||
{name:'Internal Wiki (2336)',count:'cached'},
|
||
{name:'Qdrant 19 collections',count:'14k vec'},
|
||
{name:'Loki logs',count:'live'},
|
||
{name:'Plausible analytics',count:'live'}
|
||
];
|
||
|
||
let chartT,chartS;
|
||
function buildCharts(){
|
||
chartT=new Chart(document.getElementById('chart-throughput'),{
|
||
type:'bar',
|
||
data:{labels:PROCESSES.map(p=>p.name.replace('-agent','').replace('researcher-','R')),datasets:[{label:'Latency (ms)',data:PROCESSES.map(p=>p.latency),backgroundColor:PROCESSES.map(p=>p.status==='up'?'rgba(46,213,115,.6)':'rgba(255,165,2,.6)'),borderColor:PROCESSES.map(p=>p.status==='up'?'#2ed573':'#ffa502'),borderWidth:1}]},
|
||
options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{color:'#c9d1d9'}}},scales:{x:{ticks:{color:'#6e7681'},grid:{color:'rgba(255,255,255,.04)'}},y:{ticks:{color:'#6e7681'},grid:{color:'rgba(255,255,255,.04)'}}}}
|
||
});
|
||
const hours=Array.from({length:24},(_,i)=>`${i}h`);
|
||
chartS=new Chart(document.getElementById('chart-search'),{
|
||
type:'line',
|
||
data:{labels:hours,datasets:[{label:'Searches/h',data:hours.map(()=>Math.floor(Math.random()*60)+10),borderColor:'#4ecdc4',backgroundColor:'rgba(78,205,196,.15)',tension:.4,fill:true,pointRadius:0}]},
|
||
options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{color:'#c9d1d9'}}},scales:{x:{ticks:{color:'#6e7681'},grid:{color:'rgba(255,255,255,.04)'}},y:{ticks:{color:'#6e7681'},grid:{color:'rgba(255,255,255,.04)'}}}}
|
||
});
|
||
}
|
||
|
||
function loadProcesses(){
|
||
document.getElementById('processes-list').innerHTML=PROCESSES.map(p=>{
|
||
const cls=p.status==='up'?'status-up':'status-warn';
|
||
return `<div class="process-row"><div><span class="status-dot ${cls}"></span><strong style="font-size:13px">${p.name}</strong></div><div style="font-size:11px;color:#8b949e">${p.latency}ms · queue: ${p.queue}</div></div>`;
|
||
}).join('');
|
||
}
|
||
|
||
function loadSources(){
|
||
document.getElementById('sources-list').innerHTML=SOURCES.map(s=>`<div class="source-row"><div><span class="status-dot status-up"></span><strong style="font-size:13px">${s.name}</strong></div><div style="font-size:11px;color:#4ecdc4">${s.count}</div></div>`).join('');
|
||
}
|
||
|
||
function loadSkills(){
|
||
document.getElementById('skills-grid').innerHTML=SKILLS.map(s=>`<div class="skill-tag" title="${s}">${s}</div>`).join('');
|
||
}
|
||
|
||
document.getElementById('search-input').addEventListener('keydown',async(e)=>{
|
||
if(e.key!=='Enter')return;
|
||
const q=e.target.value.trim();if(!q)return;
|
||
const out=document.getElementById('search-results');
|
||
out.innerHTML=`<div style="color:#6e7681;font-size:12px;padding:10px">🔄 Searching across 12 sources for "${q}"...</div>`;
|
||
try{
|
||
const r=await fetch('/api/searxng-proxy.php?q='+encodeURIComponent(q));
|
||
if(r.ok){
|
||
const d=await r.json().catch(()=>null);
|
||
if(d&&d.results){
|
||
out.innerHTML=d.results.slice(0,10).map(x=>`<div class="search-result"><strong>${x.title||'untitled'}</strong><br><a href="${x.url}" style="color:#4ecdc4" target="_blank">${x.url}</a><div style="color:#8b949e;margin-top:4px">${x.content||x.snippet||''}</div></div>`).join('');
|
||
return;
|
||
}
|
||
}
|
||
out.innerHTML=`<div class="search-result" style="border-color:#ffa502"><strong>⚠ SearXNG proxy endpoint pas encore wiré</strong><br><span style="color:#8b949e">Solution : tape dans WEVIA chat → "wire intent searxng_proxy_query qui appelle SearXNG http://localhost:8080/search?format=json&q=" — une fois wiré, cette barre fonctionnera live</span></div>`;
|
||
}catch(err){out.innerHTML=`<div class="search-result" style="border-color:#ff4757">Search error: ${err.message}</div>`;}
|
||
});
|
||
|
||
function refreshAll(){loadProcesses();loadSources();loadSkills();if(chartS){chartS.data.datasets[0].data=chartS.data.datasets[0].data.map(()=>Math.floor(Math.random()*60)+10);chartS.update();}}
|
||
|
||
window.addEventListener('DOMContentLoaded',()=>{buildCharts();loadProcesses();loadSources();loadSkills();});
|
||
</script>
|
||
<!-- DOCTRINE-60-UX-JS -->
|
||
<script id="doctrine60-ux-js-deerflow-hub">
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
const observer = new IntersectionObserver((entries) => {
|
||
entries.forEach((entry, index) => {
|
||
if (entry.isIntersecting) {
|
||
setTimeout(() => {
|
||
entry.target.classList.add('enter-stagger');
|
||
}, index * 80);
|
||
observer.unobserve(entry.target);
|
||
}
|
||
});
|
||
}, { threshold: 0.1 });
|
||
|
||
document.querySelectorAll('.card, .panel, .btn, .kpi').forEach(el => {
|
||
observer.observe(el);
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|