<html>
<head>
<meta charset="utf-8" />
<style>
:root {
  --accent:#1257D6; --accent-soft:#F3F8FF; --accent-dim:rgba(18,87,214,.08); --accent-line:#C9DFF7; --accent-ink:#0B3A8F; --accent-sub:#3A5A82;
  --bg:#F7F8FA; --surface:#F2F4F7; --card:#FFFFFF;
  --text-1:#151D2C; --text-2:#3D4757; --text-3:#6B7280;
  --border:#E3E6EB; --border-strong:#C9D0D9; --rowline:#EEF0F3;
  --success:#16A34A; --success-bg:#E7F6EC; --success-line:#B7E3C4;
  --warning:#B45309; --warning-bg:#FEF3E2; --warning-line:#F3D9A8;
  --danger:#D93025; --danger-bg:#FDECEA; --danger-line:#F3C4C1;
}
html[theme="dark"] {
  --accent:#4A87E8; --accent-soft:rgba(74,135,232,.14); --accent-dim:rgba(74,135,232,.14); --accent-line:rgba(74,135,232,.36); --accent-ink:#B0CBFF; --accent-sub:#93A9C9;
  --bg:#111114; --surface:#18181C; --card:#1B1B1F;
  --text-1:#FFFFFF; --text-2:#E4E4EA; --text-3:#CFCFD6;
  --border:#2A2A30; --border-strong:#3D3D45; --rowline:#232328;
  --success:#3EBB6A; --success-bg:rgba(62,187,106,.10); --success-line:rgba(62,187,106,.32);
  --warning:#E9B65A; --warning-bg:rgba(233,182,90,.14); --warning-line:rgba(233,182,90,.32);
  --danger:#F87171; --danger-bg:rgba(248,113,113,.14); --danger-line:rgba(248,113,113,.36);
}
html { background: var(--card); color: var(--text-1); font: 13px "Segoe UI", sans-serif; height: 100%; }
body { margin: 0; height: 100%; overflow: hidden; flow: vertical; }
svg { background-color: transparent; }
.soHd { flow: horizontal; padding: 8px 14px; }
.soHd.blue { background: var(--accent-soft); border-bottom: 1px solid var(--accent-line); }
.soHd.green { background: var(--success-bg); border-bottom: 1px solid var(--success-line); }
.soHd.red { background: var(--danger-bg); border-bottom: 1px solid var(--danger-line); }
.soHd.amber { background: var(--warning-bg); border-bottom: 1px solid var(--warning-line); }
.soBadge { width: 26px; height: 26px; border-radius: 6px; margin-right: 10px; margin-top: 2px; background: var(--accent); }
.soHd.green .soBadge { background: var(--success); } .soHd.red .soBadge { background: var(--danger); } .soHd.amber .soBadge { background: var(--warning); }
.soBadge svg { width: 14px; height: 14px; margin: 6px; fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.soHtx { width: *; }
.soTitle { font-size: 12.5px; font-weight: 700; color: var(--text-1); }
.soSub { font-size: 10.5px; color: var(--text-3); margin-top: 1px; }
.soBtn { padding: 6px 13px; margin-left: 7px; border-radius: 7px; border: 1px solid var(--border-strong); background: var(--card); color: var(--text-2); font-size: 12px; font-weight: 600; cursor: pointer; }
.soBtn.stop { border-color: var(--danger-line); color: var(--danger); }
.soBtn.primary { background: var(--success); color: #fff; border-color: var(--success); }
.soBar { height: 2px; background: var(--rowline); }
.soBar > div { height: 2px; width: 0%; background: var(--accent); }
.soBar.green > div { background: var(--success); }
.soStats { flow: horizontal; padding: 6px 12px 3px; }
.soStat { width: *; margin-right: 6px; background: var(--surface); border-radius: 6px; padding: 4px 10px; }
.soStat.last { margin-right: 0; }
.soStat .l { font-size: 8.5px; color: var(--text-3); text-transform: uppercase; letter-spacing: .35px; }
.soStat .v { font-size: 13px; font-weight: 700; margin-top: 1px; color: var(--text-1); }
.soChart { margin: 4px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 6px 12px; }
.soChartT { font-size: 11px; font-weight: 700; color: var(--text-1); }
.soChartS { font-size: 9.5px; color: var(--text-3); margin-top: 1px; margin-bottom: 5px; }
.soCats { display: block; }
.soCat { display: inline-block; padding: 3px 9px; margin: 0 6px 4px 0; border-radius: 99px; font-size: 10px; font-weight: 700; color: #fff; }
.soCatsEmpty { font-size: 10.5px; color: var(--text-3); padding: 4px 0; }
.soCur { padding: 2px 14px 6px; font: 10px "Consolas", monospace; color: var(--text-3); height: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.soTblHd { flow: horizontal; padding: 8px 14px; background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.soTblHd > div { font-size: 10px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .5px; }
.soBody { height: *; overflow-y: scroll; overflow-x: hidden; }
.soRow { flow: horizontal; padding: 8px 14px; border-bottom: 1px solid var(--rowline); }
.soCName { width: 230px; font-size: 12px; font-weight: 600; color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 22px; }
.soCDet  { width: 200px; font-size: 11.5px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 22px; }
.soCCat  { width: 120px; line-height: 22px; }
.soCPath { width: *; font: 10.5px "Consolas", monospace; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 22px; }
.soCAct  { width: 128px; text-align: right; }
.soCatPill { display: inline-block; padding: 1px 8px; border-radius: 99px; font-size: 10px; font-weight: 700; color: #fff; }
.soSel { background: var(--card); border: 1px solid var(--border-strong); border-radius: 6px; padding: 3px 7px; color: var(--text-1); font-size: 11px; }
.soDone { font-size: 11px; font-weight: 700; color: var(--success); line-height: 22px; }
.soEmpty { padding: 34px 16px; text-align: center; color: var(--text-3); font-size: 12px; }
.soFoot { flow: horizontal; padding: 10px 14px; border-top: 1px solid var(--border); background: var(--surface); }
.soFootLbl { font-size: 12px; color: var(--text-2); line-height: 30px; margin-right: 8px; }
.soFootGrow { width: *; }
</style>
</head>
<body>
  <div class="soHd blue" id="soHd">
    <div class="soBadge" id="soBadge"><svg viewBox="0 0 24 24" id="soBadgeSvg"><path d="M21 12a9 9 0 1 1-6.2-8.6"/></svg></div>
    <div class="soHtx"><div class="soTitle" id="soTitle">Scan</div><div class="soSub" id="soSub">Starting&#8230;</div></div>
    <span class="soBtn stop" id="soStop">Stop</span>
    <span class="soBtn" id="soClose">Close</span>
  </div>
  <div class="soBar" id="soBar"><div id="soFill"></div></div>
  <div class="soStats">
    <div class="soStat"><div class="l">Scanned</div><div class="v" id="soScanned">0</div></div>
    <div class="soStat"><div class="l">Threats</div><div class="v" id="soThreats" style="color:var(--danger)">0</div></div>
    <div class="soStat"><div class="l">Neutralized</div><div class="v" id="soNeut" style="color:var(--success)">0</div></div>
    <div class="soStat last"><div class="l">Time</div><div class="v" id="soTime">0:00</div></div>
  </div>
  <div class="soChart">
    <div class="soChartT">Threat categories</div>
    <div class="soChartS">Detections grouped by malware family</div>
    <div class="soCats" id="soCats"><div class="soCatsEmpty" id="soCatsEmpty">No detections yet.</div></div>
  </div>
  <div class="soCur" id="soCur"></div>
  <div class="soTblHd" id="soTblHd" style="display:none"><div class="soCName">Threat</div><div class="soCDet">Detection</div><div class="soCCat">Category</div><div class="soCPath">Path</div><div class="soCAct">Action</div></div>
  <div class="soBody" id="soBody"><div class="soEmpty" id="soEmpty">Scanning&#8230; no threats found yet.</div></div>
  <div class="soFoot" id="soFoot" style="display:none">
    <span class="soFootLbl">Set all</span>
    <select class="soSel" id="soSetAll"><option value="quarantine">Quarantine</option><option value="delete">Delete</option><option value="ignore">Ignore</option></select>
    <div class="soFootGrow"></div>
    <span class="soBtn primary" id="soNeutBtn">Neutralize threats</span>
  </div>

<script type="text/javascript">
  var DOT = "·", ELL = "…";
  function byId(id){ return document.getElementById(id); }
  function setText(id,t){ var e=byId(id); if(e) e.textContent=(t==null?"":String(t)); }
  function cls(el,n,on){ if(!el)return; if(on) el.classList.add(n); else el.classList.remove(n); }
  function fmtNum(n){ try{ return String(Math.round(Number(n))).replace(/\B(?=(\d{3})+(?!\d))/g, ","); }catch(e){ return ""+n; } }
  async function bridge(method){
    var args=Array.prototype.slice.call(arguments,1);
    var url="tqcall:"+method; if(args.length) url+="?args="+encodeURIComponent(JSON.stringify(args));
    try{ var r=await fetch(url); return await r.text(); }catch(e){ return ""; }
  }
  var CAT_COLOR={Ransomware:"#B91C1C",Trojan:"#DC2626",Backdoor:"#B45309",Spyware:"#BE185D",Virus:"#B91C1C",Worm:"#DC2626",Miner:"#9A3412",Script:"#C2410C",Adware:"#B45309",Generic:"#475569"};
  function catName(c){ var s=String(c||"").toLowerCase();
    if(s.indexOf("ransom")>=0)return"Ransomware"; if(s.indexOf("trojan")>=0)return"Trojan";
    if(s.indexOf("backdoor")>=0)return"Backdoor"; if(s.indexOf("spy")>=0)return"Spyware";
    if(s.indexOf("worm")>=0)return"Worm"; if(s.indexOf("virus")>=0)return"Virus";
    if(s.indexOf("min")>=0)return"Miner"; if(s.indexOf("script")>=0||s.indexOf("ps")>=0)return"Script";
    if(s.indexOf("adware")>=0||s.indexOf("pua")>=0)return"Adware"; return"Generic"; }
  var SC_MODE={quick:"Quick scan",full:"Full scan",custom:"Custom scan",autoruns:"Autoruns scan",memory:"Memory scan",forcefull:"Full scan "+DOT+" Force"};
  var _sc={threats:[],phase:"scanning",pct:0,t0:0,timer:null,neutTotal:0,neutDone:0};

  function soHead(state){
    var hd=byId("soHd"); if(!hd)return;
    cls(hd,"blue",false); cls(hd,"green",false); cls(hd,"red",false); cls(hd,"amber",false);
    var svg=byId("soBadgeSvg");
    if(state==="scanning"){ cls(hd,"blue",true); if(svg) svg.innerHTML='<path d="M21 12a9 9 0 1 1-6.2-8.6"/>'; }
    else if(state==="review"){ cls(hd,"blue",true); if(svg) svg.innerHTML='<path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z"/><path d="M9 12l2 2 4-4"/>'; }
    else if(state==="clean"||state==="done"){ cls(hd,"green",true); if(svg) svg.innerHTML='<circle cx="12" cy="12" r="9"/><path d="M8.5 12l2.5 2.5 4.5-4.5"/>'; }
    else if(state==="neutralizing"){ cls(hd,"green",true); if(svg) svg.innerHTML='<path d="M21 12a9 9 0 1 1-6.2-8.6"/>'; }
  }
  function renderCats(){
    var box=byId("soCats"); if(!box)return;
    var counts={}; _sc.threats.forEach(function(t){ counts[t.catn]=(counts[t.catn]||0)+1; });
    var keys=Object.keys(counts);
    if(!keys.length){ box.innerHTML='<div class="soCatsEmpty">No detections yet.</div>'; return; }
    box.innerHTML="";
    keys.forEach(function(k){ var c=document.createElement("span"); c.className="soCat"; c.style.background=CAT_COLOR[k]||"#475569"; c.textContent=k+" "+counts[k]; box.appendChild(c); });
  }
  function renderRows(){
    var body=byId("soBody"), hd=byId("soTblHd"); if(!body)return;
    if(!_sc.threats.length){
      if(hd) hd.style.display="none";
      body.innerHTML='<div class="soEmpty">'+(_sc.phase==="clean"?"No threats found. Your PC is clean.":"Scanning"+ELL+" no threats found yet.")+'</div>';
      return;
    }
    if(hd) hd.style.display="block";
    body.innerHTML="";
    _sc.threats.forEach(function(t,i){
      var row=document.createElement("div"); row.className="soRow";
      var act=t.done?('<span class="soDone">'+(t.status==="deleted"?"Deleted":t.status==="ignored"?"Ignored":t.status==="reboot"?"Reboot":"Quarantined")+'</span>')
        :'<select class="soSel"><option value="quarantine">Quarantine</option><option value="delete">Delete</option><option value="ignore">Ignore</option></select>';
      row.innerHTML='<div class="soCName">'+(t.name||"Threat")+'</div>'
        +'<div class="soCDet">'+(t.det||t.name||"")+'</div>'
        +'<div class="soCCat"><span class="soCatPill" style="background:'+(CAT_COLOR[t.catn]||"#475569")+'">'+t.catn+'</span></div>'
        +'<div class="soCPath">'+(t.path||t.disp||"")+'</div>'
        +'<div class="soCAct">'+act+'</div>';
      var sel=row.querySelector(".soSel");
      if(sel){ sel.value=t.choice||"quarantine"; sel.addEventListener("change",function(){ _sc.threats[i].choice=sel.value; }); }
      body.appendChild(row);
    });
  }
  function scFoot(){
    var foot=byId("soFoot"); if(!foot)return;
    var pending=_sc.threats.filter(function(t){return !t.done;}).length;
    foot.style.display=(_sc.phase==="review"&&pending>0)?"block":"none";
  }
  byId("soClose").addEventListener("click",function(){ window.close(); });
  byId("soStop").addEventListener("click",function(){ bridge("AbortScan"); byId("soStop").style.display="none"; });
  byId("soSetAll").addEventListener("change",function(){ var v=byId("soSetAll").value; _sc.threats.forEach(function(t){ if(!t.done) t.choice=v; }); renderRows(); });
  byId("soNeutBtn").addEventListener("click",function(){
    _sc.threats.forEach(function(t){ if(!t.done&&t.choice==="ignore"){ t.done=true; t.status="ignored"; } });
    var todo=_sc.threats.filter(function(t){return !t.done;});
    if(!todo.length){ _sc.phase="done"; soHead("done"); setText("soTitle","All threats handled"); setText("soSub","Your PC is clean."); renderRows(); scFoot(); return; }
    _sc.neutTotal=todo.length; _sc.neutDone=0; _sc.phase="neutralizing";
    soHead("neutralizing"); setText("soTitle","Neutralizing threats"+ELL); setText("soSub","Removing detected items.");
    cls(byId("soBar"),"green",true); byId("soFill").style.width="0%"; byId("soFoot").style.display="none";
    if(_sc.demo){ demoNeutralize(todo); }
    else { bridge("StartNeutralize", todo.map(function(t){return (t.choice||"quarantine")+"|"+t.path;}).join("\n")); }
  });

  window.__tqPush=function(msg){
    var m=msg; if(typeof m==="string"){ try{ m=JSON.parse(m); }catch(e){ return; } }
    if(!m||!m.type)return;
    if(m.type==="progress"){
      if(_sc.demoWatch){ clearTimeout(_sc.demoWatch); _sc.demoWatch=null; }   // real scan responded
      if(m.count!=null){ _sc.scanned=m.count; setText("soScanned",fmtNum(m.count)); }
      _sc.pct=Math.min(96,_sc.pct+1.6); byId("soFill").style.width=_sc.pct+"%";
      setText("soSub","Scanning"+ELL+" "+Math.round(_sc.pct)+"%");
      if(m.file) setText("soCur","scanning: "+m.file);
      if(m.threats!=null) setText("soThreats",m.threats);
    } else if(m.type==="threat"){
      if(m.source==="hosts"||m.source==="autostart"||m.source==="browser") return;
      _sc.threats.push({ name:String(m.disp||m.path||m.name||"").split("\\").pop()||(m.name||"Threat"), det:m.name||"", catn:catName(m.category), path:m.path||m.disp||"", choice:"quarantine", done:(m.action&&m.action!=="pending"), status:m.action||"" });
      setText("soThreats",String(_sc.threats.length)); renderCats();
      if(_sc.phase==="scanning") renderRows();
    } else if(m.type==="done"){
      _sc.pct=100; byId("soFill").style.width="100%"; setText("soCur","");
      if(m.count!=null) setText("soScanned",fmtNum(m.count)); byId("soStop").style.display="none";
      if(_sc.threats.length){ _sc.phase="review"; soHead("review"); setText("soTitle","Scan complete "+DOT+" "+_sc.threats.length+" threat"+(_sc.threats.length===1?"":"s")+" found"); setText("soSub","Choose an action for each, then Neutralize."); renderRows(); }
      else { _sc.phase="clean"; soHead("clean"); setText("soTitle","No threats found"); setText("soSub","Your PC is clean."); cls(byId("soBar"),"green",true); renderRows(); }
      scFoot();
    } else if(m.type==="neutralized"){
      for(var i=0;i<_sc.threats.length;i++){ if(_sc.threats[i].path===m.path){ _sc.threats[i].done=true; _sc.threats[i].status=m.status||(_sc.threats[i].choice==="delete"?"deleted":"quarantined"); break; } }
      _sc.neutDone++; setText("soNeut",_sc.neutDone); byId("soFill").style.width=Math.round(_sc.neutDone/Math.max(1,_sc.neutTotal)*100)+"%"; renderRows();
    } else if(m.type==="ndone"){
      _sc.phase="done"; soHead("done"); setText("soTitle","All threats neutralized"); setText("soSub",(m.reboot===true||m.reboot==="true")?"Restart to finish removing locked files.":"Your PC is clean."); renderRows(); scFoot();
    } else if(m.type==="error"){
      // Service not running (pipe/timeout) with nothing scanned → fall back to the labelled demo so
      // the page can be reviewed without the background service. A real error mid-scan is shown.
      if(_sc.phase==="scanning" && !_sc.demo && _sc.scanned===0 && !_sc.threats.length){ startDemo(); return; }
      var em=String(m.message||""); if(em.indexOf("pipe")<0&&_sc.phase==="scanning") setText("soSub","Error: "+em);
    }
  };

  // ---- Demo / self-test: synthesises the full scan flow (no real files touched) ----
  var DEMO_FILES=["C:\\Windows\\System32\\drivers\\etc\\hosts","C:\\Program Files\\App\\bin\\core.dll","C:\\Users\\You\\Downloads\\invoice.pdf","C:\\Users\\You\\AppData\\Local\\Temp\\tmp8f2.exe","C:\\Users\\You\\Documents\\notes.docx","C:\\Windows\\explorer.exe","C:\\Users\\You\\Desktop\\setup.exe"];
  var DEMO_THREATS=[
    {tick:6, name:"EICAR-Test-File", category:"Trojan", path:"C:\\Users\\You\\Downloads\\eicar.com"},
    {tick:14, name:"Ransom.LockBit3.Sample", category:"Ransomware", path:"C:\\Users\\You\\AppData\\Local\\Temp\\readme.locked.exe"},
    {tick:22, name:"PUA.Adware.InstallCore", category:"Adware", path:"C:\\Users\\You\\Desktop\\free-setup.exe"},
    {tick:28, name:"Trojan.Win32.Downloader", category:"Trojan", path:"C:\\Users\\You\\AppData\\Roaming\\upd\\svc.exe"}
  ];
  function startDemo(){
    _sc.demo=true; if(_sc.demoWatch){ clearTimeout(_sc.demoWatch); _sc.demoWatch=null; }
    setText("soSub","Demo "+DOT+" sample data (service not running)");
    var n=0, tick=0, TOTAL=34;
    _sc.demoTimer=setInterval(function(){
      tick++; n+=Math.floor(30+Math.random()*90);
      window.__tqPush({type:"progress", count:n, file:DEMO_FILES[tick%DEMO_FILES.length]});
      DEMO_THREATS.forEach(function(t){ if(t.tick===tick) window.__tqPush({type:"threat", name:t.name, category:t.category, path:t.path, action:"pending"}); });
      if(tick>=TOTAL){ clearInterval(_sc.demoTimer); _sc.demoTimer=null; window.__tqPush({type:"done", count:n}); }
    },90);
  }
  function demoNeutralize(todo){
    var i=0;
    var iv=setInterval(function(){
      if(i>=todo.length){ clearInterval(iv); window.__tqPush({type:"ndone", reboot:false}); return; }
      var t=todo[i++]; window.__tqPush({type:"neutralized", path:t.path, status:(t.choice==="delete"?"deleted":"quarantined")});
    },350);
  }

  window.__scanBoot=function(mode){
    _sc={threats:[],phase:"scanning",pct:0,scanned:0,t0:Date.now(),timer:null,neutTotal:0,neutDone:0,demo:false,demoWatch:null,demoTimer:null};
    soHead("scanning");
    setText("soTitle",(SC_MODE[mode]||"Scan")+" "+DOT+" Scanning"+ELL); setText("soSub","Looking for threats"+ELL);
    setText("soScanned","0"); setText("soThreats","0"); setText("soNeut","0"); setText("soTime","0:00"); setText("soCur","");
    _sc.timer=setInterval(function(){ var s=Math.floor((Date.now()-_sc.t0)/1000); setText("soTime",Math.floor(s/60)+":"+(s%60<10?"0":"")+(s%60)); },1000);
    var m=(mode==="forcefull")?"full":(mode||"quick");
    if(mode==="forcefull") bridge("StartScanForce",m,""); else bridge("StartScan",m,"");
    // If the real service hasn't answered with any progress in 2.5s, run the demo so the page is reviewable.
    _sc.demoWatch=setTimeout(function(){ if(_sc.phase==="scanning" && !_sc.demo && _sc.scanned===0 && !_sc.threats.length) startDemo(); },2500);
  };
</script>
</body>
</html>
