Minerva

Track Torn player activity with a floating multi-target tracker, alerts, and diagnostics.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

作者のサイトでサポートを受ける。または、このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Minerva
// @namespace    http://tampermonkey.net/
// @version      v0.4.41
// @description  Track Torn player activity with a floating multi-target tracker, alerts, and diagnostics.
// @author       Beatrix [1956521]
// @license      Proprietary - All Rights Reserved
// @supportURL   https://github.com/Zulenka/ProjectMinerva/issues/new/choose
// @match        https://www.torn.com/*
// @noframes
// @connect      api.torn.com
// @connect      api.github.com
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_notification
// @grant        GM_xmlhttpRequest
// @grant        GM_addValueChangeListener
// @grant        GM_removeValueChangeListener
// ==/UserScript==

(function() {
    'use strict';

    // Copyright (c) 2026 Beatrix. All rights reserved.
    // No permission is granted to copy, modify, redistribute, or republish this script.

    // --- Configuration & State ---
    const MINERVA_VERSION = "v0.4.41";
    const MINERVA_INTERNAL_TEARDOWN_SLOT = "__minerva_internal_teardown__";
    const API_KEY_STORAGE_KEY = "torn-api-key";
    const API_KEY_VAULT_STORAGE_KEY = "torn-api-key-vault";
    const API_KEY_CACHE_STORAGE_KEY = "torn-api-key-cache";
    const API_KEY_CACHE_EXPIRY_STORAGE_KEY = "torn-api-key-cache-expiry";
    const TRACKED_TARGETS_STORAGE_KEY = "minerva-tracked-targets";
    const MAX_TRACKED_TARGETS_STORAGE_KEY = "minerva-max-tracked-targets";
    const WIDGET_POS_STORAGE_KEY = "minerva-corner-widget-pos";
    const WIDGET_HIDDEN_STORAGE_KEY = "minerva-corner-widget-hidden";
    const WIDGET_COMPACT_STORAGE_KEY = "minerva-corner-widget-compact";
    const WIDGET_LOCKED_STORAGE_KEY = "minerva-corner-widget-locked";
    const API_KEY_PROMPT_POS_STORAGE_KEY = "minerva-api-key-prompt-pos";
    const TOAST_HOST_POS_STORAGE_KEY = "minerva-toast-host-pos";
    const VERSION_CHECK_LAST_AT_STORAGE_KEY = "minerva-version-check-last-at";
    const VERSION_CHECK_DISMISSED_VERSION_STORAGE_KEY = "minerva-version-check-dismissed-version";
    const CYAN_COLOR = "#00f2ff";
    const PINK_COLOR = "#ff0055";
    const MAX_UI_LOG_LINES = 250;
    const MAX_LOG_MESSAGE_CHARS = 1200;
    const API_KEY_UNLOCK_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
    const MANUAL_PING_WINDOW_MS = 5000;
    const MANUAL_PING_MAX_CLICKS_PER_WINDOW = 4;
    const MANUAL_PING_COOLDOWN_MS = 60000;
    const VERSION_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
    const GITHUB_LATEST_RELEASE_API_URL = "https://api.github.com/repos/Zulenka/ProjectMinerva/releases/latest";
    const GITHUB_RELEASES_PAGE_URL = "https://github.com/Zulenka/ProjectMinerva/releases";
    const GREASYFORK_SCRIPT_PAGE_URL = "https://greasyfork.org/en/scripts/567217-";
    
    let apiKey = null;
    let targetId = new URLSearchParams(window.location.search).get("XID");
    
    let isTracking = true;
    let thresholdSeconds = parseInt(GM_getValue("minerva-threshold", 300)); 
    let maxTrackedTargets = parseInt(GM_getValue(MAX_TRACKED_TARGETS_STORAGE_KEY, 8));
    let countdownTimer = 60;
    let currentStatus = "UNKNOWN";
    let hasWarnedNoTargets = false;
    let isUiOpen = false;
    let isLogOpen = false;
    let isSettingsPopupOpen = false;
    let lastActionRelativeText = "--";
    let lastBackgroundNotificationAt = 0;
    let widgetDragState = null;
    let apiKeyPromptDragState = null;
    let toastDragState = null;
    let requestSeq = 0;
    let pollCycleSeq = 0;
    let injectionFailureLogged = false;
    let engineIntervalId = null;
    let lastInjectionAttemptAt = 0;
    let profileInjectionObserver = null;
    let manualPingClickTimestamps = [];
    let manualPingCooldownUntil = 0;
    let versionCheckInFlight = false;
    let latestAvailableVersion = "";
    let latestAvailableReleaseUrl = "";
    let trackedTargetsValueChangeListenerId = null;
    let lastKnownLocationSearch = window.location.search || "";
    let trackedListRenderScheduled = false;
    let trackedListRenderInProgress = false;
    let engineTickInProgress = false;
    let pollCycleInProgress = false;
    let isTornDown = false;
    let trackedTargetsStartupGraceUntil = Date.now() + 4000;
    let startupNoTargetsDeferredLogged = false;
    let toastDocMouseMoveHandler = null;
    let toastDocMouseUpHandler = null;
    let toastWindowResizeHandler = null;
    let settingsDocClickHandler = null;
    let settingsWindowResizeHandler = null;
    let settingsWindowScrollHandler = null;
    let settingsDocKeydownHandler = null;
    let cornerDocMouseMoveHandler = null;
    let cornerDocMouseUpHandler = null;
    let cornerWindowResizeHandler = null;
    let trackedTargets = GM_getValue(TRACKED_TARGETS_STORAGE_KEY, []);
    let trackedStates = {};
    GM_setValue("minerva-tracking-active", true);

    if (!Array.isArray(trackedTargets)) trackedTargets = [];
    if (!Number.isFinite(maxTrackedTargets) || maxTrackedTargets < 1) maxTrackedTargets = 8;
    trackedTargets = trackedTargets.map(String).filter(Boolean);
    trackedTargets = trackedTargets.slice(0, maxTrackedTargets);
    GM_setValue(TRACKED_TARGETS_STORAGE_KEY, trackedTargets);
    trackedTargets.forEach(id => ensureTrackedState(id, id));

    // --- Logging System ---
    function getLogContextSummary() {
        const path = `${window.location.pathname || ""}${window.location.search || ""}`;
        return `ctx{tracking=${isTracking ? 1 : 0},target=${targetId || "-"},tracked=${trackedTargets.length},status=${currentStatus},path=${path}}`;
    }

    function claimActiveMinervaInstance() {
        return;
    }

    function isActiveMinervaInstance() {
        return !isTornDown;
    }

    function isLiveMinervaRuntime() {
        return !isTornDown && isActiveMinervaInstance();
    }

    function releaseActiveMinervaInstance() {
        return;
    }

    function tryClaimDomInstanceLock() {
        return true;
    }

    function ensureTrackedState(id, nameHint = null) {
        const key = String(id);
        trackedStates[key] = trackedStates[key] || {
            status: "UNKNOWN",
            thresholdStatus: "UNKNOWN",
            last: "--",
            name: key,
            isHospitalized: null
        };
        if (nameHint) trackedStates[key].name = String(nameHint);
        return trackedStates[key];
    }

    function updateAvailableUiBadge() {
        const badge = document.getElementById("minerva-update-available-badge");
        if (!badge) return;
        const hasUpdate = !!latestAvailableVersion && compareVersions(latestAvailableVersion, MINERVA_VERSION) > 0;
        badge.style.display = hasUpdate ? "inline-flex" : "none";
        badge.textContent = "UPDATE AVAILABLE";
        badge.title = hasUpdate
            ? `Minerva ${latestAvailableVersion} is available. Click to open release page.`
            : "";
    }

    function syncTargetIdFromUrl() {
        const currentSearch = window.location.search || "";
        if (currentSearch === lastKnownLocationSearch) return false;
        lastKnownLocationSearch = currentSearch;
        const nextTargetId = new URLSearchParams(currentSearch).get("XID");
        if (String(nextTargetId || "") === String(targetId || "")) return false;
        const previous = targetId;
        targetId = nextTargetId;
        addLog(`Current profile target changed from ${previous || "-"} to ${targetId || "-"}.`, "DIAGNOSTIC");
        updateTrackCurrentButton();
        renderTrackedList();
        return true;
    }

    function addLog(msg, type = "INFO") {
        let safeMsg = String(msg ?? "");
        if (safeMsg.length > MAX_LOG_MESSAGE_CHARS) {
            safeMsg = `${safeMsg.slice(0, MAX_LOG_MESSAGE_CHARS)} ...[truncated ${safeMsg.length - MAX_LOG_MESSAGE_CHARS} chars]`;
        }
        if (apiKey) {
            safeMsg = safeMsg.split(apiKey).join("[REDACTED_API_KEY]");
        }
        const time = new Date().toLocaleTimeString('en-US', { hour12: false });
        const logEntry = `[${time}] [${type}] ${safeMsg} ${getLogContextSummary()}`;
        const logContent = document.getElementById("minerva-log-content");
        
        if (logContent) {
            const line = document.createElement("div");
            line.style.color =
                type === "ERROR" ? PINK_COLOR :
                (type === "DIAGNOSTIC" ? "#f39c12" :
                (type === "DEBUG" ? "#7fd8ff" : "#a0a0a0"));
            line.style.marginBottom = "4px";
            line.innerText = logEntry;
            logContent.prepend(line);

            while (logContent.children.length > MAX_UI_LOG_LINES) {
                logContent.removeChild(logContent.lastElementChild);
            }
        }
        console.log(`[Minerva] ${logEntry}`);
    }

    function escapeHtml(value) {
        return String(value ?? "")
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#39;");
    }

    function ensureMinervaStyleOverrides() {
        if (document.getElementById("minerva-style-overrides")) return;
        const style = document.createElement("style");
        style.id = "minerva-style-overrides";
        style.textContent = `
            #minerva-master-container button,
            #minerva-settings-panel button,
            #minerva-master-container select,
            #minerva-settings-panel select {
                background-image: none !important;
                animation: none !important;
                text-shadow: none !important;
                box-shadow: none !important;
                filter: none !important;
                transform: none !important;
                background-position: initial !important;
                transition: color 0.12s ease, border-color 0.12s ease, background-color 0.12s ease !important;
            }
            #minerva-master-container button:hover,
            #minerva-settings-panel button:hover,
            #minerva-master-container button:focus,
            #minerva-settings-panel button:focus,
            #minerva-master-container button:active,
            #minerva-settings-panel button:active {
                animation: none !important;
                filter: none !important;
                transform: none !important;
                background-image: none !important;
                box-shadow: none !important;
            }
        `;
        document.head.appendChild(style);
    }

    function normalizeTrackedTargetsList(inputList) {
        let list = Array.isArray(inputList) ? inputList : [];
        list = list.map(String).filter(Boolean);
        if (!Number.isFinite(maxTrackedTargets) || maxTrackedTargets < 1) maxTrackedTargets = 8;
        return list.slice(0, maxTrackedTargets);
    }

    function syncTrackedTargetsFromStorage(source = "storage") {
        const stored = normalizeTrackedTargetsList(GM_getValue(TRACKED_TARGETS_STORAGE_KEY, []));
        const current = JSON.stringify(trackedTargets);
        const next = JSON.stringify(stored);
        if (current === next) return false;

        trackedTargets = stored;
        trackedTargets.forEach(id => ensureTrackedState(id, id));
        renderTrackedList();
        updateTrackCurrentButton();
        addLog(`Tracked targets synced from ${source}. count=${trackedTargets.length}`, "DIAGNOSTIC");
        return true;
    }

    function bindTrackedTargetsStorageSync() {
        if (typeof GM_addValueChangeListener !== "function") return;
        if (trackedTargetsValueChangeListenerId) return;
        trackedTargetsValueChangeListenerId = GM_addValueChangeListener(TRACKED_TARGETS_STORAGE_KEY, (name, oldValue, newValue, remote) => {
            if (!remote) return;
            trackedTargets = normalizeTrackedTargetsList(newValue);
            trackedTargets.forEach(id => ensureTrackedState(id, id));
            renderTrackedList();
            updateTrackCurrentButton();
            addLog(`Tracked targets synced from another tab. count=${trackedTargets.length}`, "DIAGNOSTIC");
        });
    }

    function isExternalExtensionSource(value) {
        const s = String(value || "");
        return s.startsWith("chrome-extension://") || s.startsWith("moz-extension://") || s.startsWith("safari-extension://");
    }

    function shouldIgnoreGlobalErrorEvent(e) {
        if (!e) return false;
        const msg = String(e.message || "");
        if (/^ResizeObserver loop completed with undelivered notifications\.?$/i.test(msg)) return true;
        if (/^ResizeObserver loop limit exceeded\.?$/i.test(msg)) return true;
        if (isExternalExtensionSource(e.filename)) return true;
        if (e.error && e.error.stack && isExternalExtensionSource(String(e.error.stack))) return true;
        return false;
    }

    function shouldIgnoreUnhandledRejectionEvent(e) {
        if (!e) return false;
        const reason = e.reason;
        if (!reason) return false;
        const stack = String(reason.stack || "");
        const msg = String(reason.message || reason || "");
        if (/ResizeObserver loop (completed with undelivered notifications|limit exceeded)/i.test(msg)) return true;
        return isExternalExtensionSource(stack) || isExternalExtensionSource(msg);
    }

    function getSavedWidgetPosition() {
        return GM_getValue(WIDGET_POS_STORAGE_KEY, { left: 18, bottom: 18 });
    }

    function getSavedApiKeyPromptPosition() {
        return GM_getValue(API_KEY_PROMPT_POS_STORAGE_KEY, { right: 16, top: 16 });
    }

    function getSavedToastHostPosition() {
        return GM_getValue(TOAST_HOST_POS_STORAGE_KEY, { left: null, bottom: 84, right: 16 });
    }

    function hasWebCrypto() {
        return !!(window.crypto && window.crypto.subtle && window.TextEncoder && window.TextDecoder);
    }

    function bytesToBase64(bytes) {
        let binary = "";
        const arr = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
        for (let i = 0; i < arr.length; i++) binary += String.fromCharCode(arr[i]);
        return btoa(binary);
    }

    function base64ToBytes(b64) {
        const binary = atob(String(b64 || ""));
        const out = new Uint8Array(binary.length);
        for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
        return out;
    }

    async function deriveVaultKey(passphrase, saltBytes) {
        const enc = new TextEncoder();
        const baseKey = await crypto.subtle.importKey(
            "raw",
            enc.encode(passphrase),
            "PBKDF2",
            false,
            ["deriveKey"]
        );
        return crypto.subtle.deriveKey(
            {
                name: "PBKDF2",
                salt: saltBytes,
                iterations: 150000,
                hash: "SHA-256"
            },
            baseKey,
            { name: "AES-GCM", length: 256 },
            false,
            ["encrypt", "decrypt"]
        );
    }

    async function encryptApiKeyToVault(apiKeyPlain, passphrase) {
        const enc = new TextEncoder();
        const salt = crypto.getRandomValues(new Uint8Array(16));
        const iv = crypto.getRandomValues(new Uint8Array(12));
        const key = await deriveVaultKey(passphrase, salt);
        const cipherBuf = await crypto.subtle.encrypt(
            { name: "AES-GCM", iv },
            key,
            enc.encode(apiKeyPlain)
        );
        return {
            v: 1,
            alg: "AES-GCM",
            kdf: "PBKDF2-SHA256",
            iter: 150000,
            salt: bytesToBase64(salt),
            iv: bytesToBase64(iv),
            data: bytesToBase64(new Uint8Array(cipherBuf))
        };
    }

    async function decryptApiKeyFromVault(vault, passphrase) {
        const dec = new TextDecoder();
        const salt = base64ToBytes(vault.salt);
        const iv = base64ToBytes(vault.iv);
        const cipher = base64ToBytes(vault.data);
        const key = await deriveVaultKey(passphrase, salt);
        const plainBuf = await crypto.subtle.decrypt(
            { name: "AES-GCM", iv },
            key,
            cipher
        );
        return dec.decode(plainBuf);
    }

    function clearUnlockedApiKeyCache() {
        GM_setValue(API_KEY_CACHE_STORAGE_KEY, "");
        GM_setValue(API_KEY_CACHE_EXPIRY_STORAGE_KEY, 0);
    }

    function clearAllStoredApiKeyMaterial() {
        GM_setValue(API_KEY_STORAGE_KEY, "");
        GM_setValue(API_KEY_VAULT_STORAGE_KEY, null);
        clearUnlockedApiKeyCache();
    }

    function cacheUnlockedApiKey(plainKey) {
        const expiry = Date.now() + API_KEY_UNLOCK_WINDOW_MS;
        GM_setValue(API_KEY_CACHE_STORAGE_KEY, plainKey);
        GM_setValue(API_KEY_CACHE_EXPIRY_STORAGE_KEY, expiry);
        return expiry;
    }

    function getCachedUnlockedApiKey() {
        const expiry = Number(GM_getValue(API_KEY_CACHE_EXPIRY_STORAGE_KEY, 0));
        const cached = String(GM_getValue(API_KEY_CACHE_STORAGE_KEY, "") || "");
        if (!cached || !Number.isFinite(expiry) || expiry <= Date.now()) {
            if (cached || expiry) clearUnlockedApiKeyCache();
            return null;
        }
        return cached;
    }

    function getVaultPayload() {
        const vault = GM_getValue(API_KEY_VAULT_STORAGE_KEY, null);
        if (!vault || typeof vault !== "object") return null;
        if (!vault.salt || !vault.iv || !vault.data) return null;
        return vault;
    }

    function showPassphraseEntryPanel(options = {}) {
        return new Promise((resolve) => {
            const existing = document.getElementById("minerva-passphrase-modal");
            if (existing) existing.remove();

            const pos = getSavedApiKeyPromptPosition();
            const panel = document.createElement("div");
            panel.id = "minerva-passphrase-modal";
            panel.style.cssText = `
                position: fixed;
                right: ${pos.right}px;
                top: ${pos.top}px;
                width: 380px;
                background: rgba(5, 8, 14, 0.96);
                color: #e8f6ff;
                border: 1px solid rgba(255,255,255,0.12);
                border-radius: 14px;
                box-shadow: 0 12px 28px rgba(0,0,0,0.42), 0 0 14px rgba(0,242,255,0.12);
                font-family: "Courier New", Courier, monospace;
                z-index: 10031;
                overflow: hidden;
            `;

            const title = options.title || "Minerva Passphrase";
            const submitLabel = options.submitLabel || "Continue";
            const showForgot = !!options.showForgot;
            const forgotLabel = options.forgotLabel || "Forgot Passphrase";
            const placeholder = options.placeholder || "Enter passphrase...";
            const initialValue = options.initialValue || "";

            panel.innerHTML = `
                <div id="minerva-passphrase-modal-header" style="display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; background: rgba(0,0,0,0.35); cursor: move; user-select:none;">
                    <div style="font-size:12px; font-weight:bold; color:#dffbff;">${title}</div>
                    <button id="minerva-passphrase-modal-close" title="Close" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.12); border-radius:6px; width:20px; height:20px; line-height:16px; padding:0; cursor:pointer;">x</button>
                </div>
                <div style="padding:12px;">
                    <div style="font-size:12px; color:#b8c6d1; line-height:1.4;">${options.message || "Enter passphrase."}</div>
                    <input id="minerva-passphrase-input" type="password" autocomplete="new-password" autocapitalize="off" autocorrect="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" placeholder="${placeholder}" style="margin-top:10px; width:100%; box-sizing:border-box; background:#0a0f14; color:#e8f6ff; border:1px solid rgba(255,255,255,0.14); border-radius:8px; padding:8px 10px; outline:none;" />
                    <div style="margin-top:10px; display:flex; justify-content:space-between; align-items:center; gap:8px; flex-wrap:wrap;">
                        <div>
                            ${showForgot ? `<button id="minerva-passphrase-forgot" style="background:transparent; color:#ffb7c8; border:1px solid rgba(255,0,85,0.22); border-radius:8px; padding:6px 10px; cursor:pointer;">${forgotLabel}</button>` : ``}
                        </div>
                        <div style="display:flex; justify-content:flex-end; gap:8px;">
                            <button id="minerva-passphrase-cancel" style="background:transparent; color:#aab8c2; border:1px solid rgba(255,255,255,0.12); border-radius:8px; padding:6px 10px; cursor:pointer;">Cancel</button>
                            <button id="minerva-passphrase-submit" style="background:rgba(0,242,255,0.08); color:${CYAN_COLOR}; border:1px solid rgba(0,242,255,0.28); border-radius:8px; padding:6px 10px; cursor:pointer; font-weight:bold;">${submitLabel}</button>
                        </div>
                    </div>
                    <div id="minerva-passphrase-error" style="margin-top:8px; min-height:14px; font-size:11px; color:${PINK_COLOR};"></div>
                </div>
            `;

            document.body.appendChild(panel);

            const input = panel.querySelector("#minerva-passphrase-input");
            const errorEl = panel.querySelector("#minerva-passphrase-error");
            let dragListenersBound = false;
            let moveHandler = null;
            let upHandler = null;
            const cleanupDragListeners = () => {
                if (!dragListenersBound) return;
                document.removeEventListener("mousemove", moveHandler);
                document.removeEventListener("mouseup", upHandler);
                dragListenersBound = false;
            };
            const finish = (action, value = null) => {
                cleanupDragListeners();
                apiKeyPromptDragState = null;
                panel.remove();
                resolve({ action, value });
            };

            if (input) {
                input.value = initialValue;
                input.focus();
                input.select();
            }

            panel.querySelector("#minerva-passphrase-modal-close")?.addEventListener("click", () => finish("cancel", null));
            panel.querySelector("#minerva-passphrase-cancel")?.addEventListener("click", () => finish("cancel", null));
            panel.querySelector("#minerva-passphrase-forgot")?.addEventListener("click", () => finish("forgot", null));
            panel.querySelector("#minerva-passphrase-submit")?.addEventListener("click", () => {
                const value = String(input?.value || "").trim();
                if (!value) {
                    if (errorEl) errorEl.textContent = "Passphrase is required.";
                    return;
                }
                finish("submit", value);
            });

            input?.addEventListener("keydown", (e) => {
                if (e.key === "Enter") {
                    e.preventDefault();
                    panel.querySelector("#minerva-passphrase-submit")?.click();
                } else if (e.key === "Escape") {
                    e.preventDefault();
                    finish("cancel", null);
                }
            });

            const header = panel.querySelector("#minerva-passphrase-modal-header");
            header?.addEventListener("mousedown", (e) => {
                if (e.target && e.target.id === "minerva-passphrase-modal-close") return;
                const rect = panel.getBoundingClientRect();
                apiKeyPromptDragState = {
                    startX: e.clientX,
                    startY: e.clientY,
                    startLeft: rect.left,
                    startTop: rect.top
                };
                e.preventDefault();
            });

            moveHandler = (e) => {
                if (!apiKeyPromptDragState) return;
                const dx = e.clientX - apiKeyPromptDragState.startX;
                const dy = e.clientY - apiKeyPromptDragState.startY;
                const newLeft = Math.max(8, Math.min(window.innerWidth - panel.offsetWidth - 8, apiKeyPromptDragState.startLeft + dx));
                const newTop = Math.max(8, Math.min(window.innerHeight - panel.offsetHeight - 8, apiKeyPromptDragState.startTop + dy));
                panel.style.left = `${newLeft}px`;
                panel.style.right = "auto";
                panel.style.top = `${newTop}px`;
            };
            upHandler = () => {
                if (!apiKeyPromptDragState) {
                    cleanupDragListeners();
                    return;
                }
                const rect = panel.getBoundingClientRect();
                GM_setValue(API_KEY_PROMPT_POS_STORAGE_KEY, {
                    right: Math.max(8, window.innerWidth - (rect.left + rect.width)),
                    top: Math.max(8, rect.top)
                });
                apiKeyPromptDragState = null;
                cleanupDragListeners();
            };
            document.addEventListener("mousemove", moveHandler);
            document.addEventListener("mouseup", upHandler);
            dragListenersBound = true;
        });
    }

    async function showPassphrasePrompt(message, title = "Minerva Unlock") {
        const result = await showPassphraseEntryPanel({
            title,
            message,
            submitLabel: "OK",
            showForgot: false,
            placeholder: "Enter passphrase..."
        });
        if (!result || result.action !== "submit") return null;
        return String(result.value || "").trim() || null;
    }

    async function unlockApiKeyFromVault() {
        const vault = getVaultPayload();
        if (!vault) return null;
        if (!hasWebCrypto()) {
            console.warn("[Minerva] Web Crypto unavailable; cannot unlock encrypted API key vault.");
            return null;
        }

        const unlockResult = await showPassphraseEntryPanel({
            title: "Minerva Unlock",
            message: "Enter your Minerva passphrase (required every 7 days) to unlock your API key.",
            submitLabel: "Unlock",
            showForgot: true,
            forgotLabel: "Forgot Passphrase",
            placeholder: "Unlock passphrase..."
        });
        if (!unlockResult || unlockResult.action === "cancel") {
            return "__MINERVA_UNLOCK_CANCELLED__";
        }
        if (unlockResult.action === "forgot") {
            const resetConfirmed = confirm("[Minerva] This will delete the stored encrypted API key and require a new API key + passphrase.\n\nContinue?");
            if (resetConfirmed) {
                clearAllStoredApiKeyMaterial();
                return "__MINERVA_VAULT_RESET__";
            }
            return "__MINERVA_UNLOCK_CANCELLED__";
        }
        const passphrase = String(unlockResult.value || "").trim();
        if (!passphrase) return "__MINERVA_UNLOCK_CANCELLED__";

        try {
            const plain = await decryptApiKeyFromVault(vault, passphrase);
            cacheUnlockedApiKey(plain);
            return plain;
        } catch (e) {
            console.warn("[Minerva] Failed to decrypt API key vault.", e);
            const resetConfirmed = confirm("[Minerva] Incorrect passphrase or vault could not be decrypted.\n\nChoose OK to reset the stored encrypted API key and enter a new one.\nChoose Cancel to keep Minerva locked.");
            if (resetConfirmed) {
                clearAllStoredApiKeyMaterial();
                return "__MINERVA_VAULT_RESET__";
            }
            return "__MINERVA_UNLOCK_FAILED__";
        }
    }

    async function storeApiKeySecurely(plainKey) {
        const normalized = String(plainKey || "").trim();
        if (!normalized) return { ok: false, reason: "empty" };

        if (!hasWebCrypto()) {
            GM_setValue(API_KEY_STORAGE_KEY, normalized);
            cacheUnlockedApiKey(normalized);
            return { ok: true, mode: "legacy-plain" };
        }

        const passphrase = await showPassphrasePrompt("Create a Minerva passphrase. You will re-enter it every 7 days to unlock your API key.", "Minerva Passphrase");
        if (!passphrase) return { ok: false, reason: "cancelled" };
        const confirmPassphrase = await showPassphrasePrompt("Confirm your Minerva passphrase.", "Minerva Passphrase");
        if (!confirmPassphrase) return { ok: false, reason: "cancelled" };
        if (passphrase !== confirmPassphrase) return { ok: false, reason: "mismatch" };

        const vault = await encryptApiKeyToVault(normalized, passphrase);
        GM_setValue(API_KEY_VAULT_STORAGE_KEY, vault);
        GM_setValue(API_KEY_STORAGE_KEY, ""); // remove legacy plain storage
        cacheUnlockedApiKey(normalized);
        return { ok: true, mode: "encrypted" };
    }

    async function resolveApiKeyForStartup() {
        const cached = getCachedUnlockedApiKey();
        if (cached) return cached;

        const vault = getVaultPayload();
        if (vault) {
            const unlocked = await unlockApiKeyFromVault();
            if (unlocked === "__MINERVA_UNLOCK_FAILED__") return "__MINERVA_UNLOCK_FAILED__";
            if (unlocked === "__MINERVA_UNLOCK_CANCELLED__") return "__MINERVA_UNLOCK_CANCELLED__";
            if (unlocked === "__MINERVA_VAULT_RESET__") return "__MINERVA_VAULT_RESET__";
            if (unlocked) return unlocked;
            return null;
        }

        // Backward compatibility / first-run legacy storage.
        const legacy = String(GM_getValue(API_KEY_STORAGE_KEY, "") || "").trim();
        if (legacy) {
            cacheUnlockedApiKey(legacy);
            return legacy;
        }
        return null;
    }

    function detectOwnProfileIdFromPage() {
        const scriptText = Array.from(document.scripts || []).map(s => s.textContent || "").join("\n");
        const scriptPatterns = [
            /"player_id"\s*:\s*(\d+)/i,
            /\buserID\b\s*[:=]\s*(\d+)/i,
            /\buid\b\s*[:=]\s*(\d+)/i
        ];
        for (const pattern of scriptPatterns) {
            const match = scriptText.match(pattern);
            if (match && match[1]) return String(match[1]);
        }

        const profileLinks = Array.from(document.querySelectorAll('a[href*="profiles.php?XID="]'));
        for (const link of profileLinks) {
            const href = link.getAttribute("href") || "";
            const match = href.match(/XID=(\d+)/i);
            if (!match) continue;
            const text = (link.textContent || "").trim();
            if (/\[\d+\]/.test(text) || /profile/i.test(text)) {
                return String(match[1]);
            }
        }
        return null;
    }

    function isOwnProfilePage() {
        if (!targetId) return false;
        const ownId = detectOwnProfileIdFromPage();
        return !!ownId && String(ownId) === String(targetId);
    }

    function isTrackedTarget(id) {
        if (!id) return false;
        return trackedTargets.includes(String(id));
    }

    function getAttackUrl(id) {
        return `https://www.torn.com/loader.php?sid=attack&user2ID=${encodeURIComponent(String(id))}`;
    }

    function getProfileUrl(id) {
        return `https://www.torn.com/profiles.php?XID=${encodeURIComponent(String(id))}`;
    }

    function getTrackedTargetLabel(id) {
        const state = trackedStates && trackedStates[String(id)];
        const name = String((state && state.name) || "").trim();
        if (name) return `${name} [${id}]`;
        return `[${id}]`;
    }

    function parseTravelStatusFromProfile(statusStateRaw, statusDescriptionRaw) {
        const state = String(statusStateRaw || "").trim();
        const description = String(statusDescriptionRaw || "").trim();
        const stateLower = state.toLowerCase();
        const descriptionLower = description.toLowerCase();
        const combined = `${state} ${description}`.trim();

        const traveling = /travel/i.test(state) || /traveling to/i.test(description);
        let destination = "";

        const travelToMatch = combined.match(/travel(?:l)?ing\s+to\s+([a-z][a-z\s'-]+)/i);
        if (travelToMatch && travelToMatch[1]) {
            destination = travelToMatch[1].trim();
        } else if (!traveling) {
            const locationStates = [
                "Mexico",
                "Canada",
                "Cayman Islands",
                "Switzerland",
                "Japan",
                "China",
                "UAE",
                "United Arab Emirates",
                "South Africa",
                "Hawaii",
                "Argentina",
                "United Kingdom"
            ];
            const stateNorm = state.toLowerCase();
            const found = locationStates.find(loc => stateNorm === loc.toLowerCase());
            if (found) destination = found;
        }

        return {
            traveling,
            destination: destination || ""
        };
    }

    function updateTrackCurrentButton() {
        const btn = document.getElementById("minerva-track-current");
        if (!btn || !targetId) return;
        const tracked = isTrackedTarget(targetId);
        btn.textContent = tracked ? "Untrack Current" : "Track Current";
        btn.style.color = tracked ? "#ffb0b0" : "#dffbff";
        btn.style.borderColor = tracked ? "rgba(255,100,100,0.25)" : "rgba(0,242,255,0.25)";
    }

    function showApiKeyEntryPanel(options = {}) {
        return new Promise((resolve) => {
            const existing = document.getElementById("minerva-api-key-modal");
            if (existing) existing.remove();

            const pos = getSavedApiKeyPromptPosition();
            const panel = document.createElement("div");
            panel.id = "minerva-api-key-modal";
            panel.style.cssText = `
                position: fixed;
                right: ${pos.right}px;
                top: ${pos.top}px;
                width: 360px;
                background: rgba(5, 8, 14, 0.96);
                color: #e8f6ff;
                border: 1px solid rgba(255,255,255,0.12);
                border-radius: 14px;
                box-shadow: 0 12px 28px rgba(0,0,0,0.42), 0 0 14px rgba(0,242,255,0.12);
                font-family: "Courier New", Courier, monospace;
                z-index: 10030;
                overflow: hidden;
            `;

            panel.innerHTML = `
                <div id="minerva-api-key-modal-header" style="display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; background: rgba(0,0,0,0.35); cursor: move; user-select:none;">
                    <div style="font-size:12px; font-weight:bold; color:#dffbff;">Minerva API Key</div>
                    <button id="minerva-api-key-modal-close" title="Close" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.12); border-radius:6px; width:20px; height:20px; line-height:16px; padding:0; cursor:pointer;">x</button>
                </div>
                <div style="padding:12px;">
                    <div style="font-size:12px; color:#b8c6d1; line-height:1.4;">
                        ${options.message || "Enter your Torn Public API key to enable Minerva tracking."}
                    </div>
                    <div style="margin-top:6px; font-size:11px; color:#8ea2b1; line-height:1.35;">
                        Recommended custom key access: <span style="color:#dffbff;">User -> Profile</span>
                    </div>
                    <input id="minerva-api-key-input" type="password" name="minerva_api_key_secret" autocomplete="new-password" autocapitalize="off" autocorrect="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" placeholder="Enter your Public API Key..." style="margin-top:10px; width:100%; box-sizing:border-box; background:#0a0f14; color:#e8f6ff; border:1px solid rgba(255,255,255,0.14); border-radius:8px; padding:8px 10px; outline:none;" />
                    <div style="margin-top:10px; display:flex; justify-content:space-between; align-items:center; gap:8px; flex-wrap:wrap;">
                        <button id="minerva-api-key-generate" style="background:transparent; color:#bfefff; border:1px solid rgba(0,242,255,0.18); border-radius:8px; padding:6px 10px; cursor:pointer;">Open API Page</button>
                        <div style="display:flex; justify-content:flex-end; gap:8px;">
                        <button id="minerva-api-key-cancel" style="background:transparent; color:#aab8c2; border:1px solid rgba(255,255,255,0.12); border-radius:8px; padding:6px 10px; cursor:pointer;">Cancel</button>
                        <button id="minerva-api-key-save" style="background:rgba(0,242,255,0.08); color:${CYAN_COLOR}; border:1px solid rgba(0,242,255,0.28); border-radius:8px; padding:6px 10px; cursor:pointer; font-weight:bold;">Save Key</button>
                        </div>
                    </div>
                    <div id="minerva-api-key-error" style="margin-top:8px; min-height:14px; font-size:11px; color:${PINK_COLOR};"></div>
                </div>
            `;

            document.body.appendChild(panel);

            const input = panel.querySelector("#minerva-api-key-input");
            const errorEl = panel.querySelector("#minerva-api-key-error");
            let dragListenersBound = false;
            let moveHandler = null;
            let upHandler = null;
            const cleanupDragListeners = () => {
                if (!dragListenersBound) return;
                document.removeEventListener("mousemove", moveHandler);
                document.removeEventListener("mouseup", upHandler);
                dragListenersBound = false;
            };
            const finish = (value) => {
                cleanupDragListeners();
                apiKeyPromptDragState = null;
                panel.remove();
                resolve(value);
            };

            if (input) {
                if (options.initialValue) input.value = options.initialValue;
                input.focus();
                input.select();
            }

            panel.querySelector("#minerva-api-key-modal-close")?.addEventListener("click", () => finish(null));
            panel.querySelector("#minerva-api-key-cancel")?.addEventListener("click", () => finish(null));
            panel.querySelector("#minerva-api-key-generate")?.addEventListener("click", () => {
                window.open("https://www.torn.com/preferences.php", "_blank", "noopener,noreferrer");
                if (errorEl) {
                    errorEl.style.color = "#8ea2b1";
                    errorEl.textContent = "Open the API/Keys section in Preferences, create a custom key with User -> Profile, then paste it here.";
                }
            });
            panel.querySelector("#minerva-api-key-save")?.addEventListener("click", () => {
                const value = String(input?.value || "").trim();
                if (!value) {
                    if (errorEl) errorEl.textContent = "API key is required.";
                    return;
                }
                finish(value);
            });

            input?.addEventListener("keydown", (e) => {
                if (e.key === "Enter") {
                    e.preventDefault();
                    panel.querySelector("#minerva-api-key-save")?.click();
                } else if (e.key === "Escape") {
                    e.preventDefault();
                    finish(null);
                }
            });

            const header = panel.querySelector("#minerva-api-key-modal-header");
            header?.addEventListener("mousedown", (e) => {
                if (e.target && e.target.id === "minerva-api-key-modal-close") return;
                const rect = panel.getBoundingClientRect();
                apiKeyPromptDragState = {
                    startX: e.clientX,
                    startY: e.clientY,
                    startLeft: rect.left,
                    startTop: rect.top
                };
                e.preventDefault();
            });

            moveHandler = (e) => {
                if (!apiKeyPromptDragState) return;
                const dx = e.clientX - apiKeyPromptDragState.startX;
                const dy = e.clientY - apiKeyPromptDragState.startY;
                const newLeft = Math.max(8, Math.min(window.innerWidth - panel.offsetWidth - 8, apiKeyPromptDragState.startLeft + dx));
                const newTop = Math.max(8, Math.min(window.innerHeight - panel.offsetHeight - 8, apiKeyPromptDragState.startTop + dy));
                panel.style.left = `${newLeft}px`;
                panel.style.right = "auto";
                panel.style.top = `${newTop}px`;
            };
            upHandler = () => {
                if (!apiKeyPromptDragState) {
                    cleanupDragListeners();
                    return;
                }
                const rect = panel.getBoundingClientRect();
                GM_setValue(API_KEY_PROMPT_POS_STORAGE_KEY, {
                    right: Math.max(8, window.innerWidth - (rect.left + rect.width)),
                    top: Math.max(8, rect.top)
                });
                apiKeyPromptDragState = null;
                cleanupDragListeners();
            };
            document.addEventListener("mousemove", moveHandler);
            document.addEventListener("mouseup", upHandler);
            dragListenersBound = true;
        });
    }

    function ensureTrackedTarget(id) {
        const strId = String(id);
        trackedTargets = [strId, ...trackedTargets.filter(t => t !== strId)].slice(0, maxTrackedTargets);
        GM_setValue(TRACKED_TARGETS_STORAGE_KEY, trackedTargets);
        trackedStates[strId] = trackedStates[strId] || { status: "UNKNOWN", thresholdStatus: "UNKNOWN", last: "--", name: strId };
        renderTrackedList();
        updateTrackCurrentButton();
    }

    function removeTrackedTarget(id) {
        const strId = String(id);
        trackedTargets = trackedTargets.filter(t => t !== strId);
        GM_setValue(TRACKED_TARGETS_STORAGE_KEY, trackedTargets);
        renderTrackedList();
        updateTrackCurrentButton();
    }

    function clearTrackedTargetsKeepCurrent() {
        trackedTargets = targetId ? [String(targetId)] : [];
        GM_setValue(TRACKED_TARGETS_STORAGE_KEY, trackedTargets);
        if (targetId) {
            trackedStates[String(targetId)] = trackedStates[String(targetId)] || { status: "UNKNOWN", thresholdStatus: "UNKNOWN", last: "--", name: String(targetId) };
        }
        renderTrackedList();
        updateTrackCurrentButton();
    }

    function setWidgetHidden(hidden) {
        GM_setValue(WIDGET_HIDDEN_STORAGE_KEY, !!hidden);
        const widget = document.getElementById("minerva-corner-widget");
        const reopen = document.getElementById("minerva-corner-reopen");
        if (widget) widget.style.display = hidden ? "none" : "block";
        if (reopen) {
            const pos = widget ? {
                left: parseInt(widget.style.left, 10) || 18,
                bottom: parseInt(widget.style.bottom, 10) || 18
            } : getSavedWidgetPosition();
            reopen.style.left = `${pos.left}px`;
            reopen.style.bottom = `${pos.bottom}px`;
            reopen.style.display = hidden ? "flex" : "none";
        }
    }

    function setWidgetCompact(compact) {
        GM_setValue(WIDGET_COMPACT_STORAGE_KEY, !!compact);
        const details = document.getElementById("minerva-corner-details");
        const btn = document.getElementById("minerva-corner-compact");
        const widget = document.getElementById("minerva-corner-widget");
        if (details) details.style.display = compact ? "none" : "block";
        if (btn) {
            btn.textContent = compact ? "+" : "_";
            btn.title = compact ? "Expand" : "Compact";
        }
        if (widget) {
            widget.style.width = compact ? "260px" : "420px";
            if (!compact) autoSizeCornerWidget();
            clampCornerWidgetIntoViewport();
        }
    }

    function setWidgetLocked(locked) {
        GM_setValue(WIDGET_LOCKED_STORAGE_KEY, !!locked);
        const btn = document.getElementById("minerva-corner-lock");
        const handle = document.getElementById("minerva-corner-drag-handle");
        if (btn) {
            btn.textContent = locked ? "🔒" : "🔓";
            btn.title = locked ? "Unlock Position" : "Lock Position";
            btn.style.color = locked ? "#ffd27a" : "#9fb6c6";
            btn.style.borderColor = locked ? "rgba(255,210,122,0.35)" : "rgba(255,255,255,0.15)";
        }
        if (handle) handle.style.cursor = locked ? "default" : "move";
    }

    function clampCornerWidgetIntoViewport() {
        const widget = document.getElementById("minerva-corner-widget");
        if (!widget || widget.style.display === "none") return;
        const rect = widget.getBoundingClientRect();
        const margin = 8;
        let newLeft = parseInt(widget.style.left, 10);
        let newBottom = parseInt(widget.style.bottom, 10);
        if (!Number.isFinite(newLeft)) newLeft = 18;
        if (!Number.isFinite(newBottom)) newBottom = 18;

        if (rect.left < margin) newLeft += (margin - rect.left);
        if (rect.right > window.innerWidth - margin) newLeft -= (rect.right - (window.innerWidth - margin));
        if (rect.top < margin) newBottom -= (margin - rect.top);
        if (rect.bottom > window.innerHeight - margin) newBottom += (rect.bottom - (window.innerHeight - margin));

        newLeft = Math.max(margin, Math.min(window.innerWidth - widget.offsetWidth - margin, newLeft));
        newBottom = Math.max(margin, Math.min(window.innerHeight - widget.offsetHeight - margin, newBottom));

        widget.style.left = `${newLeft}px`;
        widget.style.bottom = `${newBottom}px`;
        GM_setValue(WIDGET_POS_STORAGE_KEY, { left: newLeft, bottom: newBottom });
    }

    function snapCornerWidgetToGrid(widget) {
        if (!widget) return;

        const margin = 12;
        const rect = widget.getBoundingClientRect();
        const maxLeft = Math.max(margin, window.innerWidth - rect.width - margin);
        const maxBottom = Math.max(margin, window.innerHeight - rect.height - margin);

        let left = parseInt(widget.style.left, 10);
        let bottom = parseInt(widget.style.bottom, 10);
        if (!Number.isFinite(left)) left = margin;
        if (!Number.isFinite(bottom)) bottom = margin;

        const stepX = Math.max(40, Math.round(rect.width / 2));
        const stepY = Math.max(36, Math.round(rect.height / 2));

        const snappedLeft = Math.max(
            margin,
            Math.min(maxLeft, margin + Math.round((left - margin) / stepX) * stepX)
        );
        const snappedBottom = Math.max(
            margin,
            Math.min(maxBottom, margin + Math.round((bottom - margin) / stepY) * stepY)
        );

        widget.style.left = `${snappedLeft}px`;
        widget.style.bottom = `${snappedBottom}px`;
        GM_setValue(WIDGET_POS_STORAGE_KEY, { left: snappedLeft, bottom: snappedBottom });
    }

    function autoSizeCornerWidget() {
        const widget = document.getElementById("minerva-corner-widget");
        const details = document.getElementById("minerva-corner-details");
        if (!widget || !details) return;
        if (details.style.display === "none") return; // compact mode

        const minWidth = 340;
        const maxWidth = Math.max(minWidth, window.innerWidth - 24);
        let contentWidth = 300; // stable base width for header + threshold chrome

        // Estimate row content width from text lengths to avoid flex/scrollWidth feedback loops.
        const nameValues = trackedTargets.map(id => {
            const state = trackedStates[id] || {};
            const baseName = String(state.name || id || "");
            return `${String(id) === String(targetId) ? "▶" : ""}${baseName}`;
        });
        const statusValues = trackedTargets.map(id => String((trackedStates[id] && trackedStates[id].status) || "UNKNOWN"));
        const lastValues = trackedTargets.map(id => String((trackedStates[id] && trackedStates[id].last) || "--"));

        const maxNameChars = nameValues.reduce((m, s) => Math.max(m, s.length), 0);
        const maxStatusChars = statusValues.reduce((m, s) => Math.max(m, s.length), 0);
        const maxLastChars = lastValues.reduce((m, s) => Math.max(m, s.length), 0);
        const charPx = 7; // close enough for Courier New at this size
        const estimatedRowWidth =
            18 + // dot + spacing
            (maxNameChars * charPx) +
            18 + // gap between left/right sections
            (maxStatusChars * charPx) +
            12 +
            Math.min(maxLastChars, 36) * charPx + // row text is ellipsized
            54 + // attack + remove buttons
            28;  // row padding + borders

        contentWidth = Math.max(contentWidth, estimatedRowWidth);

        const paddedWidth = Math.ceil(contentWidth + 24);
        const targetWidth = Math.max(minWidth, Math.min(maxWidth, paddedWidth));
        widget.style.width = `${targetWidth}px`;
    }

    function autoSizeCornerWidgetListHeight() {
        const list = document.getElementById("minerva-corner-list");
        const widget = document.getElementById("minerva-corner-widget");
        const details = document.getElementById("minerva-corner-details");
        if (!list || !widget || !details) return;
        if (details.style.display === "none") return; // compact mode

        const rows = Array.from(list.children).filter(el => el instanceof HTMLElement);
        if (rows.length === 0) {
            list.style.maxHeight = "";
            list.style.overflowY = "visible";
            return;
        }

        const sampleRow = rows[0];
        const rowHeight = Math.max(24, Math.ceil(sampleRow.getBoundingClientRect().height || 24));
        const rowGap = 5; // matches CSS gap in list
        const desiredVisibleRows = Math.max(rows.length, Math.min(maxTrackedTargets, rows.length));
        const desiredHeight = desiredVisibleRows * rowHeight + Math.max(0, desiredVisibleRows - 1) * rowGap;

        const widgetRect = widget.getBoundingClientRect();
        const topMargin = 12;
        const bottomMargin = 12;
        const availableHeight = Math.max(
            80,
            Math.floor(window.innerHeight - widgetRect.top - topMargin - bottomMargin)
        );

        // Reserve space for header/threshold labels within the widget.
        const chromeHeight = Math.max(70, Math.ceil(widgetRect.height - list.getBoundingClientRect().height));
        const maxListHeight = Math.max(60, availableHeight - chromeHeight);
        const finalListHeight = Math.max(24, Math.min(desiredHeight, maxListHeight));

        list.style.maxHeight = `${finalListHeight}px`;
        list.style.overflowY = desiredHeight > finalListHeight ? "auto" : "visible";
        list.style.paddingRight = desiredHeight > finalListHeight ? "2px" : "0";
    }

    function isCornerWidgetControl(el) {
        if (!(el instanceof Element)) return false;
        return !!el.closest("#minerva-corner-hide, #minerva-corner-compact, #minerva-corner-lock, [data-minerva-remove-id], [data-minerva-attack-id], [data-minerva-ping-id]");
    }

    function notifyIfHidden(title, text) {
        const now = Date.now();
        if (now - lastBackgroundNotificationAt < 30000) return; // avoid spam
        lastBackgroundNotificationAt = now;

        if (document.hidden) {
            let usedBrowserNotification = false;

            if ("Notification" in window) {
                if (Notification.permission === "granted") {
                    const n = new Notification(title, {
                        body: text,
                        silent: true,
                        tag: `minerva-${Date.now()}`
                    });
                    usedBrowserNotification = true;
                    setTimeout(() => { try { n.close(); } catch (_) {} }, 5000);
                } else if (Notification.permission === "default") {
                    Notification.requestPermission().then((perm) => {
                        if (perm === "granted") {
                            const n = new Notification(title, {
                                body: text,
                                silent: true,
                                tag: `minerva-${Date.now()}`
                            });
                            setTimeout(() => { try { n.close(); } catch (_) {} }, 5000);
                        }
                    }).catch(() => {});
                }
            }

            if (!usedBrowserNotification) {
                GM_notification({
                    text,
                    title,
                    timeout: 4000,
                    silent: true
                });
            }
            return;
        }

        showMinervaToast(title, text);
    }

    function ensureToastHost() {
        let host = document.getElementById("minerva-toast-host");
        if (host) return host;

        const saved = getSavedToastHostPosition();
        host = document.createElement("div");
        host.id = "minerva-toast-host";
        host.style.cssText = `
            position: fixed;
            ${Number.isFinite(saved.left) ? `left: ${saved.left}px;` : ""}
            ${!Number.isFinite(saved.left) ? `right: ${Number.isFinite(saved.right) ? saved.right : 16}px;` : ""}
            bottom: ${Number.isFinite(saved.bottom) ? saved.bottom : 84}px;
            display: flex;
            flex-direction: column;
            gap: 8px;
            z-index: 10020;
            pointer-events: none;
            max-width: 360px;
        `;
        document.body.appendChild(host);

        if (!toastDocMouseMoveHandler || !toastDocMouseUpHandler || !toastWindowResizeHandler) {
            toastDocMouseMoveHandler = (e) => {
                if (!isLiveMinervaRuntime()) return;
                if (!toastDragState) return;
                const toastHost = document.getElementById("minerva-toast-host");
                if (!toastHost) return;
                const dx = e.clientX - toastDragState.startX;
                const dy = e.clientY - toastDragState.startY;
                const newLeft = Math.max(8, Math.min(window.innerWidth - toastHost.offsetWidth - 8, toastDragState.startLeft + dx));
                const newTop = Math.max(8, Math.min(window.innerHeight - toastHost.offsetHeight - 8, toastDragState.startTop + dy));
                const newBottom = Math.max(8, window.innerHeight - (newTop + toastHost.offsetHeight));
                toastHost.style.left = `${newLeft}px`;
                toastHost.style.right = "auto";
                toastHost.style.bottom = `${newBottom}px`;
            };
            toastDocMouseUpHandler = () => {
                if (!isLiveMinervaRuntime()) return;
                if (!toastDragState) return;
                const toastHost = document.getElementById("minerva-toast-host");
                if (toastHost) {
                    const rect = toastHost.getBoundingClientRect();
                    GM_setValue(TOAST_HOST_POS_STORAGE_KEY, {
                        left: Math.max(8, Math.round(rect.left)),
                        bottom: Math.max(8, Math.round(window.innerHeight - rect.bottom)),
                        right: null
                    });
                }
                toastDragState = null;
            };
            toastWindowResizeHandler = () => {
                if (!isLiveMinervaRuntime()) return;
                const toastHost = document.getElementById("minerva-toast-host");
                if (!toastHost) return;
                const rect = toastHost.getBoundingClientRect();
                let left = rect.left;
                let top = rect.top;
                left = Math.max(8, Math.min(window.innerWidth - toastHost.offsetWidth - 8, left));
                top = Math.max(8, Math.min(window.innerHeight - toastHost.offsetHeight - 8, top));
                toastHost.style.left = `${left}px`;
                toastHost.style.right = "auto";
                toastHost.style.bottom = `${Math.max(8, Math.round(window.innerHeight - (top + toastHost.offsetHeight)))}px`;
            };
            document.addEventListener("mousemove", toastDocMouseMoveHandler);
            document.addEventListener("mouseup", toastDocMouseUpHandler);
            window.addEventListener("resize", toastWindowResizeHandler);
        }

        return host;
    }

    function showMinervaToast(title, text, durationMs = 8000) {
        const host = ensureToastHost();
        if (!host) return;

        const toast = document.createElement("div");
        toast.style.cssText = `
            pointer-events: auto;
            background: rgba(5, 8, 14, 0.94);
            color: #e8f6ff;
            border: 1px solid rgba(255,255,255,0.12);
            border-left: 3px solid ${CYAN_COLOR};
            border-radius: 12px;
            box-shadow: 0 10px 24px rgba(0,0,0,0.4), 0 0 12px rgba(0,242,255,0.12);
            padding: 10px 12px;
            font-family: "Courier New", Courier, monospace;
            transform: translateY(8px);
            opacity: 0;
            transition: opacity 0.2s ease, transform 0.2s ease;
        `;
        toast.innerHTML = `
            <div data-minerva-toast-drag-handle="1" style="display:flex; align-items:center; justify-content:space-between; gap:8px; cursor:move;">
                <div style="font-size:12px; font-weight:bold; color:#dffbff;">${title}</div>
                <button type="button" data-minerva-toast-close="1" title="Close" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.12); border-radius:5px; width:18px; height:18px; line-height:14px; padding:0; cursor:pointer; font-size:11px;">x</button>
            </div>
            <div style="margin-top:4px; font-size:12px; color:#b8c6d1;">${text}</div>
        `;
        host.appendChild(toast);

        let removed = false;
        const removeToast = () => {
            if (removed) return;
            removed = true;
            toast.style.opacity = "0";
            toast.style.transform = "translateY(6px)";
            setTimeout(() => toast.remove(), 220);
        };

        toast.querySelector('[data-minerva-toast-close="1"]')?.addEventListener("click", (e) => {
            e.stopPropagation();
            removeToast();
        });
        toast.querySelector('[data-minerva-toast-drag-handle="1"]')?.addEventListener("mousedown", (e) => {
            if (e.target instanceof Element && e.target.closest('[data-minerva-toast-close="1"]')) return;
            const hostRect = host.getBoundingClientRect();
            toastDragState = {
                startX: e.clientX,
                startY: e.clientY,
                startLeft: hostRect.left,
                startTop: hostRect.top
            };
            e.preventDefault();
        });

        requestAnimationFrame(() => {
            toast.style.opacity = "1";
            toast.style.transform = "translateY(0)";
        });

        setTimeout(() => {
            removeToast();
        }, durationMs);
    }

    function showMinervaUpdateToast(latestVersion, releaseUrl) {
        latestAvailableVersion = String(latestVersion || "").trim();
        latestAvailableReleaseUrl = GREASYFORK_SCRIPT_PAGE_URL;
        updateAvailableUiBadge();
        const host = ensureToastHost();
        if (!host) return;

        const toast = document.createElement("div");
        toast.style.cssText = `
            pointer-events: auto;
            background: rgba(5, 8, 14, 0.96);
            color: #e8f6ff;
            border: 1px solid rgba(255,255,255,0.12);
            border-left: 3px solid #42ff8c;
            border-radius: 12px;
            box-shadow: 0 10px 24px rgba(0,0,0,0.4), 0 0 12px rgba(66,255,140,0.12);
            padding: 10px 12px;
            font-family: "Courier New", Courier, monospace;
            transform: translateY(8px);
            opacity: 0;
            transition: opacity 0.2s ease, transform 0.2s ease;
        `;
        toast.innerHTML = `
            <div data-minerva-toast-drag-handle="1" style="display:flex; align-items:center; justify-content:space-between; gap:8px; cursor:move;">
                <div style="font-size:12px; font-weight:bold; color:#dffbff;">Minerva Update Available</div>
                <button type="button" data-minerva-toast-close="1" title="Close" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.12); border-radius:5px; width:18px; height:18px; line-height:14px; padding:0; cursor:pointer; font-size:11px;">x</button>
            </div>
            <div style="margin-top:4px; font-size:12px; color:#b8c6d1;">Current: <span style="color:#fff;">${MINERVA_VERSION}</span> | Latest: <span style="color:#42ff8c;">${latestVersion}</span></div>
            <div style="margin-top:8px; display:flex; gap:8px; justify-content:flex-end;">
                <button type="button" data-minerva-update-dismiss="1" style="background:transparent; color:#aab8c2; border:1px solid rgba(255,255,255,0.12); border-radius:6px; padding:4px 8px; cursor:pointer; font-size:11px;">Dismiss</button>
                <button type="button" data-minerva-update-open="1" style="background:rgba(66,255,140,0.08); color:#42ff8c; border:1px solid rgba(66,255,140,0.28); border-radius:6px; padding:4px 8px; cursor:pointer; font-size:11px; font-weight:bold;">Update</button>
            </div>
        `;
        host.appendChild(toast);

        let removed = false;
        const removeToast = () => {
            if (removed) return;
            removed = true;
            toast.style.opacity = "0";
            toast.style.transform = "translateY(6px)";
            setTimeout(() => toast.remove(), 220);
        };

        toast.querySelector('[data-minerva-toast-close="1"]')?.addEventListener("click", (e) => {
            e.stopPropagation();
            removeToast();
        });
        toast.querySelector('[data-minerva-update-dismiss="1"]')?.addEventListener("click", (e) => {
            e.stopPropagation();
            GM_setValue(VERSION_CHECK_DISMISSED_VERSION_STORAGE_KEY, latestVersion);
            addLog(`Dismissed update prompt for ${latestVersion}.`, "INFO");
            removeToast();
        });
        toast.querySelector('[data-minerva-update-open="1"]')?.addEventListener("click", (e) => {
            e.stopPropagation();
            window.open(GREASYFORK_SCRIPT_PAGE_URL, "_blank", "noopener,noreferrer");
            removeToast();
        });
        toast.querySelector('[data-minerva-toast-drag-handle="1"]')?.addEventListener("mousedown", (e) => {
            if (e.target instanceof Element && e.target.closest('button')) return;
            const hostRect = host.getBoundingClientRect();
            toastDragState = {
                startX: e.clientX,
                startY: e.clientY,
                startLeft: hostRect.left,
                startTop: hostRect.top
            };
            e.preventDefault();
        });

        requestAnimationFrame(() => {
            toast.style.opacity = "1";
            toast.style.transform = "translateY(0)";
        });
    }

    function parseVersionParts(versionText) {
        const normalized = String(versionText || "").trim().replace(/^v/i, "");
        if (!normalized) return [0, 0, 0];
        return normalized.split(".").map(part => {
            const n = parseInt(part, 10);
            return Number.isFinite(n) ? n : 0;
        });
    }

    function compareVersions(a, b) {
        const av = parseVersionParts(a);
        const bv = parseVersionParts(b);
        const len = Math.max(av.length, bv.length);
        for (let i = 0; i < len; i++) {
            const ai = av[i] || 0;
            const bi = bv[i] || 0;
            if (ai > bi) return 1;
            if (ai < bi) return -1;
        }
        return 0;
    }

    function maybeCheckForMinervaUpdate(options = {}) {
        const force = !!options.force;
        const showNoUpdateToast = !!options.showNoUpdateToast;
        if (versionCheckInFlight) return;
        const lastCheckAt = Number(GM_getValue(VERSION_CHECK_LAST_AT_STORAGE_KEY, 0));
        if (!force && Number.isFinite(lastCheckAt) && (Date.now() - lastCheckAt) < VERSION_CHECK_INTERVAL_MS) return;

        versionCheckInFlight = true;
        GM_setValue(VERSION_CHECK_LAST_AT_STORAGE_KEY, Date.now());

        GM_xmlhttpRequest({
            method: "GET",
            url: GITHUB_LATEST_RELEASE_API_URL,
            headers: {
                "Accept": "application/vnd.github+json"
            },
            timeout: 10000,
            onload: function(response) {
                versionCheckInFlight = false;
                if (response.status !== 200) {
                    addLog(`Version check skipped (HTTP ${response.status}).`, "DIAGNOSTIC");
                    return;
                }
                try {
                    const data = JSON.parse(response.responseText || "{}");
                    const latest = String(data.tag_name || "").trim();
                    if (!latest) {
                        if (showNoUpdateToast) showMinervaToast("Minerva Updates", "Version check did not return a valid release tag.", 5000);
                        return;
                    }
                    const current = MINERVA_VERSION;
                    if (compareVersions(latest, current) <= 0) {
                        latestAvailableVersion = "";
                        latestAvailableReleaseUrl = "";
                        updateAvailableUiBadge();
                        addLog(`Version check complete. Current version ${current} is up to date.`, "INFO");
                        if (showNoUpdateToast) {
                            showMinervaToast("Minerva Updates", `You are on the latest version (${current}).`, 4500);
                        }
                        return;
                    }
                    const dismissed = String(GM_getValue(VERSION_CHECK_DISMISSED_VERSION_STORAGE_KEY, "") || "").trim();
                    latestAvailableVersion = latest;
                    latestAvailableReleaseUrl = GREASYFORK_SCRIPT_PAGE_URL;
                    updateAvailableUiBadge();
                    if (!force && dismissed && dismissed === latest) return;
                    addLog(`New Minerva version available: ${latest} (current ${current}).`, "INFO");
                    showMinervaUpdateToast(latest, GREASYFORK_SCRIPT_PAGE_URL);
                } catch (e) {
                    updateAvailableUiBadge();
                    addLog(`Version check parse failed: ${e.message}`, "DIAGNOSTIC");
                    if (showNoUpdateToast) showMinervaToast("Minerva Updates", "Version check failed while parsing the response.", 5000);
                }
            },
            ontimeout: function() {
                versionCheckInFlight = false;
                addLog("Version check timed out.", "DIAGNOSTIC");
                if (showNoUpdateToast) showMinervaToast("Minerva Updates", "Version check timed out.", 4500);
            },
            onerror: function() {
                versionCheckInFlight = false;
                addLog("Version check network error.", "DIAGNOSTIC");
                if (showNoUpdateToast) showMinervaToast("Minerva Updates", "Version check failed (network error).", 4500);
            }
        });
    }

    function getStatusColor(status) {
        const statusText = String(status || "").toUpperCase();
        if (statusText.startsWith("ACTIVE")) return CYAN_COLOR;
        if (statusText.startsWith("READY")) return CYAN_COLOR;
        if (statusText.startsWith("INACTIVE <")) return "#ffbf66";
        if (status === "PAUSED") return "#ffbf66";
        if (status === "UNKNOWN") return "#9fb6c6";
        return PINK_COLOR;
    }

    function formatThresholdLabel(seconds) {
        if (!Number.isFinite(seconds) || seconds <= 0) return "0s";
        if (seconds % 60 === 0) return `${Math.floor(seconds / 60)}m`;
        return `${seconds}s`;
    }

    function getManualPingCooldownRemainingMs() {
        return Math.max(0, Number(manualPingCooldownUntil || 0) - Date.now());
    }

    function isManualPingCooldownActive() {
        if (getManualPingCooldownRemainingMs() <= 0) {
            manualPingCooldownUntil = 0;
            return false;
        }
        return true;
    }

    function getManualPingCooldownLabel() {
        const remainingMs = getManualPingCooldownRemainingMs();
        if (remainingMs <= 0) return "";
        return `${Math.ceil(remainingMs / 1000)}s`;
    }

    function scheduleManualPingCooldownRefresh() {
        const remainingMs = getManualPingCooldownRemainingMs();
        if (remainingMs <= 0) return;
        setTimeout(() => {
            if (!isManualPingCooldownActive()) {
                renderTrackedList();
            }
        }, remainingMs + 50);
    }

    function tryConsumeManualPingClick() {
        const now = Date.now();

        if (isManualPingCooldownActive()) {
            return {
                ok: false,
                reason: "cooldown",
                remainingMs: getManualPingCooldownRemainingMs()
            };
        }

        manualPingClickTimestamps = manualPingClickTimestamps.filter(ts => now - ts < MANUAL_PING_WINDOW_MS);
        manualPingClickTimestamps.push(now);

        if (manualPingClickTimestamps.length > MANUAL_PING_MAX_CLICKS_PER_WINDOW) {
            manualPingCooldownUntil = now + MANUAL_PING_COOLDOWN_MS;
            manualPingClickTimestamps = [];
            scheduleManualPingCooldownRefresh();
            return {
                ok: false,
                reason: "rate_limited",
                remainingMs: MANUAL_PING_COOLDOWN_MS
            };
        }

        return { ok: true };
    }

    function updateManualPingCooldownVisuals() {
        const badge = document.getElementById("minerva-corner-ping-cooldown");
        if (!badge) return;

        if (isManualPingCooldownActive()) {
            badge.style.display = "inline-flex";
            badge.textContent = `↻ ${getManualPingCooldownLabel()}`;
            badge.title = `Manual ping cooldown: ${getManualPingCooldownLabel()} remaining`;
        } else {
            badge.style.display = "none";
            badge.textContent = "";
            badge.title = "";
        }
    }

    function positionSettingsPopup() {
        const popup = document.getElementById("minerva-settings-panel");
        const gearBtn = document.getElementById("minerva-settings-gear");
        if (!popup || !gearBtn || popup.style.position !== "fixed") return;

        const rect = gearBtn.getBoundingClientRect();
        const margin = 10;
        const desiredWidth = Math.min(980, Math.max(560, window.innerWidth - 24));
        popup.style.width = `${desiredWidth}px`;

        let left = rect.right - desiredWidth;
        let top = rect.bottom + 8;
        left = Math.max(8, Math.min(window.innerWidth - desiredWidth - 8, left));
        top = Math.max(8, Math.min(window.innerHeight - popup.offsetHeight - 8, top));

        popup.style.left = `${left}px`;
        popup.style.top = `${top}px`;
    }

    function setSettingsPopupOpen(open) {
        const popup = document.getElementById("minerva-settings-panel");
        const gearBtn = document.getElementById("minerva-settings-gear");
        if (!popup || !gearBtn || popup.style.position !== "fixed") return;

        isSettingsPopupOpen = !!open;
        popup.style.display = isSettingsPopupOpen ? "block" : "none";
        gearBtn.style.color = isSettingsPopupOpen ? CYAN_COLOR : "#9fb6c6";
        gearBtn.style.borderColor = isSettingsPopupOpen ? "rgba(0,242,255,0.28)" : "rgba(255,255,255,0.15)";
        if (isSettingsPopupOpen) {
            positionSettingsPopup();
        }
    }

    // --- Core UI Construction ---
    function buildUI() {
        if (document.getElementById("minerva-master-container")) return null; 
        ensureMinervaStyleOverrides();

        const wrapper = document.createElement("div");
        wrapper.id = "minerva-master-container";
        wrapper.style.cssText = `
            width: 100%;
            background: rgba(10, 15, 20, 0.85);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            border: 1px solid ${isTracking ? CYAN_COLOR : PINK_COLOR};
            border-radius: 12px;
            margin-bottom: 15px;
            box-shadow: 0 0 15px ${isTracking ? CYAN_COLOR + '40' : PINK_COLOR + '40'};
            color: #e0e0e0;
            font-family: "Courier New", Courier, monospace;
            overflow: hidden;
            transition: all 0.3s ease;
            z-index: 9999;
        `;

        const header = document.createElement("div");
        header.style.cssText = `
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 15px;
            cursor: pointer;
            background: rgba(0, 0, 0, 0.5);
            user-select: none;
        `;
        header.innerHTML = `
            <div style="font-weight: bold; font-size: 15px; letter-spacing: 1px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-width:0;">
                <span style="display:inline-flex; align-items:center; min-width:0;">
                <span style="color: #ffffff;">[ MINERVA ] SIGNAL: </span>
                    <span id="minerva-status-text" style="color: ${isTracking ? CYAN_COLOR : PINK_COLOR}; text-shadow: 0 0 8px ${isTracking ? CYAN_COLOR : PINK_COLOR};">AWAITING PING</span>
                </span>
                <span id="minerva-update-available-badge" role="button" tabindex="0" title="" style="display:none; color:${PINK_COLOR}; font-weight:bold; font-size:13px; letter-spacing:0.5px; text-shadow:0 0 7px ${PINK_COLOR}; cursor:pointer; white-space:nowrap; user-select:none;">UPDATE AVAILABLE</span>
            </div>
            <div style="font-size: 13px; opacity: 0.9;">
                Next Ping: <span id="minerva-countdown" style="font-weight: bold;">--</span>s <span style="margin-left:8px; font-size:10px;">▼</span>
            </div>
        `;
        
        const settings = document.createElement("div");
        settings.id = "minerva-settings-panel";
        settings.style.cssText = `
            display: none;
            padding: 15px;
            border-top: 1px solid rgba(255, 255, 255, 0.1);
            background: rgba(0, 0, 0, 0.3);
            font-size: 14px;
        `;
        
        settings.innerHTML = `
            <div style="display:flex; flex-direction:column; gap:12px;">
                <div style="display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:10px; padding:8px 10px; border:1px solid rgba(255,255,255,0.08); border-radius:8px; background:rgba(255,255,255,0.02);">
                    <div style="font-size:12px; color:#9fb6c6;">Target List: <span style="color:${CYAN_COLOR}; font-weight:bold;">MANUAL</span> <span style="color:#7f8d98;">(use Track/Untrack Current)</span></div>
                    <div style="display:flex; gap:18px; align-items:center; flex-wrap:wrap;">
                        <label style="display:flex; align-items:center; gap:10px;">
                            <strong style="color:#fff;">Inactive Threshold:</strong>
                            <select id="minerva-time-select" style="background:#0a0f14; color:${CYAN_COLOR}; border:1px solid ${CYAN_COLOR}; padding:4px 10px; border-radius:6px; outline:none; cursor:pointer;">
                                <option value="60" ${thresholdSeconds === 60 ? 'selected' : ''}>1 Minute</option>
                                <option value="300" ${thresholdSeconds === 300 ? 'selected' : ''}>5 Minutes</option>
                                <option value="600" ${thresholdSeconds === 600 ? 'selected' : ''}>10 Minutes</option>
                                <option value="900" ${thresholdSeconds === 900 ? 'selected' : ''}>15 Minutes</option>
                            </select>
                        </label>
                        <label style="display:flex; align-items:center; gap:10px;">
                            <strong style="color:#fff;">Max Tracked:</strong>
                            <select id="minerva-max-tracked-select" style="background:#0a0f14; color:${CYAN_COLOR}; border:1px solid ${CYAN_COLOR}; padding:4px 10px; border-radius:6px; outline:none; cursor:pointer;">
                                <option value="3" ${maxTrackedTargets === 3 ? 'selected' : ''}>3</option>
                                <option value="5" ${maxTrackedTargets === 5 ? 'selected' : ''}>5</option>
                                <option value="8" ${maxTrackedTargets === 8 ? 'selected' : ''}>8</option>
                                <option value="12" ${maxTrackedTargets === 12 ? 'selected' : ''}>12</option>
                            </select>
                        </label>
                    </div>
                </div>
                <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:center;">
                    <button id="minerva-track-current" style="background: transparent; border: 1px solid rgba(0,242,255,0.25); color: #dffbff; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px;">Track Current</button>
                    <button id="minerva-key-reset" style="background: transparent; border: 1px solid #774444; color: #ff9a9a; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px;">Reset API Key</button>
                    <button id="minerva-update-check" style="background: transparent; border: 1px solid rgba(66,255,140,0.2); color: #b9ffd8; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px;">Check Updates</button>
                    <button id="minerva-toast-test" style="background: transparent; border: 1px solid rgba(0,242,255,0.2); color: #bfefff; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px;">View Toast</button>
                    <button id="minerva-tracked-clear" style="background: transparent; border: 1px solid #555; color: #d0d0d0; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px;">Clear Tracked</button>
                    <button id="minerva-log-toggle" style="background: transparent; border: 1px solid #555; color: #aaa; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px; transition: 0.2s;">Show Logs ▼</button>
                </div>
            </div>

            <div id="minerva-log-container" style="display: none; margin-top: 15px; padding: 10px; background: rgba(0, 0, 0, 0.7); border: 1px solid #333; border-radius: 6px; max-height: 150px; overflow-y: auto; font-size: 12px; word-wrap: break-word;">
                <div id="minerva-log-content"></div>
            </div>
        `;

        wrapper.appendChild(header);
        wrapper.appendChild(settings);

        // UI Listeners
        const ownProfileControls = isOwnProfilePage();
        header.addEventListener("click", () => {
            if (ownProfileControls) return;
            isUiOpen = !isUiOpen;
            settings.style.display = isUiOpen ? "block" : "none";
        });

        const updateBadgeEl = wrapper.querySelector("#minerva-update-available-badge");
        const openUpdateFromBadge = (e) => {
            if (e) e.stopPropagation();
            if (!latestAvailableVersion) return;
            window.open(latestAvailableReleaseUrl || GITHUB_RELEASES_PAGE_URL, "_blank", "noopener,noreferrer");
        };
        updateBadgeEl?.addEventListener("click", openUpdateFromBadge);
        updateBadgeEl?.addEventListener("keydown", (e) => {
            if (e.key === "Enter" || e.key === " ") {
                e.preventDefault();
                openUpdateFromBadge(e);
            }
        });

        wrapper.querySelector("#minerva-time-select").addEventListener("change", (e) => {
            thresholdSeconds = parseInt(e.target.value);
            GM_setValue("minerva-threshold", thresholdSeconds);
            addLog(`Threshold changed to ${thresholdSeconds / 60} minute(s).`, "INFO");
            if (isTracking) countdownTimer = 0; 
        });

        wrapper.querySelector("#minerva-max-tracked-select").addEventListener("change", (e) => {
            maxTrackedTargets = parseInt(e.target.value);
            if (!Number.isFinite(maxTrackedTargets) || maxTrackedTargets < 1) maxTrackedTargets = 8;
            GM_setValue(MAX_TRACKED_TARGETS_STORAGE_KEY, maxTrackedTargets);
            trackedTargets = trackedTargets.slice(0, maxTrackedTargets);
            GM_setValue(TRACKED_TARGETS_STORAGE_KEY, trackedTargets);
            renderTrackedList();
            addLog(`Max tracked targets set to ${maxTrackedTargets}.`, "INFO");
        });

        wrapper.querySelector("#minerva-log-toggle").addEventListener("click", (e) => {
            isLogOpen = !isLogOpen;
            document.getElementById("minerva-log-container").style.display = isLogOpen ? "block" : "none";
            e.target.innerText = isLogOpen ? "Hide Logs ▲" : "Show Logs ▼";
            e.target.style.color = isLogOpen ? "#fff" : "#aaa";
        });

        wrapper.querySelector("#minerva-track-current").addEventListener("click", () => {
            if (!targetId) return;
            if (isTrackedTarget(targetId)) {
                removeTrackedTarget(targetId);
                addLog(`Removed current target [${targetId}] from tracked list.`, "INFO");
            } else {
                ensureTrackedTarget(targetId);
                hasWarnedNoTargets = false;
                addLog(`Added current target [${targetId}] to tracked list.`, "INFO");
                if (isTracking) countdownTimer = 0;
            }
        });

        wrapper.querySelector("#minerva-key-reset").addEventListener("click", () => {
            const confirmed = confirm("[Minerva] Reset stored Torn API key?");
            if (!confirmed) return;

            clearAllStoredApiKeyMaterial();
            apiKey = "";
            addLog("Stored API key cleared. Prompting for a new key.", "DIAGNOSTIC");

            showApiKeyEntryPanel({
                message: "Enter a new Torn Public API key for Minerva."
            }).then(async (newKey) => {
                if (!newKey) {
                    addLog("No new API key entered. Tracking requests will fail until a key is set.", "ERROR");
                    updateVisuals(PINK_COLOR, "NO API KEY");
                    return;
                }

                const storeResult = await storeApiKeySecurely(newKey.trim());
                if (!storeResult.ok) {
                    if (storeResult.reason === "mismatch") {
                        addLog("Passphrase confirmation mismatch. API key was not updated.", "ERROR");
                    } else {
                        addLog("API key update cancelled before passphrase setup completed.", "ERROR");
                    }
                    updateVisuals(PINK_COLOR, "NO API KEY");
                    return;
                }
                apiKey = newKey.trim();
                addLog(`API key updated (${storeResult.mode === "encrypted" ? "encrypted vault + 7d unlock" : "legacy plain"}).`, "INFO");

                if (isTracking) {
                    countdownTimer = 0;
                    addLog("Forcing immediate ping with new key.", "INFO");
                }
            });
        });

        wrapper.querySelector("#minerva-toast-test").addEventListener("click", () => {
            showMinervaToast("Minerva Preview", "Use this to adjust toast placement/visibility on your screen.", 8000);
        });

        wrapper.querySelector("#minerva-update-check").addEventListener("click", () => {
            addLog("Manual update check requested.", "INFO");
            maybeCheckForMinervaUpdate({ force: true, showNoUpdateToast: true });
        });

        wrapper.querySelector("#minerva-tracked-clear").addEventListener("click", () => {
            clearTrackedTargetsKeepCurrent();
            addLog("Tracked list cleared (kept current target).", "INFO");
        });
        
        updateTrackCurrentButton();
        const keyResetBtn = wrapper.querySelector("#minerva-key-reset");
        const toastTestBtn = wrapper.querySelector("#minerva-toast-test");
        const showOwnerOnlyControls = ownProfileControls;
        if (keyResetBtn) {
            keyResetBtn.style.display = showOwnerOnlyControls ? "" : "none";
        }
        if (toastTestBtn) {
            toastTestBtn.style.display = showOwnerOnlyControls ? "" : "none";
        }

        if (showOwnerOnlyControls) {
            const countdownEl = header.lastElementChild;
            if (countdownEl) {
                countdownEl.style.display = "flex";
                countdownEl.style.alignItems = "center";
                countdownEl.style.gap = "8px";
            }

            const gearBtn = document.createElement("button");
            gearBtn.id = "minerva-settings-gear";
            gearBtn.type = "button";
            gearBtn.title = "Minerva Settings";
            gearBtn.textContent = "⚙";
            gearBtn.style.cssText = `
                background: transparent;
                color: #9fb6c6;
                border: 1px solid rgba(255,255,255,0.15);
                border-radius: 6px;
                width: 24px;
                height: 22px;
                line-height: 18px;
                padding: 0;
                cursor: pointer;
                font-size: 13px;
            `;
            gearBtn.addEventListener("click", (e) => {
                e.stopPropagation();
                setSettingsPopupOpen(!isSettingsPopupOpen);
            });
            countdownEl?.appendChild(gearBtn);

            wrapper.removeChild(settings);
            settings.style.position = "fixed";
            settings.style.display = "none";
            settings.style.padding = "14px";
            settings.style.margin = "0";
            settings.style.background = "rgba(8, 12, 18, 0.96)";
            settings.style.border = "1px solid rgba(255,255,255,0.12)";
            settings.style.borderRadius = "12px";
            settings.style.boxShadow = "0 12px 28px rgba(0,0,0,0.42), 0 0 14px rgba(0,242,255,0.12)";
            settings.style.backdropFilter = "blur(8px)";
            settings.style.webkitBackdropFilter = "blur(8px)";
            settings.style.zIndex = "10025";
            settings.style.maxWidth = "calc(100vw - 16px)";
            settings.style.maxHeight = "calc(100vh - 16px)";
            settings.style.overflow = "auto";
            document.body.appendChild(settings);

            if (!settingsDocClickHandler || !settingsWindowResizeHandler || !settingsWindowScrollHandler || !settingsDocKeydownHandler) {
                settingsDocClickHandler = (e) => {
                    if (!isLiveMinervaRuntime()) return;
                    const popup = document.getElementById("minerva-settings-panel");
                    const gear = document.getElementById("minerva-settings-gear");
                    if (!popup || !gear || popup.style.position !== "fixed") return;
                    if (!isSettingsPopupOpen) return;
                    if (popup.contains(e.target) || gear.contains(e.target)) return;
                    setSettingsPopupOpen(false);
                };
                settingsWindowResizeHandler = () => {
                    if (!isLiveMinervaRuntime()) return;
                    if (isSettingsPopupOpen) positionSettingsPopup();
                };
                settingsWindowScrollHandler = () => {
                    if (!isLiveMinervaRuntime()) return;
                    if (isSettingsPopupOpen) positionSettingsPopup();
                };
                settingsDocKeydownHandler = (e) => {
                    if (!isLiveMinervaRuntime()) return;
                    if (e.key === "Escape" && isSettingsPopupOpen) {
                        setSettingsPopupOpen(false);
                    }
                };
                document.addEventListener("click", settingsDocClickHandler);
                window.addEventListener("resize", settingsWindowResizeHandler);
                window.addEventListener("scroll", settingsWindowScrollHandler, true);
                document.addEventListener("keydown", settingsDocKeydownHandler);
            }
        }

        updateAvailableUiBadge();

        return wrapper;
    }

    function buildCornerWidget() {
        if (document.getElementById("minerva-corner-widget")) return null;
        ensureMinervaStyleOverrides();

        const widget = document.createElement("div");
        widget.id = "minerva-corner-widget";
        const pos = getSavedWidgetPosition();
        widget.style.cssText = `
            position: fixed;
            left: ${pos.left}px;
            bottom: ${pos.bottom}px;
            width: 420px;
            background: rgba(5, 8, 14, 0.92);
            border: 1px solid rgba(255,255,255,0.12);
            border-radius: 14px;
            box-shadow: 0 8px 24px rgba(0,0,0,0.45), 0 0 18px rgba(0,242,255,0.12);
            color: #e8f6ff;
            z-index: 10000;
            font-family: "Courier New", Courier, monospace;
            padding: 10px 12px;
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
        `;

        widget.innerHTML = `
            <div id="minerva-corner-drag-handle" style="display:flex; justify-content:space-between; align-items:center; gap:8px; cursor:move;">
                <div style="font-weight:bold; font-size:13px; color:#dffbff;">Minerva Tracking</div>
                <div style="display:flex; align-items:center; gap:6px;">
                    <div id="minerva-corner-pill" style="font-size:11px; padding:2px 8px; border-radius:999px; border:1px solid ${PINK_COLOR}; color:${PINK_COLOR};">IDLE</div>
                    <div id="minerva-corner-ping-cooldown" style="display:none; font-size:10px; padding:2px 6px; border-radius:999px; border:1px solid rgba(255,191,102,0.35); color:#ffbf66; background:rgba(255,191,102,0.07);">↻ 60s</div>
                    <button id="minerva-corner-lock" title="Lock Position" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.15); border-radius:6px; width:24px; height:20px; line-height:16px; padding:0; cursor:pointer; font-size:12px;">🔓</button>
                    <button id="minerva-corner-compact" title="Compact" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.15); border-radius:6px; width:20px; height:20px; line-height:16px; padding:0; cursor:pointer;">_</button>
                    <button id="minerva-corner-hide" title="Hide" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.15); border-radius:6px; width:20px; height:20px; line-height:16px; padding:0; cursor:pointer;">-</button>
                </div>
            </div>
            <div id="minerva-corner-details">
                <div style="margin-top:4px; font-size:12px; color:#a9b6c0;">
                    Threshold: <span id="minerva-corner-threshold" style="color:#fff;">${thresholdSeconds}s</span>
                </div>
                <div style="margin-top:8px; font-size:11px; color:#8ea2b1; text-transform:uppercase; letter-spacing:0.6px;">Tracked Profiles</div>
                <div id="minerva-corner-list" style="margin-top:6px; display:flex; flex-direction:column; gap:5px;"></div>
            </div>
        `;

        return widget;
    }

    function buildCornerReopen() {
        if (document.getElementById("minerva-corner-reopen")) return null;
        const btn = document.createElement("button");
        btn.id = "minerva-corner-reopen";
        btn.textContent = "Minerva";
        btn.style.cssText = `
            position: fixed;
            left: 18px;
            bottom: 18px;
            display: none;
            align-items: center;
            justify-content: center;
            background: rgba(5, 8, 14, 0.92);
            color: #dffbff;
            border: 1px solid rgba(255,255,255,0.14);
            border-radius: 10px;
            padding: 6px 10px;
            font-size: 12px;
            font-family: "Courier New", Courier, monospace;
            cursor: pointer;
            z-index: 10001;
            box-shadow: 0 6px 16px rgba(0,0,0,0.35);
        `;
        btn.addEventListener("click", () => setWidgetHidden(false));
        return btn;
    }

    function updateCornerWidget(statusText) {
        const pill = document.getElementById("minerva-corner-pill");
        const threshold = document.getElementById("minerva-corner-threshold");
        if (!pill || !threshold) return;

        const active = statusText === "ACTIVE";
        const paused = statusText === "PAUSED";
        const color = paused ? PINK_COLOR : (active ? CYAN_COLOR : PINK_COLOR);
        pill.textContent = statusText || "IDLE";
        pill.style.color = color;
        pill.style.borderColor = color;
        pill.style.boxShadow = `0 0 8px ${color}33 inset`;
        threshold.textContent = `${thresholdSeconds}s`;
    }

    function renderTrackedList(forceNow = false) {
        if (!forceNow) {
            if (trackedListRenderInProgress || trackedListRenderScheduled) return;
            trackedListRenderScheduled = true;
            const flush = () => {
                trackedListRenderScheduled = false;
                renderTrackedList(true);
            };
            if (typeof window.requestAnimationFrame === "function") {
                window.requestAnimationFrame(flush);
            } else {
                setTimeout(flush, 16);
            }
            return;
        }

        trackedListRenderInProgress = true;
        try {
        const list = document.getElementById("minerva-corner-list");
        if (!list) return;
        list.innerHTML = "";

        trackedTargets.forEach(id => {
            const state = trackedStates[id] || { status: "UNKNOWN", thresholdStatus: "UNKNOWN", last: "--", isHospitalized: null };
            const row = document.createElement("div");
            const isCurrent = String(id) === String(targetId);
            const color = getStatusColor(state.status);
            const displayName = state.name || id;
            const pingCooldownActive = isManualPingCooldownActive();
            const pingCooldownLabel = getManualPingCooldownLabel();
            const hospitalKnown = typeof state.isHospitalized === "boolean";
            const hospitalColor = !hospitalKnown ? "#9fb6c6" : (state.isHospitalized ? PINK_COLOR : "#42ff8c");
            const hospitalTitle = !hospitalKnown ? "Hospital status unknown" : (state.isHospitalized ? "In hospital" : "Not in hospital");
            const safeDisplayName = escapeHtml(`${isCurrent ? "▶" : ""}${displayName}`);
            const safeStatus = escapeHtml(state.status || "UNKNOWN");
            const safeLast = escapeHtml(state.last || "--");
            row.style.cssText = `
                display:flex;
                align-items:center;
                justify-content:space-between;
                gap:8px;
                border:1px solid ${isCurrent ? "rgba(255,255,255,0.16)" : "rgba(255,255,255,0.08)"};
                background:${isCurrent ? "rgba(255,255,255,0.03)" : "rgba(255,255,255,0.015)"};
                border-radius:8px;
                padding:4px 6px;
                font-size:11px;
            `;
            row.title = `ID: ${id}`;
            row.innerHTML = `
                <div style="display:flex; align-items:center; gap:6px; min-width:0;">
                    <span style="width:7px; height:7px; border-radius:999px; background:${color}; box-shadow:0 0 8px ${color}66;"></span>
                    <span title="${hospitalTitle}" style="display:inline-flex; align-items:center; justify-content:center; width:12px; height:12px; color:${hospitalColor}; border:1px solid ${hospitalColor}55; border-radius:4px; font-size:10px; line-height:10px; background:rgba(255,255,255,0.02);">✚</span>
                    <a href="${getProfileUrl(id)}" target="_blank" rel="noopener noreferrer" title="Open profile" style="color:#ffffff; text-decoration:none; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; max-width:320px; display:inline-block;">${safeDisplayName}</a>
                </div>
                <div style="display:flex; align-items:center; gap:8px; min-width:0;">
                    <span style="color:${color}; font-weight:bold; white-space:nowrap;">${safeStatus}</span>
                    <span style="color:#9fb6c6; max-width:260px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${safeLast}</span>
                    <button data-minerva-ping-id="${id}" title="${pingCooldownActive ? `Ping cooldown (${pingCooldownLabel})` : "Ping Now"}" ${pingCooldownActive ? "disabled" : ""} style="background:transparent; color:${pingCooldownActive ? "#6c7f8d" : CYAN_COLOR}; border:1px solid ${pingCooldownActive ? "rgba(255,255,255,0.08)" : "rgba(0,242,255,0.18)"}; border-radius:5px; width:22px; height:16px; line-height:12px; padding:0; cursor:${pingCooldownActive ? "not-allowed" : "pointer"}; font-size:11px; font-weight:bold; opacity:${pingCooldownActive ? "0.55" : "1"};">↻</button>
                    <button data-minerva-attack-id="${id}" title="Attack target" style="background:transparent; color:#ffb0b0; border:1px solid rgba(255,100,100,0.18); border-radius:5px; width:22px; height:16px; line-height:12px; padding:0; cursor:pointer; font-size:11px; font-weight:bold;">⚔</button>
                    <button data-minerva-remove-id="${id}" title="Remove" style="background:transparent; color:#9fb6c6; border:1px solid rgba(255,255,255,0.12); border-radius:5px; width:16px; height:16px; line-height:12px; padding:0; cursor:pointer; font-size:11px;">x</button>
                </div>
            `;
            const pingBtn = row.querySelector(`[data-minerva-ping-id="${id}"]`);
            if (pingBtn) {
                pingBtn.addEventListener("click", (e) => {
                    e.stopPropagation();
                    const limiter = tryConsumeManualPingClick();
                    if (!limiter.ok) {
                        const seconds = Math.ceil((limiter.remainingMs || 0) / 1000);
                        if (limiter.reason === "rate_limited") {
                            addLog(`Manual ping rate limit triggered. Ping buttons locked for ${seconds}s.`, "ERROR");
                            showMinervaToast("Minerva", `Ping cooldown enabled for ${seconds}s (too many manual pings).`, 5000);
                            renderTrackedList();
                        } else if (limiter.reason === "cooldown") {
                            addLog(`Manual ping blocked during cooldown (${seconds}s remaining).`, "DIAGNOSTIC");
                        }
                        return;
                    }
                    if (!apiKey) {
                        addLog(`Cannot ping [${id}] because no API key is set.`, "ERROR");
                        updateVisuals(PINK_COLOR, "NO API KEY");
                        return;
                    }
                    addLog(`Manual ping requested for [${id}].`, "INFO");
                    checkProfileActivityForId(id, String(id) === String(targetId));
                    if (String(id) === String(targetId) && isTracking) {
                        countdownTimer = 60;
                    }
                });
            }
            const attackBtn = row.querySelector(`[data-minerva-attack-id="${id}"]`);
            if (attackBtn) {
                attackBtn.addEventListener("click", (e) => {
                    e.stopPropagation();
                    window.open(getAttackUrl(id), "_blank", "noopener,noreferrer");
                });
            }
            const removeBtn = row.querySelector(`[data-minerva-remove-id="${id}"]`);
            if (removeBtn) {
                removeBtn.addEventListener("click", (e) => {
                    e.stopPropagation();
                    removeTrackedTarget(id);
                    addLog(`Removed target [${id}] from tracked list.`, "INFO");
                });
            }
            list.appendChild(row);
        });

        autoSizeCornerWidgetListHeight();
        autoSizeCornerWidget();
        clampCornerWidgetIntoViewport();
        updateManualPingCooldownVisuals();
        } finally {
            trackedListRenderInProgress = false;
        }
    }

    // --- Visual Updater ---
    function updateVisuals(color, text) {
        const container = document.getElementById("minerva-master-container");
        const statusText = document.getElementById("minerva-status-text");
        if (container && statusText) {
            container.style.borderColor = color;
            container.style.boxShadow = `0 0 15px ${color}40`;
            statusText.style.color = color;
            statusText.style.textShadow = `0 0 8px ${color}`;
            if (text) statusText.innerText = text;
        }
        if (text) updateCornerWidget(text);
    }

    function syncTrackingStateFromUi() {
        const statusText = document.getElementById("minerva-status-text");
        if (!isTracking || !statusText) return;

        const uiStatus = String(statusText.innerText || "").trim();
        let resolvedStatus = currentStatus;
        if (!resolvedStatus || resolvedStatus === "UNKNOWN") {
            const currentTargetState = targetId ? trackedStates[String(targetId)] : null;
            let fallbackStatus = currentTargetState && currentTargetState.thresholdStatus;
            if (!fallbackStatus || fallbackStatus === "UNKNOWN") {
                const firstTrackedId = trackedTargets.length ? String(trackedTargets[0]) : "";
                const firstTrackedState = firstTrackedId ? trackedStates[firstTrackedId] : null;
                fallbackStatus = firstTrackedState && firstTrackedState.thresholdStatus;
            }
            if (fallbackStatus && fallbackStatus !== "UNKNOWN") {
                resolvedStatus = fallbackStatus;
                currentStatus = fallbackStatus;
            }
        }
        const hasKnownStatus = !!(resolvedStatus && resolvedStatus !== "UNKNOWN");
        if (!hasKnownStatus) return;

        if ((uiStatus === "PAUSED" || uiStatus === "AWAITING PING" || uiStatus === "NO TARGETS") && trackedTargets.length > 0) {
            updateVisuals(resolvedStatus === "ACTIVE" ? CYAN_COLOR : PINK_COLOR, resolvedStatus);
        }
    }

    // --- Profile UI Injection ---
    function isProfilePageContext() {
        const path = String(window.location.pathname || "").toLowerCase();
        if (path.includes("/profiles.php")) return true;
        if (path.includes("/loader.php")) {
            const sid = String(new URLSearchParams(window.location.search).get("sid") || "").toLowerCase();
            if (sid.includes("profile")) return true;
        }
        return !!targetId;
    }

    function describeInjectionNode(node) {
        if (!(node instanceof Element)) return "(invalid)";
        const id = node.id ? `#${node.id}` : "";
        const cls = typeof node.className === "string" && node.className.trim()
            ? `.${node.className.trim().split(/\s+/).slice(0, 3).join(".")}`
            : "";
        return `${node.tagName.toLowerCase()}${id}${cls}`;
    }

    function scoreInjectionHost(node) {
        if (!(node instanceof Element)) return { score: -Infinity, rejectReason: "not-element" };
        if (node.id === "minerva-master-container") return { score: -Infinity, rejectReason: "self" };
        const existingUi = document.getElementById("minerva-master-container");
        if (existingUi && node.contains(existingUi)) return { score: -Infinity, rejectReason: "contains-existing-ui" };

        const rect = node.getBoundingClientRect();
        const style = window.getComputedStyle(node);
        if (style.display === "none" || style.visibility === "hidden") return { score: -Infinity, rejectReason: "hidden" };
        if (rect.width < 260 || rect.height < 80) return { score: -Infinity, rejectReason: `too-small:${Math.round(rect.width)}x${Math.round(rect.height)}` };

        let score = 0;
        const reasons = [];

        if (node.offsetParent) {
            score += 10;
            reasons.push("visible+10");
        }
        const topScore = Math.max(0, 120 - Math.min(120, Math.abs(rect.top - 80)));
        score += topScore;
        reasons.push(`top+${Math.round(topScore)}`);
        const widthScore = Math.max(0, Math.min(80, rect.width / 12));
        score += widthScore;
        reasons.push(`width+${Math.round(widthScore)}`);

        const ident = `${node.id || ""} ${node.className || ""}`.toLowerCase();
        if (/profile|user|info|content|wrapper|container/.test(ident)) {
            score += 35;
            reasons.push("profile-ident+35");
        }
        if (/maincontainer|content-wrapper|profileroot|user-information|actions/.test(ident)) {
            score += 25;
            reasons.push("strong-ident+25");
        }

        const profileLinks = node.querySelectorAll('a[href*="profiles.php?XID="]').length;
        const attackLinks = node.querySelectorAll('a[href*="sid=attack"], a[href*="attack"]').length;
        const actionButtons = node.querySelectorAll('a,button').length;
        const headingText = Array.from(node.querySelectorAll("h1,h2,h3,h4,header,.title"))
            .map(el => (el.textContent || "").trim().toLowerCase())
            .slice(0, 10)
            .join(" | ");
        if (/user information|actions/.test(headingText)) {
            score += 30;
            reasons.push("heading-match+30");
        }

        const profileLinkScore = Math.min(profileLinks * 20, 80);
        const attackLinkScore = Math.min(attackLinks * 25, 50);
        const actionButtonScore = Math.min(actionButtons, 20);
        score += profileLinkScore + attackLinkScore + actionButtonScore;
        if (profileLinkScore) reasons.push(`profile-links+${profileLinkScore}`);
        if (attackLinkScore) reasons.push(`attack-links+${attackLinkScore}`);
        if (actionButtonScore) reasons.push(`actions+${actionButtonScore}`);

        if (node === document.body) {
            score -= 80;
            reasons.push("body-80");
        }
        if (node === document.documentElement) {
            score -= 120;
            reasons.push("html-120");
        }
        if (rect.height > window.innerHeight * 0.95 && rect.width > window.innerWidth * 0.95) {
            score -= 35;
            reasons.push("fullpage-35");
        }

        return { score, reasons, rect, desc: describeInjectionNode(node) };
    }

    function findBestDynamicInjectionHost(uiElement) {
        const candidates = new Set();

        const seedSelectors = [
            'a[href*="profiles.php?XID="]',
            'a[href*="sid=attack"]',
            'a[href*="loader.php?sid=attack"]',
            '[id*="profile"]',
            '[class*="profile"]',
            '[class*="user-information"]',
            '[class*="userInfo"]',
            '[class*="actions"]',
            '[class*="action"]',
            '[class*="sortable"]',
            '[class*="box"]',
            'h1, h2, h3',
            '#mainContainer',
            '#content-wrapper',
            '#content'
        ];

        for (const selector of seedSelectors) {
            document.querySelectorAll(selector).forEach((el) => {
                if (!(el instanceof Element)) return;
                let cur = el;
                let depth = 0;
                while (cur && depth < 5) {
                    candidates.add(cur);
                    cur = cur.parentElement;
                    depth++;
                }
            });
        }

        let bestHost = null;
        let bestScore = -Infinity;
        const ranked = [];
        for (const node of candidates) {
            if (!(node instanceof Element)) continue;
            if (node.contains(uiElement)) continue;
            const scored = scoreInjectionHost(node);
            if (Number.isFinite(scored.score)) ranked.push(scored);
            if (scored.score > bestScore) {
                bestScore = scored.score;
                bestHost = node;
            }
        }
        ranked.sort((a, b) => b.score - a.score);

        if (bestHost && bestScore > 20) {
            return { host: bestHost, score: bestScore, rankedTop: ranked.slice(0, 5) };
        }
        return { host: null, score: bestScore, rankedTop: ranked.slice(0, 5) };
    }

    function injectUiAsOverlayFallback(uiElement) {
        if (!uiElement || document.getElementById("minerva-profile-overlay-host")) return false;
        if (!document.body) return false;
        const overlayHost = document.createElement("div");
        overlayHost.id = "minerva-profile-overlay-host";
        overlayHost.style.cssText = `
            position: fixed;
            top: 12px;
            left: 12px;
            width: min(560px, calc(100vw - 24px));
            max-height: calc(100vh - 24px);
            overflow: auto;
            z-index: 10024;
        `;
        uiElement.style.width = "100%";
        uiElement.style.marginBottom = "0";
        overlayHost.appendChild(uiElement);
        document.body.appendChild(overlayHost);
        addLog("Minerva UI injected via guarded overlay fallback.", "ERROR");
        return true;
    }

    function disconnectProfileInjectionObserver() {
        if (!profileInjectionObserver) return;
        try {
            profileInjectionObserver.disconnect();
        } catch (_) {}
        profileInjectionObserver = null;
    }

    function teardownMinerva(reason = "teardown") {
        if (isTornDown) return;
        isTornDown = true;
        disconnectProfileInjectionObserver();
        if (engineIntervalId) {
            clearInterval(engineIntervalId);
            engineIntervalId = null;
        }
        pollCycleInProgress = false;
        engineTickInProgress = false;
        trackedListRenderScheduled = false;
        trackedListRenderInProgress = false;
        widgetDragState = null;
        apiKeyPromptDragState = null;
        toastDragState = null;
        try {
            if (typeof GM_removeValueChangeListener === "function" && trackedTargetsValueChangeListenerId) {
                GM_removeValueChangeListener(trackedTargetsValueChangeListenerId);
            }
        } catch (_) {}
        trackedTargetsValueChangeListenerId = null;

        [
            "minerva-master-container",
            "minerva-settings-panel",
            "minerva-corner-widget",
            "minerva-corner-reopen",
            "minerva-toast-host",
            "minerva-api-key-modal",
            "minerva-passphrase-modal",
            "minerva-profile-overlay-host"
        ].forEach((id) => {
            const el = document.getElementById(id);
            if (el) el.remove();
        });
        if (toastDocMouseMoveHandler) document.removeEventListener("mousemove", toastDocMouseMoveHandler);
        if (toastDocMouseUpHandler) document.removeEventListener("mouseup", toastDocMouseUpHandler);
        if (toastWindowResizeHandler) window.removeEventListener("resize", toastWindowResizeHandler);
        toastDocMouseMoveHandler = null;
        toastDocMouseUpHandler = null;
        toastWindowResizeHandler = null;

        if (settingsDocClickHandler) document.removeEventListener("click", settingsDocClickHandler);
        if (settingsWindowResizeHandler) window.removeEventListener("resize", settingsWindowResizeHandler);
        if (settingsWindowScrollHandler) window.removeEventListener("scroll", settingsWindowScrollHandler, true);
        if (settingsDocKeydownHandler) document.removeEventListener("keydown", settingsDocKeydownHandler);
        settingsDocClickHandler = null;
        settingsWindowResizeHandler = null;
        settingsWindowScrollHandler = null;
        settingsDocKeydownHandler = null;

        if (cornerDocMouseMoveHandler) document.removeEventListener("mousemove", cornerDocMouseMoveHandler);
        if (cornerDocMouseUpHandler) document.removeEventListener("mouseup", cornerDocMouseUpHandler);
        if (cornerWindowResizeHandler) window.removeEventListener("resize", cornerWindowResizeHandler);
        cornerDocMouseMoveHandler = null;
        cornerDocMouseUpHandler = null;
        cornerWindowResizeHandler = null;

        releaseActiveMinervaInstance();
        if (reason !== "unload") {
            console.log(`[Minerva] Runtime torn down (${reason}).`);
        }
    }

    function injectSafely() {
        if (!isProfilePageContext()) return;
        if (!targetId) return;
        const uiElement = buildUI();
        if (!uiElement) return;
        lastInjectionAttemptAt = Date.now();
        injectionFailureLogged = false;
        disconnectProfileInjectionObserver();

        const possibleTargets = [
            '.profile-wrapper',
            '.user-profile',
            '#profileroot',
            '.profile-container',
            '.profile-mini-root',
            '[class*="profile-root"]',
            '[class*="profile-wrapper"]',
            '[class*="user-information"]',
            '[class*="actions"]',
            '[class*="profile"] [class*="column"]',
            '.content-wrapper',
            '.content-wrapper > div',
            '.content-title + div',
            '#mainContainer .content-wrapper',
            '#mainContainer',
            '#content-wrapper',
            '#content'
        ];

        const tryInject = () => {
            // Preferred placement: wide center-column "Profile Notes" bar (avoid sidebar "Notes" blocks).
            const profileNotesAnchor = Array.from(document.querySelectorAll("div, h2, h3, span, a"))
                .filter((el) => {
                    if (!(el instanceof Element)) return false;
                    const text = String(el.textContent || "").trim();
                    if (!/^profile notes$/i.test(text)) return false;
                    const rect = el.getBoundingClientRect();
                    if (rect.width < 420 || rect.height < 16) return false;
                    const style = window.getComputedStyle(el);
                    if (style.display === "none" || style.visibility === "hidden") return false;
                    return true;
                })
                .sort((a, b) => b.getBoundingClientRect().width - a.getBoundingClientRect().width)[0];
            if (profileNotesAnchor && profileNotesAnchor.parentElement) {
                const notesBarHost = profileNotesAnchor.closest('div[class], section, article') || profileNotesAnchor;
                if (notesBarHost && notesBarHost.parentElement && !notesBarHost.contains(uiElement)) {
                    notesBarHost.parentElement.insertBefore(uiElement, notesBarHost);
                    disconnectProfileInjectionObserver();
                    addLog("Minerva UI injected directly above Profile Notes bar.", "INFO");
                    return true;
                }
            }

            for (let selector of possibleTargets) {
                let target = document.querySelector(selector);
                if (target && !target.contains(uiElement)) {
                    target.insertBefore(uiElement, target.firstChild);
                    disconnectProfileInjectionObserver();
                    addLog(`Minerva UI injected cleanly at ${selector}`, "INFO");
                    return true;
                }
            }

            // Fallback: anchor near common profile modules, then insert above their parent block.
            const anchors = [
                '.user-information',
                '.profile-mini-root',
                '.profile-container',
                '[class*="user-information"]',
                '[class*="profile"] [class*="information"]',
                '[class*="actions"]',
                'h2',
                'h3'
            ];
            for (const selector of anchors) {
                const anchorCandidates = Array.from(document.querySelectorAll(selector));
                const anchor = anchorCandidates.find((el) => {
                    if (!(el instanceof Element)) return false;
                    if (/^H[23]$/i.test(el.tagName)) {
                        const t = String(el.textContent || "").toLowerCase();
                        return /user information|actions/.test(t);
                    }
                    return true;
                });
                if (!anchor) continue;
                const host = anchor.closest('div[class], section, article') || anchor.parentElement;
                if (host && host.parentElement && !host.contains(uiElement)) {
                    host.parentElement.insertBefore(uiElement, host);
                    disconnectProfileInjectionObserver();
                    addLog(`Minerva UI injected via fallback anchor ${selector}`, "INFO");
                    return true;
                }
            }

            // Dynamic fallback: score likely profile containers for this layout.
            const dynamicHost = findBestDynamicInjectionHost(uiElement);
            if (dynamicHost && dynamicHost.host) {
                dynamicHost.host.insertBefore(uiElement, dynamicHost.host.firstChild || null);
                disconnectProfileInjectionObserver();
                addLog(`Minerva UI injected via dynamic layout match (score=${Math.round(dynamicHost.score)}).`, "INFO");
                return true;
            }
            if (dynamicHost && dynamicHost.rankedTop && dynamicHost.rankedTop.length) {
                addLog(`Dynamic injection candidates: ${dynamicHost.rankedTop.map(c => `${c.desc}:${Math.round(c.score)}`).join(" | ")}`, "DIAGNOSTIC");
            }

            // Last in-flow fallback: prepend into a stable page container if profile selectors miss.
            const genericHosts = [
                '#mainContainer',
                '#content-wrapper',
                '#content',
                'main'
            ];
            for (const selector of genericHosts) {
                const host = document.querySelector(selector);
                if (!host || host.contains(uiElement)) continue;
                host.insertBefore(uiElement, host.firstChild || null);
                disconnectProfileInjectionObserver();
                addLog(`Minerva UI injected via generic fallback ${selector}`, "INFO");
                return true;
            }

            if (injectUiAsOverlayFallback(uiElement)) {
                disconnectProfileInjectionObserver();
                return true;
            }

            return false;
        };
        
        if (tryInject()) return;

        const observer = new MutationObserver((mutations, obs) => {
            if (tryInject()) {
                addLog("Minerva UI injected via Observer.", "INFO");
                obs.disconnect();
                if (profileInjectionObserver === obs) profileInjectionObserver = null;
                return;
            }
        });
        profileInjectionObserver = observer;
        observer.observe(document.body, { childList: true, subtree: true });

        // Last-resort fallback if Torn's profile DOM is unusual.
        setTimeout(() => {
            if (!document.getElementById("minerva-master-container") && tryInject()) {
                observer.disconnect();
                if (profileInjectionObserver === observer) profileInjectionObserver = null;
            }
        }, 2500);

        setTimeout(() => {
            if (!document.getElementById("minerva-master-container") && !injectionFailureLogged) {
                injectionFailureLogged = true;
                addLog(`Profile UI injection still missing after retries. selectors=${possibleTargets.length}, pageTitle=${document.title || "-"}`, "ERROR");
                addLog(`First anchors present snapshot: user-information=${!!document.querySelector('.user-information')}, profile-container=${!!document.querySelector('.profile-container')}, actions=${!!document.querySelector('[class*=\"actions\"]')}`, "DIAGNOSTIC");
                const dyn = findBestDynamicInjectionHost(uiElement);
                if (dyn && dyn.rankedTop && dyn.rankedTop.length) {
                    addLog(`Top dynamic candidates: ${dyn.rankedTop.map(c => `${c.desc}:${Math.round(c.score)}[${(c.reasons || []).slice(0, 3).join(",")}]`).join(" || ")}`, "DIAGNOSTIC");
                }
            }
            if (!document.getElementById("minerva-master-container")) {
                observer.disconnect();
                if (profileInjectionObserver === observer) profileInjectionObserver = null;
            }
        }, 4000);
    }

    function injectCornerWidget() {
        const widget = buildCornerWidget();
        const reopen = buildCornerReopen();
        if (widget) document.body.appendChild(widget);
        if (reopen) document.body.appendChild(reopen);

        const activeWidget = document.getElementById("minerva-corner-widget");
        if (!activeWidget) return;

        const hideBtn = document.getElementById("minerva-corner-hide");
        if (hideBtn) {
            hideBtn.addEventListener("click", (e) => {
                e.stopPropagation();
                setWidgetHidden(true);
            });
        }

        const compactBtn = document.getElementById("minerva-corner-compact");
        if (compactBtn) {
            compactBtn.addEventListener("click", (e) => {
                e.stopPropagation();
                const details = document.getElementById("minerva-corner-details");
                const currentlyCompact = details && details.style.display === "none";
                setWidgetCompact(!currentlyCompact);
            });
        }

        const lockBtn = document.getElementById("minerva-corner-lock");
        if (lockBtn) {
            lockBtn.addEventListener("click", (e) => {
                e.stopPropagation();
                const currentlyLocked = GM_getValue(WIDGET_LOCKED_STORAGE_KEY, false);
                setWidgetLocked(!currentlyLocked);
            });
        }

        activeWidget.addEventListener("mousedown", (e) => {
            const locked = GM_getValue(WIDGET_LOCKED_STORAGE_KEY, false);
            const clickingHeader = !!(e.target instanceof Element && e.target.closest("#minerva-corner-drag-handle"));
            const forceDrag = e.shiftKey; // emergency move if locked/header is hard to reach
            if (isCornerWidgetControl(e.target)) return;
            if (!clickingHeader && !forceDrag) return;
            if (locked && !forceDrag) return;

            const rect = activeWidget.getBoundingClientRect();
            widgetDragState = {
                startX: e.clientX,
                startY: e.clientY,
                startLeft: rect.left,
                startTop: rect.top
            };
            e.preventDefault();
        });

        if (!cornerDocMouseMoveHandler || !cornerDocMouseUpHandler) {
            cornerDocMouseMoveHandler = (e) => {
                if (!isLiveMinervaRuntime()) return;
                if (!widgetDragState) return;
                const widgetEl = document.getElementById("minerva-corner-widget");
                if (!widgetEl) return;

                const dx = e.clientX - widgetDragState.startX;
                const dy = e.clientY - widgetDragState.startY;
                const newLeft = Math.max(8, Math.min(window.innerWidth - widgetEl.offsetWidth - 8, widgetDragState.startLeft + dx));
                const newTop = Math.max(8, Math.min(window.innerHeight - widgetEl.offsetHeight - 8, widgetDragState.startTop + dy));
                const newBottom = Math.max(8, window.innerHeight - (newTop + widgetEl.offsetHeight));
                widgetEl.style.left = `${newLeft}px`;
                widgetEl.style.bottom = `${newBottom}px`;
            };
            cornerDocMouseUpHandler = () => {
                if (!isLiveMinervaRuntime()) return;
                if (!widgetDragState) return;
                const widgetEl = document.getElementById("minerva-corner-widget");
                if (widgetEl) {
                    snapCornerWidgetToGrid(widgetEl);
                }
                widgetDragState = null;
            };
            document.addEventListener("mousemove", cornerDocMouseMoveHandler);
            document.addEventListener("mouseup", cornerDocMouseUpHandler);
        }

        const hidden = GM_getValue(WIDGET_HIDDEN_STORAGE_KEY, false);
        const compact = GM_getValue(WIDGET_COMPACT_STORAGE_KEY, false);
        const locked = GM_getValue(WIDGET_LOCKED_STORAGE_KEY, false);
        setWidgetCompact(compact);
        setWidgetLocked(locked);
        setWidgetHidden(hidden);
        clampCornerWidgetIntoViewport();
        updateCornerWidget(isTracking ? "AWAITING PING" : "PAUSED");
        renderTrackedList();
        ensureToastHost();

        if (!cornerWindowResizeHandler) {
            cornerWindowResizeHandler = () => {
                if (!isLiveMinervaRuntime()) return;
                autoSizeCornerWidgetListHeight();
                autoSizeCornerWidget();
                clampCornerWidgetIntoViewport();
            };
            window.addEventListener("resize", cornerWindowResizeHandler);
        }
    }

    // --- API & Tracking Logic ---
    function checkProfileActivityForId(id, isPrimary = false, done = null) {
        const reqId = ++requestSeq;
        const startedAt = Date.now();
        const requestUrl = `https://api.torn.com/v2/user/${id}/profile?striptags=true&key=${encodeURIComponent(apiKey)}`;
        const finish = () => { if (typeof done === "function") done(); };
        if (isPrimary) {
            addLog(`Request #${reqId} start: profile lookup for [${id}]`, "DEBUG");
        }
        GM_xmlhttpRequest({
            method: "GET",
            url: requestUrl,
            headers: {
                "Authorization": `ApiKey ${apiKey}`
            },
            timeout: 10000, 
            onload: function(response) {
                if (!isActiveMinervaInstance()) {
                    finish();
                    return;
                }
                const durationMs = Date.now() - startedAt;
                if (response.status !== 200) {
                    const state = ensureTrackedState(id);
                    state.status = `HTTP ${response.status}`;
                    state.last = "--";
                    if (isPrimary) {
                        updateVisuals(PINK_COLOR, `HTTP ${response.status}`);
                        addLog(`Request #${reqId} failed in ${durationMs}ms. HTTP ${response.status}: ${response.statusText}`, "ERROR");
                    }
                    renderTrackedList();
                    finish();
                    return;
                }
                
                try {
                    let data = JSON.parse(response.responseText);
                    if (isPrimary) {
                        addLog(`Request #${reqId} ok in ${durationMs}ms. Root keys: ${Object.keys(data).join(", ")}`, "DEBUG");
                    }
                    
                    if (data.error) {
                        const state = ensureTrackedState(id);
                        state.status = "API ERROR";
                        state.last = "--";
                        if (isPrimary) {
                            updateVisuals(PINK_COLOR, `API ERROR: ${data.error.error}`);
                            addLog(`Request #${reqId} Torn API Error Code ${data.error.code}: ${data.error.error}`, "ERROR");
                        }
                        renderTrackedList();
                        finish();
                        return;
                    }

                    const profileName = (data.profile && data.profile.name) || (data.user && data.user.name) || trackedStates[id]?.name || String(id);
                    let lastActionData =
                        (data.profile && data.profile.last_action)
                        || data.last_action
                        || (data.user && data.user.last_action);

                    if (!lastActionData || !lastActionData.timestamp) {
                        const rootKeys = Object.keys(data);
                        const state = ensureTrackedState(id, profileName);
                        state.status = "NO ACTIVITY";
                        state.last = "--";
                        if (isPrimary) {
                            updateVisuals(PINK_COLOR, "ACTIVITY UNAVAILABLE");
                            addLog(`Request #${reqId} target profile data missing \`last_action\` (API returned profile without activity field).`, "ERROR");
                            addLog(`Root keys received: ${rootKeys.join(", ")}`, "DIAGNOSTIC");
                            if (data.profile) addLog(`Profile keys: ${Object.keys(data.profile).join(", ")}`, "DIAGNOSTIC");
                        }
                        renderTrackedList();
                        finish();
                        return;
                    }

                    let lastActionTimestamp = Number(lastActionData.timestamp);
                    if (!Number.isFinite(lastActionTimestamp)) {
                        const state = ensureTrackedState(id, profileName);
                        state.status = "BAD TS";
                        state.last = "--";
                        if (isPrimary) {
                            updateVisuals(PINK_COLOR, "BAD TIMESTAMP");
                            addLog(`Request #${reqId} \`last_action.timestamp\` is not a valid number (${String(lastActionData.timestamp)}).`, "ERROR");
                        }
                        renderTrackedList();
                        finish();
                        return;
                    }

                    let currentTime = Math.floor(Date.now() / 1000);
                    let secondsSinceActive = Math.max(0, currentTime - lastActionTimestamp);
                    let newStatus = (secondsSinceActive <= thresholdSeconds) ? "ACTIVE" : "INACTIVE";
                    const apiLastActionStatus = String(lastActionData.status || "").toLowerCase();
                    const thresholdLabel = formatThresholdLabel(thresholdSeconds);
                    let actualPresenceStatus = "INACTIVE";
                    if (apiLastActionStatus === "online") {
                        actualPresenceStatus = "ACTIVE";
                    } else if (secondsSinceActive <= thresholdSeconds) {
                        actualPresenceStatus = "Ready";
                    } else {
                        actualPresenceStatus = `INACTIVE ${thresholdLabel}+`;
                    }
                    const relativeText = apiLastActionStatus === "online"
                        ? "Online now"
                        : (lastActionData.relative || `${secondsSinceActive}s ago`);
                    const state = ensureTrackedState(id, profileName);
                    const previousThresholdStatus = state.thresholdStatus || "UNKNOWN";
                    const previousHospitalized = state.isHospitalized;
                    const previousTraveling = state.isTraveling;
                    const previousTravelDestination = state.travelDestination || "";
                    const apiProfileStatusState = String((data.profile && data.profile.status && data.profile.status.state) || (data.status && data.status.state) || "");
                    const apiProfileStatusDescription = String((data.profile && data.profile.status && data.profile.status.description) || (data.status && data.status.description) || "");
                    const isHospitalized = /hospital/i.test(apiProfileStatusState) || /hospital/i.test(apiProfileStatusDescription);
                    const travelInfo = parseTravelStatusFromProfile(apiProfileStatusState, apiProfileStatusDescription);
                    state.status = actualPresenceStatus; // row display uses actual Torn presence
                    state.thresholdStatus = newStatus; // notifications use threshold crossing
                    state.last = relativeText;
                    state.isHospitalized = isHospitalized;
                    state.isTraveling = travelInfo.traveling;
                    state.travelDestination = travelInfo.destination || "";

                    if (isPrimary) {
                        lastActionRelativeText = relativeText;
                    }
                    
                    if (isPrimary) {
                        addLog(`Request #${reqId} parsed target [${id}] => threshold=${newStatus}, presence=${actualPresenceStatus}, age=${secondsSinceActive}s`, "DEBUG");
                        addLog(`Request #${reqId} action details: apiStatus=${lastActionData.status || "-"}, relative=${lastActionData.relative || "-"}, ts=${lastActionData.timestamp}`, "DIAGNOSTIC");
                        updateVisuals(newStatus === "ACTIVE" ? CYAN_COLOR : PINK_COLOR, newStatus);
                    }
                    renderTrackedList();

                    if (previousThresholdStatus !== newStatus && previousThresholdStatus !== "UNKNOWN") {
                        const targetLabel = getTrackedTargetLabel(id);
                        addLog(`Target ${targetLabel} threshold status changed from ${previousThresholdStatus} to ${newStatus}`, "INFO");
                        if (newStatus === "INACTIVE") {
                            notifyIfHidden("Minerva Tracking", `Target ${targetLabel} crossed your inactivity threshold (${thresholdSeconds}s).`);
                        } else if (newStatus === "ACTIVE") {
                            notifyIfHidden("Minerva Tracking", `Target ${targetLabel} is active again.`);
                        }
                    }

                    if (previousHospitalized === false && isHospitalized === true) {
                        const targetLabel = getTrackedTargetLabel(id);
                        addLog(`Target ${targetLabel} has been hospitalized.`, "INFO");
                        notifyIfHidden("Minerva Hospital", `Target ${targetLabel} is now in the hospital.`);
                    }
                    if (previousHospitalized === true && isHospitalized === false) {
                        const targetLabel = getTrackedTargetLabel(id);
                        addLog(`Target ${targetLabel} is no longer hospitalized.`, "INFO");
                        notifyIfHidden("Minerva Recovery", `Target ${targetLabel} is no longer in the hospital.`);
                    }

                    if (previousTraveling === false && travelInfo.traveling === true) {
                        const targetLabel = getTrackedTargetLabel(id);
                        const travelLabel = travelInfo.destination || "a destination";
                        addLog(`Target ${targetLabel} started traveling to ${travelLabel}.`, "INFO");
                        notifyIfHidden("Minerva Travel", `Target ${targetLabel} started traveling to ${travelLabel}.`);
                    }
                    if (previousTraveling === true && travelInfo.traveling === false) {
                        const targetLabel = getTrackedTargetLabel(id);
                        const arrivalLabel = travelInfo.destination || previousTravelDestination || "destination";
                        addLog(`Target ${targetLabel} arrived at ${arrivalLabel}.`, "INFO");
                        notifyIfHidden("Minerva Travel", `Target ${targetLabel} arrived at ${arrivalLabel}.`);
                    }

                    if (isPrimary && currentStatus === "INACTIVE" && newStatus === "ACTIVE") {
                        notifyIfHidden("Minerva Tracking Alert", `Target ${getTrackedTargetLabel(id)} has just become ACTIVE!`);
                    }
                    if (isPrimary) currentStatus = newStatus;
                    finish();

                } catch (e) {
                    const state = ensureTrackedState(id);
                    state.status = "PARSE ERR";
                    state.last = "--";
                    if (isPrimary) {
                        updateVisuals(PINK_COLOR, "JSON PARSE ERROR");
                        addLog(`Request #${reqId} JSON Parse Failed: ${e.message}`, "ERROR");
                        if (response && typeof response.responseText === "string") {
                            addLog(`Response preview: ${response.responseText.slice(0, 240)}`, "DIAGNOSTIC");
                        }
                    }
                    renderTrackedList();
                    finish();
                }
            },
            ontimeout: function() {
                if (!isActiveMinervaInstance()) {
                    finish();
                    return;
                }
                const durationMs = Date.now() - startedAt;
                const state = ensureTrackedState(id);
                state.status = "TIMEOUT";
                state.last = "--";
                if (isPrimary) {
                    updateVisuals(PINK_COLOR, "API TIMEOUT");
                    addLog(`Request #${reqId} timed out after ${durationMs}ms (limit 10000ms).`, "ERROR");
                }
                renderTrackedList();
                finish();
            },
            onerror: function(err) {
                if (!isActiveMinervaInstance()) {
                    finish();
                    return;
                }
                const durationMs = Date.now() - startedAt;
                const state = ensureTrackedState(id);
                state.status = "NET ERR";
                state.last = "--";
                if (isPrimary) {
                    updateVisuals(PINK_COLOR, "NETWORK ERROR");
                    let detail = (err && err.error) ? err.error : (err && err.statusText ? err.statusText : "Check console for object dump");
                    addLog(`Request #${reqId} network error after ${durationMs}ms: ${detail}`, "ERROR");
                    addLog(`Network error object keys: ${err ? Object.keys(err).join(", ") : "(none)"}`, "DIAGNOSTIC");
                    console.error("[Minerva Raw Network Error]", err);
                }
                renderTrackedList();
                finish();
            }
        });
    }

    function checkTargetActivity() {
        if (!isActiveMinervaInstance()) return;
        if (pollCycleInProgress) {
            addLog("Skipped poll cycle start because a previous cycle is still running.", "DIAGNOSTIC");
            return;
        }
        pollCycleInProgress = true;
        const cycleId = ++pollCycleSeq;
        let ids = trackedTargets.slice(0, maxTrackedTargets);
        if (ids.length === 0) {
            const recovered = syncTrackedTargetsFromStorage("poll-empty");
            if (recovered) {
                ids = trackedTargets.slice(0, maxTrackedTargets);
                addLog(`Poll cycle #${cycleId} recovered tracked targets from storage before empty-state handling. ids=[${ids.join(", ") || "-"}]`, "DIAGNOSTIC");
            }
        }
        const profileTargetId = targetId ? String(targetId) : "";
        const primaryId = (profileTargetId && ids.includes(profileTargetId))
            ? profileTargetId
            : String(ids[0] || "");
        addLog(`Poll cycle #${cycleId} start. ids=[${ids.join(", ") || "-"}], primary=${primaryId || "-"}, countdown=${countdownTimer}`, "DEBUG");
        if (ids.length === 0) {
            pollCycleInProgress = false;
            if (Date.now() < trackedTargetsStartupGraceUntil) {
                if (!startupNoTargetsDeferredLogged) {
                    startupNoTargetsDeferredLogged = true;
                    addLog("Startup target list is empty; delaying NO TARGETS while storage sync settles.", "DIAGNOSTIC");
                }
                return;
            }
            if (isTracking) {
                updateVisuals(PINK_COLOR, "NO TARGETS");
                if (!hasWarnedNoTargets) {
                    addLog("No tracked targets. Use 'Track Current' on a profile page to start tracking.", "ERROR");
                    hasWarnedNoTargets = true;
                }
            }
            return;
        }
        hasWarnedNoTargets = false;

        let index = 0;
        const cycleStartedAt = Date.now();
        const finishCycle = () => {
            pollCycleInProgress = false;
        };
        const next = () => {
            if (index >= ids.length) {
                addLog(`Poll cycle #${cycleId} queued all ${ids.length} target(s) in ${Date.now() - cycleStartedAt}ms.`, "DEBUG");
                finishCycle();
                return;
            }
            const id = ids[index++];
            checkProfileActivityForId(id, String(id) === primaryId, () => {
                if (index < ids.length) {
                    setTimeout(next, 300);
                } else {
                    addLog(`Poll cycle #${cycleId} complete in ${Date.now() - cycleStartedAt}ms.`, "DEBUG");
                    finishCycle();
                }
            });
        };
        next();
    }

    // --- Main Clock ---
    function runEngine() {
        if (isTornDown) return;
        if (engineTickInProgress) return;
        engineTickInProgress = true;
        try {
        syncTargetIdFromUrl();
        syncTrackingStateFromUi();
        updateManualPingCooldownVisuals();

        if (isProfilePageContext() && targetId && !document.getElementById("minerva-master-container")) {
            if ((Date.now() - lastInjectionAttemptAt) > 5000) {
                addLog("Profile UI missing; retrying injection.", "DIAGNOSTIC");
                injectSafely();
            }
        }

        if (isTracking) {
            let timerDisplay = document.getElementById("minerva-countdown");
            if (timerDisplay) timerDisplay.innerText = countdownTimer;

            if (countdownTimer <= 0) {
                checkTargetActivity();
                countdownTimer = 60; 
            } else {
                countdownTimer--;
            }
        }
        } finally {
            engineTickInProgress = false;
        }
    }

    function bootMinerva() {
        isTornDown = false;
        claimActiveMinervaInstance();
        trackedTargetsStartupGraceUntil = Date.now() + 4000;
        startupNoTargetsDeferredLogged = false;
        addLog(`Booting Minerva ${MINERVA_VERSION}. UA=${navigator.userAgent}`, "DIAGNOSTIC");
        addLog(`Initial state loaded. tracking=${isTracking}, targetId=${targetId || "-"}, trackedTargets=[${trackedTargets.join(", ")}], threshold=${thresholdSeconds}s, maxTracked=${maxTrackedTargets}`, "DIAGNOSTIC");
        bindTrackedTargetsStorageSync();
        syncTrackedTargetsFromStorage("boot");
        if (trackedTargets.length === 0) {
            setTimeout(() => {
                if (!isLiveMinervaRuntime()) return;
                syncTrackedTargetsFromStorage("boot-retry-250ms");
            }, 250);
            setTimeout(() => {
                if (!isLiveMinervaRuntime()) return;
                syncTrackedTargetsFromStorage("boot-retry-1000ms");
            }, 1000);
        }
        injectSafely();
        injectCornerWidget();
        if (engineIntervalId) {
            clearInterval(engineIntervalId);
        }
        engineIntervalId = setInterval(runEngine, 1000);
        
        if (isTracking) {
            setTimeout(checkTargetActivity, 1500); 
        }
        setTimeout(maybeCheckForMinervaUpdate, 2500);
    }

    function promptForApiKeyAndBoot(message = "Enter your Torn Public API key to enable Minerva tracking.") {
        showApiKeyEntryPanel({ message }).then(async (enteredKey) => {
            if (!enteredKey) return;
            const plain = enteredKey.trim();
            const storeResult = await storeApiKeySecurely(plain);
            if (!storeResult.ok) {
                if (storeResult.reason === "mismatch") {
                    alert("[Minerva] Passphrase confirmation mismatch. API key was not saved.");
                }
                return;
            }
            apiKey = plain;
            bootMinerva();
        });
    }

    (async () => {
        const resolvedApiKey = await resolveApiKeyForStartup();
        if (resolvedApiKey === "__MINERVA_UNLOCK_FAILED__") {
            return;
        }
        if (resolvedApiKey === "__MINERVA_UNLOCK_CANCELLED__") {
            console.warn("[Minerva] Unlock cancelled. Minerva remains locked until reload or key reset.");
            return;
        }
        if (resolvedApiKey === "__MINERVA_VAULT_RESET__") {
            promptForApiKeyAndBoot("Your encrypted API key was reset. Enter a new Torn Public API key for Minerva.");
            return;
        }

        if (!resolvedApiKey) {
            promptForApiKeyAndBoot();
            return;
        }

        apiKey = resolvedApiKey;
        bootMinerva();
    })();

    window.addEventListener("error", (e) => {
        if (isTornDown) return;
        if (shouldIgnoreGlobalErrorEvent(e)) return;
        addLog(`Window error: ${e.message} @ ${e.filename || "unknown"}:${e.lineno || 0}:${e.colno || 0}`, "ERROR");
        if (e && e.error && e.error.stack) {
            addLog(`Window error stack: ${String(e.error.stack).split("\n").slice(0, 6).join(" | ")}`, "DIAGNOSTIC");
        }
    });
    window.addEventListener("unhandledrejection", (e) => {
        if (isTornDown) return;
        if (shouldIgnoreUnhandledRejectionEvent(e)) return;
        const reason = e && e.reason ? (e.reason.stack || e.reason.message || String(e.reason)) : "unknown";
        addLog(`Unhandled promise rejection: ${String(reason).slice(0, 300)}`, "ERROR");
        if (e && e.reason && e.reason.stack) {
            addLog(`Unhandled rejection stack: ${String(e.reason.stack).split("\n").slice(0, 6).join(" | ")}`, "DIAGNOSTIC");
        }
    });

    window.addEventListener("focus", () => {
        if (isTornDown) return;
        syncTrackedTargetsFromStorage("focus");
    });

    window.addEventListener("pagehide", () => {
        teardownMinerva("unload");
    });
    window.addEventListener("beforeunload", () => {
        teardownMinerva("unload");
    });
    window[MINERVA_INTERNAL_TEARDOWN_SLOT] = teardownMinerva;

})();