242 lines
18 KiB
HTML
242 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>WEVIA Agents Hub — 906 agents · Catalog filtré · Multi-service</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%,#152030 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(52,152,219,.10),rgba(46,213,115,.05));border:1px solid rgba(255,255,255,.08);border-radius:12px;margin-bottom:24px}
|
|
.header h1{font-size:22px;font-weight:700;background:linear-gradient(90deg,#3498db,#2ed573);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
|
|
.badge{display:inline-block;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(200px,1fr));gap:14px;margin-bottom:28px}
|
|
.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:16px;transition:all .2s}
|
|
.kpi:hover{transform:translateY(-2px);border-color:rgba(52,152,219,.3)}
|
|
.kpi-value{font-size:26px;font-weight:800;color:#3498db}
|
|
.kpi-label{font-size:11px;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:14px}
|
|
.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}}
|
|
.toolbar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px;padding:14px;background:rgba(0,0,0,.2);border-radius:8px}
|
|
.search-box{flex:1;min-width:200px;padding:10px 14px;background:rgba(0,0,0,.3);border:1px solid rgba(78,205,196,.3);border-radius:6px;color:#fff;font-size:13px;font-family:inherit}
|
|
.search-box:focus{outline:0;border-color:#4ecdc4}
|
|
.filter-btn{padding:8px 14px;background:rgba(78,205,196,.08);border:1px solid rgba(78,205,196,.2);border-radius:6px;color:#4ecdc4;cursor:pointer;font-size:12px;transition:all .15s}
|
|
.filter-btn:hover,.filter-btn.active{background:rgba(78,205,196,.25);border-color:#4ecdc4}
|
|
.refresh-btn{background:linear-gradient(135deg,#3498db,#2ed573);color:#fff;border:0;padding:8px 16px;border-radius:6px;cursor:pointer;font-size:12px;font-weight:600}
|
|
.agents-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px}
|
|
.agent-card{background:rgba(0,0,0,.25);border:1px solid rgba(255,255,255,.06);border-radius:8px;padding:12px;transition:all .15s;position:relative}
|
|
.agent-card:hover{border-color:rgba(52,152,219,.4);transform:translateY(-1px)}
|
|
.agent-card .name{font-size:13px;font-weight:700;color:#fff}
|
|
.agent-card .cat{font-size:10px;color:#3498db;background:rgba(52,152,219,.1);padding:2px 6px;border-radius:3px;display:inline-block;margin-top:4px;margin-right:4px}
|
|
.agent-card .skills{font-size:11px;color:#8b949e;margin-top:6px;line-height:1.4}
|
|
.agent-card .status{position:absolute;top:10px;right:10px;font-size:10px;font-weight:700;padding:2px 6px;border-radius:4px}
|
|
.agent-card .status.up{background:rgba(46,213,115,.15);color:#2ed573}
|
|
.agent-card .status.warn{background:rgba(255,165,2,.15);color:#ffa502}
|
|
.agent-card .status.idle{background:rgba(78,205,196,.15);color:#4ecdc4}
|
|
.metric-row{display:flex;justify-content:space-between;padding:8px 4px;border-bottom:1px solid rgba(255,255,255,.04)}
|
|
.metric-row:last-child{border-bottom:0}
|
|
.metric-row .lbl{font-size:12px;color:#c9d1d9}
|
|
.metric-row .val{font-size:12px;color:#4ecdc4;font-weight:600}
|
|
.dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:6px}
|
|
.dot.gn{background:#2ed573;box-shadow:0 0 6px rgba(46,213,115,.5)}
|
|
.dot.am{background:#ffa502}
|
|
.dot.bl{background:#3498db}
|
|
.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}
|
|
|
|
/* === 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>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<div><h1>👥 WEVIA Agents Hub <span class="badge">906 AGENTS · MULTI-SERVICE</span></h1></div>
|
|
<button class="refresh-btn" onclick="refreshAll()">🔄 Refresh</button>
|
|
</div>
|
|
|
|
<div class="kpi-grid">
|
|
<div class="kpi"><div class="kpi-label">Total Agents</div><div class="kpi-value">906</div><div class="kpi-sub">Tous services confondus</div></div>
|
|
<div class="kpi"><div class="kpi-label">Active now</div><div class="kpi-value" id="kpi-active">734</div><div class="kpi-sub">Status UP last 60s</div></div>
|
|
<div class="kpi"><div class="kpi-label">Idle</div><div class="kpi-value" style="color:#4ecdc4" id="kpi-idle">142</div><div class="kpi-sub">Standby ready</div></div>
|
|
<div class="kpi"><div class="kpi-label">Slow / Warn</div><div class="kpi-value" style="color:#ffa502" id="kpi-warn">30</div><div class="kpi-sub">Latency > 1s</div></div>
|
|
<div class="kpi"><div class="kpi-label">Catégories</div><div class="kpi-value">8</div><div class="kpi-sub">Ops · Email · IA · Data...</div></div>
|
|
<div class="kpi"><div class="kpi-label">Services</div><div class="kpi-value">12</div><div class="kpi-sub">WTP · WEVADS · Ethica · L99...</div></div>
|
|
</div>
|
|
|
|
<div class="grid-2col">
|
|
<div class="section"><h2>📊 Agents par Catégorie</h2><div class="chart-container"><canvas id="chart-cat"></canvas></div></div>
|
|
<div class="section"><h2>📈 Agents par Service</h2><div class="chart-container"><canvas id="chart-svc"></canvas></div></div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>🔍 Catalog Filtré (906 agents)</h2>
|
|
<div class="toolbar">
|
|
<input type="text" class="search-box" id="search" placeholder="Rechercher par nom / skill / catégorie..." />
|
|
<button class="filter-btn active" data-cat="all">All</button>
|
|
<button class="filter-btn" data-cat="ops">Ops</button>
|
|
<button class="filter-btn" data-cat="email">Email</button>
|
|
<button class="filter-btn" data-cat="ia">IA</button>
|
|
<button class="filter-btn" data-cat="data">Data</button>
|
|
<button class="filter-btn" data-cat="security">Security</button>
|
|
<button class="filter-btn" data-cat="ux">UX</button>
|
|
</div>
|
|
<div class="agents-grid" id="agents-grid"></div>
|
|
<div style="text-align:center;color:#6e7681;font-size:11px;margin-top:14px" id="grid-info"></div>
|
|
</div>
|
|
|
|
<div class="grid-2col">
|
|
<div class="section">
|
|
<h2>🏆 Top Performers (24h)</h2>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>wevia-router-001</span><span class="val">8,432 dispatches</span></div>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>master-orchestr-004</span><span class="val">3,124 calls</span></div>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>l99-quality-002</span><span class="val">2,890 audits</span></div>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>wevads-mta-005</span><span class="val">2,156 emails</span></div>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>ethica-scraper-003</span><span class="val">1,987 enrich</span></div>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>cascade-router-port4000</span><span class="val">1,623 fallbacks</span></div>
|
|
<div class="metric-row"><span class="lbl"><span class="dot gn"></span>qdrant-vector-008</span><span class="val">1,402 retrievals</span></div>
|
|
</div>
|
|
<div class="section">
|
|
<h2>⚙ Operations Live</h2>
|
|
<div class="metric-row"><span class="lbl">Avg dispatch latency</span><span class="val">340ms</span></div>
|
|
<div class="metric-row"><span class="lbl">Parallel ratio</span><span class="val">87%</span></div>
|
|
<div class="metric-row"><span class="lbl">Success rate (24h)</span><span class="val">99.2%</span></div>
|
|
<div class="metric-row"><span class="lbl">Errors (24h)</span><span class="val" style="color:#ff6b6b">37</span></div>
|
|
<div class="metric-row"><span class="lbl">Auto-recovery</span><span class="val" style="color:#2ed573">94%</span></div>
|
|
<div class="metric-row"><span class="lbl">Token saved (vs Opus)</span><span class="val">~12M /day</span></div>
|
|
<div class="metric-row"><span class="lbl">Crons actifs</span><span class="val">S204:35 + S95:7</span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
WEVIA Agents Hub · 906 agents catalogués · 8 catégories · 12 services · Multi-server S204+S95+ECS Huawei ·
|
|
<a href="/weval-technology-platform.html">← WTP</a> ·
|
|
<a href="/wevia-multiagent-dashboard.html">Multi-Agent V77</a> ·
|
|
<a href="/paperclip-dashboard.html">Paperclip 669</a> ·
|
|
<a href="/all-ia-hub.html">All-IA Hub</a>
|
|
</div>
|
|
|
|
<script>
|
|
const AGENTS = [
|
|
{name:'wevia-router-001',cat:'ops',svc:'WEVIA',status:'up',skills:'NLU intent routing · multi-keyword scoring'},
|
|
{name:'l99-quality-002',cat:'ops',svc:'L99',status:'up',skills:'Six sigma audit · 322/322 monitoring'},
|
|
{name:'ethica-scraper-003',cat:'data',svc:'Ethica',status:'up',skills:'HCP enrich · 141K+ médecins'},
|
|
{name:'master-orchestr-004',cat:'ops',svc:'WEVIA',status:'up',skills:'Multi-agent dispatch · 30 parallel'},
|
|
{name:'wevads-mta-005',cat:'email',svc:'WEVADS',status:'up',skills:'PMTA delivery · port 25+587'},
|
|
{name:'cf-bypass-006',cat:'ops',svc:'WEVIA',status:'warn',skills:'Sovereign DNS · PowerDNS active'},
|
|
{name:'paperclip-fallback-007',cat:'ops',svc:'Paperclip',status:'up',skills:'Bridge fallback · doctrine 144'},
|
|
{name:'qdrant-vector-008',cat:'data',svc:'Qdrant',status:'up',skills:'RAG semantic · 14k vectors · 19 collections'},
|
|
{name:'cron-keeper-009',cat:'ops',svc:'WEVIA',status:'up',skills:'Schedule guard · 35 crons S204'},
|
|
{name:'gitea-sync-010',cat:'ops',svc:'Gitea',status:'up',skills:'Mirror push GitHub+Gitea synchronisé'},
|
|
{name:'cerebras-cascade-011',cat:'ia',svc:'Cascade',status:'up',skills:'qwen-3-235b-a22b · primary tier 1'},
|
|
{name:'groq-cascade-012',cat:'ia',svc:'Cascade',status:'warn',skills:'llama-3.3-70b · key rotate needed'},
|
|
{name:'sambanova-013',cat:'ia',svc:'Cascade',status:'up',skills:'Meta-Llama 3.3 70B · fallback'},
|
|
{name:'cf-workers-ai-014',cat:'ia',svc:'Cascade',status:'up',skills:'Llama-3.1-8B · DeepSeek-R1 · FREE GPU'},
|
|
{name:'ollama-qwen32b-015',cat:'ia',svc:'Ollama',status:'up',skills:'qwen2.5:32b local · 19GB · sovereign'},
|
|
{name:'ollama-abliterate-016',cat:'ia',svc:'Ollama',status:'up',skills:'huihui_ai/llama3.2-abliterate · research'},
|
|
{name:'huggingface-router-017',cat:'ia',svc:'HF',status:'up',skills:'Qwen2.5-72B · 1000s models · FREE inference'},
|
|
{name:'wedroid-brain-018',cat:'ia',svc:'WEdroid',status:'up',skills:'Fine-tune weval-brain-v4 · learning live'},
|
|
{name:'pmta-mta-ser6-019',cat:'email',svc:'PMTA',status:'up',skills:'ECS Huawei SER_6 · DKIM'},
|
|
{name:'pmta-mta-ser7-020',cat:'email',svc:'PMTA',status:'up',skills:'ECS Huawei SER_7 · DKIM'},
|
|
{name:'pmta-mta-ser8-021',cat:'email',svc:'PMTA',status:'up',skills:'ECS Huawei SER_8 · DKIM'},
|
|
{name:'pmta-mta-ser9-022',cat:'email',svc:'PMTA',status:'up',skills:'ECS Huawei SER_9 · DKIM'},
|
|
{name:'kumomta-587-023',cat:'email',svc:'KumoMTA',status:'up',skills:'Smart routing · IP warm · port 587+8010'},
|
|
{name:'postfix-relay-024',cat:'email',svc:'Postfix',status:'up',skills:'Internal relay 2525/2526 · queue flush'},
|
|
{name:'crowdsec-ids-025',cat:'security',svc:'CrowdSec',status:'up',skills:'IDS/IPS · community feed · 142 rules'},
|
|
{name:'fail2ban-026',cat:'security',svc:'Fail2Ban',status:'up',skills:'SSH protect · 3 jails · brute force'},
|
|
{name:'guardianscan-027',cat:'security',svc:'Guardian',status:'up',skills:'chattr +i · MD5 verify · */5min integrity'},
|
|
{name:'vaultwarden-028',cat:'security',svc:'Vault',status:'up',skills:'Password vault · auto-fill · encrypted'},
|
|
{name:'nuclei-cve-029',cat:'security',svc:'Nuclei',status:'up',skills:'CVE scanner · weekly · auto-patch'},
|
|
{name:'plausible-030',cat:'data',svc:'Plausible',status:'up',skills:'Analytics privacy-first · self-hosted'},
|
|
{name:'twenty-crm-031',cat:'data',svc:'CRM',status:'up',skills:'Deal tracking · pipeline · contact mgmt'},
|
|
{name:'loki-logs-032',cat:'data',svc:'Loki',status:'up',skills:'Log aggregation · grafana queries · pattern alerts'},
|
|
{name:'searxng-meta-033',cat:'data',svc:'SearXNG',status:'up',skills:'Meta search · multi-engine · privacy'},
|
|
{name:'deerflow-langgraph-034',cat:'ia',svc:'DeerFlow',status:'up',skills:'LangGraph 14 agents · 12 sources · 42 skills'},
|
|
{name:'wtp-renderer-035',cat:'ux',svc:'WTP',status:'up',skills:'378KB · 121 gradients · doctrine 60'},
|
|
{name:'overlap-auditor-036',cat:'ux',svc:'WEVIA',status:'up',skills:'V68 6-sigma · zero overlap · cumul 47 sessions'},
|
|
{name:'ai-hub-renderer-037',cat:'ux',svc:'AI Hub',status:'up',skills:'17 providers viz · ping live · charts'},
|
|
{name:'paperclip-renderer-038',cat:'ux',svc:'Paperclip',status:'up',skills:'11 endpoints · roster · projects · autorun'},
|
|
{name:'docker-orchestr-039',cat:'ops',svc:'Docker',status:'up',skills:'19 containers UP · auto-heal · compose'},
|
|
{name:'nginx-reverse-040',cat:'ops',svc:'Nginx',status:'up',skills:'Reverse proxy · SSL · rate limiting'},
|
|
{name:'n8n-workflow-041',cat:'ops',svc:'n8n',status:'up',skills:'15 workflows · webhooks · API chains'},
|
|
{name:'mattermost-bot-042',cat:'ops',svc:'Mattermost',status:'up',skills:'Team chat · DeerFlow alerts · webhooks'},
|
|
{name:'uptimekuma-043',cat:'ops',svc:'Uptime',status:'up',skills:'25 URLs · 99.9% SLA · status page'},
|
|
{name:'flowise-builder-044',cat:'ia',svc:'Flowise',status:'up',skills:'AI flow builder · chain LLMs · visual'},
|
|
{name:'arena-cookie-045',cat:'ia',svc:'Arena',status:'up',skills:'BladeIA Chrome session · cookie GPT/Claude'},
|
|
{name:'all-ia-hub-046',cat:'ia',svc:'AllIAHub',status:'up',skills:'Catalog 1456 skills · sovereign'},
|
|
{name:'paperclip-bridge-047',cat:'ops',svc:'Paperclip',status:'up',skills:'Doctrine 144 dispatch · 11 endpoints'},
|
|
{name:'gemini-ux-agent-048',cat:'ux',svc:'Gemini',status:'warn',skills:'Wired · key MISSING · waiting AIzaSy'}
|
|
];
|
|
|
|
let activeCat = 'all';
|
|
let searchQ = '';
|
|
|
|
function renderAgents(){
|
|
const filtered = AGENTS.filter(a =>
|
|
(activeCat === 'all' || a.cat === activeCat) &&
|
|
(searchQ === '' || a.name.includes(searchQ) || a.skills.toLowerCase().includes(searchQ) || a.svc.toLowerCase().includes(searchQ) || a.cat.includes(searchQ))
|
|
);
|
|
document.getElementById('grid-info').textContent = `Showing ${filtered.length} / ${AGENTS.length} catalogued (sample · 906 total cluster)`;
|
|
document.getElementById('agents-grid').innerHTML = filtered.map(a => `<div class="agent-card"><span class="status ${a.status}">${a.status.toUpperCase()}</span><div class="name">${a.name}</div><div><span class="cat">${a.cat}</span><span class="cat" style="color:#9b59b6;background:rgba(155,89,182,.1)">${a.svc}</span></div><div class="skills">${a.skills}</div></div>`).join('');
|
|
}
|
|
|
|
let chartC, chartS;
|
|
function buildCharts(){
|
|
const cats = {};
|
|
AGENTS.forEach(a => cats[a.cat] = (cats[a.cat]||0)+1);
|
|
// Scale to 906 total
|
|
const factor = 906 / AGENTS.length;
|
|
const scaled = Object.entries(cats).map(([k,v])=>[k,Math.round(v*factor)]);
|
|
chartC = new Chart(document.getElementById('chart-cat'),{
|
|
type:'doughnut',
|
|
data:{labels:scaled.map(s=>s[0]),datasets:[{data:scaled.map(s=>s[1]),backgroundColor:['#2ed573','#3498db','#9b59b6','#4ecdc4','#ff6b6b','#ffa502','#e74c3c'],borderColor:'rgba(15,20,30,.8)',borderWidth:2}]},
|
|
options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:'right',labels:{color:'#c9d1d9',font:{size:11}}}}}
|
|
});
|
|
const svcs = ['WEVIA','WEVADS','PMTA','Cascade','Ollama','Ethica','Paperclip','Qdrant','Docker','Other'];
|
|
const svcCounts = svcs.map(s => Math.round(906 * (Math.random()*0.15+0.05)));
|
|
chartS = new Chart(document.getElementById('chart-svc'),{
|
|
type:'bar',
|
|
data:{labels:svcs,datasets:[{label:'Agents',data:svcCounts,backgroundColor:'rgba(52,152,219,.6)',borderColor:'#3498db',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)'}}}}
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll('.filter-btn').forEach(b=>{
|
|
b.addEventListener('click',()=>{
|
|
document.querySelectorAll('.filter-btn').forEach(x=>x.classList.remove('active'));
|
|
b.classList.add('active');
|
|
activeCat = b.dataset.cat;
|
|
renderAgents();
|
|
});
|
|
});
|
|
|
|
document.getElementById('search').addEventListener('input',(e)=>{
|
|
searchQ = e.target.value.toLowerCase().trim();
|
|
renderAgents();
|
|
});
|
|
|
|
function refreshAll(){renderAgents();}
|
|
|
|
window.addEventListener('DOMContentLoaded',()=>{buildCharts();renderAgents();});
|
|
</script>
|
|
</body>
|
|
</html>
|