omoggle MAX score

ONE switch + typed target score / fluctuate range (7.5-10). Three hooks (vision-wasm, detectForVideo, signed-frame) feed a flawless face the server scores at your chosen value. Camera-safe. Join Discord for updates, community, and the upcoming premium script!

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         omoggle MAX score
// @namespace    https://omoggle.com/
// @version      4.7.0
// @description  ONE switch + typed target score / fluctuate range (7.5-10). Three hooks (vision-wasm, detectForVideo, signed-frame) feed a flawless face the server scores at your chosen value. Camera-safe. Join Discord for updates, community, and the upcoming premium script!
// @match        https://omoggle.com/*
// @match        https://*.omoggle.com/*
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';
    const W = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;
    const VER = '4.7.0';

    const LS_KEY = 'omog_max_v2';
    const DEFAULTS = { enabled: true, mode: 'range', target: 9.6, rangeMin: 9.0, rangeMax: 9.9, wanderStep: 0.05, jitter: true, jitterAmt: 0.0008, stream: 'face_landmarks', debug: true, logEveryN: 90 };
    let CFG; try { CFG = Object.assign({}, DEFAULTS, JSON.parse(W.localStorage.getItem(LS_KEY) || '{}')); } catch (e) { CFG = Object.assign({}, DEFAULTS); }
    const saveCfg = () => { try { W.localStorage.setItem(LS_KEY, JSON.stringify(CFG)); } catch (e) {} };

    const LOGS = [];
    function rec(tag, msg, data) { LOGS.push({ t: Date.now(), tag, msg, data }); if (LOGS.length > 1000) LOGS.shift(); if (CFG.debug) { try { console.log('%c[OMG]%c ' + tag + ' ' + msg, 'color:#9cf;font-weight:bold', '', data !== undefined ? data : ''); } catch (e) {} } }

    // ==================== IDEAL FACE (offline-verified 9.4 "perfect" at all aspects) ====================
    const PARAMS = { FH: 0.62, FW: 0.3940, JW: 0.3597, JY: 0.26, EY: 0.058, IH: 0.05, EW: 0.0969, EH: 0.0290, T: 0.0005, MOUTH: 0.2103 };
    function genNorm(P) {
        const lm = []; for (let i = 0; i < 478; i++) lm.push({ x: 0.5, y: 0.5, z: 0 });
        const cx = 0.5, cy = 0.5, set = (li, ri, hw, yy) => { lm[li] = { x: cx - hw, y: yy, z: 0 }; lm[ri] = { x: cx + hw, y: yy, z: 0 }; };
        lm[10] = { x: cx, y: cy - P.FH / 2, z: 0 }; lm[152] = { x: cx, y: cy + P.FH / 2, z: 0 };
        lm[234] = { x: cx - P.FW / 2, y: cy, z: 0 }; lm[454] = { x: cx + P.FW / 2, y: cy, z: 0 };
        set(172, 397, P.JW / 2, cy + P.JY); set(150, 379, P.JW / 2, cy + P.JY * 0.9); set(171, 396, P.JW / 2, cy + P.JY * 1.1);
        const eyeY = cy - P.EY;
        lm[133] = { x: cx - P.IH, y: eyeY, z: 0 }; lm[33] = { x: cx - P.IH - P.EW, y: eyeY - P.T, z: 0 };
        lm[362] = { x: cx + P.IH, y: eyeY, z: 0 }; lm[263] = { x: cx + P.IH + P.EW, y: eyeY - P.T, z: 0 };
        const lcx = cx - P.IH - P.EW / 2, rcx = cx + P.IH + P.EW / 2;
        lm[159] = { x: lcx, y: eyeY - P.EH / 2, z: 0 }; lm[145] = { x: lcx, y: eyeY + P.EH / 2, z: 0 };
        lm[386] = { x: rcx, y: eyeY - P.EH / 2, z: 0 }; lm[374] = { x: rcx, y: eyeY + P.EH / 2, z: 0 };
        lm[1] = { x: cx, y: cy, z: 0 }; lm[0] = { x: cx, y: eyeY + P.MOUTH, z: 0 };
        const fill = [[70, 300, .18, -.12], [63, 293, .14, -.14], [105, 334, .10, -.16], [46, 276, .20, -.10], [116, 345, .22, .02], [123, 352, .20, .06], [50, 280, .18, .10], [187, 411, .16, .16], [132, 361, .24, 0], [174, 399, .06, .20], [136, 365, .12, .20], [148, 377, .08, .24], [176, 401, .10, .22], [58, 288, .22, -.04]];
        for (const f of fill) { lm[f[0]] = { x: cx - f[2], y: cy + f[3], z: 0 }; lm[f[1]] = { x: cx + f[2], y: cy + f[3], z: 0 }; }
        return lm;
    }
    const _NORM = genNorm(PARAMS);
    const PEAK_DELTAS = { 0: [0.00238, -0.00148], 133: [-0.00537, -0.00507], 159: [0.00489, 0.00189], 176: [0.00392, -0.00571], 187: [0.00433, 0.00566], 293: [0.00167, -0.00274], 352: [-0.00052, 0.00213], 362: [0.00571, 0.00174], 386: [0.00402, 0.00377] };
    const LOW_DELTAS = { 0: [-0.00589, 0.00354], 33: [0.0024, -0.00215], 50: [-0.00312, -0.00189], 58: [-0.0075, -0.00572], 105: [-0.00128, 0.00165], 116: [-0.00368, 0.0027], 123: [0.00578, 0.00299], 145: [0.00243, 0.00522], 159: [0.00304, -0.00501], 171: [0.00375, -0.0019], 263: [-0.00048, 0.00605], 300: [-0.00572, 0.00073], 334: [0.00191, -0.00197], 352: [0.0001, 0.00005], 365: [0.00352, -0.0045], 374: [0.00455, -0.00071], 377: [0.00595, 0.00473], 379: [-0.00028, 0.00566], 386: [-0.00027, -0.016], 399: [-0.00495, -0.00209], 401: [0.00373, -0.00379] };
    function applyD(d) { const a = _NORM.map(p => ({ x: p.x, y: p.y, z: 0 })); for (const k in d) a[+k] = { x: _NORM[+k].x + d[k][0], y: _NORM[+k].y + d[k][1], z: 0 }; return a; }
    const _LOW = applyD(LOW_DELTAS), _PEAK = applyD(PEAK_DELTAS);
    function faceL(L) { return _LOW.map((p, i) => ({ x: p.x + (_PEAK[i].x - p.x) * L, y: p.y + (_PEAK[i].y - p.y) * L, z: 0 })); }

    const _WP = [[33, 263], [133, 362], [70, 300], [63, 293], [105, 334], [46, 276], [116, 345], [123, 352], [50, 280], [187, 411], [132, 361], [174, 399], [150, 379], [172, 397], [136, 365], [171, 396], [148, 377], [176, 401], [58, 288]];
    const _F = (a, b) => Math.hypot(a.x - b.x, a.y - b.y), _L = (a, b) => Math.atan2(b.y - a.y, b.x - a.x) * 57.29578, _O = (e, t, r) => Math.max(t, Math.min(r, e));
    const _B = (e, t, r, a, n) => e >= t && e <= r ? 10 : e < t ? _O((e - a) / (t - a) * 10, 0, 10) : _O((n - e) / (n - r) * 10, 0, 10);
    function simpleScore(p) {
        const m = -((_L(p[33], p[133]) + _L(p[362], p[263])) / 2); let jx = 0; for (const pr of [[172, 397], [150, 379], [171, 396]]) { const r = _F(p[pr[0]], p[pr[1]]); if (r > jx) jx = r; }
        const h = _F(p[234], p[454]), f = _F(p[10], p[152]), g = jx, b = f > 0 ? g / f : 0, v = (p[133].x + p[362].x) / 2, w = (p[10].y + p[152].y) / 2; let _ = 0;
        for (const pr of _WP) { const r = p[pr[0]], q = p[pr[1]]; _ += (h > 0 ? Math.abs(Math.abs(r.x - v) - Math.abs(q.x - v)) / h : 0) + (f > 0 ? Math.abs(Math.abs(r.y - w) - Math.abs(q.y - w)) / f : 0); }
        const y = Math.round((1 - _O(_ / (2 * _WP.length) / .09, 0, 1)) * 100), k = (p[133].y + p[33].y) / 2, j = (p[362].y + p[263].y) / 2, Nl = (k + j) / 2;
        const C = Math.abs(p[0].y - Nl), S = f > 0 ? C / f : 0, E = g > 0 ? _F(p[234], p[454]) / g : 0, R = _F(p[33], p[133]), Ih = _F(p[159], p[145]), Mw = _F(p[263], p[362]), Uh = _F(p[386], p[374]);
        const z = Math.max(.2, ((R > 0 ? Ih / R : 0) + (Mw > 0 ? Uh / Mw : 0)) / 2), H = h > 0 ? _F(p[133], p[362]) / h : 0;
        const G = _B(m, 2, 6.5, -2, 11), Y = _B(b, .58, .78, .42, .96), q = _B(S, .27, .34, .2, .43), V = _B(E, 1.04, 1.24, .86, 1.48), K = _B(z, .22, .3, .18, .43);
        const J = Math.round((.18 * Y + .24 * q + .18 * V + .16 * K + .24 * _B(H, .22, .31, .15, .42)) * 10) / 10;
        return _O(.12 * G + .14 * Y + y / 10 * .24 + .14 * q + .1 * V + .08 * K + .18 * J, 1.1, 10);
    }
    const _TBL = []; for (let L = 0; L <= 1.0001; L += 0.02) _TBL.push([L, simpleScore(faceL(L))]);
    const SCORE_MIN = _TBL[0][1], SCORE_MAX = _TBL[_TBL.length - 1][1];
    function solveL(score) {
        score = Math.max(SCORE_MIN, Math.min(SCORE_MAX, score));
        for (let i = 0; i < _TBL.length - 1; i++) { const a = _TBL[i], b = _TBL[i + 1]; if (score >= a[1] && score <= b[1]) { const f = (score - a[1]) / ((b[1] - a[1]) || 1); return a[0] + (b[0] - a[0]) * f; } }
        return 1;
    }
    let _tgt = null;
    function nextBase() {
        let target;
        if (CFG.mode === 'range') {
            const lo = Math.min(CFG.rangeMin, CFG.rangeMax), hi = Math.max(CFG.rangeMin, CFG.rangeMax);
            if (_tgt === null) _tgt = (lo + hi) / 2;
            _tgt += (Math.random() - 0.5) * CFG.wanderStep;
            if (_tgt < lo) _tgt = 2 * lo - _tgt; if (_tgt > hi) _tgt = 2 * hi - _tgt;
            target = _tgt;
        } else target = CFG.target;
        return faceL(solveL(target));
    }
    let _aspect = 4 / 3, _aspT = 0;
    function getAspect() {
        const now = Date.now(); if (now - _aspT < 1000) return _aspect; _aspT = now;
        try {
            let best = document.querySelector('video.scanner-video');
            if (!(best && best.videoWidth > 0)) { best = null; document.querySelectorAll('video').forEach(v => { if (v.videoWidth > 0 && v.videoHeight > 0 && (!best || v.videoWidth * v.videoHeight > best.videoWidth * best.videoHeight)) best = v; }); }
            if (best && best.videoWidth > 0) _aspect = best.videoWidth / best.videoHeight;
        } catch (e) {}
        return _aspect;
    }
    function idealObjects(aspect) {
        const a = aspect || getAspect(), j = CFG.jitter ? CFG.jitterAmt : 0, cx = 0.5;
        return nextBase().map(p => ({ x: cx + (p.x - cx) / a + (Math.random() - 0.5) * j, y: p.y + (Math.random() - 0.5) * j, z: 0 }));
    }
    function encodeLM(lms) {
        const b = new Uint8Array(lms.length * 17), dv = new DataView(b.buffer);
        for (let i = 0; i < lms.length; i++) { const o = i * 17; b[o] = 0x0a; b[o + 1] = 0x0f; b[o + 2] = 0x0d; dv.setFloat32(o + 3, lms[i].x, true); b[o + 7] = 0x15; dv.setFloat32(o + 8, lms[i].y, true); b[o + 12] = 0x1d; dv.setFloat32(o + 13, lms[i].z, true); }
        return b;
    }

    let _calls = 0, _how = '';
    function bump(how) { _calls++; if (_calls % CFG.logEveryN === 1) rec('MAX', 'feeding flawless face via ' + how, { frame: _calls, aspect: +getAspect().toFixed(2) }); }

    // ==================== HOOK 1: vision-wasm ModuleFactory ====================
    let _hookedWasm = false, _mf;
    const TD = new TextDecoder('utf-8');
    function ptrToStr(mod, ptr) { if (typeof ptr === 'string') return ptr; const H = mod.HEAPU8; if (!H || typeof ptr !== 'number') return ''; let e = ptr; while (e < H.length && H[e] !== 0) e++; try { return TD.decode(H.subarray(ptr, e)); } catch (x) { return ''; } }
    function installWasm(mod) {
        if (!mod || mod.__omg) return; mod.__omg = true;
        const dispatch = function (namePtr) {
            const args = Array.prototype.slice.call(arguments, 1); let name = ''; try { name = ptrToStr(mod, namePtr); } catch (e) {}
            try { if (CFG.enabled && name === CFG.stream && args[0] instanceof Uint8Array) { args[0] = encodeLM(idealObjects()); bump('wasm'); } } catch (e) {}
            try { const SL = mod.simpleListeners; if (SL && SL[name]) return SL[name].apply(null, args); } catch (e) {}
        };
        try { Object.defineProperty(mod, '_wrapSimpleListenerOutput', { configurable: true, get() { return dispatch; }, set() {} }); } catch (e) { mod._wrapSimpleListenerOutput = dispatch; }
        _hookedWasm = true; rec('MAX', 'HOOK1 vision-wasm armed ✓');
    }
    function wrapFactory(orig) {
        if (typeof orig !== 'function' || orig.__omg) return orig;
        const wrapped = function () { let r; try { r = orig.apply(this, arguments); } catch (e) { throw e; } Promise.resolve(r).then(m => { try { installWasm(m); } catch (e) {} }).catch(() => {}); return r; };
        wrapped.__omg = true; return wrapped;
    }
    try { Object.defineProperty(W, 'ModuleFactory', { configurable: true, get() { return _mf; }, set(v) { _mf = wrapFactory(v); rec('MAX', 'ModuleFactory trapped'); } }); rec('MAX', 'HOOK1 ModuleFactory accessor armed'); }
    catch (e) { rec('MAX', 'HOOK1 trap failed', '' + e); }

    // ==================== HOOK 2: FaceLandmarker.detectForVideo ====================
    let _hookedDFV = false, _req = null;
    function wrapDFV(proto) {
        if (!proto || proto.__omgD) return false; const orig = proto.detectForVideo; if (typeof orig !== 'function') return false;
        proto.detectForVideo = function () {
            if (CFG.enabled) {
                try {
                    const vf = arguments[0]; let vw = 0, vh = 0; try { vw = vf.videoWidth || vf.width || 0; vh = vf.videoHeight || vf.height || 0; } catch (e) {}
                    const res = { faceLandmarks: [idealObjects(vw > 0 && vh > 0 ? vw / vh : 0)], faceBlendshapes: [], facialTransformationMatrixes: [] };
                    bump('detectForVideo'); const cb = arguments[2]; if (typeof cb === 'function') { cb(res); return; } return res;
                } catch (e) {}
            }
            return orig.apply(this, arguments);
        };
        proto.__omgD = true; _hookedDFV = true; rec('MAX', 'HOOK2 detectForVideo armed ✓'); return true;
    }
    function chk(v) { try { if (typeof v === 'function' && v.prototype && typeof v.prototype.detectForVideo === 'function') return wrapDFV(v.prototype); } catch (e) {} return false; }
    function tryWebpack() {
        try {
            const key = Object.keys(W).find(k => /^webpackChunk/.test(k));
            if (!key || !Array.isArray(W[key])) return;
            if (W[key].push === Array.prototype.push) return;
            if (!_req) { W[key].push([[], {}, (r) => { _req = r; }]); }
            if (_req && _req.c) for (const id in _req.c) { const ex = _req.c[id] && _req.c[id].exports; if (!ex) continue; chk(ex); if (typeof ex === 'object') for (const k in ex) { try { chk(ex[k]); } catch (e) {} } }
        } catch (e) {}
    }

    let tries = 0;
    const poll = setInterval(() => { tries++; if (!_hookedDFV) tryWebpack(); if ((_hookedWasm || _hookedDFV) && tries > 8) clearInterval(poll); if (tries > 1200) clearInterval(poll); }, 200);

    // ==================== HOOK 3: the SIGNED frame ====================
    let _hookedSign = false;
    function dvOf(data) { try { if (data instanceof ArrayBuffer) return new DataView(data); if (ArrayBuffer.isView(data)) return new DataView(data.buffer, data.byteOffset, data.byteLength); } catch (e) {} return null; }
    function isFrame(dv) { if (!dv || dv.byteLength < 17) return false; try { if (dv.getUint8(0) !== 4) return false; const s = dv.getUint16(13, true); return (17 + 2 * s * 4) === dv.byteLength; } catch (e) { return false; } }
    function rewriteFrame(dv) {
        const s = dv.getUint16(13, true), aspect = dv.getFloat32(9, true) || getAspect(), ideal = idealObjects(aspect), n = Math.min(s, ideal.length);
        dv.setUint8(15, 255); dv.setUint8(16, 2);
        let c = 17; for (let i = 0; i < n; i++) { dv.setFloat32(c, ideal[i].x, true); dv.setFloat32(c + 4, ideal[i].y, true); c += 8; }
    }
    try {
        if (W.crypto && W.crypto.subtle && typeof W.crypto.subtle.sign === 'function') {
            const _sign = W.crypto.subtle.sign;
            W.crypto.subtle.sign = function (alg, key, data) {
                try { if (CFG.enabled) { const dv = dvOf(data); if (isFrame(dv)) { rewriteFrame(dv); bump('signed-frame'); } } } catch (e) {}
                return _sign.call(this, alg, key, data);
            };
            _hookedSign = true; rec('MAX', 'HOOK3 signed-frame hooked ✓');
        }
    } catch (e) { rec('MAX', 'HOOK3 failed', '' + e); }

    // ==================== API ====================
    W.__omog = {
        version: VER, cfg: CFG,
        enable(b) { CFG.enabled = (b !== false); saveCfg(); rec('CFG', 'enabled=' + CFG.enabled); },
        setScore(t) { CFG.mode = 'fixed'; CFG.target = Math.max(7.5, Math.min(10, +t)); saveCfg(); rec('CFG', 'fixed score=' + CFG.target); },
        setRange(lo, hi) { CFG.mode = 'range'; CFG.rangeMin = Math.max(7.5, Math.min(10, +lo)); CFG.rangeMax = Math.max(7.5, Math.min(10, +hi)); saveCfg(); rec('CFG', 'fluctuate ' + CFG.rangeMin + '-' + CFG.rangeMax); },
        get status() { return { version: VER, on: CFG.enabled, mode: CFG.mode, target: CFG.mode === 'range' ? (CFG.rangeMin + '-' + CFG.rangeMax) : CFG.target, sendingNow: +(_tgt || CFG.target), hookWasm: _hookedWasm, hookDFV: _hookedDFV, hookSign: _hookedSign, frames: _calls }; },
        get logs() { return LOGS; },
        dump() { const o = { ts: new Date().toISOString(), version: VER, cfg: CFG, status: this.status, recent: LOGS.slice(-200) }; const t = JSON.stringify(o, null, 2); try { W.navigator.clipboard && W.navigator.clipboard.writeText(t); } catch (e) {} console.log('%c[OMG] DUMP v' + VER + ' (copied)', 'color:#6f6;font-weight:bold'); console.log(t); return o; },
    };

    // ==================== UI ====================
    function buildUI() {
        if (!document.body || document.getElementById('omog-panel')) return;
        const p = document.createElement('div');
        p.id = 'omog-panel';
        p.style.cssText = 'position:fixed;z-index:2147483647;bottom:12px;right:12px;background:#11141a;color:#cfe;font:13px/1.4 monospace;padding:12px 14px;border:1px solid #2a3340;border-radius:10px;box-shadow:0 6px 24px rgba(0,0,0,.55);width:205px;opacity:.96';
        const IN = 'width:48px;background:#1b2230;color:#cfe;border:1px solid #2a3340;border-radius:5px;text-align:center';
        
        p.innerHTML =
            '<div style="font-weight:bold;color:#9cf;margin-bottom:8px;font-size:14px">OMG · MAX <span style="color:#6f6">v' + VER + '</span></div>' +
            '<label style="display:flex;justify-content:space-between;align-items:center;font-size:15px;margin:6px 0">MAX my score <input id="omog-en" type="checkbox" style="transform:scale(1.5)"></label>' +
            '<label style="display:flex;justify-content:space-between;align-items:center;font-size:13px;margin:6px 0">fluctuate <input id="omog-fluc" type="checkbox"></label>' +
            '<label style="display:flex;justify-content:space-between;align-items:center;margin:4px 0">score <input id="omog-tgt" type="number" step="0.1" min="7.5" max="10" style="' + IN + '"></label>' +
            '<label style="display:flex;justify-content:space-between;align-items:center;margin:4px 0">range <span><input id="omog-min" type="number" step="0.1" min="7.5" max="10" style="' + IN + '">–<input id="omog-max" type="number" step="0.1" min="7.5" max="10" style="' + IN + '"></span></label>' +
            '<div style="color:#789;font-size:10px;margin:6px 0">7.5–10. fluctuate = wander between range; off = hold the score.</div>' +
            '<button id="omog-dump" style="width:100%;margin-top:4px;cursor:pointer;background:#1b2230;color:#cfe;border:1px solid #2a3340;border-radius:6px;padding:4px;font-family:monospace">Dump logs</button>' +
            
            // Updated Discord Link Button with Community/Updates and Premium Script Coming Soon notice
            '<a id="omog-discord" href="https://discord.gg/4VVVbnJXD" target="_blank" style="display:block;text-align:center;width:100%;margin-top:6px;box-sizing:border-box;background:#5865F2;color:#fff;text-decoration:none;border-radius:6px;padding:6px;font-weight:bold;font-size:11px;line-height:1.3;transition:background 0.2s;font-family:sans-serif">' +
                'Join Discord for Updates & Community' +
                '<div style="font-size:9px;font-weight:normal;opacity:0.85;margin-top:2px;color:#ffd700">★ Premium Script Soon! ★</div>' +
            '</a>' +
            
            '<div id="omog-st" style="margin-top:8px;color:#789;font-size:11px"></div>';
        
        document.body.appendChild(p);
        
        const $ = s => p.querySelector(s);
        $('#omog-en').checked = CFG.enabled; $('#omog-en').onchange = e => { CFG.enabled = e.target.checked; saveCfg(); };
        $('#omog-fluc').checked = CFG.mode === 'range'; $('#omog-fluc').onchange = e => { CFG.mode = e.target.checked ? 'range' : 'fixed'; saveCfg(); };
        $('#omog-tgt').value = CFG.target; $('#omog-tgt').onchange = e => { CFG.target = Math.max(7.5, Math.min(10, +e.target.value || 9.6)); saveCfg(); };
        $('#omog-min').value = CFG.rangeMin; $('#omog-min').onchange = e => { CFG.rangeMin = Math.max(7.5, Math.min(10, +e.target.value || 9)); saveCfg(); };
        $('#omog-max').value = CFG.rangeMax; $('#omog-max').onchange = e => { CFG.rangeMax = Math.max(7.5, Math.min(10, +e.target.value || 9.9)); saveCfg(); };
        $('#omog-dump').onclick = () => W.__omog.dump();
        
        const discBtn = $('#omog-discord');
        discBtn.onmouseenter = () => { discBtn.style.background = '#4752C4'; };
        discBtn.onmouseleave = () => { discBtn.style.background = '#5865F2'; };
    }

    setInterval(() => {
        try {
            buildUI();
            const st = document.getElementById('omog-st');
            const score = CFG.mode === 'range' ? ((_tgt || 0).toFixed(1)) : (+CFG.target).toFixed(1);
            if (st) st.textContent = (CFG.enabled ? 'ON' : 'off') + ' · ' + ((_hookedWasm || _hookedDFV || _hookedSign) ? ('hooked[' + (_hookedWasm ? 'W' : '') + (_hookedDFV ? 'D' : '') + (_hookedSign ? 'S' : '') + ']') : 'arming…') + ' · score:' + score;
            const en = document.getElementById('omog-en'); if (en && en !== document.activeElement) en.checked = CFG.enabled;
        } catch (e) {}
    }, 1000);
    if (document.body) buildUI(); else document.addEventListener('DOMContentLoaded', buildUI);

    rec('BOOT', 'omoggle MAX v' + VER + ' armed', { enabled: CFG.enabled });
})();