diff --git a/UberWolfCli.LICENSE.txt b/UberWolfCli.LICENSE.txt deleted file mode 100644 index ac7261b..0000000 --- a/UberWolfCli.LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Sinflower - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/UberWolfCli.exe b/UberWolfCli.exe deleted file mode 100644 index 25dcf73..0000000 Binary files a/UberWolfCli.exe and /dev/null differ diff --git a/js/plugins.js b/js/plugins.js index 8444168..bf95be8 100644 --- a/js/plugins.js +++ b/js/plugins.js @@ -365,4 +365,7 @@ var $plugins = [{ "status": true, "description": "イベント実行中、先頭フォロワーがプレイヤーの方を向く", "parameters": {} -}]; +}, + { "name": "TLInspector", "status": true, "description": "TL source inspector", "parameters": {} }, + { "name": "Forge_MZ", "status": true, "description": "Forge — in-game cheat & editor overlay", "parameters": {} } + ]; diff --git a/js/plugins/Forge_MZ.js b/js/plugins/Forge_MZ.js new file mode 100644 index 0000000..2f455ab --- /dev/null +++ b/js/plugins/Forge_MZ.js @@ -0,0 +1,91 @@ +//============================================================================= +// forge.js - In-game cheat & editor overlay for RPG Maker MV/MZ +//============================================================================= +/*: + * @target MZ MV + * @plugindesc Forge - modern in-game editor + * @author len, shellawa + * @url https://gitgud.io/zero64801/forge-mvmz/ + */ +/**/ +(function () { + var toggleKey = "f8"; + var uiScale = "2.5"; + // Forge's shortcut matcher uses legacy keyCode. Some NW.js/Wine builds deliver + // keydown with keyCode=0 while still setting key/code - map those back. + window.__dazedKeyCode = function (e) { + var kc = e.keyCode || e.which || 0; + if (kc) return kc; + var key = String(e.key || "").toLowerCase(); + var code = String(e.code || ""); + if (key === "control") return 17; + if (key === "alt") return 18; + if (key === "shift") return 16; + if (key === "meta") return 91; + var fm = /^f(\d{1,2})$/.exec(key) || /^f(\d{1,2})$/i.exec(code); + if (fm) return 111 + parseInt(fm[1], 10); + var km = /^key([a-z])$/i.exec(code); + if (km) return km[1].toUpperCase().charCodeAt(0); + if (key.length === 1) { + var c = key.charCodeAt(0); + if (c >= 97 && c <= 122) return c - 32; + if (c >= 48 && c <= 57) return c; + } + var dm = /^digit([0-9])$/i.exec(code); + if (dm) return 48 + parseInt(dm[1], 10); + return 0; + }; + try { + var saved = JSON.parse(localStorage.getItem("forge:shortcuts") || "{}"); + saved.toggle_ui = Object.assign({}, saved.toggle_ui, { keyStr: toggleKey, enabled: true }); + localStorage.setItem("forge:shortcuts", JSON.stringify(saved)); + } catch (e) {} + function resolveUiScale(v) { + if (v !== "auto" && v != null && String(v).trim() !== "") { + var n = parseFloat(v); + if (!isNaN(n) && n > 0) return Math.max(0.75, Math.min(3, n)); + } + var base = 816; + var gameW = (typeof Graphics !== "undefined" && Graphics.width) ? Graphics.width : 0; + var viewW = window.innerWidth || document.documentElement.clientWidth || base; + var w = Math.max(gameW || base, viewW); + var scale = w / base; + var dpr = window.devicePixelRatio || 1; + if (dpr > 1.15) scale *= Math.min(2, 0.75 + dpr * 0.35); + return Math.max(1, Math.min(2.75, scale)); + } + function applyUiScale() { + var host = document.getElementById("forge-mvmz-host"); + if (!host) return; + var fx = resolveUiScale(uiScale); + host.style.zoom = String(fx); + } + if (!window.__dazedForgeUiScaleHook) { + window.__dazedForgeUiScaleHook = true; + var observer = new MutationObserver(applyUiScale); + observer.observe(document.documentElement, { childList: true, subtree: true }); + window.addEventListener("resize", applyUiScale); + setInterval(applyUiScale, 500); + } + applyUiScale(); +})(); +/**/ +(function(){var e=document.createElement(`style`);e.textContent=`@import "https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap";:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:#ff6568;--color-orange-400:#ff8b1a;--color-yellow-300:#ffe02a;--color-yellow-400:#fac800;--color-yellow-500:#edb200;--color-fuchsia-500:#e12afb;--color-gray-200:#e5e7eb;--color-gray-300:#d1d5dc;--color-gray-400:#99a1af;--color-gray-500:#6a7282;--color-gray-600:#4a5565;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-black:900;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-normal:1.5;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#0b0c10;--color-bg2:#13151f;--color-text:#f1f5f9;--color-text-dim:#9aa1b1;--color-accent:#6366f1;--color-accent-weak:#1e3a6e;--color-border:#222533;--color-danger:#ef4444;--color-ok:#10b981;--color-warn:#fb923c;--color-frozen:#8b5cf6}@supports (color:lab(0% 0 0)){:root,:host{--color-red-400:lab(63.7053% 60.745 31.3109);--color-orange-400:lab(70.0429% 42.5156 75.8207);--color-yellow-300:lab(89.7033% -.480294 84.4917);--color-yellow-400:lab(83.2664% 8.65132 106.895);--color-yellow-500:lab(76.3898% 14.5258 98.4589);--color-fuchsia-500:lab(56.4256% 83.132 -64.639);--color-gray-200:lab(91.6229% -.159115 -2.26791);--color-gray-300:lab(85.1236% -.612259 -3.7138);--color-gray-400:lab(65.9269% -.832707 -8.17473);--color-gray-500:lab(47.7841% -.393182 -10.0268);--color-gray-600:lab(35.6337% -1.58697 -10.8425)}}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::-webkit-file-upload-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:transparent;border-radius:0}::-webkit-file-upload-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:transparent;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:transparent;border-radius:0}:where(select:-webkit-any([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:-webkit-any([multiple],[size])) optgroup option{padding-left:20px}:where(select:is([multiple],[size])) optgroup option{padding-left:20px}::-webkit-file-upload-button{margin-right:4px}::file-selector-button{margin-right:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-year-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-month-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-day-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-hour-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-minute-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-second-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-millisecond-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button{-webkit-appearance:button;appearance:button}input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;appearance:button}::-webkit-file-upload-button{-webkit-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{top:0;bottom:0;left:0;right:0}.top-0{top:0}.top-4{top:calc(var(--spacing) * 4)}.top-\\[-0\\.5px\\]{top:-.5px}.top-\\[4px\\]{top:4px}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.left-4{left:calc(var(--spacing) * 4)}.left-\\[4px\\]{left:4px}.left-\\[24px\\]{left:24px}.z-2147482999{z-index:2147482999}.z-2147483000{z-index:2147483000}.z-2147483647{z-index:2147483647}.m-0{margin:0}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:var(--spacing)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mr-3{margin-right:calc(var(--spacing) * 3)}.mr-4{margin-right:calc(var(--spacing) * 4)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-1\\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.min-h-0{min-height:0}.w-1\\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-4{width:calc(var(--spacing) * 4)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-32{width:calc(var(--spacing) * 32)}.w-40{width:calc(var(--spacing) * 40)}.w-48{width:calc(var(--spacing) * 48)}.w-full{width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-grab{cursor:grab}.cursor-move{cursor:move}.cursor-nwse-resize{cursor:nwse-resize}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.grid-cols-\\[repeat\\(auto-fit\\,minmax\\(140px\\,1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}.grid-cols-\\[repeat\\(auto-fit\\,minmax\\(160px\\,1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.grid-cols-\\[repeat\\(auto-fit\\,minmax\\(260px\\,1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.grid-cols-\\[repeat\\(auto-fit\\,minmax\\(300px\\,1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{grid-gap:calc(var(--spacing) * 2);gap:calc(var(--spacing) * 2)}.gap-3{grid-gap:calc(var(--spacing) * 3);gap:calc(var(--spacing) * 3)}.gap-4{grid-gap:calc(var(--spacing) * 4);gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-top:calc(var(--spacing) * var(--tw-space-y-reverse));margin-bottom:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-1>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(var(--spacing) * var(--tw-space-x-reverse));margin-right:calc(var(--spacing) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-1\\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(calc(var(--spacing) * 1.5) * var(--tw-space-x-reverse));margin-right:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse));margin-right:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-2\\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(calc(var(--spacing) * 2.5) * var(--tw-space-x-reverse));margin-right:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(calc(var(--spacing) * 3) * var(--tw-space-x-reverse));margin-right:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-3\\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(calc(var(--spacing) * 3.5) * var(--tw-space-x-reverse));margin-right:calc(calc(var(--spacing) * 3.5) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-left:calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse));margin-right:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border)}:where(.divide-border\\/50>:not(:last-child)){border-color:rgba(34,37,51,.5)}@supports (color:color-mix(in lab, red, red)){:where(.divide-border\\/50>:not(:last-child)){border-color:color-mix(in oklab, var(--color-border) 50%, transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\\[\\#2a2d3a\\]{border-color:#2a2d3a}.border-accent{border-color:var(--color-accent)}.border-accent\\/30{border-color:rgba(99,102,241,.3)}@supports (color:color-mix(in lab, red, red)){.border-accent\\/30{border-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.border-accent\\/50{border-color:rgba(99,102,241,.5)}@supports (color:color-mix(in lab, red, red)){.border-accent\\/50{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.border-border{border-color:var(--color-border)}.border-border\\/50{border-color:rgba(34,37,51,.5)}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab, var(--color-border) 50%, transparent)}}.border-danger\\/30{border-color:rgba(239,68,68,.3)}@supports (color:color-mix(in lab, red, red)){.border-danger\\/30{border-color:color-mix(in oklab, var(--color-danger) 30%, transparent)}}.border-fuchsia-500\\/30{border-color:rgba(225,42,251,.3)}@supports (color:color-mix(in lab, red, red)){.border-fuchsia-500\\/30{border-color:color-mix(in oklab, var(--color-fuchsia-500) 30%, transparent)}}.border-gray-500\\/30{border-color:rgba(106,114,130,.3)}@supports (color:color-mix(in lab, red, red)){.border-gray-500\\/30{border-color:color-mix(in oklab, var(--color-gray-500) 30%, transparent)}}.border-ok\\/30{border-color:rgba(16,185,129,.3)}@supports (color:color-mix(in lab, red, red)){.border-ok\\/30{border-color:color-mix(in oklab, var(--color-ok) 30%, transparent)}}.border-warn\\/30{border-color:rgba(251,146,60,.3)}@supports (color:color-mix(in lab, red, red)){.border-warn\\/30{border-color:color-mix(in oklab, var(--color-warn) 30%, transparent)}}.border-yellow-500\\/30{border-color:rgba(237,178,0,.3)}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\\/30{border-color:color-mix(in oklab, var(--color-yellow-500) 30%, transparent)}}.border-l-frozen{border-left-color:var(--color-frozen)}.bg-\\[\\#1a1d24\\]{background-color:#1a1d24}.bg-\\[\\#3a3f4d\\]{background-color:#3a3f4d}.bg-\\[\\#7ba4ff\\]\\/10{background-color:rgba(123,164,255,.1);background-color:lab(67.3388% 4.90472 -50.2993/.1)}.bg-\\[\\#13151a\\]{background-color:#13151a}.bg-accent{background-color:var(--color-accent)}.bg-accent-weak{background-color:var(--color-accent-weak)}.bg-accent\\/5{background-color:rgba(99,102,241,.05)}@supports (color:color-mix(in lab, red, red)){.bg-accent\\/5{background-color:color-mix(in oklab, var(--color-accent) 5%, transparent)}}.bg-accent\\/10{background-color:rgba(99,102,241,.1)}@supports (color:color-mix(in lab, red, red)){.bg-accent\\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.bg-accent\\/20{background-color:rgba(99,102,241,.2)}@supports (color:color-mix(in lab, red, red)){.bg-accent\\/20{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.bg-bg{background-color:var(--color-bg)}.bg-bg2{background-color:var(--color-bg2)}.bg-border{background-color:var(--color-border)}.bg-border\\/50{background-color:rgba(34,37,51,.5)}@supports (color:color-mix(in lab, red, red)){.bg-border\\/50{background-color:color-mix(in oklab, var(--color-border) 50%, transparent)}}.bg-danger{background-color:var(--color-danger)}.bg-danger\\/10{background-color:rgba(239,68,68,.1)}@supports (color:color-mix(in lab, red, red)){.bg-danger\\/10{background-color:color-mix(in oklab, var(--color-danger) 10%, transparent)}}.bg-danger\\/20{background-color:rgba(239,68,68,.2)}@supports (color:color-mix(in lab, red, red)){.bg-danger\\/20{background-color:color-mix(in oklab, var(--color-danger) 20%, transparent)}}.bg-frozen\\/20{background-color:rgba(139,92,246,.2)}@supports (color:color-mix(in lab, red, red)){.bg-frozen\\/20{background-color:color-mix(in oklab, var(--color-frozen) 20%, transparent)}}.bg-fuchsia-500\\/10{background-color:rgba(225,42,251,.1)}@supports (color:color-mix(in lab, red, red)){.bg-fuchsia-500\\/10{background-color:color-mix(in oklab, var(--color-fuchsia-500) 10%, transparent)}}.bg-gray-500\\/10{background-color:rgba(106,114,130,.1)}@supports (color:color-mix(in lab, red, red)){.bg-gray-500\\/10{background-color:color-mix(in oklab, var(--color-gray-500) 10%, transparent)}}.bg-ok{background-color:var(--color-ok)}.bg-ok\\/10{background-color:rgba(16,185,129,.1)}@supports (color:color-mix(in lab, red, red)){.bg-ok\\/10{background-color:color-mix(in oklab, var(--color-ok) 10%, transparent)}}.bg-ok\\/20{background-color:rgba(16,185,129,.2)}@supports (color:color-mix(in lab, red, red)){.bg-ok\\/20{background-color:color-mix(in oklab, var(--color-ok) 20%, transparent)}}.bg-transparent{background-color:transparent}.bg-warn\\/10{background-color:rgba(251,146,60,.1)}@supports (color:color-mix(in lab, red, red)){.bg-warn\\/10{background-color:color-mix(in oklab, var(--color-warn) 10%, transparent)}}.bg-white{background-color:var(--color-white)}.bg-yellow-500\\/10{background-color:rgba(237,178,0,.1)}@supports (color:color-mix(in lab, red, red)){.bg-yellow-500\\/10{background-color:color-mix(in oklab, var(--color-yellow-500) 10%, transparent)}}.fill-current{fill:currentColor}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-1{padding-left:var(--spacing);padding-right:var(--spacing)}.px-1\\.5{padding-left:calc(var(--spacing) * 1.5);padding-right:calc(var(--spacing) * 1.5)}.px-2{padding-left:calc(var(--spacing) * 2);padding-right:calc(var(--spacing) * 2)}.px-2\\.5{padding-left:calc(var(--spacing) * 2.5);padding-right:calc(var(--spacing) * 2.5)}.px-3{padding-left:calc(var(--spacing) * 3);padding-right:calc(var(--spacing) * 3)}.px-3\\.5{padding-left:calc(var(--spacing) * 3.5);padding-right:calc(var(--spacing) * 3.5)}.px-4{padding-left:calc(var(--spacing) * 4);padding-right:calc(var(--spacing) * 4)}.py-0\\.5{padding-top:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * .5)}.py-1{padding-top:var(--spacing);padding-bottom:var(--spacing)}.py-1\\.5{padding-top:calc(var(--spacing) * 1.5);padding-bottom:calc(var(--spacing) * 1.5)}.py-2{padding-top:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 2)}.py-3{padding-top:calc(var(--spacing) * 3);padding-bottom:calc(var(--spacing) * 3)}.pt-1{padding-top:var(--spacing)}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-1\\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\\[\\#7ba4ff\\]{color:#7ba4ff}.text-accent{color:var(--color-accent)}.text-danger{color:var(--color-danger)}.text-frozen{color:var(--color-frozen)}.text-fuchsia-500{color:var(--color-fuchsia-500)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-ok{color:var(--color-ok)}.text-orange-400{color:var(--color-orange-400)}.text-text{color:var(--color-text)}.text-text-dim{color:var(--color-text-dim)}.text-warn{color:var(--color-warn)}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.uppercase{text-transform:uppercase}.opacity-50{opacity:.5}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,rgba(0,0,0,.1)), 0 1px 2px -1px var(--tw-shadow-color,rgba(0,0,0,.1));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,rgba(0,0,0,.25));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,rgba(0,0,0,.1)), 0 4px 6px -4px var(--tw-shadow-color,rgba(0,0,0,.1));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,rgba(0,0,0,.1)), 0 1px 2px -1px var(--tw-shadow-color,rgba(0,0,0,.1));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{user-select:none}.select-text{user-select:text}@media (hover:hover){.group-hover\\:text-accent:is(:where(.group):hover *){color:var(--color-accent)}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.first-letter\\:text-\\[\\#7ba4ff\\]:first-letter{color:#7ba4ff}@media (hover:hover){.hover\\:bg-\\[\\#2a2d3a\\]:hover{background-color:#2a2d3a}.hover\\:bg-accent\\/20:hover{background-color:rgba(99,102,241,.2)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-accent\\/20:hover{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.hover\\:bg-accent\\/30:hover{background-color:rgba(99,102,241,.3)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-accent\\/30:hover{background-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.hover\\:bg-accent\\/80:hover{background-color:rgba(99,102,241,.8)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-accent\\/80:hover{background-color:color-mix(in oklab, var(--color-accent) 80%, transparent)}}.hover\\:bg-accent\\/85:hover{background-color:rgba(99,102,241,.85)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-accent\\/85:hover{background-color:color-mix(in oklab, var(--color-accent) 85%, transparent)}}.hover\\:bg-border:hover{background-color:var(--color-border)}.hover\\:bg-border\\/30:hover{background-color:rgba(34,37,51,.3)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-border\\/30:hover{background-color:color-mix(in oklab, var(--color-border) 30%, transparent)}}.hover\\:bg-border\\/50:hover{background-color:rgba(34,37,51,.5)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-border\\/50:hover{background-color:color-mix(in oklab, var(--color-border) 50%, transparent)}}.hover\\:bg-border\\/80:hover{background-color:rgba(34,37,51,.8)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-border\\/80:hover{background-color:color-mix(in oklab, var(--color-border) 80%, transparent)}}.hover\\:bg-danger\\/20:hover{background-color:rgba(239,68,68,.2)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-danger\\/20:hover{background-color:color-mix(in oklab, var(--color-danger) 20%, transparent)}}.hover\\:bg-danger\\/30:hover{background-color:rgba(239,68,68,.3)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-danger\\/30:hover{background-color:color-mix(in oklab, var(--color-danger) 30%, transparent)}}.hover\\:bg-danger\\/80:hover{background-color:rgba(239,68,68,.8)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-danger\\/80:hover{background-color:color-mix(in oklab, var(--color-danger) 80%, transparent)}}.hover\\:bg-frozen\\/30:hover{background-color:rgba(139,92,246,.3)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-frozen\\/30:hover{background-color:color-mix(in oklab, var(--color-frozen) 30%, transparent)}}.hover\\:bg-ok\\/30:hover{background-color:rgba(16,185,129,.3)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-ok\\/30:hover{background-color:color-mix(in oklab, var(--color-ok) 30%, transparent)}}.hover\\:text-danger:hover{color:var(--color-danger)}.hover\\:text-gray-200:hover{color:var(--color-gray-200)}.hover\\:text-gray-300:hover{color:var(--color-gray-300)}.hover\\:text-gray-400:hover{color:var(--color-gray-400)}.hover\\:text-red-400:hover{color:var(--color-red-400)}.hover\\:text-white:hover{color:var(--color-white)}.hover\\:text-yellow-300:hover{color:var(--color-yellow-300)}.hover\\:opacity-100:hover{opacity:1}.hover\\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\\:border-accent:focus{border-color:var(--color-accent)}.focus\\:bg-border\\/30:focus{background-color:rgba(34,37,51,.3)}@supports (color:color-mix(in lab, red, red)){.focus\\:bg-border\\/30:focus{background-color:color-mix(in oklab, var(--color-border) 30%, transparent)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:opacity-50:disabled{opacity:.5}:host{--color-bg:#0b0c10;--color-bg-elev:#13151f;--color-bg-input:#1a1c29;--color-bg2:#13151f;--color-text:#f1f5f9;--color-text-dim:#9aa1b1;--color-text-faint:#646b7d;--color-accent:#6366f1;--color-accent-weak:#1e3a6e;--color-border:#222533;--color-danger:#ef4444;--color-ok:#10b981;--color-warn:#fb923c;--color-frozen:#8b5cf6}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:#222533;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#6366f1}body,:host{color:#f1f5f9;font-family:Outfit,system-ui,-apple-system,sans-serif}*,:after,:before{--tw-border-style:solid}.cursor-grab{cursor:-webkit-grab;cursor:grab}.active\\:cursor-grabbing:active{cursor:-webkit-grabbing;cursor:grabbing}.space-x-1>:not([hidden])~:not([hidden]){margin-left:4px}.space-x-1\\.5>:not([hidden])~:not([hidden]){margin-left:6px}.space-x-2>:not([hidden])~:not([hidden]){margin-left:8px}.space-x-2\\.5>:not([hidden])~:not([hidden]){margin-left:10px}.space-x-3>:not([hidden])~:not([hidden]){margin-left:12px}.space-x-4>:not([hidden])~:not([hidden]){margin-left:16px}.space-y-0\\.5>:not([hidden])~:not([hidden]){margin-top:2px}.space-y-1>:not([hidden])~:not([hidden]){margin-top:4px}.space-y-2>:not([hidden])~:not([hidden]){margin-top:8px}.space-y-2\\.5>:not([hidden])~:not([hidden]){margin-top:10px}.space-y-3>:not([hidden])~:not([hidden]){margin-top:12px}.space-y-4>:not([hidden])~:not([hidden]){margin-top:16px}.space-y-6>:not([hidden])~:not([hidden]){margin-top:24px}.divide-y>:not([hidden])~:not([hidden]){border-top-width:1px;border-color:var(--color-border)}input,textarea,[contenteditable=true]{user-select:text!important}button,button:focus{outline:none!important}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 transparent}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 transparent}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 transparent}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 transparent}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 transparent}@property --tw-duration{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 transparent;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 transparent;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 transparent;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 transparent;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 transparent;--tw-duration:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}} +/*$vite$:1*/`,document.head.appendChild(e);var t=!1,n=Array.isArray,r=Array.prototype.indexOf,i=Array.prototype.includes,a=Array.from,o=Object.defineProperty,s=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyDescriptors,l=Object.prototype,u=Array.prototype,d=Object.getPrototypeOf,f=Object.isExtensible;function p(e){return typeof e==`function`}var m=()=>{};function h(e){return e()}function g(e){for(var t=0;t{e=n,t=r}),resolve:e,reject:t}}function v(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);let n=[];for(let r of e)if(n.push(r),n.length===t)break;return n}function y(e){"@babel/helpers - typeof";return y=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},y(e)}function b(e,t){if(y(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(y(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function x(e){var t=b(e,`string`);return y(t)==`symbol`?t:t+``}function S(e,t,n){return(t=x(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ee,C=1<<24,w=1024,te=2048,ne=4096,re=8192,ie=16384,ae=32768,oe=1<<25,se=65536,ce=1<<19,le=1<<20,ue=1<<25,de=65536,fe=1<<21,pe=1<<22,me=1<<23,he=Symbol(`$state`),ge=Symbol(`legacy props`),_e=Symbol(``),ve=Symbol(`proxy path`),ye=Symbol(`attributes`),be=Symbol(`class`),xe=Symbol(`style`),Se=Symbol(`text`),Ce=Symbol(`form reset`),we=Symbol(`hmr anchor`),Te=new class extends Error{constructor(...e){super(...e),S(this,`name`,`StaleReactionError`),S(this,`message`,"The reaction that called `getAbortSignal()` was re-run or destroyed")}},Ee=!!((ee=globalThis.document)!=null&&ee.contentType)&&globalThis.document.contentType.includes(`xml`);function De(e){if(t){let t=Error(`invariant_violation\nAn invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app — please open an issue at https://github.com/sveltejs/svelte, citing the following message: "${e}"\nhttps://svelte.dev/e/invariant_violation`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/invariant_violation`)}function Oe(e){if(t){let t=Error(`lifecycle_outside_component\n\`${e}(...)\` can only be used during component initialisation\nhttps://svelte.dev/e/lifecycle_outside_component`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function ke(){if(t){let e=Error("async_derived_orphan\nCannot create a `$derived(...)` with an `await` expression outside of an effect tree\nhttps://svelte.dev/e/async_derived_orphan");throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/async_derived_orphan`)}function Ae(){if(t){let e=Error("bind_invalid_checkbox_value\nUsing `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead\nhttps://svelte.dev/e/bind_invalid_checkbox_value");throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/bind_invalid_checkbox_value`)}function je(){if(t){let e=Error(`derived_references_self +A derived value cannot reference itself recursively +https://svelte.dev/e/derived_references_self`);throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/derived_references_self`)}function Me(e,n,r){if(t){let t=Error(`each_key_duplicate\n${r?`Keyed each block has duplicate key \`${r}\` at indexes ${e} and ${n}`:`Keyed each block has duplicate key at indexes ${e} and ${n}`}\nhttps://svelte.dev/e/each_key_duplicate`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Ne(e,n,r){if(t){let t=Error(`each_key_volatile\nKeyed each block has key that is not idempotent — the key for item at index ${e} was \`${n}\` but is now \`${r}\`. Keys must be the same each time for a given item\nhttps://svelte.dev/e/each_key_volatile`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/each_key_volatile`)}function Pe(e){if(t){let t=Error(`effect_in_teardown\n\`${e}\` cannot be used inside an effect cleanup function\nhttps://svelte.dev/e/effect_in_teardown`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/effect_in_teardown`)}function Fe(){if(t){let e=Error(`effect_in_unowned_derived +Effect cannot be created inside a \`$derived\` value that was not itself created inside an effect +https://svelte.dev/e/effect_in_unowned_derived`);throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Ie(e){if(t){let t=Error(`effect_orphan\n\`${e}\` can only be used inside an effect (e.g. during component initialisation)\nhttps://svelte.dev/e/effect_orphan`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/effect_orphan`)}function Le(){if(t){let e=Error(`effect_update_depth_exceeded +Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state +https://svelte.dev/e/effect_update_depth_exceeded`);throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function Re(){if(t){let e=Error("invalid_snippet\nCould not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`\nhttps://svelte.dev/e/invalid_snippet");throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/invalid_snippet`)}function ze(e){if(t){let t=Error(`props_invalid_value\nCannot do \`bind:${e}={undefined}\` when \`${e}\` has a fallback value\nhttps://svelte.dev/e/props_invalid_value`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/props_invalid_value`)}function Be(e){if(t){let t=Error(`props_rest_readonly\nRest element properties of \`$props()\` such as \`${e}\` are readonly\nhttps://svelte.dev/e/props_rest_readonly`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/props_rest_readonly`)}function Ve(e){if(t){let t=Error(`rune_outside_svelte\nThe \`${e}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files\nhttps://svelte.dev/e/rune_outside_svelte`);throw t.name=`Svelte error`,t}else throw Error(`https://svelte.dev/e/rune_outside_svelte`)}function He(){if(t){let e=Error("state_descriptors_fixed\nProperty descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.\nhttps://svelte.dev/e/state_descriptors_fixed");throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Ue(){if(t){let e=Error(`state_prototype_fixed +Cannot set prototype of \`$state\` object +https://svelte.dev/e/state_prototype_fixed`);throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function We(){if(t){let e=Error("state_unsafe_mutation\nUpdating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`\nhttps://svelte.dev/e/state_unsafe_mutation");throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Ge(){if(t){let e=Error("svelte_boundary_reset_onerror\nA `` `reset` function cannot be called while an error is still being handled\nhttps://svelte.dev/e/svelte_boundary_reset_onerror");throw e.name=`Svelte error`,e}else throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var Ke={},qe=Symbol(`uninitialized`),Je=Symbol(`filename`),Ye=`http://www.w3.org/1999/xhtml`,Xe=`http://www.w3.org/2000/svg`,Ze=`font-weight: bold`,Qe=`font-weight: normal`;function $e(e){t?console.warn(`%c[svelte] await_reactivity_loss\n%cDetected reactivity loss when reading \`${e}\`. This happens when state is read in an async function after an earlier \`await\`\nhttps://svelte.dev/e/await_reactivity_loss`,Ze,Qe):console.warn(`https://svelte.dev/e/await_reactivity_loss`)}function et(e,n){t?console.warn(`%c[svelte] await_waterfall\n%cAn async derived, \`${e}\` (${n}) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app\nhttps://svelte.dev/e/await_waterfall`,Ze,Qe):console.warn(`https://svelte.dev/e/await_waterfall`)}function tt(){t?console.warn(`%c[svelte] derived_inert +%cReading a derived belonging to a now-destroyed effect may result in stale values +https://svelte.dev/e/derived_inert`,Ze,Qe):console.warn(`https://svelte.dev/e/derived_inert`)}function nt(e,n,r){t?console.warn(`%c[svelte] hydration_attribute_changed\n%cThe \`${e}\` attribute on \`${n}\` changed its value between server and client renders. The client value, \`${r}\`, will be ignored in favour of the server value\nhttps://svelte.dev/e/hydration_attribute_changed`,Ze,Qe):console.warn(`https://svelte.dev/e/hydration_attribute_changed`)}function rt(e){t?console.warn(`%c[svelte] hydration_mismatch\n%c${e?`Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near ${e}`:`Hydration failed because the initial UI does not match what was rendered on the server`}\nhttps://svelte.dev/e/hydration_mismatch`,Ze,Qe):console.warn(`https://svelte.dev/e/hydration_mismatch`)}function it(){t?console.warn("%c[svelte] select_multiple_invalid_value\n%cThe `value` property of a ` `);function fl(e,t){Mt(t,!0);let n=Hs(t,`value`,15,0),r=Hs(t,`min`,19,()=>-1/0),i=Hs(t,`max`,3,1/0),a=P(I(String(n())));Mi(()=>{F(a,String(n()),!0)});let o=()=>{var e;let o=parseFloat(H(a));isNaN(o)&&(o=n()),o=Math.max(r(),Math.min(i(),o)),n(o),F(a,String(o),!0),(e=t.onchange)==null||e.call(t,n())},s=(e,o)=>{var s;o.shiftKey&&(e*=10);let c=n()+e;c=Math.max(r(),Math.min(i(),c)),n(c),F(a,String(c),!0),(s=t.onchange)==null||s.call(t,n())},c=e=>{e.stopPropagation(),e.key===`Enter`?(o(),e.target.blur()):e.key===`Escape`&&(F(a,String(n()),!0),e.target.blur())};var l=dl(),u=L(l),d=R(u,2);us(d);var f=R(d,2);D(l),U(`click`,u,e=>s(-1,e)),Ua(`blur`,d,o),U(`keydown`,d,c),Cs(d,()=>H(a),e=>F(a,e)),U(`click`,f,e=>s(1,e)),G(e,l),Nt()}Wa([`click`,`keydown`]);var pl=W(``);function ml(e,t){Mt(t,!0);let n=Hs(t,`locked`,3,!1);var r=pl(),i=L(r),a=e=>{uc(e,{size:14})},o=e=>{cc(e,{size:14})};mo(i,e=>{n()?e(a):e(o,-1)}),D(r),z(()=>{Jo(r,1,`flex h-6 w-6 shrink-0 items-center justify-center rounded transition-colors focus:outline-none ${n()?`bg-frozen/20 text-frozen hover:bg-frozen/30`:`hover:bg-border text-gray-500 hover:text-gray-300`}`),ps(r,`title`,n()?`Unfreeze`:`Freeze`),ps(r,`aria-label`,n()?`Unfreeze state`:`Freeze state`)}),U(`click`,r,()=>{var e;return(e=t.ontoggle)==null?void 0:e.call(t,!n())}),G(e,r),Nt()}Wa([`click`]);var hl=W(``),gl=W(``),_l=W(`
`),vl=W(`
`);function yl(e,t){Mt(t,!0);let n=P(I([])),r=P(I([])),i=P(``),a=P(void 0);Mi(()=>{if(Q.targetVarId!==null&&H(a)&&H(r).length>0){let e=H(r).findIndex(e=>e.id===Q.targetVarId);e!==-1&&H(a).scrollToIndex(e),Q.targetVarId=null}});let o,s=P(!1),c=new Set,l=I({}),u=()=>{if(!H(i).trim())c=new Set(H(n).map(e=>e.id));else{let e=H(i).trim().toLowerCase(),t=H(n).filter(t=>String(t.id)===e||t.name.toLowerCase().includes(e)||t.value!==void 0&&t.value!==null&&String(t.value).toLowerCase().includes(e));c=new Set(t.map(e=>e.id))}},d=()=>{F(r,H(n).filter(e=>c.has(e.id)).sort((e,t)=>{let n=Zc.isFavorite(`variables`,e.id),r=Zc.isFavorite(`variables`,t.id);return n&&!r?-1:!n&&r?1:e.id-t.id}),!0)},f=()=>{F(n,q.vars.list(),!0),u(),d()},p=e=>{F(i,e.target.value,!0),clearTimeout(o),o=setTimeout(()=>{u(),d()},300)};Ws(()=>{f();let e=setInterval(()=>{H(s)||(F(n,q.vars.list(),!0),d())},1e3);return()=>clearInterval(e)});let h=(e,t)=>{q.vars.set(e,t),Y.vars.has(e)&&X.freezeVar(e,!0);let r=H(n).find(t=>t.id===e);r&&(r.value=t)};var g=vl(),_=L(g),v=L(_);us(v);var y=R(v,2),b=L(y);D(y),D(_);var x=R(_,2);Ps(ul(L(x),{get items(){return H(r)},itemHeight:36,itemTemplate:(e,t=m)=>{let r=Wn(()=>l[t().id]||typeof t().value);var i=_l(),a=L(i),o=L(a,!0);D(a);var c=R(a,2),u=L(c),f=L(u,!0);D(u),D(c);var p=R(c,2),g=L(p),_=L(g);{let e=Wn(()=>Zc.isFavorite(`variables`,t().id)?`fill-current`:``);bc(_,{size:16,get class(){return H(e)}})}D(g);var v=R(g,2),y=L(v,!0);D(v);var b=R(v,2),x=e=>{{let n=Wn(()=>Number(t().value)||0);fl(e,{get value(){return H(n)},onchange:e=>h(t().id,e)})}},S=e=>{var n=hl(),r=L(n);r.value=r.__value=`true`;var i=R(r);i.value=i.__value=`false`,D(n);var a;Qo(n),z(()=>{a!==(a=t().value?`true`:`false`)&&(n.value=n.__value=t().value?`true`:`false`,Zo(n,t().value?`true`:`false`))}),U(`change`,n,e=>h(t().id,e.currentTarget.value===`true`)),G(e,n)},ee=e=>{var n=gl();us(n),z(e=>ds(n,e),[()=>String(t().value===void 0||t().value===null?``:t().value)]),Ua(`blur`,n,e=>h(t().id,e.currentTarget.value)),U(`keydown`,n,e=>{e.stopPropagation(),e.key===`Enter`&&e.currentTarget.blur()}),G(e,n)};mo(b,e=>{H(r)===`number`?e(x):H(r)===`boolean`?e(S,1):e(ee,-1)});var C=R(b,2),w=L(C);{let e=Wn(()=>Y.vars.has(t().id));ml(w,{get locked(){return H(e)},ontoggle:e=>{X.freezeVar(t().id,e),F(n,[...H(n)],!0),d()}})}D(C),D(p),D(i),z((e,n,a)=>{Jo(i,1,`border-border/50 hover:bg-border/30 flex h-full items-center border-b px-4 transition-colors ${e==null?``:e}`),K(o,n),ps(u,`title`,t().name),K(f,t().name),Jo(g,1,`mr-2 flex items-center justify-center transition-colors ${a==null?``:a}`),K(y,H(r)===`number`?`NUM`:H(r)===`string`?`STR`:`BOOL`)},[()=>Y.vars.has(t().id)?`border-l-frozen border-l-4 pl-3`:``,()=>t().id.toString().padStart(4,`0`),()=>Zc.isFavorite(`variables`,t().id)?`text-yellow-400 hover:text-yellow-300`:`text-gray-600 hover:text-gray-400`]),U(`focusin`,p,()=>F(s,!0)),U(`focusout`,p,()=>F(s,!1)),U(`click`,g,()=>{Zc.toggleFavorite(`variables`,t().id),d()}),U(`click`,v,()=>{(l[t().id]||typeof t().value)===`number`?l[t().id]=`string`:l[t().id]=`number`}),G(e,i)},$$slots:{itemTemplate:!0}}),e=>F(a,e,!0),()=>H(a)),D(x),D(g),z(()=>{var e;ds(v,H(i)),K(b,`${(e=H(r).length)==null?``:e} items`)}),U(`input`,v,p),G(e,g),Nt()}Wa([`input`,`focusin`,`focusout`,`click`,`change`,`keydown`]);var bl=W(``);function xl(e,t){Mt(t,!0);let n=Hs(t,`value`,15,!1),r=()=>{var e;n(!n()),(e=t.onchange)==null||e.call(t,n())};var i=bl(),a=L(i);D(i),z(()=>{Jo(i,1,`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors ${n()?`bg-ok`:`bg-[#3a3f4d]`}`),Jo(a,1,`absolute top-[4px] h-4 w-4 rounded-full bg-white shadow transition-all ${n()?`left-[24px]`:`left-[4px]`}`)}),U(`click`,i,r),G(e,i),Nt()}Wa([`click`]);var Sl=W(`
`),Cl=W(`
`);function wl(e,t){Mt(t,!0);let n=P(I([])),r=P(I([])),i=P(``),a=P(void 0);Mi(()=>{if(Q.targetSwitchId!==null&&H(a)&&H(r).length>0){let e=H(r).findIndex(e=>e.id===Q.targetSwitchId);e!==-1&&H(a).scrollToIndex(e),Q.targetSwitchId=null}});let o,s=P(!1),c=new Set,l=()=>{if(!H(i).trim())c=new Set(H(n).map(e=>e.id));else{let e=H(i).trim().toLowerCase(),t=H(n).filter(t=>String(t.id)===e||t.name.toLowerCase().includes(e)||(t.value?`true`:`false`).includes(e));c=new Set(t.map(e=>e.id))}},u=()=>{F(r,H(n).filter(e=>c.has(e.id)).sort((e,t)=>{let n=Zc.isFavorite(`switches`,e.id),r=Zc.isFavorite(`switches`,t.id);return n&&!r?-1:!n&&r?1:e.id-t.id}),!0)},d=()=>{F(n,q.switches.list(),!0),l(),u()},f=e=>{F(i,e.target.value,!0),clearTimeout(o),o=setTimeout(()=>{l(),u()},300)};Ws(()=>{d();let e=setInterval(()=>{H(s)||(F(n,q.switches.list(),!0),u())},1e3);return()=>clearInterval(e)});let p=(e,t)=>{q.switches.set(e,t),Y.switches.has(e)&&X.freezeSwitch(e,!0);let r=H(n).find(t=>t.id===e);r&&(r.value=t)},h=e=>{H(r).forEach(t=>p(t.id,e)),d(),zc.show(`All filtered switches turned ${e?`ON`:`OFF`}`,`success`)};var g=Cl(),_=L(g),v=L(_);us(v);var y=R(v,2),b=L(y),x=R(b,2),S=R(x,2),ee=L(S);D(S),D(y),D(_);var C=R(_,2);Ps(ul(L(C),{get items(){return H(r)},itemHeight:36,itemTemplate:(e,t=m)=>{var r=Sl(),i=L(r),a=L(i,!0);D(i);var o=R(i,2),c=L(o),l=L(c,!0);D(c),D(o);var d=R(o,2),f=L(d),h=L(f);{let e=Wn(()=>Zc.isFavorite(`switches`,t().id)?`fill-current`:``);bc(h,{size:16,get class(){return H(e)}})}D(f);var g=R(f,2);xl(g,{get value(){return t().value},onchange:e=>p(t().id,e)});var _=R(g,2),v=L(_);{let e=Wn(()=>Y.switches.has(t().id));ml(v,{get locked(){return H(e)},ontoggle:e=>{X.freezeSwitch(t().id,e),F(n,[...H(n)],!0),u()}})}D(_),D(d),D(r),z((e,n,i)=>{Jo(r,1,`border-border/50 hover:bg-border/30 flex h-full items-center border-b px-4 transition-colors ${e==null?``:e}`),K(a,n),Jo(c,1,`truncate text-sm select-text cursor-text ${t().value?`text-white font-bold`:`text-gray-400`}`),K(l,t().name),Jo(f,1,`flex items-center justify-center transition-colors ${i==null?``:i}`)},[()=>Y.switches.has(t().id)?`border-l-frozen border-l-4 pl-3`:``,()=>t().id.toString().padStart(4,`0`),()=>Zc.isFavorite(`switches`,t().id)?`text-yellow-400 hover:text-yellow-300`:`text-gray-600 hover:text-gray-400`]),Ua(`mouseenter`,d,()=>F(s,!0)),Ua(`mouseleave`,d,()=>F(s,!1)),U(`click`,f,()=>{Zc.toggleFavorite(`switches`,t().id),u()}),G(e,r)},$$slots:{itemTemplate:!0}}),e=>F(a,e,!0),()=>H(a)),D(C),D(g),z(()=>{var e;ds(v,H(i)),K(ee,`${(e=H(r).length)==null?``:e} items`)}),U(`input`,v,f),U(`click`,b,()=>h(!0)),U(`click`,x,()=>h(!1)),G(e,g),Nt()}Wa([`input`,`click`]);var Tl=W(`
`),El=W(`
`),Dl=W(`
`);function Ol(e,t){Mt(t,!0);let n=P(I([])),r=P(I([])),i=P(``),a=P(void 0);Mi(()=>{if(Q.targetItemKey!==null&&H(a)){let[e,t]=Q.targetItemKey.split(`:`);if(e===H(o)){if(H(r).length>0){let e=H(r).findIndex(e=>e.id===parseInt(t,10));e!==-1&&H(a).scrollToIndex(e),Q.targetItemKey=null}}else p(e)}});let o=P(I(Fc.Item)),s,c=P(!1),l=new Set,u=()=>{if(!H(i).trim())l=new Set(H(n).map(e=>e.id));else{let e=H(i).trim().toLowerCase(),t=H(n).filter(t=>String(t.id)===e||t.name.toLowerCase().includes(e)||String(t.count).includes(e)||t.description&&t.description.toLowerCase().includes(e));l=new Set(t.map(e=>e.id))}},d=()=>{let e=H(o)===Fc.Item?`items`:H(o)===Fc.Weapon?`weapons`:`armors`;F(r,H(n).filter(e=>l.has(e.id)).sort((t,n)=>{let r=Zc.isFavorite(e,t.id),i=Zc.isFavorite(e,n.id);return r&&!i?-1:!r&&i?1:t.id-n.id}),!0)},f=()=>{F(n,q.inv.list(H(o)),!0),u(),d()},p=e=>{F(o,e,!0),f(),H(a)&&H(a).resetScroll()},h=e=>{F(i,e.target.value,!0),clearTimeout(s),s=setTimeout(()=>{u(),d()},300)};Ws(()=>{f();let e=setInterval(()=>{H(c)||(F(n,q.inv.list(H(o)),!0),d())},1e3);return()=>clearInterval(e)});let g=(e,t)=>{q.inv.setCount(H(o),e,t),Y.items.has(`${H(o)}:${e}`)&&X.freezeItem(H(o),e,!0)};var _=Dl(),v=L(_),y=L(v),b=L(y),x=R(b,2),S=R(x,2);D(y);var ee=R(y,2);us(ee),D(v);var C=R(v,2);Ps(ul(L(C),{get items(){return H(r)},itemHeight:48,itemTemplate:(e,t=m)=>{var r=El(),i=L(r),a=L(i,!0);D(i);var s=R(i,2),l=L(s),u=L(l,!0);D(l);var f=R(l,2),p=e=>{var n=Tl(),r=L(n,!0);D(n),z((e,t)=>{ps(n,`title`,e),K(r,t)},[()=>t().description.replace(/\n/g,` `),()=>t().description.replace(/\n/g,` `)]),G(e,n)};mo(f,e=>{t().description&&e(p)}),D(s);var h=R(s,2),_=L(h),v=L(_);{let e=Wn(()=>Zc.isFavorite(H(o)===Fc.Item?`items`:H(o)===Fc.Weapon?`weapons`:`armors`,t().id)?`fill-current`:``);bc(v,{size:16,get class(){return H(e)}})}D(_);var y=R(_,2);{let e=Wn(()=>q.inv.maxStack(H(o),t().id));fl(y,{get value(){return t().count},min:0,get max(){return H(e)},onchange:e=>g(t().id,e)})}var b=R(y,2),x=L(b);{let e=Wn(()=>Y.items.has(`${H(o)}:${t().id}`));ml(x,{get locked(){return H(e)},ontoggle:e=>{X.freezeItem(H(o),t().id,e),F(n,[...H(n)],!0),d()}})}D(b),D(h),D(r),z((e,n,i)=>{Jo(r,1,`border-border/50 hover:bg-border/30 flex h-full items-center border-b px-4 transition-colors ${e==null?``:e}`),K(a,n),ps(l,`title`,t().name),K(u,t().name),Jo(_,1,`mr-1 flex items-center justify-center transition-colors ${i==null?``:i}`)},[()=>Y.items.has(`${H(o)}:${t().id}`)?`border-l-frozen border-l-4 pl-3`:``,()=>t().id.toString().padStart(4,`0`),()=>Zc.isFavorite(H(o)===Fc.Item?`items`:H(o)===Fc.Weapon?`weapons`:`armors`,t().id)?`text-yellow-400 hover:text-yellow-300`:`text-gray-600 hover:text-gray-400`]),U(`focusin`,h,()=>F(c,!0)),U(`focusout`,h,()=>F(c,!1)),U(`click`,_,()=>{let e=H(o)===Fc.Item?`items`:H(o)===Fc.Weapon?`weapons`:`armors`;Zc.toggleFavorite(e,t().id),d()}),G(e,r)},$$slots:{itemTemplate:!0}}),e=>F(a,e,!0),()=>H(a)),D(C),D(_),z(()=>{Jo(b,1,`rounded px-3 py-1.5 text-sm font-semibold transition-colors ${H(o)===Fc.Item?`bg-accent text-white`:`bg-border hover:bg-border/80 text-gray-300`}`),Jo(x,1,`rounded px-3 py-1.5 text-sm font-semibold transition-colors ${H(o)===Fc.Weapon?`bg-accent text-white`:`bg-border hover:bg-border/80 text-gray-300`}`),Jo(S,1,`rounded px-3 py-1.5 text-sm font-semibold transition-colors ${H(o)===Fc.Armor?`bg-accent text-white`:`bg-border hover:bg-border/80 text-gray-300`}`),ds(ee,H(i))}),U(`click`,b,()=>p(Fc.Item)),U(`click`,x,()=>p(Fc.Weapon)),U(`click`,S,()=>p(Fc.Armor)),U(`input`,ee,h),G(e,_),Nt()}Wa([`click`,`input`,`focusin`,`focusout`]);var kl=W(``),Al=W(``),jl=W(`
`),Ml=W(`
`),Nl=W(`
No skills in database.
`),Pl=W(``),Fl=W(`
`),Il=W(`No active states.`),Ll=W(``),Rl=W(`

