121 lines
11 KiB
HTML
121 lines
11 KiB
HTML
<!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>
|