ONO.speed - Stake Smooth Speed Hack

Smooth, optimized speed scaling (rAF delta), timers auto-on, CSS snap for near-instant animations. Collapsible advanced options. Max speed capped at 9.9x.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name          ONO.speed -  Stake Smooth Speed Hack
// @namespace     https://github.com/cutiejf/stakespeed/blob/main/ono.speed
// @version       3.0.1
// @description   Smooth, optimized speed scaling (rAF delta), timers auto-on, CSS snap for near-instant animations. Collapsible advanced options. Max speed capped at 9.9x.
// @author        jayfantz
// @match         https://stake.com/*
// @grant         none
// ==/UserScript==
(function () {
    'use strict';

    // ---------------- State / Config
    let speed = 1.0;
    const bootTime = performance.now();
    let scaledTimeOffset = 0;

    const MAX_SPEED = 9.9;
    const MAX_Z_INDEX = '2147483647';
    const BORDER_PURPLE = '#7340a3';

    const hooks = {
        requestAnimationFrame: true,
        setTimeout: true,
        setInterval: true,
        css: true,
        time: false,
        date: false,
        gsap: null,
        pixi: null,
        three: null,
        anime: null,
        velocity: null,
    };
    const CSS_SNAP_S = 0.015;
    const MIN_TIMEOUT_MS = 0;
    const MIN_INTERVAL_MS = 1;

    // ---------------- Colors
const C = {
  deepNavy:      '#0f212e',   // background / footer base
  darkPill:      '#1f3341',   // main panel body
  darkerButton:  '#0c1a25',   // inner button tone or accent divs
  midGray:       '#55646e',   // borders, lines, text subtle
  lightGray:     '#909ba1',   // primary text
  actionGreen:   '#107721',   // buttons, highlights, icons
  shadow:        '#263a46'    // shadow / glow edge
};


    // ---------------- Keep native refs
    const native = {
        setTimeout: window.setTimeout.bind(window),
        setInterval: window.setInterval.bind(window),
        requestAnimationFrame: window.requestAnimationFrame.bind(window),
        performance: window.performance,
        Date: window.Date,
    };

    // --- Helper function to format speed ---
    function formatSpeed(s) {
        // Bold the number AND the 'x' multiplier
        return `<b style="font-size: 18px;">${s.toFixed(1)}</b> <b style="font-style: italic;">x</b>`;
    }

    // --- Core Styling for Shadow DOM (Must be self-contained) ---
const globalStyle = `
  * {
    box-sizing: border-box !important;
    font-family: Inter, system-ui, -apple-system, Segoe UI, Arial, sans-serif !important;
    color: ${C.lightGray} !important;
    margin: 0 !important;
    line-height: 1.2 !important;
    user-select: none !important;
  }

  #gauge-wrapper {
    position: fixed;
    top: 40px;
    left: 40px;
    z-index: ${MAX_Z_INDEX};
    cursor: default;
  }

  #gauge {
    background: ${C.darkPill};
    border: 3px solid ${C.midGray};
    border-radius: 18px;
    display: flex;
    flex-direction: column;
    cursor: move;
    box-shadow:
    inset 0 1px 3px rgba(255,255,255,0.06),
    inset 0 -2px 5px rgba(0,0,0,0.6),
    0 0 22px ${C.shadow}bb,
    0 0 30px rgba(15,33,46,0.45);
  }

#gauge-header {
  display: flex;
  align-items: center;
  padding: 8px 10px 6px 12px !important;
  gap: 8px;
  box-shadow:         inset 0 2px 4px rgba(0,0,0,0.75),  /* deep inner top shadow */
    inset 0 2px 4px rgba(255,255,255,0.05); /* subtle lower light */
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
}

  #gauge-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: ${C.deepNavy};
    border-top: 1px solid ${C.midGray};
    border-bottom-left-radius: 14px;
    border-bottom-right-radius: 14px;
    padding: 8px 18px !important;
  }

  #gauge-footer span {
    font-size: 11px !important;
    color: ${C.lightGray}cc !important;
    font-weight: 700 !important;
  }

  #footer-arrow {
    cursor: pointer !important;
    font-size: 16px !important;
    color: ${C.actionGreen} !important;
    font-weight: bold !important;
  }

  button {
    background: none !important;
    border: none !important;
    color: ${C.actionGreen} !important;
    font-size: 24px !important;
    font-weight: bold !important;
    line-height: 1 !important;
    cursor: pointer !important;
    padding: 0 2px !important;
  }

  #spd {
    min-width: 48px;
    text-align: center;
    line-height: 1;
    white-space: nowrap;
  }

  #spd b {
    font-weight: bold !important;
    font-size: 18px !important;
    color: ${C.lightGray} !important;
    line-height: 1 !important;
  }

  #panel {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    background: ${C.darkPill};
    border: 3px solid ${C.midGray};
    border-radius: 16px;
    padding: 10px 16px !important;
    display: none;
    flex-direction: column;
    font-size: 14px;
    min-width: 280px;
    cursor: default;
    box-shadow:
      0 6px 14px rgba(0,0,0,0.55),
      inset 0 0 0 6px ${C.deepNavy},
      inset 0 2px 4px rgba(255,255,255,0.08);
  }

  #panel .section-title {
    margin-top: 8px !important;
    margin-bottom: 4px !important;
    color: ${C.lightGray} !important;
    opacity: .85 !important;
    font-weight: 600 !important;
    border-bottom: 1px solid ${C.midGray} !important;
    padding-bottom: 4px !important;
  }

  .toggle-row {
    display: grid;
    grid-template-columns: 1fr 46px;
    align-items: center;
    margin: 6px 0 !important;
    gap: 10px;
  }

  .toggle-label-bold {
    font-weight: bold !important;
  }

  .toggle-label-desc {
    color: ${C.lightGray}99 !important;
    font-size: 11px !important;
    font-style: italic !important;
    margin-top: 2px !important;
  }

  .collapsible-toggle {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin: 8px 0 !important;
    padding: 4px 0 !important;
    border-top: 1px solid ${C.midGray};
    color: ${C.actionGreen} !important;
    font-weight: bold !important;
    cursor: pointer;
    font-size: 14px !important;
  }
.warning-text {
    font-size: 9.5px !important;
    color: #ff4444 !important;
    opacity: 0.85;
    margin: 2px 0 6px 0 !important;
    line-height: 1.25 !important;
    letter-spacing: 0.1px;
    text-shadow: 0 0 4px rgba(255, 60, 60, 0.25);
font-weight: 700 !important;
  }

  .collapsible-arrow {
    transition: transform 0.2s;
  }

  .toggle-switch {
    width:46px;height:24px;
    border-radius:20px;
    background:${C.deepNavy};
    border:1px solid ${C.lightGray};
    position:relative;
    cursor:pointer;
    transition:background .2s,border .2s;
  }

  .knob {
    width:20px;height:20px;
    border-radius:50%;
    background:${C.darkPill};
    position:absolute;top:1px;left:1px;
    transition:left .2s, background .2s, box-shadow .2s;
    box-shadow:0 0 6px ${C.shadow};
  }
`;


    // ---------------- UI (Rebuilt inside Shadow DOM) ----------------

    // 1. Create the container (host) for the Shadow DOM
    const shadowHost = document.createElement('div');
    shadowHost.id = 'shadow-host';
    document.documentElement.appendChild(shadowHost);

    // 2. Attach the Shadow DOM
    const shadowRoot = shadowHost.attachShadow({ mode: 'open' });

    // 3. Inject global style into the Shadow DOM
    const styleElement = document.createElement('style');
    styleElement.textContent = globalStyle;
    shadowRoot.appendChild(styleElement);

    // 4. Create the gauge wrapper inside the shadow root
    const gaugeWrapper = document.createElement('div');
    gaugeWrapper.id = 'gauge-wrapper';
    shadowRoot.appendChild(gaugeWrapper);

    const gauge = document.createElement('div');
    gauge.id = 'gauge';
    gaugeWrapper.appendChild(gauge);

    // Create inner elements
    const gaugeHeader = document.createElement('div');
    gaugeHeader.id = 'gauge-header';
    gaugeHeader.innerHTML = `
        <button id="dec">–</button>
        <span id="spd">${formatSpeed(speed)}</span>
        <button id="inc">+</button>
    `;
    gauge.appendChild(gaugeHeader);

    const gaugeFooter = document.createElement('div');
    gaugeFooter.id = 'gauge-footer';
    gaugeFooter.innerHTML = `
        <span>ONO.speed</span>
        <span id="footer-arrow">▼</span>
    `;
    gauge.appendChild(gaugeFooter);

    const panel = document.createElement('div');
    panel.id = 'panel';
    gaugeWrapper.appendChild(panel);


    // --- Descriptions and UI Functions (Re-scoped for Shadow DOM) ---
    const hookDescriptions = {
        requestAnimationFrame: 'Smooth frame-by-frame animation loops',
        setTimeout: 'One-time function delays',
        setInterval: 'Recurring function delays',
        css: 'Browser-native UI movement and styling',
        time: 'Affects high-precision timing for games/physics',
        date: 'Affects login sessions, expiration, and notifications',
        gsap: 'Greensock\'s industry-standard animation engine',
        pixi: 'PIXI.js 2D game loop',
        three: 'THREE.js 3D scene timing',
        anime: 'Anime.js animation library',
        velocity: 'Velocity.js animation library',
    };

    function makeToggleRow(labelText, key, initial) {
        const row = document.createElement('div');
        row.className = 'toggle-row';

        const labelContainer = document.createElement('div');
        labelContainer.innerHTML = `
            <div class="toggle-label-bold">${labelText}</div>
            <div class="toggle-label-desc">${hookDescriptions[key] || ''}</div>
        `;

        const toggle = document.createElement('div');
        toggle.className = 'toggle-switch';
        const toggleWrapper = document.createElement('div');
        toggleWrapper.style = 'justify-self: end;';

        const knob = document.createElement('div');
        knob.className = 'knob';
        toggle.appendChild(knob);
        toggleWrapper.appendChild(toggle);

const setVisual = (on) => {
  knob.style.left = on ? '25px' : '1px';
  knob.style.background = on ? C.actionGreen : '#1c3b4a'; // lighter navy off
  knob.style.boxShadow = on
    ? `0 0 6px ${C.actionGreen}99`
    : `0 0 4px ${C.shadow}55`;
  toggle.style.border = `1px solid ${on ? C.actionGreen : C.midGray}`;
  toggle.style.background = on ? C.darkPill : '#152a37'; // softer off tone
};



        hooks[key] = initial;
        setVisual(!!initial);
        toggle.addEventListener('click', (e) => {
            e.stopPropagation();
            hooks[key] = !hooks[key];
            setVisual(hooks[key]);
            updateHooks();
        });

        row.append(labelContainer, toggleWrapper);
        return row;
    }

    function section(title) {
        const t = document.createElement('div');
        t.textContent = title;
        t.className = 'section-title';
        panel.appendChild(t);
    }

    function createCollapsibleToggle(panelElement, labelText) {
        const toggleRow = document.createElement('div');
        toggleRow.className = 'collapsible-toggle';
        toggleRow.innerHTML = `
            <span>${labelText}</span>
            <span class="collapsible-arrow">▼</span>
        `;

        const arrowEl = toggleRow.querySelector('.collapsible-arrow');
        panelElement.style.display = 'none';
        arrowEl.style.transform = 'rotate(-90deg)';

        toggleRow.onclick = (e) => {
            e.stopPropagation();
            const isVisible = panelElement.style.display !== 'none';
            panelElement.style.display = isVisible ? 'none' : 'flex';
            arrowEl.style.transform = isVisible ? 'rotate(-90deg)' : 'rotate(0deg)';
        };

        return toggleRow;
    }

    // --- UI Layout Injection (into Shadow DOM) ---

    section('Core JS Timing');
    panel.append(
        makeToggleRow('requestAnimationFrame', 'requestAnimationFrame', hooks.requestAnimationFrame),
        makeToggleRow('setTimeout', 'setTimeout', hooks.setTimeout),
        makeToggleRow('setInterval', 'setInterval', hooks.setInterval),
    );

    // --- Global Clocks Section (Collapsible) ---
    const clockPanel = document.createElement('div');
    clockPanel.style.display = 'flex';
    clockPanel.style.flexDirection = 'column';

    panel.appendChild(createCollapsibleToggle(clockPanel, 'More Clocks (Caution)'));

    const warningText = document.createElement('div');
    warningText.className = 'warning-text';
    warningText.innerHTML = `
        *Caution:* Global clock overrides can lead to session errors or delayed notifications.
    `;
    clockPanel.appendChild(warningText);

    clockPanel.append(
        makeToggleRow('performance.now()', 'time', hooks.time),
        makeToggleRow('Date.now() / new Date()', 'date', hooks.date),
    );
    panel.appendChild(clockPanel);

    // --- CSS & Libraries Section ---
    section('CSS & Libraries');
    panel.append(
        makeToggleRow('CSS Animations/Transitions', 'css', hooks.css),
    );

    // --- Libraries Section (Collapsible) ---
    const libPanel = document.createElement('div');
    libPanel.style.display = 'flex';
    libPanel.style.flexDirection = 'column';

    panel.appendChild(createCollapsibleToggle(libPanel, 'More Libraries'));

    const libRows = {
        gsap: makeToggleRow('GSAP (globalTimeline)', 'gsap', false),
        pixi: makeToggleRow('PIXI (Ticker)', 'pixi', false),
        three: makeToggleRow('THREE.js (Clock)', 'three', false),
        anime: makeToggleRow('Anime.js', 'anime', false),
        velocity: makeToggleRow('Velocity.js', 'velocity', false),
    };
    // Need unique IDs for library rows to detect library presence later
    libRows.gsap.id = 'lib-gsap';
    libRows.pixi.id = 'lib-pixi';
    libRows.three.id = 'lib-three';
    libRows.anime.id = 'lib-anime';
    libRows.velocity.id = 'lib-velocity';

    libPanel.append(libRows.gsap, libRows.pixi, libRows.three, libRows.anime, libRows.velocity);
    panel.appendChild(libPanel);

    // ---------------- Dragging (Re-scoped to Shadow DOM) ----------------
    let dx, dy;

    gauge.addEventListener('mousedown', (e) => {
        // Find if the click target is any interactive element inside the gauge or panel
        const interactiveTarget = e.target.closest('button, #footer-arrow, .knob, .collapsible-toggle');
        const isInsidePanel = panel.contains(e.target);

        // Drag exclusion checks
        if (interactiveTarget || isInsidePanel) {
            return;
        }

        e.preventDefault();
        e.stopPropagation();

        // Temporarily set the body cursor to 'move' for continuous feedback
        document.body.style.cursor = 'move';

        // Calculate offset relative to the Shadow DOM host/page
        const gaugeRect = gaugeWrapper.getBoundingClientRect();
        dx = e.pageX - gaugeRect.left;
        dy = e.pageY - gaugeRect.top;

        const move = (ev)=>{
            gaugeWrapper.style.left = ev.pageX - dx + 'px';
            gaugeWrapper.style.top = ev.pageY - dy + 'px';
        };

        const up = ()=>{
            document.removeEventListener('mousemove', move);
            document.removeEventListener('mouseup', up);

            // Restore body cursor
            document.body.style.cursor = 'default';
        };

        document.addEventListener('mousemove', move);
        document.addEventListener('mouseup', up);
    });

    const spdEl = shadowRoot.querySelector('#spd');
    const footerArrow = shadowRoot.querySelector('#footer-arrow');

    // Panel toggle function
    const togglePanel = (e) => {
        e.stopPropagation();
        const isVisible = panel.style.display === 'flex';
        panel.style.display = isVisible ? 'none' : 'flex';
        footerArrow.textContent = isVisible ? '▼' : '▲'; // Change arrow text
    };

    // Attach click handlers
    shadowRoot.querySelector('#inc').onclick = () => setSpeed(speed + 0.1);
    shadowRoot.querySelector('#dec').onclick = () => setSpeed(Math.max(0.1, speed - 0.1));
    footerArrow.onclick = togglePanel;

    // ---------------- Core / Helper Functions (Unchanged) ----------------
    function setSpeed(target) {
        let newSpeed = Math.max(0.1, target);
        newSpeed = Math.min(MAX_SPEED, newSpeed);

        const currentTime = performance.now();
        const realDelta = currentTime - bootTime;
        const currentScaledTime = realDelta * speed + scaledTimeOffset;

        speed = newSpeed;
        scaledTimeOffset = currentScaledTime - (currentTime - bootTime) * speed;

        spdEl.innerHTML = formatSpeed(speed);
        afterSpeedChange();
    }

    function afterSpeedChange() {
        if (hooks.css) applyCSSScaling();
        applyLibScaling();
        updateHooks();
    }

    function getVirtualTime() {
        return (performance.now() - bootTime) * speed + scaledTimeOffset;
    }

    // ---------------- Core Hooks ----------------
    let rafLast = 0;
    let rafVirtual = 0;

    function enableVirtualRAF() {
        window.requestAnimationFrame = cb => {
            native.requestAnimationFrame(now => {
                if (rafLast === 0) {
                    rafLast = now;
                    rafVirtual = getVirtualTime();
                }
                const delta = now - rafLast;
                rafLast = now;
                rafVirtual += delta * speed;
                cb(rafVirtual);
            });
        };
    }

    function disableVirtualRAF() {
        window.requestAnimationFrame = native.requestAnimationFrame;
        rafLast = 0;
        rafVirtual = 0;
    }

    function enableVirtualTime() {
        window.performance.now = () => getVirtualTime();
    }

    function disableVirtualTime() {
        window.performance.now = native.performance.now.bind(native.performance);
    }

    function enableVirtualDate() {
        const nativeDate = native.Date;
        const nativeNow = nativeDate.now;
        const realDateBoot = nativeNow();
        const performanceBoot = performance.now();

        function ScaledDate(...args) {
            if (!new.target) {
                return new nativeDate(realDateBoot + getVirtualTime() - performanceBoot).toString();
            }
            if (args.length === 0) {
                const offset = getVirtualTime() - performanceBoot;
                return new nativeDate(realDateBoot + offset);
            }
            return new nativeDate(...args);
        }
        ScaledDate.now = () => realDateBoot + getVirtualTime() - performanceBoot;
        Object.assign(ScaledDate, nativeDate);
        window.Date = ScaledDate;
    }

    function disableVirtualDate() {
        window.Date = native.Date;
    }

    function updateHooks() {
        if (hooks.setTimeout) {
            window.setTimeout = (fn, t, ...a) => {
                const base = Number.isFinite(t) ? (t ?? 0) : 0;
                const scaled = Math.max(MIN_TIMEOUT_MS, Math.round(base / speed));
                return native.setTimeout(fn, scaled, ...a);
            };
        } else {
            window.setTimeout = native.setTimeout;
        }

        if (hooks.setInterval) {
            window.setInterval = (fn, t, ...a) => {
                const base = Number.isFinite(t) ? (t ?? 0) : 0;
                const scaled = Math.max(MIN_INTERVAL_MS, Math.round(base / speed));
                return native.setInterval(fn, scaled, ...a);
            };
        } else {
            window.setInterval = native.setInterval;
        }

        if (hooks.requestAnimationFrame) enableVirtualRAF(); else disableVirtualRAF();
        if (hooks.time) enableVirtualTime(); else disableVirtualTime();
        if (hooks.date) enableVirtualDate(); else disableVirtualDate();
        if (hooks.css) applyCSSScaling(); else restoreCSSDurations();
    }

    // ---------------- CSS scaling ----------------
    const cssCache = new Map();
    let cssObserver = null;

    function cacheDurations(el) {
        if (el.nodeType !== 1) return;
        try {
            // Note: getComputedStyle still works on host elements, even from Shadow DOM.
            const st = getComputedStyle(el);
            const anim = st.animationDuration;
            const trans = st.transitionDuration;
            if (!anim && !trans) return;
            const rec = cssCache.get(el) || {};
            if (!rec.anim && anim && anim !== '0s') rec.anim = anim.split(',').map(s => parseFloat(s) || 0);
            if (!rec.trans && trans && trans !== '0s') rec.trans = trans.split(',').map(s => parseFloat(s) || 0);
            if (rec.anim || rec.trans) cssCache.set(el, rec);
        } catch { /* cross-origin/shadow DOM */ }
    }

    function scaleSecondsArray(arr, scale) {
        return arr.map(v => {
            const out = v * scale;
            return (out <= CSS_SNAP_S) ? '0.001s' : out.toFixed(4) + 's';
        }).join(', ');
    }

    function applyScaleToEl(el, scale) {
        const rec = cssCache.get(el);
        if (!rec || !el.style) return;
        if (rec.anim)  el.style.animationDuration  = scaleSecondsArray(rec.anim,  scale);
        if (rec.trans) el.style.transitionDuration = scaleSecondsArray(rec.trans, scale);
    }

    function scanAndCacheTree(root = document.body) {
        if (root.nodeType !== 1) return;
        cacheDurations(root);
        // Note: Querying the host DOM from Shadow DOM still works.
        root.querySelectorAll('*').forEach(cacheDurations);
    }

    function applyScaleTree(root, scale) {
        if (root.nodeType !== 1) return;
        applyScaleToEl(root, scale);
        root.querySelectorAll('*').forEach(el => applyScaleToEl(el, scale));
    }

    function applyCSSScaling() {
        const scale = 1 / speed;
        if (!cssObserver) {
            scanAndCacheTree(document.documentElement);
            cssObserver = new MutationObserver(muts => {
                for (const m of muts) {
                    if (m.type === 'childList') {
                        m.addedNodes.forEach(n => {
                            if (n.nodeType === 1) {
                                scanAndCacheTree(n);
                                applyScaleTree(n, scale);
                            }
                        });
                    }
                }
            });
            cssObserver.observe(document.documentElement, { childList: true, subtree: true });
        }
        cssCache.forEach((_, el) => applyScaleToEl(el, scale));
    }

    function restoreCSSDurations() {
        cssCache.forEach((rec, el) => {
            if (!el || !el.style) return;
            if (rec.anim)  el.style.animationDuration  = rec.anim.map(v => v + 's').join(', ');
            if (rec.trans) el.style.transitionDuration = rec.trans.map(v => v + 's').join(', ');
        });
        if (cssObserver) {
            cssObserver.disconnect();
            cssObserver = null;
        }
    }
    // ---------------- Library hooks ----------------
    let threePatched = false;
    let pixiPatched = false;

    function applyLibScaling() {
        if (window.gsap) {
            try {
                if (hooks.gsap) window.gsap.globalTimeline.timeScale(speed);
                else window.gsap.globalTimeline.timeScale(1);
            } catch {}
        }
        if (window.PIXI && window.PIXI.Ticker) {
            try {
                if (hooks.pixi) {
                    if (window.PIXI.Ticker.shared) window.PIXI.Ticker.shared.speed = speed;
                    if (window.PIXI.Ticker.system) window.PIXI.Ticker.system.speed = speed;
                    if (!pixiPatched) { pixiPatched = true; }
                } else {
                    if (window.PIXI.Ticker.shared) window.PIXI.Ticker.shared.speed = 1;
                    if (window.PIXI.Ticker.system) window.PIXI.Ticker.system.speed = 1;
                }
            } catch {}
        }
        if (window.THREE && window.THREE.Clock) {
            try {
                const C = window.THREE.Clock;
                if (!threePatched) {
                    if (!C.prototype.___nativeGetDelta) {
                        C.prototype.___nativeGetDelta = C.prototype.getDelta;
                        C.prototype.getDelta = function () {
                            const d = this.___nativeGetDelta();
                            return hooks.three ? d * speed : d;
                        };
                    }
                    if (!C.prototype.___nativeGetElapsedTime) {
                        C.prototype.___nativeGetElapsedTime = C.prototype.getElapsedTime;
                        C.prototype.getElapsedTime = function () {
                            const e = this.___nativeGetElapsedTime();
                            return hooks.three ? e * speed : e;
                        };
                    }
                    threePatched = true;
                }
            } catch {}
        }
        if (window.anime) {
            try { window.anime.speed = hooks.anime ? speed : 1; } catch {}
        }
        if (window.Velocity) {
            try { window.Velocity.mock = hooks.velocity ? (1 / speed) : false; } catch {}
        }
    }

    const libDetectAndInit = () => {
        // Querying the main window for library objects still works
        const present = { gsap:  !!(window.gsap), pixi:  !!(window.PIXI && window.PIXI.Ticker), three: !!(window.THREE && window.THREE.Clock), anime: !!(window.anime), velocity: !!(window.Velocity) };
        for (const k of Object.keys(present)) {
            if (hooks[k] === null) hooks[k] = present[k];
            // Re-select elements using the shadowRoot
            const rowMap = {
                gsap: shadowRoot.querySelector('#lib-gsap'),
                pixi: shadowRoot.querySelector('#lib-pixi'),
                three: shadowRoot.querySelector('#lib-three'),
                anime: shadowRoot.querySelector('#lib-anime'),
                velocity: shadowRoot.querySelector('#lib-velocity')
            };
            // Note: The logic below assumes the element and its class structure exist
            if (rowMap[k]) {
                const boldLabel = rowMap[k].querySelector('.toggle-label-bold');
                if (boldLabel) boldLabel.style.opacity = present[k] ? '1' : '.55';
            }
        }
        applyLibScaling();
    };
    native.setInterval(libDetectAndInit, 1500);
    libDetectAndInit();

    // ---------------- Init
    function boot() {
        const initialPerformanceNow = native.performance.now();
        scaledTimeOffset = initialPerformanceNow - initialPerformanceNow * speed;
        updateHooks();
    }
    boot();
})();