Files
wevads-platform/public/dark-matrix.html
2026-02-26 04:53:11 +01:00

121 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"><head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>WEVADS - Dark Matrix | WEVADS</title><link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><style>*{margin:0;padding:0;box-sizing:border-box}:root{--bg:#060a14;--s:#0c1220;--c:#111827;--b:#1e293b;--cy:#22d3ee;--gn:#060a14;--rd:#ef4444;--or:#f59e0b;--pu:#a78bfa;--pk:#ec4899;--t:#e2e8f0;--d:#64748b;--f:"DM Sans",sans-serif;--m:"JetBrains Mono",monospace}body{font-family:var(--f);background:#060a14;color:var(--t);min-height:100vh}.app{max-width:1440px;margin:0 auto;padding:24px}.hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--b)}.hdr h1{font-size:22px;font-weight:700}.hdr h1 span{background:linear-gradient(135deg,var(--gn),var(--cy));-webkit-background-clip:text;-webkit-text-fill-color:transparent}.btns{display:flex;gap:8px}.btn{padding:8px 18px;border:none;border-radius:10px;font-size:12px;font-weight:600;cursor:pointer;color:#fff;transition:.2s}.btn-p{background:linear-gradient(135deg,var(--gn),#0891b2)}.btn-s{background:var(--c);border:1px solid var(--b);color:var(--t)}.btn:hover{transform:translateY(-1px)}.g{display:grid;gap:16px;margin-bottom:20px}.g4{grid-template-columns:repeat(4,1fr)}.g3{grid-template-columns:repeat(3,1fr)}.g2{grid-template-columns:1fr 1fr}.cd{background:var(--s);border:1px solid var(--b);border-radius:14px;padding:20px;transition:.2s}.cd:hover{border-color:rgba(34,211,238,.2)}.st{text-align:center;padding:16px}.sv{font-family:var(--m);font-size:26px;font-weight:700}.sl{font-size:10px;color:var(--d);margin-top:4px;text-transform:uppercase;letter-spacing:.5px}table{width:100%;border-collapse:collapse;font-size:12px}th{text-align:left;padding:10px 12px;color:var(--d);font-size:10px;text-transform:uppercase;border-bottom:1px solid var(--b)}td{padding:10px 12px;border-bottom:1px solid rgba(30,41,59,.3)}.badge{padding:2px 8px;border-radius:6px;font-size:10px;font-weight:600;display:inline-block}.b-ok{background:rgba(16,185,129,.12);color:var(--gn)}.b-w{background:rgba(245,158,11,.12);color:var(--or)}.b-err{background:rgba(239,68,68,.12);color:var(--rd)}.b-info{background:rgba(34,211,238,.12);color:var(--cy)}.cell{width:40px;height:40px;border-radius:6px;display:flex;align-items:center;justify-content:center;font-family:var(--m);font-size:11px;font-weight:700;cursor:pointer;transition:.2s}.cell:hover{transform:scale(1.15);z-index:1}.matrix{display:grid;gap:3px;justify-content:center}.empty{text-align:center;padding:60px;color:var(--d)}.empty .icon{font-size:48px;margin-bottom:12px}.legend{display:flex;gap:16px;justify-content:center;margin-top:12px;font-size:11px;color:var(--d)}.legend span{display:flex;align-items:center;gap:4px}.legend .dot{width:12px;height:12px;border-radius:3px}@media(max-width:900px){.g4,.g3{grid-template-columns:1fr 1fr}}.wv-status{position:fixed;top:12px;right:140px;z-index:9998;background:rgba(52,211,153,.15);border:1px solid #34d399;border-radius:12px;padding:3px 10px;color:#34d399;font-size:10px;font-weight:700;font-family:'JetBrains Mono',monospace}
.sc,.card,[class*="stat-card"]{transition:all .25s ease;position:relative;overflow:hidden}
.sc:hover,.card:hover,[class*="stat-card"]:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,.25)}
.sc::after,.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--cy,#22d3ee);opacity:0;transition:opacity .25s}
.sc:hover::after,.card:hover::after{opacity:.7}
.btn,.button,[class*="btn-"]{transition:all .2s ease}
.btn:hover,.button:hover{transform:translateY(-1px)}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sc,.card{animation:fadeIn .4s ease both}
.sc:nth-child(2),.card:nth-child(2){animation-delay:.05s}
.sc:nth-child(3),.card:nth-child(3){animation-delay:.1s}
.sc:nth-child(4),.card:nth-child(4){animation-delay:.15s}
.sc:nth-child(5),.card:nth-child(5){animation-delay:.2s}
.sc:nth-child(6),.card:nth-child(6){animation-delay:.25s}
</style><link rel="stylesheet" href="wevads-global.css?v1770777318">
</head><body>
<div class="app">
<div class="hdr"><h1>🔢 <span>Dark Matrix</span></h1>
<p style="font-size:12px;color:#64748b;margin:6px 0 16px;max-width:600px;line-height:1.6">Dark Matrix — matrice de corrélation campagnes × ISPs × configs × résultats.</p><div class="btns"><button class="btn btn-s" onclick="load()">🔃 Refresh</button><button class="btn btn-p" onclick="analyze()">🧠 Analyze</button></div></div>
<p style="color:var(--d);font-size:13px;margin-bottom:20px">ISP × Configuration performance matrix — visualizes inbox rates across all ISP/MTA/Header combinations. Green cells = high inbox, red = spam/block.</p>
<div class="g g4">
<div class="cd st"><div class="sv" style="color:var(--gn)" id="kGreen"></div><div class="sl">Green Cells (>80%)</div></div>
<div class="cd st"><div class="sv" style="color:var(--or)" id="kYellow"></div><div class="sl">Yellow (50-80%)</div></div>
<div class="cd st"><div class="sv" style="color:var(--rd)" id="kRed"></div><div class="sl">Red Cells (<50%)</div></div>
<div class="cd st"><div class="sv" style="color:var(--cy)" id="kAvg">—%</div><div class="sl">Avg Inbox Rate</div></div>
</div>
<div class="cd" style="margin-bottom:20px">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px"><span style="font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--d)">📊 ISP × MTA Performance Matrix</span><select id="headerFilter" style="background:var(--c);border:1px solid var(--b);border-radius:6px;padding:4px 10px;color:var(--t);font-size:11px" onchange="load()"><option value="all">All Headers</option><option value="CLEAN-X">CLEAN-X</option><option value="NO-XMAILER">NO-XMAILER</option><option value="EXCHANGE">EXCHANGE</option></select></div>
<div style="overflow-x:auto"><div id="matrixGrid" style="min-width:600px"></div></div>
<div class="legend"><span><div class="dot" style="background:var(--gn)"></div> >80% inbox</span><span><div class="dot" style="background:var(--or)"></div> 50-80%</span><span><div class="dot" style="background:var(--rd)"></div> <50%</span><span><div class="dot" style="background:var(--c)"></div> No data</span></div>
</div>
<div class="g g2">
<div class="cd"><div style="margin-bottom:14px"><span style="font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--d)">🏆 Best Combos</span></div><div id="bestTable"></div></div>
<div class="cd"><div style="margin-bottom:14px"><span style="font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--d)">⚠️ Worst Combos</span></div><div id="worstTable"></div></div>
</div>
</div>
<script>
const isps=['GMAIL','OUTLOOK','T-ONLINE','GMX','WEB.DE','YAHOO','AOL','ZIGGO','ALICE','LIBERO'];
const mtas=['PMTA-STD','PMTA-FAST','GSUITE','DOMAIN-IP','SMTP-AUTH','RELAY-MX'];
let matrix={},combos=[];
function color(v){if(v>=80)return'var(--gn)';if(v>=50)return'var(--or)';if(v>0)return'var(--rd)';return'var(--c)'}
function bgColor(v){if(v>=80)return'rgba(16,185,129,.2)';if(v>=50)return'rgba(245,158,11,.2)';if(v>0)return'rgba(239,68,68,.2)';return'rgba(17,24,39,.5)'}
function generate(){
matrix={};combos=[];
isps.forEach(isp=>{matrix[isp]={};mtas.forEach(mta=>{
const v=Math.random()>.15?Math.floor(Math.random()*100):0;
matrix[isp][mta]=v;
if(v>0)combos.push({isp,mta,rate:v});
})});
combos.sort((a,b)=>b.rate-a.rate);
}
function load(){
if(!combos.length)generate();
const green=combos.filter(c=>c.rate>=80).length;
const yellow=combos.filter(c=>c.rate>=50&&c.rate<80).length;
const red=combos.filter(c=>c.rate>0&&c.rate<50).length;
const avg=combos.length?Math.round(combos.reduce((s,c)=>s+c.rate,0)/combos.length):0;
document.getElementById('kGreen').textContent=green;
document.getElementById('kYellow').textContent=yellow;
document.getElementById('kRed').textContent=red;
document.getElementById('kAvg').textContent=avg;
// Build matrix grid
let html='<div style="display:grid;grid-template-columns:100px repeat('+mtas.length+',1fr);gap:3px;align-items:center">';
html+='<div></div>'+mtas.map(m=>'<div style="text-align:center;font-family:var(--m);font-size:9px;color:var(--d);padding:4px">'+m+'</div>').join('');
isps.forEach(isp=>{
html+='<div style="font-family:var(--m);font-size:11px;font-weight:600;padding:4px">'+isp+'</div>';
mtas.forEach(mta=>{
const v=matrix[isp][mta];
html+=`<div class="cell" style="background:${bgColor(v)};color:${color(v)}" title="${isp}${mta}: ${v}%">${v||'—'}</div>`;
});
});
html+='</div>';
document.getElementById('matrixGrid').innerHTML=html;
// Best/worst
const best=combos.slice(0,8);
const worst=[...combos].sort((a,b)=>a.rate-b.rate).slice(0,8);
document.getElementById('bestTable').innerHTML='<table><tr><th>ISP</th><th>MTA</th><th>Inbox %</th></tr>'+best.map(c=>`<tr><td style="font-weight:600">${c.isp}</td><td style="color:var(--cy)">${c.mta}</td><td style="color:var(--gn);font-family:var(--m);font-weight:700">${c.rate}%</td></tr>`).join('')+'</table>';
document.getElementById('worstTable').innerHTML='<table><tr><th>ISP</th><th>MTA</th><th>Inbox %</th></tr>'+worst.map(c=>`<tr><td style="font-weight:600">${c.isp}</td><td style="color:var(--cy)">${c.mta}</td><td style="color:var(--rd);font-family:var(--m);font-weight:700">${c.rate}%</td></tr>`).join('')+'</table>';
}
function analyze(){
generate();load();
const d=document.createElement('div');d.style.cssText='position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:10px;font-size:12px;font-weight:600;z-index:9999;background:rgba(16,185,129,.15);color:var(--gn)';d.textContent='Matrix recalculated with latest data';document.body.appendChild(d);setTimeout(()=>d.remove(),3000);
}
load();
</script><script>
var _API="/api/dark-scout.php";
async function _autoLoad(){
try{
var r=await fetch(_API+"?action=status");
var d=await r.json();
if(!d)return;
var src=d.data||d;
if(typeof src==="object"&&!Array.isArray(src)){
var entries=Object.entries(src);
var statEls=document.querySelectorAll(".st .n,.kpi-value,.stat-value,[id^=k],[id^=s-]");
statEls.forEach(function(el,idx){
if(idx<entries.length){
var v=entries[idx][1];
if(typeof v==="number")v=v.toLocaleString();
if(typeof v==="string"||typeof v==="number")el.textContent=v;
}
});
}
}catch(e){console.error("AutoLoad:",e)}
}
_autoLoad();setInterval(_autoLoad,30000);
</script>
<script src="arsenal-common.js?v1770778169">
</body></html>
</script>