Core Status

Level
EXP
HP
MP
TP

Parameters

Skills

States

`,1),zl=W(`
Start a game or select an actor to edit stats.
`),Bl=W(`
Actors
`);function Vl(e,t){Mt(t,!0);let n=P(I([])),r=P(null),i=P(null),a=P(null),o=P(``),s=P(``);Mi(()=>{Q.targetActorId!==null&&H(n).length>0&&(F(r,Q.targetActorId,!0),Q.targetActorId=null,Q.targetActorStat=null,c())});let c=()=>{F(n,J.list(),!0),H(r)===null&&H(n).length>0&&F(r,H(n)[0].id,!0),H(r)!==null&&F(i,J.get(H(r)),!0)};Ws(()=>{c();let e=setInterval(()=>{c()},1e3);return()=>clearInterval(e)});let l=e=>{F(r,e,!0),F(i,J.get(e),!0)},u=(e,t)=>{H(r)!==null&&(e===`hp`?J.setHp(H(r),t):e===`mp`?J.setMp(H(r),t):e===`tp`&&J.setTp(H(r),t),Y.stats.has(`${H(r)}:${e}`)&&X.freezeStat(H(r),e,!0),F(i,J.get(H(r)),!0))},d=(e,t)=>{H(r)!==null&&(J.setParam(H(r),e,t),F(i,J.get(H(r)),!0))},f=()=>{H(r)===null||!H(i)||(H(i).inParty?J.removeFromParty(H(r)):J.addToParty(H(r)),c())},p=(e,t)=>{H(r)!==null&&(t?J.forgetSkill(H(r),e):J.learnSkill(H(r),e),F(i,J.get(H(r)),!0))},m={[Lc.MHP]:`Max HP`,[Lc.MMP]:`Max MP`,[Lc.ATK]:`Attack`,[Lc.DEF]:`Defense`,[Lc.MAT]:`M. Attack`,[Lc.MDF]:`M. Defense`,[Lc.AGI]:`Agility`,[Lc.LUK]:`Luck`};var h=Bl(),g=L(h),_=R(L(g),2);yo(_,21,()=>H(n),ho,(e,t)=>{var n=Al(),i=L(n),a=L(i),o=e=>{G(e,kl())};mo(a,e=>{H(t).inParty&&e(o)});var s=R(a,2),c=L(s,!0);D(s),D(i);var u=R(i,2),d=L(u);D(u),D(n),z(()=>{var e;ps(n,`id`,`actor-btn-${H(t).id}`),Jo(n,1,`flex w-full items-center justify-between rounded px-2.5 py-2 text-left text-sm transition-colors ${H(r)===H(t).id?`bg-accent text-white font-semibold`:`hover:bg-border/50 text-gray-300`}`),K(c,H(t).name),K(d,`Lv.${(e=H(t).level)==null?``:e}`)}),U(`click`,n,()=>l(H(t).id)),G(e,n)}),D(_),D(g);var v=R(g,2),y=L(v),b=e=>{var t,n=Rl(),l=_i(n),h=L(l),g=L(h),_=L(g,!0);D(g);var v=R(g,2),y=L(v);D(v),D(h);var b=R(h,2),x=L(b),S=R(x,2),ee=L(S,!0);D(S),D(b),D(l);var C=R(l,2),w=L(C),te=R(L(w),2),ne=R(L(te),2),re=L(ne);fl(re,{get value(){return H(i).level},min:1,max:99,onchange:e=>{H(r)!==null&&(J.setLevel(H(r),e),Y.stats.has(`${H(r)}:level`)&&X.freezeStat(H(r),`level`,!0),F(i,J.get(H(r)),!0),c())}});var ie=R(re,2);{let e=Wn(()=>Y.stats.has(`${H(r)}:level`));ml(ie,{get locked(){return H(e)},ontoggle:e=>{H(r)!==null&&(X.freezeStat(H(r),`level`,e),F(i,J.get(H(r)),!0))}})}D(ne),D(te);var ae=R(te,2),oe=R(L(ae),2),se=L(oe);fl(se,{get value(){return H(i).exp},min:0,onchange:e=>{H(r)!==null&&(J.setExp(H(r),e),Y.stats.has(`${H(r)}:exp`)&&X.freezeStat(H(r),`exp`,!0),F(i,J.get(H(r)),!0),c())}});var ce=R(se,2);{let e=Wn(()=>Y.stats.has(`${H(r)}:exp`));ml(ce,{get locked(){return H(e)},ontoggle:e=>{H(r)!==null&&(X.freezeStat(H(r),`exp`,e),F(i,J.get(H(r)),!0))}})}D(oe),D(ae);var le=R(ae,2),ue=R(L(le),2),de=L(ue);fl(de,{get value(){return H(i).hp},min:0,get max(){return H(i).mhp},onchange:e=>u(`hp`,e)});var fe=R(de,2);{let e=Wn(()=>Y.stats.has(`${H(r)}:hp`));ml(fe,{get locked(){return H(e)},ontoggle:e=>{H(r)!==null&&(X.freezeStat(H(r),`hp`,e),F(i,J.get(H(r)),!0))}})}D(ue),D(le);var pe=R(le,2),me=R(L(pe),2),he=L(me);fl(he,{get value(){return H(i).mp},min:0,get max(){return H(i).mmp},onchange:e=>u(`mp`,e)});var ge=R(he,2);{let e=Wn(()=>Y.stats.has(`${H(r)}:mp`));ml(ge,{get locked(){return H(e)},ontoggle:e=>{H(r)!==null&&(X.freezeStat(H(r),`mp`,e),F(i,J.get(H(r)),!0))}})}D(me),D(pe);var _e=R(pe,2),ve=R(L(_e),2),ye=L(ve);fl(ye,{get value(){return H(i).tp},min:0,get max(){return H(i).mtp},onchange:e=>u(`tp`,e)});var be=R(ye,2);{let e=Wn(()=>Y.stats.has(`${H(r)}:tp`));ml(be,{get locked(){return H(e)},ontoggle:e=>{H(r)!==null&&(X.freezeStat(H(r),`tp`,e),F(i,J.get(H(r)),!0))}})}D(ve),D(_e),D(w);var xe=R(w,2);yo(R(L(xe),2),17,()=>H(i).params,e=>e.id,(e,t)=>{var n=jl(),a=L(n),o=L(a,!0);D(a);var s=R(a,2),c=L(s);fl(c,{get value(){return H(t).value},min:1,onchange:e=>{d(H(t).id,e),Y.stats.has(`${H(r)}:param_${H(t).id}`)&&X.freezeStat(H(r),`param_${H(t).id}`,!0)}});var l=R(c,2);{let e=Wn(()=>Y.stats.has(`${H(r)}:param_${H(t).id}`));ml(l,{get locked(){return H(e)},ontoggle:e=>{H(r)!==null&&(X.freezeStat(H(r),`param_${H(t).id}`,e),F(i,J.get(H(r)),!0))}})}D(s),D(n),z(()=>{ps(n,`id`,`stat-param_${H(t).id}`),K(o,m[H(t).id]||`Stat`)}),G(e,n)}),D(xe),D(C);var Se=R(C,2),Ce=L(Se),we=R(L(Ce),2);us(we),D(Ce);var Te=R(Ce,2);yo(Te,21,()=>H(i).skills.filter(e=>!H(o).trim()||e.name.toLowerCase().includes(H(o).trim().toLowerCase())||e.id.toString().includes(H(o).trim())),e=>e.id,(e,t)=>{var n=Ml(),r=L(n),i=L(r);D(r);var a=R(r,2),o=L(a,!0);D(a),D(n),z(e=>{var n;K(i,`${e==null?``:e}: ${(n=H(t).name)==null?``:n}`),Jo(a,1,`rounded border px-3 py-1 text-xs font-semibold transition-colors ${H(t).learned?`border-danger/30 text-danger bg-danger/10 hover:bg-danger/20`:`border-accent/30 text-accent bg-accent/10 hover:bg-accent/20`}`),K(o,H(t).learned?`Forget`:`Learn`)},[()=>H(t).id.toString().padStart(3,`0`)]),U(`click`,a,()=>p(H(t).id,H(t).learned)),G(e,n)},e=>{G(e,Nl())}),D(Te),D(Se);var Ee=R(Se,2),De=L(Ee),Oe=R(L(De),2),ke=L(Oe);us(ke);var Ae=R(ke,2),je=e=>{var t=Pl();U(`click`,t,()=>{H(r)!==null&&(J.clearStates(H(r)),F(i,J.get(H(r)),!0))}),G(e,t)};mo(Ae,e=>{H(i).states.length>0&&e(je)}),D(Oe),D(De);var Me=R(De,2);yo(Me,21,()=>H(i).states,ho,(e,t)=>{var n=Fl(),a=L(n),o=L(a,!0);D(a);var s=R(a,2);D(n),z(()=>K(o,H(t).name)),U(`click`,s,()=>{H(r)!==null&&(J.removeState(H(r),H(t).id),F(i,J.get(H(r)),!0))}),G(e,n)},e=>{G(e,Il())}),D(Me);var Ne=R(Me,2),Pe=L(Ne),Fe=L(Pe);Fe.value=(t=Fe.__value=null)!=null&&t!==void 0?t:``,yo(R(Fe),17,()=>J.listStates().filter(e=>!H(s).trim()||e.name.toLowerCase().includes(H(s).trim().toLowerCase())||e.id.toString().includes(H(s).trim())),ho,(e,t)=>{var n=Ll(),r=L(n);D(n);var i={};z(e=>{var a;if(K(r,`${e==null?``:e}: ${(a=H(t).name)==null?``:a}`),i!==(i=H(t).id)){var o;n.value=(o=n.__value=H(t).id)==null?``:o}},[()=>H(t).id.toString().padStart(3,`0`)]),G(e,n)}),D(Pe);var Ie=R(Pe,2);D(Ne),D(Ee),z(()=>{var e;K(_,H(i).name),K(y,`Actor ID: ${(e=H(i).id)==null?``:e}`),Jo(S,1,`rounded border px-3 py-1.5 text-xs font-semibold transition-colors ${H(i).inParty?`border-danger/30 bg-danger/20 text-danger hover:bg-danger/30`:`border-ok/30 bg-ok/20 text-ok hover:bg-ok/30`}`),K(ee,H(i).inParty?`Remove Party`:`Add Party`),Ie.disabled=H(a)===null}),U(`click`,x,()=>{H(r)!==null&&(J.recover(H(r)),F(i,J.get(H(r)),!0))}),U(`click`,S,f),Cs(we,()=>H(o),e=>F(o,e)),Cs(ke,()=>H(s),e=>F(s,e)),$o(Pe,()=>H(a),e=>F(a,e)),U(`click`,Ie,()=>{H(r)!==null&&H(a)!==null&&(J.addState(H(r),H(a)),F(i,J.get(H(r)),!0),F(a,null))}),G(e,n)},x=e=>{G(e,zl())};mo(y,e=>{H(i)?e(b):e(x,-1)}),D(v),D(h),G(e,h),Nt()}Wa([`click`]);function Hl(e){let t=e-1;return t*t*t+1}function Ul(e,{from:t,to:n},r={}){var{delay:i=0,duration:a=e=>Math.sqrt(e)*120,easing:o=Hl}=r,s=getComputedStyle(e),c=s.transform===`none`?``:s.transform,[l,u]=s.transformOrigin.split(` `).map(parseFloat);l/=e.clientWidth,u/=e.clientHeight;var d=Wl(e),f=e.clientWidth/n.width/d,p=e.clientHeight/n.height/d,m=t.left+t.width*l,h=t.top+t.height*u,g=n.left+n.width*l,_=n.top+n.height*u,v=(m-g)*f,y=(h-_)*p,b=t.width/n.width,x=t.height/n.height;return{delay:i,duration:typeof a==`function`?a(Math.sqrt(v*v+y*y)):a,easing:o,css:(e,t)=>`transform: ${c} translate(${t*v}px, ${t*y}px) scale(${e+t*b}, ${e+t*x});`}}function Wl(e){if(`currentCSSZoom`in e)return e.currentCSSZoom;for(var t=e,n=1;t!==null;)n*=+getComputedStyle(t).zoom,t=t.parentElement;return n}var Gl=W(` `),Kl=W(``),ql=W(`

