EvoWare

Killaura, dodging, ESP, zoom, auto‑respawn and much more. Buy me a coffee :) paypal.me/Izkuh

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         EvoWare
// @namespace    http://tampermonkey.net/
// @version      2026-05-23.2
// @description  Killaura, dodging, ESP, zoom, auto‑respawn and much more. Buy me a coffee :) paypal.me/Izkuh
// @author       #Ex
// @match        https://evowars.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=evowars.io
// @grant        none
// @license      GPL-3.0
// ==/UserScript==

(function() {
    'use strict';

    // UI – spacious, full‑size background, big toggles
    const iframe = document.createElement('iframe');
    iframe.id = 'evoware-frame';
    iframe.style.cssText = `position:fixed!important;top:50px!important;left:50px!important;width:560px!important;height:600px!important;border:none!important;z-index:2147483647!important;background:transparent!important;pointer-events:auto!important;transition:opacity 0.15s!important;`;
    document.body.appendChild(iframe);
    const doc = iframe.contentDocument || iframe.contentWindow.document;
    doc.open();
    doc.write(`<!DOCTYPE html><html><head><style>
        *{margin:0;padding:0;box-sizing:border-box}
        html,body{height:100%;width:100%}
        body{background:rgba(8,4,16,0.96);font-family:'Segoe UI',Arial,sans-serif;color:#b8a0d0;border-radius:12px;border:1px solid #4a2080;box-shadow:0 0 40px rgba(100,20,200,0.4);display:flex;flex-direction:column}
        #drag-bar{height:42px;padding:0 16px;font-size:14px;font-weight:600;color:#c8b0f0;border-bottom:1px solid #4a2080;cursor:grab;display:flex;align-items:center;justify-content:space-between;user-select:none;background:linear-gradient(180deg,rgba(30,10,50,0.98),rgba(20,5,35,0.98));flex-shrink:0;border-radius:12px 12px 0 0}
        #drag-bar:active{cursor:grabbing}.title{letter-spacing:0.5px}.hint{font-size:9px;color:#6040a0;font-weight:400}
        .body{display:flex;flex:1;background:rgba(12,6,22,0.96);overflow:hidden;border-radius:0 0 12px 12px}
        .content{display:flex;padding:14px;gap:14px;overflow-y:auto;flex:1}
        .col{flex:1;display:flex;flex-direction:column;gap:10px;min-width:0}
        .st{font-size:11px;font-weight:700;letter-spacing:1.5px;margin-bottom:4px;text-transform:uppercase;color:#7050b0}
        .sec{background:rgba(18,10,30,0.9);border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:10px;border:1px solid #302050}
        .row{display:flex;justify-content:space-between;align-items:center;font-size:13px;color:#c8b8e0;user-select:none;gap:12px}
        .tgl{position:relative;width:56px;height:28px;display:inline-block;cursor:pointer;flex-shrink:0}
        .tgl input{opacity:0;width:0;height:0;position:absolute}
        .sld{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:#2a1840;transition:0.2s;border-radius:28px}
        .sld:before{position:absolute;content:"";height:22px;width:22px;left:3px;bottom:3px;background:#6040a0;transition:0.2s;border-radius:50%}
        input:checked+.sld{background:#7c3aed;box-shadow:0 0 8px rgba(124,58,237,0.5)}
        input:checked+.sld:before{transform:translateX(28px);background:#fff}
        .rw{display:flex;align-items:center;gap:8px;flex:1;position:relative}
        .slider-wrap{position:relative;width:100%;height:22px}
        .slider-wrap input[type=range]{position:absolute;width:100%;top:50%;transform:translateY(-50%);-webkit-appearance:none;appearance:none;background:transparent;pointer-events:none;z-index:2;height:6px}
        .slider-wrap input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background:#7c3aed;cursor:pointer;pointer-events:auto;border:1px solid #a78bfa;box-shadow:0 0 6px rgba(124,58,237,0.4)}
        .slider-track-bg{position:absolute;top:50%;transform:translateY(-50%);width:100%;height:4px;background:#2a1840;border-radius:3px;z-index:1}
        .slider-track-fill{position:absolute;top:50%;transform:translateY(-50%);height:4px;background:#7c3aed;border-radius:3px;z-index:1;box-shadow:0 0 6px rgba(124,58,237,0.3)}
        .val{color:#8060c0;font-size:11px;min-width:32px;text-align:right;flex-shrink:0;font-variant-numeric:tabular-nums}
        .stat-val{font-weight:600;font-size:12px}
        .help{display:inline-block;width:16px;height:16px;border-radius:50%;background:#4a2080;color:#c8b0f0;text-align:center;line-height:16px;font-size:11px;font-weight:700;cursor:help;margin-left:4px;position:relative}
        .help:hover::after{content:attr(data-tip);position:absolute;left:22px;top:-6px;background:#1a0a2e;color:#fff;padding:6px 10px;border-radius:6px;font-size:11px;white-space:nowrap;z-index:10;border:1px solid #7c3aed;max-width:260px;white-space:normal}
        ::-webkit-scrollbar{width:4px}
        ::-webkit-scrollbar-track{background:#1a0a2e}
        ::-webkit-scrollbar-thumb{background:#4a2080;border-radius:4px}
    </style></head><body>
        <div id="drag-bar"><span class="title">⚔ EvoWare</span><span class="hint">INSERT toggle · Drag to move</span></div>
        <div class="body"><div class="content">
            <div class="col">
                <div><div class="st">Combat</div><div class="sec">
                    <div class="row"><span>Killaura<span class="help" data-tip="Auto-aim & attack enemies in range">?</span></span><label class="tgl"><input type="checkbox" id="tgl-killaura"><span class="sld"></span></label></div>
                    <div class="row"><span>Target Level</span><span class="val" id="val-lvlrange">0-100</span></div>
                    <div class="slider-wrap"><div class="slider-track-bg"></div><div class="slider-track-fill" id="track-lvl"></div><input type="range" id="rng-lvlmin" min="0" max="100" value="0" step="1"><input type="range" id="rng-lvlmax" min="0" max="100" value="100" step="1"></div>
                    <div class="row"><span>Dodge<span class="help" data-tip="Turn & boost away from threat">?</span></span><label class="tgl"><input type="checkbox" id="tgl-dodgeatk"><span class="sld"></span></label></div>
                    <div class="row"><span>Dodge on CD<span class="help" data-tip="Dodge only while attack recharging">?</span></span><label class="tgl"><input type="checkbox" id="tgl-dodgecd"><span class="sld"></span></label></div>
                    <div class="row"><span>Auto Respawn<span class="help" data-tip="Automatically clicks 'Play' after death">?</span></span><label class="tgl"><input type="checkbox" id="tgl-autorespawn"><span class="sld"></span></label></div>
                    <div class="row"><span>Swing Angle<span class="help" data-tip="Aim offset from target direction">?</span></span><div class="rw"><div class="slider-wrap"><div class="slider-track-bg"></div><div class="slider-track-fill" id="track-offset"></div><input type="range" id="rng-offset" min="0" max="360" value="135"></div><span class="val" id="val-offset">135°</span></div></div>
                </div></div>
                <div><div class="st">Visuals</div><div class="sec">
                    <div class="row"><span>Enemy Range<span class="help" data-tip="Show enemy attack radius">?</span></span><label class="tgl"><input type="checkbox" id="tgl-enemyrange"><span class="sld"></span></label></div>
                    <div class="row"><span>Attack Timer<span class="help" data-tip="Show enemy attack cooldown">?</span></span><label class="tgl"><input type="checkbox" id="tgl-cooldown"><span class="sld"></span></label></div>
                    <div class="row"><span>Tracers<span class="help" data-tip="Line to each enemy">?</span></span><label class="tgl"><input type="checkbox" id="tgl-tracers"><span class="sld"></span></label></div>
                    <div class="row"><span>Hitboxes<span class="help" data-tip="Show enemy collision size">?</span></span><label class="tgl"><input type="checkbox" id="tgl-hitboxes"><span class="sld"></span></label></div>
                    <div class="row"><span>Target Glow<span class="help" data-tip="Highlight current target">?</span></span><label class="tgl"><input type="checkbox" id="tgl-killable"><span class="sld"></span></label></div>
                </div></div>
            </div>
            <div class="col">
                <div><div class="st">Settings</div><div class="sec">
                    <div class="row"><span>Zoom<span class="help" data-tip="Adjust camera zoom">?</span></span><div class="rw"><div class="slider-wrap"><div class="slider-track-bg"></div><div class="slider-track-fill" id="track-zoom"></div><input type="range" id="rng-zoom" min="0.2" max="3" step="0.05" value="0.5"></div><span class="val" id="val-zoom">0.50x</span></div></div>
                </div></div>
                <div><div class="st">Info</div><div class="sec">
                    <div class="row"><span>Level</span><span class="stat-val" style="color:#a78bfa" id="txt-level">--</span></div>
                    <div class="row"><span>Range</span><span class="stat-val" style="color:#c084fc" id="txt-range">--</span></div>
                    <div class="row"><span>Target</span><span class="stat-val" style="color:#e879f9" id="txt-target">--</span></div>
                    <div class="row"><span>Nearby</span><span class="stat-val" style="color:#a78bfa" id="txt-nearby">0</span></div>
                    <div class="row"><span>Dodge</span><span class="stat-val" style="color:#4ade80" id="txt-safe">--</span></div>
                </div></div>
            </div>
        </div></div>
        <script>
            function S(t,d){window.parent.postMessage({evoware:1,type:t,data:d},'*')}
            const D=document.getElementById('drag-bar');let dr=false,sx,sy,sl,st;
            D.addEventListener('mousedown',function(e){if(e.target.tagName==='INPUT'||e.target.tagName==='LABEL')return;dr=true;sx=e.clientX;sy=e.clientY;const f=window.parent.document.getElementById('evoware-frame');sl=f.offsetLeft;st=f.offsetTop;e.preventDefault()});
            window.addEventListener('mousemove',function(e){if(!dr)return;const f=window.parent.document.getElementById('evoware-frame');let nx=sl+(e.clientX-sx),ny=st+(e.clientY-sy);nx=Math.max(0,Math.min(nx,window.parent.innerWidth-f.offsetWidth));ny=Math.max(0,Math.min(ny,window.parent.innerHeight-f.offsetHeight));f.style.left=nx+'px';f.style.top=ny+'px'});
            window.addEventListener('mouseup',function(){dr=false});
            function UR(r,t,min,max,vel,suf,cb){const v=parseFloat(r.value);t.style.left='0%';t.style.width=((v-min)/(max-min)*100)+'%';vel.textContent=(suf==='°'?parseInt(v):v.toFixed(2))+suf;if(cb)cb(v);}
            const rM=document.getElementById('rng-lvlmin'),rX=document.getElementById('rng-lvlmax'),tL=document.getElementById('track-lvl'),vL=document.getElementById('val-lvlrange');
            function uL(){let mn=parseInt(rM.value),mx=parseInt(rX.value);if(mn>mx){[mn,mx]=[mx,mn];rM.value=mn;rX.value=mx;}tL.style.left=(mn/100*100)+'%';tL.style.width=((mx-mn)/100*100)+'%';vL.textContent=mn+'-'+mx;S('lvlrange',{min:mn,max:mx});}
            rM.addEventListener('input',uL);rX.addEventListener('input',uL);uL();
            const rO=document.getElementById('rng-offset'),tO=document.getElementById('track-offset'),vO=document.getElementById('val-offset');UR(rO,tO,0,360,vO,'°',function(v){S('offset',v)});rO.addEventListener('input',function(){UR(rO,tO,0,360,vO,'°',function(v){S('offset',v)})});
            const rZ=document.getElementById('rng-zoom'),tZ=document.getElementById('track-zoom'),vZ=document.getElementById('val-zoom');UR(rZ,tZ,0.2,3,vZ,'x',function(v){S('zoom',v)});rZ.addEventListener('input',function(){UR(rZ,tZ,0.2,3,vZ,'x',function(v){S('zoom',v)})});
            document.getElementById('tgl-killaura').addEventListener('change',function(){S('killaura',this.checked)});
            document.getElementById('tgl-dodgeatk').addEventListener('change',function(){S('dodgeatk',this.checked)});
            document.getElementById('tgl-dodgecd').addEventListener('change',function(){S('dodgecd',this.checked)});
            document.getElementById('tgl-autorespawn').addEventListener('change',function(){S('autorespawn',this.checked)});
            document.getElementById('tgl-enemyrange').addEventListener('change',function(){S('enemyrange',this.checked)});
            document.getElementById('tgl-cooldown').addEventListener('change',function(){S('cooldown',this.checked)});
            document.getElementById('tgl-tracers').addEventListener('change',function(){S('tracers',this.checked)});
            document.getElementById('tgl-hitboxes').addEventListener('change',function(){S('hitboxes',this.checked)});
            document.getElementById('tgl-killable').addEventListener('change',function(){S('killable',this.checked)});
            window.addEventListener('message',function(e){if(!e.data||!e.data.evoware)return;if(e.data.type==='updateStats'){document.getElementById('txt-level').textContent=e.data.level;document.getElementById('txt-range').textContent=e.data.range;document.getElementById('txt-target').textContent=e.data.target;document.getElementById('txt-nearby').textContent=e.data.nearby;document.getElementById('txt-safe').textContent=e.data.safe}if(e.data.type==='updateKillaura')document.getElementById('tgl-killaura').checked=e.data.checked;if(e.data.type==='updateAutorespawn')document.getElementById('tgl-autorespawn').checked=e.data.checked});
        <\/script></body></html>`);
    doc.close();

    // ──────────────────────────────────────────────────────────────
    //  GLOBALS
    // ──────────────────────────────────────────────────────────────
    let rt, pType, gameCanvas;
    let showTracers = false, showHitboxes = false, showKillable = false, showEnemyRange = false, showCooldown = false;
    let killaura = false, dodgeAttacks = false, dodgeOnCD = false;
    let autoRespawn = false;
    let offset = 135, zoomLevel = 0.5, lvlMin = 0, lvlMax = 100;
    let target = null, targetLevel = 0, menuVisible = true;
    let lastDodge = 0, dodgeCD = 2000;
    let enemyTimers = new Map(), gameStartTime = 0;
    let enemyPrevAngle = new Map();
    let nc = 0, ss = '--';
    let lastRespawnTry = 0;
    let boostTimeout = null;

    // ──────────────────────────────────────────────────────────────
    //  UTILITIES
    // ──────────────────────────────────────────────────────────────
    const getAttackCooldown = (level) => Math.max(100, level * 100);

    function applyZoom() {
        if (rt?.running_layout?.layers) {
            for (const l of rt.running_layout.layers) {
                if (l?.scale !== undefined) { l.scale = zoomLevel; if (l.setZIndicesStaleFrom) l.setZIndicesStaleFrom(0); }
            }
            rt.redraw = true;
        }
    }

    function gs(obj) {
        if (!obj) return { lv: 0, sz: 0, rng: 0 };
        let lv = 0, sz = obj.width || 0;
        try {
            if (obj.instance_vars) {
                let lvs = [];
                for (let i = 0; i < obj.instance_vars.length; i++) {
                    const v = obj.instance_vars[i];
                    if (typeof v === 'number' && v >= 1 && v <= 200 && Number.isInteger(v)) lvs.push({ i, v });
                }
                if (lvs.length) {
                    lvs.sort((a, b) => b.v - a.v);
                    const early = lvs.filter(l => l.i < 15);
                    lv = early.length >= 2 ? early[1].v : (early.length === 1 ? early[0].v + 1 : lvs[0].v + 1);
                }
            }
        } catch (e) {}
        if (!lv && sz > 0) lv = Math.max(1, Math.floor(sz / 3.5));
        return { lv, sz, rng: sz * 2.2 };
    }

    function getPlayer() {
        if (!rt?.running_layout || !pType) return null;
        const instances = pType.instances;
        let self = null, md = Infinity;
        for (let i = 0; i < instances.length; i++) {
            const p = instances[i]; if (!p) continue;
            const d = Math.hypot(p.x - rt.running_layout.scrollX, p.y - rt.running_layout.scrollY);
            if (d < md && d < 500) { md = d; self = p; }
        }
        return self;
    }

    function sendStats() {
        const self = getPlayer();
        const ps = self ? gs(self) : null;
        iframe.contentWindow.postMessage({
            evoware: 1, type: 'updateStats',
            level: 'Lv.' + (ps ? ps.lv : '--'),
            range: ps ? Math.floor(ps.rng) + 'u' : '--',
            target: targetLevel > 0 ? 'Lv.' + targetLevel : '--',
            nearby: nc, safe: ss
        }, '*');
    }

    function simMouse(type, clientX, clientY, button = 0, buttons = 0) {
        if (!gameCanvas) return;
        const opts = { bubbles: true, cancelable: true, view: window, clientX, clientY, button, buttons };
        gameCanvas.dispatchEvent(new MouseEvent(type, opts));
        document.dispatchEvent(new MouseEvent(type, opts));
    }

    // ──────────────────────────────────────────────────────────────
    //  KILLAURA – only when enemy is within range, aim+click, no teleport
    // ──────────────────────────────────────────────────────────────
    function killAll() {
        const self = getPlayer(); if (!self) return;
        const ps = gs(self); if (!ps) return;
        const rect = gameCanvas.getBoundingClientRect();
        const sc = self.layer.getScale();
        const vx = rect.left + rect.width/2, vy = rect.top + rect.height/2;
        const instances = pType.instances;

        // Find the closest enemy within attack range
        let bestTarget = null;
        let bestDist = Infinity;
        for (let i = 0; i < instances.length; i++) {
            const p = instances[i]; if (!p || p.uid === self.uid) continue;
            if (p.width <= 0) continue;
            const dist = Math.hypot(p.x - self.x, p.y - self.y);
            if (dist > ps.rng) continue; // only enemies in range
            const es = gs(p);
            if (es.lv < lvlMin || es.lv > lvlMax) continue;
            if (dist < bestDist) {
                bestDist = dist;
                bestTarget = p;
            }
        }
        if (!bestTarget) { target = null; targetLevel = 0; return; }
        target = bestTarget;
        targetLevel = gs(target).lv;

        // Aim with offset
        const dx = target.x - self.x, dy = target.y - self.y;
        const angleToTarget = Math.atan2(dy, dx);
        const offsetRad = (offset * Math.PI) / 180;
        self.angle = ((angleToTarget + offsetRad) % (Math.PI * 2) + (Math.PI * 2)) % (Math.PI * 2);

        // Click on target screen position
        const sx = vx + (target.x - self.x) * sc;
        const sy = vy + (target.y - self.y) * sc;
        simMouse('mousedown', sx, sy, 0, 1);
        simMouse('mouseup', sx, sy, 0, 0);
    }

    // ──────────────────────────────────────────────────────────────
    //  NATURAL DODGE – 180° turn + boost away (unchanged)
    // ──────────────────────────────────────────────────────────────
    function detectThreats(self) {
        if (!self || !pType) return [];
        const threats = []; const instances = pType.instances;
        for (let i = 0; i < instances.length; i++) {
            const p = instances[i]; if (!p || p.uid === self.uid) continue;
            if (p.width <= 0) continue;
            const dx = p.x - self.x, dy = p.y - self.y, dist = Math.hypot(dx, dy);
            const es = gs(p);
            if (dist > es.rng * 2.5) continue;
            const angle = p.angle || 0; const prev = enemyPrevAngle.get(p.uid);
            if (prev !== undefined) {
                const angleDiff = Math.abs(angle - prev);
                const ndiff = Math.min(angleDiff, Math.PI * 2 - angleDiff);
                if (ndiff > 0.2) {
                    const angleToUs = Math.atan2(dy, dx);
                    const facingUs = Math.abs(angle - angleToUs) < 0.7;
                    if (facingUs || dist < es.rng * 1.2) {
                        threats.push({ dx, dy, dist, es });
                    }
                }
            }
            enemyPrevAngle.set(p.uid, angle);
        }
        const alive = new Set(); for (let i = 0; i < instances.length; i++) { const p = instances[i]; if (p && p.uid && p.width > 0) alive.add(p.uid); }
        for (const uid of enemyPrevAngle.keys()) { if (!alive.has(uid)) enemyPrevAngle.delete(uid); }
        return threats;
    }

    function dodge(self) {
        if (!self || !pType || !dodgeAttacks) { ss = '--'; return; }
        const now = performance.now();
        if (now - lastDodge < dodgeCD) { ss = '⏳ CD'; return; }
        if (dodgeOnCD && now - lastDodge < 400) {} else if (dodgeOnCD) { ss = '✓ Ready'; return; }

        const threats = detectThreats(self);
        if (threats.length === 0) { ss = dodgeOnCD ? '✓ Waiting' : '✓ Safe'; return; }

        let totalX = 0, totalY = 0;
        for (const t of threats) {
            const dist = Math.hypot(t.dx, t.dy);
            if (dist < 0.01) continue;
            const weight = Math.max(0, (t.es.rng * 1.3 - dist) / (t.es.rng * 1.3));
            totalX += (t.dx / dist) * weight;
            totalY += (t.dy / dist) * weight;
        }
        const threatMag = Math.hypot(totalX, totalY);
        if (threatMag > 0.01) {
            const escapeAngle = Math.atan2(-totalY, -totalX);
            self.angle = escapeAngle;
            const pushStrength = Math.min(12, threatMag * 8);
            const pushX = -totalX / threatMag * pushStrength;
            const pushY = -totalY / threatMag * pushStrength;
            self.x += pushX;
            self.y += pushY;
            if (rt?.running_layout) {
                rt.running_layout.scrollX += pushX;
                rt.running_layout.scrollY += pushY;
            }
        }

        if (boostTimeout) clearTimeout(boostTimeout);
        const rect = gameCanvas.getBoundingClientRect();
        const cx = rect.left + rect.width/2;
        const cy = rect.top + rect.height/2;
        simMouse('mousedown', cx, cy, 2, 2);
        boostTimeout = setTimeout(() => {
            simMouse('mouseup', cx, cy, 2, 0);
            boostTimeout = null;
        }, 250);

        lastDodge = now;
        ss = '💨 Boost away';
    }

    // ──────────────────────────────────────────────────────────────
    //  AUTO RESPAWN (unchanged)
    // ──────────────────────────────────────────────────────────────
    function tryRespawn() {
        const now = performance.now();
        if (now - lastRespawnTry < 2500) return;
        lastRespawnTry = now;
        const rect = gameCanvas.getBoundingClientRect();
        const cx = rect.left + rect.width/2;
        const cy = rect.top + rect.height/2;
        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', keyCode: 13, bubbles: true }));
        document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', keyCode: 13, bubbles: true }));
        const offsets = [0, -30, 30, -60, 60];
        offsets.forEach((offY, idx) => {
            setTimeout(() => {
                simMouse('mousedown', cx, cy + offY, 0, 1);
                simMouse('mouseup', cx, cy + offY, 0, 0);
            }, idx * 80);
        });
    }

    // ──────────────────────────────────────────────────────────────
    //  TIMERS & ESP (unchanged)
    // ──────────────────────────────────────────────────────────────
    function updateTimers() {
        if (!pType || !gameStartTime) return;
        const instances = pType.instances;
        for (let i = 0; i < instances.length; i++) {
            const p = instances[i]; if (!p || !p.uid || p.width <= 0) continue;
            if (!enemyTimers.has(p.uid)) {
                const es = gs(p);
                enemyTimers.set(p.uid, { cd: getAttackCooldown(es.lv) });
            }
        }
        const alive = new Set(); for (let i = 0; i < instances.length; i++) { const p = instances[i]; if (p && p.uid && p.width > 0) alive.add(p.uid); }
        for (const uid of enemyTimers.keys()) { if (!alive.has(uid)) enemyTimers.delete(uid); }
    }

    const esp = document.createElement('canvas');
    const ctx = esp.getContext('2d');
    esp.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:999998;';
    esp.width = innerWidth; esp.height = innerHeight;
    document.body.appendChild(esp);
    window.addEventListener('resize', () => { esp.width = innerWidth; esp.height = innerHeight; });

    function draw() {
        if (!rt?.running_layout || !pType) return;
        const now = performance.now(), instances = pType.instances;
        const self = getPlayer(); if (!self) return;
        const ps = gs(self), rect = gameCanvas.getBoundingClientRect();
        const vx = rect.left + rect.width / 2, vy = rect.top + rect.height / 2, sc = self.layer.getScale();
        ctx.clearRect(0, 0, esp.width, esp.height);
        let nearby = 0;
        if (dodgeAttacks) {
            const sr = Math.max(ps.rng, 80) * 1.5 * sc;
            ctx.beginPath(); ctx.arc(vx, vy, sr, 0, Math.PI * 2);
            ctx.strokeStyle = dodgeOnCD ? "rgba(251,191,36,0.4)" : "rgba(74,222,128,0.4)";
            ctx.lineWidth = 2; ctx.setLineDash([5, 5]); ctx.stroke(); ctx.setLineDash([]);
        }
        if (killaura) {
            ctx.beginPath(); ctx.arc(vx, vy, ps.rng * sc, 0, Math.PI * 2);
            ctx.strokeStyle = "rgba(124,58,237,0.3)"; ctx.lineWidth = 1.5;
            ctx.setLineDash([4, 4]); ctx.stroke(); ctx.setLineDash([]);
        }
        if (killaura && target) {
            const angle = self.angle || 0, bl2 = (ps.sz * 0.9) * sc;
            const dx = target.x - self.x, dy = target.y - self.y, da = Math.atan2(dy, dx);
            ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(vx + Math.cos(da) * bl2, vy + Math.sin(da) * bl2);
            ctx.strokeStyle = "rgba(255,255,255,0.4)"; ctx.lineWidth = 1.5; ctx.setLineDash([2, 2]); ctx.stroke(); ctx.setLineDash([]);
            ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(vx + Math.cos(angle) * bl2, vy + Math.sin(angle) * bl2);
            ctx.strokeStyle = "#a855f7"; ctx.lineWidth = 3; ctx.stroke();
            const or2 = (offset * Math.PI) / 180;
            ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(vx + Math.cos(da + or2) * bl2, vy + Math.sin(da + or2) * bl2);
            ctx.strokeStyle = "#22c55e"; ctx.lineWidth = 2; ctx.setLineDash([3, 3]); ctx.stroke(); ctx.setLineDash([]);
        }
        for (let i = 0; i < instances.length; i++) {
            const p = instances[i]; if (!p || p.uid === self.uid) continue;
            if (p.width <= 0) continue;
            const es = gs(p);
            if (es.lv <= 0) continue;
            const px = vx + (p.x - self.x) * sc, py = vy + (p.y - self.y) * sc;
            const dist = Math.hypot(p.x - self.x, p.y - self.y), inRng = dist <= ps.rng;
            const killable = es.lv <= ps.lv, danger = es.lv > ps.lv * 1.3;
            if (inRng) nearby++;
            if (showCooldown) {
                const t = enemyTimers.get(p.uid);
                if (t) {
                    const elapsed = (now - gameStartTime) % t.cd;
                    const remaining = t.cd - elapsed, pct = elapsed / t.cd;
                    ctx.beginPath(); ctx.arc(px, py, 28, 0, Math.PI * 2);
                    ctx.strokeStyle = "rgba(255,255,255,0.08)"; ctx.lineWidth = 2.5; ctx.stroke();
                    ctx.beginPath(); ctx.arc(px, py, 28, -Math.PI / 2, -Math.PI / 2 + Math.PI * 2 * pct);
                    ctx.strokeStyle = pct < 0.15 ? "#22c55e" : "#f59e0b"; ctx.lineWidth = 2.5; ctx.stroke();
                    ctx.fillStyle = "#fff"; ctx.font = "bold 9px Arial"; ctx.textAlign = "center";
                    ctx.fillText((remaining / 1000).toFixed(1) + "s", px, py - 34);
                }
            }
            if (showKillable && inRng) {
                ctx.beginPath(); ctx.arc(px, py, 22, 0, Math.PI * 2);
                if (killable) {
                    ctx.shadowColor = "#22c55e"; ctx.shadowBlur = 15;
                    ctx.strokeStyle = "#22c55e"; ctx.lineWidth = 3; ctx.stroke(); ctx.shadowBlur = 0;
                } else if (danger) {
                    ctx.shadowColor = "#ef4444"; ctx.shadowBlur = 15;
                    ctx.strokeStyle = "#ef4444"; ctx.lineWidth = 3; ctx.setLineDash([4, 4]); ctx.stroke(); ctx.setLineDash([]); ctx.shadowBlur = 0;
                }
            }
            if (showEnemyRange && es.rng > 0) {
                ctx.beginPath(); ctx.arc(px, py, es.rng * sc, 0, Math.PI * 2);
                ctx.strokeStyle = dist < es.rng ? "rgba(255,60,60,0.9)" : "rgba(255,60,60,0.5)";
                ctx.lineWidth = 2;
                ctx.setLineDash([2, 2]); ctx.stroke(); ctx.setLineDash([]);
            }
            if (showHitboxes) {
                const r = (p.width / 2) * sc * 1.5;
                ctx.beginPath(); ctx.arc(px, py, r, 0, Math.PI * 2);
                ctx.fillStyle = killable ? "rgba(34,197,94,0.08)" : "rgba(124,58,237,0.08)"; ctx.fill();
                ctx.strokeStyle = killable ? "#22c55e" : "#a855f7"; ctx.lineWidth = 1; ctx.stroke();
            }
            if (showTracers) {
                ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(px, py);
                ctx.strokeStyle = inRng ? (killable ? "rgba(34,197,94,0.6)" : "rgba(168,85,247,0.5)") : "rgba(168,85,247,0.12)";
                ctx.lineWidth = inRng ? 1.5 : 0.5; ctx.stroke();
            }
            if (killaura && target && p.uid === target.uid) {
                ctx.beginPath(); ctx.arc(px, py, 26, 0, Math.PI * 2);
                ctx.strokeStyle = "#a855f7"; ctx.lineWidth = 2.5; ctx.setLineDash([3, 3]); ctx.stroke(); ctx.setLineDash([]);
                ctx.fillStyle = "#fff"; ctx.font = "bold 10px Arial"; ctx.textAlign = "center";
                ctx.fillText("Lv." + es.lv, px, py - 30);
            }
        }
        nc = nearby; sendStats();
    }

    // ──────────────────────────────────────────────────────────────
    //  MAIN LOOP
    // ──────────────────────────────────────────────────────────────
    function loop() {
        try {
            if (rt?.running_layout) {
                if (!gameStartTime) gameStartTime = performance.now();
                applyZoom();
                updateTimers();
                const needDraw = showTracers || showHitboxes || showKillable || showEnemyRange || showCooldown || killaura || dodgeAttacks;
                if (needDraw) draw(); else ctx.clearRect(0, 0, esp.width, esp.height);
                if (pType) {
                    const self = getPlayer();
                    if (self) {
                        if (killaura) killAll();
                        let enemiesRemain = false;
                        if (killaura && dodgeAttacks && self) {
                            const ps = gs(self);
                            const instances = pType.instances;
                            for (let i = 0; i < instances.length; i++) {
                                const p = instances[i];
                                if (!p || p.uid === self.uid) continue;
                                if (p.width <= 0) continue;
                                const dist = Math.hypot(p.x - self.x, p.y - self.y);
                                if (dist <= ps.rng) {
                                    const es = gs(p);
                                    if (es.lv >= lvlMin && es.lv <= lvlMax) {
                                        enemiesRemain = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (dodgeAttacks && killaura && enemiesRemain) {
                            dodge(self);
                        }
                    } else {
                        if (autoRespawn) tryRespawn();
                    }
                }
            }
        } catch (e) {}
        requestAnimationFrame(loop);
    }

    // ──────────────────────────────────────────────────────────────
    //  INIT
    // ──────────────────────────────────────────────────────────────
    const init = setInterval(() => {
        if (window.cr_getC2Runtime && (rt = window.cr_getC2Runtime())) {
            clearInterval(init);
            gameCanvas = rt.canvas;
            for (const t of rt.types_by_index) {
                if (t?.instvar_sids?.length === 72) { pType = t; break; }
            }
            if (!pType) {
                for (const t of rt.types_by_index) {
                    if (t?.instances?.length > 0) {
                        const i = t.instances[0];
                        if (i.x !== undefined && i.y !== undefined && i.width !== undefined && i.angle !== undefined) {
                            pType = t; break;
                        }
                    }
                }
            }
            loop();
        }
    }, 500);

    // ──────────────────────────────────────────────────────────────
    //  MESSAGE HANDLER
    // ──────────────────────────────────────────────────────────────
    window.addEventListener('message', function(e) {
        if (!e.data || !e.data.evoware) return;
        switch (e.data.type) {
            case 'killaura': killaura = e.data.data; if (!killaura) { target = null; targetLevel = 0; } break;
            case 'dodgeatk': dodgeAttacks = e.data.data; break;
            case 'dodgecd': dodgeOnCD = e.data.data; break;
            case 'autorespawn': autoRespawn = e.data.data; break;
            case 'lvlrange': lvlMin = e.data.data.min; lvlMax = e.data.data.max; break;
            case 'enemyrange': showEnemyRange = e.data.data; break;
            case 'cooldown': showCooldown = e.data.data; break;
            case 'tracers': showTracers = e.data.data; break;
            case 'hitboxes': showHitboxes = e.data.data; break;
            case 'killable': showKillable = e.data.data; break;
            case 'offset': offset = e.data.data; break;
            case 'zoom': zoomLevel = e.data.data; break;
        }
    });

    // ──────────────────────────────────────────────────────────────
    //  KEYBINDINGS (INSERT toggles menu)
    // ──────────────────────────────────────────────────────────────
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Insert') {
            e.preventDefault(); e.stopPropagation();
            menuVisible = !menuVisible;
            iframe.style.opacity = menuVisible ? '1' : '0';
            iframe.style.pointerEvents = menuVisible ? 'auto' : 'none';
        }
    }, true);
})();