`),Jl=W(`
Configure the hold key in the Keys panel.
`),Yl=W(`
Warning: Game is permanently sped up. Turn this back on to require holding a key.
`),Xl=W(``),Zl=W(`
`),Ql=W(`

Active Enemies

`),$l=W(`LEAD`),eu=W(`
`),tu=W(`
No active party members found (start/load a game).
`),nu=W(`

Quick Actions

Party Resources

Gold
Steps
Playtime

Battle Settings

God Mode
One-Hit Kill
Disable Encounters

Movement

Noclip (Walk Through Walls)
Move Speed

Game Speed

Hold Key to Fast Forward
Speed Multiplier
`);function ru(e,t){Mt(t,!0);let n=P(0),r=P(0),i=P(0),a=P(4),o=P(!1),s=P(I([])),c=P(I([])),l=[{title:`System & Menus`,actions:[`quick_save`,`quick_load`,`open_save_scene`,`open_load_scene`,`goto_title`]},{title:`Battle Actions`,actions:[`force_victory`,`force_defeat`,`force_escape`,`trigger_encounter`]},{title:`Health Controls`,actions:[`party_recovery`,`party_wound`,`enemy_recovery`,`enemy_wound`]}],u=()=>{F(n,q.gold.get(),!0),F(r,q.party.steps(),!0),F(i,q.party.playtime(),!0),window.$gamePlayer&&F(a,window.$gamePlayer._moveSpeed||4,!0),F(o,!!(window.SceneManager&&window.SceneManager._scene&&window.SceneManager._scene.constructor.name===`Scene_Battle`)),H(o)&&window.$gameTroop?F(s,window.$gameTroop.members().map(e=>({ref:e,name:e.name(),hp:e.hp,mhp:e.mhp,mp:e.mp,mmp:e.mmp,tp:e.tp,maxTp:e.maxTp()})),!0):F(s,[],!0),window.$gameParty?F(c,window.$gameParty.members().map(e=>({ref:e,id:e.actorId(),name:e.name(),level:typeof e.level==`function`?e.level():e._level||1,hp:e.hp,mhp:e.mhp,mp:e.mp,mmp:e.mmp,tp:e.tp,maxTp:e.maxTp()})),!0):F(c,[],!0)};Ws(()=>{u();let e=setInterval(u,1e3);return()=>clearInterval(e)});let d=e=>{q.gold.set(e),Y.gold!==null&&X.freezeGold(!0),F(n,q.gold.get(),!0)},f=e=>{let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},p=(e,t)=>{e.ref.setHp(t),u()},m=(e,t)=>{e.ref.setMp(t),u()},h=(e,t)=>{e.ref.setTp?e.ref.setTp(t):e.ref.tp=t,u()},g=P(null),_=(e,t)=>{e!==t&&window.$gameParty&&typeof window.$gameParty.swapOrder==`function`&&(window.$gameParty.swapOrder(e,t),u())};var v=nu(),y=L(v),b=R(L(y),2);yo(b,21,()=>l,ho,(e,t)=>{var n=ql(),r=L(n),i=L(r,!0);D(r);var a=R(r,2);yo(a,21,()=>H(t).actions,ho,(e,t)=>{let n=Wn(()=>nl.find(e=>e.id===H(t)));var r=eo(),i=_i(r),a=e=>{var t=Kl(),r=L(t),i=L(r,!0);D(r);var a=R(r,2),o=e=>{var t=Gl(),r=L(t,!0);D(t),z(e=>K(r,e),[()=>{var e;return Yc.fromString(((e=$.get(H(n).id))==null?void 0:e.keyStr)||``).asDisplayString()}]),G(e,t)},s=Wn(()=>{var e;return(e=$.get(H(n).id))==null?void 0:e.keyStr});mo(a,e=>{H(s)&&e(o)}),D(t),z(()=>K(i,H(n).name)),U(`click`,t,()=>{var e,t;(e=(t=H(n)).onEnter)==null||e.call(t),u()}),G(e,t)};mo(i,e=>{H(n)&&e(a)}),G(e,r)}),D(a),D(n),z(()=>K(i,H(t).title)),G(e,n)}),D(b),D(y);var x=R(y,2),S=L(x),ee=R(L(S),2),C=R(L(ee),2),w=L(C);fl(w,{get value(){return H(n)},min:0,max:99999999,onchange:d});var te=R(w,2);{let e=Wn(()=>Y.gold!==null);ml(te,{get locked(){return H(e)},ontoggle:e=>{X.freezeGold(e),u()}})}D(C),D(ee);var ne=R(ee,2),re=R(L(ne),2),ie=L(re,!0);D(re),D(ne);var ae=R(ne,2),oe=R(L(ae),2),se=L(oe,!0);D(oe),D(ae),D(S);var ce=R(S,2),le=R(L(ce),2),ue=L(le);xl(R(L(ue),2),{get value(){return Z.god},onchange:e=>Wc.setGod(e)}),D(ue);var de=R(ue,2);xl(R(L(de),2),{get value(){return Z.ohko},onchange:e=>Wc.setOhko(e)}),D(de);var fe=R(de,2);xl(R(L(fe),2),{get value(){return Z.noEncounter},onchange:e=>Wc.setNoEncounter(e)}),D(fe),D(le),D(ce),D(x);var pe=R(x,2),me=R(L(pe),2),he=L(me);xl(R(L(he),2),{get value(){return Y.noclip},onchange:e=>X.setNoclip(e)}),D(he);var ge=R(he,2);fl(R(L(ge),2),{get value(){return H(a)},min:1,max:8,onchange:e=>q.map.speed(e)}),D(ge),D(me),D(pe);var _e=R(pe,2),ve=R(L(_e),2),ye=L(ve),be=L(ye);xl(R(L(be),2),{get value(){return Z.speedUseKey},onchange:e=>{Wc.setSpeedUseKey(e),e?Wc.setSpeed(1):Wc.setSpeed(Z.speedBoost)}}),D(be);var xe=R(be,2),Se=e=>{G(e,Jl())},Ce=e=>{G(e,Yl())};mo(xe,e=>{Z.speedUseKey?e(Se):e(Ce,-1)}),D(ye);var we=R(ye,2),Te=R(L(we),2);yo(Te,20,()=>[.5,1,2,3,5,8],ho,(e,t)=>{var n=Xl(),r=L(n);D(n),z(()=>{Jo(n,1,`border-border h-7 w-9 rounded border text-xs transition-colors ${Z.speedBoost===t?`border-accent bg-accent text-white font-semibold`:`bg-bg hover:bg-border/50 text-gray-300`}`),K(r,`${t==null?``:t}x`)}),U(`click`,n,()=>{Wc.setSpeedBoost(t),Z.speedUseKey||Wc.setSpeed(t)}),G(e,n)}),D(Te),D(we),D(ve),D(_e);var Ee=R(_e,2),De=e=>{var t=Ql(),n=R(L(t),2);yo(n,21,()=>H(s),ho,(e,t)=>{var n=Zl(),r=L(n),i=L(r),a=L(i,!0);D(i),D(r);var o=R(r,2),s=L(o),c=L(s),l=L(c);D(c),fl(R(c,2),{get value(){return H(t).hp},min:0,get max(){return H(t).mhp},onchange:e=>p(H(t),e)}),D(s);var u=R(s,2),d=L(u),f=L(d);D(d),fl(R(d,2),{get value(){return H(t).mp},min:0,get max(){return H(t).mmp},onchange:e=>m(H(t),e)}),D(u);var g=R(u,2),_=L(g),v=L(_);D(_),fl(R(_,2),{get value(){return H(t).tp},min:0,get max(){return H(t).maxTp},onchange:e=>h(H(t),e)}),D(g),D(o),D(n),z(()=>{var e,n,r,i,o;K(a,H(t).name),K(l,`HP (${(e=H(t).hp)==null?``:e}/${(n=H(t).mhp)==null?``:n})`),K(f,`MP (${(r=H(t).mp)==null?``:r}/${(i=H(t).mmp)==null?``:i})`),K(v,`TP (${(o=H(t).tp)==null?``:o})`)}),G(e,n)}),D(n),D(t),G(e,t)};mo(Ee,e=>{H(o)&&H(s).length>0&&e(De)});var Oe=R(Ee,2),ke=R(L(Oe),2);yo(ke,31,()=>H(c),e=>e.id,(e,t,n)=>{var r=eu(),i=L(r),a=L(i),o=L(a),s=R(L(o),2),c=L(s),l=R(c),u=e=>{G(e,$l())};mo(l,e=>{H(n)===0&&e(u)}),D(s),D(o);var d=R(o,2),f=L(d);D(d),D(a);var v=R(a,2),y=L(v),b=L(y),x=L(b);D(b),fl(R(b,2),{get value(){return H(t).hp},min:0,get max(){return H(t).mhp},onchange:e=>p(H(t),e)}),D(y);var S=R(y,2),ee=L(S),C=L(ee);D(ee),fl(R(ee,2),{get value(){return H(t).mp},min:0,get max(){return H(t).mmp},onchange:e=>m(H(t),e)}),D(S);var w=R(S,2),te=L(w),ne=L(te);D(te),fl(R(te,2),{get value(){return H(t).tp},min:0,get max(){return H(t).maxTp},onchange:e=>h(H(t),e)}),D(w),D(v),D(i),D(r),z(()=>{var e,o,s,l,u,d,p;Jo(r,1,`rounded p-2.5 transition-all duration-200 ${H(g)===H(n)?`border border-dashed border-accent/50 bg-accent/5`:`border border-border bg-bg`}`),Jo(i,1,`space-y-2 ${H(g)===H(n)?`invisible`:``}`),Jo(a,1,`flex w-full items-center justify-between pb-2 text-xs font-bold text-white ${H(g)===null?`cursor-grab active:cursor-grabbing`:``}`),K(c,`${(e=H(t).name)==null?``:e} `),K(f,`Lv.${(o=H(t).level)==null?``:o}`),K(x,`HP (${(s=H(t).hp)==null?``:s}/${(l=H(t).mhp)==null?``:l})`),K(C,`MP (${(u=H(t).mp)==null?``:u}/${(d=H(t).mmp)==null?``:d})`),K(ne,`TP (${(p=H(t).tp)==null?``:p})`)}),Ua(`dragenter`,r,e=>e.preventDefault()),Ua(`dragover`,r,e=>{if(e.preventDefault(),H(g)!==null&&H(g)!==H(n)){let t=e.currentTarget.getBoundingClientRect(),r=t.top+t.height/2;if(H(g)H(n)&&e.clientY>r)return;_(H(g),H(n)),F(g,H(n),!0)}}),Ua(`dragstart`,a,e=>{if(e.dataTransfer){e.dataTransfer.effectAllowed=`move`;let t=e.currentTarget.closest(`[role="listitem"]`);t&&e.dataTransfer.setDragImage(t,20,20)}setTimeout(()=>{F(g,H(n),!0)},0)}),Ua(`dragend`,a,()=>{F(g,null)}),Io(r,()=>Ul,()=>({duration:250})),G(e,r)},e=>{G(e,tu())}),D(ke),D(Oe),D(v),z(e=>{K(ie,H(r)),K(se,e)},[()=>f(H(i))]),Ua(`dragenter`,Oe,e=>e.preventDefault()),Ua(`dragover`,Oe,e=>e.preventDefault()),Ua(`dragenter`,ke,e=>e.preventDefault()),Ua(`dragover`,ke,e=>e.preventDefault()),G(e,v),Nt()}Wa([`click`]);var iu=W(``),au=W(`
No saved locations yet.
`),ou=W(`
`),su=W(`

Teleport

Saved Locations

`);function cu(e,t){Mt(t,!0);let n=P(I({mapId:0,x:0,y:0,dir:0})),r=P(I([])),i=P(0),a=P(0),o=P(0),s=P(I([])),c=P(``),l=P(``),u=P(``);Mi(()=>{H(o)>0&&q.map.loadMapEvents(H(o)).then(e=>{F(s,e,!0),e.find(e=>e.id.toString()===H(c))||F(c,``)})});let d=P(I([])),f=P(``),p=()=>{let e=q.map.current();e&&(F(n,e,!0),F(o,H(o)||e.mapId,!0),F(i,e.x,!0),F(a,e.y,!0)),F(r,q.map.list(),!0);try{let e=localStorage.getItem(`forge:locations`);e&&F(d,JSON.parse(e),!0)}catch(e){}};Ws(()=>{p();let e=setInterval(()=>{let e=q.map.current();e&&(e.mapId!==H(n).mapId||e.x!==H(n).x||e.y!==H(n).y)&&F(n,e,!0)},1e3);return()=>clearInterval(e)});let m=()=>{q.map.teleport(H(o),H(i),H(a),0,0)},h=()=>{let e=q.map.current();if(!e)return;let t=H(r).find(t=>t.id===e.mapId);F(d,[...H(d),{id:Date.now().toString(),name:H(f)||`Saved Location`,mapId:e.mapId,mapName:t?t.name:`Map ${e.mapId}`,x:e.x,y:e.y}],!0),F(f,``),localStorage.setItem(`forge:locations`,JSON.stringify(H(d)))},g=e=>{F(d,H(d).filter(t=>t.id!==e),!0),localStorage.setItem(`forge:locations`,JSON.stringify(H(d)))},_=e=>{q.map.teleport(e.mapId,e.x,e.y,0,0)};var v=su(),y=L(v),b=R(L(y),2),x=L(b);D(b);var S=R(b,2),ee=L(S),C=L(ee),w=R(L(C),2);us(w),D(C);var te=R(C,2);yo(te,21,()=>H(r).filter(e=>!H(l).trim()||e.name.toLowerCase().includes(H(l).trim().toLowerCase())||e.id.toString().includes(H(l).trim())),ho,(e,t)=>{var r=iu(),i=L(r);D(r);var a={};z(e=>{var o;if(K(i,`${H(t).id===H(n).mapId?`[CURRENT] `:``}${e==null?``:e}: ${(o=H(t).name)==null?``:o}`),a!==(a=H(t).id)){var s;r.value=(s=r.__value=H(t).id)==null?``:s}},[()=>H(t).id.toString().padStart(3,`0`)]),G(e,r)}),D(te),D(ee);var ne=R(ee,2),re=L(ne),ie=R(L(re),2);us(ie),D(re);var ae=R(re,2),oe=L(ae);oe.value=oe.__value=``,yo(R(oe),17,()=>H(s).filter(e=>!H(u).trim()||e.name.toLowerCase().includes(H(u).trim().toLowerCase())||e.id.toString().includes(H(u).trim())),ho,(e,t)=>{var n=iu(),r=L(n);D(n);var i={};z(()=>{var e,a,o;if(K(r,`${(e=H(t).name)==null?``:e} (X:${(a=H(t).x)==null?``:a}, Y:${(o=H(t).y)==null?``:o})`),i!==(i=H(t).id)){var s;n.value=(s=n.__value=H(t).id)==null?``:s}}),G(e,n)}),D(ae),D(ne);var se=R(ne,2),ce=L(se),le=R(L(ce),2);us(le),D(ce);var ue=R(ce,2),de=R(L(ue),2);us(de),D(ue),D(se);var fe=R(se,2);D(S),D(y);var pe=R(y,2),me=R(L(pe),2),he=L(me);us(he);var ge=R(he,2);D(me);var _e=R(me,2),ve=L(_e),ye=e=>{G(e,au())},be=e=>{var t=eo();yo(_i(t),17,()=>H(d),e=>e.id,(e,t)=>{var n=ou(),r=L(n),i=L(r),a=L(i,!0);D(i);var o=R(i,2),s=L(o);D(o),D(r);var c=R(r,2),l=L(c),u=R(l,2);Ec(L(u),{size:14}),D(u),D(c),D(n),z(()=>{var e,n,r,i;K(a,H(t).name),K(s,`${(e=H(t).mapName)==null?``:e} (Map ${(n=H(t).mapId)==null?``:n}) • X:${(r=H(t).x)==null?``:r} Y:${(i=H(t).y)==null?``:i}`)}),U(`click`,l,()=>_(H(t))),U(`click`,u,()=>g(H(t).id)),G(e,n)}),G(e,t)};mo(ve,e=>{H(d).length===0?e(ye):e(be,-1)}),D(_e),D(pe),D(v),z(()=>{var e,t,r;return K(x,`Current: Map ${(e=H(n).mapId)==null?``:e} (${(t=H(n).x)==null?``:t}, ${(r=H(n).y)==null?``:r})`)}),Cs(w,()=>H(l),e=>F(l,e)),$o(te,()=>H(o),e=>F(o,e)),Cs(ie,()=>H(u),e=>F(u,e)),U(`change`,ae,e=>{let t=parseInt(e.target.value);if(isNaN(t))return;let n=H(s).find(e=>e.id===t);n&&(F(i,n.x,!0),F(a,n.y,!0))}),$o(ae,()=>H(c),e=>F(c,e)),Cs(le,()=>H(i),e=>F(i,e)),Cs(de,()=>H(a),e=>F(a,e)),U(`click`,fe,m),U(`keydown`,he,e=>{e.stopPropagation(),e.key===`Enter`&&h()}),Cs(he,()=>H(f),e=>F(f,e)),U(`click`,ge,h),G(e,v),Nt()}Wa([`change`,`click`,`keydown`]);var lu=W(` `,1),uu=W(``),du=W(`
`),fu=W(`
`);function pu(e,t){Mt(t,!0);let n=P(I([])),r=P(I([])),i=P(``),a=P(null),o,s=()=>{let e=H(n);if(H(i).trim()){let t=H(i).trim().toLowerCase();e=H(n).filter(e=>String(e.id)===t||e.name.toLowerCase().includes(t))}F(r,e.sort((e,t)=>{let n=Zc.isFavorite(`commonEvents`,e.id),r=Zc.isFavorite(`commonEvents`,t.id);return n&&!r?-1:!n&&r?1:e.id-t.id}),!0)},c=()=>{F(n,q.commonev.list(),!0),s()},l=e=>{F(i,e.target.value,!0),s()};Ws(()=>{c()});let u=e=>{H(a)===e?(q.commonev.run(e),F(a,null),clearTimeout(o)):(F(a,e,!0),clearTimeout(o),o=setTimeout(()=>{H(a)===e&&F(a,null)},3e3))},d=()=>{F(a,null),clearTimeout(o)};var f=fu(),p=L(f),h=L(p);us(h);var g=R(h,2),_=L(g);D(g),D(p);var v=R(p,2);ul(L(v),{get items(){return H(r)},itemHeight:38,itemTemplate:(e,t=m)=>{var n=du(),r=L(n),i=L(r),o=L(i,!0);D(i);var c=R(i,2),l=L(c,!0);D(c),D(r);var f=R(r,2),p=L(f),h=L(p);{let e=Wn(()=>Zc.isFavorite(`commonEvents`,t().id)?`fill-current`:``);bc(h,{size:16,get class(){return H(e)}})}D(p);var g=R(p,2),_=L(g),v=e=>{var n=lu(),r=_i(n),i=R(r,2);U(`click`,r,()=>u(t().id)),U(`click`,i,d),G(e,n)},y=e=>{var n=uu();U(`click`,n,()=>u(t().id)),G(e,n)};mo(_,e=>{H(a)===t().id?e(v):e(y,-1)}),D(g),D(f),D(n),z((e,n)=>{K(o,e),ps(c,`title`,t().name),K(l,t().name),Jo(p,1,`mr-2 flex items-center justify-center transition-colors ${n==null?``:n}`)},[()=>t().id.toString().padStart(4,`0`),()=>Zc.isFavorite(`commonEvents`,t().id)?`text-yellow-400 hover:text-yellow-300`:`text-gray-600 hover:text-gray-400`]),U(`click`,p,()=>{Zc.toggleFavorite(`commonEvents`,t().id),s()}),G(e,n)},$$slots:{itemTemplate:!0}}),D(v),D(f),z(()=>{var e;ds(h,H(i)),K(_,`${(e=H(r).length)==null?``:e} items`)}),U(`input`,h,l),G(e,f),Nt()}Wa([`input`,`click`]);var mu=W(``),hu=W(`
`),gu=W(`
No active data locks. Use the lock icon on variables, switches, items, or stats to freeze their value.
`),_u=W(`
`);function vu(e,t){Mt(t,!0);let n=P(I([])),r=()=>{F(n,X.summary(),!0)};Ws(()=>{r();let e=setInterval(r,1e3);return()=>clearInterval(e)});let i=e=>{if(e.type===`var`)X.freezeVar(e.id,!1);else if(e.type===`switch`)X.freezeSwitch(e.id,!1);else if(e.type===`item`){let[t,n]=e.key.split(`:`);X.freezeItem(t,parseInt(n,10),!1)}else if(e.type===`stat`||e.type===`param`){let[t,n]=e.key.split(`:`);X.freezeStat(parseInt(t,10),n,!1)}else e.type===`gold`&&X.freezeGold(!1);r()},a=e=>{if(e.type===`var`)Q.targetVarId=e.id,Q.activeTab=Ic.Vars;else if(e.type===`switch`)Q.targetSwitchId=e.id,Q.activeTab=Ic.Switches;else if(e.type===`item`)Q.targetItemKey=e.key,Q.activeTab=Ic.Inv;else if(e.type===`gold`)Q.activeTab=Ic.General;else if(e.type===`stat`||e.type===`param`){let[t,n]=e.key.split(`:`);Q.targetActorId=parseInt(t,10),Q.targetActorStat=n,Q.activeTab=Ic.Actors}},o=()=>{X.clearAll(),r()},s=e=>e===`var`?`VAR`:e===`switch`?`SW`:e===`item`?`ITEM`:e===`stat`?`STAT`:e===`param`?`PARAM`:e===`gold`?`GOLD`:`LOCK`,c=e=>e===`var`?`border-accent/30 bg-accent/10 text-accent`:e===`switch`?`border-ok/30 bg-ok/10 text-ok`:e===`item`?`border-warn/30 bg-warn/10 text-warn`:e===`stat`?`border-danger/30 bg-danger/10 text-danger`:e===`param`?`border-fuchsia-500/30 bg-fuchsia-500/10 text-fuchsia-500`:e===`gold`?`border-yellow-500/30 bg-yellow-500/10 text-yellow-500`:`border-gray-500/30 bg-gray-500/10 text-gray-400`;var l=_u(),u=L(l),d=L(u),f=L(d);D(d);var p=R(d,2),m=e=>{var t=mu();U(`click`,t,o),G(e,t)};mo(p,e=>{H(n).length>0&&e(m)}),D(u);var h=R(u,2);yo(h,21,()=>H(n),ho,(e,t)=>{var n=hu(),r=L(n),o=L(r),l=L(o,!0);D(o);var u=R(o,2),d=L(u,!0);D(u),D(r);var f=R(r,2),p=L(f),m=L(p,!0);D(p);var h=R(p,2);D(f),D(n),z((e,n)=>{Jo(o,1,`rounded border px-1.5 py-0.5 text-[10px] font-bold font-mono tracking-wide ${e==null?``:e}`),K(l,n),ps(u,`title`,H(t).label),K(d,H(t).label),K(m,typeof H(t).value==`boolean`?H(t).value?`ON`:`OFF`:H(t).value)},[()=>c(H(t).type),()=>s(H(t).type)]),U(`keydown`,n,e=>e.key===`Enter`&&a(H(t))),U(`click`,n,()=>a(H(t))),U(`click`,h,e=>{e.stopPropagation(),i(H(t))}),G(e,n)},e=>{G(e,gu())}),D(h),D(l),z(()=>{var e;return K(f,`${(e=H(n).length)==null?``:e} active locks`)}),G(e,l),Nt()}Wa([`click`,`keydown`]);var yu=W(`
Press a key...
`),bu=W(``),xu=W(``),Su=W(`
`);function Cu(e,t){Mt(t,!0);let n=Hs(t,`value`,15,``),r=Hs(t,`required`,3,!1),i=Hs(t,`combiningKeyAlone`,3,!1),a=P(!1),o=()=>{F(a,!0);let e=e=>{var a;e.preventDefault(),e.stopPropagation();let o=Yc.fromEvent(e);o.isCombiningKey()&&!i()||(n(o.asString()),(a=t.onchange)==null||a.call(t,n()),r())},r=()=>{F(a,!1),window.removeEventListener(`keydown`,e,{capture:!0})};window.addEventListener(`keydown`,e,{capture:!0}),setTimeout(()=>{window.addEventListener(`click`,r,{capture:!0,once:!0})},100)},s=e=>{if(!e)return`None`;try{return Yc.fromString(e).asDisplayString()}catch(t){return e}};var c=Su(),l=L(c),u=e=>{G(e,yu())},d=e=>{var t=bu(),r=L(t,!0);D(t),z(e=>{Jo(t,1,`border-border bg-bg2 hover:bg-border/50 flex h-8 flex-1 items-center rounded border px-3 text-sm font-medium transition-colors ${n()?`text-white`:`text-gray-500`}`),K(r,e)},[()=>s(n())]),U(`click`,t,o),G(e,t)};mo(l,e=>{H(a)?e(u):e(d,-1)});var f=R(l,2),p=e=>{var r=xu();Mc(L(r),{size:14}),D(r),U(`click`,r,()=>{var e;n(``),(e=t.onchange)==null||e.call(t,n())}),G(e,r)};mo(f,e=>{!r()&&n()&&!H(a)&&e(p)}),D(c),G(e,c),Nt()}Wa([`click`]);var wu=W(`
`),Tu=W(`
`);function Eu(e,t){Mt(t,!0);let n=P(I([])),r=P(``),i=P(I([])),a=()=>{if(!H(r).trim())F(i,H(n),!0);else{let e=H(r).trim().toLowerCase();F(i,H(n).filter(t=>t.name.toLowerCase().includes(e)||t.desc.toLowerCase().includes(e)||t.keyStr.toLowerCase().includes(e)),!0)}},o=()=>{F(n,$.shortcuts.map(e=>({...e})),!0),a()};Ws(()=>{o()});let s=e=>{F(r,e.target.value,!0),a()},c=(e,t)=>{$.update(e,{keyStr:t}),o()},l=(e,t)=>{$.update(e,{enabled:t}),o()},u=()=>{localStorage.removeItem(`forge:shortcuts`),zc.show(`Defaults restored. Please reload the game.`,`success`)};var d=Tu(),f=L(d),p=L(f);us(p);var m=R(p,2);D(f);var h=R(f,2);yo(h,21,()=>H(i),e=>e.id,(e,t)=>{var n=wu(),r=L(n),i=L(r),a=L(i,!0);D(i);var o=R(i,2),s=L(o,!0);D(o),D(r);var u=R(r,2),d=L(u);{let e=Wn(()=>H(t).id===`speed_hold`||H(t).id===`skip_message`);Cu(d,{get value(){return H(t).keyStr},get required(){return H(t).required},get combiningKeyAlone(){return H(e)},onchange:e=>c(H(t).id,e)})}D(u);var f=R(u,2);xl(L(f),{get value(){return H(t).enabled},onchange:e=>l(H(t).id,e)}),D(f),D(n),z(()=>{Jo(i,1,`font-semibold text-sm ${H(t).enabled?`text-white`:`text-gray-500`}`),K(a,H(t).name),K(s,H(t).desc)}),G(e,n)}),D(h),D(d),z(()=>ds(p,H(r))),U(`input`,p,s),U(`click`,m,u),G(e,d),Nt()}Wa([`input`,`click`]),yt();var Du=Ls(()=>Xc),Ou=W(`

UI Preferences

Inactive Opacity
Controls how transparent the panel becomes when the mouse leaves.
Remember Window Position
Save the exact window dimensions and position between game boots.
Auto-Open on Boot
Automatically display the Forge panel when the game finishes loading.
Show Launcher Icon
Display a draggable icon to open the panel without a shortcut.

Gameplay

Quick Save / Load Slot
The save file slot used by the Quick Save and Quick Load shortcuts.

Data Management

Factory Reset
Wipes all Forge settings, locks, and saved layout data.
`);function ku(e,t){Mt(t,!1);let n=()=>Zc.save();Fs();var r=Ou(),i=L(r),a=R(L(i),2),o=R(L(a),2);fl(L(o),{get value(){return Du().inactiveOpacity},min:10,max:100,onchange:e=>{Du(Du().inactiveOpacity=e),n()}}),D(o),D(a);var s=R(a,2);xl(R(L(s),2),{onchange:()=>n(),get value(){return Du().rememberPosition},set value(e){Du(Du().rememberPosition=e)},$$legacy:!0}),D(s);var c=R(s,2);xl(R(L(c),2),{onchange:()=>n(),get value(){return Du().autoOpen},set value(e){Du(Du().autoOpen=e)},$$legacy:!0}),D(c);var l=R(c,2);xl(R(L(l),2),{onchange:()=>n(),get value(){return Du().showLauncher},set value(e){Du(Du().showLauncher=e)},$$legacy:!0}),D(l),D(i);var u=R(i,2),d=R(L(u),2),f=R(L(d),2);fl(L(f),{get value(){return Du().quickSaveSlot},min:1,max:20,onchange:e=>{Du(Du().quickSaveSlot=e),n()}}),D(f),D(d),D(u);var p=R(u,2),m=R(L(p),2),h=R(L(m),2);D(m),D(p),D(r),U(`click`,h,()=>Zc.resetAll()),G(e,r),Nt()}Wa([`click`]);var Au=W(`
No logs recorded yet.
`),ju=W(` `),Mu=W(`Narrator / Unknown`),Nu=W(`
`),Pu=W(`

Game Dialogue Logs

`);function Fu(e,t){Mt(t,!0);let n=P(void 0),r=e=>{let t=new Date(e);return`${t.getHours().toString().padStart(2,`0`)}:${t.getMinutes().toString().padStart(2,`0`)}:${t.getSeconds().toString().padStart(2,`0`)}`};Mi(()=>{Qc.entries.length&&setTimeout(()=>{var e,t;H(n)&&((e=(t=H(n)).scrollToBottom)==null||e.call(t))},10)});var i=Pu(),a=L(i),o=L(a),s=R(L(o),2);wc(L(s),{size:14}),ut(2),D(s),D(o);var c=R(o,2),l=L(c),u=e=>{var t=Au();mc(L(t),{size:32,class:`opacity-50`}),ut(2),D(t),G(e,t)},d=e=>{Ps(ul(e,{get items(){return Qc.entries},itemHeight:80,containerHeight:400,itemTemplate:(e,t=m)=>{var n=Nu(),i=L(n),a=L(i),o=e=>{var n=ju(),r=L(n,!0);D(n),z(()=>K(r,t().speaker)),G(e,n)},s=e=>{G(e,Mu())};mo(a,e=>{t().speaker?e(o):e(s,-1)});var c=R(a,2),l=L(c,!0);D(c),D(i);var u=R(i,2),d=L(u,!0);D(u),D(n),z(e=>{K(l,e),K(d,t().text)},[()=>r(t().timestamp)]),G(e,n)},$$slots:{itemTemplate:!0}}),e=>F(n,e,!0),()=>H(n))};mo(l,e=>{Qc.entries.length===0?e(u):e(d,-1)}),D(c),D(a),D(i),U(`click`,s,()=>tl.clear()),G(e,i),Nt()}Wa([`click`]);var Iu=W(``),Lu=W(``),Ru=W(`
`),zu=W(`
`,1);function Bu(e,t){Mt(t,!0),Mi(()=>{let e=document.getElementById(`forge-mvmz-host`);if(!e)return;let t=!1,n=()=>{t=!1},r=[`mousedown`,`mousemove`,`mouseup`,`click`,`dblclick`,`pointerdown`,`pointermove`,`pointerup`,`contextmenu`,`wheel`,`touchstart`,`touchmove`,`touchend`,`keydown`,`keyup`],i=e=>{(e.type===`mousedown`||e.type===`pointerdown`||e.type===`touchstart`)&&(t=!0);let n=e.type===`mousemove`||e.type===`pointermove`||e.type===`touchmove`,r=e.type===`mouseup`||e.type===`pointerup`||e.type===`touchend`;if(n){let n=!1;if(`buttons`in e?n=e.buttons>0:`touches`in e&&(n=e.touches.length>0),n&&!t)return}r&&!t||e.stopPropagation()};if(window.addEventListener(`mouseup`,n,{capture:!0}),window.addEventListener(`pointerup`,n,{capture:!0}),window.addEventListener(`touchend`,n,{capture:!0}),Q.visible)for(let t of r)e.addEventListener(t,i,!1);else for(let t of r)e.removeEventListener(t,i,!1);return()=>{window.removeEventListener(`mouseup`,n,{capture:!0}),window.removeEventListener(`pointerup`,n,{capture:!0}),window.removeEventListener(`touchend`,n,{capture:!0});for(let t of r)e.removeEventListener(t,i,!1)}});let n=[{id:Ic.General,label:`General`},{id:Ic.Vars,label:`Variables`},{id:Ic.Switches,label:`Switches`},{id:Ic.Inv,label:`Inventory`},{id:Ic.Actors,label:`Actors`},{id:Ic.Map,label:`Map`},{id:Ic.CommonEv,label:`Events`},{id:Ic.Locks,label:`Locks`},{id:Ic.Logs,label:`Logs`},{id:Ic.Shortcuts,label:`Keys`},{id:Ic.Settings,label:`Settings`}],r=P(0),i=P(0),a=P(840),o=P(520),s=P(!1);Ws(()=>{Zc.load(),X.install(),Wc.install(),tl.install(),$.init(nl);try{let e=JSON.parse(localStorage.getItem(`forge:panel`)||`null`);e&&Xc.rememberPosition?(F(r,e.x,!0),F(i,e.y,!0),F(a,e.w,!0),F(o,e.h,!0)):typeof window<`u`&&(F(r,0),F(i,0),F(a,Math.min(840,window.innerWidth||840),!0),F(o,Math.min(520,window.innerHeight||520),!0));let t=localStorage.getItem(`forge:lastTab`);t&&Object.values(Ic).includes(t)&&(Q.activeTab=t)}catch(e){}Xc.autoOpen&&!Q.visible&&(Q.visible=!0)});let c=()=>{Xc.rememberPosition&&localStorage.setItem(`forge:panel`,JSON.stringify({x:H(r),y:H(i),w:H(a),h:H(o)})),localStorage.setItem(`forge:lastTab`,Q.activeTab)},l=P(!1),u=P(0),d=P(0),f=P(0),p=P(0),m=e=>{H(l)&&(F(r,Math.max(0,Math.min(window.innerWidth-H(a),H(f)+e.clientX-H(u))),!0),F(i,Math.max(0,Math.min(window.innerHeight-H(o),H(p)+e.clientY-H(d))),!0))},h=()=>{F(l,!1),window.removeEventListener(`mousemove`,m,!0),window.removeEventListener(`mouseup`,h,!0),c()},g=e=>{e.target.closest(`button, input, select`)||(F(l,!0),F(u,e.clientX,!0),F(d,e.clientY,!0),F(f,H(r),!0),F(p,H(i),!0),window.addEventListener(`mousemove`,m,!0),window.addEventListener(`mouseup`,h,!0))},_=P(!1),v=P(0),y=P(0),b=e=>{H(_)&&(F(a,Math.max(560,Math.min(window.innerWidth-H(r),H(v)+e.clientX-H(u))),!0),F(o,Math.max(360,Math.min(window.innerHeight-H(i),H(y)+e.clientY-H(d))),!0))},x=()=>{F(_,!1),window.removeEventListener(`mousemove`,b,!0),window.removeEventListener(`mouseup`,x,!0),c()},S=e=>{F(_,!0),F(u,e.clientX,!0),F(d,e.clientY,!0),F(v,H(a),!0),F(y,H(o),!0),window.addEventListener(`mousemove`,b,!0),window.addEventListener(`mouseup`,x,!0),e.stopPropagation()};var ee=zu(),C=_i(ee),w=e=>{var t=Lu(),u=L(t),d=L(u),f=R(d,2);yo(f,21,()=>n,ho,(e,t)=>{var n=Iu(),r=L(n),i=e=>{Ac(e,{size:14})},a=e=>{ic(e,{size:14})},o=e=>{Sc(e,{size:14})},s=e=>{gc(e,{size:14})},l=e=>{Oc(e,{size:14})},u=e=>{fc(e,{size:14})},d=e=>{Pc(e,{size:14})},f=e=>{uc(e,{size:14})},p=e=>{mc(e,{size:14})},m=e=>{oc(e,{size:14})},h=e=>{vc(e,{size:14})};mo(r,e=>{H(t).id===`general`?e(i):H(t).id===`vars`?e(a,1):H(t).id===`switches`?e(o,2):H(t).id===`inv`?e(s,3):H(t).id===`actors`?e(l,4):H(t).id===`map`?e(u,5):H(t).id===`commonev`?e(d,6):H(t).id===`locks`?e(f,7):H(t).id===`logs`?e(p,8):H(t).id===`shortcuts`?e(m,9):H(t).id===`settings`&&e(h,10)});var g=R(r,2),_=L(g,!0);D(g),D(n),z(()=>{Jo(n,1,`w-full text-left rounded px-3 py-2 text-xs font-semibold transition-all flex items-center space-x-2.5 focus:outline-none ${Q.activeTab===H(t).id?`bg-[#7ba4ff]/10 text-[#7ba4ff] shadow-sm`:`text-gray-400 hover:bg-[#2a2d3a] hover:text-gray-200`}`),K(_,H(t).label)}),U(`click`,n,()=>{var e;Q.activeTab=H(t).id,(e=window.getSelection())==null||e.removeAllRanges(),c()}),G(e,n)}),D(f);var p=R(f,2),m=L(p);ps(m,`title`,`1.0.0`),m.textContent=`1.0.0`,D(p),D(u);var h=R(u,2),v=L(h),y=L(v),b=L(y,!0);D(y);var x=R(y,2);Mc(L(x),{size:14}),D(x),D(v);var ee=R(v,2),C=L(ee),w=e=>{yl(e,{})},te=e=>{wl(e,{})},ne=e=>{Ol(e,{})},re=e=>{Vl(e,{})},ie=e=>{ru(e,{})},ae=e=>{cu(e,{})},oe=e=>{pu(e,{})},se=e=>{vu(e,{})},ce=e=>{Fu(e,{})},le=e=>{Eu(e,{})},ue=e=>{ku(e,{})};mo(C,e=>{Q.activeTab===Ic.Vars?e(w):Q.activeTab===Ic.Switches?e(te,1):Q.activeTab===Ic.Inv?e(ne,2):Q.activeTab===Ic.Actors?e(re,3):Q.activeTab===Ic.General?e(ie,4):Q.activeTab===Ic.Map?e(ae,5):Q.activeTab===Ic.CommonEv?e(oe,6):Q.activeTab===Ic.Locks?e(se,7):Q.activeTab===Ic.Logs?e(ce,8):Q.activeTab===Ic.Shortcuts?e(le,9):Q.activeTab===Ic.Settings&&e(ue,10)}),D(ee),D(h),il(R(h,2),{onmousedown:S}),D(t),z(e=>{var n,c,u,d;Xo(t,`opacity: ${H(l)||H(_)||H(s)?1:Xc.inactiveOpacity/100}; left: ${(n=H(r))==null?``:n}px; top: ${(c=H(i))==null?``:c}px; width: ${(u=H(a))==null?``:u}px; height: ${(d=H(o))==null?``:d}px; background: #13151a; color: #d4d8e3;`),K(b,e)},[()=>{var e;return((e=n.find(e=>e.id===Q.activeTab))==null?void 0:e.label)||``}]),Ua(`mouseenter`,t,()=>F(s,!0)),Ua(`mouseleave`,t,()=>F(s,!1)),U(`mousedown`,d,g),U(`mousedown`,v,g),U(`click`,x,()=>Q.visible=!1),G(e,t)};mo(C,e=>{Q.visible&&e(w)});var te=R(C,2);yo(te,21,()=>zc.toasts,e=>e.id,(e,t)=>{var n=Ru(),r=L(n),i=R(r,2),a=L(i,!0);D(i),D(n),z(()=>{Xo(n,`background: #1a1d24; border-color: ${H(t).type===`success`?`#10b981`:H(t).type===`warn`?`#fb923c`:H(t).type===`error`?`#ef4444`:`#6366f1`}; opacity: 0.95; min-width: 160px; max-width: 320px;`),Xo(r,`background: ${H(t).type===`success`?`#10b981`:H(t).type===`warn`?`#fb923c`:H(t).type===`error`?`#ef4444`:`#6366f1`};`),K(a,H(t).message)}),G(e,n)}),D(te),ol(R(te,2),{}),G(e,ee),Nt()}Wa([`mousedown`,`click`]);var Vu=`forge-mvmz-host`,Hu=document.getElementById(Vu);Hu||(Hu=document.createElement(`div`),Hu.id=Vu,Hu.style.position=`fixed`,Hu.style.top=`0`,Hu.style.left=`0`,Hu.style.width=`100vw`,Hu.style.height=`100vh`,Hu.style.pointerEvents=`none`,Hu.style.zIndex=`2147483647`,document.body.appendChild(Hu));var Uu=document.createElement(`style`);Uu.textContent=`#${Vu} { z-index: 2147483647 !important; }`,document.head.appendChild(Uu);var Wu=null,Gu;typeof Hu.attachShadow==`function`?(Wu=Hu.attachShadow({mode:`open`}),Gu=Wu,setTimeout(()=>{for(let e of document.head.querySelectorAll(`style`)){let t=e.textContent||``;if(t.includes(`tailwind`)||t.includes(`--color-bg`)){let e=document.createElement(`style`);e.textContent=t,Wu.appendChild(e)}}},0)):(Gu=Hu,setTimeout(()=>{for(let e of document.head.querySelectorAll(`style`)){let t=e.textContent||``;if(t.includes(`tailwind`)||t.includes(`--color-bg`)){let e=document.createElement(`style`);e.textContent=t,document.head.appendChild(e)}}},0));var Ku=document.createElement(`div`);Ku.style.pointerEvents=`none`,Ku.style.width=`100%`,Ku.style.height=`100%`,Gu.appendChild(Ku);try{to(Bu,{target:Ku})}catch(e){console.error(`[FORGE] Error mounting Svelte App:`,e)}if(window.Input!==void 0&&window.Input._onKeyDown){let e=window.Input._onKeyDown;window.Input._onKeyDown=function(t){let n=t.composedPath&&t.composedPath()[0]||t.target;Hu.contains(n)||e.call(this,t)}}if(window.Input!==void 0&&window.Input._onKeyUp){let e=window.Input._onKeyUp;window.Input._onKeyUp=function(t){let n=t.composedPath&&t.composedPath()[0]||t.target;Hu.contains(n)||e.call(this,t)}}})(); \ No newline at end of file diff --git a/js/plugins/TLInspector.js b/js/plugins/TLInspector.js new file mode 100644 index 0000000..01c28cc --- /dev/null +++ b/js/plugins/TLInspector.js @@ -0,0 +1,3041 @@ +//============================================================================= +// TLInspector.js +// Idea by Sakura · Plugin by Kao_SSS +//============================================================================= +/*: + * @plugindesc Translation Source Inspector - shows which source file/line every + * on-screen line of text and image comes from, and jumps to it in VSCode. + * @author Kao_SSS + * + * @help + * ---------------------------------------------------------------------------- + * TLInspector (RPGMaker MV / MZ, NW.js) + * Credits: Idea by Sakura · Plugin by Kao_SSS + * ---------------------------------------------------------------------------- + * A drop-in proofreading aid for translators. While the game runs, it tracks + * every message / choice / scrolling-text line and every on-screen image, and + * maps each one back to its EXACT source file and line number: + * + * - Dialogue / choices / scroll text -> www/data/MapXXX.json, + * CommonEvents.json, Troops.json (by identity-matching the running event + * list, so duplicate strings are never confused). + * - Scenario-plugin dialogue -> scenario/Scenario.json and similar + * (plugin scenario engines such as Nore/"Tes" that keep command-lists in one + * big JSON dictionary keyed by scene name, loaded into $dataScenario). Both + * in-game location and "Locate in Files" cover these. + * - Pictures and other images -> img/... path + the event command + * (or JS call stack) that loaded them. + * - Plugin / menu UI text (Bitmap.drawText / drawTextEx) -> where the VALUE + * itself lives whenever it can be resolved: a TextManager vocab assignment + * in a plugin .js, a System.json term, a database name/description, a + * notetag , or a plugins.js parameter. Strings built with + * String.prototype.format ("%1 remaining") are traced back to their + * template. The draw call site is kept as secondary info. + * + * Press the hotkey (default F10) to open the inspector overlay. Each row has an + * "Open in VSCode" button (runs `code -g file:line`) and an **edit** button to + * change the text and save it back to the source file without leaving the game. + * + * Live refresh (NW.js playtest only): + * In-game overlay "save to file" reloads that JSON into memory immediately. + * VSCode / external saves: we watch data/*.json; once the file mtime is stable + * (save finished), reload instantly. The game cannot hook Ctrl+S in VSCode itself. + * + * Limitations: + * - NW.js desktop playtest only (not browser) + * - Text already shown by a running event won't update until re-triggered + * (in-game overlay edit still updates the current message box) + * - Plugin .js / plugins.js changes still need F5 + * + * ---------------------------------------------------------------------------- + * Install: drop this file in www/js/plugins/ and add one line to plugins.js: + * { "name": "TLInspector", "status": true, "description": "TL source inspector", "parameters": {} } + * Place it LAST in the list. Remove that line to fully disable for a release. + * + * Config: edit the CFG object a few lines below. + * ---------------------------------------------------------------------------- + */ + +(function () { + 'use strict'; + + //========================================================================= + // Config + //========================================================================= + var CFG = { + enabled: true, + hotkey: "F9", // key (event.key) that toggles the overlay + editorCmd: "auto", // 'auto' = auto-detect installed editors (VS Code, Cursor, + // VSCodium, Insiders, Windsurf). Or set an absolute path to + // force a specific editor exe. + editor: 'auto', // which editor click-to-source opens files in: + // 'auto' = VSCode if it's installed, else the built-in + // in-game editor (also the fallback if a + // VSCode launch fails). + // 'builtin' = always the built-in in-game editor (view & + // edit the source file right inside the game). + // 'vscode' = always VSCode (uses editorCmd above). + workspaceFolder: "auto",// 'auto' = open files inside the game ROOT folder as the + // VSCode workspace (so they don't land in whatever window + // happened to be open last). Or set an absolute folder. + editorReuseWindow: true,// pass -r so VSCode reuses its current window + historySize: 80, // how many past text lines to keep + captureUiText: true, // capture plugin / menu / UI text drawn via Bitmap.drawText + // (so e.g. status-window strings from plugins.js are locatable) + dataDirOverride: null, // set an absolute path to force the data dir + uiScale: "2.5" // overlay scale: 'auto' from game width, or a number (1.5, 2, …) + }; + + if (!CFG.enabled) { return; } + + function resolveUiScale(v) { + if (v !== 'auto' && v != null && String(v).trim() !== '') { + var n = parseFloat(v); + if (!isNaN(n) && n > 0) { return Math.max(0.75, Math.min(3, n)); } + } + var base = 816; + var viewW = window.innerWidth || document.documentElement.clientWidth || base; + // The overlay lives in WINDOW pixels, so scale from the window size only. + // Using the game's internal resolution made a 1920px-wide game in a ~1366px + // window zoom 2.35x, with the 460px panel swallowing >80% of the screen. + var scale = viewW / base; + var dpr = window.devicePixelRatio || 1; + if (dpr > 1.15) { scale *= Math.min(2, 0.75 + dpr * 0.35); } + // Whatever the math says, keep the panel under ~45% of the window + // (the >=1 floor below still wins for small windows). + scale = Math.min(scale, (viewW * 0.45) / 460); + return Math.max(1, Math.min(2.75, scale)); + } + + function currentUiScale() { + return resolveUiScale(CFG.uiScale); + } + + function applyOverlayScale() { + var s = currentUiScale(); + var z = (s === 1) ? '' : String(s); + if (ui.root) { + ui.root.style.zoom = z; + ui.root.style.transformOrigin = (ui.side === 'left') ? 'top left' : 'top right'; + } + if (editor.root) { + editor.root.style.zoom = z; + editor.root.style.transformOrigin = 'top center'; + } + if (ui.pickLabel) { ui.pickLabel.style.zoom = z; } + } + + //========================================================================= + // Node / environment bootstrap (NW.js exposes require) + //========================================================================= + var nodeOk = false, fs = null, path = null, cp = null; + try { + if (typeof require === 'function') { + fs = require('fs'); + path = require('path'); + cp = require('child_process'); + nodeOk = true; + } + } catch (e) { nodeOk = false; } + + var ENGINE = (typeof Utils !== 'undefined' && Utils.RPGMAKER_NAME) || 'MV'; + + // Resolve the www root (where index.html lives) -> data dir. + // Primary method = exactly how the engine itself resolves paths + // (StorageManager.localFileDirectoryPath uses process.mainModule.filename), + // which is reliable regardless of the page URL scheme NW.js uses. + function resolveWwwRoot() { + try { + if (nodeOk && process.mainModule && process.mainModule.filename) { + return path.dirname(process.mainModule.filename); + } + } catch (e) { /* fall through */ } + try { + var href = window.location.href; // file:///C:/.../www/index.html + var p = decodeURIComponent(new URL(href).pathname); + if (/^\/[A-Za-z]:\//.test(p)) { p = p.slice(1); } // strip leading slash on Windows + return path ? path.dirname(p) : p.replace(/\/[^\/]*$/, ''); + } catch (e2) { + return nodeOk ? process.cwd() : ''; + } + } + var WWW_ROOT = resolveWwwRoot(); + var DATA_DIR = CFG.dataDirOverride || (path ? path.join(WWW_ROOT, 'data') : WWW_ROOT + '/data'); + + // The game root = folder holding the .exe. On MV that's the PARENT of www/; on MZ + // there is no www/, so it IS the resolved root. Used as the VSCode workspace folder + // so opened files land in the game's own project window, not the last-used one. + var GAME_ROOT = (function () { + try { + if (path && WWW_ROOT && path.basename(WWW_ROOT).toLowerCase() === 'www') { + return path.dirname(WWW_ROOT); + } + } catch (e) { /* ignore */ } + return WWW_ROOT; + })(); + + function mapFile(mapId) { + var n = ('000' + mapId).slice(-3); + return path ? path.join(DATA_DIR, 'Map' + n + '.json') : DATA_DIR + '/Map' + n + '.json'; + } + function dataFile(name) { + return path ? path.join(DATA_DIR, name) : DATA_DIR + '/' + name; + } + + // Scenario systems (e.g. the Nore / "Tes" engine) keep event command-lists OUTSIDE + // Map/CommonEvents/Troops: one big JSON dictionary under scenario/, keyed by scene + // name, loaded into a global ($dataScenario) and run via Game_Interpreter.setupChild. + // Each value is a plain MZ command list, so once we know the file + key it resolves + // to a line just like any other data file. + var SCENARIO_DIR = 'scenario'; + var SCENARIO_SETS = [ + { global: '$dataScenario', file: 'Scenario.json' }, + { global: '$dataScenario_en', file: 'Scenario_en.json' } + ]; + function scenarioPath(fileName) { + return path ? path.join(WWW_ROOT, SCENARIO_DIR, fileName) + : WWW_ROOT + '/' + SCENARIO_DIR + '/' + fileName; + } + // Every *.json actually present in the scenario/ folder (empty for normal games). + function scenarioFiles() { + var out = []; + if (!nodeOk) { return out; } + try { + fs.readdirSync(scenarioPath('')).forEach(function (f) { + if (/\.json$/i.test(f)) { out.push(scenarioPath(f)); } + }); + } catch (e) { /* no scenario/ folder -> normal for most games */ } + return out; + } + // If a scenario file's dictionary is already parsed into a known global, return the + // global name so callers can reuse it instead of re-parsing a (often huge) file. + function scenarioGlobalForFile(file) { + var base = baseName(file).toLowerCase(); + for (var i = 0; i < SCENARIO_SETS.length; i++) { + if (SCENARIO_SETS[i].file.toLowerCase() === base) { return SCENARIO_SETS[i].global; } + } + return null; + } + + function log() { + if (window.console) { console.log.apply(console, ['[TLInspector]'].concat([].slice.call(arguments))); } + } + log('init', { engine: ENGINE, node: nodeOk, dataDir: DATA_DIR, credits: 'Idea by Sakura · Plugin by Kao_SSS' }); + + //========================================================================= + // File cache + JSON value locator (path -> char offset -> line:col) + //========================================================================= + var fileCache = {}; // path -> { mtime, text, lineStarts } + + function readFileCached(file) { + if (!nodeOk) { return null; } + try { + var st = fs.statSync(file); + var mt = st.mtimeMs; + var c = fileCache[file]; + if (c && c.mtime === mt) { return c; } + var text = fs.readFileSync(file, 'utf8'); + var lineStarts = [0]; + for (var i = 0; i < text.length; i++) { + if (text.charCodeAt(i) === 10) { lineStarts.push(i + 1); } + } + c = { mtime: mt, text: text, lineStarts: lineStarts }; + fileCache[file] = c; + return c; + } catch (e) { return null; } + } + + function offsetToLineCol(c, off) { + var ls = c.lineStarts, lo = 0, hi = ls.length - 1, mid; + while (lo < hi) { + mid = (lo + hi + 1) >> 1; + if (ls[mid] <= off) { lo = mid; } else { hi = mid - 1; } + } + return { line: lo + 1, col: off - ls[lo] + 1 }; + } + + // --- minimal structural JSON scanner ------------------------------------ + function skipWs(t, i) { + while (i < t.length) { + var ch = t.charCodeAt(i); + if (ch === 32 || ch === 9 || ch === 10 || ch === 13) { i++; } else { break; } + } + return i; + } + function scanString(t, i) { // i at opening quote -> returns index after closing quote + i++; // past " + while (i < t.length) { + var ch = t[i]; + if (ch === '\\') { i += 2; continue; } + if (ch === '"') { return i + 1; } + i++; + } + return i; + } + function readKey(t, i) { // i at opening quote -> { end, value } + var start = i + 1, j = i + 1, out = ''; + while (j < t.length) { + var ch = t[j]; + if (ch === '\\') { out += t[j + 1]; j += 2; continue; } + if (ch === '"') { return { end: j + 1, value: out }; } + out += ch; j++; + } + return { end: j, value: out }; + } + function skipValue(t, i) { + i = skipWs(t, i); + var ch = t[i]; + if (ch === '"') { return scanString(t, i); } + if (ch === '{' || ch === '[') { + var open = ch, close = ch === '{' ? '}' : ']', depth = 0; + for (; i < t.length; i++) { + var c = t[i]; + if (c === '"') { i = scanString(t, i) - 1; continue; } + if (c === open) { depth++; } + else if (c === close) { depth--; if (depth === 0) { return i + 1; } } + } + return i; + } + // number / true / false / null + while (i < t.length && ',}] \t\r\n'.indexOf(t[i]) === -1) { i++; } + return i; + } + + // Walk `path` (array of string keys / number indices) -> start offset of value, or -1. + function locateOffset(t, pathArr) { + var i = skipWs(t, 0); + for (var s = 0; s < pathArr.length; s++) { + var step = pathArr[s]; + i = skipWs(t, i); + if (typeof step === 'number') { + if (t[i] !== '[') { return -1; } + i = skipWs(t, i + 1); + if (t[i] === ']') { return -1; } + for (var k = 0; k < step; k++) { + i = skipValue(t, i); + i = skipWs(t, i); + if (t[i] !== ',') { return -1; } + i = skipWs(t, i + 1); + } + // i now at target element value start + } else { + if (t[i] !== '{') { return -1; } + i = skipWs(t, i + 1); + var found = false; + while (i < t.length && t[i] !== '}') { + if (t[i] !== '"') { return -1; } + var key = readKey(t, i); + i = skipWs(t, key.end); + if (t[i] !== ':') { return -1; } + i = skipWs(t, i + 1); + if (key.value === step) { found = true; break; } + i = skipValue(t, i); + i = skipWs(t, i); + if (t[i] === ',') { i = skipWs(t, i + 1); } + } + if (!found) { return -1; } + } + } + return skipWs(t, i); + } + + // File drifted under a structural path (e.g. the scenario JSON was re-exported while + // the game held an older parse, shifting command indices): find the exact quoted + // value instead, preferring the occurrence nearest the path's top-level container so + // duplicate lines in other scenes/events don't win. + function reanchorByText(c, pathArr, quoted) { + var hits = [], p = c.text.indexOf(quoted), CAP = 5000; + while (p >= 0 && hits.length < CAP) { hits.push(p); p = c.text.indexOf(quoted, p + quoted.length); } + if (!hits.length) { return null; } + if (hits.length === 1) { return offsetToLineCol(c, hits[0]); } + var anchor = locateOffset(c.text, pathArr.slice(0, 1)); // start of the scene / list + var best = hits[0]; + if (anchor >= 0) { + var bd = Math.abs(hits[0] - anchor); + for (var k = 1; k < hits.length; k++) { var dd = Math.abs(hits[k] - anchor); if (dd < bd) { bd = dd; best = hits[k]; } } + } + return offsetToLineCol(c, best); + } + + var lineCache = {}; // file::pathKey::mtime -> {line,col} + function locateLine(file, pathArr, expectedText) { + if (!file || !pathArr || !nodeOk) { return null; } + var c = readFileCached(file); + if (!c) { return null; } + var key = file + '::' + pathArr.join('/') + '::' + c.mtime; + if (lineCache.hasOwnProperty(key)) { return lineCache[key]; } + var off = locateOffset(c.text, pathArr); + var quoted = (expectedText != null && expectedText !== '') ? JSON.stringify(String(expectedText)) : null; + var res; + if (off >= 0 && (!quoted || c.text.substr(off, quoted.length) === quoted)) { + res = offsetToLineCol(c, off); // path still valid (verified against the text) + } else if (quoted) { + // Path drifted (or the text isn't where the path points) -> re-anchor by exact + // text; if that finds nothing, still fall back to the structural offset. + res = reanchorByText(c, pathArr, quoted) || (off >= 0 ? offsetToLineCol(c, off) : null); + } else { + res = off >= 0 ? offsetToLineCol(c, off) : null; + } + lineCache[key] = res; + return res; + } + + //========================================================================= + // Provenance: map a running event command-list to its source file + path + //========================================================================= + function resolveList(list) { + try { + if (typeof $dataMap !== 'undefined' && $dataMap && $dataMap.events && + typeof $gameMap !== 'undefined' && $gameMap) { + var evs = $dataMap.events; + for (var e = 0; e < evs.length; e++) { + var ev = evs[e]; + if (!ev || !ev.pages) { continue; } + for (var p = 0; p < ev.pages.length; p++) { + if (ev.pages[p].list === list) { + return { file: mapFile($gameMap.mapId()), + prefix: ['events', e, 'pages', p, 'list'], + label: 'Map' + ('000' + $gameMap.mapId()).slice(-3) + ' ev' + e }; + } + } + } + } + if (typeof $dataCommonEvents !== 'undefined' && $dataCommonEvents) { + for (var c = 0; c < $dataCommonEvents.length; c++) { + var ce = $dataCommonEvents[c]; + if (ce && ce.list === list) { + return { file: dataFile('CommonEvents.json'), + prefix: [c, 'list'], label: 'CommonEvent ' + c }; + } + } + } + if (typeof $gameTroop !== 'undefined' && $gameTroop && $gameTroop._troopId && + typeof $dataTroops !== 'undefined' && $dataTroops) { + var tr = $dataTroops[$gameTroop._troopId]; + if (tr && tr.pages) { + for (var tp = 0; tp < tr.pages.length; tp++) { + if (tr.pages[tp].list === list) { + return { file: dataFile('Troops.json'), + prefix: [$gameTroop._troopId, 'pages', tp, 'list'], + label: 'Troop ' + $gameTroop._troopId }; + } + } + } + } + // Scenario dictionaries: the running list is a value of $dataScenario keyed + // by scene name (setupChild runs the list by reference, so identity holds). + for (var si = 0; si < SCENARIO_SETS.length; si++) { + var sg = SCENARIO_SETS[si], dict = window[sg.global]; + if (!dict || typeof dict !== 'object') { continue; } + for (var sk in dict) { + if (dict.hasOwnProperty(sk) && dict[sk] === list) { + return { file: scenarioPath(sg.file), prefix: [sk], + label: sg.file.replace(/\.json$/i, '') + ':' + sk }; + } + } + } + } catch (e) { log('resolveList error', e); } + return null; + } + + function pathToString(arr) { + var s = ''; + for (var i = 0; i < arr.length; i++) { + s += typeof arr[i] === 'number' ? '[' + arr[i] + ']' : (i ? '.' : '') + arr[i]; + } + return s; + } + + //========================================================================= + // Record store + //========================================================================= + var groupSeq = 0; + var currentGroup = -1; + var textRecords = []; // {kind,text,file,prefix,tail,group,ts,_key} + var imageTriggers = {}; // picture filename -> {file,prefix,tail,label} + var BUMP_GUARD_MS = 1000; + + function findByKey(key) { + for (var i = 0; i < textRecords.length; i++) { if (textRecords[i]._key === key) { return i; } } + return -1; + } + // Text seen again -> move it to the top (newest) so it never feels "undetected" + // when it was buried in history. Guard against churn from per-frame UI redraws. + function seenExisting(i, group) { + var r = textRecords[i], now = Date.now(); + if (now - r.ts < BUMP_GUARD_MS) { + r.ts = now; if (group != null && group !== -1) { r.group = group; } + return; // recently seen: keep its position + } + textRecords.splice(i, 1); + r.ts = now; if (group != null && group !== -1) { r.group = group; } + textRecords.push(r); + scheduleRefresh(); + } + + function pushText(kind, prov, tail, text, group, srcIndex, srcEventId) { + if (text == null || text === '') { return; } + var file = prov ? prov.file : null; + var key = 't\u0000' + kind + '\u0000' + text + '\u0000' + (file || '') + '\u0000' + (tail ? JSON.stringify(tail) : ''); + var i = findByKey(key); + if (i >= 0) { seenExisting(i, group); return; } + textRecords.push({ + kind: kind, text: text, file: file, + prefix: prov ? prov.prefix : null, + tail: tail, label: prov ? prov.label : '(unresolved)', + group: group, ts: Date.now(), + srcIndex: (srcIndex == null ? null : srcIndex), + srcEventId: (srcEventId == null ? 0 : srcEventId), + _key: key + }); + while (textRecords.length > CFG.historySize) { textRecords.shift(); } + scheduleRefresh(); + } + + function captureFromList(list, startIdx, textCode, eventId) { + var prov = resolveList(list); + var group = ++groupSeq; + currentGroup = group; + var i = startIdx + 1; + while (i < list.length && list[i] && list[i].code === textCode) { + pushText('text', prov, prov ? prov.prefix.concat([i, 'parameters', 0]) : null, + list[i].parameters[0], group, i, eventId); + i++; + } + // inline "Show Choices" immediately following the text block + if (list[i] && list[i].code === 102) { + captureChoices(list, i, prov, group, eventId); + } + } + + function captureChoices(list, idx, prov, group, eventId) { + if (prov === undefined) { prov = resolveList(list); } + if (group === undefined) { group = ++groupSeq; currentGroup = group; } + var choices = list[idx] && list[idx].parameters && list[idx].parameters[0]; + if (!Array.isArray(choices)) { return; } + for (var n = 0; n < choices.length; n++) { + pushText('choice', prov, + prov ? prov.prefix.concat([idx, 'parameters', 0, n]) : null, + choices[n], group, idx, eventId); + } + } + + //========================================================================= + // Hooks: text + //========================================================================= + if (typeof Game_Interpreter !== 'undefined') { + var GI = Game_Interpreter.prototype; + + var _c101 = GI.command101; + GI.command101 = function () { + var list = this._list, start = this._index; + var r = _c101.apply(this, arguments); + try { if (this._index !== start) { captureFromList(list, start, 401, this._eventId); } } + catch (e) { log('c101', e); } + return r; + }; + + var _c105 = GI.command105; + GI.command105 = function () { + var list = this._list, start = this._index; + var r = _c105.apply(this, arguments); + try { if (this._index !== start) { captureFromList(list, start, 405, this._eventId); } } + catch (e) { log('c105', e); } + return r; + }; + + var _c102 = GI.command102; + GI.command102 = function () { + // A STANDALONE "Show Choices" (not following a message — those are consumed + // inside command101) doesn't advance this._index within the method: MV bumps + // it later in executeCommand, MZ takes params as an arg. So gating on an index + // change missed standalone choice menus entirely. Instead capture exactly when + // the choices get set up: this call, while the message box wasn't already busy. + var list = this._list, idx = this._index; + var wasBusy = (typeof $gameMessage !== 'undefined') && $gameMessage && + $gameMessage.isBusy && $gameMessage.isBusy(); + var r = _c102.apply(this, arguments); + try { + if (!wasBusy && list && list[idx] && list[idx].code === 102) { + captureChoices(list, idx, undefined, undefined, this._eventId); + } + } catch (e) { log('c102', e); } + return r; + }; + + // Show Picture -> remember which command triggered each picture file + var _c231 = GI.command231; + GI.command231 = function () { + try { + var list = this._list, idx = this._index; + var name = this._params && this._params[1]; + if (name) { + var prov = resolveList(list); + imageTriggers['img/pictures/' + name + '.png'] = { + file: prov ? prov.file : null, + path: prov ? prov.prefix.concat([idx, 'parameters', 1]) : null, + label: prov ? prov.label : '(unresolved)' + }; + } + } catch (e) { log('c231', e); } + return _c231.apply(this, arguments); + }; + } + + // Clear "live" marker when the message box closes + if (typeof Game_Message !== 'undefined') { + var _clear = Game_Message.prototype.clear; + Game_Message.prototype.clear = function () { + currentGroup = -1; + scheduleRefresh(); + return _clear.apply(this, arguments); + }; + } + + // Capture plugin / menu / UI text. The true chokepoint is Bitmap.drawText: + // Window_Base.drawText/drawTextEx AND direct `this.contents.drawText(...)` calls + // inside plugins all funnel through it. We skip while a message box is showing + // (that text is captured precisely via the interpreter hooks) and de-duplicate by + // a digit-normalized key so a ticking value ("Money: 12"/"Money: 13") logs once. + if (CFG.captureUiText && typeof Bitmap !== 'undefined' && Bitmap.prototype.drawText) { + // Direct draws (Window_Base.drawText, plugin `this.contents.drawText(...)`). + // drawTextEx renders one character per call here, so single chars are dropped. + var _bmDrawText = Bitmap.prototype.drawText; + Bitmap.prototype.drawText = function (text) { + try { maybeCaptureUiText(text); } catch (e) { /* ignore */ } + return _bmDrawText.apply(this, arguments); + }; + } + if (CFG.captureUiText && typeof Window_Base !== 'undefined' && Window_Base.prototype.drawTextEx) { + // Escape-processed text (item descriptions, help text, names) arrives here as a + // whole string before being drawn character-by-character. + var _drawTextEx = Window_Base.prototype.drawTextEx; + Window_Base.prototype.drawTextEx = function (text) { + try { maybeCaptureUiText(text); } catch (e) { /* ignore */ } + return _drawTextEx.apply(this, arguments); + }; + } + function maybeCaptureUiText(text) { + if (typeof text !== 'string') { return; } + if (text.replace(/\s/g, '').length < 2) { return; } // drop single chars (per-char draws) + if (!/[^\s\d.,:%/+\-()]/.test(text)) { return; } // require a real letter + if (typeof $gameMessage !== 'undefined' && $gameMessage && $gameMessage.isBusy && $gameMessage.isBusy()) { return; } + var key = 'ui ' + text.replace(/\d+/g, '#'); // digit-normalized: "Money: 12/13" -> one entry + var i = findByKey(key); + if (i >= 0) { seenExisting(i, -1); return; } + var site = firstUserFrame(new Error().stack); + var rec = { kind: 'ui', text: text, file: site.file, prefix: null, + tail: null, label: site.label, uiLine: site.line, uiCol: null, + group: -1, ts: Date.now(), _key: key }; + // Prefer the VALUE's own home (vocab assignment / term / notetag / parameter) + // over the draw call site; keep the site as secondary info. + try { + var src = resolveUiSource(text); + if (src) { + rec.srcKind = src.kind; rec.label = src.label; rec.expText = src.expText; + if (src.file) { + rec.file = src.file; rec.uiLine = src.line || null; rec.uiCol = src.col || null; + rec.tail = src.tail || null; + rec.siteFile = site.file; rec.siteLine = site.line; rec.siteLabel = site.label; + } + } + } catch (e) { log('uiSource', e); } + textRecords.push(rec); + while (textRecords.length > CFG.historySize) { textRecords.shift(); } + scheduleRefresh(); + } + + function firstUserFrame(stack) { + var lines = (stack || '').split('\n'); + for (var i = 1; i < lines.length; i++) { + var m = lines[i].match(/(js\/plugins\/[^):]+|js\/[^):]+):(\d+):(\d+)/); + if (m && m[1].indexOf('TLInspector') === -1) { + var f = m[1]; + return { file: path ? path.join(WWW_ROOT, f) : WWW_ROOT + '/' + f, + line: parseInt(m[2], 10), label: f + ':' + m[2] }; + } + } + return { file: null, line: null, label: '(unknown)' }; + } + + //========================================================================= + // UI text provenance: map a drawn string back to the VALUE's own home + // (TextManager vocab assignment, System.json term, database field, notetag + // meta value, or plugins.js parameter) instead of just the draw call site. + // Index is built lazily from live game state; invalidated on F9 reload. + //========================================================================= + var uiValueIndex = null, uiIndexBuiltAt = 0; + + function uiIndexAdd(map, value, cand) { + if (typeof value !== 'string') { return; } + if (value.replace(/\s/g, '').length < 2) { return; } // same floor as capture + (map[value] || (map[value] = [])).push(cand); + } + + function buildUiValueIndex() { + // null prototype: game text can legitimately be 'constructor'/'toString'… + var map = Object.create(null); + // TextManager vocab: plugin-assigned own DATA properties. (The engine's own + // terms are accessor properties reading $dataSystem.terms -> indexed below.) + try { + if (typeof TextManager !== 'undefined') { + Object.getOwnPropertyNames(TextManager).forEach(function (p) { + var d = Object.getOwnPropertyDescriptor(TextManager, p); + if (d && !d.get && typeof d.value === 'string') { + uiIndexAdd(map, d.value, { t: 'tm', prop: p }); + } + }); + } + } catch (e) { log('uiIndex tm', e); } + // System.json: terms, type-name lists, and a few top-level strings. + try { + if (typeof $dataSystem !== 'undefined' && $dataSystem) { + var sysFile = dataFile('System.json'); + var terms = $dataSystem.terms || {}; + ['basic', 'commands', 'params'].forEach(function (g) { + (terms[g] || []).forEach(function (v, i) { + uiIndexAdd(map, v, { t: 'json', file: sysFile, path: ['terms', g, i], + label: 'System terms.' + g + '[' + i + ']' }); + }); + }); + var msgs = terms.messages || {}; + Object.keys(msgs).forEach(function (k) { + uiIndexAdd(map, msgs[k], { t: 'json', file: sysFile, path: ['terms', 'messages', k], + label: 'System terms.messages.' + k }); + }); + ['elements', 'skillTypes', 'weaponTypes', 'armorTypes', 'equipTypes'].forEach(function (g) { + ($dataSystem[g] || []).forEach(function (v, i) { + uiIndexAdd(map, v, { t: 'json', file: sysFile, path: [g, i], + label: 'System ' + g + '[' + i + ']' }); + }); + }); + uiIndexAdd(map, $dataSystem.gameTitle, { t: 'json', file: sysFile, path: ['gameTitle'], label: 'System gameTitle' }); + uiIndexAdd(map, $dataSystem.currencyUnit, { t: 'json', file: sysFile, path: ['currencyUnit'], label: 'System currencyUnit' }); + } + } catch (e) { log('uiIndex system', e); } + // Database display fields + notetag meta values. A meta value resolves to the + // object's "note" line; locateMetaValue narrows to the value inside the tag. + [ + ['$dataActors', 'Actors.json', ['name', 'nickname', 'profile']], + ['$dataClasses', 'Classes.json', ['name']], + ['$dataSkills', 'Skills.json', ['name', 'description', 'message1', 'message2']], + ['$dataItems', 'Items.json', ['name', 'description']], + ['$dataWeapons', 'Weapons.json', ['name', 'description']], + ['$dataArmors', 'Armors.json', ['name', 'description']], + ['$dataEnemies', 'Enemies.json', ['name']], + ['$dataStates', 'States.json', ['name', 'message1', 'message2', 'message3', 'message4']] + ].forEach(function (spec) { + try { + var arr = window[spec[0]]; + if (!Array.isArray(arr)) { return; } + var file = dataFile(spec[1]), short = spec[1].replace(/\.json$/i, ''); + for (var id = 1; id < arr.length; id++) { + var o = arr[id]; + if (!o) { continue; } + spec[2].forEach(function (f) { + uiIndexAdd(map, o[f], { t: 'json', file: file, path: [id, f], + label: short + '[' + id + '].' + f }); + }); + if (o.meta) { + Object.keys(o.meta).forEach(function (mk) { + if (typeof o.meta[mk] === 'string') { + uiIndexAdd(map, o.meta[mk], { t: 'meta', file: file, path: [id, 'note'], + label: short + '[' + id + '] note <' + mk + ':…>' }); + } + }); + } + } + } catch (e) { log('uiIndex ' + spec[0], e); } + }); + // Plugin parameters (plugins.js). + try { + if (window.$plugins) { + window.$plugins.forEach(function (pl) { + if (!pl || pl.status === false || !pl.parameters) { return; } + Object.keys(pl.parameters).forEach(function (pk) { + uiIndexAdd(map, pl.parameters[pk], { t: 'param', plugin: pl.name, param: pk }); + }); + }); + } + } catch (e) { log('uiIndex params', e); } + return map; + } + + function uiValueCandidates(text) { + if (!uiValueIndex) { uiValueIndex = buildUiValueIndex(); uiIndexBuiltAt = Date.now(); } + if (!jsLitIndex) { jsLitIndex = buildJsLitIndex(); } + var c = uiValueIndex[text] || null; + var lits = jsLitIndex[text] || null; + if (!c && !lits && Date.now() - uiIndexBuiltAt > 5000) { + // Vocab tables can be rewritten at runtime (language toggles): on a miss, + // rebuild against current state, at most once every 5s. + uiValueIndex = buildUiValueIndex(); uiIndexBuiltAt = Date.now(); + c = uiValueIndex[text] || null; + } + if (lits) { c = (c || []).concat(lits); } + return c; + } + + // Parse a JS string literal starting at t[i] (the quote) -> {value, end} or null. + function parseJsString(t, i) { + var q = t[i]; + if (q !== '"' && q !== "'" && q !== '`') { return null; } + var out = '', j = i + 1; + while (j < t.length) { + var ch = t[j]; + if (ch === '\\') { + var n = t[j + 1]; + if (n === 'n') { out += '\n'; } + else if (n === 't') { out += '\t'; } + else if (n === 'r') { out += '\r'; } + else if (n === 'u') { out += String.fromCharCode(parseInt(t.substr(j + 2, 4), 16) || 0); j += 4; } + else if (n === 'x') { out += String.fromCharCode(parseInt(t.substr(j + 2, 2), 16) || 0); j += 2; } + else { out += n; } + j += 2; continue; + } + if (ch === q) { return { value: out, end: j + 1 }; } + if (ch === '\n' && q !== '`') { return null; } // unterminated + out += ch; j++; + } + return null; + } + + // Plugin .js files in LOAD order (later plugins overwrite earlier assignments, so + // "last literal match" below = the assignment that actually won at runtime). + function pluginFilesInLoadOrder() { + var out = []; + if (!nodeOk) { return out; } + var pdir = path.join(WWW_ROOT, 'js', 'plugins'); + try { + if (window.$plugins) { + window.$plugins.forEach(function (pl) { + if (pl && pl.status !== false && pl.name && pl.name !== 'TLInspector') { + out.push(path.join(pdir, pl.name + '.js')); + } + }); + } + } catch (e) { /* ignore */ } + if (!out.length) { + try { + fs.readdirSync(pdir).forEach(function (f) { + if (/\.js$/.test(f) && f !== 'TLInspector.js') { out.push(path.join(pdir, f)); } + }); + } catch (e) { /* ignore */ } + } + return out; + } + + // Find the plugin-file assignment `TextManager. = ''` whose literal + // equals the property's CURRENT runtime value — this is what distinguishes an + // English vocab file from the Japanese one when both assign the same property. + // Falls back to the last assignment site in load order (value built at runtime). + var tmAssignCache = {}; // prop \0 value -> {file,line,col,exact} | null + function locateTextManagerAssignment(prop, value) { + var key = prop + '\u0000' + value; + if (tmAssignCache.hasOwnProperty(key)) { return tmAssignCache[key]; } + var safe = String(prop).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + var re = new RegExp('TextManager\\s*(?:\\.\\s*' + safe + + '|\\[\\s*[\'"]' + safe + '[\'"]\\s*\\])\\s*=(?![=>])', 'g'); + var literalHit = null, lastSite = null; + pluginFilesInLoadOrder().forEach(function (file) { + var c = readFileCached(file); + if (!c) { return; } + re.lastIndex = 0; + var m; + while ((m = re.exec(c.text))) { + if (inComment(c, m.index)) { continue; } + var vi = skipWs(c.text, m.index + m[0].length); + var site = { file: file, off: vi }; + lastSite = site; + var lit = parseJsString(c.text, vi); + if (lit && lit.value === value) { literalHit = site; } + } + }); + var hit = literalHit || lastSite, res = null; + if (hit) { + var lc = offsetToLineCol(readFileCached(hit.file), hit.off); + res = { file: hit.file, line: lc.line, col: lc.col, off: hit.off, exact: !!literalHit }; + } + tmAssignCache[key] = res; + return res; + } + + // Locate a plugin parameter value inside plugins.js (bounded to that plugin's entry). + function locatePluginParam(plugin, param, value) { + if (!nodeOk) { return null; } + var file = path.join(WWW_ROOT, 'js', 'plugins.js'); + var c = readFileCached(file); + if (!c) { return null; } + var anchor = c.text.indexOf('"name":"' + plugin + '"'); + if (anchor < 0) { + anchor = c.text.search(new RegExp('"name"\\s*:\\s*"' + + String(plugin).replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '"')); + } + if (anchor < 0) { return null; } + var next = c.text.indexOf('"name":', anchor + 7); // start of the NEXT plugin entry + var p = c.text.indexOf(JSON.stringify(String(value)), anchor); + var lc = offsetToLineCol(c, (p >= 0 && (next < 0 || p < next)) ? p : anchor); + return { file: file, line: lc.line, col: lc.col }; + } + + // Line/col of a notetag VALUE inside an object's "note" string. The JSON path + // points at the whole note; narrow to the meta value's escaped text within it. + function locateMetaValue(file, pathArr, value) { + if (!file || !pathArr || !nodeOk) { return null; } + var c = readFileCached(file); + if (!c) { return null; } + var key = file + '::meta:' + pathArr.join('/') + '::' + value + '::' + c.mtime; + if (lineCache.hasOwnProperty(key)) { return lineCache[key]; } + var res = null; + var off = locateOffset(c.text, pathArr); + if (off >= 0 && c.text[off] === '"') { + var end = scanString(c.text, off); + var esc = JSON.stringify(String(value)).slice(1, -1); + var p = esc ? c.text.indexOf(esc, off) : -1; + res = offsetToLineCol(c, (p >= 0 && p < end) ? p : off); + } else if (off >= 0) { + res = offsetToLineCol(c, off); + } + lineCache[key] = res; + return res; + } + + // String literals hardcoded in plugin .js code — e.g. a medal/skill table defined + // as arrays right in a plugin ("Great Sage" in Nore_MedalParam.js). Lowest-priority + // source: a drawn string can coincidentally equal an unrelated code literal, so + // vocab/data/notetag/param sources always win over this. Built once, lazily + // (plugin files can't change without F5); dropped on F9 in case one was edited + // through the built-in editor. + var jsLitIndex = null; + var JSLIT_MAX_PER_VALUE = 8; + function buildJsLitIndex() { + // null prototype: plugin code is full of literals like 'constructor'/'toString' + var map = Object.create(null); + pluginFilesInLoadOrder().forEach(function (file) { + var c = readFileCached(file); + if (!c) { return; } + var t = c.text, i = 0, n = t.length; + while (i < n) { + var ch = t[i], nx = t[i + 1]; + if (ch === '/' && nx === '/') { var e1 = t.indexOf('\n', i); i = e1 < 0 ? n : e1 + 1; continue; } + if (ch === '/' && nx === '*') { var e2 = t.indexOf('*/', i + 2); i = e2 < 0 ? n : e2 + 2; continue; } + if (ch === '"' || ch === "'" || ch === '`') { + var lit = parseJsString(t, i); + if (lit) { + var v = lit.value; + // same floors as maybeCaptureUiText: >=2 non-space chars + a real letter + if (v.replace(/\s/g, '').length >= 2 && /[^\s\d.,:%/+\-()]/.test(v)) { + var arr = map[v] || (map[v] = []); + if (arr.length < JSLIT_MAX_PER_VALUE) { arr.push({ t: 'jslit', file: file, off: i }); } + } + i = lit.end; continue; + } + } + i++; + } + }); + return map; + } + + // Recent String.prototype.format calls (template -> output), so a drawn string + // like "2 turn(s) remaining" resolves to its '%1 turn(s) remaining' template even + // though the drawn form never exists in any file. + var FORMAT_LOG = [], FORMAT_LOG_MAX = 40; + if (CFG.captureUiText && String.prototype.format) { + var _strFormat = String.prototype.format; + String.prototype.format = function () { + var out = _strFormat.apply(this, arguments); + try { + if (arguments.length && typeof out === 'string' && out.length >= 2) { + var tpl = String(this); + if (tpl !== out) { + var last = FORMAT_LOG[FORMAT_LOG.length - 1]; + if (!last || last.out !== out || last.tpl !== tpl) { + FORMAT_LOG.push({ tpl: tpl, out: out }); + if (FORMAT_LOG.length > FORMAT_LOG_MAX) { FORMAT_LOG.shift(); } + } + } + } + } catch (e) { /* ignore */ } + return out; + }; + } + + // Drawn string -> best value-source descriptor, or null if unknown. + function resolveUiSource(text) { + var val = text, via = '', cands = uiValueCandidates(text); + if (!cands) { + for (var i = FORMAT_LOG.length - 1; i >= 0; i--) { + if (FORMAT_LOG[i].out === text) { + cands = uiValueCandidates(FORMAT_LOG[i].tpl); + if (cands) { val = FORMAT_LOG[i].tpl; via = ' ← format()'; } + break; + } + } + } + if (!cands || !cands.length) { return null; } + var ORDER = { tm: 0, json: 1, meta: 2, param: 3, jslit: 4 }; + var best = cands[0]; + for (var k = 1; k < cands.length; k++) { + if (ORDER[cands[k].t] < ORDER[best.t]) { best = cands[k]; } + } + var loc = null; + if (best.t === 'tm') { + loc = locateTextManagerAssignment(best.prop, val); + // The assignment's own RHS literal is also in the jslit index — that's the + // SAME location, not an "other match": drop it before counting extras. + if (loc) { + cands = cands.filter(function (x) { + return !(x.t === 'jslit' && x.file === loc.file && x.off === loc.off); + }); + } + } + var extra = cands.length - 1; + var suffix = via + (extra > 0 ? ' (+' + extra + ' other match' + (extra > 1 ? 'es' : '') + ')' : ''); + if (best.t === 'tm') { + if (loc) { + return { kind: 'tm', file: loc.file, line: loc.line, col: loc.col, + label: 'TextManager.' + best.prop + suffix, expText: val }; + } + return { kind: 'tm', file: null, expText: val, + label: 'TextManager.' + best.prop + ' (assignment not in plugin files)' + suffix }; + } + if (best.t === 'param') { + var pp = locatePluginParam(best.plugin, best.param, val); + return { kind: 'param', file: pp && pp.file, line: pp && pp.line, col: pp && pp.col, + label: 'plugins.js ' + best.plugin + ' → ' + best.param + suffix, expText: val }; + } + if (best.t === 'jslit') { + var cf = readFileCached(best.file); + if (!cf) { return null; } + var ll = offsetToLineCol(cf, best.off); + return { kind: 'jslit', file: best.file, line: ll.line, col: ll.col, + label: baseName(best.file) + ' string literal' + suffix, expText: val }; + } + return { kind: best.t, file: best.file, tail: best.path, label: best.label + suffix, expText: val }; + } + + //========================================================================= + // Hooks: images (load log with call-site) + //========================================================================= + var imageLog = []; // {url, label, ts, bitmap} + if (typeof ImageManager !== 'undefined') { + var _loadBitmap = ImageManager.loadBitmap; + ImageManager.loadBitmap = function (folder, filename) { + var bm = _loadBitmap.apply(this, arguments); + try { + if (filename) { + var url = folder + filename + '.png'; + var last = imageLog[imageLog.length - 1]; + if (!last || last.url !== url) { + var site = firstUserFrame(new Error().stack); + imageLog.push({ url: url, label: site.label, ts: Date.now(), bitmap: bm }); + while (imageLog.length > CFG.historySize) { imageLog.shift(); } + } else if (last && !last.bitmap) { last.bitmap = bm; } + } + } catch (e) { /* ignore */ } + return bm; + }; + } + + //========================================================================= + // Live on-screen image collection (walk the sprite tree) + //========================================================================= + function collectOnScreenImages() { + var out = [], seen = {}; + var scene = (typeof SceneManager !== 'undefined') && SceneManager._scene; + if (!scene) { return out; } + var canvas = getGameCanvas(); + var rect = canvas ? canvas.getBoundingClientRect() : null; + var scale = rect && typeof Graphics !== 'undefined' && Graphics.width ? + rect.width / Graphics.width : 1; + + (function walk(obj) { + if (!obj) { return; } + if (obj.visible === false) { return; } + var bmp = obj.bitmap; + if (bmp && bmp._url) { + var vis = ('worldVisible' in obj) ? obj.worldVisible : true; + if (vis) { + var b = null; + try { b = obj.getBounds && obj.getBounds(); } catch (e) { b = null; } + if (b && b.width > 0 && b.height > 0) { + if (!seen[bmp._url]) { seen[bmp._url] = true; } + out.push({ + url: decodeUrl(bmp._url), + bitmap: bmp, + screen: rect ? { + x: rect.left + b.x * scale, y: rect.top + b.y * scale, + w: b.width * scale, h: b.height * scale + } : null + }); + } + } + } + var kids = obj.children; + if (kids) { for (var i = 0; i < kids.length; i++) { walk(kids[i]); } } + })(scene); + return out; + } + + function getGameCanvas() { + if (typeof Graphics !== 'undefined') { + if (Graphics._canvas) { return Graphics._canvas; } + if (Graphics._renderer && Graphics._renderer.view) { return Graphics._renderer.view; } + } + return document.querySelector('canvas'); + } + + // Bitmap URLs are percent-encoded (ImageManager uses encodeURIComponent on the + // filename), e.g. "img/pictures/%E3%83%90%E3%82%B9.png" for "バス". Decode so the + // path matches the real file on disk. + function decodeUrl(u) { + if (!u) { return u; } + try { return decodeURIComponent(u); } catch (e) { return u; } + } + + function urlToAbsPath(url) { + if (!url) { return null; } + var rel = decodeUrl(url).replace(/^\.?\//, ''); + return path ? path.join(WWW_ROOT, rel) : WWW_ROOT + '/' + rel; + } + + //========================================================================= + // External actions (VSCode / file explorer) + //========================================================================= + // Auto-locate installed editors so the user never has to touch the system PATH. + // We support the whole VS Code family (VS Code, Insiders, Cursor, VSCodium, + // Windsurf): they share an identical CLI (" -g file:line:col"), so the + // same launch path works for all of them. The user picks which one to use from a + // dropdown in the panel (see the editor ' + + 'Aa' + + 'W' + + '.*' + + '' + + '' + + '' + + '' + + '' + + '
' + + '' + + 'Replace' + + 'Replace All' + + '
'; + root.appendChild(find); + + var main = document.createElement('div'); + main.style.cssText = 'flex:1 1 auto;display:flex;overflow:hidden;background:#1b1e26'; + + var gutter = document.createElement('div'); + gutter.className = 'tl-ed-gutter'; + gutter.style.cssText = 'flex:0 0 auto;min-width:42px;overflow:hidden;text-align:right;' + + 'padding:8px 6px 8px 10px;color:#566;background:#161922;white-space:pre;' + + 'user-select:none;-webkit-user-select:none;font:12px/18px Consolas,Menlo,monospace'; + + var area = document.createElement('textarea'); + area.className = 'tl-ed-area'; + area.setAttribute('wrap', 'off'); // one logical line == one visual row + area.setAttribute('spellcheck', 'false'); + area.style.cssText = 'flex:1 1 auto;resize:none;border:0;outline:0;padding:8px 10px;' + + 'color:#e6e6e6;background:#1b1e26;white-space:pre;overflow:auto;' + + 'font:12px/18px Consolas,Menlo,monospace;tab-size:4;-moz-tab-size:4'; + + main.appendChild(gutter); + main.appendChild(area); + root.appendChild(main); + + var foot = document.createElement('div'); + foot.style.cssText = 'padding:5px 12px;background:#11131a;border-top:1px solid #333;color:#8aa;flex:0 0 auto;display:flex;gap:14px;border-radius:0 0 8px 8px'; + foot.innerHTML = 'Ctrl+S save · Ctrl+F find · Ctrl+H replace · Esc close · Tab indent' + + ''; + root.appendChild(foot); + + var st = document.createElement('style'); + st.textContent = + '#tl-editor .tl-ed-btn{cursor:pointer;padding:3px 9px;border-radius:4px;background:#333;color:#ddd}' + + '#tl-editor .tl-ed-btn:hover{filter:brightness(1.35)}' + + '#tl-editor .tl-ed-tabs{display:flex;overflow-x:auto;background:#0e1016;border-bottom:1px solid #333;flex:0 0 auto}' + + '#tl-editor .tl-ed-tab{display:flex;align-items:center;gap:6px;padding:5px 8px;border-right:1px solid #222;color:#9ab;cursor:pointer;white-space:nowrap;max-width:220px;flex:0 0 auto}' + + '#tl-editor .tl-ed-tab.on{background:#1b1e26;color:#fff}' + + '#tl-editor .tl-ed-tab .nm{overflow:hidden;text-overflow:ellipsis}' + + '#tl-editor .tl-ed-tab .dot{color:#fd6}' + + '#tl-editor .tl-ed-tab .x{color:#889;border-radius:3px;padding:0 4px}' + + '#tl-editor .tl-ed-tab .x:hover{background:#555;color:#fff}' + + '#tl-editor .tl-ed-find{background:#12141b;border-bottom:1px solid #333;padding:5px 8px;flex:0 0 auto}' + + '#tl-editor .tl-fr{display:flex;align-items:center;gap:6px;margin:2px 0}' + + '#tl-editor .tl-fq,#tl-editor .tl-fr-in{flex:0 0 240px;width:240px;min-width:0;background:#1b1e26;border:1px solid #344;color:#eee;padding:3px 6px;font:12px Consolas,Menlo,monospace;outline:none}' + + '#tl-editor .tl-fopt{cursor:pointer;padding:2px 6px;border-radius:3px;background:#222;color:#9ab;font:11px monospace}' + + '#tl-editor .tl-fopt.on{background:#2a5db0;color:#fff}' + + '#tl-editor .tl-fcount{color:#9ab;min-width:62px;text-align:center;font-size:11px}' + + '#tl-editor .tl-fcount.err{color:#f88}' + + '#tl-editor .tl-fbtn{cursor:pointer;padding:2px 8px;border-radius:3px;background:#333;color:#ddd;white-space:nowrap}' + + '#tl-editor .tl-fbtn:hover{filter:brightness(1.3)}'; + root.appendChild(st); + + head.addEventListener('click', function (e) { + var a = e.target.getAttribute('data-act'); + if (a === 'save') { saveEditor(); } + else if (a === 'close') { closeEditor(); } + else if (a === 'find') { openFind(false); } + }); + + // tab strip: click selects, click the x closes + tabs.addEventListener('click', function (e) { + var t = e.target; + while (t && t !== tabs && !t.hasAttribute('data-ti')) { t = t.parentNode; } + if (!t || t === tabs) { return; } + var i = parseInt(t.getAttribute('data-ti'), 10); + if (e.target.classList.contains('x')) { closeTab(i); } else { selectTab(i); } + }); + + // find widget wiring + editor.fq = find.querySelector('.tl-fq'); + editor.frin = find.querySelector('.tl-fr-in'); + editor.fcount = find.querySelector('.tl-fcount'); + editor.fq.addEventListener('input', function () { + editor.find.q = this.value; recomputeMatches(); + showMatch(editor.find.idx < 0 ? 0 : editor.find.idx); + }); + editor.fq.addEventListener('keydown', function (e) { + if (e.key === 'Enter') { e.preventDefault(); showMatch(editor.find.idx + (e.shiftKey ? -1 : 1)); } + else if (e.key === 'Escape') { e.preventDefault(); closeFind(); } + }); + editor.frin.addEventListener('input', function () { editor.find.r = this.value; }); + editor.frin.addEventListener('keydown', function (e) { + if (e.key === 'Enter') { e.preventDefault(); replaceCurrent(); } + else if (e.key === 'Escape') { e.preventDefault(); closeFind(); } + }); + find.addEventListener('click', function (e) { + var opt = e.target.getAttribute('data-opt'); + var fa = e.target.getAttribute('data-fa'); + if (opt) { + var f = editor.find; f[opt] = !f[opt]; + e.target.classList.toggle('on', f[opt]); + recomputeMatches(); showMatch(f.idx < 0 ? 0 : f.idx); + } else if (fa === 'next') { showMatch(editor.find.idx + 1); } + else if (fa === 'prev') { showMatch(editor.find.idx - 1); } + else if (fa === 'close') { closeFind(); } + else if (fa === 'rep') { replaceCurrent(); } + else if (fa === 'repall') { replaceAll(); } + }); + + area.addEventListener('input', function () { + markDirty(); refreshGutter(); + if (editor.find.open) { recomputeMatches(); updateFindCount(); } + }); + area.addEventListener('scroll', syncGutter); + area.addEventListener('keydown', onEditorKey, false); + + // Keep the game from reacting to clicks/keys aimed at the editor (mirrors the + // inspector panel's isolation). With "freeze" off this is what protects typing. + ['mousedown', 'mouseup', 'click', 'dblclick', 'wheel', 'contextmenu', + 'touchstart', 'touchend', 'touchmove', 'pointerdown', 'pointerup', + 'keydown', 'keyup', 'keypress'].forEach(function (t) { + root.addEventListener(t, function (ev) { ev.stopPropagation(); }, false); + }); + + document.body.appendChild(root); + editor.root = root; + editor.area = area; + editor.gutter = gutter; + editor.tabsEl = tabs; + editor.findEl = find; + editor.statusEl = foot.querySelector('.tl-ed-status'); + applyOverlayScale(); + } + + //--- documents / tabs ---------------------------------------------------- + function docIndexByFile(file) { + for (var i = 0; i < editor.docs.length; i++) { if (editor.docs[i].file === file) { return i; } } + return -1; + } + + // Files above this size are NOT loaded whole into the