handler-playable-sdk 0.5.544 → 0.5.548

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Yr=Object.create;var Kt=Object.defineProperty;var Kr=Object.getOwnPropertyDescriptor;var Xr=Object.getOwnPropertyNames;var Jr=Object.getPrototypeOf,Zr=Object.prototype.hasOwnProperty;var he=(s,e)=>()=>(s&&(e=s(s=0)),e);var vt=(s,e)=>{for(var t in e)Kt(s,t,{get:e[t],enumerable:!0})},Ba=(s,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Xr(e))!Zr.call(s,i)&&i!==t&&Kt(s,i,{get:()=>e[i],enumerable:!(n=Kr(e,i))||n.enumerable});return s};var Ze=(s,e,t)=>(t=s!=null?Yr(Jr(s)):{},Ba(e||!s||!s.__esModule?Kt(t,"default",{value:s,enumerable:!0}):t,s)),Qr=s=>Ba(Kt({},"__esModule",{value:!0}),s);var fe,wi=he(()=>{"use strict";fe=class{static get(e){var t;return(t=this.store.get(e))==null?void 0:t.data}static set(e,t){this.store.set(e,{data:t})}static has(e){return this.store.has(e)}static clear(){this.store.clear()}};fe.store=new Map});function oo(){var s,e;try{let t=typeof window!="undefined"&&(document.querySelector('script[src*="inline-assets.js"]')||((e=(s=document.querySelector("script"))==null?void 0:s.textContent)==null?void 0:e.includes("inline-assets.js"))||window.INLINE_ASSETS),n=typeof window!="undefined"&&document.querySelector('link[href*="assets/"], script[src*="assets/"]');return!!(t&&!n)}catch{return!1}}async function lo(){try{if(typeof window!="undefined"){let s=await fetch("./build-settings.json");if(s.ok){let e=await s.json();return console.log("[AssetLoader] Loaded build settings:",e),e}}}catch{}return null}function co(){try{if(typeof window!="undefined"){let s=new XMLHttpRequest;if(s.open("GET","./build-settings.json",!1),s.send(),s.status===200&&s.responseText){let e=JSON.parse(s.responseText);return console.log("[AssetLoader] Loaded build settings (sync):",e),e}}}catch{}return null}async function po(){if(console.log(`[AssetLoader] getInlineAssets() called - Effective mode: ${B}`),Object.keys(me).length>0)return console.log("[AssetLoader] Returning cached inline assets:",Object.keys(me)),me;if(typeof window!="undefined"&&window.INLINE_ASSETS)return console.log("[AssetLoader] Using pre-loaded INLINE_ASSETS from window:",Object.keys(window.INLINE_ASSETS)),me={...window.INLINE_ASSETS},me;if(!(B==="publish"&&oe!==!1))return console.log("[AssetLoader] Inline assets disabled for this build mode."),me;if(!xi){let e=typeof window!="undefined"?new URL("inline-assets.js",window.location.href).href:"./inline-assets.js";console.log("[AssetLoader] Loading inline assets from:",e),xi=(async()=>{try{try{let a=await import(e+"?t="+Date.now());if(a.INLINE_ASSETS)return console.log("[AssetLoader] Loaded INLINE_ASSETS via ES module:",Object.keys(a.INLINE_ASSETS)),a.INLINE_ASSETS}catch(a){console.warn("[AssetLoader] ES module import failed, trying text parse:",a)}let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);let n=await t.text();console.log("[AssetLoader] Received JS code, length:",n.length);let i=n.match(/export\s+const\s+INLINE_ASSETS\s*=\s*({[\s\S]*?});?\s*$/m);if(i)try{let a=i[1];console.log("[AssetLoader] Found INLINE_ASSETS export, parsing...");let r=new Function("return "+a)();return console.log("[AssetLoader] Parsed inline assets:",Object.keys(r)),r}catch(a){return console.warn("[AssetLoader] Failed to parse inline assets:",a),{}}else return console.warn("[AssetLoader] INLINE_ASSETS export not found in response"),console.log("[AssetLoader] JS code preview:",n.substring(0,500)),{}}catch(t){return console.warn("[AssetLoader] Failed to load inline assets:",t),{}}})()}return me=await xi,console.log("[AssetLoader] Final inline assets cache:",Object.keys(me)),me}function Ei(s){return s===null||typeof s!="object"||(Object.freeze(s),Object.values(s).forEach(e=>Ei(e))),s}function uo(s=64,e=64,t=16711680){let n=document.createElement("canvas");n.width=s,n.height=e;let i=n.getContext("2d");return i.fillStyle=`#${t.toString(16).padStart(6,"0")}`,i.fillRect(0,0,s,e),i.strokeStyle="#000",i.strokeRect(0,0,s,e),i.fillStyle="#fff",i.font="10px sans-serif",i.textAlign="center",i.fillText("MISSING",s/2,e/2),be.Texture.from(n)}function Si(s,e){xs.set(s,e)}var be,vs,ws,De,B,oe,Te,me,xi,xs,He,Qt=he(()=>{"use strict";be=require("pixi.js");wi();vs=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",ws=oo(),De=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,B=ws?"publish":vs,oe=De==null?void 0:De.assetsInlined;De!=null&&De.buildMode&&(B=De.buildMode,console.log(`[AssetLoader] Build mode overridden by inline settings: ${B}`));Te=co();Te!=null&&Te.buildMode&&(B=Te.buildMode,console.log(`[AssetLoader] Build mode overridden by sync settings: ${B}`));(Te==null?void 0:Te.assetsInlined)!==void 0&&(oe=Te.assetsInlined);lo().then(s=>{s!=null&&s.buildMode&&s.buildMode!==B&&(B=s.buildMode,console.log(`[AssetLoader] Build mode overridden by settings: ${B}`)),(s==null?void 0:s.assetsInlined)!==void 0&&(oe=s.assetsInlined)}).catch(()=>{});console.log(`[AssetLoader] MODULE LOADED - Compile: ${vs}, Runtime: ${ws?"publish":"dev"}, Effective: ${B}`);me={},xi=null;xs=new Map;He=class{static async load(e,t,n,i){let a=`${e}:${t.path}`,r=fe.get(a);if(r!==void 0)return r;console.log(`[AssetLoader] Loading asset: ${e}, type: ${t.type}, Effective mode: ${B}`),console.log(`[AssetLoader] Window defined: ${typeof window!="undefined"}, INLINE_ASSETS exists: ${!!(typeof window!="undefined"&&window.INLINE_ASSETS)}, keys: ${typeof window!="undefined"&&window.INLINE_ASSETS?Object.keys(window.INLINE_ASSETS).length:"N/A"}`);let o=await po(),l=o[e];if(!l&&i&&(l=o[i],l&&console.log(`[AssetLoader] Found inline data for ${e} using configId: ${i}`)),!l&&t.path){let p=t.path.split("/");if(p.length>=2){let u=p[p.length-1].split(".")[0];o[u]&&(l=o[u],console.log(`[AssetLoader] Found inline data for ${e} using assetName: ${u}`))}}if(console.log("[AssetLoader] Inline data for",e,":",l?"FOUND":"NOT FOUND"),B==="publish"&&oe!==!1&&(console.log("[AssetLoader] \u26A0\uFE0F PUBLISH MODE DETECTED - inline assets are MANDATORY"),!l))throw new Error(`[AssetLoader] PUBLISH MODE: Inline asset required but NOT FOUND for object: ${e}, path: ${t.path}`);let d=xs.get(t.type);if(d)try{let p=await d(t.path,l,e,n);return fe.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}try{let p;switch(t.type){case"image":p=await this.loadImage(t.path,l);break;case"json":p=await this.loadJSON(t.path,l),p=Ei(p);break;default:throw new Error(`Unknown asset type: ${t.type}`)}return fe.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}}static async loadImage(e,t){let n=B==="publish",i=n&&oe!==!1;if(console.log(`[AssetLoader] loadImage - Effective mode: ${B}, isPublishMode: ${n}, inlineData: ${t?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for object. Path: ${e}`);if(typeof t!="string"||!t.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof t}`);try{return await be.Assets.load(t)}catch(a){throw console.error("[AssetLoader] Failed to load texture from data URI:",a),a}}if(t&&typeof t=="string"&&t.startsWith("data:"))try{return await be.Assets.load(t)}catch(a){return console.error("[AssetLoader] Failed to load texture from data URI, falling back to path:",a),await be.Assets.load(e)}return await be.Assets.load(e)}static async loadJSON(e,t){let n=B==="publish",i=n&&oe!==!1;if(console.log(`[AssetLoader] loadJSON - Effective mode: ${B}, isPublishMode: ${n}, inlineData: ${t?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${e}`);if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let r=atob(t.split(",")[1]);return JSON.parse(r)}return JSON.parse(t)}if(t){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let r=atob(t.split(",")[1]);return JSON.parse(r)}return JSON.parse(t)}let a=await fetch(e);if(!a.ok)throw new Error(`JSON fetch failed: ${e}`);return a.json()}static handleFailure(e,t,n){if(B==="dev"){let a=t==="image"?uo():Ei({__placeholder:!0,type:t});return fe.set(e+":"+((n==null?void 0:n.path)||"missing"),a),a}throw n}};Si("image",async(s,e)=>{let t=B==="publish",n=t&&oe!==!1,i=B==="brand",a=t&&oe===!1;if(console.log(`[AssetLoader] registerType('image') - Effective mode: ${B}, isPublishMode: ${t}, isBrandMode: ${i}, inlineData: ${e?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${s}`);if(typeof e!="string"||!e.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof e}`);return be.Assets.load(e)}let r=s;return(i||a)&&s&&!s.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(r=s,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${s}" as-is`)):(r=`assets/${s}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${s}" -> "${r}"`))),be.Assets.load(e||r)});Si("json",async(s,e)=>{let t=B==="publish",n=t&&oe!==!1,i=B==="brand",a=t&&oe===!1;if(console.log(`[AssetLoader] registerType('json') - Effective mode: ${B}, isPublishMode: ${t}, isBrandMode: ${i}, inlineData: ${e?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${s}`);return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e)}let r=s;if((i||a)&&s&&!s.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(r=s,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${s}" as-is`)):(r=`assets/${s}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${s}" -> "${r}"`))),e)return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e);let o=await fetch(r);if(!o.ok)throw new Error(`JSON fetch failed: ${s}`);return o.json()})});var Ss={};vt(Ss,{AssetTextures:()=>le,initAssetTextures:()=>Ti});function Ti(s,e){Es.init(s,e),typeof window!="undefined"&&(window.__AssetTextures=le)}var Ai,Es,le,nt=he(()=>{"use strict";Qt();Ai=class{constructor(){this.textures=new Map;this.readyPromise=null;this.priorityReadyPromise=null;this.priorityReadyResolve=null;this.config=null;this.app=null;this.attempted=new Set;this.waiters=new Set}init(e,t){if(this.config===e&&this.app===t&&this.priorityReadyPromise){console.log("[AssetTextures] init called with same config/app; keeping existing state");return}this.textures.clear(),this.readyPromise=null,this.priorityReadyPromise=null,this.priorityReadyResolve=null,this.attempted.clear(),this.waiters.clear(),this.priorityReadyPromise=new Promise(n=>{this.priorityReadyResolve=n}),this.config=e,this.app=t,console.log("[AssetTextures] Initialized with config, cleared previous textures")}async ready(){if(this.readyPromise){await this.readyPromise;return}if(!this.config)throw new Error("[AssetTextures] Must call init() before ready() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before ready() - app is null");let e=this.config,t=this.app;return this.readyPromise=(async()=>{var r;console.log("[AssetTextures] Loading all assets...");let n=new Set(["background_loading_1"]),i=[],a=[];for(let[o,l]of e.objects.entries()){let c=(r=l.render)==null?void 0:r.asset;if(!c)continue;let d=async()=>{var p;try{let u=(p=l.identity)==null?void 0:p.id;console.log(`[AssetTextures] Loading ${c.type}: ${o} (${u})`);let g=await He.load(o,c,t,u);this.textures.set(o,g),console.log(`[AssetTextures] \u2713 Loaded: ${o}`)}catch(u){console.error(`[AssetTextures] \u2717 Failed to load: ${o}`,u)}finally{this.attempted.add(o);try{for(let u of Array.from(this.waiters))u()}catch{}}};n.has(o)?i.push(d()):a.push(d())}i.length>0&&(console.log("[AssetTextures] Phase 1: Loading priority assets (loading screen)..."),await Promise.all(i),console.log("[AssetTextures] Phase 1: Priority assets ready")),this.priorityReadyResolve&&this.priorityReadyResolve(),console.log("[AssetTextures] Phase 2: Loading remaining assets..."),await Promise.all(a),console.log("[AssetTextures] All textures loaded:",Array.from(this.textures.keys()))})(),this.readyPromise}async priorityReady(){return this.priorityReadyPromise?this.priorityReadyPromise:Promise.resolve()}async waitFor(e,t={}){if(!this.config)throw new Error("[AssetTextures] Must call init() before waitFor() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before waitFor() - app is null");let i=Array.from(new Set((e||[]).filter(o=>typeof o=="string"&&o))).filter(o=>{var l,c,d,p;try{let u=(d=(c=(l=this.config)==null?void 0:l.objects)==null?void 0:c.get)==null?void 0:d.call(c,o);return!!((p=u==null?void 0:u.render)!=null&&p.asset)}catch{return!1}});if(i.length===0)return;this.ready().catch(()=>{});let a=()=>i.every(o=>this.textures.has(o)||this.attempted.has(o));if(a())return;let r=typeof t.timeoutMs=="number"?t.timeoutMs:15e3;await new Promise(o=>{let l=!1,c=()=>{l||a()&&(l=!0,this.waiters.delete(c),o())};this.waiters.add(c),c(),r>0&&setTimeout(()=>{l||(l=!0,this.waiters.delete(c),console.warn("[AssetTextures] waitFor timed out; continuing",{ids:i}),o())},r)})}get(e){return this.textures.get(e)}set(e,t){this.textures.set(e,t),console.log(`[AssetTextures] Updated texture: ${e}`)}clear(){this.textures.clear(),this.readyPromise=null,console.log("[AssetTextures] Cleared all textures")}getAllIds(){return Array.from(this.textures.keys())}},Es=new Ai,le=new Proxy(Es,{get(s,e){return e in s&&typeof s[e]=="function"?s[e].bind(s):s.get(e)},set(s,e,t){return s.set(e,t),!0}})});var Be={};vt(Be,{applyConfigOverride:()=>ce,applyConfigOverrides:()=>ke,applyConfigsToDisk:()=>hn,clearConfigOverrides:()=>ne,clearConfigOverridesForObject:()=>Ps,configOverrideManager:()=>_s,deepClone:()=>W,exportConfigsAsJSON:()=>Fe,getConfigOverrides:()=>X,getConfigStateSummary:()=>Ie,getOverrideMode:()=>Tt,redoLastConfigChange:()=>gn,removeConfigOverride:()=>Lt,resetToApplied:()=>kt,resetToOriginal:()=>fn,setOverrideMode:()=>Oi,trackObjectCreation:()=>Os,trackObjectDeletion:()=>Rs,undoLastConfigChange:()=>un});function cn(){return typeof window=="undefined"?null:window.__editableConfig||null}function Mi(){return typeof window=="undefined"?null:window.__editableConfigBaseline||null}function ji(s,e){var t,n;if(!s)return null;try{if(s instanceof Map)return(t=s.get(e))!=null?t:null;if(typeof s=="object")return(n=s[e])!=null?n:null}catch{}return null}function Do(s,e,t){if(s){if(s instanceof Map){s.set(e,t);return}typeof s=="object"&&(s[e]=t)}}function Is(s,e){for(let t of e)At(s,t.path,t.value)}function dn(s){var o;if(typeof window=="undefined")return;let e=cn();if(!e)return;let t=Mi(),n=(o=t?ji(t.objects,s):null)!=null?o:ji(e.objects,s);if(!n)return;let i=W(n),a=X().filter(l=>l.objectId===s);try{Is(i,a)}catch(l){console.error("[CONFIG] Failed to reapply overrides for object",s,l);return}Do(e.objects,s,i);let r=window.applyEditableObjectConfig;if(typeof r=="function")try{r(s,i)}catch{}}function Pi(){var i;if(typeof window=="undefined")return;let s=cn();if(!(s!=null&&s.engine))return;let e=Mi(),t=W(((i=e==null?void 0:e.engine)!=null?i:s.engine)||{}),n=X().filter(a=>!a.objectId&&!a.sceneId);try{Is(t,n)}catch(a){console.error("[CONFIG] Failed to reapply engine overrides",a);return}try{let a=s.engine;for(let r of Object.keys(a))r in t||delete a[r];for(let[r,o]of Object.entries(t))a[r]=o}catch{s.engine=t}}function Ho(){if(typeof window=="undefined")return"unknown";let s=window;return typeof s.__HANDLER_PROJECT_ID=="string"?s.__HANDLER_PROJECT_ID:"handler-default"}function js(){return`handler_preview_config_overrides::${Ho()}`}function No(){if(typeof window=="undefined")return[];try{let s=window.localStorage.getItem(js());if(!s)return[];let e=JSON.parse(s);return Array.isArray(e)?e:[]}catch{return[]}}function pn(s){if(typeof window!="undefined")try{window.localStorage.setItem(js(),JSON.stringify(s))}catch{}}function Tt(){return typeof window=="undefined"?!1:window.__enableConfigOverrides===!0}function Oi(s){if(typeof window!="undefined"){window.__enableConfigOverrides=s;try{window.localStorage.setItem(Ms,s?"true":"false")}catch{}}}function ce(s,e={}){var u,g;let{objectId:t,path:n,value:i}=s,{silent:a=!1,persist:r=!0,emitEvent:o=!0}=e,l=cn();if(!l){console.warn("[CONFIG] applyConfigOverride: No editable config found in window.__editableConfig");return}let c=t?(g=(u=l.objects)==null?void 0:u.get)==null?void 0:g.call(u,t):l.engine;if(!c){console.warn("[CONFIG] applyConfigOverride: Override target not found:",{objectId:t,path:n,hasObjects:!!l.objects});return}a||console.log("[CONFIG] applyConfigOverride: Target found, applying...",{objectId:t,path:n,value:i});let d;try{d=zs(c,n),At(c,n,i)}catch(f){console.error("[CONFIG] applyConfigOverride failed:",{objectId:t,path:n,value:i},f);return}if(e.trackHistory!==!1){window.__configChanges=window.__configChanges||[];let f=window.__configChanges;f.push({objectId:t,path:n,oldValue:d,newValue:i,ts:Date.now()}),f.length>_i&&f.shift(),window.__configChangeRedo=[]}if(r){let f=X(),h=f.findIndex(m=>m.objectId===t&&m.sceneId===s.sceneId&&m.path===n);h>=0?f[h].value=i:f.push(s),window.__configOverrides=f,pn(f),Tt()||Oi(!0)}a||console.log("[CONFIG] Applied override:",s),o&&typeof window!="undefined"&&window.dispatchEvent(new CustomEvent("config:changed",{detail:s}))}function ke(s,e={}){let t=e.emitEvent!==!1,n=[];for(let i of s)i!=null&&i.objectId&&typeof i.objectId=="string"&&n.push(i.objectId),ce(i,{...e,emitEvent:!1});if(t&&typeof window!="undefined"){let i=Array.from(new Set(n));window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch",objectIds:i,count:s.length}}))}}function ne(){window.__configOverrides=[],window.__configChanges=[],window.__configChangeRedo=[],pn([]),console.log("[CONFIG] Cleared all overrides")}function Ps(s){let e=X().filter(n=>n.objectId!==s);window.__configOverrides=e,pn(e);let t=window.__configChanges||[];window.__configChanges=t.filter(n=>n.objectId!==s),dn(s),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"clear_object",objectId:s}}))}function Lt(s,e){let t=X().filter(i=>i.objectId!==s||i.path!==e);window.__configOverrides=t,pn(t);let n=window.__configChanges||[];window.__configChanges=n.filter(i=>i.objectId!==s||i.path!==e),s?dn(s):Pi(),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"remove",objectId:s,path:e}}))}function X(){return typeof window=="undefined"?[]:(window.__configOverrides||(window.__configOverrides=No()),window.__configOverrides||[])}function un(){var a;if(typeof window=="undefined")return!1;let s=window.__configChanges||[];if(s.length===0)return!1;let e=s.pop();window.__configChangeRedo=window.__configChangeRedo||[];let t=window.__configChangeRedo;if(e.changeType==="object_create"){let{screenId:r}=e.metadata||{};return e.objectId&&r&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:r})}).catch(o=>console.error("[CONFIG] Failed to delete object on undo:",o)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Deleted object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:r,objectConfigId:o}=e.metadata||{},l=e.oldValue;return e.objectId&&r&&l&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:r,instanceId:e.objectId,objectConfigId:o||((a=l==null?void 0:l.identity)==null?void 0:a.id),config:l})}).catch(c=>console.error("[CONFIG] Failed to recreate object on undo:",c)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Recreated object",e.objectId),!0}t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType});let n=Mi(),i=!1;if(n){let r=e.objectId?ji(n.objects,e.objectId):n.engine;if(r){let o=zs(r,e.path);JSON.stringify(o)===JSON.stringify(e.oldValue)&&(i=!0)}}return i?Lt(e.objectId,e.path):(ce({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?dn(e.objectId):Pi()),console.log("[CONFIG] Undo:",e.path),!0}function gn(){var n;if(typeof window=="undefined")return!1;let s=window.__configChangeRedo||[];if(s.length===0)return!1;let e=s.pop();if(e.changeType==="object_create"){let{screenId:i,objectConfigId:a}=e.metadata||{},r=e.newValue;return e.objectId&&i&&r&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:e.objectId,objectConfigId:a||((n=r==null?void 0:r.identity)==null?void 0:n.id),config:r})}).catch(l=>console.error("[CONFIG] Failed to recreate object on redo:",l)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Recreated object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:i}=e.metadata||{};return e.objectId&&i&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:i})}).catch(r=>console.error("[CONFIG] Failed to delete object on redo:",r)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Deleted object",e.objectId),!0}return window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType}),ce({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?dn(e.objectId):Pi(),console.log("[CONFIG] Redo:",e.path),!0}function Os(s,e,t){var i;if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let n=window.__configChanges;n.push({objectId:s,path:"__object_create__",oldValue:null,newValue:t,ts:Date.now(),changeType:"object_create",metadata:{screenId:e,objectConfigId:(i=t==null?void 0:t.identity)==null?void 0:i.id}}),window.__configChangeRedo=[],n.length>_i&&n.shift(),console.log("[CONFIG] Tracked object creation:",s)}function Rs(s,e,t){if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let n=window.__configChanges;n.push({objectId:s,path:"__object_delete__",oldValue:t,newValue:null,ts:Date.now(),changeType:"object_delete",metadata:{screenId:e}}),window.__configChangeRedo=[],n.length>_i&&n.shift(),console.log("[CONFIG] Tracked object deletion:",s)}function At(s,e,t){var r;let n=e.split("."),i=n.pop(),a=s;for(let o of n){if(a[o]!==void 0&&typeof a[o]!="object")throw new Error(`Invalid override path: ${e} (hit primitive at ${o})`);a[o]=(r=a[o])!=null?r:{},a=a[o]}a[i]=t}function zs(s,e){return e.split(".").reduce((t,n)=>t?t[n]:void 0,s)}function W(s){if(s===null||typeof s!="object")return s;if(s instanceof Date)return new Date(s.getTime());if(s instanceof Set)return new Set([...s].map(t=>W(t)));if(ArrayBuffer.isView(s))return s.slice();if(s instanceof Array)return s.map(t=>W(t));if(s instanceof Map){let t=new Map;return s.forEach((n,i)=>t.set(i,W(n))),t}let e={};for(let t in s)Object.prototype.hasOwnProperty.call(s,t)&&(e[t]=W(s[t]));return e}function Fe(){let s=window.__editableConfigBaseline;if(!s){let e=window.__editableConfig;if(!e)throw new Error("Cannot export: no config loaded");return ks(e)}return ks(s)}function ks(s){let e={objects:{},scenes:{},engine:W(s.engine||{})},t=s.objects;if(t instanceof Map)t.forEach((a,r)=>{e.objects[r]=W(a)});else if(t&&typeof t=="object")for(let a in t)e.objects[a]=W(t[a]);let n=s.scenes;if(n instanceof Map)n.forEach((a,r)=>{e.scenes[r]=W(a)});else if(n&&typeof n=="object")for(let a in n)e.scenes[a]=W(n[a]);let i=X();for(let a of i)a.objectId?(e.objects[a.objectId]||(e.objects[a.objectId]={}),At(e.objects[a.objectId],a.path,a.value)):a.sceneId?(e.scenes[a.sceneId]||(e.scenes[a.sceneId]={}),At(e.scenes[a.sceneId],a.path,a.value)):At(e.engine,a.path,a.value);return e}function Ie(){let s=X(),e=new Set;for(let t of s)t.objectId?e.add(t.objectId):e.add("__engine__");return{modifiedObjects:Array.from(e),overrideCount:s.length,hasChanges:s.length>0,overrides:s}}async function hn(s){let e=Fe(),t={};for(let[i,a]of Object.entries(e.objects)){let r=a,o=i;/^(json\.|ui\.|effects\.|engine\.)/.test(o)||(o=`json.${i}`),r&&typeof r=="object"&&(r.identity||(r.identity={}),r.identity.id=o),t[`objects/${o}.json`]=r}e.engine&&(e.engine.runtime&&(t["engine/engine.runtime.json"]=e.engine.runtime),e.engine.assets&&(t["engine/engine.assets.json"]=e.engine.assets),e.engine.splash&&(t["engine/engine.splash.json"]=e.engine.splash),e.engine.loading&&(t["engine/engine.loading.json"]=e.engine.loading),e.engine.start&&(t["engine/engine.start.json"]=e.engine.start),e.engine.tutorial&&(t["engine/engine.tutorial.json"]=e.engine.tutorial),e.engine.endgame&&(t["engine/engine.endgame.json"]=e.engine.endgame),!e.engine.runtime&&!e.engine.assets&&(t["engine/engine.json"]=e.engine));for(let[i,a]of Object.entries(e.scenes)){let r=i.startsWith("scene.")?i:`scene.${i}`;t[`scenes/${r}.json`]=a}let n=await fetch("/api/apply",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:t,assets:{},hadCacheAtApply:X().length>0,versionName:s})});if(!n.ok){let i=await n.json();throw new Error(`Apply failed: ${i.error||"Unknown error"}`)}ne();try{let i=cn();i&&(window.__editableConfigBaseline=W(i))}catch{}localStorage.setItem("handler_last_applied",Date.now().toString()),console.log("[Config Persistence] \u2705 Applied to disk successfully")}function kt(){ne(),window.location.reload()}async function fn(){if(!confirm("This will restore all configs to their original state. All uncommitted changes in cache AND applied changes will be lost. Continue?"))return;let e=await fetch("/api/reset-to-original",{method:"POST"});if(!e.ok){let t=await e.json();throw new Error(`Reset failed: ${t.error||"Unknown error"}`)}ne(),window.location.reload()}var Ms,_i,_s,J=he(()=>{"use strict";Ms="handler_preview_override_mode";if(typeof window!="undefined"){let s=window.localStorage.getItem(Ms);window.__enableConfigOverrides=s===null?!0:s==="true"}_i=500;_s={getCurrentConfig(){return window.__editableConfig||null},getChanges(){return window.__configChanges||[]},clearChanges(){window.__configChanges=[],window.__configChangeRedo=[]}}});function Fo(s,e){try{if(typeof s=="object"&&s!==null)return s;if(typeof s!="string")return null;if(s.startsWith("data:")){let n=s.indexOf(",");if(n===-1)return null;let i=s.slice(0,n);if(!i.includes("application/json")&&!i.includes("text/plain"))return null;let a=s.slice(n+1),r=i.includes("base64")?typeof atob=="function"?atob(a):a:decodeURIComponent(a);return JSON.parse(r)}let t=s.trim();return t.startsWith("{")||t.startsWith("[")?JSON.parse(s):null}catch{return null}}function Bo(s){if(typeof window=="undefined"||!window.INLINE_ASSETS)return null;let e=window.INLINE_ASSETS,t=s.replace(/^\.\/+/,""),n=t.split("/").pop()||t,i=[t,n,t.replace(/\.json$/,""),n.replace(/\.json$/,"")];for(let a of i){let r=e[a];if(r){let o=Fo(r,a);if(o!==null)return o}}return null}async function It(s){if(Ri.has(s)&&!zi)return console.log(`[CONFIG] Using cached config for: "${s}"`),Ri.get(s);if(console.log(`[CONFIG] loadConfigFile called with: "${s}", MODE: ${F.toUpperCase()}, CACHE: ${zi?"DISABLED":"ENABLED"}`),F==="publish"){let n=Bo(s);return n?(console.log(`[CONFIG] \u2713 Loaded ${s} via INLINE_ASSETS`),n):(console.log(`[CONFIG] \u2139\uFE0F Optional config ${s} not in INLINE_ASSETS, skipping fetch in publish mode`),{})}F==="brand"||console.log(`[CONFIG] DEV MODE: Trying nested paths first, then flattened for "${s}"`);let e;F==="brand"?e=[`./${s.split("/").pop()||s}`,`./${s}`,`./${s.replace(/^configs\//,"")}`,`./${s.replace(/^configs\//,"").replace(/\//g,".")}`]:e=[`./${s}`,`./${s.replace(/^configs\//,"")}`,`./${s.replace(/^configs\//,"").replace(/\//g,".")}`],e=Array.from(new Set(e.flatMap(n=>n.startsWith("./")?[n,`/${n.slice(2)}`]:n.startsWith("/")?[n]:[n,`/${n}`]))),console.log("[CONFIG] Will try candidates:",e);let t=(async()=>{let n=zi?"no-store":"force-cache";for(let i of e)try{let a=await fetch(i,{cache:n});if(!a.ok)continue;let r=await a.json();return console.log(`[CONFIG] \u2713 Loaded ${s} via ${i}`,r),r}catch(a){console.warn(`[CONFIG] \u2717 Failed to load ${i} (mode: ${F}):`,a)}return console.warn(`[CONFIG] \u2717 All attempts failed for ${s}; using defaults`),{}})();return Ri.set(s,t),t}async function mn(){console.log("[CONFIG] Loading component schemas...");let s=["components/identity.schema.json","components/transform.schema.json","components/render.schema.json","components/motion.schema.json","components/effects.schema.json","components/interaction.schema.json","components/gameplay.rules.schema.json","components/gameplay.tuning.schema.json","components/visibility.schema.json","components/audio.schema.json","components/physics.schema.json","components/ui.schema.json"],e=new Map;for(let t of s)try{let n=F==="publish"||F==="brand"?t.split("/").pop()||t:`configs/${t}`,i=await It(n);i.component&&(e.set(i.component,i),console.log(`[CONFIG] \u2713 Schema loaded: ${i.component} ${F==="publish"||F==="brand"?"(flattened)":"(nested)"}`))}catch(n){console.warn(`[CONFIG] \u2717 Failed to load schema ${t}:`,n)}return console.log(`[CONFIG] Loaded ${e.size} component schemas`),e}async function je(s){console.log(`[CONFIG] Loading object config: ${s}`);let e=F==="publish"||F==="brand"?`${s}.json`:`configs/objects/${s}.json`;return await It(e)}async function bn(s){let e=new Map;if(s.objects&&Array.isArray(s.objects)){for(let t of s.objects)if(t.enabled&&t.object_config)try{let n=t.instance_id;/^(json\.|ui\.|effects\.|engine\.)/.test(n)||(n=`json.${n}`);let i=await je(n);(!i||Object.keys(i).length===0)&&n!==t.instance_id&&(i=await je(t.instance_id)),!i||Object.keys(i).length===0?(console.log(`[CONFIG] No instance snapshot for ${t.instance_id}, using template ${t.object_config}`),i=await je(t.object_config)):console.log(`[CONFIG] \u2713 Loaded instance snapshot for ${t.instance_id}`),e.set(t.instance_id,{...i,instance_id:t.instance_id,object_config:t.object_config})}catch(n){console.warn(`Failed to load object ${t.object_config}:`,n)}}return e}async function yn(){console.log("[CONFIG] Loading engine configs...");let s=["runtime","assets","splash","loading","start","tutorial","endgame"],e=await Promise.all(s.map(n=>{let i=`engine.${n}.json`,a=F==="publish"||F==="brand"?i:`configs/engine/${i}`;return It(a)})),t=Object.fromEntries(s.map((n,i)=>[n,e[i]]));return console.log("[CONFIG] Engine configs loaded:",Object.fromEntries(s.map(n=>{var r;let i=(r=t[n])!=null?r:{},a=Object.keys(i);return[n,a.length>0?a:"empty"]}))),t}async function $i(){return await It(F==="publish"||F==="brand"?"game.prompt.json":"configs/engine/game.prompt.json")}async function vn(s="scene.main"){console.log(`[CONFIG] Loading scene config: ${s}`);let e=F==="publish"||F==="brand"?`${s}.json`:`configs/scenes/${s}.json`;return await It(e)}function it(s,e){let t=[];if(!s.identity)return t.push("Missing required identity component"),{valid:!1,errors:t};let n=e.get("identity");if(n)for(let i of n.required||[])s.identity[i]||t.push(`Missing required identity field: ${i}`);for(let[i,a]of Object.entries(s)){if(i==="identity")continue;let r=e.get(i);if(r&&a&&typeof a=="object"){let o=a;for(let l of r.required||[])o[l]===void 0&&t.push(`Missing required field in ${i}: ${l}`);if(r.constraints&&typeof r.constraints=="object")for(let[l,c]of Object.entries(r.constraints)){let d=o[l];if(d!==void 0&&c&&typeof c=="object"){let p=c;typeof d=="number"&&(p.min!==void 0&&d<p.min&&t.push(`${i}.${l} value ${d} is below minimum ${p.min}`),p.max!==void 0&&d>p.max&&t.push(`${i}.${l} value ${d} is above maximum ${p.max}`))}}}}return{valid:t.length===0,errors:t}}function Ue(s,e){let t={...s},n=["identity","transform","render"];for(let[i,a]of e.entries())a.defaults&&Object.keys(a.defaults).length>0&&(n.includes(i)||t[i])&&(t[i]||(t[i]={}),t[i]={...a.defaults,...t[i]});return t}function ie(s,e,t,n){return typeof s!="number"||!Number.isFinite(s)?e:Math.min(Math.max(s,t),n)}function Ds(s,e){if(Array.isArray(s))return{x:ie(s[0],e.x,-2e3,2e3),y:ie(s[1],e.y,-2e3,2e3)};if(!s||typeof s!="object")return e;let{x:t,y:n}=s;return{x:ie(t,e.x,-2e3,2e3),y:ie(n,e.y,-2e3,2e3)}}function Uo(s,e){if(Array.isArray(s))return{x:ie(s[0],e.x,0,1),y:ie(s[1],e.y,0,1)};if(!s||typeof s!="object")return e;let{x:t,y:n}=s;return{x:ie(t,e.x,0,1),y:ie(n,e.y,0,1)}}function Go(s){if(Array.isArray(s))return{x:ie(s[0],.5,-10,10),y:ie(s[1],.5,-10,10)};if(s&&typeof s=="object"){let{x:e,y:t}=s;return{x:ie(e,.5,-10,10),y:ie(t,.5,-10,10)}}return typeof s=="string"?s:null}async function xe(s="scene.main",e){var l,c,d,p,u,g,f,h,m,b,y,v,w,E;console.log("[CONFIG] ===== Starting Object-Centric Config Load =====");let t=await mn(),n=X();n.length>0&&console.log(`[CONFIG] Applying ${n.length} active overrides`);let i=await vn(s);console.log(`[CONFIG] Scene config loaded: ${((l=i.objects)==null?void 0:l.length)||0} objects`);let a=await yn();console.log("[CONFIG] Loading object configs...");let r=await bn(i);console.log(`[CONFIG] Loaded ${r.size} object configs:`,Array.from(r.keys()));for(let[j,z]of r.entries()){let S=Ue(z,t),P=it(S,t);P.valid||console.warn(`Object ${j} validation errors:`,P.errors),(c=S.transform)!=null&&c.position&&(S.transform.position=Ds(S.transform.position,{x:0,y:0})),(d=S.transform)!=null&&d.offset&&(S.transform.offset=Ds(S.transform.offset,{x:0,y:0})),((p=S.transform)==null?void 0:p.anchor)!==void 0&&(S.transform.anchor=Go(S.transform.anchor)),((u=S.transform)==null?void 0:u.position_ratio)!==void 0&&S.transform.position_ratio!==null&&(S.transform.position_ratio=Uo(S.transform.position_ratio,{x:.5,y:.5})),r.set(j,S)}if(e){if(e.objects)for(let[j,z]of e.objects.entries())r.set(j,z);e.engine&&(a.runtime={...a.runtime,...e.engine.runtime},a.assets={...a.assets,...e.engine.assets},a.splash={...(g=a.splash)!=null?g:{},...(f=e.engine.splash)!=null?f:{}})}let o={objects:r,engine:a,scene:i,schemas:t,theme:{background_color:"#ffffff",text_color:"#000000",square_color:"#cccccc",cta_background:"#007bff",cta_text:"#ffffff"},gameplay:{}};return typeof window!="undefined"&&(window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Ue(o,t))),n.length>0&&Tt()&&ke(n,{silent:!0,persist:!1}),console.log("[CONFIG] ===== Object-Centric Config Load Complete ====="),console.log("[CONFIG] Summary:",{schemas:Array.from(t.keys()),objects:Array.from(r.keys()),engine:{runtime:Object.keys((h=a.runtime)!=null?h:{}),assets:Object.keys((m=a.assets)!=null?m:{}),splash:Object.keys((b=a.splash)!=null?b:{}),loading:Object.keys((y=a.loading)!=null?y:{}),start:Object.keys((v=a.start)!=null?v:{}),tutorial:Object.keys((w=a.tutorial)!=null?w:{}),endgame:Object.keys((E=a.endgame)!=null?E:{})},scene:i.scene_id||"unknown"}),o}function Di(s){var t,n,i,a,r,o,l,c,d,p,u,g,f,h,m,b,y,v,w,E,j,z,S,P,R,T,A,M,k,C,x,I,L;let e={gameplay:{},ui:{},theme:{},assets:{}};for(let[_,O]of s.objects.entries()){let H=((t=O.identity)==null?void 0:t.id)||_;H.includes("character")&&(e.gameplay.character_pos=((n=O.transform)==null?void 0:n.position)||{x:0,y:0},e.gameplay.character_scale=((i=O.transform)==null?void 0:i.scale)||1,e.gameplay.character_anim_speed=((r=(a=O.gameplay)==null?void 0:a.tuning)==null?void 0:r.anim_speed)||.003,e.gameplay.character_relief_scale=((l=(o=O.gameplay)==null?void 0:o.tuning)==null?void 0:l.relief_scale)||1.22,e.gameplay.character_relief_speed=((d=(c=O.gameplay)==null?void 0:c.tuning)==null?void 0:d.relief_speed)||.22),(H.includes("gun")||H.includes("flame"))&&(e.gameplay.gun=O.gun||{},e.gameplay.gunmuzzle=((p=O.effects)==null?void 0:p.gunmuzzle)||{},e.gameplay.muzzle_levels=((u=O.effects)==null?void 0:u.muzzle_levels)||{},e.gameplay.flame=((g=O.effects)==null?void 0:g.flame)||{}),H.includes("diamond")&&(e.gameplay.diamond=O),H.includes("ice")&&(e.gameplay.melt=O.melt||{},e.gameplay.melt_anchor=((f=O.transform)==null?void 0:f.melt_anchor)||{x:0,y:0},e.gameplay.melt_pos=((h=O.transform)==null?void 0:h.position)||{x:0,y:0},e.gameplay.hybrid_melting=((m=O.effects)==null?void 0:m.hybrid_melting)||{},e.gameplay.physics_chunks=((b=O.effects)==null?void 0:b.physics_chunks)||{},e.gameplay.melting_particles=((y=O.effects)==null?void 0:y.melting_particles)||{},e.gameplay.hard_ice=O.hard_ice||{}),H.includes("water")&&(e.gameplay.water_drops=O),H.includes("crack")&&(e.gameplay.crack=O),H.includes("hand")&&(e.gameplay.hand=((v=O.gameplay)==null?void 0:v.tuning)||{},e.gameplay.brush_start_pos=((w=O.transform)==null?void 0:w.brush_start_pos)||{x:0,y:-120},e.gameplay.hand_scale=((E=O.transform)==null?void 0:E.scale)||1.5),H.includes("hazard")&&(e.gameplay.hazard=((j=O.gameplay)==null?void 0:j.tuning)||{},e.gameplay.danger_pos=((z=O.transform)==null?void 0:z.danger_pos)||{x:0,y:235},e.gameplay.danger_pulse=((P=(S=O.gameplay)==null?void 0:S.tuning)==null?void 0:P.danger_pulse)||{},e.gameplay.hazard_height=((T=(R=O.gameplay)==null?void 0:R.tuning)==null?void 0:T.hazard_height)||140)}return e.gameplay.timeline=((A=s.engine.runtime)==null?void 0:A.timeline)||{},e.gameplay.drag_surface=((M=s.engine.runtime)==null?void 0:M.drag_surface)||{},e.gameplay.background=((k=s.engine.runtime)==null?void 0:k.background)||{},e.gameplay.ui_styles=((C=s.engine.runtime)==null?void 0:C.ui_styles)||{},e.gameplay.label_pulse=((x=s.engine.runtime)==null?void 0:x.label_pulse)||{},e.ui=((I=s.engine.runtime)==null?void 0:I.ui)||{},e.theme=((L=s.engine.runtime)==null?void 0:L.theme)||{},e.assets=s.engine.assets||{},e}var $s,F,Ri,zi,Hi=he(()=>{"use strict";J();$s=null,F="dev";if(typeof window!="undefined"){let s=window.__BUILD_SETTINGS__;if(s!=null&&s.buildMode)$s=s,F=s.buildMode,console.log("[CONFIG] Loaded inline build settings:",s,"buildMode:",F);else try{let e=new XMLHttpRequest;if(e.open("GET","./build-settings.json",!1),e.send(),e.status===200&&e.responseText){let t=JSON.parse(e.responseText);$s=t,F=t.buildMode||"dev",console.log("[CONFIG] Loaded build settings:",t,"buildMode:",F)}else console.log("[CONFIG] No build-settings.json found, using default buildMode:",F)}catch(e){console.log("[CONFIG] Failed to load build-settings.json:",e instanceof Error?e.message:String(e))}}console.log("[CONFIG] Final buildMode:",F);Ri=new Map,zi=F==="dev"||typeof window!="undefined"&&window.location.search.includes("hot-reload")});function Ni(s,e){let t=[];function n(i,a,r=""){if(i!==a){if(typeof i!=typeof a){t.push(`${r}: type changed`);return}if(typeof i=="object"&&i!==null&&a!==null){let o=new Set([...Object.keys(i),...Object.keys(a)]);for(let l of o){let c=r?`${r}.${l}`:l;l in i?l in a?n(i[l],a[l],c):t.push(`${c}: removed`):t.push(`${c}: added`)}}else t.push(`${r}: changed`)}}return n(s,e),t}function Fi(s,e,t,n){let i={...t};for(let[a,r]of n.entries())i[a]&&r.defaults&&(i[a]={...r.defaults,...i[a]});return i}var jt,Ge,Bi=he(()=>{"use strict";jt=class{shouldFullReload(e){return e.type==="component"||e.type==="scene"}getAffectedObjects(e){return e.type==="object"&&e.objectId?[e.objectId]:[]}},Ge=class{constructor(e=1e3){this.pollingInterval=null;this.fileHashes=new Map;this.callbacks=new Map;this.intervalMs=e}watch(e,t){this.callbacks.set(e,t),this.pollingInterval===null&&(this.pollingInterval=window.setInterval(()=>{this.checkAllFiles()},this.intervalMs))}async checkAllFiles(){for(let[e,t]of this.callbacks.entries())try{let n=`${e}?t=${Date.now()}&r=${Math.random()}`,i=await fetch(n,{cache:"no-cache",headers:{"Cache-Control":"no-cache"}});if(i.ok){let a=await i.text(),r=this.hashString(a),o=this.fileHashes.get(e);if(o&&o!==r&&console.log(`[HOT-RELOAD] File changed: ${e}`),o&&o!==r){console.log(`[HOT-RELOAD] File changed: ${e}`);let l=this.determineEventType(e);t(l),this.fileHashes.set(e,r)}else o||this.fileHashes.set(e,r)}}catch(n){console.warn(`Failed to check ${e}:`,n)}}determineEventType(e){var t,n;return e.includes("/components/")?{type:"component",path:e,componentName:(t=e.split("/").pop())==null?void 0:t.replace(".schema.json","")}:e.includes("/engine/")?{type:"engine",path:e}:e.includes("/scenes/")?{type:"scene",path:e}:e.includes("/objects/")?{type:"object",path:e,objectId:(n=e.split("/").pop())==null?void 0:n.replace(".json","")}:{type:"object",path:e}}hashString(e){let t=0;for(let n=0;n<e.length;n++){let i=e.charCodeAt(n);t=(t<<5)-t+i,t=t&t}return t.toString()}unwatch(e){this.callbacks.delete(e),this.fileHashes.delete(e)}stop(){this.pollingInterval!==null&&(clearInterval(this.pollingInterval),this.pollingInterval=null),this.callbacks.clear(),this.fileHashes.clear()}}});function Gi(s){if(typeof window=="undefined")return;let e=typeof Ui!="undefined"&&!!Ui.hot,t=window.location.search.includes("hot-reload");if(!(e||t))return;let i=null,a=!1,r=null;if(t){r=new Ge;let f=window.__configWatcher;f!=null&&f.stop&&f.stop(),window.__configWatcher=r}let o=new Set,l=f=>{var b,y;if(!r)return;let h=new Set;h.add("configs/engine/engine.runtime.json"),h.add("configs/engine/engine.assets.json"),h.add("configs/engine/engine.splash.json"),h.add("configs/scenes/scene.main.json");let m=(y=(b=f.scene)==null?void 0:b.objects)!=null?y:[];for(let v of m)v!=null&&v.object_config&&h.add(`configs/objects/${v.object_config}.json`);for(let v of o)h.has(v)||r.unwatch(v);for(let v of h)o.has(v)||r.watch(v,w=>g(w));o=h},c=new Set,d=!1,p=async f=>{let h=await je(f),m=Ue(h,s.activeConfig.schemas),b=it(m,s.activeConfig.schemas);b.valid||console.warn(`[HOT-RELOAD] ${f} validation errors:`,b.errors),await s.liveEditBridge.applyObjectConfig(f,m)};async function u(f){if(!a){a=!0;try{if(d||c.size===0){s.audioSystem.destroy();let h=await xe("scene.main");s.setActiveConfig(h),s.gameObjectManager.updateConfig(h),s.CustomAssets.updateConfig(h),await s.CustomAssets.ready();let m=s.createAudioSystem(h);s.setAudioSystem(m),window.__audioSystem=m,await m.start(),s.liveEditBridge.rebuildIndexes(),l(h),console.log(`[GAME] Hot-reload complete (${f})`)}else{let h=Array.from(c);c.clear();for(let m of h)await p(m);console.log(`[GAME] Hot-reload updated objects: ${h.join(", ")}`)}}catch(h){console.warn("[GAME] Hot-reload failed:",h)}finally{a=!1,d=!1,c.clear()}}}function g(f){f.type==="object"&&f.objectId?c.add(f.objectId):d=!0,i&&window.clearTimeout(i),i=window.setTimeout(()=>{u(f.type)},120)}e&&Ui.hot.on("config-change",()=>{g({type:"hmr"})}),t&&(l(s.activeConfig),console.log(`[GAME] Hot-reload watcher enabled (${o.size} files)`))}var Ui,Hs=he(()=>{"use strict";Bi();Hi();Ui={}});var Ns={};vt(Ns,{ConfigWatcher:()=>Ge,DefaultReloadStrategy:()=>jt,applyDefaults:()=>Ue,diffConfigs:()=>Ni,loadAllObjectConfigs:()=>bn,loadComponentSchemas:()=>mn,loadEngineConfig:()=>yn,loadGamePromptConfig:()=>$i,loadObjectCentricConfig:()=>xe,loadObjectConfig:()=>je,loadSceneConfig:()=>vn,rehydrateObject:()=>Fi,setupHotReload:()=>Gi,toLegacyFormat:()=>Di,validateObjectConfig:()=>it});var wn=he(()=>{"use strict";Hi();Bi();Hs()});var Cr={};vt(Cr,{AssetEditorModal:()=>Sa});var Sa,Ca=he(()=>{"use strict";Sa=class{constructor(){this.modal=null;this.currentObjectId=null;this.currentPath=null;this.currentAsset="";this.onApplyCallback=null}show(e,t,n,i){this.currentObjectId=e,this.currentPath=t,this.currentAsset=n,this.onApplyCallback=i,this.createModal(e,n),document.body.appendChild(this.modal),this.attachModalListeners()}createModal(e,t){let n=document.createElement("div");n.className="asset-editor-modal",n.innerHTML=`
1
+ "use strict";var eo=Object.create;var Qt=Object.defineProperty;var to=Object.getOwnPropertyDescriptor;var io=Object.getOwnPropertyNames;var no=Object.getPrototypeOf,ao=Object.prototype.hasOwnProperty;var be=(s,e)=>()=>(s&&(e=s(s=0)),e);var Et=(s,e)=>{for(var t in e)Qt(s,t,{get:e[t],enumerable:!0})},Ka=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of io(e))!ao.call(s,n)&&n!==t&&Qt(s,n,{get:()=>e[n],enumerable:!(i=to(e,n))||i.enumerable});return s};var tt=(s,e,t)=>(t=s!=null?eo(no(s)):{},Ka(e||!s||!s.__esModule?Qt(t,"default",{value:s,enumerable:!0}):t,s)),so=s=>Ka(Qt({},"__esModule",{value:!0}),s);var ye,Ln=be(()=>{"use strict";ye=class{static get(e){var t;return(t=this.store.get(e))==null?void 0:t.data}static set(e,t){this.store.set(e,{data:t})}static has(e){return this.store.has(e)}static clear(){this.store.clear()}};ye.store=new Map});function ho(){var s,e;try{let t=typeof window!="undefined"&&(document.querySelector('script[src*="inline-assets.js"]')||((e=(s=document.querySelector("script"))==null?void 0:s.textContent)==null?void 0:e.includes("inline-assets.js"))||window.INLINE_ASSETS),i=typeof window!="undefined"&&document.querySelector('link[href*="assets/"], script[src*="assets/"]');return!!(t&&!i)}catch{return!1}}async function fo(){try{if(typeof window!="undefined"){let s=await fetch("./build-settings.json");if(s.ok){let e=await s.json();return console.log("[AssetLoader] Loaded build settings:",e),e}}}catch{}return null}function mo(){try{if(typeof window!="undefined"){let s=new XMLHttpRequest;if(s.open("GET","./build-settings.json",!1),s.send(),s.status===200&&s.responseText){let e=JSON.parse(s.responseText);return console.log("[AssetLoader] Loaded build settings (sync):",e),e}}}catch{}return null}async function bo(){if(console.log(`[AssetLoader] getInlineAssets() called - Effective mode: ${U}`),Object.keys(ve).length>0)return console.log("[AssetLoader] Returning cached inline assets:",Object.keys(ve)),ve;if(typeof window!="undefined"&&window.INLINE_ASSETS)return console.log("[AssetLoader] Using pre-loaded INLINE_ASSETS from window:",Object.keys(window.INLINE_ASSETS)),ve={...window.INLINE_ASSETS},ve;if(!(U==="publish"&&ce!==!1))return console.log("[AssetLoader] Inline assets disabled for this build mode."),ve;if(!kn){let e=typeof window!="undefined"?new URL("inline-assets.js",window.location.href).href:"./inline-assets.js";console.log("[AssetLoader] Loading inline assets from:",e),kn=(async()=>{try{try{let a=await import(e+"?t="+Date.now());if(a.INLINE_ASSETS)return console.log("[AssetLoader] Loaded INLINE_ASSETS via ES module:",Object.keys(a.INLINE_ASSETS)),a.INLINE_ASSETS}catch(a){console.warn("[AssetLoader] ES module import failed, trying text parse:",a)}let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);let i=await t.text();console.log("[AssetLoader] Received JS code, length:",i.length);let n=i.match(/export\s+const\s+INLINE_ASSETS\s*=\s*({[\s\S]*?});?\s*$/m);if(n)try{let a=n[1];console.log("[AssetLoader] Found INLINE_ASSETS export, parsing...");let r=new Function("return "+a)();return console.log("[AssetLoader] Parsed inline assets:",Object.keys(r)),r}catch(a){return console.warn("[AssetLoader] Failed to parse inline assets:",a),{}}else return console.warn("[AssetLoader] INLINE_ASSETS export not found in response"),console.log("[AssetLoader] JS code preview:",i.substring(0,500)),{}}catch(t){return console.warn("[AssetLoader] Failed to load inline assets:",t),{}}})()}return ve=await kn,console.log("[AssetLoader] Final inline assets cache:",Object.keys(ve)),ve}function In(s){return s===null||typeof s!="object"||(Object.freeze(s),Object.values(s).forEach(e=>In(e))),s}function yo(s=64,e=64,t=16711680){let i=document.createElement("canvas");i.width=s,i.height=e;let n=i.getContext("2d");return n.fillStyle=`#${t.toString(16).padStart(6,"0")}`,n.fillRect(0,0,s,e),n.strokeStyle="#000",n.strokeRect(0,0,s,e),n.fillStyle="#fff",n.font="10px sans-serif",n.textAlign="center",n.fillText("MISSING",s/2,e/2),we.Texture.from(i)}function Pn(s,e){ks.set(s,e)}var we,Ts,Ls,Ne,U,ce,Ie,ve,kn,ks,Fe,ni=be(()=>{"use strict";we=require("pixi.js");Ln();Ts=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Ls=ho(),Ne=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,U=Ls?"publish":Ts,ce=Ne==null?void 0:Ne.assetsInlined;Ne!=null&&Ne.buildMode&&(U=Ne.buildMode,console.log(`[AssetLoader] Build mode overridden by inline settings: ${U}`));Ie=mo();Ie!=null&&Ie.buildMode&&(U=Ie.buildMode,console.log(`[AssetLoader] Build mode overridden by sync settings: ${U}`));(Ie==null?void 0:Ie.assetsInlined)!==void 0&&(ce=Ie.assetsInlined);fo().then(s=>{s!=null&&s.buildMode&&s.buildMode!==U&&(U=s.buildMode,console.log(`[AssetLoader] Build mode overridden by settings: ${U}`)),(s==null?void 0:s.assetsInlined)!==void 0&&(ce=s.assetsInlined)}).catch(()=>{});console.log(`[AssetLoader] MODULE LOADED - Compile: ${Ts}, Runtime: ${Ls?"publish":"dev"}, Effective: ${U}`);ve={},kn=null;ks=new Map;Fe=class{static async load(e,t,i,n){let a=`${e}:${t.path}`,r=ye.get(a);if(r!==void 0)return r;console.log(`[AssetLoader] Loading asset: ${e}, type: ${t.type}, Effective mode: ${U}`),console.log(`[AssetLoader] Window defined: ${typeof window!="undefined"}, INLINE_ASSETS exists: ${!!(typeof window!="undefined"&&window.INLINE_ASSETS)}, keys: ${typeof window!="undefined"&&window.INLINE_ASSETS?Object.keys(window.INLINE_ASSETS).length:"N/A"}`);let o=await bo(),l=o[e];if(!l&&n&&(l=o[n],l&&console.log(`[AssetLoader] Found inline data for ${e} using configId: ${n}`)),!l&&t.path){let p=t.path.split("/");if(p.length>=2){let u=p[p.length-1].split(".")[0];o[u]&&(l=o[u],console.log(`[AssetLoader] Found inline data for ${e} using assetName: ${u}`))}}if(console.log("[AssetLoader] Inline data for",e,":",l?"FOUND":"NOT FOUND"),U==="publish"&&ce!==!1&&(console.log("[AssetLoader] \u26A0\uFE0F PUBLISH MODE DETECTED - inline assets are MANDATORY"),!l))throw new Error(`[AssetLoader] PUBLISH MODE: Inline asset required but NOT FOUND for object: ${e}, path: ${t.path}`);let d=ks.get(t.type);if(d)try{let p=await d(t.path,l,e,i);return ye.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}try{let p;switch(t.type){case"image":p=await this.loadImage(t.path,l);break;case"json":p=await this.loadJSON(t.path,l),p=In(p);break;default:throw new Error(`Unknown asset type: ${t.type}`)}return ye.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}}static async loadImage(e,t){let i=U==="publish",n=i&&ce!==!1;if(console.log(`[AssetLoader] loadImage - Effective mode: ${U}, isPublishMode: ${i}, inlineData: ${t?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for object. Path: ${e}`);if(typeof t!="string"||!t.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof t}`);try{return await we.Assets.load(t)}catch(a){throw console.error("[AssetLoader] Failed to load texture from data URI:",a),a}}if(t&&typeof t=="string"&&t.startsWith("data:"))try{return await we.Assets.load(t)}catch(a){return console.error("[AssetLoader] Failed to load texture from data URI, falling back to path:",a),await we.Assets.load(e)}return await we.Assets.load(e)}static async loadJSON(e,t){let i=U==="publish",n=i&&ce!==!1;if(console.log(`[AssetLoader] loadJSON - Effective mode: ${U}, isPublishMode: ${i}, inlineData: ${t?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${e}`);if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let r=atob(t.split(",")[1]);return JSON.parse(r)}return JSON.parse(t)}if(t){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let r=atob(t.split(",")[1]);return JSON.parse(r)}return JSON.parse(t)}let a=await fetch(e);if(!a.ok)throw new Error(`JSON fetch failed: ${e}`);return a.json()}static handleFailure(e,t,i){if(U==="dev"){let a=t==="image"?yo():In({__placeholder:!0,type:t});return ye.set(e+":"+((i==null?void 0:i.path)||"missing"),a),a}throw i}};Pn("image",async(s,e)=>{let t=U==="publish",i=t&&ce!==!1,n=U==="brand",a=t&&ce===!1;if(console.log(`[AssetLoader] registerType('image') - Effective mode: ${U}, isPublishMode: ${t}, isBrandMode: ${n}, inlineData: ${e?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${s}`);if(typeof e!="string"||!e.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof e}`);return we.Assets.load(e)}let r=s;return(n||a)&&s&&!s.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(r=s,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${s}" as-is`)):(r=`assets/${s}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${s}" -> "${r}"`))),we.Assets.load(e||r)});Pn("json",async(s,e)=>{let t=U==="publish",i=t&&ce!==!1,n=U==="brand",a=t&&ce===!1;if(console.log(`[AssetLoader] registerType('json') - Effective mode: ${U}, isPublishMode: ${t}, isBrandMode: ${n}, inlineData: ${e?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${s}`);return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e)}let r=s;if((n||a)&&s&&!s.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(r=s,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${s}" as-is`)):(r=`assets/${s}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${s}" -> "${r}"`))),e)return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e);let o=await fetch(r);if(!o.ok)throw new Error(`JSON fetch failed: ${s}`);return o.json()})});var Ps={};Et(Ps,{AssetTextures:()=>pe,initAssetTextures:()=>_n});function _n(s,e){Is.init(s,e),typeof window!="undefined"&&(window.__AssetTextures=pe)}var jn,Is,pe,st=be(()=>{"use strict";ni();jn=class{constructor(){this.textures=new Map;this.readyPromise=null;this.priorityReadyPromise=null;this.priorityReadyResolve=null;this.config=null;this.app=null;this.attempted=new Set;this.waiters=new Set}init(e,t){if(this.config===e&&this.app===t&&this.priorityReadyPromise){console.log("[AssetTextures] init called with same config/app; keeping existing state");return}this.textures.clear(),this.readyPromise=null,this.priorityReadyPromise=null,this.priorityReadyResolve=null,this.attempted.clear(),this.waiters.clear(),this.priorityReadyPromise=new Promise(i=>{this.priorityReadyResolve=i}),this.config=e,this.app=t,console.log("[AssetTextures] Initialized with config, cleared previous textures")}async ready(){if(this.readyPromise){await this.readyPromise;return}if(!this.config)throw new Error("[AssetTextures] Must call init() before ready() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before ready() - app is null");let e=this.config,t=this.app;return this.readyPromise=(async()=>{var r;console.log("[AssetTextures] Loading all assets...");let i=new Set(["background_loading_1"]),n=[],a=[];for(let[o,l]of e.objects.entries()){let c=(r=l.render)==null?void 0:r.asset;if(!c)continue;let d=async()=>{var p;try{let u=(p=l.identity)==null?void 0:p.id;console.log(`[AssetTextures] Loading ${c.type}: ${o} (${u})`);let g=await Fe.load(o,c,t,u);this.textures.set(o,g),console.log(`[AssetTextures] \u2713 Loaded: ${o}`)}catch(u){console.error(`[AssetTextures] \u2717 Failed to load: ${o}`,u)}finally{this.attempted.add(o);try{for(let u of Array.from(this.waiters))u()}catch{}}};i.has(o)?n.push(d()):a.push(d())}n.length>0&&(console.log("[AssetTextures] Phase 1: Loading priority assets (loading screen)..."),await Promise.all(n),console.log("[AssetTextures] Phase 1: Priority assets ready")),this.priorityReadyResolve&&this.priorityReadyResolve(),console.log("[AssetTextures] Phase 2: Loading remaining assets..."),await Promise.all(a),console.log("[AssetTextures] All textures loaded:",Array.from(this.textures.keys()))})(),this.readyPromise}async priorityReady(){return this.priorityReadyPromise?this.priorityReadyPromise:Promise.resolve()}async waitFor(e,t={}){if(!this.config)throw new Error("[AssetTextures] Must call init() before waitFor() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before waitFor() - app is null");let n=Array.from(new Set((e||[]).filter(o=>typeof o=="string"&&o))).filter(o=>{var l,c,d,p;try{let u=(d=(c=(l=this.config)==null?void 0:l.objects)==null?void 0:c.get)==null?void 0:d.call(c,o);return!!((p=u==null?void 0:u.render)!=null&&p.asset)}catch{return!1}});if(n.length===0)return;this.ready().catch(()=>{});let a=()=>n.every(o=>this.textures.has(o)||this.attempted.has(o));if(a())return;let r=typeof t.timeoutMs=="number"?t.timeoutMs:15e3;await new Promise(o=>{let l=!1,c=()=>{l||a()&&(l=!0,this.waiters.delete(c),o())};this.waiters.add(c),c(),r>0&&setTimeout(()=>{l||(l=!0,this.waiters.delete(c),console.warn("[AssetTextures] waitFor timed out; continuing",{ids:n}),o())},r)})}get(e){return this.textures.get(e)}set(e,t){this.textures.set(e,t),console.log(`[AssetTextures] Updated texture: ${e}`)}clear(){this.textures.clear(),this.readyPromise=null,console.log("[AssetTextures] Cleared all textures")}getAllIds(){return Array.from(this.textures.keys())}},Is=new jn,pe=new Proxy(Is,{get(s,e){return e in s&&typeof s[e]=="function"?s[e].bind(s):s.get(e)},set(s,e,t){return s.set(e,t),!0}})});var Ge={};Et(Ge,{applyConfigOverride:()=>ne,applyConfigOverrides:()=>Pe,applyConfigsToDisk:()=>mi,clearConfigOverrides:()=>ae,clearConfigOverridesForObject:()=>$s,configOverrideManager:()=>Ds,deepClone:()=>Y,exportConfigsAsJSON:()=>Ue,getConfigOverrides:()=>Z,getConfigStateSummary:()=>Me,getOverrideMode:()=>Mt,redoLastConfigChange:()=>fi,removeConfigOverride:()=>jt,resetToApplied:()=>_t,resetToOriginal:()=>bi,setOverrideMode:()=>Fn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Ns,undoLastConfigChange:()=>hi});function pi(){return typeof window=="undefined"?null:window.__editableConfig||null}function Dn(){return typeof window=="undefined"?null:window.__editableConfigBaseline||null}function $n(s,e){var t,i;if(!s)return null;try{if(s instanceof Map)return(t=s.get(e))!=null?t:null;if(typeof s=="object")return(i=s[e])!=null?i:null}catch{}return null}function Go(s,e,t){if(s){if(s instanceof Map){s.set(e,t);return}typeof s=="object"&&(s[e]=t)}}function Os(s,e){for(let t of e)Pt(s,t.path,t.value)}function ui(s){var o;if(typeof window=="undefined")return;let e=pi();if(!e)return;let t=Dn(),i=(o=t?$n(t.objects,s):null)!=null?o:$n(e.objects,s);if(!i)return;let n=Y(i),a=Z().filter(l=>l.objectId===s);try{Os(n,a)}catch(l){console.error("[CONFIG] Failed to reapply overrides for object",s,l);return}Go(e.objects,s,n);let r=window.applyEditableObjectConfig;if(typeof r=="function")try{r(s,n)}catch{}}function Hn(){var n;if(typeof window=="undefined")return;let s=pi();if(!(s!=null&&s.engine))return;let e=Dn(),t=Y(((n=e==null?void 0:e.engine)!=null?n:s.engine)||{}),i=Z().filter(a=>!a.objectId&&!a.sceneId);try{Os(t,i)}catch(a){console.error("[CONFIG] Failed to reapply engine overrides",a);return}try{let a=s.engine;for(let r of Object.keys(a))r in t||delete a[r];for(let[r,o]of Object.entries(t))a[r]=o}catch{s.engine=t}}function qo(){if(typeof window=="undefined")return"unknown";let s=window;return typeof s.__HANDLER_PROJECT_ID=="string"?s.__HANDLER_PROJECT_ID:"handler-default"}function Rs(){return`handler_preview_config_overrides::${qo()}`}function Vo(){if(typeof window=="undefined")return[];try{let s=window.localStorage.getItem(Rs());if(!s)return[];let e=JSON.parse(s);return Array.isArray(e)?e:[]}catch{return[]}}function gi(s){if(typeof window!="undefined")try{window.localStorage.setItem(Rs(),JSON.stringify(s))}catch{}}function Mt(){return typeof window=="undefined"?!1:window.__enableConfigOverrides===!0}function Fn(s){if(typeof window!="undefined"){window.__enableConfigOverrides=s;try{window.localStorage.setItem(zs,s?"true":"false")}catch{}}}function ne(s,e={}){var u,g;let{objectId:t,path:i,value:n}=s,{silent:a=!1,persist:r=!0,emitEvent:o=!0}=e,l=pi();if(!l){console.warn("[CONFIG] applyConfigOverride: No editable config found in window.__editableConfig");return}let c=t?(g=(u=l.objects)==null?void 0:u.get)==null?void 0:g.call(u,t):l.engine;if(!c){console.warn("[CONFIG] applyConfigOverride: Override target not found:",{objectId:t,path:i,hasObjects:!!l.objects});return}a||console.log("[CONFIG] applyConfigOverride: Target found, applying...",{objectId:t,path:i,value:n});let d;try{d=Fs(c,i),Pt(c,i,n)}catch(h){console.error("[CONFIG] applyConfigOverride failed:",{objectId:t,path:i,value:n},h);return}if(e.trackHistory!==!1){window.__configChanges=window.__configChanges||[];let h=window.__configChanges;h.push({objectId:t,path:i,oldValue:d,newValue:n,ts:Date.now()}),h.length>Nn&&h.shift(),window.__configChangeRedo=[]}if(r){let h=Z(),f=h.findIndex(m=>m.objectId===t&&m.sceneId===s.sceneId&&m.path===i);f>=0?h[f].value=n:h.push(s),window.__configOverrides=h,gi(h),Mt()||Fn(!0)}a||console.log("[CONFIG] Applied override:",s),o&&typeof window!="undefined"&&window.dispatchEvent(new CustomEvent("config:changed",{detail:s}))}function Pe(s,e={}){let t=e.emitEvent!==!1,i=[];for(let n of s)n!=null&&n.objectId&&typeof n.objectId=="string"&&i.push(n.objectId),ne(n,{...e,emitEvent:!1});if(t&&typeof window!="undefined"){let n=Array.from(new Set(i));window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch",objectIds:n,count:s.length}}))}}function ae(){window.__configOverrides=[],window.__configChanges=[],window.__configChangeRedo=[],gi([]),console.log("[CONFIG] Cleared all overrides")}function $s(s){let e=Z().filter(i=>i.objectId!==s);window.__configOverrides=e,gi(e);let t=window.__configChanges||[];window.__configChanges=t.filter(i=>i.objectId!==s),ui(s),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"clear_object",objectId:s}}))}function jt(s,e){let t=Z().filter(n=>n.objectId!==s||n.path!==e);window.__configOverrides=t,gi(t);let i=window.__configChanges||[];window.__configChanges=i.filter(n=>n.objectId!==s||n.path!==e),s?ui(s):Hn(),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"remove",objectId:s,path:e}}))}function Z(){return typeof window=="undefined"?[]:(window.__configOverrides||(window.__configOverrides=Vo()),window.__configOverrides||[])}function hi(){var a;if(typeof window=="undefined")return!1;let s=window.__configChanges||[];if(s.length===0)return!1;let e=s.pop();window.__configChangeRedo=window.__configChangeRedo||[];let t=window.__configChangeRedo;if(e.changeType==="object_create"){let{screenId:r}=e.metadata||{};return e.objectId&&r&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:r})}).catch(o=>console.error("[CONFIG] Failed to delete object on undo:",o)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Deleted object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:r,objectConfigId:o}=e.metadata||{},l=e.oldValue;return e.objectId&&r&&l&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:r,instanceId:e.objectId,objectConfigId:o||((a=l==null?void 0:l.identity)==null?void 0:a.id),config:l})}).catch(c=>console.error("[CONFIG] Failed to recreate object on undo:",c)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Recreated object",e.objectId),!0}t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType});let i=Dn(),n=!1;if(i){let r=e.objectId?$n(i.objects,e.objectId):i.engine;if(r){let o=Fs(r,e.path);JSON.stringify(o)===JSON.stringify(e.oldValue)&&(n=!0)}}return n?jt(e.objectId,e.path):(ne({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?ui(e.objectId):Hn()),console.log("[CONFIG] Undo:",e.path),!0}function fi(){var i;if(typeof window=="undefined")return!1;let s=window.__configChangeRedo||[];if(s.length===0)return!1;let e=s.pop();if(e.changeType==="object_create"){let{screenId:n,objectConfigId:a}=e.metadata||{},r=e.newValue;return e.objectId&&n&&r&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,instanceId:e.objectId,objectConfigId:a||((i=r==null?void 0:r.identity)==null?void 0:i.id),config:r})}).catch(l=>console.error("[CONFIG] Failed to recreate object on redo:",l)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Recreated object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:n}=e.metadata||{};return e.objectId&&n&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:n})}).catch(r=>console.error("[CONFIG] Failed to delete object on redo:",r)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Deleted object",e.objectId),!0}return window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType}),ne({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?ui(e.objectId):Hn(),console.log("[CONFIG] Redo:",e.path),!0}function Hs(s,e,t){var n;if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:s,path:"__object_create__",oldValue:null,newValue:t,ts:Date.now(),changeType:"object_create",metadata:{screenId:e,objectConfigId:(n=t==null?void 0:t.identity)==null?void 0:n.id}}),window.__configChangeRedo=[],i.length>Nn&&i.shift(),console.log("[CONFIG] Tracked object creation:",s)}function Ns(s,e,t){if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:s,path:"__object_delete__",oldValue:t,newValue:null,ts:Date.now(),changeType:"object_delete",metadata:{screenId:e}}),window.__configChangeRedo=[],i.length>Nn&&i.shift(),console.log("[CONFIG] Tracked object deletion:",s)}function Pt(s,e,t){var r;let i=e.split("."),n=i.pop(),a=s;for(let o of i){if(a[o]!==void 0&&typeof a[o]!="object")throw new Error(`Invalid override path: ${e} (hit primitive at ${o})`);a[o]=(r=a[o])!=null?r:{},a=a[o]}a[n]=t}function Fs(s,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,s)}function Y(s){if(s===null||typeof s!="object")return s;if(s instanceof Date)return new Date(s.getTime());if(s instanceof Set)return new Set([...s].map(t=>Y(t)));if(ArrayBuffer.isView(s))return s.slice();if(s instanceof Array)return s.map(t=>Y(t));if(s instanceof Map){let t=new Map;return s.forEach((i,n)=>t.set(n,Y(i))),t}let e={};for(let t in s)Object.prototype.hasOwnProperty.call(s,t)&&(e[t]=Y(s[t]));return e}function Ue(){let s=window.__editableConfigBaseline;if(!s){let e=window.__editableConfig;if(!e)throw new Error("Cannot export: no config loaded");return _s(e)}return _s(s)}function _s(s){let e={objects:{},scenes:{},engine:Y(s.engine||{})},t=s.objects;if(t instanceof Map)t.forEach((a,r)=>{e.objects[r]=Y(a)});else if(t&&typeof t=="object")for(let a in t)e.objects[a]=Y(t[a]);let i=s.scenes;if(i instanceof Map)i.forEach((a,r)=>{e.scenes[r]=Y(a)});else if(i&&typeof i=="object")for(let a in i)e.scenes[a]=Y(i[a]);let n=Z();for(let a of n)a.objectId?(e.objects[a.objectId]||(e.objects[a.objectId]={}),Pt(e.objects[a.objectId],a.path,a.value)):a.sceneId?(e.scenes[a.sceneId]||(e.scenes[a.sceneId]={}),Pt(e.scenes[a.sceneId],a.path,a.value)):Pt(e.engine,a.path,a.value);return e}function Me(){let s=Z(),e=new Set;for(let t of s)t.objectId?e.add(t.objectId):e.add("__engine__");return{modifiedObjects:Array.from(e),overrideCount:s.length,hasChanges:s.length>0,overrides:s}}async function mi(s){let e=Ue(),t={};for(let[n,a]of Object.entries(e.objects)){let r=a,o=n;/^(json\.|ui\.|effects\.|engine\.)/.test(o)||(o=`json.${n}`),r&&typeof r=="object"&&(r.identity||(r.identity={}),r.identity.id=o),t[`objects/${o}.json`]=r}e.engine&&(e.engine.runtime&&(t["engine/engine.runtime.json"]=e.engine.runtime),e.engine.assets&&(t["engine/engine.assets.json"]=e.engine.assets),e.engine.splash&&(t["engine/engine.splash.json"]=e.engine.splash),e.engine.loading&&(t["engine/engine.loading.json"]=e.engine.loading),e.engine.start&&(t["engine/engine.start.json"]=e.engine.start),e.engine.tutorial&&(t["engine/engine.tutorial.json"]=e.engine.tutorial),e.engine.endgame&&(t["engine/engine.endgame.json"]=e.engine.endgame),!e.engine.runtime&&!e.engine.assets&&(t["engine/engine.json"]=e.engine));for(let[n,a]of Object.entries(e.scenes)){let r=n.startsWith("scene.")?n:`scene.${n}`;t[`scenes/${r}.json`]=a}let i=await fetch("/api/apply",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:t,assets:{},hadCacheAtApply:Z().length>0,versionName:s})});if(!i.ok){let n=await i.json();throw new Error(`Apply failed: ${n.error||"Unknown error"}`)}ae();try{let n=pi();n&&(window.__editableConfigBaseline=Y(n))}catch{}localStorage.setItem("handler_last_applied",Date.now().toString()),console.log("[Config Persistence] \u2705 Applied to disk successfully")}function _t(){ae(),window.location.reload()}async function bi(){if(!confirm("This will restore all configs to their original state. All uncommitted changes in cache AND applied changes will be lost. Continue?"))return;let e=await fetch("/api/reset-to-original",{method:"POST"});if(!e.ok){let t=await e.json();throw new Error(`Reset failed: ${t.error||"Unknown error"}`)}ae(),window.location.reload()}var zs,Nn,Ds,K=be(()=>{"use strict";zs="handler_preview_override_mode";if(typeof window!="undefined"){let s=window.localStorage.getItem(zs);window.__enableConfigOverrides=s===null?!0:s==="true"}Nn=500;Ds={getCurrentConfig(){return window.__editableConfig||null},getChanges(){return window.__configChanges||[]},clearChanges(){window.__configChanges=[],window.__configChangeRedo=[]}}});function Wo(s,e){try{if(typeof s=="object"&&s!==null)return s;if(typeof s!="string")return null;if(s.startsWith("data:")){let i=s.indexOf(",");if(i===-1)return null;let n=s.slice(0,i);if(!n.includes("application/json")&&!n.includes("text/plain"))return null;let a=s.slice(i+1),r=n.includes("base64")?typeof atob=="function"?atob(a):a:decodeURIComponent(a);return JSON.parse(r)}let t=s.trim();return t.startsWith("{")||t.startsWith("[")?JSON.parse(s):null}catch{return null}}function Yo(s){if(typeof window=="undefined"||!window.INLINE_ASSETS)return null;let e=window.INLINE_ASSETS,t=s.replace(/^\.\/+/,""),i=t.split("/").pop()||t,n=[t,i,t.replace(/\.json$/,""),i.replace(/\.json$/,"")];for(let a of n){let r=e[a];if(r){let o=Wo(r,a);if(o!==null)return o}}return null}async function Ot(s){if(Bn.has(s)&&!Un)return console.log(`[CONFIG] Using cached config for: "${s}"`),Bn.get(s);if(console.log(`[CONFIG] loadConfigFile called with: "${s}", MODE: ${B.toUpperCase()}, CACHE: ${Un?"DISABLED":"ENABLED"}`),B==="publish"){let i=Yo(s);return i?(console.log(`[CONFIG] \u2713 Loaded ${s} via INLINE_ASSETS`),i):(console.log(`[CONFIG] \u2139\uFE0F Optional config ${s} not in INLINE_ASSETS, skipping fetch in publish mode`),{})}B==="brand"||console.log(`[CONFIG] DEV MODE: Trying nested paths first, then flattened for "${s}"`);let e;B==="brand"?e=[`./${s.split("/").pop()||s}`,`./${s}`,`./${s.replace(/^configs\//,"")}`,`./${s.replace(/^configs\//,"").replace(/\//g,".")}`]:e=[`./${s}`,`./${s.replace(/^configs\//,"")}`,`./${s.replace(/^configs\//,"").replace(/\//g,".")}`],e=Array.from(new Set(e.flatMap(i=>i.startsWith("./")?[i,`/${i.slice(2)}`]:i.startsWith("/")?[i]:[i,`/${i}`]))),console.log("[CONFIG] Will try candidates:",e);let t=(async()=>{let i=Un?"no-store":"force-cache";for(let n of e)try{let a=await fetch(n,{cache:i});if(!a.ok)continue;let r=await a.json();return console.log(`[CONFIG] \u2713 Loaded ${s} via ${n}`,r),r}catch(a){console.warn(`[CONFIG] \u2717 Failed to load ${n} (mode: ${B}):`,a)}return console.warn(`[CONFIG] \u2717 All attempts failed for ${s}; using defaults`),{}})();return Bn.set(s,t),t}async function yi(){console.log("[CONFIG] Loading component schemas...");let s=["components/identity.schema.json","components/transform.schema.json","components/render.schema.json","components/motion.schema.json","components/effects.schema.json","components/interaction.schema.json","components/gameplay.rules.schema.json","components/gameplay.tuning.schema.json","components/visibility.schema.json","components/audio.schema.json","components/physics.schema.json","components/ui.schema.json"],e=new Map;for(let t of s)try{let i=B==="publish"||B==="brand"?t.split("/").pop()||t:`configs/${t}`,n=await Ot(i);n.component&&(e.set(n.component,n),console.log(`[CONFIG] \u2713 Schema loaded: ${n.component} ${B==="publish"||B==="brand"?"(flattened)":"(nested)"}`))}catch(i){console.warn(`[CONFIG] \u2717 Failed to load schema ${t}:`,i)}return console.log(`[CONFIG] Loaded ${e.size} component schemas`),e}async function je(s){console.log(`[CONFIG] Loading object config: ${s}`);let e=B==="publish"||B==="brand"?`${s}.json`:`configs/objects/${s}.json`;return await Ot(e)}async function vi(s){let e=new Map;if(s.objects&&Array.isArray(s.objects)){for(let t of s.objects)if(t.enabled&&t.object_config)try{let i=t.instance_id;/^(json\.|ui\.|effects\.|engine\.)/.test(i)||(i=`json.${i}`);let n=await je(i);(!n||Object.keys(n).length===0)&&i!==t.instance_id&&(n=await je(t.instance_id)),!n||Object.keys(n).length===0?(console.log(`[CONFIG] No instance snapshot for ${t.instance_id}, using template ${t.object_config}`),n=await je(t.object_config)):console.log(`[CONFIG] \u2713 Loaded instance snapshot for ${t.instance_id}`),e.set(t.instance_id,{...n,instance_id:t.instance_id,object_config:t.object_config})}catch(i){console.warn(`Failed to load object ${t.object_config}:`,i)}}return e}async function wi(){console.log("[CONFIG] Loading engine configs...");let s=["runtime","assets","splash","loading","start","tutorial","endgame"],e=await Promise.all(s.map(i=>{let n=`engine.${i}.json`,a=B==="publish"||B==="brand"?n:`configs/engine/${n}`;return Ot(a)})),t=Object.fromEntries(s.map((i,n)=>[i,e[n]]));return console.log("[CONFIG] Engine configs loaded:",Object.fromEntries(s.map(i=>{var r;let n=(r=t[i])!=null?r:{},a=Object.keys(n);return[i,a.length>0?a:"empty"]}))),t}async function Gn(){return await Ot(B==="publish"||B==="brand"?"game.prompt.json":"configs/engine/game.prompt.json")}async function xi(s="scene.main"){console.log(`[CONFIG] Loading scene config: ${s}`);let e=B==="publish"||B==="brand"?`${s}.json`:`configs/scenes/${s}.json`;return await Ot(e)}function ot(s,e){let t=[];if(!s.identity)return t.push("Missing required identity component"),{valid:!1,errors:t};let i=e.get("identity");if(i)for(let n of i.required||[])s.identity[n]||t.push(`Missing required identity field: ${n}`);for(let[n,a]of Object.entries(s)){if(n==="identity")continue;let r=e.get(n);if(r&&a&&typeof a=="object"){let o=a;for(let l of r.required||[])o[l]===void 0&&t.push(`Missing required field in ${n}: ${l}`);if(r.constraints&&typeof r.constraints=="object")for(let[l,c]of Object.entries(r.constraints)){let d=o[l];if(d!==void 0&&c&&typeof c=="object"){let p=c;typeof d=="number"&&(p.min!==void 0&&d<p.min&&t.push(`${n}.${l} value ${d} is below minimum ${p.min}`),p.max!==void 0&&d>p.max&&t.push(`${n}.${l} value ${d} is above maximum ${p.max}`))}}}}return{valid:t.length===0,errors:t}}function qe(s,e){let t={...s},i=["identity","transform","render"];for(let[n,a]of e.entries())a.defaults&&Object.keys(a.defaults).length>0&&(i.includes(n)||t[n])&&(t[n]||(t[n]={}),t[n]={...a.defaults,...t[n]});return t}function se(s,e,t,i){return typeof s!="number"||!Number.isFinite(s)?e:Math.min(Math.max(s,t),i)}function Us(s,e){if(Array.isArray(s))return{x:se(s[0],e.x,-2e3,2e3),y:se(s[1],e.y,-2e3,2e3)};if(!s||typeof s!="object")return e;let{x:t,y:i}=s;return{x:se(t,e.x,-2e3,2e3),y:se(i,e.y,-2e3,2e3)}}function Ko(s,e){if(Array.isArray(s))return{x:se(s[0],e.x,0,1),y:se(s[1],e.y,0,1)};if(!s||typeof s!="object")return e;let{x:t,y:i}=s;return{x:se(t,e.x,0,1),y:se(i,e.y,0,1)}}function Xo(s){if(Array.isArray(s))return{x:se(s[0],.5,-10,10),y:se(s[1],.5,-10,10)};if(s&&typeof s=="object"){let{x:e,y:t}=s;return{x:se(e,.5,-10,10),y:se(t,.5,-10,10)}}return typeof s=="string"?s:null}async function Ce(s="scene.main",e){var l,c,d,p,u,g,h,f,m,b,y,v,w,E;console.log("[CONFIG] ===== Starting Object-Centric Config Load =====");let t=await yi(),i=Z();i.length>0&&console.log(`[CONFIG] Applying ${i.length} active overrides`);let n=await xi(s);console.log(`[CONFIG] Scene config loaded: ${((l=n.objects)==null?void 0:l.length)||0} objects`);let a=await wi();console.log("[CONFIG] Loading object configs...");let r=await vi(n);console.log(`[CONFIG] Loaded ${r.size} object configs:`,Array.from(r.keys()));for(let[P,M]of r.entries()){let x=qe(M,t),_=ot(x,t);_.valid||console.warn(`Object ${P} validation errors:`,_.errors),(c=x.transform)!=null&&c.position&&(x.transform.position=Us(x.transform.position,{x:0,y:0})),(d=x.transform)!=null&&d.offset&&(x.transform.offset=Us(x.transform.offset,{x:0,y:0})),((p=x.transform)==null?void 0:p.anchor)!==void 0&&(x.transform.anchor=Xo(x.transform.anchor)),((u=x.transform)==null?void 0:u.position_ratio)!==void 0&&x.transform.position_ratio!==null&&(x.transform.position_ratio=Ko(x.transform.position_ratio,{x:.5,y:.5})),r.set(P,x)}if(e){if(e.objects)for(let[P,M]of e.objects.entries())r.set(P,M);e.engine&&(a.runtime={...a.runtime,...e.engine.runtime},a.assets={...a.assets,...e.engine.assets},a.splash={...(g=a.splash)!=null?g:{},...(h=e.engine.splash)!=null?h:{}})}let o={objects:r,engine:a,scene:n,schemas:t,theme:{background_color:"#ffffff",text_color:"#000000",square_color:"#cccccc",cta_background:"#007bff",cta_text:"#ffffff"},gameplay:{}};return typeof window!="undefined"&&(window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=qe(o,t))),i.length>0&&Mt()&&Pe(i,{silent:!0,persist:!1}),console.log("[CONFIG] ===== Object-Centric Config Load Complete ====="),console.log("[CONFIG] Summary:",{schemas:Array.from(t.keys()),objects:Array.from(r.keys()),engine:{runtime:Object.keys((f=a.runtime)!=null?f:{}),assets:Object.keys((m=a.assets)!=null?m:{}),splash:Object.keys((b=a.splash)!=null?b:{}),loading:Object.keys((y=a.loading)!=null?y:{}),start:Object.keys((v=a.start)!=null?v:{}),tutorial:Object.keys((w=a.tutorial)!=null?w:{}),endgame:Object.keys((E=a.endgame)!=null?E:{})},scene:n.scene_id||"unknown"}),o}function qn(s){var t,i,n,a,r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,E,P,M,x,_,O,T,A,j,k,C,S,I,L;let e={gameplay:{},ui:{},theme:{},assets:{}};for(let[R,z]of s.objects.entries()){let N=((t=z.identity)==null?void 0:t.id)||R;N.includes("character")&&(e.gameplay.character_pos=((i=z.transform)==null?void 0:i.position)||{x:0,y:0},e.gameplay.character_scale=((n=z.transform)==null?void 0:n.scale)||1,e.gameplay.character_anim_speed=((r=(a=z.gameplay)==null?void 0:a.tuning)==null?void 0:r.anim_speed)||.003,e.gameplay.character_relief_scale=((l=(o=z.gameplay)==null?void 0:o.tuning)==null?void 0:l.relief_scale)||1.22,e.gameplay.character_relief_speed=((d=(c=z.gameplay)==null?void 0:c.tuning)==null?void 0:d.relief_speed)||.22),(N.includes("gun")||N.includes("flame"))&&(e.gameplay.gun=z.gun||{},e.gameplay.gunmuzzle=((p=z.effects)==null?void 0:p.gunmuzzle)||{},e.gameplay.muzzle_levels=((u=z.effects)==null?void 0:u.muzzle_levels)||{},e.gameplay.flame=((g=z.effects)==null?void 0:g.flame)||{}),N.includes("diamond")&&(e.gameplay.diamond=z),N.includes("ice")&&(e.gameplay.melt=z.melt||{},e.gameplay.melt_anchor=((h=z.transform)==null?void 0:h.melt_anchor)||{x:0,y:0},e.gameplay.melt_pos=((f=z.transform)==null?void 0:f.position)||{x:0,y:0},e.gameplay.hybrid_melting=((m=z.effects)==null?void 0:m.hybrid_melting)||{},e.gameplay.physics_chunks=((b=z.effects)==null?void 0:b.physics_chunks)||{},e.gameplay.melting_particles=((y=z.effects)==null?void 0:y.melting_particles)||{},e.gameplay.hard_ice=z.hard_ice||{}),N.includes("water")&&(e.gameplay.water_drops=z),N.includes("crack")&&(e.gameplay.crack=z),N.includes("hand")&&(e.gameplay.hand=((v=z.gameplay)==null?void 0:v.tuning)||{},e.gameplay.brush_start_pos=((w=z.transform)==null?void 0:w.brush_start_pos)||{x:0,y:-120},e.gameplay.hand_scale=((E=z.transform)==null?void 0:E.scale)||1.5),N.includes("hazard")&&(e.gameplay.hazard=((P=z.gameplay)==null?void 0:P.tuning)||{},e.gameplay.danger_pos=((M=z.transform)==null?void 0:M.danger_pos)||{x:0,y:235},e.gameplay.danger_pulse=((_=(x=z.gameplay)==null?void 0:x.tuning)==null?void 0:_.danger_pulse)||{},e.gameplay.hazard_height=((T=(O=z.gameplay)==null?void 0:O.tuning)==null?void 0:T.hazard_height)||140)}return e.gameplay.timeline=((A=s.engine.runtime)==null?void 0:A.timeline)||{},e.gameplay.drag_surface=((j=s.engine.runtime)==null?void 0:j.drag_surface)||{},e.gameplay.background=((k=s.engine.runtime)==null?void 0:k.background)||{},e.gameplay.ui_styles=((C=s.engine.runtime)==null?void 0:C.ui_styles)||{},e.gameplay.label_pulse=((S=s.engine.runtime)==null?void 0:S.label_pulse)||{},e.ui=((I=s.engine.runtime)==null?void 0:I.ui)||{},e.theme=((L=s.engine.runtime)==null?void 0:L.theme)||{},e.assets=s.engine.assets||{},e}var Bs,B,Bn,Un,Vn=be(()=>{"use strict";K();Bs=null,B="dev";if(typeof window!="undefined"){let s=window.__BUILD_SETTINGS__;if(s!=null&&s.buildMode)Bs=s,B=s.buildMode,console.log("[CONFIG] Loaded inline build settings:",s,"buildMode:",B);else try{let e=new XMLHttpRequest;if(e.open("GET","./build-settings.json",!1),e.send(),e.status===200&&e.responseText){let t=JSON.parse(e.responseText);Bs=t,B=t.buildMode||"dev",console.log("[CONFIG] Loaded build settings:",t,"buildMode:",B)}else console.log("[CONFIG] No build-settings.json found, using default buildMode:",B)}catch(e){console.log("[CONFIG] Failed to load build-settings.json:",e instanceof Error?e.message:String(e))}}console.log("[CONFIG] Final buildMode:",B);Bn=new Map,Un=B==="dev"||typeof window!="undefined"&&window.location.search.includes("hot-reload")});function Wn(s,e){let t=[];function i(n,a,r=""){if(n!==a){if(typeof n!=typeof a){t.push(`${r}: type changed`);return}if(typeof n=="object"&&n!==null&&a!==null){let o=new Set([...Object.keys(n),...Object.keys(a)]);for(let l of o){let c=r?`${r}.${l}`:l;l in n?l in a?i(n[l],a[l],c):t.push(`${c}: removed`):t.push(`${c}: added`)}}else t.push(`${r}: changed`)}}return i(s,e),t}function Yn(s,e,t,i){let n={...t};for(let[a,r]of i.entries())n[a]&&r.defaults&&(n[a]={...r.defaults,...n[a]});return n}var Rt,Ve,Kn=be(()=>{"use strict";Rt=class{shouldFullReload(e){return e.type==="component"||e.type==="scene"}getAffectedObjects(e){return e.type==="object"&&e.objectId?[e.objectId]:[]}},Ve=class{constructor(e=1e3){this.pollingInterval=null;this.fileHashes=new Map;this.callbacks=new Map;this.intervalMs=e}watch(e,t){this.callbacks.set(e,t),this.pollingInterval===null&&(this.pollingInterval=window.setInterval(()=>{this.checkAllFiles()},this.intervalMs))}async checkAllFiles(){for(let[e,t]of this.callbacks.entries())try{let i=`${e}?t=${Date.now()}&r=${Math.random()}`,n=await fetch(i,{cache:"no-cache",headers:{"Cache-Control":"no-cache"}});if(n.ok){let a=await n.text(),r=this.hashString(a),o=this.fileHashes.get(e);if(o&&o!==r&&console.log(`[HOT-RELOAD] File changed: ${e}`),o&&o!==r){console.log(`[HOT-RELOAD] File changed: ${e}`);let l=this.determineEventType(e);t(l),this.fileHashes.set(e,r)}else o||this.fileHashes.set(e,r)}}catch(i){console.warn(`Failed to check ${e}:`,i)}}determineEventType(e){var t,i;return e.includes("/components/")?{type:"component",path:e,componentName:(t=e.split("/").pop())==null?void 0:t.replace(".schema.json","")}:e.includes("/engine/")?{type:"engine",path:e}:e.includes("/scenes/")?{type:"scene",path:e}:e.includes("/objects/")?{type:"object",path:e,objectId:(i=e.split("/").pop())==null?void 0:i.replace(".json","")}:{type:"object",path:e}}hashString(e){let t=0;for(let i=0;i<e.length;i++){let n=e.charCodeAt(i);t=(t<<5)-t+n,t=t&t}return t.toString()}unwatch(e){this.callbacks.delete(e),this.fileHashes.delete(e)}stop(){this.pollingInterval!==null&&(clearInterval(this.pollingInterval),this.pollingInterval=null),this.callbacks.clear(),this.fileHashes.clear()}}});function Jn(s){if(typeof window=="undefined")return;let e=typeof Xn!="undefined"&&!!Xn.hot,t=window.location.search.includes("hot-reload");if(!(e||t))return;let n=null,a=!1,r=null;if(t){r=new Ve;let h=window.__configWatcher;h!=null&&h.stop&&h.stop(),window.__configWatcher=r}let o=new Set,l=h=>{var b,y;if(!r)return;let f=new Set;f.add("configs/engine/engine.runtime.json"),f.add("configs/engine/engine.assets.json"),f.add("configs/engine/engine.splash.json"),f.add("configs/scenes/scene.main.json");let m=(y=(b=h.scene)==null?void 0:b.objects)!=null?y:[];for(let v of m)v!=null&&v.object_config&&f.add(`configs/objects/${v.object_config}.json`);for(let v of o)f.has(v)||r.unwatch(v);for(let v of f)o.has(v)||r.watch(v,w=>g(w));o=f},c=new Set,d=!1,p=async h=>{let f=await je(h),m=qe(f,s.activeConfig.schemas),b=ot(m,s.activeConfig.schemas);b.valid||console.warn(`[HOT-RELOAD] ${h} validation errors:`,b.errors),await s.liveEditBridge.applyObjectConfig(h,m)};async function u(h){if(!a){a=!0;try{if(d||c.size===0){s.audioSystem.destroy();let f=await Ce("scene.main");s.setActiveConfig(f),s.gameObjectManager.updateConfig(f),s.CustomAssets.updateConfig(f),await s.CustomAssets.ready();let m=s.createAudioSystem(f);s.setAudioSystem(m),window.__audioSystem=m,await m.start(),s.liveEditBridge.rebuildIndexes(),l(f),console.log(`[GAME] Hot-reload complete (${h})`)}else{let f=Array.from(c);c.clear();for(let m of f)await p(m);console.log(`[GAME] Hot-reload updated objects: ${f.join(", ")}`)}}catch(f){console.warn("[GAME] Hot-reload failed:",f)}finally{a=!1,d=!1,c.clear()}}}function g(h){h.type==="object"&&h.objectId?c.add(h.objectId):d=!0,n&&window.clearTimeout(n),n=window.setTimeout(()=>{u(h.type)},120)}e&&Xn.hot.on("config-change",()=>{g({type:"hmr"})}),t&&(l(s.activeConfig),console.log(`[GAME] Hot-reload watcher enabled (${o.size} files)`))}var Xn,Gs=be(()=>{"use strict";Kn();Vn();Xn={}});var qs={};Et(qs,{ConfigWatcher:()=>Ve,DefaultReloadStrategy:()=>Rt,applyDefaults:()=>qe,diffConfigs:()=>Wn,loadAllObjectConfigs:()=>vi,loadComponentSchemas:()=>yi,loadEngineConfig:()=>wi,loadGamePromptConfig:()=>Gn,loadObjectCentricConfig:()=>Ce,loadObjectConfig:()=>je,loadSceneConfig:()=>xi,rehydrateObject:()=>Yn,setupHotReload:()=>Jn,toLegacyFormat:()=>qn,validateObjectConfig:()=>ot});var Si=be(()=>{"use strict";Vn();Kn();Gs()});var Pr={};Et(Pr,{AssetEditorModal:()=>Pa});var Pa,Ma=be(()=>{"use strict";Pa=class{constructor(){this.modal=null;this.currentObjectId=null;this.currentPath=null;this.currentAsset="";this.onApplyCallback=null}show(e,t,i,n){this.currentObjectId=e,this.currentPath=t,this.currentAsset=i,this.onApplyCallback=n,this.createModal(e,i),document.body.appendChild(this.modal),this.attachModalListeners()}createModal(e,t){let i=document.createElement("div");i.className="asset-editor-modal",i.innerHTML=`
2
2
  <div class="asset-editor-card">
3
3
  <div class="asset-editor-header">
4
4
  <div>
@@ -43,7 +43,7 @@
43
43
  <button class="debug-btn primary" data-modal-apply>Apply</button>
44
44
  </div>
45
45
  </div>
46
- `,this.modal=n}attachModalListeners(){if(!this.modal)return;this.modal.querySelectorAll("[data-modal-close]").forEach(r=>{r.addEventListener("click",()=>this.close())}),this.modal.querySelectorAll("[data-tab]").forEach(r=>{r.addEventListener("click",o=>{let c=o.target.dataset.tab;c&&this.switchTab(c)})});let n=this.modal.querySelector("[data-ai-generate]");n==null||n.addEventListener("click",()=>{this.openAiEditor("generate")});let i=this.modal.querySelector("[data-ai-edit]");i==null||i.addEventListener("click",()=>{this.openAiEditor("edit")});let a=this.modal.querySelector("[data-modal-apply]");a==null||a.addEventListener("click",()=>{this.apply()}),this.modal.addEventListener("click",r=>{r.target===this.modal&&this.close()})}switchTab(e){if(!this.modal)return;this.modal.querySelectorAll("[data-tab]").forEach(i=>{i.classList.toggle("active",i.getAttribute("data-tab")===e)}),this.modal.querySelectorAll("[data-tab-panel]").forEach(i=>{i.classList.toggle("active",i.getAttribute("data-tab-panel")===e)})}openAiEditor(e){let t=window.__openAiEditor;if(typeof t!="function"){alert("AI Editor not available. Please check your setup.");return}let n="";e==="edit"&&this.currentAsset?n=`Edit this image: ${this.currentObjectId}`:n=`Create an image for: ${this.currentObjectId}`,t(this.currentObjectId||"unknown",n,this.currentAsset,{path:this.currentPath,onApply:i=>{this.onApplyCallback&&this.onApplyCallback(i),this.close()}})}apply(){this.onApplyCallback&&this.onApplyCallback("library/placeholder.png"),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.currentObjectId=null,this.currentPath=null,this.onApplyCallback=null}}});var Ll={};vt(Ll,{COLORS:()=>pe,ConfigWatcher:()=>Ge,DebugPanel:()=>Ht,DefaultReloadStrategy:()=>jt,Handler:()=>re,PlayableLoadingScreen:()=>ai,PreviewShell:()=>ti,STROKE_WIDTH:()=>Pr,THEME:()=>_r,applyConfigOverride:()=>ce,applyConfigOverrides:()=>ke,applyConfigsToDisk:()=>hn,applyDefaults:()=>Ue,baseLottie:()=>bi,bootstrap:()=>ml,clearConfigOverrides:()=>ne,clearConfigOverridesForObject:()=>Ps,configOverrideManager:()=>_s,createPreviewShell:()=>La,deepClone:()=>W,default:()=>$e,defaultPreset:()=>xn,deviceGroups:()=>Wi,devicePresets:()=>Vi,diffConfigs:()=>Ni,exportConfigsAsJSON:()=>Fe,getConfigOverrides:()=>X,getConfigStateSummary:()=>Ie,getOverrideMode:()=>Tt,getPresetById:()=>qe,getPresetsByCategory:()=>qo,loadAllObjectConfigs:()=>bn,loadComponentSchemas:()=>mn,loadEngineConfig:()=>yn,loadGamePromptConfig:()=>$i,loadObjectCentricConfig:()=>xe,loadObjectConfig:()=>je,loadSceneConfig:()=>vn,redoLastConfigChange:()=>gn,rehydrateObject:()=>Fi,removeConfigOverride:()=>Lt,resetToApplied:()=>kt,resetToOriginal:()=>fn,setBootstrapDependencies:()=>hl,setOverrideMode:()=>Oi,setupHotReload:()=>Gi,setupLiveEditBridge:()=>ni,toLegacyFormat:()=>Di,trackObjectCreation:()=>Os,trackObjectDeletion:()=>Rs,undoLastConfigChange:()=>un,validateObjectConfig:()=>it});module.exports=Qr(Ll);var Ae={};function Xt(s,e,t=!1){Ae[s]||(Ae[s]=[]),Ae[s].push({fn:e,once:t})}function gi(s,e){if(Ae[s]){if(!e){delete Ae[s];return}Ae[s]=Ae[s].filter(t=>t.fn!==e)}}function Jt(s,...e){let t=Ae[s];if(t)for(let n of[...t])n.fn(...e),n.once&&gi(s,n.fn)}function Q(s,e){Xt(s,e,!0)}var q=null,ae=[],Qe=null;function qa(s){q=s,ae=[],Qe!==null&&(clearTimeout(Qe),Qe=null)}function Va(){var s,e,t;return{endpoint:(q==null?void 0:q.endpoint)||"",transport:(q==null?void 0:q.transport)||"beacon",batchSize:(s=q==null?void 0:q.batchSize)!=null?s:10,flushIntervalMs:(e=q==null?void 0:q.flushIntervalMs)!=null?e:300,maxQueue:(t=q==null?void 0:q.maxQueue)!=null?t:200,debug:!!(q!=null&&q.debug)}}async function Ua(s,e,t,n){let i=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let a=navigator.sendBeacon(s,new Blob([i],{type:"application/json"}));n&&console.log("[handler.telemetry] beacon",a,e);return}catch(a){n&&console.warn("[handler.telemetry] beacon failed, fallback to fetch",a)}try{await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:i,keepalive:!0}),n&&console.log("[handler.telemetry] fetch",e)}catch(a){n&&console.warn("[handler.telemetry] fetch failed",a)}}function hi(s,e){let t=Va();if(e&&t.endpoint){if(ae.push(s),ae.length>t.maxQueue&&(ae=ae.slice(ae.length-t.maxQueue)),ae.length>=t.batchSize){Ga();return}Qe===null&&(Qe=window.setTimeout(()=>{Qe=null,Ga()},t.flushIntervalMs))}}async function Ga(){let s=Va();if(!s.endpoint||ae.length===0)return;let e=ae.splice(0,s.batchSize);await Ua(s.endpoint,{events:e},s.transport,s.debug),ae.length>0&&await Ua(s.endpoint,{events:ae.splice(0,s.batchSize)},s.transport,s.debug)}function Wa(s){return Math.max(0,Math.min(1,s))}function eo(s){let e=String(s!=null?s:"power2.out");if(e==="linear")return t=>t;if(e==="sine.inOut")return t=>.5-Math.cos(Math.PI*t)/2;if(e==="power2.out"||e==="easeOutQuad")return t=>1-(1-t)*(1-t);if(e.startsWith("back.out")){let t=e.match(/back\.out\(([\d.]+)\)/),n=t?Number(t[1]):1.8;return i=>1+(n+1)*Math.pow(i-1,3)+n*Math.pow(i-1,2)}return t=>1-(1-t)*(1-t)}function wt(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function to(s,e){let t=s==null?void 0:s[e];return typeof t=="number"?t:0}function Ya(s,e,t){try{s[e]=t}catch{}}function no(s){let e=s==null?void 0:s.scale;if(!e)return null;let t=typeof e.x=="number"?e.x:1,n=typeof e.y=="number"?e.y:1;return{x:t,y:n}}function Ka(s,e){let t=s==null?void 0:s.scale;if(t)try{typeof t.set=="function"?t.set(e.x,e.y):(typeof t.x=="number"&&(t.x=e.x),typeof t.y=="number"&&(t.y=e.y))}catch{}}function Xa(s,e){let t=no(s);if(!t)return{from:null,to:null};let n=null,i=null;return typeof e.scale=="number"?(n=e.scale,i=e.scale):e.scale&&typeof e.scale=="object"&&(typeof e.scale.x=="number"&&(n=e.scale.x),typeof e.scale.y=="number"&&(i=e.scale.y)),typeof e.scaleX=="number"&&(n=e.scaleX),typeof e.scaleY=="number"&&(i=e.scaleY),n===null&&i===null?{from:null,to:null}:{from:{x:t.x,y:t.y},to:{x:n!=null?n:t.x,y:i!=null?i:t.y}}}function Ja(){let s=new Set,e=new WeakMap,t=null,n=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,o(),s.size>0&&n()})},i=d=>{var u;s.add(d);let p=(u=e.get(d.target))!=null?u:new Set;p.add(d),e.set(d.target,p),n()},a=d=>{s.delete(d);let p=e.get(d.target);p&&(p.delete(d),p.size===0&&e.delete(d.target))},r=d=>{d.killed||(d.killed=!0,a(d))},o=()=>{var p,u;let d=wt();for(let g of Array.from(s)){if(g.killed||g.paused)continue;let f=d-g.startMs-g.delayMs;if(f<0)continue;let h=g.durationMs>0?f/g.durationMs:1,m=Wa(h),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(h),b-1):0;if(g.repeat>0&&h>=1){let E=h-y;m=Wa(E)}let v=g.ease(m);g.yoyo&&y%2===1&&(v=1-v);for(let E of g.props)Ya(g.target,E.key,E.from+(E.to-E.from)*v);g.scaleFrom&&g.scaleTo&&Ka(g.target,{x:g.scaleFrom.x+(g.scaleTo.x-g.scaleFrom.x)*v,y:g.scaleFrom.y+(g.scaleTo.y-g.scaleFrom.y)*v});try{(p=g.onUpdate)==null||p.call(g)}catch{}if(h>=b){r(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var E;let g=Math.max(0,(typeof p.duration=="number"?p.duration:.5)*1e3),f=Math.max(0,(typeof p.delay=="number"?p.delay:0)*1e3+((E=u==null?void 0:u.delayMsOverride)!=null?E:0)),h=eo(p.ease),m=typeof p.repeat=="number"?Math.max(0,p.repeat|0):0,b=p.yoyo===!0,y=new Set(["duration","delay","ease","repeat","yoyo","onUpdate","onComplete","scale","scaleX","scaleY"]),v=[];for(let j of Object.keys(p)){if(y.has(j))continue;let z=p[j];typeof z=="number"&&v.push({key:j,from:to(d,j),to:z})}let w=Xa(d,p);return{target:d,startMs:wt(),delayMs:f,durationMs:g,ease:h,props:v,scaleFrom:w.from,scaleTo:w.to,repeat:m,yoyo:b,onUpdate:typeof p.onUpdate=="function"?p.onUpdate:void 0,onComplete:typeof p.onComplete=="function"?p.onComplete:void 0,killed:!1,paused:!1,pauseAtMs:null}},c={to(d,p){let u=l(d,p);return i(u),{kill:()=>r(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=wt())},resume:()=>{var h;if(!u.paused)return;let g=(h=u.pauseAtMs)!=null?h:wt(),f=wt()-g;u.startMs+=f,u.paused=!1,u.pauseAtMs=null},isActive:()=>!u.killed&&!u.paused}},fromTo(d,p,u){return c.set(d,p),c.to(d,u)},set(d,p){if(!d||!p)return;for(let g of Object.keys(p)){let f=p[g];g==="scale"||g==="scaleX"||g==="scaleY"||typeof f=="number"&&Ya(d,g,f)}let u=Xa(d,p);u.to&&Ka(d,u.to)},killTweensOf(d){let p=e.get(d);if(p)for(let u of Array.from(p))r(u)},timeline(d={}){let p=[],u=0,g=!1,f=[],h=y=>{if(typeof y=="number")return Math.max(0,y*1e3);let v=typeof y=="string"?y.trim():"";return v.startsWith("+=")?u+Math.max(0,Number(v.slice(2))*1e3||0):v?Math.max(0,Number(v)*1e3||0):u},m=y=>{p.push(y);let v=Math.max(0,(typeof y.vars.duration=="number"?y.vars.duration:.5)*1e3);u=Math.max(u,y.atMs+v)},b={to(y,v,w){return m({kind:"to",target:y,vars:v,atMs:h(w)}),b},fromTo(y,v,w,E){return m({kind:"fromTo",target:y,vars:w,from:v,atMs:h(E)}),b},play(){var y,v;if(g)return b;g=!0,f=[];for(let w of p)w.kind==="fromTo"&&c.set(w.target,(y=w.from)!=null?y:{}),f.push(c.to(w.target,{...w.vars,delay:w.atMs/1e3+((v=w.vars.delay)!=null?v:0)}));return b},pause(){for(let y of f)y.pause();return b},kill(){for(let y of f)y.kill();f=[],g=!1}};return d.paused||b.play(),b}};return c}function Za(){if(typeof window=="undefined")return;let s=window;if(!s.gsap)try{s.gsap=Ja()}catch{}}var Qa={name:"handler-playable-sdk",version:"0.5.544",type:"module",description:"Handler Playable SDK v0.1 with contract-aligned surface (root sandbox, canonical event envelope).",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./pixi":{types:"./dist/pixi/index.d.ts",import:"./dist/pixi/index.js",require:"./dist/pixi/index.cjs"},"./pixi/index.css":{import:"./dist/pixi/index.css",require:"./dist/pixi/index.css"},"./three":{types:"./dist/three/index.d.ts",import:"./dist/three/index.js",require:"./dist/three/index.cjs"},"./cli":{types:"./dist/cli/index.d.ts",import:"./dist/cli/index.js",require:"./dist/cli/index.cjs"}},bin:{"handler-student-helper":"./bin/student-helper.mjs","handler-validate":"./bin/validate.mjs","handler-sync-screens":"./bin/sync-screens.mjs","handler-brand-dna":"./bin/brand-dna.mjs","handler-setup-library":"./bin/setup-library.mjs","handler-screen-helper":"./bin/screen-helper.mjs"},scripts:{prebuild:"python3 src/preview/build-css.py",build:"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --minify --external lottie-web && npm run create-mjs-symlinks && npm run postbuild-cli && npm run obfuscate && npm run postbuild",postbuild:"python3 src/preview/copy-css-to-dist.py","postbuild-cli":"cp src/cli/*.mjs dist/cli/ && chmod +x dist/cli/*.mjs && chmod +x bin/*.mjs","create-mjs-symlinks":"cd dist && ln -sf index.js index.mjs && cd pixi && ln -sf index.js index.mjs && cd ../three && ln -sf index.js index.mjs","build:dev":"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --external lottie-web && npm run create-mjs-symlinks && npm run postbuild-cli",obfuscate:"javascript-obfuscator dist/pixi/index.js --output dist/pixi/index.js --config obfuscator.config.json && javascript-obfuscator dist/three/index.js --output dist/three/index.js --config obfuscator.config.json && javascript-obfuscator dist/cli/index.js --output dist/cli/index.js --config obfuscator.config.json && npm run obfuscate-cli","obfuscate-cli":'for file in dist/cli/*.mjs; do javascript-obfuscator "$file" --output "$file" --config obfuscator.config.json; done',lint:"eslint 'src/**/*.{ts,tsx}'",typecheck:"tsc --noEmit",prepublishOnly:"npm run build","publish:update":"node scripts/publish-and-update.cjs patch","publish:update:minor":"node scripts/publish-and-update.cjs minor","publish:update:major":"node scripts/publish-and-update.cjs major"},author:"Handler",license:"MIT",publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/HandlerAIGames/handler-playable-sdk.git"},files:["dist","bin","LICENSE","README.md"],peerDependencies:{"lottie-web":"^5.0.0","pixi.js":"^8.0.0",three:"^0.182.0"},peerDependenciesMeta:{"pixi.js":{optional:!0},three:{optional:!0},"lottie-web":{optional:!0}},devDependencies:{"@types/three":"^0.182.0",eslint:"^9.39.2","javascript-obfuscator":"^5.1.0","pixi.js":"8.8.1",three:"^0.182.0","ts-node":"^10.9.2",tsup:"^8.4.0",typescript:"^5.7.2","typescript-eslint":"^8.53.0"},dependencies:{"@google/genai":"^1.35.0","@google/generative-ai":"^0.24.1",jszip:"^3.10.1",sharp:"^0.34.5"}};var ee=0,ao=ee++,es=ee++,ts=ee++,ns=ee++,is=ee++,as=ee++,ss=ee++,rs=ee++,os=ee++,ls=ee++,cs=ee++,ds=ee++,U=ao;function ps(){return U===es}function us(){return U===ts}function gs(){return U===ns}function hs(){return U===is}function et(){return U===as}function tt(){return U===ss}function fs(){return U===rs}function ms(){return U===os}function bs(){return U===ls}function fi(){return U===cs}function mi(){return U===ds}function ys(){let s=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(s==="mraid")try{mraid.getState(),U=es;return}catch{}else if(s==="dapi")try{dapi.isReady(),U=ts;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(U=ns)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(U=is)}catch{}else if(e==="mintegral")window.gameReady&&(U=as);else if(e==="tapjoy")window.TJ_API&&(U=ss);else if(e==="tiktok")window.openAppStore&&(U=rs);else if(e==="smadex")try{window.smxTracking&&(U=os)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(U=ls)}catch{}else e==="vungle"?U=cs:(s==="nucleo"||e==="nucleo")&&(U=ds)}var Zt=Ze(require("lottie-web"),1),bi=Zt.default;typeof window!="undefined"&&(window.lottie=Zt.default,window.__baseLottie=Zt.default);var so=require("pixi.js");var yi=require("pixi.js");var ro=null;function vi(s){ro=s}Qt();wi();var xt=require("pixi.js");Qt();var go=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Ci=go;if(typeof window!="undefined")try{let s=new XMLHttpRequest;if(s.open("GET","./build-settings.json",!1),s.send(),s.status===200&&s.responseText){let e=JSON.parse(s.responseText);e!=null&&e.buildMode&&(Ci=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Ci}`))}}catch{}function ho(s){var t,n,i,a,r;if(typeof window!="undefined"&&window.resolveAnchorVec2)return window.resolveAnchorVec2(s);let e={center:{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};if(Array.isArray(s))return{x:(t=s[0])!=null?t:.5,y:(n=s[1])!=null?n:.5};if(s&&typeof s=="object"&&"x"in s&&"y"in s)return{x:(i=s.x)!=null?i:.5,y:(a=s.y)!=null?a:.5};if(typeof s=="string"){let o=s.trim().toLowerCase();return(r=e[o])!=null?r:{x:.5,y:.5}}return null}var Le=class{static async create(e,t,n){var l,c,d,p,u,g,f;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Ci}`);let i=(l=t==null?void 0:t.render)==null?void 0:l.asset;if(!i){console.log(`[ObjectFactory] No asset definition for: ${e}, returning empty container`);let h=new xt.Container;return this.applyTransform(h,t==null?void 0:t.transform,t),h}let a=(c=t==null?void 0:t.identity)==null?void 0:c.id;console.log(`[ObjectFactory] Calling AssetLoader.load() for: ${e}, configId: ${a}, type: ${i.type}, path: ${i.path}`);let r=await He.load(e,i,n,a);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(d=r==null?void 0:r.constructor)==null?void 0:d.name}`);let o;if(i.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",r,"for object:",e),o=new xt.Sprite(r),console.log("[ObjectFactory] Created object:",o,"type:",(p=o==null?void 0:o.constructor)==null?void 0:p.name),this.applyTransform(o,t==null?void 0:t.transform,t);else if(i.type==="json")if(console.log("[ObjectFactory] JSON asset for",e,"rawAsset type:",(u=r==null?void 0:r.constructor)==null?void 0:u.name,r),r&&(((g=r.constructor)==null?void 0:g.name)==="Container"||r instanceof xt.Container)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let h=[i.path,`/assets/${i.path}`,`assets/${i.path}`,`../assets/${i.path}`],m=!1;for(let b of h)try{let y=await fetch(b);if(y.ok){o=await y.json(),console.log("[ObjectFactory] Reloaded JSON directly from:",b,"type:",(f=o==null?void 0:o.constructor)==null?void 0:f.name),m=!0;break}}catch{continue}m||(console.error("[ObjectFactory] Failed to reload JSON from any path"),o=r)}else o=r;else o=r,o&&typeof o=="object"&&("x"in o||"position"in o)&&this.applyTransform(o,t==null?void 0:t.transform,t);return o}static applyTransform(e,t,n){var i,a,r,o;if(!(!t||!e)&&(t.position&&("x"in e&&"y"in e?(e.x=(i=t.position.x)!=null?i:0,e.y=(a=t.position.y)!=null?a:0):"position"in e&&e.position&&e.position.set((r=t.position.x)!=null?r:0,(o=t.position.y)!=null?o:0)),t.scale!==void 0&&"scale"in e&&e.scale&&(typeof e.scale=="object"&&"set"in e.scale?e.scale.set(t.scale):e.scale=t.scale),t.rotation!==void 0&&"rotation"in e&&(e.rotation=t.rotation),t.anchor&&"anchor"in e&&e.anchor)){let l=ho(t.anchor);l&&("set"in e.anchor?e.anchor.set(l.x,l.y):(e.anchor.x=l.x,e.anchor.y=l.y))}}};var Et=class{constructor(){this.config=null}init(e){this.config=e}get(e){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return this.config.objects.get(e)}getAllIds(){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return Array.from(this.config.objects.keys())}has(e){return this.config?this.config.objects.has(e):!1}};var bo=Ze(require("pixi.js"),1);typeof window!="undefined"&&(window.__basePixi=bo);nt();var en=require("pixi.js");nt();var Li=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new Et}init(e,t){this.registry.init(e),this.app=t}updateConfig(e){this.registry.init(e),this.instanceCache.clear(),this.readyPromise=null}async ready(){this.readyPromise&&await this.readyPromise;let t=this.registry.getAllIds().filter(i=>!this.instanceCache.has(i));if(t.length===0)return;let n=async i=>{i.length&&(console.log("[Assets] Loading objects:",i),await Promise.all(i.map(async a=>{var o;let r=this.registry.get(a);if(!r){console.warn("[Assets] No config found for object:",a);return}try{let l=await Le.create(a,r,this.app);this.instanceCache.set(a,l),console.log("[Assets] Loaded object:",a,(o=l==null?void 0:l.constructor)==null?void 0:o.name)}catch(l){console.error("[Assets] Failed to load object:",a,l)}})))};return this.readyPromise=(async()=>{await n(t);let i=this.registry.getAllIds().filter(a=>!this.instanceCache.has(a));i.length>0&&(console.warn("[Assets] Retrying missing assets:",i),await n(i)),console.log("[Assets] Ready. Cached objects:",Array.from(this.instanceCache.keys()))})(),this.readyPromise}resetScene(){this.instanceCache.clear(),this.readyPromise=null}async reloadObject(e){let t=this.registry.get(e);if(t){let n=await Le.create(e,t,this.app);this.instanceCache.set(e,n)}}get(e){return this.instanceCache.get(e)}},yo=new Li,vo=new Proxy(yo,{get(s,e){if(e in s&&typeof s[e]=="function")return s[e].bind(s);if(s.get(e))return s.get(e)}});nt();var Cs=require("pixi.js"),ye={width:400,height:600,designWidth:400,scaleFactor:1},nn={scale:1,position:1},Ii=[];function xo(s,e,t,n,i,a,r){Ii.push({element:s,originalScale:a,positionHelper:e,heightPercent:i}),e(s,t,n,i,a,r,!1)}function Eo(){Ii.forEach(({element:s,originalScale:e,positionHelper:t,heightPercent:n})=>{let i=e*ye.scaleFactor;t(s,ye.width,ye.height,n,i,!0,!1)})}function ki(s,e){console.log(`[SCREEN] updateScreenState called: ${s}x${e}`),ye.width=s,ye.height=e,ye.scaleFactor=Math.min(s/ye.designWidth,1.15),nn.scale=ye.scaleFactor,nn.position=1,console.log(`[SCREEN] Global multipliers - scale: ${nn.scale.toFixed(3)}`),Eo()}var Ct={layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}};function So(s,e,t){let n=Ct[s];n&&n[e]!==void 0&&(n[e]=t,console.log(`Updated ${s}.${e} = ${t}`))}function Co(){return Ct}var Ao={center:{x:.5,y:.5},"center-center":{x:.5,y:.5},middle:{x:.5,y:.5},"middle-center":{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},"left-center":{x:0,y:.5},"right-center":{x:1,y:.5},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};function tn(s,e){return typeof s=="number"&&Number.isFinite(s)?s:e}function an(s,e={x:.5,y:.5}){var t;if(Array.isArray(s))return{x:tn(s[0],e.x),y:tn(s[1],e.y)};if(s&&typeof s=="object"){let n=s;return{x:tn(n.x,e.x),y:tn(n.y,e.y)}}if(typeof s=="string"){let n=s.trim().toLowerCase();return(t=Ao[n])!=null?t:e}return e}function As(s,e,t,n={}){var g,f,h,m,b,y;let i=an(t),a=(g=n.inset)!=null?g:{},r=(f=n.padding)!=null?f:{x:0,y:0},o=((h=a.left)!=null?h:0)+r.x,l=((m=a.right)!=null?m:0)+r.x,c=((b=a.top)!=null?b:0)+r.y,d=((y=a.bottom)!=null?y:0)+r.y,p=Math.max(0,s-o-l),u=Math.max(0,e-c-d);return{x:o+p*i.x,y:c+u*i.y}}function Ts(s,e,t,n={}){var h,m,b,y,v,w;let i=(h=n.inset)!=null?h:{},a=(m=n.padding)!=null?m:{x:0,y:0},r=((b=i.left)!=null?b:0)+a.x,o=((y=i.right)!=null?y:0)+a.x,l=((v=i.top)!=null?v:0)+a.y,c=((w=i.bottom)!=null?w:0)+a.y,d=Math.max(0,s-r-o),p=Math.max(0,e-l-c),u=an(t,{x:.5,y:.5}),g=Math.min(Math.max(u.x,0),1),f=Math.min(Math.max(u.y,0),1);return{x:r+d*g,y:l+p*f}}if(typeof window!="undefined"){let s=window.innerWidth,e=window.innerHeight,t=()=>{let n=window.innerWidth,i=window.innerHeight;(n!==s||i!==e)&&(s=n,e=i,ki(n,i))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),ki(window.innerWidth,window.innerHeight),window.updateDebugConfig=So,window.getDebugConfig=Co,window.copyConfig=zo,window.applyConfig=St,window.applyConfigForRatio=$o,window.positionAtBottom=Ls,window.positionAtTop=ko,window.positionAtCenter=Io,window.positionAtLeft=jo,window.positionAtRight=Mo,window.positionAtBottomLeft=Po,window.positionAtBottomRight=_o,window.positionAtTopLeft=Oo,window.positionAtTopRight=Ro,window.applyPositionContract=Lo,console.log("\u{1F3AE} Debug Config Functions Available:"),console.log("\u2022 updateDebugConfig(category, key, value)"),console.log("\u2022 getDebugConfig()"),console.log("\u2022 copyConfig(presetName)"),console.log("\u2022 applyConfig(config)"),console.log("\u2022 applyConfigForRatio(width, height)"),console.log("\u{1F4CD} Positioning Helpers Available (with scale):"),console.log("\u2022 positionAtBottom(element, w, h, percent, scale)"),console.log("\u2022 positionAtTop(element, w, h, percent, scale)"),console.log("\u2022 positionAtCenter(element, w, h, offsetX, offsetY, scale)"),console.log("\u2022 positionAtLeft/Right(element, w, h, percent, scale)"),console.log("\u2022 Corner positions: BottomLeft/Right, TopLeft/Right (all with scale)"),console.log("\u2022 applyPositionContract(element, w, h, contract)"),console.log("Example: positionAtCenter(mySprite, 400, 600, 0, -50, 1.2)")}function sn(s,e,t=0){return s*e+t}function rn(s,e,t=0){return s*(1-e)+t}function on(s,e,t=0){return s*e+t}function ln(s,e,t=0){return s*(1-e)+t}function te(s,e=0){return s/2+e}function To(s,e){return s*e}function Lo(s,e,t,n){var r,o,l,c,d,p,u,g,f,h,m,b,y,v,w,E,j,z,S,P;let i=0,a=0;switch(n.type){case"top":i=te(e,(o=(r=n.offset)==null?void 0:r.x)!=null?o:0),a=sn(t,n.percent,(c=(l=n.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":i=te(e,(p=(d=n.offset)==null?void 0:d.x)!=null?p:0),a=rn(t,n.percent,(g=(u=n.offset)==null?void 0:u.y)!=null?g:0);break;case"left":i=on(e,n.percent,(h=(f=n.offset)==null?void 0:f.x)!=null?h:0),a=te(t,(b=(m=n.offset)==null?void 0:m.y)!=null?b:0);break;case"right":i=ln(e,n.percent,(v=(y=n.offset)==null?void 0:y.x)!=null?v:0),a=te(t,(E=(w=n.offset)==null?void 0:w.y)!=null?E:0);break;case"center":i=te(e,(z=(j=n.offset)==null?void 0:j.x)!=null?z:0),a=te(t,(P=(S=n.offset)==null?void 0:S.y)!=null?P:0);break}s.position?s.position.set(i,a):(s.x=i,s.y=a),n.scale!==void 0&&n.scale!==1&&s.scale&&(typeof s.scale.set=="function"?s.scale.set(n.scale,n.scale):(s.scale.x=n.scale,s.scale.y=n.scale))}function Ls(s,e,t,n=.2,i=1,a=!0,r=!1){let o=To(t,n),l=rn(t,n/2);ve(s,te(e),l);let c=a?i*ye.scaleFactor:i;we(s,c),r&&!Ii.find(d=>d.element===s)&&xo(s,Ls,e,t,n,i,a)}function ko(s,e,t,n=.1,i=1){ve(s,te(e),sn(t,n)),we(s,i)}function Io(s,e,t,n=0,i=0,a=1){ve(s,te(e,n),te(t,i)),we(s,a)}function jo(s,e,t,n=.1,i=1){ve(s,on(e,n),te(t)),we(s,i)}function Mo(s,e,t,n=.1,i=1){ve(s,ln(e,n),te(t)),we(s,i)}function Po(s,e,t,n=.05,i=.05,a=1){ve(s,on(e,i),rn(t,n)),we(s,a)}function _o(s,e,t,n=.05,i=.05,a=1){ve(s,ln(e,i),rn(t,n)),we(s,a)}function Oo(s,e,t,n=.05,i=.05,a=1){ve(s,on(e,i),sn(t,n)),we(s,a)}function Ro(s,e,t,n=.05,i=.05,a=1){ve(s,ln(e,i),sn(t,n)),we(s,a)}function ve(s,e,t){s&&s.position?typeof s.position.set=="function"?s.position.set(e,t):(s.position.x=e,s.position.y=t):s&&(s.x=e,s.y=t)}function we(s,e){e!==1&&s&&s.scale&&(typeof s.scale.set=="function"?s.scale.set(e,e):s.scale.x!==void 0&&s.scale.y!==void 0&&(s.scale.x=e,s.scale.y=e))}var Ne={default:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}},wide:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.9,screen_scale_y:1.1},engine:{scale:1,background_scale:1.1,background_offset_y:0,background_alpha:.95,label_pulse_speed:3,label_pulse_intensity:.03}},square:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.85,screen_scale_y:.85},engine:{scale:1,background_scale:1,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}},tall:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1.1,screen_scale_y:.9},engine:{scale:1,background_scale:.95,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}}};function zo(s){return s&&Ne[s]?JSON.parse(JSON.stringify(Ne[s])):JSON.parse(JSON.stringify(Ct))}function St(s){Object.keys(s).forEach(e=>{let t=e;Ct[t]&&s[t]&&Object.assign(Ct[t],s[t])}),console.log("Config applied:",s)}function $o(s,e){let t=s/e;t>1.6?(St(Ne.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(St(Ne.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(St(Ne.square),console.log("Applied SQUARE config for ratio:",t)):(St(Ne.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let s=window;s.configPresets=Ne,s.resolveAnchorVec2=s.resolveAnchorVec2||an,s.resolveScreenAnchorPoint=s.resolveScreenAnchorPoint||As,s.resolveScreenRatioPoint=s.resolveScreenRatioPoint||Ts}wn();function V(s,e){let t=(i,a)=>a===0?i:t(a,i%a),n=t(s,e);return`${s/n}:${e/n}`}var td=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:V(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:V(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:V(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:V(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:V(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:V(360,780)}],nd=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:V(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:V(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:V(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:V(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:V(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:V(412,915)}],id=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:V(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:V(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:V(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:V(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:V(800,1280)}],qi=[{id:"playable-portrait",label:"Playable Portrait",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"mraid-320x480",label:"MRAID 320\xD7480",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"playable",ratio:V(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:V(768,1024),mraidScale:.7}];var Vi=[...qi],Wi=[{category:"playable",label:"Playable Ad",devices:qi}],xn=qi[0];function qe(s){return Vi.find(e=>e.id===s)||xn}function qo(s){return Vi.filter(e=>e.category===s)}J();var Me=class{async updateProperty(e,t,n,i={}){var l,c,d;console.log("[PropertyUpdateManager] Updating:",e,t,n);let a=window.getEditableObjectConfig;if(typeof a!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let r=a(e);if(!r){console.error("[PropertyUpdateManager] Config not found for:",e);return}ce({objectId:e,path:t,value:n},{persist:!0});let o=window.applyEditableObjectConfig;if(typeof o=="function"){let p=window.__editableConfig,u=(d=(c=(l=p==null?void 0:p.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:r;await o(e,u),console.log("[PropertyUpdateManager] Applied config successfully")}else console.warn("[PropertyUpdateManager] applyEditableObjectConfig not available");this.triggerRefresh(e),i.refreshInspector&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}getNestedProperty(e,t){let n=t.split("."),i=e;for(let a of n)if(i&&typeof i=="object"&&a in i)i=i[a];else return;return i}triggerRefresh(e){let t=window.__refreshHierarchy;typeof t=="function"&&t(),window.dispatchEvent(new CustomEvent("inspector:property-updated",{detail:{objectId:e}}))}};function Yi(s){let e=document.createElement("input");e.type="file",e.accept="image/*",e.onchange=async t=>{var a;let n=(a=t.target.files)==null?void 0:a[0];if(!n)return;let i=new FileReader;i.onload=async()=>{let r=i.result,o=s.category||"misc",c=`${(s.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")||"new_asset"}_uploaded`;try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:`${c}.png`,data:r,overwrite:!0})})).json();if(!(p!=null&&p.success)){alert(`Upload failed: ${(p==null?void 0:p.error)||"Unknown error"}`);return}let u=window.addAssetToRegistry;typeof u=="function"&&u(o,`${c}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch{}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),await s.onApply(p.path)}catch(d){console.error("[QuickActionsBar] Upload error:",d),alert("Upload failed. Check console.")}},i.readAsDataURL(n)},e.click()}var En=class{constructor(){this.updateManager=new Me}async handleAction(e,t,n){console.log("[QuickActionsBar] Action:",e,t,n);let i=window.getEditableObjectConfig;if(typeof i!="function")return;let a=i(t);if(!a)return;let r=this.updateManager.getNestedProperty(a,n);if(e==="ai-convert"||e==="upload"||e==="library"){let o=n==="ui.text"||n==="render.asset.path",l=n==="render.asset.path";o&&(await this.prepareForImageConversion(t,a),e==="ai-convert"&&n!=="render.asset.path"&&(n="render.asset.path"))}switch(e){case"library":this.openLibrary(t,n,r);break;case"ai-edit":this.openAIEditor(t,n,r);break;case"upload":this.openUpload(t,n);break;case"reset":await this.resetToDefault(t,n);break;case"ai-convert":this.handleAiConvert(t,n,r);break;default:console.warn("[QuickActionsBar] Unknown action:",e)}}async prepareForImageConversion(e,t){var n,i;if(console.log("[QuickActionsBar] Preparing for image conversion:",e),t.render||(t.render={alpha:1,visible:!0}),(t.render.alpha===0||t.render.alpha===void 0)&&(t.render.alpha=1,await this.updateManager.updateProperty(e,"render.alpha",1)),(t.render.visible===!1||t.render.visible===void 0)&&(t.render.visible=!0,await this.updateManager.updateProperty(e,"render.visible",!0)),t.render.asset||(t.render.asset={type:"image",path:""}),t.render.asset.type!=="image"&&(t.render.asset.type="image",await this.updateManager.updateProperty(e,"render.asset",{type:"image",path:t.render.asset.path||""})),t.ui&&t.ui.renderMode!=="png"){await this.updateManager.updateProperty(e,"ui.renderMode","png",{refreshInspector:!0}),await this.updateManager.updateProperty(e,"render.tint","#ffffff");let r=((i=(n=t.transform)==null?void 0:n.scale)!=null?i:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",r),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",r)}this.ensureSlotInRegistry(e,t)}ensureSlotInRegistry(e,t){var o,l,c;let n=window.getEditableAssets;if(typeof n!="function")return;let i=n();if(!i||!i.slots)return;let a=e.startsWith("json.")?e.replace("json.",""):e;if(!i.slots.some(d=>d.objectId===a||d.slotId===a)){let d=((o=t.identity)==null?void 0:o.category)||"ui";console.log("[QuickActionsBar] Adding new slot to registry for converted object:",a),i.slots.push({slotId:a,displayName:a.replace(/_/g," "),objectId:a,category:d,currentAsset:((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.path)||"",defaultAsset:"",libraryFolder:d,assetType:"image"}),i.categories&&!i.categories.includes(d)&&i.categories.push(d),i.libraryAssets&&!i.libraryAssets[d]&&(i.libraryAssets[d]=[]);let p=window.reRenderAssetLibrary;typeof p=="function"&&p()}}openLibrary(e,t,n){var a;let i=window.__debugContext;if(i){if(i.activeTab!=="library"){i.activeTab="library";let r=window.__updateWorkbenchTabs;typeof r=="function"&&r()}if(i.libraryPanel){let r=window.getEditableObjectConfig,o=r==null?void 0:r(e),l=(a=o==null?void 0:o.identity)==null?void 0:a.category;l||(l=t.split(".")[0]==="render"?"environment":"ui"),console.log("[QuickActionsBar] Highlighting library slot:",e,"category:",l),i.libraryPanel.highlightSlot(e,l)}}}openAIEditor(e,t,n){let i=window.__openAiEditor;if(typeof i=="function"){let a=t.split(".").pop()||t;i(a,`Edit ${a} for ${e}`,n,{objectId:e,path:t})}else console.warn("[QuickActionsBar] AI Editor not available")}openUpload(e,t){var r;let n=window.getEditableObjectConfig,i=n==null?void 0:n(e),a=((r=i==null?void 0:i.identity)==null?void 0:r.category)||(t.split(".")[0]==="render"?"environment":"ui");Yi({objectId:e,category:a,onApply:async o=>{var d,p;await this.updateManager.updateProperty(e,t,o);let l=window.__debugContext;(p=(d=l==null?void 0:l.options)==null?void 0:d.onPropertyChange)==null||p.call(d,e,t,o);let c=window.__highlightLibrarySlot;typeof c=="function"&&setTimeout(()=>{c(e,a)},500),window.dispatchEvent(new CustomEvent("inspector:refresh"))}})}async resetToDefault(e,t){console.log("[QuickActionsBar] Reset to default:",e,t);try{let n=await this.getDefaultValue(e,t);n!==void 0?(await this.updateManager.updateProperty(e,t,n),console.log("[QuickActionsBar] Reset to default value:",n)):alert("No default value found for this property.")}catch(n){console.error("[QuickActionsBar] Failed to reset to default:",n),alert("Failed to reset property. Check console for details.")}}async getDefaultValue(e,t){let n=t.split(".");if(n.length<2)return;let i=n[0],a=n.slice(1),r=window.__editableConfig;if(!(r!=null&&r.schemas))return;let o=null;if(r.schemas instanceof Map?o=r.schemas.get(i):typeof r.schemas=="object"&&(o=r.schemas[i]),!(o!=null&&o.defaults))return;let l=o.defaults;for(let c of a)if(l&&typeof l=="object")l=l[c];else return;return l}handleAiConvert(e,t,n){let i=window.__openAiEditor;if(typeof i=="function"){let r=`A single, high-quality, high-detail game UI icon/asset representing "${String(n||e.replace(/_/g," ").replace("json.",""))}". Modern stylized 3D rendered style, vibrant colors, soft lighting, isolated on solid magenta background, highly polished professional game art.`,o="render.asset.path";console.log("[QuickActionsBar] AI Convert for:",e,"from:",t,"to:",o),i(e,r,"",{objectId:e,path:o});let l=window.__debugContext;if(l){l.activeTab="ai";let c=window.__updateWorkbenchTabs;typeof c=="function"&&c()}}else console.warn("[QuickActionsBar] AI Editor not available")}};var Vo=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],Wo=["environment","ui","character","system","backgrounds"],Yo=["bg","world","ui"],Fs={SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},DragToWin:{targetId:"",successDistance:80},DragSnap:{snapTargetId:"",snapDistance:40},JoystickMove:{speed:6,bounds:{left:-400,right:400,top:-300,bottom:300}}},Sn=class{constructor(){this.modal=null;this.state=null}open(e){this.state=this.createInitialState(e),this.createModal(),document.body.appendChild(this.modal),this.attachEventListeners(),this.updateStepUI()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),window.__wizardAssetPicker=null,this.modal=null,this.state=null}createInitialState(e){return{step:1,objectType:"sprite",instanceId:"",displayName:"",category:"environment",screenId:e.screenId,layer:"world",positionMode:"static",anchorPreset:"center",anchorX:.5,anchorY:.5,positionX:0,positionY:0,offsetX:0,offsetY:0,scale:.2,rotation:0,zIndex:0,assetPath:"",tint:"",alpha:1,text:"",font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",graphicsWidth:200,graphicsHeight:200,graphicsFill:"#FFFFFF",graphicsAlpha:1,interactionEnabled:!1,dragEnabled:!1,hoverEnabled:!1,clickEnabled:!1,logicId:"",logicPropsRaw:""}}createModal(){let e=document.createElement("div");e.className="wizard-modal",e.innerHTML=`
46
+ `,this.modal=i}attachModalListeners(){if(!this.modal)return;this.modal.querySelectorAll("[data-modal-close]").forEach(r=>{r.addEventListener("click",()=>this.close())}),this.modal.querySelectorAll("[data-tab]").forEach(r=>{r.addEventListener("click",o=>{let c=o.target.dataset.tab;c&&this.switchTab(c)})});let i=this.modal.querySelector("[data-ai-generate]");i==null||i.addEventListener("click",()=>{this.openAiEditor("generate")});let n=this.modal.querySelector("[data-ai-edit]");n==null||n.addEventListener("click",()=>{this.openAiEditor("edit")});let a=this.modal.querySelector("[data-modal-apply]");a==null||a.addEventListener("click",()=>{this.apply()}),this.modal.addEventListener("click",r=>{r.target===this.modal&&this.close()})}switchTab(e){if(!this.modal)return;this.modal.querySelectorAll("[data-tab]").forEach(n=>{n.classList.toggle("active",n.getAttribute("data-tab")===e)}),this.modal.querySelectorAll("[data-tab-panel]").forEach(n=>{n.classList.toggle("active",n.getAttribute("data-tab-panel")===e)})}openAiEditor(e){let t=window.__openAiEditor;if(typeof t!="function"){alert("AI Editor not available. Please check your setup.");return}let i="";e==="edit"&&this.currentAsset?i=`Edit this image: ${this.currentObjectId}`:i=`Create an image for: ${this.currentObjectId}`,t(this.currentObjectId||"unknown",i,this.currentAsset,{path:this.currentPath,onApply:n=>{this.onApplyCallback&&this.onApplyCallback(n),this.close()}})}apply(){this.onApplyCallback&&this.onApplyCallback("library/placeholder.png"),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.currentObjectId=null,this.currentPath=null,this.onApplyCallback=null}}});var Ol={};Et(Ol,{COLORS:()=>he,ConfigWatcher:()=>Ve,DebugPanel:()=>Ut,DefaultReloadStrategy:()=>Rt,Handler:()=>le,PlayableLoadingScreen:()=>pn,PreviewShell:()=>ln,STROKE_WIDTH:()=>Dr,THEME:()=>Hr,applyConfigOverride:()=>ne,applyConfigOverrides:()=>Pe,applyConfigsToDisk:()=>mi,applyDefaults:()=>qe,baseLottie:()=>Cn,bootstrap:()=>El,clearConfigOverrides:()=>ae,clearConfigOverridesForObject:()=>$s,configOverrideManager:()=>Ds,createPreviewShell:()=>Oa,deepClone:()=>Y,default:()=>He,defaultPreset:()=>Ei,deviceGroups:()=>ea,devicePresets:()=>Qn,diffConfigs:()=>Wn,exportConfigsAsJSON:()=>Ue,getConfigOverrides:()=>Z,getConfigStateSummary:()=>Me,getOverrideMode:()=>Mt,getPresetById:()=>We,getPresetsByCategory:()=>Jo,loadAllObjectConfigs:()=>vi,loadComponentSchemas:()=>yi,loadEngineConfig:()=>wi,loadGamePromptConfig:()=>Gn,loadObjectCentricConfig:()=>Ce,loadObjectConfig:()=>je,loadSceneConfig:()=>xi,redoLastConfigChange:()=>fi,rehydrateObject:()=>Yn,removeConfigOverride:()=>jt,resetToApplied:()=>_t,resetToOriginal:()=>bi,setBootstrapDependencies:()=>xl,setOverrideMode:()=>Fn,setupHotReload:()=>Jn,setupLiveEditBridge:()=>cn,toLegacyFormat:()=>qn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Ns,undoLastConfigChange:()=>hi,validateObjectConfig:()=>ot});module.exports=so(Ol);var ke={};function ei(s,e,t=!1){ke[s]||(ke[s]=[]),ke[s].push({fn:e,once:t})}function wn(s,e){if(ke[s]){if(!e){delete ke[s];return}ke[s]=ke[s].filter(t=>t.fn!==e)}}function ti(s,...e){let t=ke[s];if(t)for(let i of[...t])i.fn(...e),i.once&&wn(s,i.fn)}function ee(s,e){ei(s,e,!0)}var V=null,re=[],it=null;function Za(s){V=s,re=[],it!==null&&(clearTimeout(it),it=null)}function Qa(){var s,e,t;return{endpoint:(V==null?void 0:V.endpoint)||"",transport:(V==null?void 0:V.transport)||"beacon",batchSize:(s=V==null?void 0:V.batchSize)!=null?s:10,flushIntervalMs:(e=V==null?void 0:V.flushIntervalMs)!=null?e:300,maxQueue:(t=V==null?void 0:V.maxQueue)!=null?t:200,debug:!!(V!=null&&V.debug)}}async function Xa(s,e,t,i){let n=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let a=navigator.sendBeacon(s,new Blob([n],{type:"application/json"}));i&&console.log("[handler.telemetry] beacon",a,e);return}catch(a){i&&console.warn("[handler.telemetry] beacon failed, fallback to fetch",a)}try{await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}),i&&console.log("[handler.telemetry] fetch",e)}catch(a){i&&console.warn("[handler.telemetry] fetch failed",a)}}function xn(s,e){let t=Qa();if(e&&t.endpoint){if(re.push(s),re.length>t.maxQueue&&(re=re.slice(re.length-t.maxQueue)),re.length>=t.batchSize){Ja();return}it===null&&(it=window.setTimeout(()=>{it=null,Ja()},t.flushIntervalMs))}}async function Ja(){let s=Qa();if(!s.endpoint||re.length===0)return;let e=re.splice(0,s.batchSize);await Xa(s.endpoint,{events:e},s.transport,s.debug),re.length>0&&await Xa(s.endpoint,{events:re.splice(0,s.batchSize)},s.transport,s.debug)}function es(s){return Math.max(0,Math.min(1,s))}function ro(s){let e=String(s!=null?s:"power2.out");if(e==="linear")return t=>t;if(e==="sine.inOut")return t=>.5-Math.cos(Math.PI*t)/2;if(e==="power2.out"||e==="easeOutQuad")return t=>1-(1-t)*(1-t);if(e.startsWith("back.out")){let t=e.match(/back\.out\(([\d.]+)\)/),i=t?Number(t[1]):1.8;return n=>1+(i+1)*Math.pow(n-1,3)+i*Math.pow(n-1,2)}return t=>1-(1-t)*(1-t)}function Ct(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function oo(s,e){let t=s==null?void 0:s[e];return typeof t=="number"?t:0}function ts(s,e,t){try{s[e]=t}catch{}}function lo(s){let e=s==null?void 0:s.scale;if(!e)return null;let t=typeof e.x=="number"?e.x:1,i=typeof e.y=="number"?e.y:1;return{x:t,y:i}}function is(s,e){let t=s==null?void 0:s.scale;if(t)try{typeof t.set=="function"?t.set(e.x,e.y):(typeof t.x=="number"&&(t.x=e.x),typeof t.y=="number"&&(t.y=e.y))}catch{}}function ns(s,e){let t=lo(s);if(!t)return{from:null,to:null};let i=null,n=null;return typeof e.scale=="number"?(i=e.scale,n=e.scale):e.scale&&typeof e.scale=="object"&&(typeof e.scale.x=="number"&&(i=e.scale.x),typeof e.scale.y=="number"&&(n=e.scale.y)),typeof e.scaleX=="number"&&(i=e.scaleX),typeof e.scaleY=="number"&&(n=e.scaleY),i===null&&n===null?{from:null,to:null}:{from:{x:t.x,y:t.y},to:{x:i!=null?i:t.x,y:n!=null?n:t.y}}}function as(){let s=new Set,e=new WeakMap,t=null,i=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,o(),s.size>0&&i()})},n=d=>{var u;s.add(d);let p=(u=e.get(d.target))!=null?u:new Set;p.add(d),e.set(d.target,p),i()},a=d=>{s.delete(d);let p=e.get(d.target);p&&(p.delete(d),p.size===0&&e.delete(d.target))},r=d=>{d.killed||(d.killed=!0,a(d))},o=()=>{var p,u;let d=Ct();for(let g of Array.from(s)){if(g.killed||g.paused)continue;let h=d-g.startMs-g.delayMs;if(h<0)continue;let f=g.durationMs>0?h/g.durationMs:1,m=es(f),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(f),b-1):0;if(g.repeat>0&&f>=1){let E=f-y;m=es(E)}let v=g.ease(m);g.yoyo&&y%2===1&&(v=1-v);for(let E of g.props)ts(g.target,E.key,E.from+(E.to-E.from)*v);g.scaleFrom&&g.scaleTo&&is(g.target,{x:g.scaleFrom.x+(g.scaleTo.x-g.scaleFrom.x)*v,y:g.scaleFrom.y+(g.scaleTo.y-g.scaleFrom.y)*v});try{(p=g.onUpdate)==null||p.call(g)}catch{}if(f>=b){r(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var E;let g=Math.max(0,(typeof p.duration=="number"?p.duration:.5)*1e3),h=Math.max(0,(typeof p.delay=="number"?p.delay:0)*1e3+((E=u==null?void 0:u.delayMsOverride)!=null?E:0)),f=ro(p.ease),m=typeof p.repeat=="number"?Math.max(0,p.repeat|0):0,b=p.yoyo===!0,y=new Set(["duration","delay","ease","repeat","yoyo","onUpdate","onComplete","scale","scaleX","scaleY"]),v=[];for(let P of Object.keys(p)){if(y.has(P))continue;let M=p[P];typeof M=="number"&&v.push({key:P,from:oo(d,P),to:M})}let w=ns(d,p);return{target:d,startMs:Ct(),delayMs:h,durationMs:g,ease:f,props:v,scaleFrom:w.from,scaleTo:w.to,repeat:m,yoyo:b,onUpdate:typeof p.onUpdate=="function"?p.onUpdate:void 0,onComplete:typeof p.onComplete=="function"?p.onComplete:void 0,killed:!1,paused:!1,pauseAtMs:null}},c={to(d,p){let u=l(d,p);return n(u),{kill:()=>r(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=Ct())},resume:()=>{var f;if(!u.paused)return;let g=(f=u.pauseAtMs)!=null?f:Ct(),h=Ct()-g;u.startMs+=h,u.paused=!1,u.pauseAtMs=null},isActive:()=>!u.killed&&!u.paused}},fromTo(d,p,u){return c.set(d,p),c.to(d,u)},set(d,p){if(!d||!p)return;for(let g of Object.keys(p)){let h=p[g];g==="scale"||g==="scaleX"||g==="scaleY"||typeof h=="number"&&ts(d,g,h)}let u=ns(d,p);u.to&&is(d,u.to)},killTweensOf(d){let p=e.get(d);if(p)for(let u of Array.from(p))r(u)},timeline(d={}){let p=[],u=0,g=!1,h=[],f=y=>{if(typeof y=="number")return Math.max(0,y*1e3);let v=typeof y=="string"?y.trim():"";return v.startsWith("+=")?u+Math.max(0,Number(v.slice(2))*1e3||0):v?Math.max(0,Number(v)*1e3||0):u},m=y=>{p.push(y);let v=Math.max(0,(typeof y.vars.duration=="number"?y.vars.duration:.5)*1e3);u=Math.max(u,y.atMs+v)},b={to(y,v,w){return m({kind:"to",target:y,vars:v,atMs:f(w)}),b},fromTo(y,v,w,E){return m({kind:"fromTo",target:y,vars:w,from:v,atMs:f(E)}),b},play(){var y,v;if(g)return b;g=!0,h=[];for(let w of p)w.kind==="fromTo"&&c.set(w.target,(y=w.from)!=null?y:{}),h.push(c.to(w.target,{...w.vars,delay:w.atMs/1e3+((v=w.vars.delay)!=null?v:0)}));return b},pause(){for(let y of h)y.pause();return b},kill(){for(let y of h)y.kill();h=[],g=!1}};return d.paused||b.play(),b}};return c}function ss(){if(typeof window=="undefined")return;let s=window;if(!s.gsap)try{s.gsap=as()}catch{}}var rs={name:"handler-playable-sdk",version:"0.5.548",type:"module",description:"Handler Playable SDK v0.1 with contract-aligned surface (root sandbox, canonical event envelope).",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./pixi":{types:"./dist/pixi/index.d.ts",import:"./dist/pixi/index.js",require:"./dist/pixi/index.cjs"},"./pixi/index.css":{import:"./dist/pixi/index.css",require:"./dist/pixi/index.css"},"./three":{types:"./dist/three/index.d.ts",import:"./dist/three/index.js",require:"./dist/three/index.cjs"},"./cli":{types:"./dist/cli/index.d.ts",import:"./dist/cli/index.js",require:"./dist/cli/index.cjs"}},bin:{"handler-student-helper":"./bin/student-helper.mjs","handler-validate":"./bin/validate.mjs","handler-sync-screens":"./bin/sync-screens.mjs","handler-brand-dna":"./bin/brand-dna.mjs","handler-setup-library":"./bin/setup-library.mjs","handler-screen-helper":"./bin/screen-helper.mjs"},scripts:{prebuild:"python3 src/preview/build-css.py",build:"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --minify --external lottie-web && npm run create-mjs-symlinks && npm run postbuild-cli && npm run obfuscate && npm run postbuild",postbuild:"python3 src/preview/copy-css-to-dist.py","postbuild-cli":"cp src/cli/*.mjs dist/cli/ && chmod +x dist/cli/*.mjs && chmod +x bin/*.mjs","create-mjs-symlinks":"cd dist && ln -sf index.js index.mjs && cd pixi && ln -sf index.js index.mjs && cd ../three && ln -sf index.js index.mjs","build:dev":"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --external lottie-web && npm run create-mjs-symlinks && npm run postbuild-cli",obfuscate:"javascript-obfuscator dist/pixi/index.js --output dist/pixi/index.js --config obfuscator.config.json && javascript-obfuscator dist/three/index.js --output dist/three/index.js --config obfuscator.config.json && javascript-obfuscator dist/cli/index.js --output dist/cli/index.js --config obfuscator.config.json && npm run obfuscate-cli","obfuscate-cli":'for file in dist/cli/*.mjs; do javascript-obfuscator "$file" --output "$file" --config obfuscator.config.json; done',lint:"eslint 'src/**/*.{ts,tsx}'",typecheck:"tsc --noEmit",prepublishOnly:"npm run build","publish:update":"node scripts/publish-and-update.cjs patch","publish:update:minor":"node scripts/publish-and-update.cjs minor","publish:update:major":"node scripts/publish-and-update.cjs major"},author:"Handler",license:"MIT",publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/HandlerAIGames/handler-playable-sdk.git"},files:["dist","bin","LICENSE","README.md"],peerDependencies:{"lottie-web":"^5.0.0","pixi.js":"^8.0.0",three:"^0.182.0"},peerDependenciesMeta:{"pixi.js":{optional:!0},three:{optional:!0},"lottie-web":{optional:!0}},devDependencies:{"@types/three":"^0.182.0",eslint:"^9.39.2","javascript-obfuscator":"^5.1.0","pixi.js":"8.8.1",three:"^0.182.0","ts-node":"^10.9.2",tsup:"^8.4.0",typescript:"^5.7.2","typescript-eslint":"^8.53.0"},dependencies:{"@google/genai":"^1.35.0","@google/generative-ai":"^0.24.1",jszip:"^3.10.1",sharp:"^0.34.5"}};var te=0,po=te++,os=te++,ls=te++,cs=te++,ds=te++,ps=te++,us=te++,gs=te++,hs=te++,fs=te++,ms=te++,bs=te++,G=po;function ys(){return G===os}function vs(){return G===ls}function ws(){return G===cs}function xs(){return G===ds}function nt(){return G===ps}function at(){return G===us}function Ss(){return G===gs}function Es(){return G===hs}function Cs(){return G===fs}function Sn(){return G===ms}function En(){return G===bs}function As(){let s=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(s==="mraid")try{mraid.getState(),G=os;return}catch{}else if(s==="dapi")try{dapi.isReady(),G=ls;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(G=cs)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(G=ds)}catch{}else if(e==="mintegral")window.gameReady&&(G=ps);else if(e==="tapjoy")window.TJ_API&&(G=us);else if(e==="tiktok")window.openAppStore&&(G=gs);else if(e==="smadex")try{window.smxTracking&&(G=hs)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(G=fs)}catch{}else e==="vungle"?G=ms:(s==="nucleo"||e==="nucleo")&&(G=bs)}var ii=tt(require("lottie-web"),1),Cn=ii.default;typeof window!="undefined"&&(window.lottie=ii.default,window.__baseLottie=ii.default);var uo=require("pixi.js");var An=require("pixi.js");var go=null;function Tn(s){go=s}ni();Ln();var At=require("pixi.js");ni();var vo=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Mn=vo;if(typeof window!="undefined")try{let s=new XMLHttpRequest;if(s.open("GET","./build-settings.json",!1),s.send(),s.status===200&&s.responseText){let e=JSON.parse(s.responseText);e!=null&&e.buildMode&&(Mn=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Mn}`))}}catch{}function wo(s){var t,i,n,a,r;if(typeof window!="undefined"&&window.resolveAnchorVec2)return window.resolveAnchorVec2(s);let e={center:{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};if(Array.isArray(s))return{x:(t=s[0])!=null?t:.5,y:(i=s[1])!=null?i:.5};if(s&&typeof s=="object"&&"x"in s&&"y"in s)return{x:(n=s.x)!=null?n:.5,y:(a=s.y)!=null?a:.5};if(typeof s=="string"){let o=s.trim().toLowerCase();return(r=e[o])!=null?r:{x:.5,y:.5}}return null}var de=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Mn}`);let n=(l=t==null?void 0:t.render)==null?void 0:l.asset;if(!n){console.log(`[ObjectFactory] No asset definition for: ${e}, returning empty container`);let f=new At.Container;return this.applyTransform(f,t==null?void 0:t.transform,t),f}let a=(c=t==null?void 0:t.identity)==null?void 0:c.id;console.log(`[ObjectFactory] Calling AssetLoader.load() for: ${e}, configId: ${a}, type: ${n.type}, path: ${n.path}`);let r=await Fe.load(e,n,i,a);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(d=r==null?void 0:r.constructor)==null?void 0:d.name}`);let o;if(n.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",r,"for object:",e),o=new At.Sprite(r),console.log("[ObjectFactory] Created object:",o,"type:",(p=o==null?void 0:o.constructor)==null?void 0:p.name),this.applyTransform(o,t==null?void 0:t.transform,t);else if(n.type==="json")if(console.log("[ObjectFactory] JSON asset for",e,"rawAsset type:",(u=r==null?void 0:r.constructor)==null?void 0:u.name,r),r&&(((g=r.constructor)==null?void 0:g.name)==="Container"||r instanceof At.Container)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let f=[n.path,`/assets/${n.path}`,`assets/${n.path}`,`../assets/${n.path}`],m=!1;for(let b of f)try{let y=await fetch(b);if(y.ok){o=await y.json(),console.log("[ObjectFactory] Reloaded JSON directly from:",b,"type:",(h=o==null?void 0:o.constructor)==null?void 0:h.name),m=!0;break}}catch{continue}m||(console.error("[ObjectFactory] Failed to reload JSON from any path"),o=r)}else o=r;else o=r,o&&typeof o=="object"&&("x"in o||"position"in o)&&this.applyTransform(o,t==null?void 0:t.transform,t);return o}static applyTransform(e,t,i){var n,a,r,o;if(!(!t||!e)&&(t.position&&("x"in e&&"y"in e?(e.x=(n=t.position.x)!=null?n:0,e.y=(a=t.position.y)!=null?a:0):"position"in e&&e.position&&e.position.set((r=t.position.x)!=null?r:0,(o=t.position.y)!=null?o:0)),t.scale!==void 0&&"scale"in e&&e.scale&&(typeof e.scale=="object"&&"set"in e.scale?e.scale.set(t.scale):e.scale=t.scale),t.rotation!==void 0&&"rotation"in e&&(e.rotation=t.rotation),t.anchor&&"anchor"in e&&e.anchor)){let l=wo(t.anchor);l&&("set"in e.anchor?e.anchor.set(l.x,l.y):(e.anchor.x=l.x,e.anchor.y=l.y))}}};var Tt=class{constructor(){this.config=null}init(e){this.config=e}get(e){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return this.config.objects.get(e)}getAllIds(){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return Array.from(this.config.objects.keys())}has(e){return this.config?this.config.objects.has(e):!1}};var Eo=tt(require("pixi.js"),1);typeof window!="undefined"&&(window.__basePixi=Eo);st();var ai=require("pixi.js");st();var On=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new Tt}init(e,t){this.registry.init(e),this.app=t}updateConfig(e){this.registry.init(e),this.instanceCache.clear(),this.readyPromise=null}async ready(){this.readyPromise&&await this.readyPromise;let t=this.registry.getAllIds().filter(n=>!this.instanceCache.has(n));if(t.length===0)return;let i=async n=>{n.length&&(console.log("[Assets] Loading objects:",n),await Promise.all(n.map(async a=>{var o;let r=this.registry.get(a);if(!r){console.warn("[Assets] No config found for object:",a);return}try{let l=await de.create(a,r,this.app);this.instanceCache.set(a,l),console.log("[Assets] Loaded object:",a,(o=l==null?void 0:l.constructor)==null?void 0:o.name)}catch(l){console.error("[Assets] Failed to load object:",a,l)}})))};return this.readyPromise=(async()=>{await i(t);let n=this.registry.getAllIds().filter(a=>!this.instanceCache.has(a));n.length>0&&(console.warn("[Assets] Retrying missing assets:",n),await i(n)),console.log("[Assets] Ready. Cached objects:",Array.from(this.instanceCache.keys()))})(),this.readyPromise}resetScene(){this.instanceCache.clear(),this.readyPromise=null}async reloadObject(e){let t=this.registry.get(e);if(t){let i=await de.create(e,t,this.app);this.instanceCache.set(e,i)}}get(e){return this.instanceCache.get(e)}},Co=new On,Ao=new Proxy(Co,{get(s,e){if(e in s&&typeof s[e]=="function")return s[e].bind(s);if(s.get(e))return s.get(e)}});st();var Ms=require("pixi.js"),xe={width:400,height:600,designWidth:400,scaleFactor:1},ri={scale:1,position:1},zn=[];function Lo(s,e,t,i,n,a,r){zn.push({element:s,originalScale:a,positionHelper:e,heightPercent:n}),e(s,t,i,n,a,r,!1)}function ko(){zn.forEach(({element:s,originalScale:e,positionHelper:t,heightPercent:i})=>{let n=e*xe.scaleFactor;t(s,xe.width,xe.height,i,n,!0,!1)})}function Rn(s,e){console.log(`[SCREEN] updateScreenState called: ${s}x${e}`),xe.width=s,xe.height=e,xe.scaleFactor=Math.min(s/xe.designWidth,1.15),ri.scale=xe.scaleFactor,ri.position=1,console.log(`[SCREEN] Global multipliers - scale: ${ri.scale.toFixed(3)}`),ko()}var ue={layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}};function Io(s,e,t){let i=ue[s];i&&i[e]!==void 0&&(i[e]=t,console.log(`Updated ${s}.${e} = ${t}`))}function Po(){return ue}var Mo={center:{x:.5,y:.5},"center-center":{x:.5,y:.5},middle:{x:.5,y:.5},"middle-center":{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},"left-center":{x:0,y:.5},"right-center":{x:1,y:.5},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};function si(s,e){return typeof s=="number"&&Number.isFinite(s)?s:e}function rt(s,e={x:.5,y:.5}){var t;if(Array.isArray(s))return{x:si(s[0],e.x),y:si(s[1],e.y)};if(s&&typeof s=="object"){let i=s;return{x:si(i.x,e.x),y:si(i.y,e.y)}}if(typeof s=="string"){let i=s.trim().toLowerCase();return(t=Mo[i])!=null?t:e}return e}function kt(s,e,t,i={}){var g,h,f,m,b,y;let n=rt(t),a=(g=i.inset)!=null?g:{},r=(h=i.padding)!=null?h:{x:0,y:0},o=((f=a.left)!=null?f:0)+r.x,l=((m=a.right)!=null?m:0)+r.x,c=((b=a.top)!=null?b:0)+r.y,d=((y=a.bottom)!=null?y:0)+r.y,p=Math.max(0,s-o-l),u=Math.max(0,e-c-d);return{x:o+p*n.x,y:c+u*n.y}}function It(s,e,t,i={}){var f,m,b,y,v,w;let n=(f=i.inset)!=null?f:{},a=(m=i.padding)!=null?m:{x:0,y:0},r=((b=n.left)!=null?b:0)+a.x,o=((y=n.right)!=null?y:0)+a.x,l=((v=n.top)!=null?v:0)+a.y,c=((w=n.bottom)!=null?w:0)+a.y,d=Math.max(0,s-r-o),p=Math.max(0,e-l-c),u=rt(t,{x:.5,y:.5}),g=Math.min(Math.max(u.x,0),1),h=Math.min(Math.max(u.y,0),1);return{x:r+d*g,y:l+p*h}}if(typeof window!="undefined"){let s=window.innerWidth,e=window.innerHeight,t=()=>{let i=window.innerWidth,n=window.innerHeight;(i!==s||n!==e)&&(s=i,e=n,Rn(i,n))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),Rn(window.innerWidth,window.innerHeight),window.updateDebugConfig=Io,window.getDebugConfig=Po,window.copyConfig=Bo,window.applyConfig=Lt,window.applyConfigForRatio=Uo,window.positionAtBottom=js,window.positionAtTop=Oo,window.positionAtCenter=Ro,window.positionAtLeft=zo,window.positionAtRight=$o,window.positionAtBottomLeft=Do,window.positionAtBottomRight=Ho,window.positionAtTopLeft=No,window.positionAtTopRight=Fo,window.applyPositionContract=_o,console.log("\u{1F3AE} Debug Config Functions Available:"),console.log("\u2022 updateDebugConfig(category, key, value)"),console.log("\u2022 getDebugConfig()"),console.log("\u2022 copyConfig(presetName)"),console.log("\u2022 applyConfig(config)"),console.log("\u2022 applyConfigForRatio(width, height)"),console.log("\u{1F4CD} Positioning Helpers Available (with scale):"),console.log("\u2022 positionAtBottom(element, w, h, percent, scale)"),console.log("\u2022 positionAtTop(element, w, h, percent, scale)"),console.log("\u2022 positionAtCenter(element, w, h, offsetX, offsetY, scale)"),console.log("\u2022 positionAtLeft/Right(element, w, h, percent, scale)"),console.log("\u2022 Corner positions: BottomLeft/Right, TopLeft/Right (all with scale)"),console.log("\u2022 applyPositionContract(element, w, h, contract)"),console.log("Example: positionAtCenter(mySprite, 400, 600, 0, -50, 1.2)")}function oi(s,e,t=0){return s*e+t}function li(s,e,t=0){return s*(1-e)+t}function ci(s,e,t=0){return s*e+t}function di(s,e,t=0){return s*(1-e)+t}function ie(s,e=0){return s/2+e}function jo(s,e){return s*e}function _o(s,e,t,i){var r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,E,P,M,x,_;let n=0,a=0;switch(i.type){case"top":n=ie(e,(o=(r=i.offset)==null?void 0:r.x)!=null?o:0),a=oi(t,i.percent,(c=(l=i.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":n=ie(e,(p=(d=i.offset)==null?void 0:d.x)!=null?p:0),a=li(t,i.percent,(g=(u=i.offset)==null?void 0:u.y)!=null?g:0);break;case"left":n=ci(e,i.percent,(f=(h=i.offset)==null?void 0:h.x)!=null?f:0),a=ie(t,(b=(m=i.offset)==null?void 0:m.y)!=null?b:0);break;case"right":n=di(e,i.percent,(v=(y=i.offset)==null?void 0:y.x)!=null?v:0),a=ie(t,(E=(w=i.offset)==null?void 0:w.y)!=null?E:0);break;case"center":n=ie(e,(M=(P=i.offset)==null?void 0:P.x)!=null?M:0),a=ie(t,(_=(x=i.offset)==null?void 0:x.y)!=null?_:0);break}s.position?s.position.set(n,a):(s.x=n,s.y=a),i.scale!==void 0&&i.scale!==1&&s.scale&&(typeof s.scale.set=="function"?s.scale.set(i.scale,i.scale):(s.scale.x=i.scale,s.scale.y=i.scale))}function js(s,e,t,i=.2,n=1,a=!0,r=!1){let o=jo(t,i),l=li(t,i/2);Se(s,ie(e),l);let c=a?n*xe.scaleFactor:n;Ee(s,c),r&&!zn.find(d=>d.element===s)&&Lo(s,js,e,t,i,n,a)}function Oo(s,e,t,i=.1,n=1){Se(s,ie(e),oi(t,i)),Ee(s,n)}function Ro(s,e,t,i=0,n=0,a=1){Se(s,ie(e,i),ie(t,n)),Ee(s,a)}function zo(s,e,t,i=.1,n=1){Se(s,ci(e,i),ie(t)),Ee(s,n)}function $o(s,e,t,i=.1,n=1){Se(s,di(e,i),ie(t)),Ee(s,n)}function Do(s,e,t,i=.05,n=.05,a=1){Se(s,ci(e,n),li(t,i)),Ee(s,a)}function Ho(s,e,t,i=.05,n=.05,a=1){Se(s,di(e,n),li(t,i)),Ee(s,a)}function No(s,e,t,i=.05,n=.05,a=1){Se(s,ci(e,n),oi(t,i)),Ee(s,a)}function Fo(s,e,t,i=.05,n=.05,a=1){Se(s,di(e,n),oi(t,i)),Ee(s,a)}function Se(s,e,t){s&&s.position?typeof s.position.set=="function"?s.position.set(e,t):(s.position.x=e,s.position.y=t):s&&(s.x=e,s.y=t)}function Ee(s,e){e!==1&&s&&s.scale&&(typeof s.scale.set=="function"?s.scale.set(e,e):s.scale.x!==void 0&&s.scale.y!==void 0&&(s.scale.x=e,s.scale.y=e))}var Be={default:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}},wide:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.9,screen_scale_y:1.1},engine:{scale:1,background_scale:1.1,background_offset_y:0,background_alpha:.95,label_pulse_speed:3,label_pulse_intensity:.03}},square:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.85,screen_scale_y:.85},engine:{scale:1,background_scale:1,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}},tall:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1.1,screen_scale_y:.9},engine:{scale:1,background_scale:.95,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}}};function Bo(s){return s&&Be[s]?JSON.parse(JSON.stringify(Be[s])):JSON.parse(JSON.stringify(ue))}function Lt(s){Object.keys(s).forEach(e=>{let t=e;ue[t]&&s[t]&&Object.assign(ue[t],s[t])}),console.log("Config applied:",s)}function Uo(s,e){let t=s/e;t>1.6?(Lt(Be.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(Lt(Be.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(Lt(Be.square),console.log("Applied SQUARE config for ratio:",t)):(Lt(Be.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let s=window;s.configPresets=Be,s.resolveAnchorVec2=s.resolveAnchorVec2||rt,s.resolveScreenAnchorPoint=s.resolveScreenAnchorPoint||kt,s.resolveScreenRatioPoint=s.resolveScreenRatioPoint||It}Si();function W(s,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(s,e);return`${s/i}:${e/i}`}var ld=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:W(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:W(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:W(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:W(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:W(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:W(360,780)}],cd=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:W(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:W(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:W(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:W(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:W(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:W(412,915)}],dd=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:W(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:W(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:W(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:W(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:W(800,1280)}],Zn=[{id:"playable-portrait",label:"Playable Portrait",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"mraid-320x480",label:"MRAID 320\xD7480",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"playable",ratio:W(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:W(768,1024),mraidScale:.7}];var Qn=[...Zn],ea=[{category:"playable",label:"Playable Ad",devices:Zn}],Ei=Zn[0];function We(s){return Qn.find(e=>e.id===s)||Ei}function Jo(s){return Qn.filter(e=>e.category===s)}K();var _e=class{async updateProperty(e,t,i,n={}){var l,c,d;console.log("[PropertyUpdateManager] Updating:",e,t,i);let a=window.getEditableObjectConfig;if(typeof a!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let r=a(e);if(!r){console.error("[PropertyUpdateManager] Config not found for:",e);return}ne({objectId:e,path:t,value:i},{persist:!0});let o=window.applyEditableObjectConfig;if(typeof o=="function"){let p=window.__editableConfig,u=(d=(c=(l=p==null?void 0:p.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:r;await o(e,u),console.log("[PropertyUpdateManager] Applied config successfully")}else console.warn("[PropertyUpdateManager] applyEditableObjectConfig not available");this.triggerRefresh(e),n.refreshInspector&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}getNestedProperty(e,t){let i=t.split("."),n=e;for(let a of i)if(n&&typeof n=="object"&&a in n)n=n[a];else return;return n}triggerRefresh(e){let t=window.__refreshHierarchy;typeof t=="function"&&t(),window.dispatchEvent(new CustomEvent("inspector:property-updated",{detail:{objectId:e}}))}};function ta(s){let e=document.createElement("input");e.type="file",e.accept="image/*",e.onchange=async t=>{var a;let i=(a=t.target.files)==null?void 0:a[0];if(!i)return;let n=new FileReader;n.onload=async()=>{let r=n.result,o=s.category||"misc",c=`${(s.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")||"new_asset"}_uploaded`;try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:`${c}.png`,data:r,overwrite:!0})})).json();if(!(p!=null&&p.success)){alert(`Upload failed: ${(p==null?void 0:p.error)||"Unknown error"}`);return}let u=window.addAssetToRegistry;typeof u=="function"&&u(o,`${c}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch{}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),await s.onApply(p.path)}catch(d){console.error("[QuickActionsBar] Upload error:",d),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var Ci=class{constructor(){this.updateManager=new _e}async handleAction(e,t,i){console.log("[QuickActionsBar] Action:",e,t,i);let n=window.getEditableObjectConfig;if(typeof n!="function")return;let a=n(t);if(!a)return;let r=this.updateManager.getNestedProperty(a,i);if(e==="ai-convert"||e==="upload"||e==="library"){let o=i==="ui.text"||i==="render.asset.path",l=i==="render.asset.path";o&&(await this.prepareForImageConversion(t,a),e==="ai-convert"&&i!=="render.asset.path"&&(i="render.asset.path"))}switch(e){case"library":this.openLibrary(t,i,r);break;case"ai-edit":this.openAIEditor(t,i,r);break;case"upload":this.openUpload(t,i);break;case"reset":await this.resetToDefault(t,i);break;case"ai-convert":this.handleAiConvert(t,i,r);break;default:console.warn("[QuickActionsBar] Unknown action:",e)}}async prepareForImageConversion(e,t){var i,n;if(console.log("[QuickActionsBar] Preparing for image conversion:",e),t.render||(t.render={alpha:1,visible:!0}),(t.render.alpha===0||t.render.alpha===void 0)&&(t.render.alpha=1,await this.updateManager.updateProperty(e,"render.alpha",1)),(t.render.visible===!1||t.render.visible===void 0)&&(t.render.visible=!0,await this.updateManager.updateProperty(e,"render.visible",!0)),t.render.asset||(t.render.asset={type:"image",path:""}),t.render.asset.type!=="image"&&(t.render.asset.type="image",await this.updateManager.updateProperty(e,"render.asset",{type:"image",path:t.render.asset.path||""})),t.ui&&t.ui.renderMode!=="png"){await this.updateManager.updateProperty(e,"ui.renderMode","png",{refreshInspector:!0}),await this.updateManager.updateProperty(e,"render.tint","#ffffff");let r=((n=(i=t.transform)==null?void 0:i.scale)!=null?n:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",r),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",r)}this.ensureSlotInRegistry(e,t)}ensureSlotInRegistry(e,t){var o,l,c;let i=window.getEditableAssets;if(typeof i!="function")return;let n=i();if(!n||!n.slots)return;let a=e.startsWith("json.")?e.replace("json.",""):e;if(!n.slots.some(d=>d.objectId===a||d.slotId===a)){let d=((o=t.identity)==null?void 0:o.category)||"ui";console.log("[QuickActionsBar] Adding new slot to registry for converted object:",a),n.slots.push({slotId:a,displayName:a.replace(/_/g," "),objectId:a,category:d,currentAsset:((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.path)||"",defaultAsset:"",libraryFolder:d,assetType:"image"}),n.categories&&!n.categories.includes(d)&&n.categories.push(d),n.libraryAssets&&!n.libraryAssets[d]&&(n.libraryAssets[d]=[]);let p=window.reRenderAssetLibrary;typeof p=="function"&&p()}}openLibrary(e,t,i){var a;let n=window.__debugContext;if(n){if(n.activeTab!=="library"){n.activeTab="library";let r=window.__updateWorkbenchTabs;typeof r=="function"&&r()}if(n.libraryPanel){let r=window.getEditableObjectConfig,o=r==null?void 0:r(e),l=(a=o==null?void 0:o.identity)==null?void 0:a.category;l||(l=t.split(".")[0]==="render"?"environment":"ui"),console.log("[QuickActionsBar] Highlighting library slot:",e,"category:",l),n.libraryPanel.highlightSlot(e,l)}}}openAIEditor(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let a=t.split(".").pop()||t;n(a,`Edit ${a} for ${e}`,i,{objectId:e,path:t})}else console.warn("[QuickActionsBar] AI Editor not available")}openUpload(e,t){var r;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e),a=((r=n==null?void 0:n.identity)==null?void 0:r.category)||(t.split(".")[0]==="render"?"environment":"ui");ta({objectId:e,category:a,onApply:async o=>{var d,p;await this.updateManager.updateProperty(e,t,o);let l=window.__debugContext;(p=(d=l==null?void 0:l.options)==null?void 0:d.onPropertyChange)==null||p.call(d,e,t,o);let c=window.__highlightLibrarySlot;typeof c=="function"&&setTimeout(()=>{c(e,a)},500),window.dispatchEvent(new CustomEvent("inspector:refresh"))}})}async resetToDefault(e,t){console.log("[QuickActionsBar] Reset to default:",e,t);try{let i=await this.getDefaultValue(e,t);i!==void 0?(await this.updateManager.updateProperty(e,t,i),console.log("[QuickActionsBar] Reset to default value:",i)):alert("No default value found for this property.")}catch(i){console.error("[QuickActionsBar] Failed to reset to default:",i),alert("Failed to reset property. Check console for details.")}}async getDefaultValue(e,t){let i=t.split(".");if(i.length<2)return;let n=i[0],a=i.slice(1),r=window.__editableConfig;if(!(r!=null&&r.schemas))return;let o=null;if(r.schemas instanceof Map?o=r.schemas.get(n):typeof r.schemas=="object"&&(o=r.schemas[n]),!(o!=null&&o.defaults))return;let l=o.defaults;for(let c of a)if(l&&typeof l=="object")l=l[c];else return;return l}handleAiConvert(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let r=`A single, high-quality, high-detail game UI icon/asset representing "${String(i||e.replace(/_/g," ").replace("json.",""))}". Modern stylized 3D rendered style, vibrant colors, soft lighting, isolated on solid magenta background, highly polished professional game art.`,o="render.asset.path";console.log("[QuickActionsBar] AI Convert for:",e,"from:",t,"to:",o),n(e,r,"",{objectId:e,path:o});let l=window.__debugContext;if(l){l.activeTab="ai";let c=window.__updateWorkbenchTabs;typeof c=="function"&&c()}}else console.warn("[QuickActionsBar] AI Editor not available")}};var Zo=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],Qo=["environment","ui","character","system","backgrounds"],el=["bg","world","ui"],Vs={SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},DragToWin:{targetId:"",successDistance:80},DragSnap:{snapTargetId:"",snapDistance:40},JoystickMove:{speed:6,bounds:{left:-400,right:400,top:-300,bottom:300}}},Ai=class{constructor(){this.modal=null;this.state=null}open(e){this.state=this.createInitialState(e),this.createModal(),document.body.appendChild(this.modal),this.attachEventListeners(),this.updateStepUI()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),window.__wizardAssetPicker=null,this.modal=null,this.state=null}createInitialState(e){return{step:1,objectType:"sprite",instanceId:"",displayName:"",category:"environment",screenId:e.screenId,layer:"world",positionMode:"static",anchorPreset:"center",anchorX:.5,anchorY:.5,positionX:0,positionY:0,offsetX:0,offsetY:0,scale:.2,rotation:0,zIndex:0,assetPath:"",tint:"",alpha:1,text:"",font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",graphicsWidth:200,graphicsHeight:200,graphicsFill:"#FFFFFF",graphicsAlpha:1,interactionEnabled:!1,dragEnabled:!1,hoverEnabled:!1,clickEnabled:!1,logicId:"",logicPropsRaw:""}}createModal(){let e=document.createElement("div");e.className="wizard-modal",e.innerHTML=`
47
47
  <div class="wizard-card">
48
48
  <div class="wizard-header">
49
49
  <div class="wizard-title">
@@ -95,19 +95,19 @@
95
95
  <div class="wizard-field-group">
96
96
  <label class="wizard-label required">Category</label>
97
97
  <select class="wizard-select" data-field="category">
98
- ${Wo.map(e=>`<option value="${e}">${e}</option>`).join("")}
98
+ ${Qo.map(e=>`<option value="${e}">${e}</option>`).join("")}
99
99
  </select>
100
100
  </div>
101
101
  <div class="wizard-field-group">
102
102
  <label class="wizard-label required">Screen</label>
103
103
  <select class="wizard-select" data-field="screenId" required>
104
- ${Vo.map(e=>`<option value="${e.value}">${e.label}</option>`).join("")}
104
+ ${Zo.map(e=>`<option value="${e.value}">${e.label}</option>`).join("")}
105
105
  </select>
106
106
  </div>
107
107
  <div class="wizard-field-group">
108
108
  <label class="wizard-label required">Layer</label>
109
109
  <select class="wizard-select" data-field="layer">
110
- ${Yo.map(e=>`<option value="${e}">${e}</option>`).join("")}
110
+ ${el.map(e=>`<option value="${e}">${e}</option>`).join("")}
111
111
  </select>
112
112
  </div>
113
113
  </div>
@@ -266,7 +266,7 @@
266
266
  <label class="wizard-label">Logic Component</label>
267
267
  <select class="wizard-select" data-field="logicId">
268
268
  <option value="">None</option>
269
- ${Object.keys(Fs).map(e=>`<option value="${e}">${e}</option>`).join("")}
269
+ ${Object.keys(Vs).map(e=>`<option value="${e}">${e}</option>`).join("")}
270
270
  </select>
271
271
  </div>
272
272
  <div class="wizard-field-group">
@@ -288,19 +288,19 @@
288
288
  </div>
289
289
  </div>
290
290
  </div>
291
- `}renderTypeCard(e,t,n){return`
291
+ `}renderTypeCard(e,t,i){return`
292
292
  <button class="wizard-type-card" type="button" data-object-type="${e}">
293
293
  <div class="wizard-type-icon">${t}</div>
294
- <div class="wizard-type-name">${n}</div>
294
+ <div class="wizard-type-name">${i}</div>
295
295
  </button>
296
- `}attachEventListeners(){if(!this.modal||!this.state)return;this.modal.addEventListener("click",t=>{var a;let n=t.target,i=n.dataset.action||((a=n.closest("[data-action]"))==null?void 0:a.getAttribute("data-action"));if(i)switch(i){case"close":case"cancel":this.close();break;case"back":this.goToStep(this.state.step-1);break;case"next":this.state.step<6?this.goToStep(this.state.step+1):this.submit();break}}),this.modal.addEventListener("click",t=>{let i=t.target.closest("[data-asset-action]");if(!i)return;let a=i.dataset.assetAction;a&&(t.preventDefault(),this.handleAssetAction(a))}),this.modal.addEventListener("click",t=>{let i=t.target.closest("[data-object-type]");if(!i)return;let a=i.dataset.objectType;a&&this.setObjectType(a)}),Array.from(this.modal.querySelectorAll("[data-field]")).forEach(t=>{let n=()=>this.handleFieldChange(t);t.addEventListener("input",n),t.addEventListener("change",n)}),this.modal.addEventListener("click",t=>{t.target===this.modal&&this.close()})}handleAssetAction(e){if(this.state)switch(e){case"library":this.openLibraryPicker();break;case"upload":this.openUploadPicker();break;case"ai":this.openAiPicker();break;default:break}}openLibraryPicker(){if(!this.state)return;this.setAssetPickerHint("Select an asset from the Library tab."),window.__wizardAssetPicker={onPick:t=>{this.state.assetPath=t,this.setAssetPickerHint(""),this.updateStepUI()}};let e=window.__debugContext;if(e){e.activeTab="library";let t=window.__updateWorkbenchTabs;typeof t=="function"&&t()}}openUploadPicker(){if(!this.state)return;this.setAssetPickerHint("Upload an image to add it to the library.");let e=this.state.instanceId||"new_asset",t=this.state.category||"environment";Yi({objectId:e,category:t,onApply:n=>{this.state.assetPath=n,this.setAssetPickerHint(""),this.updateStepUI()}})}openAiPicker(){if(!this.state)return;this.setAssetPickerHint('Generate and click "Save to Library" to use it here.'),window.__wizardAssetPicker={onPick:n=>{this.state.assetPath=n,this.setAssetPickerHint(""),this.updateStepUI()}};let e=window.__openAiEditor;if(typeof e!="function"){alert("AI Editor is not available.");return}let t=this.state.displayName||this.state.instanceId||"new asset";e(this.state.instanceId||"new_asset",`Create an image for ${t}`,"",{})}setAssetPickerHint(e){if(!this.modal)return;let t=this.modal.querySelector("[data-asset-picker-hint]");if(t){if(!e){t.style.display="none",t.textContent="";return}t.textContent=e,t.style.display="block"}}handleFieldChange(e){if(!this.state)return;let t=e.dataset.field;if(t){if(e instanceof HTMLInputElement&&e.type==="checkbox")this.state[t]=e.checked;else if(e instanceof HTMLInputElement&&e.type==="number"){let n=e.value===""?0:Number(e.value);this.state[t]=Number.isNaN(n)?0:n}else this.state[t]=e.value;t==="anchorPreset"&&this.applyAnchorPreset(this.state.anchorPreset),t==="logicId"&&this.applyLogicDefaults(this.state.logicId),this.updateStepUI()}}setObjectType(e){this.state&&(this.state.objectType=e,this.state.scale=e==="sprite"||e==="ui-image"?.2:1,(e==="ui-text"||e==="ui-image")&&(this.state.category="ui",this.state.layer="ui"),this.updateStepUI())}applyAnchorPreset(e){if(!this.state)return;let t={center:[.5,.5],"top-left":[0,0],"top-right":[1,0],"bottom-left":[0,1],"bottom-right":[1,1]};if(e!=="custom"&&t[e]){let[n,i]=t[e];this.state.anchorX=n,this.state.anchorY=i}}applyLogicDefaults(e){if(!this.state)return;if(!e){this.state.logicPropsRaw="";return}let t=Fs[e];t&&(this.state.logicPropsRaw=JSON.stringify(t,null,2))}goToStep(e){if(!this.state)return;let t=Math.max(1,Math.min(6,e));this.state.step=t,this.updateStepUI()}updateStepUI(){if(!this.modal||!this.state)return;Array.from(this.modal.querySelectorAll(".wizard-step")).forEach(t=>{let n=Number(t.dataset.step||"0");t.classList.toggle("active",n===this.state.step)}),this.updateProgressDots(),this.updateTypeSections(),this.syncFieldValues(),this.updatePreview(),this.updateActionButtons()}updateProgressDots(){if(!this.modal||!this.state)return;let e=this.modal.querySelector("[data-wizard-progress]");if(!e)return;let t=Array.from({length:6},(n,i)=>{let a=i+1;return`
296
+ `}attachEventListeners(){if(!this.modal||!this.state)return;this.modal.addEventListener("click",t=>{var a;let i=t.target,n=i.dataset.action||((a=i.closest("[data-action]"))==null?void 0:a.getAttribute("data-action"));if(n)switch(n){case"close":case"cancel":this.close();break;case"back":this.goToStep(this.state.step-1);break;case"next":this.state.step<6?this.goToStep(this.state.step+1):this.submit();break}}),this.modal.addEventListener("click",t=>{let n=t.target.closest("[data-asset-action]");if(!n)return;let a=n.dataset.assetAction;a&&(t.preventDefault(),this.handleAssetAction(a))}),this.modal.addEventListener("click",t=>{let n=t.target.closest("[data-object-type]");if(!n)return;let a=n.dataset.objectType;a&&this.setObjectType(a)}),Array.from(this.modal.querySelectorAll("[data-field]")).forEach(t=>{let i=()=>this.handleFieldChange(t);t.addEventListener("input",i),t.addEventListener("change",i)}),this.modal.addEventListener("click",t=>{t.target===this.modal&&this.close()})}handleAssetAction(e){if(this.state)switch(e){case"library":this.openLibraryPicker();break;case"upload":this.openUploadPicker();break;case"ai":this.openAiPicker();break;default:break}}openLibraryPicker(){if(!this.state)return;this.setAssetPickerHint("Select an asset from the Library tab."),window.__wizardAssetPicker={onPick:t=>{this.state.assetPath=t,this.setAssetPickerHint(""),this.updateStepUI()}};let e=window.__debugContext;if(e){e.activeTab="library";let t=window.__updateWorkbenchTabs;typeof t=="function"&&t()}}openUploadPicker(){if(!this.state)return;this.setAssetPickerHint("Upload an image to add it to the library.");let e=this.state.instanceId||"new_asset",t=this.state.category||"environment";ta({objectId:e,category:t,onApply:i=>{this.state.assetPath=i,this.setAssetPickerHint(""),this.updateStepUI()}})}openAiPicker(){if(!this.state)return;this.setAssetPickerHint('Generate and click "Save to Library" to use it here.'),window.__wizardAssetPicker={onPick:i=>{this.state.assetPath=i,this.setAssetPickerHint(""),this.updateStepUI()}};let e=window.__openAiEditor;if(typeof e!="function"){alert("AI Editor is not available.");return}let t=this.state.displayName||this.state.instanceId||"new asset";e(this.state.instanceId||"new_asset",`Create an image for ${t}`,"",{})}setAssetPickerHint(e){if(!this.modal)return;let t=this.modal.querySelector("[data-asset-picker-hint]");if(t){if(!e){t.style.display="none",t.textContent="";return}t.textContent=e,t.style.display="block"}}handleFieldChange(e){if(!this.state)return;let t=e.dataset.field;if(t){if(e instanceof HTMLInputElement&&e.type==="checkbox")this.state[t]=e.checked;else if(e instanceof HTMLInputElement&&e.type==="number"){let i=e.value===""?0:Number(e.value);this.state[t]=Number.isNaN(i)?0:i}else this.state[t]=e.value;t==="anchorPreset"&&this.applyAnchorPreset(this.state.anchorPreset),t==="logicId"&&this.applyLogicDefaults(this.state.logicId),this.updateStepUI()}}setObjectType(e){this.state&&(this.state.objectType=e,this.state.scale=e==="sprite"||e==="ui-image"?.2:1,(e==="ui-text"||e==="ui-image")&&(this.state.category="ui",this.state.layer="ui"),this.updateStepUI())}applyAnchorPreset(e){if(!this.state)return;let t={center:[.5,.5],"top-left":[0,0],"top-right":[1,0],"bottom-left":[0,1],"bottom-right":[1,1]};if(e!=="custom"&&t[e]){let[i,n]=t[e];this.state.anchorX=i,this.state.anchorY=n}}applyLogicDefaults(e){if(!this.state)return;if(!e){this.state.logicPropsRaw="";return}let t=Vs[e];t&&(this.state.logicPropsRaw=JSON.stringify(t,null,2))}goToStep(e){if(!this.state)return;let t=Math.max(1,Math.min(6,e));this.state.step=t,this.updateStepUI()}updateStepUI(){if(!this.modal||!this.state)return;Array.from(this.modal.querySelectorAll(".wizard-step")).forEach(t=>{let i=Number(t.dataset.step||"0");t.classList.toggle("active",i===this.state.step)}),this.updateProgressDots(),this.updateTypeSections(),this.syncFieldValues(),this.updatePreview(),this.updateActionButtons()}updateProgressDots(){if(!this.modal||!this.state)return;let e=this.modal.querySelector("[data-wizard-progress]");if(!e)return;let t=Array.from({length:6},(i,n)=>{let a=n+1;return`
297
297
  <div class="wizard-step-indicator">
298
298
  <span class="wizard-step-dot ${a===this.state.step?"active":a<this.state.step?"completed":""}"></span>
299
299
  <span class="wizard-step-label">Step ${a}</span>
300
300
  </div>
301
- `});e.innerHTML=t.join("")}updateTypeSections(){if(!this.modal||!this.state)return;let e=this.state.objectType;Array.from(this.modal.querySelectorAll("[data-type-section]")).forEach(i=>{let a=i.dataset.typeSection,o=a==="sprite"&&(e==="sprite"||e==="ui-image")||a===e;i.style.display=o?"block":"none"});let n=this.modal.querySelector("[data-type-help]");if(n){let i=e==="ui-text"?"UI text uses the UI renderer with font settings.":e==="graphics"?"Graphics are simple shapes with width/height and fill.":e==="container"?"Containers are empty parents for grouping objects.":"Sprite/UI image uses image assets.";n.textContent=i}}syncFieldValues(){if(!this.modal||!this.state)return;let e=this.state;Array.from(this.modal.querySelectorAll("[data-field]")).forEach(i=>{let a=i.dataset.field;if(!a)return;let r=e[a];i instanceof HTMLInputElement&&i.type==="checkbox"?i.checked=!!r:typeof r!="undefined"&&(i.value=String(r))}),Array.from(this.modal.querySelectorAll("[data-object-type]")).forEach(i=>{i.classList.toggle("selected",i.dataset.objectType===this.state.objectType)})}updatePreview(){if(!this.modal||!this.state)return;let e=this.modal.querySelector("[data-preview-json]"),t=this.modal.querySelector("[data-validation-errors]");if(!e||!t)return;let n=this.buildPayload();e.textContent=JSON.stringify(n,null,2);let i=this.validate();i.length>0?(t.style.display="block",t.textContent=i.join(`
302
- `)):(t.style.display="none",t.textContent="")}updateActionButtons(){if(!this.modal||!this.state)return;let e=this.modal.querySelector('[data-action="back"]'),t=this.modal.querySelector('[data-action="next"]');e&&(e.disabled=this.state.step===1),t&&(t.textContent=this.state.step===6?"Create":"Next",t.disabled=this.state.step===6&&this.validate().length>0)}validate(){if(!this.state)return[];let e=[],t=this.state.instanceId.trim();return t||e.push("Object ID is required."),t.startsWith("json.")&&e.push('Object ID must not start with "json." (instance id only).'),t&&!/^[a-zA-Z0-9._-]+$/.test(t)&&e.push("Object ID must use letters, numbers, dot, dash, or underscore."),t&&!this.isInstanceIdUnique(t)&&e.push(`Object ID "${t}" already exists.`),(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&!this.state.assetPath.trim()&&e.push("Asset path is required for image-based objects."),this.state.objectType==="ui-text"&&!this.state.text.trim()&&e.push("Text content is required for UI Text."),e}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let n=window.__HANDLER_SCREEN_INDEX,i=n==null?void 0:n.instanceToScreen;return i&&typeof i=="object"?!Object.prototype.hasOwnProperty.call(i,e):!0}buildPayload(){if(!this.state)return{};let e=this.state.instanceId.trim(),t=`json.${e}`;return{screenId:this.state.screenId,instanceId:e,objectConfigId:t,layer:this.state.layer,config:this.buildObjectConfig(t)}}buildObjectConfig(e){if(!this.state)return{};let t={identity:{id:e,category:this.state.category},transform:{position:{x:this.state.positionX,y:this.state.positionY},offset:{x:this.state.offsetX,y:this.state.offsetY},scale:this.state.scale,rotation:this.state.rotation,anchor:{x:this.state.anchorX,y:this.state.anchorY},position_ratio:null,position_mode:this.state.positionMode},render:{alpha:this.state.alpha,visible:!0,tint:this.state.tint||null,z_index:this.state.zIndex},instance_id:this.state.instanceId.trim(),object_config:e};return(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&(t.render.asset={type:"image",path:this.normalizeAssetPath(this.state.assetPath.trim())}),this.state.objectType==="ui-text"&&(t.ui={kind:"text",renderMode:"text",text:this.state.text,font:this.state.font,fontSize:this.state.fontSize,letterSpacing:this.state.letterSpacing,align:this.state.align,color:this.state.tint||"#FFFFFF"},t.render.tint=null),this.state.objectType==="graphics"&&(t.effects={width:this.state.graphicsWidth,height:this.state.graphicsHeight,fill_color:this.state.graphicsFill,fill_alpha:this.state.graphicsAlpha}),this.state.interactionEnabled&&(t.interaction={enabled:!0,drag:{enabled:this.state.dragEnabled},hover:{enabled:this.state.hoverEnabled},click:{enabled:this.state.clickEnabled}}),this.state.logicId&&(t.logic={id:this.state.logicId,props:this.parseLogicProps(this.state.logicPropsRaw)}),t}parseLogicProps(e){if(!e||!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}normalizeAssetPath(e){return!e||e.startsWith("raw/")?e:e.startsWith("/raw/")?e.replace(/^\/raw\//,"raw/"):e}async submit(){var n;if(!this.state)return;if(this.validate().length>0){this.updatePreview();return}let t=this.buildPayload();try{let i=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await i.json().catch(()=>({}));if(!i.ok||(a==null?void 0:a.success)===!1){let r=((n=a==null?void 0:a.errors)==null?void 0:n.join(`
303
- `))||(a==null?void 0:a.error)||"Failed to create object.";alert(r);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),this.close()}catch(i){alert(`Failed to create object: ${i instanceof Error?i.message:String(i)}`)}}async syncScreens(){try{await fetch("/api/sync-screens",{method:"POST"})}catch(e){console.warn("[AddObjectWizard] Failed to sync screens:",e)}}};var Cn=class{constructor(e){this.menu=null;this.closeHandler=null;this.keyHandler=null;this.options=e}open(e){this.createMenu(),document.body.appendChild(this.menu),this.positionMenu(e),this.attachListeners()}close(){var e,t;this.menu&&this.menu.parentNode&&this.menu.parentNode.removeChild(this.menu),this.closeHandler&&(window.removeEventListener("click",this.closeHandler),this.closeHandler=null),this.keyHandler&&(window.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.menu=null,(t=(e=this.options).onClose)==null||t.call(e)}createMenu(){let e=document.createElement("div");e.className="context-menu",e.setAttribute("data-context-menu","true"),e.innerHTML=`
301
+ `});e.innerHTML=t.join("")}updateTypeSections(){if(!this.modal||!this.state)return;let e=this.state.objectType;Array.from(this.modal.querySelectorAll("[data-type-section]")).forEach(n=>{let a=n.dataset.typeSection,o=a==="sprite"&&(e==="sprite"||e==="ui-image")||a===e;n.style.display=o?"block":"none"});let i=this.modal.querySelector("[data-type-help]");if(i){let n=e==="ui-text"?"UI text uses the UI renderer with font settings.":e==="graphics"?"Graphics are simple shapes with width/height and fill.":e==="container"?"Containers are empty parents for grouping objects.":"Sprite/UI image uses image assets.";i.textContent=n}}syncFieldValues(){if(!this.modal||!this.state)return;let e=this.state;Array.from(this.modal.querySelectorAll("[data-field]")).forEach(n=>{let a=n.dataset.field;if(!a)return;let r=e[a];n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked=!!r:typeof r!="undefined"&&(n.value=String(r))}),Array.from(this.modal.querySelectorAll("[data-object-type]")).forEach(n=>{n.classList.toggle("selected",n.dataset.objectType===this.state.objectType)})}updatePreview(){if(!this.modal||!this.state)return;let e=this.modal.querySelector("[data-preview-json]"),t=this.modal.querySelector("[data-validation-errors]");if(!e||!t)return;let i=this.buildPayload();e.textContent=JSON.stringify(i,null,2);let n=this.validate();n.length>0?(t.style.display="block",t.textContent=n.join(`
302
+ `)):(t.style.display="none",t.textContent="")}updateActionButtons(){if(!this.modal||!this.state)return;let e=this.modal.querySelector('[data-action="back"]'),t=this.modal.querySelector('[data-action="next"]');e&&(e.disabled=this.state.step===1),t&&(t.textContent=this.state.step===6?"Create":"Next",t.disabled=this.state.step===6&&this.validate().length>0)}validate(){if(!this.state)return[];let e=[],t=this.state.instanceId.trim();return t||e.push("Object ID is required."),t.startsWith("json.")&&e.push('Object ID must not start with "json." (instance id only).'),t&&!/^[a-zA-Z0-9._-]+$/.test(t)&&e.push("Object ID must use letters, numbers, dot, dash, or underscore."),t&&!this.isInstanceIdUnique(t)&&e.push(`Object ID "${t}" already exists.`),(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&!this.state.assetPath.trim()&&e.push("Asset path is required for image-based objects."),this.state.objectType==="ui-text"&&!this.state.text.trim()&&e.push("Text content is required for UI Text."),e}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let i=window.__HANDLER_SCREEN_INDEX,n=i==null?void 0:i.instanceToScreen;return n&&typeof n=="object"?!Object.prototype.hasOwnProperty.call(n,e):!0}buildPayload(){if(!this.state)return{};let e=this.state.instanceId.trim(),t=`json.${e}`;return{screenId:this.state.screenId,instanceId:e,objectConfigId:t,layer:this.state.layer,config:this.buildObjectConfig(t)}}buildObjectConfig(e){if(!this.state)return{};let t={identity:{id:e,category:this.state.category},transform:{position:{x:this.state.positionX,y:this.state.positionY},offset:{x:this.state.offsetX,y:this.state.offsetY},scale:this.state.scale,rotation:this.state.rotation,anchor:{x:this.state.anchorX,y:this.state.anchorY},position_ratio:null,position_mode:this.state.positionMode},render:{alpha:this.state.alpha,visible:!0,tint:this.state.tint||null,z_index:this.state.zIndex},instance_id:this.state.instanceId.trim(),object_config:e};return(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&(t.render.asset={type:"image",path:this.normalizeAssetPath(this.state.assetPath.trim())}),this.state.objectType==="ui-text"&&(t.ui={kind:"text",renderMode:"text",text:this.state.text,font:this.state.font,fontSize:this.state.fontSize,letterSpacing:this.state.letterSpacing,align:this.state.align,color:this.state.tint||"#FFFFFF"},t.render.tint=null),this.state.objectType==="graphics"&&(t.effects={width:this.state.graphicsWidth,height:this.state.graphicsHeight,fill_color:this.state.graphicsFill,fill_alpha:this.state.graphicsAlpha}),this.state.interactionEnabled&&(t.interaction={enabled:!0,drag:{enabled:this.state.dragEnabled},hover:{enabled:this.state.hoverEnabled},click:{enabled:this.state.clickEnabled}}),this.state.logicId&&(t.logic={id:this.state.logicId,props:this.parseLogicProps(this.state.logicPropsRaw)}),t}parseLogicProps(e){if(!e||!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}normalizeAssetPath(e){return!e||e.startsWith("raw/")?e:e.startsWith("/raw/")?e.replace(/^\/raw\//,"raw/"):e}async submit(){var i;if(!this.state)return;if(this.validate().length>0){this.updatePreview();return}let t=this.buildPayload();try{let n=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await n.json().catch(()=>({}));if(!n.ok||(a==null?void 0:a.success)===!1){let r=((i=a==null?void 0:a.errors)==null?void 0:i.join(`
303
+ `))||(a==null?void 0:a.error)||"Failed to create object.";alert(r);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),this.close()}catch(n){alert(`Failed to create object: ${n instanceof Error?n.message:String(n)}`)}}async syncScreens(){try{await fetch("/api/sync-screens",{method:"POST"})}catch(e){console.warn("[AddObjectWizard] Failed to sync screens:",e)}}};var Ti=class{constructor(e){this.menu=null;this.closeHandler=null;this.keyHandler=null;this.options=e}open(e){this.createMenu(),document.body.appendChild(this.menu),this.positionMenu(e),this.attachListeners()}close(){var e,t;this.menu&&this.menu.parentNode&&this.menu.parentNode.removeChild(this.menu),this.closeHandler&&(window.removeEventListener("click",this.closeHandler),this.closeHandler=null),this.keyHandler&&(window.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.menu=null,(t=(e=this.options).onClose)==null||t.call(e)}createMenu(){let e=document.createElement("div");e.className="context-menu",e.setAttribute("data-context-menu","true"),e.innerHTML=`
304
304
  <div class="context-menu-item" data-action="duplicate">Duplicate</div>
305
305
  <div class="context-menu-item" data-action="rename">Rename</div>
306
306
  <div class="context-menu-item" data-action="move">Move to Screen</div>
@@ -309,11 +309,11 @@
309
309
  <div class="context-menu-item" data-action="inspect">Open in Inspector</div>
310
310
  <div class="context-menu-separator"></div>
311
311
  <div class="context-menu-item danger" data-action="delete">Delete</div>
312
- `,this.menu=e}positionMenu(e){if(!this.menu)return;let{x:t,y:n}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${n}px`;let i=this.menu.getBoundingClientRect(),a=i.right-window.innerWidth,r=i.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),r>0&&(this.menu.style.top=`${n-r-8}px`)}attachListeners(){this.menu&&(this.menu.addEventListener("click",e=>{let n=e.target.dataset.action;n&&(e.stopPropagation(),this.handleAction(n))}),this.closeHandler=e=>{let t=e.target;this.menu&&t&&this.menu.contains(t)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=e=>{e.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler))}handleAction(e){var t,n;switch(e){case"duplicate":this.handleDuplicate();break;case"rename":this.handleRename();break;case"move":this.handleMove();break;case"copy":this.handleCopyConfig();break;case"inspect":this.handleOpenInspector();break;case"delete":(n=(t=this.options).onDeleteRequest)==null||n.call(t,this.options.objectId),this.close();break}}async handleDuplicate(){var i,a,r,o,l;let e=`${this.options.objectId}_copy`,t=window.prompt("New instance ID",e);if(!t)return;if(!this.isInstanceIdUnique(t)){alert(`Instance ID "${t}" already exists.`);return}let n=window.confirm(`Share config with original?
313
- OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:this.options.objectId,newInstanceId:t,shareConfig:n,screenId:this.options.screenId})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((i=d==null?void 0:d.errors)==null?void 0:i.join(`
314
- `))||(d==null?void 0:d.error)||"Duplicate failed.";alert(p);return}(r=(a=this.options).onRefresh)==null||r.call(a),(l=(o=this.options).onSelect)==null||l.call(o,t),this.close()}catch(c){alert(`Duplicate failed: ${c instanceof Error?c.message:String(c)}`)}}async handleRename(){var t,n,i,a,r;let e=window.prompt("New instance ID",this.options.objectId);if(!(!e||e===this.options.objectId)){if(!this.isInstanceIdUnique(e)){alert(`Instance ID "${e}" already exists.`);return}try{let o=await fetch("/api/objects/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:this.options.objectId,screenId:this.options.screenId,newInstanceId:e})}),l=await o.json().catch(()=>({}));if(!o.ok||(l==null?void 0:l.success)===!1){let c=((t=l==null?void 0:l.errors)==null?void 0:t.join(`
315
- `))||(l==null?void 0:l.error)||"Rename failed.";alert(c);return}(i=(n=this.options).onRefresh)==null||i.call(n),(r=(a=this.options).onSelect)==null||r.call(a,e),this.close()}catch(o){alert(`Rename failed: ${o instanceof Error?o.message:String(o)}`)}}}async handleMove(){var n,i,a;let e=window.prompt("Move to screen (loading/start/gameplay/tutorial/endgame)",this.options.screenId);if(!e)return;let t=e.trim();if(!["loading","start","gameplay","tutorial","endgame"].includes(t)){alert("Invalid screen. Use: loading, start, gameplay, tutorial, endgame.");return}if(t!==this.options.screenId){if(this.options.onMoveRequest){this.options.onMoveRequest(this.options.objectId,t),this.close();return}try{let r=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:this.options.objectId,fromScreenId:this.options.screenId,toScreenId:t})}),o=await r.json().catch(()=>({}));if(!r.ok||(o==null?void 0:o.success)===!1){let l=((n=o==null?void 0:o.errors)==null?void 0:n.join(`
316
- `))||(o==null?void 0:o.error)||"Move failed.";alert(l);return}(a=(i=this.options).onRefresh)==null||a.call(i),this.close()}catch(r){alert(`Move failed: ${r instanceof Error?r.message:String(r)}`)}}}handleCopyConfig(){var i,a;let e=window.getEditableObjectConfig,t=typeof e=="function"?e(this.options.objectId):null;if(!t){let r=window.__editableObjectConfigs;r&&typeof r.get=="function"&&(t=(i=r.get(this.options.objectId))!=null?i:null)}if(!t){alert("Config not found.");return}let n=JSON.stringify(t,null,2);(a=navigator.clipboard)==null||a.writeText(n).catch(()=>{alert("Failed to copy to clipboard.")}),this.close()}handleOpenInspector(){var t,n;let e=window.__previewSelectObject;typeof e=="function"&&e(this.options.objectId),(n=(t=this.options).onSelect)==null||n.call(t,this.options.objectId),this.close()}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let n=window.__HANDLER_SCREEN_INDEX,i=n==null?void 0:n.instanceToScreen;return i&&typeof i=="object"?!Object.prototype.hasOwnProperty.call(i,e):!0}};var Mt=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],An=class{constructor(e){this.menu=null;this.closeHandler=null;this.keyHandler=null;this.templates=[];this.isLoadingTemplates=!1;this.targetScreen="gameplay";this.view="root";this.templateQuery="";this.templateGroup=null;this.options=e}getTargetScreenStorageKey(){return`handler_preview_add_menu_target_screen::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}async open(e){await this.loadTemplates(),this.loadTargetScreen(),this.view="root",this.templateQuery="",this.templateGroup=null,this.createMenu(),document.body.appendChild(this.menu),this.positionMenu(e),this.attachListeners()}close(){var e,t;this.menu&&this.menu.parentNode&&this.menu.parentNode.removeChild(this.menu),this.closeHandler&&(window.removeEventListener("click",this.closeHandler),this.closeHandler=null),this.keyHandler&&(window.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.menu=null,(t=(e=this.options).onClose)==null||t.call(e)}async loadTemplates(){if(!this.isLoadingTemplates){this.isLoadingTemplates=!0;try{let e=await fetch("/api/objects/templates");if(e.ok){let t=await e.json();this.templates=Array.isArray(t.templates)?t.templates:[]}}catch(e){console.warn("[AddObjectMenu] Failed to load templates:",e),this.templates=[]}finally{this.isLoadingTemplates=!1}}}createMenu(){let e=document.createElement("div");e.className="context-menu",e.setAttribute("data-context-menu","true"),e.innerHTML=this.renderMenuHtml(),this.menu=e,this.updateTargetScreenUI()}positionMenu(e){if(!this.menu)return;let{x:t,y:n}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${n}px`;let i=this.menu.getBoundingClientRect(),a=i.right-window.innerWidth,r=i.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),r>0&&(this.menu.style.top=`${n-r-8}px`)}attachListeners(){this.menu&&(this.menu.addEventListener("click",e=>{let t=e.target,n=t==null?void 0:t.closest("[data-action]");if(!n||n.classList.contains("disabled"))return;let i=n.dataset.action;if(!i)return;if(e.preventDefault(),e.stopPropagation(),i==="set-screen"){let d=n.dataset.screenId;if(!d||!Mt.some(p=>p.value===d))return;this.setTargetScreen(d);return}if(i==="open-view"){let d=(n.dataset.view||"").trim();(d==="templates"||d==="templates-group"||d==="screens"||d==="systems"||d==="root")&&this.setView(d);return}if(i==="back"){this.setView("root");return}if(i==="open-template-group"){let d=(n.dataset.templateGroup||"").trim();if(!d)return;this.templateGroup=d,this.setView("templates-group");return}if(i==="template-pack"){let d=(n.dataset.templatePack||"").trim();(d==="ui"||d==="screen")&&this.handleInstallTemplatePack(d);return}let a=n.dataset.objectType,r=n.dataset.systemType,o=n.dataset.templateId,l=n.dataset.screenId,c=l!=null?l:this.targetScreen;i==="object"&&a?this.handleCreateObject(a,c):i==="system"&&r?this.handleCreateSystem(r,c):i==="template"&&o&&this.handleCreateFromTemplate(o,c)}),this.menu.addEventListener("input",e=>{if(!this.menu)return;let t=e.target,n=t&&t instanceof HTMLInputElement?t:null;n&&n.classList.contains("context-menu-search")&&(this.templateQuery=n.value||"",this.updateMenuContents({preserveTemplateSearchFocus:!0}))}),this.closeHandler=e=>{let t=e.target;this.menu&&t&&this.menu.contains(t)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=e=>{e.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler))}async promptScreen(e="Select Screen"){return new Promise(t=>{var c,d,p;let n=document.createElement("div");n.className="add-menu-modal-overlay",n.innerHTML=`
312
+ `,this.menu=e}positionMenu(e){if(!this.menu)return;let{x:t,y:i}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${i}px`;let n=this.menu.getBoundingClientRect(),a=n.right-window.innerWidth,r=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),r>0&&(this.menu.style.top=`${i-r-8}px`)}attachListeners(){this.menu&&(this.menu.addEventListener("click",e=>{let i=e.target.dataset.action;i&&(e.stopPropagation(),this.handleAction(i))}),this.closeHandler=e=>{let t=e.target;this.menu&&t&&this.menu.contains(t)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=e=>{e.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler))}handleAction(e){var t,i;switch(e){case"duplicate":this.handleDuplicate();break;case"rename":this.handleRename();break;case"move":this.handleMove();break;case"copy":this.handleCopyConfig();break;case"inspect":this.handleOpenInspector();break;case"delete":(i=(t=this.options).onDeleteRequest)==null||i.call(t,this.options.objectId),this.close();break}}async handleDuplicate(){var n,a,r,o,l;let e=`${this.options.objectId}_copy`,t=window.prompt("New instance ID",e);if(!t)return;if(!this.isInstanceIdUnique(t)){alert(`Instance ID "${t}" already exists.`);return}let i=window.confirm(`Share config with original?
313
+ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:this.options.objectId,newInstanceId:t,shareConfig:i,screenId:this.options.screenId})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((n=d==null?void 0:d.errors)==null?void 0:n.join(`
314
+ `))||(d==null?void 0:d.error)||"Duplicate failed.";alert(p);return}(r=(a=this.options).onRefresh)==null||r.call(a),(l=(o=this.options).onSelect)==null||l.call(o,t),this.close()}catch(c){alert(`Duplicate failed: ${c instanceof Error?c.message:String(c)}`)}}async handleRename(){var t,i,n,a,r;let e=window.prompt("New instance ID",this.options.objectId);if(!(!e||e===this.options.objectId)){if(!this.isInstanceIdUnique(e)){alert(`Instance ID "${e}" already exists.`);return}try{let o=await fetch("/api/objects/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:this.options.objectId,screenId:this.options.screenId,newInstanceId:e})}),l=await o.json().catch(()=>({}));if(!o.ok||(l==null?void 0:l.success)===!1){let c=((t=l==null?void 0:l.errors)==null?void 0:t.join(`
315
+ `))||(l==null?void 0:l.error)||"Rename failed.";alert(c);return}(n=(i=this.options).onRefresh)==null||n.call(i),(r=(a=this.options).onSelect)==null||r.call(a,e),this.close()}catch(o){alert(`Rename failed: ${o instanceof Error?o.message:String(o)}`)}}}async handleMove(){var i,n,a;let e=window.prompt("Move to screen (loading/start/gameplay/tutorial/endgame)",this.options.screenId);if(!e)return;let t=e.trim();if(!["loading","start","gameplay","tutorial","endgame"].includes(t)){alert("Invalid screen. Use: loading, start, gameplay, tutorial, endgame.");return}if(t!==this.options.screenId){if(this.options.onMoveRequest){this.options.onMoveRequest(this.options.objectId,t),this.close();return}try{let r=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:this.options.objectId,fromScreenId:this.options.screenId,toScreenId:t})}),o=await r.json().catch(()=>({}));if(!r.ok||(o==null?void 0:o.success)===!1){let l=((i=o==null?void 0:o.errors)==null?void 0:i.join(`
316
+ `))||(o==null?void 0:o.error)||"Move failed.";alert(l);return}(a=(n=this.options).onRefresh)==null||a.call(n),this.close()}catch(r){alert(`Move failed: ${r instanceof Error?r.message:String(r)}`)}}}handleCopyConfig(){var n,a;let e=window.getEditableObjectConfig,t=typeof e=="function"?e(this.options.objectId):null;if(!t){let r=window.__editableObjectConfigs;r&&typeof r.get=="function"&&(t=(n=r.get(this.options.objectId))!=null?n:null)}if(!t){alert("Config not found.");return}let i=JSON.stringify(t,null,2);(a=navigator.clipboard)==null||a.writeText(i).catch(()=>{alert("Failed to copy to clipboard.")}),this.close()}handleOpenInspector(){var t,i;let e=window.__previewSelectObject;typeof e=="function"&&e(this.options.objectId),(i=(t=this.options).onSelect)==null||i.call(t,this.options.objectId),this.close()}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let i=window.__HANDLER_SCREEN_INDEX,n=i==null?void 0:i.instanceToScreen;return n&&typeof n=="object"?!Object.prototype.hasOwnProperty.call(n,e):!0}};var zt=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],Li=class{constructor(e){this.menu=null;this.closeHandler=null;this.keyHandler=null;this.templates=[];this.isLoadingTemplates=!1;this.targetScreen="gameplay";this.view="root";this.templateQuery="";this.templateGroup=null;this.options=e}getTargetScreenStorageKey(){return`handler_preview_add_menu_target_screen::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}async open(e){await this.loadTemplates(),this.loadTargetScreen(),this.view="root",this.templateQuery="",this.templateGroup=null,this.createMenu(),document.body.appendChild(this.menu),this.positionMenu(e),this.attachListeners()}close(){var e,t;this.menu&&this.menu.parentNode&&this.menu.parentNode.removeChild(this.menu),this.closeHandler&&(window.removeEventListener("click",this.closeHandler),this.closeHandler=null),this.keyHandler&&(window.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.menu=null,(t=(e=this.options).onClose)==null||t.call(e)}async loadTemplates(){if(!this.isLoadingTemplates){this.isLoadingTemplates=!0;try{let e=await fetch("/api/objects/templates");if(e.ok){let t=await e.json();this.templates=Array.isArray(t.templates)?t.templates:[]}}catch(e){console.warn("[AddObjectMenu] Failed to load templates:",e),this.templates=[]}finally{this.isLoadingTemplates=!1}}}createMenu(){let e=document.createElement("div");e.className="context-menu",e.setAttribute("data-context-menu","true"),e.innerHTML=this.renderMenuHtml(),this.menu=e,this.updateTargetScreenUI()}positionMenu(e){if(!this.menu)return;let{x:t,y:i}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${i}px`;let n=this.menu.getBoundingClientRect(),a=n.right-window.innerWidth,r=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),r>0&&(this.menu.style.top=`${i-r-8}px`)}attachListeners(){this.menu&&(this.menu.addEventListener("click",e=>{let t=e.target,i=t==null?void 0:t.closest("[data-action]");if(!i||i.classList.contains("disabled"))return;let n=i.dataset.action;if(!n)return;if(e.preventDefault(),e.stopPropagation(),n==="set-screen"){let d=i.dataset.screenId;if(!d||!zt.some(p=>p.value===d))return;this.setTargetScreen(d);return}if(n==="open-view"){let d=(i.dataset.view||"").trim();(d==="templates"||d==="templates-group"||d==="screens"||d==="systems"||d==="root")&&this.setView(d);return}if(n==="back"){this.setView("root");return}if(n==="open-template-group"){let d=(i.dataset.templateGroup||"").trim();if(!d)return;this.templateGroup=d,this.setView("templates-group");return}if(n==="template-pack"){let d=(i.dataset.templatePack||"").trim();(d==="ui"||d==="screen")&&this.handleInstallTemplatePack(d);return}let a=i.dataset.objectType,r=i.dataset.systemType,o=i.dataset.templateId,l=i.dataset.screenId,c=l!=null?l:this.targetScreen;n==="object"&&a?this.handleCreateObject(a,c):n==="system"&&r?this.handleCreateSystem(r,c):n==="template"&&o&&this.handleCreateFromTemplate(o,c)}),this.menu.addEventListener("input",e=>{if(!this.menu)return;let t=e.target,i=t&&t instanceof HTMLInputElement?t:null;i&&i.classList.contains("context-menu-search")&&(this.templateQuery=i.value||"",this.updateMenuContents({preserveTemplateSearchFocus:!0}))}),this.closeHandler=e=>{let t=e.target;this.menu&&t&&this.menu.contains(t)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=e=>{e.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler))}async promptScreen(e="Select Screen"){return new Promise(t=>{var c,d,p;let i=document.createElement("div");i.className="add-menu-modal-overlay",i.innerHTML=`
317
317
  <div class="add-menu-modal">
318
318
  <div class="add-menu-modal-header">
319
319
  <div class="add-menu-modal-title">${this.escapeHtml(e)}</div>
@@ -322,7 +322,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
322
322
  <div class="add-menu-modal-body">
323
323
  <label class="add-menu-modal-label">Screen:</label>
324
324
  <select class="add-menu-modal-select" id="screen-select" required>
325
- ${Mt.map((u,g)=>`<option value="${this.escapeHtml(u.value)}" ${g===2?"selected":""}>${this.escapeHtml(u.label)}</option>`).join("")}
325
+ ${zt.map((u,g)=>`<option value="${this.escapeHtml(u.value)}" ${g===2?"selected":""}>${this.escapeHtml(u.label)}</option>`).join("")}
326
326
  </select>
327
327
  </div>
328
328
  <div class="add-menu-modal-footer">
@@ -330,8 +330,8 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
330
330
  <button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Confirm</button>
331
331
  </div>
332
332
  </div>
333
- `;let i=()=>{n.parentNode&&n.parentNode.removeChild(n)},a=()=>{let g=n.querySelector("#screen-select").value.trim();if(!g||!Mt.some(f=>f.value===g)){alert("Please select a valid screen.");return}i(),t(g)},r=()=>{i(),t(null)};n.querySelector(".add-menu-modal").addEventListener("click",u=>{u.stopPropagation()}),(c=n.querySelector('[data-action="confirm"]'))==null||c.addEventListener("click",a),(d=n.querySelector('[data-action="cancel"]'))==null||d.addEventListener("click",r),(p=n.querySelector(".add-menu-modal-close"))==null||p.addEventListener("click",r),n.addEventListener("click",u=>{u.target===n&&r()});let l=n.querySelector("#screen-select");l.addEventListener("keydown",u=>{u.key==="Enter"?(u.preventDefault(),a()):u.key==="Escape"&&(u.preventDefault(),r())}),document.body.appendChild(n),l.focus()})}loadTargetScreen(){try{let t=(window.localStorage.getItem(this.getTargetScreenStorageKey())||"").trim();Mt.some(n=>n.value===t)?this.targetScreen=t:this.targetScreen="gameplay"}catch{this.targetScreen="gameplay"}}setTargetScreen(e){this.targetScreen=e;try{window.localStorage.setItem(this.getTargetScreenStorageKey(),e)}catch{}this.updateTargetScreenUI()}updateTargetScreenUI(){let e=this.menu;if(!e)return;Array.from(e.querySelectorAll(".context-menu-screen-chip[data-screen-id]")).forEach(n=>{let i=n.dataset.screenId;n.classList.toggle("active",i===this.targetScreen)})}setView(e){var t;if(this.view=e,e!=="templates-group"&&(this.templateGroup=null),this.updateMenuContents(),e==="templates"||e==="templates-group"){let n=(t=this.menu)==null?void 0:t.querySelector(".context-menu-search");n&&n.focus()}}updateMenuContents(e){if(!this.menu)return;let t=!!(e!=null&&e.preserveTemplateSearchFocus)&&document.activeElement===this.menu.querySelector(".context-menu-search");if(this.menu.innerHTML=this.renderMenuHtml(),this.updateTargetScreenUI(),t){let n=this.menu.querySelector(".context-menu-search");n==null||n.focus(),n&&(n.selectionStart=n.selectionEnd=n.value.length)}}renderMenuHtml(){return this.view==="templates"?this.renderTemplatesView():this.view==="templates-group"?this.renderTemplatesGroupView():this.view==="screens"?this.renderScreensView():this.view==="systems"?this.renderSystemsView():this.renderRootView()}getPackTemplateIds(e){return e==="ui"?["template.ui.rotating_logo","template.ui.floating_cta_badge"]:["template.screen.rotating_coin","template.screen.rotating_gem"]}getMissingPackTemplateIds(e){let t=new Set(this.templates.map(n=>String(n.id||"").toLowerCase()));return this.getPackTemplateIds(e).filter(n=>!t.has(n.toLowerCase()))}async handleInstallTemplatePack(e){var t;try{let i=await fetch(e==="ui"?"/api/templates/ui":"/api/templates/screen",{method:"POST",headers:{"Content-Type":"application/json"},body:"{}"}),a=await i.json().catch(()=>({}));if(!i.ok||(a==null?void 0:a.success)===!1){let r=((t=a==null?void 0:a.errors)==null?void 0:t.join(`
334
- `))||(a==null?void 0:a.error)||"Failed to install templates.";alert(r);return}await this.loadTemplates(),this.updateMenuContents()}catch(n){alert(`Failed to install templates: ${n instanceof Error?n.message:String(n)}`)}}renderRootView(){let e=this.templates.length;return`
333
+ `;let n=()=>{i.parentNode&&i.parentNode.removeChild(i)},a=()=>{let g=i.querySelector("#screen-select").value.trim();if(!g||!zt.some(h=>h.value===g)){alert("Please select a valid screen.");return}n(),t(g)},r=()=>{n(),t(null)};i.querySelector(".add-menu-modal").addEventListener("click",u=>{u.stopPropagation()}),(c=i.querySelector('[data-action="confirm"]'))==null||c.addEventListener("click",a),(d=i.querySelector('[data-action="cancel"]'))==null||d.addEventListener("click",r),(p=i.querySelector(".add-menu-modal-close"))==null||p.addEventListener("click",r),i.addEventListener("click",u=>{u.target===i&&r()});let l=i.querySelector("#screen-select");l.addEventListener("keydown",u=>{u.key==="Enter"?(u.preventDefault(),a()):u.key==="Escape"&&(u.preventDefault(),r())}),document.body.appendChild(i),l.focus()})}loadTargetScreen(){try{let t=(window.localStorage.getItem(this.getTargetScreenStorageKey())||"").trim();zt.some(i=>i.value===t)?this.targetScreen=t:this.targetScreen="gameplay"}catch{this.targetScreen="gameplay"}}setTargetScreen(e){this.targetScreen=e;try{window.localStorage.setItem(this.getTargetScreenStorageKey(),e)}catch{}this.updateTargetScreenUI()}updateTargetScreenUI(){let e=this.menu;if(!e)return;Array.from(e.querySelectorAll(".context-menu-screen-chip[data-screen-id]")).forEach(i=>{let n=i.dataset.screenId;i.classList.toggle("active",n===this.targetScreen)})}setView(e){var t;if(this.view=e,e!=="templates-group"&&(this.templateGroup=null),this.updateMenuContents(),e==="templates"||e==="templates-group"){let i=(t=this.menu)==null?void 0:t.querySelector(".context-menu-search");i&&i.focus()}}updateMenuContents(e){if(!this.menu)return;let t=!!(e!=null&&e.preserveTemplateSearchFocus)&&document.activeElement===this.menu.querySelector(".context-menu-search");if(this.menu.innerHTML=this.renderMenuHtml(),this.updateTargetScreenUI(),t){let i=this.menu.querySelector(".context-menu-search");i==null||i.focus(),i&&(i.selectionStart=i.selectionEnd=i.value.length)}}renderMenuHtml(){return this.view==="templates"?this.renderTemplatesView():this.view==="templates-group"?this.renderTemplatesGroupView():this.view==="screens"?this.renderScreensView():this.view==="systems"?this.renderSystemsView():this.renderRootView()}getPackTemplateIds(e){return e==="ui"?["template.ui.rotating_logo","template.ui.floating_cta_badge","template.ui.bottom_cta_button","template.ui.hand_pointer","template.ui.title_banner","template.ui.instruction_text","template.ui.score_hud"]:["template.screen.rotating_coin","template.screen.rotating_gem","template.screen.tap_destroy_target","template.screen.draggable_piece","template.screen.snap_slot","template.screen.collectable_coin","template.screen.player_swerve","template.screen.enemy_damageable"]}getMissingPackTemplateIds(e){let t=new Set(this.templates.map(i=>String(i.id||"").toLowerCase()));return this.getPackTemplateIds(e).filter(i=>!t.has(i.toLowerCase()))}async handleInstallTemplatePack(e){var t;try{let n=await fetch(e==="ui"?"/api/templates/ui":"/api/templates/screen",{method:"POST",headers:{"Content-Type":"application/json"},body:"{}"}),a=await n.json().catch(()=>({}));if(!n.ok||(a==null?void 0:a.success)===!1){let r=((t=a==null?void 0:a.errors)==null?void 0:t.join(`
334
+ `))||(a==null?void 0:a.error)||"Failed to install templates.";alert(r);return}await this.loadTemplates(),this.updateMenuContents()}catch(i){alert(`Failed to install templates: ${i instanceof Error?i.message:String(i)}`)}}renderRootView(){let e=this.templates.length;return`
335
335
  ${this.renderTargetScreenSection()}
336
336
  <div class="context-menu-section-title">Objects</div>
337
337
  <div class="context-menu-item" data-action="object" data-object-type="sprite">\u{1F5BC}\uFE0F Sprite</div>
@@ -343,17 +343,17 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
343
343
  <div class="context-menu-item context-menu-submenu" data-action="open-view" data-view="templates">\u{1F4DA} Templates <span class="context-menu-subtle">${e}</span></div>
344
344
  <div class="context-menu-item context-menu-submenu" data-action="open-view" data-view="screens">\u{1FA9F} Screens</div>
345
345
  <div class="context-menu-item context-menu-submenu" data-action="open-view" data-view="systems">\u{1F9E9} Systems</div>
346
- `}renderTemplatesView(){let e=(this.templateQuery||"").trim().toLowerCase(),t=this.groupTemplates(this.templates),n=["UI Templates","Screen Templates","Gameplay Templates","Effects","Other"];if(e){let o=this.templates.filter(l=>`${l.id} ${l.label}`.toLowerCase().includes(e)).slice().sort((l,c)=>l.label.localeCompare(c.label)).map(l=>{let c=`${l.id} ${l.label}`.toLowerCase();return`<div class="context-menu-item" data-action="template" data-template-id="${this.escapeHtml(l.id)}" data-template-haystack="${this.escapeHtml(c)}">${this.escapeHtml(l.label)}</div>`}).join("");return`
346
+ `}renderTemplatesView(){let e=(this.templateQuery||"").trim().toLowerCase(),t=this.groupTemplates(this.templates),i=["UI Templates","Screen Templates","Gameplay Templates","Effects","Other"];if(e){let o=this.templates.filter(l=>`${l.id} ${l.label}`.toLowerCase().includes(e)).slice().sort((l,c)=>l.label.localeCompare(c.label)).map(l=>{let c=`${l.id} ${l.label}`.toLowerCase();return`<div class="context-menu-item" data-action="template" data-template-id="${this.escapeHtml(l.id)}" data-template-haystack="${this.escapeHtml(c)}">${this.escapeHtml(l.label)}</div>`}).join("");return`
347
347
  <div class="context-menu-item context-menu-back" data-action="back">\u2190 Back</div>
348
348
  <div class="context-menu-section-title">Templates</div>
349
349
  <input class="context-menu-search" type="text" placeholder="Search templates\u2026" value="${this.escapeHtml(this.templateQuery)}" />
350
350
  ${o||'<div class="context-menu-item disabled">No matches</div>'}
351
- `}let i=n.map(r=>{var d,p;let o=(p=(d=t.get(r))==null?void 0:d.length)!=null?p:0,l=r==="UI Templates"||r==="Screen Templates";return o<=0&&!l?`<div class="context-menu-item disabled">${this.escapeHtml(r)} <span class="context-menu-subtle">0</span></div>`:`<div class="${o>0,"context-menu-item context-menu-submenu"}" data-action="open-template-group" data-template-group="${this.escapeHtml(r)}">${this.escapeHtml(r)} <span class="context-menu-subtle">${o}</span></div>`}).join(""),a=this.templates.length>0?"":'<div class="context-menu-item disabled">No templates available</div>';return`
351
+ `}let n=i.map(r=>{var d,p;let o=(p=(d=t.get(r))==null?void 0:d.length)!=null?p:0,l=r==="UI Templates"||r==="Screen Templates";return o<=0&&!l?`<div class="context-menu-item disabled">${this.escapeHtml(r)} <span class="context-menu-subtle">0</span></div>`:`<div class="${o>0,"context-menu-item context-menu-submenu"}" data-action="open-template-group" data-template-group="${this.escapeHtml(r)}">${this.escapeHtml(r)} <span class="context-menu-subtle">${o}</span></div>`}).join(""),a=this.templates.length>0?"":'<div class="context-menu-item disabled">No templates available</div>';return`
352
352
  <div class="context-menu-item context-menu-back" data-action="back">\u2190 Back</div>
353
353
  <div class="context-menu-section-title">Templates</div>
354
354
  <input class="context-menu-search" type="text" placeholder="Search templates\u2026" value="${this.escapeHtml(this.templateQuery)}" />
355
- ${i||a}
356
- `}renderTemplatesGroupView(){let e=(this.templateGroup||"").trim(),t=(this.templateQuery||"").trim().toLowerCase(),i=(this.groupTemplates(this.templates).get(e)||[]).slice().sort((l,c)=>l.label.localeCompare(c.label)),a=(()=>{if(e==="UI Templates"){let l=this.getMissingPackTemplateIds("ui"),c=l.length?"\u2795 Install / Update UI Templates":"\u21BB Update UI Templates",d=l.length?`missing ${l.length}`:"";return`<div class="context-menu-item" data-action="template-pack" data-template-pack="ui">${this.escapeHtml(c)}${d?` <span class="context-menu-subtle">${this.escapeHtml(d)}</span>`:""}</div>`}if(e==="Screen Templates"){let l=this.getMissingPackTemplateIds("screen"),c=l.length?"\u2795 Install / Update Screen Templates":"\u21BB Update Screen Templates",d=l.length?`missing ${l.length}`:"";return`<div class="context-menu-item" data-action="template-pack" data-template-pack="screen">${this.escapeHtml(c)}${d?` <span class="context-menu-subtle">${this.escapeHtml(d)}</span>`:""}</div>`}return""})(),o=(t?i.filter(l=>`${l.id} ${l.label}`.toLowerCase().includes(t)):i).map(l=>{let c=`${l.id} ${l.label}`.toLowerCase();return`<div class="context-menu-item" data-action="template" data-template-id="${this.escapeHtml(l.id)}" data-template-haystack="${this.escapeHtml(c)}">${this.escapeHtml(l.label)}</div>`}).join("");return`
355
+ ${n||a}
356
+ `}renderTemplatesGroupView(){let e=(this.templateGroup||"").trim(),t=(this.templateQuery||"").trim().toLowerCase(),n=(this.groupTemplates(this.templates).get(e)||[]).slice().sort((l,c)=>l.label.localeCompare(c.label)),a=(()=>{if(e==="UI Templates"){let l=this.getMissingPackTemplateIds("ui"),c=l.length?"\u2795 Install / Update UI Templates":"\u21BB Update UI Templates",d=l.length?`missing ${l.length}`:"";return`<div class="context-menu-item" data-action="template-pack" data-template-pack="ui">${this.escapeHtml(c)}${d?` <span class="context-menu-subtle">${this.escapeHtml(d)}</span>`:""}</div>`}if(e==="Screen Templates"){let l=this.getMissingPackTemplateIds("screen"),c=l.length?"\u2795 Install / Update Screen Templates":"\u21BB Update Screen Templates",d=l.length?`missing ${l.length}`:"";return`<div class="context-menu-item" data-action="template-pack" data-template-pack="screen">${this.escapeHtml(c)}${d?` <span class="context-menu-subtle">${this.escapeHtml(d)}</span>`:""}</div>`}return""})(),o=(t?n.filter(l=>`${l.id} ${l.label}`.toLowerCase().includes(t)):n).map(l=>{let c=`${l.id} ${l.label}`.toLowerCase();return`<div class="context-menu-item" data-action="template" data-template-id="${this.escapeHtml(l.id)}" data-template-haystack="${this.escapeHtml(c)}">${this.escapeHtml(l.label)}</div>`}).join("");return`
357
357
  <div class="context-menu-item context-menu-back" data-action="open-view" data-view="templates">\u2190 Back</div>
358
358
  <div class="context-menu-section-title">${this.escapeHtml(e||"Templates")}</div>
359
359
  <input class="context-menu-search" type="text" placeholder="Search\u2026" value="${this.escapeHtml(this.templateQuery)}" />
@@ -379,14 +379,14 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
379
379
  `}renderTargetScreenSection(){return`
380
380
  <div class="context-menu-section-title">Target Screen</div>
381
381
  <div class="context-menu-screen-grid">
382
- ${Mt.map(e=>`
382
+ ${zt.map(e=>`
383
383
  <button class="context-menu-screen-chip ${e.value===this.targetScreen?"active":""}" type="button" data-action="set-screen" data-screen-id="${this.escapeHtml(e.value)}">
384
384
  ${this.escapeHtml(e.label)}
385
385
  </button>
386
386
  `).join("")}
387
387
  </div>
388
388
  <div class="context-menu-separator"></div>
389
- `}groupTemplates(e){let t=new Map,n=(i,a)=>{var o;let r=(o=t.get(i))!=null?o:[];r.push(a),t.set(i,r)};return e.forEach(i=>{let a=(i.id||"").toLowerCase();return a.startsWith("template.ui.")||a.startsWith("template.start.")||a.startsWith("template.endgame.")?n("UI Templates",i):a.startsWith("template.screen.")?n("Screen Templates",i):a.includes(".template")?n("Gameplay Templates",i):a.startsWith("effects.")||a.includes("effect")?n("Effects",i):n("Other",i)}),t}async promptName(e="new_object",t="Enter Object Name"){return new Promise(n=>{var d,p,u;let i=document.createElement("div");i.className="add-menu-modal-overlay",i.innerHTML=`
389
+ `}groupTemplates(e){let t=new Map,i=(n,a)=>{var o;let r=(o=t.get(n))!=null?o:[];r.push(a),t.set(n,r)};return e.forEach(n=>{let a=(n.id||"").toLowerCase();return a.startsWith("template.ui.")||a.startsWith("template.start.")||a.startsWith("template.endgame.")?i("UI Templates",n):a.startsWith("template.screen.")?i("Screen Templates",n):a.includes(".template")?i("Gameplay Templates",n):a.startsWith("effects.")||a.includes("effect")?i("Effects",n):i("Other",n)}),t}async promptName(e="new_object",t="Enter Object Name"){return new Promise(i=>{var d,p,u;let n=document.createElement("div");n.className="add-menu-modal-overlay",n.innerHTML=`
390
390
  <div class="add-menu-modal">
391
391
  <div class="add-menu-modal-header">
392
392
  <div class="add-menu-modal-title">${this.escapeHtml(t)}</div>
@@ -402,7 +402,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
402
402
  <button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Confirm</button>
403
403
  </div>
404
404
  </div>
405
- `;let a=()=>{i.parentNode&&i.parentNode.removeChild(i)},r=()=>{let f=i.querySelector("#name-input").value.trim(),h=this.sanitizeInstanceId(f);if(!h){alert("Invalid name. Use letters, numbers, dots, dashes, or underscores.");return}a(),n(h)},o=()=>{a(),n(null)};i.querySelector(".add-menu-modal").addEventListener("click",g=>{g.stopPropagation()}),(d=i.querySelector('[data-action="confirm"]'))==null||d.addEventListener("click",r),(p=i.querySelector('[data-action="cancel"]'))==null||p.addEventListener("click",o),(u=i.querySelector(".add-menu-modal-close"))==null||u.addEventListener("click",o),i.addEventListener("click",g=>{g.target===i&&o()});let c=i.querySelector("#name-input");c.addEventListener("keydown",g=>{g.key==="Enter"?(g.preventDefault(),r()):g.key==="Escape"&&(g.preventDefault(),o())}),c.select(),document.body.appendChild(i),c.focus()})}async promptSpawnerConfig(){return new Promise(e=>{var f,h,m;let t=document.createElement("div");t.className="add-menu-modal-overlay";let n="template_id",i=`${n}_spawner_1`,a="",r=JSON.stringify([{x:-120,y:-120},{x:0,y:-120},{x:120,y:-120}],null,2),o=JSON.stringify({x:[-240,240],y:[-170,-170]},null,2),l="";t.innerHTML=`
405
+ `;let a=()=>{n.parentNode&&n.parentNode.removeChild(n)},r=()=>{let h=n.querySelector("#name-input").value.trim(),f=this.sanitizeInstanceId(h);if(!f){alert("Invalid name. Use letters, numbers, dots, dashes, or underscores.");return}a(),i(f)},o=()=>{a(),i(null)};n.querySelector(".add-menu-modal").addEventListener("click",g=>{g.stopPropagation()}),(d=n.querySelector('[data-action="confirm"]'))==null||d.addEventListener("click",r),(p=n.querySelector('[data-action="cancel"]'))==null||p.addEventListener("click",o),(u=n.querySelector(".add-menu-modal-close"))==null||u.addEventListener("click",o),n.addEventListener("click",g=>{g.target===n&&o()});let c=n.querySelector("#name-input");c.addEventListener("keydown",g=>{g.key==="Enter"?(g.preventDefault(),r()):g.key==="Escape"&&(g.preventDefault(),o())}),c.select(),document.body.appendChild(n),c.focus()})}async promptSpawnerConfig(){return new Promise(e=>{var h,f,m;let t=document.createElement("div");t.className="add-menu-modal-overlay";let i="template_id",n=`${i}_spawner_1`,a="",r=JSON.stringify([{x:-120,y:-120},{x:0,y:-120},{x:120,y:-120}],null,2),o=JSON.stringify({x:[-240,240],y:[-170,-170]},null,2),l="";t.innerHTML=`
406
406
  <div class="add-menu-modal add-menu-modal-wide">
407
407
  <div class="add-menu-modal-header">
408
408
  <div class="add-menu-modal-title">Create Spawner</div>
@@ -411,11 +411,11 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
411
411
  <div class="add-menu-modal-body">
412
412
  <div class="add-menu-modal-row">
413
413
  <label class="add-menu-modal-label">Instance ID:</label>
414
- <input class="add-menu-modal-input" id="spawner-instance-id" value="${this.escapeHtml(i)}" />
414
+ <input class="add-menu-modal-input" id="spawner-instance-id" value="${this.escapeHtml(n)}" />
415
415
  </div>
416
416
  <div class="add-menu-modal-row">
417
417
  <label class="add-menu-modal-label">Template ID (single):</label>
418
- <input class="add-menu-modal-input" id="spawner-template-id" value="${this.escapeHtml(n)}" />
418
+ <input class="add-menu-modal-input" id="spawner-template-id" value="${this.escapeHtml(i)}" />
419
419
  </div>
420
420
  <div class="add-menu-modal-row">
421
421
  <label class="add-menu-modal-label">Spawn Templates (JSON, optional):</label>
@@ -494,18 +494,18 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
494
494
  <button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Create</button>
495
495
  </div>
496
496
  </div>
497
- `;let c=()=>{t.parentNode&&t.parentNode.removeChild(t)},d=b=>{let y=b.trim();if(!y)return null;try{return JSON.parse(y)}catch{return null}},p=()=>{var G;let b=t.querySelector("#spawner-instance-id").value.trim(),y=t.querySelector("#spawner-template-id").value.trim(),v=t.querySelector("#spawner-spawn-templates").value,w=t.querySelector("#spawner-position-source").value.trim(),E=t.querySelector("#spawner-point-mode").value.trim(),j=t.querySelector("#spawner-spawn-points").value,z=t.querySelector("#spawner-random-bounds").value,S=t.querySelector("#spawner-pattern").value.trim(),P=Number(t.querySelector("#spawner-rate").value.trim()),R=Number(t.querySelector("#spawner-pool").value.trim()),T=Number(t.querySelector("#spawner-lifetime").value.trim()),A=t.querySelector("#spawner-return-on-invisible").checked,M=t.querySelector("#spawner-movement").value.trim(),k=t.querySelector("#spawner-velocity").value.trim(),C=t.querySelector("#spawner-velocity-range").value,x=d(v),I=Array.isArray(x)&&x.length?x:null,L=typeof((G=I==null?void 0:I[0])==null?void 0:G.templateId)=="string"?String(I[0].templateId):y;if(!b){alert("Instance ID is required.");return}if(!L){alert("Template ID is required (or provide Spawn Templates JSON).");return}let _={templateId:L,spawnPattern:S,spawnRate:Number.isFinite(P)?P:650,poolSize:Number.isFinite(R)?R:18,returnOnInvisible:A,positionSource:w,spawnPointMode:E,movementMode:M,lifetime:Number.isFinite(T)?T:5e3};I&&(_.spawnTemplates=I);let O=d(j);Array.isArray(O)&&(_.spawnPoints=O);let H=d(z);if(H&&typeof H=="object"&&(_.randomBounds=H),k.includes(",")){let[K,ze]=k.split(",").map(Ye=>Ye.trim()),ue=Number(K),ge=Number(ze);Number.isFinite(ue)&&Number.isFinite(ge)&&(_.velocity={x:ue,y:ge})}let N=d(C);N&&typeof N=="object"&&(_.velocityRange=N),c(),e({templateId:L,instanceId:b,spawnerProps:_})},u=()=>{c(),e(null)};t.querySelector(".add-menu-modal").addEventListener("click",b=>b.stopPropagation()),(f=t.querySelector('[data-action="confirm"]'))==null||f.addEventListener("click",p),(h=t.querySelector('[data-action="cancel"]'))==null||h.addEventListener("click",u),(m=t.querySelector(".add-menu-modal-close"))==null||m.addEventListener("click",u),t.addEventListener("click",b=>{b.target===t&&u()}),document.body.appendChild(t),t.querySelector("#spawner-instance-id").focus()})}sanitizeInstanceId(e){let t=e.trim();return!t||!/^[a-zA-Z0-9._-]+$/.test(t)?null:t}buildDefaultConfig(e,t,n){let i=`json.${t}`,a={identity:{id:i,category:e==="ui-image"||e==="ui-text"?"ui":"environment"},transform:{position:{x:0,y:0},offset:{x:0,y:0},scale:e==="sprite"||e==="ui-image"?.2:1,rotation:0,anchor:{x:.5,y:.5},position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0},instance_id:t,object_config:i};return(e==="sprite"||e==="ui-image")&&(a.render.asset={type:"image",path:`raw/${n}.png`}),e==="ui-text"&&(a.ui={kind:"text",renderMode:"text",text:n,font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",color:"#FFFFFF"}),e==="graphics"&&(a.effects={width:200,height:200,fill_color:"#FFFFFF",fill_alpha:1}),a}async handleCreateObject(e,t){var l,c,d;this.close();let n=t!=null?t:await this.promptScreen();if(!n)return;let i=e==="ui-text"?"text_1":e==="graphics"?"graphics_1":"sprite_1",a=await this.promptName(i);if(!a)return;let r=a,o=this.buildDefaultConfig(e,r,a);try{let p=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,instanceId:r,objectConfigId:o.identity.id,layer:e==="ui-image"||e==="ui-text"?"ui":"world",config:o})}),u=await p.json().catch(()=>({}));if(!p.ok||(u==null?void 0:u.success)===!1){let f=((l=u==null?void 0:u.errors)==null?void 0:l.join(`
498
- `))||(u==null?void 0:u.error)||"Failed to create object.";alert(f);return}let{trackObjectCreation:g}=await Promise.resolve().then(()=>(J(),Be));g(r,n,o),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed")),(d=(c=this.options).onRefresh)==null||d.call(c)}catch(p){alert(`Failed to create object: ${p instanceof Error?p.message:String(p)}`)}}async handleCreateFromTemplate(e,t){var r,o,l;this.close();let n=t!=null?t:await this.promptScreen();if(!n)return;let i=e.replace(/\.template$/,"").replace(/^json\./,"").replace(/[._]/g,"_")+"_1",a=await this.promptName(i);if(a)try{let c=await fetch("/api/objects/create-from-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({templateId:e,instanceId:a,screenId:n})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((r=d==null?void 0:d.errors)==null?void 0:r.join(`
499
- `))||(d==null?void 0:d.error)||"Failed to create from template.";alert(p);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(l=(o=this.options).onRefresh)==null||l.call(o)}catch(c){alert(`Failed to create from template: ${c instanceof Error?c.message:String(c)}`)}}async handleCreateSystem(e,t){var i,a,r,o,l,c,d,p,u,g,f,h,m,b,y,v,w,E,j,z,S,P,R,T,A,M,k;this.close();let n=t!=null?t:await this.promptScreen();if(n){if(e==="collectable-system")try{let C=await fetch("/api/systems/collectable-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n})}),x=await C.json().catch(()=>({}));if(!C.ok||(x==null?void 0:x.success)===!1){let I=((i=x==null?void 0:x.errors)==null?void 0:i.join(`
500
- `))||(x==null?void 0:x.error)||"Failed to create collectable system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(r=(a=this.options).onRefresh)==null||r.call(a)}catch(C){alert(`Failed to create collectable system: ${C instanceof Error?C.message:String(C)}`)}if(e==="drag-snap-couples")try{let C=await fetch("/api/systems/drag-snap-couples",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n})}),x=await C.json().catch(()=>({}));if(!C.ok||(x==null?void 0:x.success)===!1){let I=((o=x==null?void 0:x.errors)==null?void 0:o.join(`
501
- `))||(x==null?void 0:x.error)||"Failed to create drag-snap system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(c=(l=this.options).onRefresh)==null||c.call(l)}catch(C){alert(`Failed to create drag-snap system: ${C instanceof Error?C.message:String(C)}`)}if(e==="swerve-collect")try{let C=await fetch("/api/systems/swerve-collect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n})}),x=await C.json().catch(()=>({}));if(!C.ok||(x==null?void 0:x.success)===!1){let I=((d=x==null?void 0:x.errors)==null?void 0:d.join(`
502
- `))||(x==null?void 0:x.error)||"Failed to create swerve collect system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(u=(p=this.options).onRefresh)==null||u.call(p)}catch(C){alert(`Failed to create swerve collect system: ${C instanceof Error?C.message:String(C)}`)}if(e==="tap-destroy")try{let C=await fetch("/api/systems/tap-destroy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n})}),x=await C.json().catch(()=>({}));if(!C.ok||(x==null?void 0:x.success)===!1){let I=((g=x==null?void 0:x.errors)==null?void 0:g.join(`
503
- `))||(x==null?void 0:x.error)||"Failed to create tap destroy system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(h=(f=this.options).onRefresh)==null||h.call(f)}catch(C){alert(`Failed to create tap destroy system: ${C instanceof Error?C.message:String(C)}`)}if(e==="scratch-card")try{let C=await fetch("/api/systems/scratch-card",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n})}),x=await C.json().catch(()=>({}));if(!C.ok||(x==null?void 0:x.success)===!1){let I=((m=x==null?void 0:x.errors)==null?void 0:m.join(`
504
- `))||(x==null?void 0:x.error)||"Failed to create scratch card system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(y=(b=this.options).onRefresh)==null||y.call(b)}catch(C){alert(`Failed to create scratch card system: ${C instanceof Error?C.message:String(C)}`)}if(e==="start-screen"||e==="start-screen-no-hand")try{let x=await fetch("/api/systems/start-screen",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,withHand:e==="start-screen"})}),I=await x.json().catch(()=>({}));if(!x.ok||(I==null?void 0:I.success)===!1){let L=((v=I==null?void 0:I.errors)==null?void 0:v.join(`
505
- `))||(I==null?void 0:I.error)||"Failed to create start screen template.";alert(L);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(E=(w=this.options).onRefresh)==null||E.call(w)}catch(C){alert(`Failed to create start screen template: ${C instanceof Error?C.message:String(C)}`)}if(e==="endgame-screen"||e==="endgame-screen-no-hand")try{let x=await fetch("/api/systems/endgame-screen",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,withHand:e==="endgame-screen"})}),I=await x.json().catch(()=>({}));if(!x.ok||(I==null?void 0:I.success)===!1){let L=((j=I==null?void 0:I.errors)==null?void 0:j.join(`
506
- `))||(I==null?void 0:I.error)||"Failed to create endgame screen template.";alert(L);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(S=(z=this.options).onRefresh)==null||S.call(z)}catch(C){alert(`Failed to create endgame screen template: ${C instanceof Error?C.message:String(C)}`)}if(e==="bullet-system")try{let C=await fetch("/api/systems/bullet-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n})}),x=await C.json().catch(()=>({}));if(!C.ok||(x==null?void 0:x.success)===!1){let I=((P=x==null?void 0:x.errors)==null?void 0:P.join(`
507
- `))||(x==null?void 0:x.error)||"Failed to create bullet system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(T=(R=this.options).onRefresh)==null||T.call(R)}catch(C){alert(`Failed to create bullet system: ${C instanceof Error?C.message:String(C)}`)}if(e==="spawner"){let C=await this.promptSpawnerConfig();if(!C)return;let{templateId:x,instanceId:I,spawnerProps:L}=C;try{let _=await fetch("/api/systems/spawner",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,templateId:x,instanceId:I,spawnerProps:L})}),O=await _.json().catch(()=>({}));if(!_.ok||(O==null?void 0:O.success)===!1){let H=((A=O==null?void 0:O.errors)==null?void 0:A.join(`
508
- `))||(O==null?void 0:O.error)||"Failed to create spawner.";alert(H);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(k=(M=this.options).onRefresh)==null||k.call(M)}catch(_){alert(`Failed to create spawner: ${_ instanceof Error?_.message:String(_)}`)}}}}escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}async syncScreens(){try{await fetch("/api/sync-screens",{method:"POST"})}catch(e){console.warn("[AddObjectMenu] Failed to sync screens:",e)}}};var Tn=class{constructor(){this.root=null;this.listContainer=null;this.searchInput=null;this.selectedId=null;this.selectedIds=new Set;this.lastSelectedIndex=-1;this.objectEntries=[];this.options=null;this.retryTimer=null;this.screenFilter="all";this.showTemplates=!1;this.isContextMenuOpen=!1;this.systemBundles=new Map}getScreenFilterStorageKey(){return`handler_preview_screen_filter::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getShowTemplatesStorageKey(){return`handler_preview_show_templates::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}render(){return`
497
+ `;let c=()=>{t.parentNode&&t.parentNode.removeChild(t)},d=b=>{let y=b.trim();if(!y)return null;try{return JSON.parse(y)}catch{return null}},p=()=>{var q;let b=t.querySelector("#spawner-instance-id").value.trim(),y=t.querySelector("#spawner-template-id").value.trim(),v=t.querySelector("#spawner-spawn-templates").value,w=t.querySelector("#spawner-position-source").value.trim(),E=t.querySelector("#spawner-point-mode").value.trim(),P=t.querySelector("#spawner-spawn-points").value,M=t.querySelector("#spawner-random-bounds").value,x=t.querySelector("#spawner-pattern").value.trim(),_=Number(t.querySelector("#spawner-rate").value.trim()),O=Number(t.querySelector("#spawner-pool").value.trim()),T=Number(t.querySelector("#spawner-lifetime").value.trim()),A=t.querySelector("#spawner-return-on-invisible").checked,j=t.querySelector("#spawner-movement").value.trim(),k=t.querySelector("#spawner-velocity").value.trim(),C=t.querySelector("#spawner-velocity-range").value,S=d(v),I=Array.isArray(S)&&S.length?S:null,L=typeof((q=I==null?void 0:I[0])==null?void 0:q.templateId)=="string"?String(I[0].templateId):y;if(!b){alert("Instance ID is required.");return}if(!L){alert("Template ID is required (or provide Spawn Templates JSON).");return}let R={templateId:L,spawnPattern:x,spawnRate:Number.isFinite(_)?_:650,poolSize:Number.isFinite(O)?O:18,returnOnInvisible:A,positionSource:w,spawnPointMode:E,movementMode:j,lifetime:Number.isFinite(T)?T:5e3};I&&(R.spawnTemplates=I);let z=d(P);Array.isArray(z)&&(R.spawnPoints=z);let N=d(M);if(N&&typeof N=="object"&&(R.randomBounds=N),k.includes(",")){let[J,De]=k.split(",").map(Je=>Je.trim()),fe=Number(J),me=Number(De);Number.isFinite(fe)&&Number.isFinite(me)&&(R.velocity={x:fe,y:me})}let F=d(C);F&&typeof F=="object"&&(R.velocityRange=F),c(),e({templateId:L,instanceId:b,spawnerProps:R})},u=()=>{c(),e(null)};t.querySelector(".add-menu-modal").addEventListener("click",b=>b.stopPropagation()),(h=t.querySelector('[data-action="confirm"]'))==null||h.addEventListener("click",p),(f=t.querySelector('[data-action="cancel"]'))==null||f.addEventListener("click",u),(m=t.querySelector(".add-menu-modal-close"))==null||m.addEventListener("click",u),t.addEventListener("click",b=>{b.target===t&&u()}),document.body.appendChild(t),t.querySelector("#spawner-instance-id").focus()})}sanitizeInstanceId(e){let t=e.trim();return!t||!/^[a-zA-Z0-9._-]+$/.test(t)?null:t}buildDefaultConfig(e,t,i){let n=`json.${t}`,a={identity:{id:n,category:e==="ui-image"||e==="ui-text"?"ui":"environment"},transform:{position:{x:0,y:0},offset:{x:0,y:0},scale:e==="sprite"||e==="ui-image"?.2:1,rotation:0,anchor:{x:.5,y:.5},position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0},instance_id:t,object_config:n};return(e==="sprite"||e==="ui-image")&&(a.render.asset={type:"image",path:`raw/${i}.png`}),e==="ui-text"&&(a.ui={kind:"text",renderMode:"text",text:i,font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",color:"#FFFFFF"}),e==="graphics"&&(a.effects={width:200,height:200,fill_color:"#FFFFFF",fill_alpha:1}),a}async handleCreateObject(e,t){var l,c,d;this.close();let i=t!=null?t:await this.promptScreen();if(!i)return;let n=e==="ui-text"?"text_1":e==="graphics"?"graphics_1":"sprite_1",a=await this.promptName(n);if(!a)return;let r=a,o=this.buildDefaultConfig(e,r,a);try{let p=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:r,objectConfigId:o.identity.id,layer:e==="ui-image"||e==="ui-text"?"ui":"world",config:o})}),u=await p.json().catch(()=>({}));if(!p.ok||(u==null?void 0:u.success)===!1){let h=((l=u==null?void 0:u.errors)==null?void 0:l.join(`
498
+ `))||(u==null?void 0:u.error)||"Failed to create object.";alert(h);return}let{trackObjectCreation:g}=await Promise.resolve().then(()=>(K(),Ge));g(r,i,o),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed")),(d=(c=this.options).onRefresh)==null||d.call(c)}catch(p){alert(`Failed to create object: ${p instanceof Error?p.message:String(p)}`)}}async handleCreateFromTemplate(e,t){var r,o,l;this.close();let i=t!=null?t:await this.promptScreen();if(!i)return;let n=e.replace(/\.template$/,"").replace(/^json\./,"").replace(/[._]/g,"_")+"_1",a=await this.promptName(n);if(a)try{let c=await fetch("/api/objects/create-from-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({templateId:e,instanceId:a,screenId:i})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((r=d==null?void 0:d.errors)==null?void 0:r.join(`
499
+ `))||(d==null?void 0:d.error)||"Failed to create from template.";alert(p);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(l=(o=this.options).onRefresh)==null||l.call(o)}catch(c){alert(`Failed to create from template: ${c instanceof Error?c.message:String(c)}`)}}async handleCreateSystem(e,t){var n,a,r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,E,P,M,x,_,O,T,A,j,k;this.close();let i=t!=null?t:await this.promptScreen();if(i){if(e==="collectable-system")try{let C=await fetch("/api/systems/collectable-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await C.json().catch(()=>({}));if(!C.ok||(S==null?void 0:S.success)===!1){let I=((n=S==null?void 0:S.errors)==null?void 0:n.join(`
500
+ `))||(S==null?void 0:S.error)||"Failed to create collectable system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(r=(a=this.options).onRefresh)==null||r.call(a)}catch(C){alert(`Failed to create collectable system: ${C instanceof Error?C.message:String(C)}`)}if(e==="drag-snap-couples")try{let C=await fetch("/api/systems/drag-snap-couples",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await C.json().catch(()=>({}));if(!C.ok||(S==null?void 0:S.success)===!1){let I=((o=S==null?void 0:S.errors)==null?void 0:o.join(`
501
+ `))||(S==null?void 0:S.error)||"Failed to create drag-snap system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(c=(l=this.options).onRefresh)==null||c.call(l)}catch(C){alert(`Failed to create drag-snap system: ${C instanceof Error?C.message:String(C)}`)}if(e==="swerve-collect")try{let C=await fetch("/api/systems/swerve-collect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await C.json().catch(()=>({}));if(!C.ok||(S==null?void 0:S.success)===!1){let I=((d=S==null?void 0:S.errors)==null?void 0:d.join(`
502
+ `))||(S==null?void 0:S.error)||"Failed to create swerve collect system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(u=(p=this.options).onRefresh)==null||u.call(p)}catch(C){alert(`Failed to create swerve collect system: ${C instanceof Error?C.message:String(C)}`)}if(e==="tap-destroy")try{let C=await fetch("/api/systems/tap-destroy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await C.json().catch(()=>({}));if(!C.ok||(S==null?void 0:S.success)===!1){let I=((g=S==null?void 0:S.errors)==null?void 0:g.join(`
503
+ `))||(S==null?void 0:S.error)||"Failed to create tap destroy system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(f=(h=this.options).onRefresh)==null||f.call(h)}catch(C){alert(`Failed to create tap destroy system: ${C instanceof Error?C.message:String(C)}`)}if(e==="scratch-card")try{let C=await fetch("/api/systems/scratch-card",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await C.json().catch(()=>({}));if(!C.ok||(S==null?void 0:S.success)===!1){let I=((m=S==null?void 0:S.errors)==null?void 0:m.join(`
504
+ `))||(S==null?void 0:S.error)||"Failed to create scratch card system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(y=(b=this.options).onRefresh)==null||y.call(b)}catch(C){alert(`Failed to create scratch card system: ${C instanceof Error?C.message:String(C)}`)}if(e==="start-screen"||e==="start-screen-no-hand")try{let S=await fetch("/api/systems/start-screen",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,withHand:e==="start-screen"})}),I=await S.json().catch(()=>({}));if(!S.ok||(I==null?void 0:I.success)===!1){let L=((v=I==null?void 0:I.errors)==null?void 0:v.join(`
505
+ `))||(I==null?void 0:I.error)||"Failed to create start screen template.";alert(L);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(E=(w=this.options).onRefresh)==null||E.call(w)}catch(C){alert(`Failed to create start screen template: ${C instanceof Error?C.message:String(C)}`)}if(e==="endgame-screen"||e==="endgame-screen-no-hand")try{let S=await fetch("/api/systems/endgame-screen",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,withHand:e==="endgame-screen"})}),I=await S.json().catch(()=>({}));if(!S.ok||(I==null?void 0:I.success)===!1){let L=((P=I==null?void 0:I.errors)==null?void 0:P.join(`
506
+ `))||(I==null?void 0:I.error)||"Failed to create endgame screen template.";alert(L);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(x=(M=this.options).onRefresh)==null||x.call(M)}catch(C){alert(`Failed to create endgame screen template: ${C instanceof Error?C.message:String(C)}`)}if(e==="bullet-system")try{let C=await fetch("/api/systems/bullet-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await C.json().catch(()=>({}));if(!C.ok||(S==null?void 0:S.success)===!1){let I=((_=S==null?void 0:S.errors)==null?void 0:_.join(`
507
+ `))||(S==null?void 0:S.error)||"Failed to create bullet system.";alert(I);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(T=(O=this.options).onRefresh)==null||T.call(O)}catch(C){alert(`Failed to create bullet system: ${C instanceof Error?C.message:String(C)}`)}if(e==="spawner"){let C=await this.promptSpawnerConfig();if(!C)return;let{templateId:S,instanceId:I,spawnerProps:L}=C;try{let R=await fetch("/api/systems/spawner",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,templateId:S,instanceId:I,spawnerProps:L})}),z=await R.json().catch(()=>({}));if(!R.ok||(z==null?void 0:z.success)===!1){let N=((A=z==null?void 0:z.errors)==null?void 0:A.join(`
508
+ `))||(z==null?void 0:z.error)||"Failed to create spawner.";alert(N);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(k=(j=this.options).onRefresh)==null||k.call(j)}catch(R){alert(`Failed to create spawner: ${R instanceof Error?R.message:String(R)}`)}}}}escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}async syncScreens(){try{await fetch("/api/sync-screens",{method:"POST"})}catch(e){console.warn("[AddObjectMenu] Failed to sync screens:",e)}}};var ki=class{constructor(){this.root=null;this.listContainer=null;this.searchInput=null;this.selectedId=null;this.selectedIds=new Set;this.lastSelectedIndex=-1;this.objectEntries=[];this.options=null;this.retryTimer=null;this.screenFilter="all";this.showTemplates=!1;this.isContextMenuOpen=!1;this.systemBundles=new Map}getScreenFilterStorageKey(){return`handler_preview_screen_filter::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getShowTemplatesStorageKey(){return`handler_preview_show_templates::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}render(){return`
509
509
  <div class="scene-panel scene-objects panel-accent-teal" data-panel="scene-objects">
510
510
  <div class="scene-panel-header" data-panel-handle>
511
511
  <div class="panel-title">
@@ -544,7 +544,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
544
544
  </div>
545
545
  <div class="panel-resize-handle-v" data-panel-resize-v></div>
546
546
  </div>
547
- `}initialize(e,t){var r,o,l,c,d,p,u,g,f;this.options=t,this.root=e.querySelector('[data-panel="scene-objects"]'),this.listContainer=(r=this.root)==null?void 0:r.querySelector("[data-object-list]"),this.searchInput=(o=this.root)==null?void 0:o.querySelector("#scene-object-search"),(l=this.searchInput)==null||l.addEventListener("input",()=>this.refreshObjects()),(c=this.listContainer)==null||c.addEventListener("click",h=>{let m=h.target,b=m==null?void 0:m.closest("[data-object-visibility-toggle][data-object-id]");if(b){let E=b.dataset.objectId;if(!E)return;h.preventDefault(),h.stopPropagation(),this.toggleObjectVisibility(E);return}let y=m==null?void 0:m.closest("[data-system-bundle-action][data-system-bundle-id]");if(!y)return;h.preventDefault(),h.stopPropagation();let v=y.dataset.systemBundleAction,w=y.dataset.systemBundleId;if(!(!v||!w)){if(v==="toggle-visibility"){this.toggleSystemBundleVisibility(w);return}v==="delete"&&this.deleteSystemBundle(w)}});let n=(d=this.root)==null?void 0:d.querySelector("[data-add-object]");n==null||n.addEventListener("click",h=>{h.stopPropagation();let m=n.getBoundingClientRect();this.openAddObjectMenu({x:m.left,y:m.bottom+4})});let i=(p=this.root)==null?void 0:p.querySelector("#scene-screen-filter");if(i){try{let h=window.localStorage.getItem(this.getScreenFilterStorageKey());h&&(this.screenFilter=h)}catch{}i.value=this.screenFilter;try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}i.addEventListener("change",()=>{let h=i.value||"all";this.screenFilter=h;try{window.localStorage.setItem(this.getScreenFilterStorageKey(),this.screenFilter)}catch{}try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}this.refreshObjects()})}let a=(u=this.root)==null?void 0:u.querySelector("#scene-templates-toggle");if(a){try{let h=window.localStorage.getItem(this.getShowTemplatesStorageKey());this.showTemplates=h==="true"}catch{}a.checked=this.showTemplates,a.addEventListener("change",()=>{this.showTemplates=!!a.checked;try{window.localStorage.setItem(this.getShowTemplatesStorageKey(),this.showTemplates?"true":"false")}catch{}this.refreshObjects()})}(g=this.root)==null||g.addEventListener("click",h=>{let m=h.target;if(!m||m.closest("[data-context-menu]"))return;if(m.tagName==="INPUT"&&m.classList.contains("scene-object-checkbox")){let j=m.dataset.objectId;if(!j)return;h.stopPropagation(),this.toggleBatchSelect(j);return}let b=m.closest(".scene-object-item[data-object-id]");if(!b)return;let y=b.dataset.objectId;if(!y)return;let v=h.ctrlKey||h.metaKey;h.shiftKey&&this.lastSelectedIndex>=0?this.selectRange(this.lastSelectedIndex,y):v?this.toggleBatchSelect(y):this.select(y)}),(f=this.listContainer)==null||f.addEventListener("contextmenu",h=>{var j;let m=h.target,b=m==null?void 0:m.closest("[data-object-id]");if(!b)return;let y=b.dataset.objectId;if(!y)return;h.preventDefault();let v=window.getEditableObjectConfig,w=typeof v=="function"?v(y):null;if(!w){let z=window.__editableObjectConfigs;z&&typeof z.get=="function"&&(w=(j=z.get(y))!=null?j:null)}let E=this.inferScreen(y,w);this.showContextMenu(y,E,h.clientX,h.clientY)}),window.addEventListener("handler:screen-index-loaded",()=>this.refreshObjects()),window.addEventListener("handler:scene-objects-refresh",()=>this.refreshObjects())}setSelected(e){e?(this.selectedIds.clear(),this.selectedIds.add(e),this.selectedId=e):(this.selectedIds.clear(),this.selectedId=null),this.updateSelectionUI()}getSelectedIds(){return Array.from(this.selectedIds)}updateSelectionUI(){var a,r,o,l,c;if(!this.listContainer)return;Array.from(this.listContainer.querySelectorAll("[data-object-id]")).forEach(d=>{let p=d.dataset.objectId,u=p?this.selectedIds.has(p):!1,g=p===this.selectedId;d.classList.toggle("selected",u),d.classList.toggle("active",g);let f=d.closest(".scene-object-item-wrapper"),h=f==null?void 0:f.querySelector(".scene-object-checkbox");h&&(h.checked=u)});let t=(a=this.root)==null?void 0:a.querySelector("[data-breadcrumbs]"),n=(r=this.root)==null?void 0:r.querySelector("[data-breadcrumb-screen]"),i=(o=this.root)==null?void 0:o.querySelector("[data-breadcrumb-object]");if(t&&n&&i){let d=this.selectedIds.size===1?this.selectedId:null;if(d){let p=window.getEditableObjectConfig,u=typeof p=="function"?p(d):null;if(!u){let b=window.__editableObjectConfigs;b&&typeof b.get=="function"&&(u=(l=b.get(d))!=null?l:null)}let g=this.inferScreen(d,u),f={loading:"Loading",start:"Start",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},h=(((c=u==null?void 0:u.identity)==null?void 0:c.id)||d).toString(),m=this.formatDisplayName(h);n.textContent=f[g]||g,i.textContent=m,t.style.display="flex"}else t.style.display="none"}}refreshObjects(){var v;if(!this.listContainer)return;let e=window.getEditableObjectList,t=window.refreshEditableConfigIndex;if(typeof t=="function"&&t(),typeof e!="function"){this.scheduleRetry();return}let n=e();if(!Array.isArray(n)||n.length===0){let w=window.__editableObjectConfigs;w&&typeof w.keys=="function"&&(n=Array.from(w.keys()))}if(!Array.isArray(n)||n.length===0){this.scheduleRetry();return}let i=(((v=this.searchInput)==null?void 0:v.value)||"").trim().toLowerCase(),a=["loading","start","gameplay","tutorial","endgame"],r=Object.fromEntries(a.map(w=>[w,[]])),o=Object.fromEntries(a.map(w=>[w,[]])),l=[],c=[],d=new Map;this.systemBundles=new Map;let p=w=>{var z,S,P,R,T;let E=(R=(P=(S=(z=window.__editableConfig)==null?void 0:z.objects)==null?void 0:S.get)==null?void 0:P.call(S,w))!=null?R:null;if(E)return E;let j=window.__editableObjectConfigs;return j&&typeof j.get=="function"&&(T=j.get(w))!=null?T:null};n.forEach(w=>{var H,N,G,K,ze,ue,ge,Ye;let E=p(w),j=(((H=E==null?void 0:E.identity)==null?void 0:H.category)||"scene").toString(),z=(((N=E==null?void 0:E.identity)==null?void 0:N.id)||w).toString(),S=j.toLowerCase(),P=z.toLowerCase(),R=S.includes("ui")||P.startsWith("ui")||P.includes("label"),T=S==="system",A=((G=E==null?void 0:E.identity)==null?void 0:G.is_template)===!0||P.includes(".template")||w.toLowerCase().includes(".template"),M=typeof((K=E==null?void 0:E.identity)==null?void 0:K.system_group)=="string"?E.identity.system_group:null,k=typeof((ze=E==null?void 0:E.identity)==null?void 0:ze.system_label)=="string"?E.identity.system_label:M?this.formatDisplayName(M):null,C=this.formatDisplayName(z||w),x=((ue=E==null?void 0:E.render)==null?void 0:ue.visible)===!1||(E==null?void 0:E.enabled)===!1,I=this.getObjectType(E),L={id:w,label:C,category:j,isUi:R,isTemplate:A,isUnused:x,objectType:I,systemGroupId:M,systemLabel:k},_=this.inferScreen(L.id,E);if(!(this.screenFilter!=="all"&&_!==this.screenFilter||!(!i||L.id.toLowerCase().includes(i)||L.label.toLowerCase().includes(i)))){if(M){if(A&&!this.showTemplates)return;let D=(ge=d.get(M))!=null?ge:[];D.push(L),d.set(M,D);let Z=(Ye=this.systemBundles.get(M))!=null?Ye:{label:k!=null?k:M,objectIds:[]};Z.label=k!=null?k:Z.label,Z.objectIds.push(w),this.systemBundles.set(M,Z);return}if(A){if(!this.showTemplates)return;c.push(L);return}T?l.push(L):(L.isUnused?o:r)[_].push(L)}});let u={loading:"Loading Screen",start:"Start Screen",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},f=[...Array.from(d.entries()).map(([w,E])=>{var j,z,S,P;return{groupId:w,label:(z=(j=this.systemBundles.get(w))==null?void 0:j.label)!=null?z:w,objectIds:(P=(S=this.systemBundles.get(w))==null?void 0:S.objectIds)!=null?P:[],entries:E}})].sort((w,E)=>w.label.localeCompare(E.label)),h=f.length>0?this.renderSystemBundlesGroup(f):"",m=l.length>0?this.renderSystemGroup(l):"",b=a.map(w=>this.renderGroup(u[w],[...r[w],...o[w]])).join(""),y=c.length>0?this.renderGroup("Templates",c):"";if(this.listContainer.innerHTML=h+m+b+y,this.objectEntries=[...f.flatMap(w=>w.entries),...l,...a.flatMap(w=>[...r[w],...o[w]]),...c],l.length>0){let w=this.listContainer.querySelector("[data-delete-system-group]");w==null||w.addEventListener("click",E=>{E.stopPropagation(),this.deleteSystemGroup(l)})}this.updateSelectionUI()}renderSystemBundlesGroup(e){if(!e.length)return"";let t=e.map(n=>this.renderSystemBundle(n.groupId,n.label,n.objectIds,n.entries)).join("");return`
547
+ `}initialize(e,t){var r,o,l,c,d,p,u,g,h;this.options=t,this.root=e.querySelector('[data-panel="scene-objects"]'),this.listContainer=(r=this.root)==null?void 0:r.querySelector("[data-object-list]"),this.searchInput=(o=this.root)==null?void 0:o.querySelector("#scene-object-search"),(l=this.searchInput)==null||l.addEventListener("input",()=>this.refreshObjects()),(c=this.listContainer)==null||c.addEventListener("click",f=>{let m=f.target,b=m==null?void 0:m.closest("[data-object-visibility-toggle][data-object-id]");if(b){let E=b.dataset.objectId;if(!E)return;f.preventDefault(),f.stopPropagation(),this.toggleObjectVisibility(E);return}let y=m==null?void 0:m.closest("[data-system-bundle-action][data-system-bundle-id]");if(!y)return;f.preventDefault(),f.stopPropagation();let v=y.dataset.systemBundleAction,w=y.dataset.systemBundleId;if(!(!v||!w)){if(v==="toggle-visibility"){this.toggleSystemBundleVisibility(w);return}v==="delete"&&this.deleteSystemBundle(w)}});let i=(d=this.root)==null?void 0:d.querySelector("[data-add-object]");i==null||i.addEventListener("click",f=>{f.stopPropagation();let m=i.getBoundingClientRect();this.openAddObjectMenu({x:m.left,y:m.bottom+4})});let n=(p=this.root)==null?void 0:p.querySelector("#scene-screen-filter");if(n){try{let f=window.localStorage.getItem(this.getScreenFilterStorageKey());f&&(this.screenFilter=f)}catch{}n.value=this.screenFilter;try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}n.addEventListener("change",()=>{let f=n.value||"all";this.screenFilter=f;try{window.localStorage.setItem(this.getScreenFilterStorageKey(),this.screenFilter)}catch{}try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}this.refreshObjects()})}let a=(u=this.root)==null?void 0:u.querySelector("#scene-templates-toggle");if(a){try{let f=window.localStorage.getItem(this.getShowTemplatesStorageKey());this.showTemplates=f==="true"}catch{}a.checked=this.showTemplates,a.addEventListener("change",()=>{this.showTemplates=!!a.checked;try{window.localStorage.setItem(this.getShowTemplatesStorageKey(),this.showTemplates?"true":"false")}catch{}this.refreshObjects()})}(g=this.root)==null||g.addEventListener("click",f=>{let m=f.target;if(!m||m.closest("[data-context-menu]"))return;if(m.tagName==="INPUT"&&m.classList.contains("scene-object-checkbox")){let P=m.dataset.objectId;if(!P)return;f.stopPropagation(),this.toggleBatchSelect(P);return}let b=m.closest(".scene-object-item[data-object-id]");if(!b)return;let y=b.dataset.objectId;if(!y)return;let v=f.ctrlKey||f.metaKey;f.shiftKey&&this.lastSelectedIndex>=0?this.selectRange(this.lastSelectedIndex,y):v?this.toggleBatchSelect(y):this.select(y)}),(h=this.listContainer)==null||h.addEventListener("contextmenu",f=>{var P;let m=f.target,b=m==null?void 0:m.closest("[data-object-id]");if(!b)return;let y=b.dataset.objectId;if(!y)return;f.preventDefault();let v=window.getEditableObjectConfig,w=typeof v=="function"?v(y):null;if(!w){let M=window.__editableObjectConfigs;M&&typeof M.get=="function"&&(w=(P=M.get(y))!=null?P:null)}let E=this.inferScreen(y,w);this.showContextMenu(y,E,f.clientX,f.clientY)}),window.addEventListener("handler:screen-index-loaded",()=>this.refreshObjects()),window.addEventListener("handler:scene-objects-refresh",()=>this.refreshObjects())}setSelected(e){e?(this.selectedIds.clear(),this.selectedIds.add(e),this.selectedId=e):(this.selectedIds.clear(),this.selectedId=null),this.updateSelectionUI()}getSelectedIds(){return Array.from(this.selectedIds)}updateSelectionUI(){var a,r,o,l,c;if(!this.listContainer)return;Array.from(this.listContainer.querySelectorAll("[data-object-id]")).forEach(d=>{let p=d.dataset.objectId,u=p?this.selectedIds.has(p):!1,g=p===this.selectedId;d.classList.toggle("selected",u),d.classList.toggle("active",g);let h=d.closest(".scene-object-item-wrapper"),f=h==null?void 0:h.querySelector(".scene-object-checkbox");f&&(f.checked=u)});let t=(a=this.root)==null?void 0:a.querySelector("[data-breadcrumbs]"),i=(r=this.root)==null?void 0:r.querySelector("[data-breadcrumb-screen]"),n=(o=this.root)==null?void 0:o.querySelector("[data-breadcrumb-object]");if(t&&i&&n){let d=this.selectedIds.size===1?this.selectedId:null;if(d){let p=window.getEditableObjectConfig,u=typeof p=="function"?p(d):null;if(!u){let b=window.__editableObjectConfigs;b&&typeof b.get=="function"&&(u=(l=b.get(d))!=null?l:null)}let g=this.inferScreen(d,u),h={loading:"Loading",start:"Start",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},f=(((c=u==null?void 0:u.identity)==null?void 0:c.id)||d).toString(),m=this.formatDisplayName(f);i.textContent=h[g]||g,n.textContent=m,t.style.display="flex"}else t.style.display="none"}}refreshObjects(){var v;if(!this.listContainer)return;let e=window.getEditableObjectList,t=window.refreshEditableConfigIndex;if(typeof t=="function"&&t(),typeof e!="function"){this.scheduleRetry();return}let i=e();if(!Array.isArray(i)||i.length===0){let w=window.__editableObjectConfigs;w&&typeof w.keys=="function"&&(i=Array.from(w.keys()))}if(!Array.isArray(i)||i.length===0){this.scheduleRetry();return}let n=(((v=this.searchInput)==null?void 0:v.value)||"").trim().toLowerCase(),a=["loading","start","gameplay","tutorial","endgame"],r=Object.fromEntries(a.map(w=>[w,[]])),o=Object.fromEntries(a.map(w=>[w,[]])),l=[],c=[],d=new Map;this.systemBundles=new Map;let p=w=>{var M,x,_,O,T;let E=(O=(_=(x=(M=window.__editableConfig)==null?void 0:M.objects)==null?void 0:x.get)==null?void 0:_.call(x,w))!=null?O:null;if(E)return E;let P=window.__editableObjectConfigs;return P&&typeof P.get=="function"&&(T=P.get(w))!=null?T:null};i.forEach(w=>{var N,F,q,J,De,fe,me,Je;let E=p(w),P=(((N=E==null?void 0:E.identity)==null?void 0:N.category)||"scene").toString(),M=(((F=E==null?void 0:E.identity)==null?void 0:F.id)||w).toString(),x=P.toLowerCase(),_=M.toLowerCase(),O=x.includes("ui")||_.startsWith("ui")||_.includes("label"),T=x==="system",A=((q=E==null?void 0:E.identity)==null?void 0:q.is_template)===!0||_.includes(".template")||w.toLowerCase().includes(".template"),j=typeof((J=E==null?void 0:E.identity)==null?void 0:J.system_group)=="string"?E.identity.system_group:null,k=typeof((De=E==null?void 0:E.identity)==null?void 0:De.system_label)=="string"?E.identity.system_label:j?this.formatDisplayName(j):null,C=this.formatDisplayName(M||w),S=((fe=E==null?void 0:E.render)==null?void 0:fe.visible)===!1||(E==null?void 0:E.enabled)===!1,I=this.getObjectType(E),L={id:w,label:C,category:P,isUi:O,isTemplate:A,isUnused:S,objectType:I,systemGroupId:j,systemLabel:k},R=this.inferScreen(L.id,E);if(!(this.screenFilter!=="all"&&R!==this.screenFilter||!(!n||L.id.toLowerCase().includes(n)||L.label.toLowerCase().includes(n)))){if(j){if(A&&!this.showTemplates)return;let D=(me=d.get(j))!=null?me:[];D.push(L),d.set(j,D);let Q=(Je=this.systemBundles.get(j))!=null?Je:{label:k!=null?k:j,objectIds:[]};Q.label=k!=null?k:Q.label,Q.objectIds.push(w),this.systemBundles.set(j,Q);return}if(A){if(!this.showTemplates)return;c.push(L);return}T?l.push(L):(L.isUnused?o:r)[R].push(L)}});let u={loading:"Loading Screen",start:"Start Screen",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},h=[...Array.from(d.entries()).map(([w,E])=>{var P,M,x,_;return{groupId:w,label:(M=(P=this.systemBundles.get(w))==null?void 0:P.label)!=null?M:w,objectIds:(_=(x=this.systemBundles.get(w))==null?void 0:x.objectIds)!=null?_:[],entries:E}})].sort((w,E)=>w.label.localeCompare(E.label)),f=h.length>0?this.renderSystemBundlesGroup(h):"",m=l.length>0?this.renderSystemGroup(l):"",b=a.map(w=>this.renderGroup(u[w],[...r[w],...o[w]])).join(""),y=c.length>0?this.renderGroup("Templates",c):"";if(this.listContainer.innerHTML=f+m+b+y,this.objectEntries=[...h.flatMap(w=>w.entries),...l,...a.flatMap(w=>[...r[w],...o[w]]),...c],l.length>0){let w=this.listContainer.querySelector("[data-delete-system-group]");w==null||w.addEventListener("click",E=>{E.stopPropagation(),this.deleteSystemGroup(l)})}this.updateSelectionUI()}renderSystemBundlesGroup(e){if(!e.length)return"";let t=e.map(i=>this.renderSystemBundle(i.groupId,i.label,i.objectIds,i.entries)).join("");return`
548
548
  <div class="scene-object-group scene-object-group-system">
549
549
  <div class="scene-object-group-title">
550
550
  <span>\u{1F9E9} Systems <span class="scene-object-count">${e.length}</span></span>
@@ -553,10 +553,10 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
553
553
  ${t}
554
554
  </div>
555
555
  </div>
556
- `}renderSystemBundle(e,t,n,i){let a=this.isBundleAllHidden(n),r=a?"Show all objects in this system":"Hide all objects in this system",o=a?"is-hidden":"",l=i.map(d=>this.renderEntryItem(d)).join(""),c=this.escapeHtml(e);return`
556
+ `}renderSystemBundle(e,t,i,n){let a=this.isBundleAllHidden(i),r=a?"Show all objects in this system":"Hide all objects in this system",o=a?"is-hidden":"",l=n.map(d=>this.renderEntryItem(d)).join(""),c=this.escapeHtml(e);return`
557
557
  <div class="scene-object-group scene-object-group-bundle" data-system-bundle="${c}">
558
558
  <div class="scene-object-group-title">
559
- <span>${this.escapeHtml(t)} <span class="scene-object-count">${n.length}</span></span>
559
+ <span>${this.escapeHtml(t)} <span class="scene-object-count">${i.length}</span></span>
560
560
  <div class="scene-object-group-actions">
561
561
  <button class="scene-object-group-action scene-object-group-visibility ${o}" data-system-bundle-action="toggle-visibility" data-system-bundle-id="${c}" type="button" title="${r}">\u{1F441}\uFE0F</button>
562
562
  <button class="scene-object-group-delete" data-system-bundle-action="delete" data-system-bundle-id="${c}" type="button" title="Delete this system">\u{1F5D1}\uFE0F</button>
@@ -566,18 +566,18 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
566
566
  ${l}
567
567
  </div>
568
568
  </div>
569
- `}renderEntryItem(e){var l,c,d;let t=window.getEditableObjectConfig,n=typeof t=="function"?t(e.id):null;if(!n){let p=window.__editableObjectConfigs;p&&typeof p.get=="function"&&(n=(l=p.get(e.id))!=null?l:null)}let i=(c=n==null?void 0:n.ui)!=null&&c.text?`"${n.ui.text.substring(0,12)}${n.ui.text.length>12?"...":""}"`:"",a=e.isTemplate?'<span class="scene-object-badge template">template</span>':"",r=((d=n==null?void 0:n.render)==null?void 0:d.visible)===!1;return`
569
+ `}renderEntryItem(e){var l,c,d;let t=window.getEditableObjectConfig,i=typeof t=="function"?t(e.id):null;if(!i){let p=window.__editableObjectConfigs;p&&typeof p.get=="function"&&(i=(l=p.get(e.id))!=null?l:null)}let n=(c=i==null?void 0:i.ui)!=null&&c.text?`"${i.ui.text.substring(0,12)}${i.ui.text.length>12?"...":""}"`:"",a=e.isTemplate?'<span class="scene-object-badge template">template</span>':"",r=((d=i==null?void 0:i.render)==null?void 0:d.visible)===!1;return`
570
570
  <div class="scene-object-item-wrapper">
571
571
  <input type="checkbox" class="scene-object-checkbox" ${this.selectedIds.has(e.id)?"checked":""} data-object-id="${e.id}">
572
572
  ${this.renderVisibilityButton(e.id,r)}
573
573
  <button class="scene-object-item ${e.isUnused?"unused":""}" data-object-id="${e.id}">
574
574
  <span class="scene-object-label">${e.label}</span>
575
- ${i?`<span class="scene-object-text-preview">${i}</span>`:""}
575
+ ${n?`<span class="scene-object-text-preview">${n}</span>`:""}
576
576
  ${a}
577
577
  <span class="scene-object-badge ${e.isUi?"ui":"scene"}">${e.category}</span>
578
578
  </button>
579
579
  </div>
580
- `}escapeHtml(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}toggleObjectVisibility(e){var a;let t=(a=window.__editableConfig)==null?void 0:a.objects;if(!t||typeof t.get!="function")return;let n=t.get(e);if(!n)return;n.render||(n.render={});let i=n.render.visible!==!1;n.render.visible=!i;try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e,action:"update"}}))}catch{}this.refreshObjects()}renderVisibilityButton(e,t){let n=t?"Show object":"Hide object";return`<button class="${t?"scene-object-eye is-hidden":"scene-object-eye"}" type="button" data-object-visibility-toggle="true" data-object-id="${this.escapeHtml(e)}" title="${n}">\u{1F441}\uFE0F</button>`}isBundleAllHidden(e){var n;if(!e.length)return!1;let t=(n=window.__editableConfig)==null?void 0:n.objects;return e.every(i=>{var r,o,l;let a=(o=(r=t==null?void 0:t.get)==null?void 0:r.call(t,i))!=null?o:null;return((l=a==null?void 0:a.render)==null?void 0:l.visible)===!1})}toggleSystemBundleVisibility(e){var o;let t=this.systemBundles.get(e);if(!t)return;let n=t.objectIds||[];if(!n.length)return;let i=(o=window.__editableConfig)==null?void 0:o.objects;if(!i||typeof i.get!="function")return;let r=this.isBundleAllHidden(n);n.forEach(l=>{let c=i.get(l);c&&(c.render||(c.render={}),c.render.visible=r)});try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}this.refreshObjects()}async deleteSystemBundle(e){let t=this.systemBundles.get(e);if(!t)return;let n=t.label||e,i=Array.from(new Set(t.objectIds||[]));!i.length||!window.confirm(`Delete system "${n}" (${i.length} object${i.length!==1?"s":""})? This removes them from the screen configuration.`)||await this.deleteMultipleObjects(i)}formatDisplayName(e){let t=e.replace(/^json\./,"").replace(/^ui\./,"").replace(/_\d+$/,"").replace(/\./g," ").replace(/_/g," ");return t=t.split(" ").map(n=>n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()).join(" "),t}inferScreen(e,t){var o,l;let n=window.__HANDLER_SCREEN_INDEX,i=(o=n==null?void 0:n.instanceToScreen)==null?void 0:o[e];if(i==="loading"||i==="start"||i==="gameplay"||i==="tutorial"||i==="endgame")return i;let a=(((l=t==null?void 0:t.identity)==null?void 0:l.id)||"").toString(),r=`${e} ${a}`.toLowerCase();return r.includes("loading")?"loading":r.includes("start")?"start":r.includes("tutorial")?"tutorial":r.includes("endgame")||r.includes("end_card")||r.includes("endcard")?"endgame":"gameplay"}getObjectType(e){var t,n,i,a,r,o,l,c,d;return e?(t=e.ui)!=null&&t.text?"text":(a=(i=(n=e.render)==null?void 0:n.asset)==null?void 0:i.path)!=null&&a.endsWith(".json")?"animation":((o=(r=e.render)==null?void 0:r.asset)==null?void 0:o.type)==="image"||(l=e.render)!=null&&l.texture?"sprite":(d=(c=e.gameplay)==null?void 0:c.tuning)!=null&&d.panel_width?"graphics":"container":"container"}renderGroup(e,t){if(!t.length)return"";let n=window.getEditableObjectConfig,i=t.map(a=>{var g,f,h;let r=typeof n=="function"?n(a.id):null;if(!r){let m=window.__editableObjectConfigs;m&&typeof m.get=="function"&&(r=(g=m.get(a.id))!=null?g:null)}let o=this.getTypeIconByType(a.objectType),l=this.getAssetPreview(r),c=(f=r==null?void 0:r.ui)!=null&&f.text?`"${r.ui.text.substring(0,12)}${r.ui.text.length>12?"...":""}"`:"",d=a.isTemplate?'<span class="scene-object-badge template">template</span>':"",p=((h=r==null?void 0:r.render)==null?void 0:h.visible)===!1;return`
580
+ `}escapeHtml(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}toggleObjectVisibility(e){var a;let t=(a=window.__editableConfig)==null?void 0:a.objects;if(!t||typeof t.get!="function")return;let i=t.get(e);if(!i)return;i.render||(i.render={});let n=i.render.visible!==!1;i.render.visible=!n;try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e,action:"update"}}))}catch{}this.refreshObjects()}renderVisibilityButton(e,t){let i=t?"Show object":"Hide object";return`<button class="${t?"scene-object-eye is-hidden":"scene-object-eye"}" type="button" data-object-visibility-toggle="true" data-object-id="${this.escapeHtml(e)}" title="${i}">\u{1F441}\uFE0F</button>`}isBundleAllHidden(e){var i;if(!e.length)return!1;let t=(i=window.__editableConfig)==null?void 0:i.objects;return e.every(n=>{var r,o,l;let a=(o=(r=t==null?void 0:t.get)==null?void 0:r.call(t,n))!=null?o:null;return((l=a==null?void 0:a.render)==null?void 0:l.visible)===!1})}toggleSystemBundleVisibility(e){var o;let t=this.systemBundles.get(e);if(!t)return;let i=t.objectIds||[];if(!i.length)return;let n=(o=window.__editableConfig)==null?void 0:o.objects;if(!n||typeof n.get!="function")return;let r=this.isBundleAllHidden(i);i.forEach(l=>{let c=n.get(l);c&&(c.render||(c.render={}),c.render.visible=r)});try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}this.refreshObjects()}async deleteSystemBundle(e){let t=this.systemBundles.get(e);if(!t)return;let i=t.label||e,n=Array.from(new Set(t.objectIds||[]));!n.length||!window.confirm(`Delete system "${i}" (${n.length} object${n.length!==1?"s":""})? This removes them from the screen configuration.`)||await this.deleteMultipleObjects(n)}formatDisplayName(e){let t=e.replace(/^json\./,"").replace(/^ui\./,"").replace(/_\d+$/,"").replace(/\./g," ").replace(/_/g," ");return t=t.split(" ").map(i=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join(" "),t}inferScreen(e,t){var o,l;let i=window.__HANDLER_SCREEN_INDEX,n=(o=i==null?void 0:i.instanceToScreen)==null?void 0:o[e];if(n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame")return n;let a=(((l=t==null?void 0:t.identity)==null?void 0:l.id)||"").toString(),r=`${e} ${a}`.toLowerCase();return r.includes("loading")?"loading":r.includes("start")?"start":r.includes("tutorial")?"tutorial":r.includes("endgame")||r.includes("end_card")||r.includes("endcard")?"endgame":"gameplay"}getObjectType(e){var t,i,n,a,r,o,l,c,d;return e?(t=e.ui)!=null&&t.text?"text":(a=(n=(i=e.render)==null?void 0:i.asset)==null?void 0:n.path)!=null&&a.endsWith(".json")?"animation":((o=(r=e.render)==null?void 0:r.asset)==null?void 0:o.type)==="image"||(l=e.render)!=null&&l.texture?"sprite":(d=(c=e.gameplay)==null?void 0:c.tuning)!=null&&d.panel_width?"graphics":"container":"container"}renderGroup(e,t){if(!t.length)return"";let i=window.getEditableObjectConfig,n=t.map(a=>{var g,h,f;let r=typeof i=="function"?i(a.id):null;if(!r){let m=window.__editableObjectConfigs;m&&typeof m.get=="function"&&(r=(g=m.get(a.id))!=null?g:null)}let o=this.getTypeIconByType(a.objectType),l=this.getAssetPreview(r),c=(h=r==null?void 0:r.ui)!=null&&h.text?`"${r.ui.text.substring(0,12)}${r.ui.text.length>12?"...":""}"`:"",d=a.isTemplate?'<span class="scene-object-badge template">template</span>':"",p=((f=r==null?void 0:r.render)==null?void 0:f.visible)===!1;return`
581
581
  <div class="scene-object-item-wrapper">
582
582
  <input type="checkbox" class="scene-object-checkbox" ${this.selectedIds.has(a.id)?"checked":""} data-object-id="${a.id}">
583
583
  ${this.renderVisibilityButton(a.id,p)}
@@ -592,17 +592,17 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
592
592
  <div class="scene-object-group">
593
593
  <div class="scene-object-group-title">${e} <span class="scene-object-count">${t.length}</span></div>
594
594
  <div class="scene-object-group-items">
595
- ${i}
595
+ ${n}
596
596
  </div>
597
597
  </div>
598
- `}renderSystemGroup(e){if(!e.length)return"";let t=window.getEditableObjectConfig,n=e.map(i=>{var p,u,g;let a=typeof t=="function"?t(i.id):null;if(!a){let f=window.__editableObjectConfigs;f&&typeof f.get=="function"&&(a=(p=f.get(i.id))!=null?p:null)}let r=this.getTypeIconByType(i.objectType),o=this.getAssetPreview(a),l=(u=a==null?void 0:a.ui)!=null&&u.text?`"${a.ui.text.substring(0,12)}${a.ui.text.length>12?"...":""}"`:"",c=((g=a==null?void 0:a.render)==null?void 0:g.visible)===!1;return`
598
+ `}renderSystemGroup(e){if(!e.length)return"";let t=window.getEditableObjectConfig,i=e.map(n=>{var p,u,g;let a=typeof t=="function"?t(n.id):null;if(!a){let h=window.__editableObjectConfigs;h&&typeof h.get=="function"&&(a=(p=h.get(n.id))!=null?p:null)}let r=this.getTypeIconByType(n.objectType),o=this.getAssetPreview(a),l=(u=a==null?void 0:a.ui)!=null&&u.text?`"${a.ui.text.substring(0,12)}${a.ui.text.length>12?"...":""}"`:"",c=((g=a==null?void 0:a.render)==null?void 0:g.visible)===!1;return`
599
599
  <div class="scene-object-item-wrapper">
600
- <input type="checkbox" class="scene-object-checkbox" ${this.selectedIds.has(i.id)?"checked":""} data-object-id="${i.id}">
601
- ${this.renderVisibilityButton(i.id,c)}
602
- <button class="scene-object-item ${i.isUnused?"unused":""}" data-object-id="${i.id}">
603
- <span class="scene-object-label">${i.label}</span>
600
+ <input type="checkbox" class="scene-object-checkbox" ${this.selectedIds.has(n.id)?"checked":""} data-object-id="${n.id}">
601
+ ${this.renderVisibilityButton(n.id,c)}
602
+ <button class="scene-object-item ${n.isUnused?"unused":""}" data-object-id="${n.id}">
603
+ <span class="scene-object-label">${n.label}</span>
604
604
  ${l?`<span class="scene-object-text-preview">${l}</span>`:""}
605
- <span class="scene-object-badge system">${i.category}</span>
605
+ <span class="scene-object-badge system">${n.category}</span>
606
606
  </button>
607
607
  </div>
608
608
  `}).join("");return`
@@ -612,23 +612,23 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
612
612
  <button class="scene-object-group-delete" data-delete-system-group type="button" title="Delete all system objects">\u{1F5D1}\uFE0F</button>
613
613
  </div>
614
614
  <div class="scene-object-group-items">
615
- ${n}
615
+ ${i}
616
616
  </div>
617
617
  </div>
618
- `}getTypeIconByType(e){return{text:"\u{1F4DD}",sprite:"\u{1F5BC}\uFE0F",graphics:"\u2B1C",container:"\u{1F4E6}",animation:"\u{1F3AC}"}[e]||"\u{1F4E6}"}getTypeIcon(e){var n,i,a,r,o,l;if(!e)return"\u{1F4E6}";if((n=e.render)!=null&&n.texture){let c=e.render.texture;return c.includes("button")?"\u{1F518}":c.includes("key")?"\u{1F511}":"\u{1F5BC}\uFE0F"}if((i=e.ui)!=null&&i.text)return"\u{1F4DD}";if(((a=e.identity)==null?void 0:a.category)==="ui")return"\u{1F3A8}";if(e.effects||(o=(r=e.identity)==null?void 0:r.id)!=null&&o.includes("effect"))return"\u2728";if(e.audio)return"\u{1F50A}";let t=((l=e.identity)==null?void 0:l.id)||"";return t.includes("background")?"\u{1F5BC}\uFE0F":t.includes("character")?"\u{1F464}":t.includes("key")?"\u{1F511}":t.includes("draggable")?"\u{1F3AF}":t.includes("machine")?"\u2699\uFE0F":t.includes("tutorial")||t.includes("hand")?"\u{1F446}":"\u{1F4E6}"}getAssetPreview(e){var n;if(!e)return null;let t=(n=e.render)==null?void 0:n.texture;return t&&(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg"))?t.startsWith("library/")||t.startsWith("/raw/")?`/raw/${t.replace(/^\/raw\//,"")}`:`/raw/${t}`:null}getColorIndicator(e){var n,i,a,r;if(!e)return"";let t=((n=e.render)==null?void 0:n.background_color)||((a=(i=e.gameplay)==null?void 0:i.tuning)==null?void 0:a.panel_bg_color)||((r=e.ui)==null?void 0:r.backgroundColor);return t?`<span class="scene-object-color-dot" style="background-color: ${t}" title="${t}"></span>`:""}getMetadata(e){var n,i,a,r;if(!e)return"";let t=[];return((n=e.render)==null?void 0:n.visible)===!1&&t.push("hidden"),((i=e.render)==null?void 0:i.z_index)!==void 0&&t.push(`z:${e.render.z_index}`),((a=e.interaction)!=null&&a.clickable||(r=e.ui)!=null&&r.button)&&t.push("clickable"),t.length>0?t.join(" \u2022 "):""}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refreshObjects()},400))}select(e){var t,n,i;this.selectedId=e,this.selectedIds.has(e)||this.selectedIds.add(e),this.updateLastSelectedIndex(e),this.updateSelectionUI(),(t=this.options)==null||t.onSelect(e),(i=(n=this.options)==null?void 0:n.onMultiSelect)==null||i.call(n,Array.from(this.selectedIds))}toggleBatchSelect(e){var t,n;this.selectedIds.has(e)?this.selectedIds.delete(e):this.selectedIds.add(e),this.updateSelectionUI(),(n=(t=this.options)==null?void 0:t.onMultiSelect)==null||n.call(t,Array.from(this.selectedIds))}toggleSelect(e){this.toggleBatchSelect(e)}selectRange(e,t){var r,o,l;let n=this.objectEntries.findIndex(c=>c.id===t);if(n===-1)return;let i=Math.min(e,n),a=Math.max(e,n);for(let c=i;c<=a;c++)c>=0&&c<this.objectEntries.length&&this.selectedIds.add(this.objectEntries[c].id);this.selectedId=t,this.updateLastSelectedIndex(t),this.updateSelectionUI(),(r=this.options)==null||r.onSelect(this.selectedId),(l=(o=this.options)==null?void 0:o.onMultiSelect)==null||l.call(o,Array.from(this.selectedIds))}updateLastSelectedIndex(e){this.lastSelectedIndex=this.objectEntries.findIndex(t=>t.id===e)}getDefaultScreenForCreate(){if(this.screenFilter!=="all")return this.screenFilter;let e=window.__HANDLER_ACTIVE_SCREEN;return e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"}async openAddObjectMenu(e){try{await new An({onRefresh:()=>this.refreshObjects(),onClose:()=>{}}).open(e)}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectMenu:",t)}}async openAddObjectWizard(e){try{new Sn().open({screenId:e})}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectWizard:",t)}}async showContextMenu(e,t,n,i){if(!this.isContextMenuOpen){this.isContextMenuOpen=!0,this.selectedIds.has(e)||this.select(e);try{new Cn({objectId:e,screenId:t,onSelect:r=>{r&&this.select(r)},onRefresh:()=>this.refreshObjects(),onClose:()=>{this.isContextMenuOpen=!1},onDeleteRequest:r=>this.deleteObject(r),onMoveRequest:(r,o)=>this.moveObject(r,o)}).open({x:n,y:i})}catch(a){this.isContextMenuOpen=!1,console.warn("[SceneObjectsPanel] Failed to open context menu:",a)}}}async deleteObject(e){var i;let t=this.getSelectedIds();if(t.length>1&&t.includes(e)){if(!window.confirm(`Delete ${t.length} selected object${t.length!==1?"s":""}? This removes them from the screen configuration.`))return;await this.deleteMultipleObjects(t)}else{if(!window.confirm(`Delete "${e}"? This removes it from the screen configuration.`))return;try{let r=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e})}),o=await r.json().catch(()=>null);if(!r.ok||(o==null?void 0:o.success)===!1){let l=((i=o==null?void 0:o.errors)==null?void 0:i.join(`
618
+ `}getTypeIconByType(e){return{text:"\u{1F4DD}",sprite:"\u{1F5BC}\uFE0F",graphics:"\u2B1C",container:"\u{1F4E6}",animation:"\u{1F3AC}"}[e]||"\u{1F4E6}"}getTypeIcon(e){var i,n,a,r,o,l;if(!e)return"\u{1F4E6}";if((i=e.render)!=null&&i.texture){let c=e.render.texture;return c.includes("button")?"\u{1F518}":c.includes("key")?"\u{1F511}":"\u{1F5BC}\uFE0F"}if((n=e.ui)!=null&&n.text)return"\u{1F4DD}";if(((a=e.identity)==null?void 0:a.category)==="ui")return"\u{1F3A8}";if(e.effects||(o=(r=e.identity)==null?void 0:r.id)!=null&&o.includes("effect"))return"\u2728";if(e.audio)return"\u{1F50A}";let t=((l=e.identity)==null?void 0:l.id)||"";return t.includes("background")?"\u{1F5BC}\uFE0F":t.includes("character")?"\u{1F464}":t.includes("key")?"\u{1F511}":t.includes("draggable")?"\u{1F3AF}":t.includes("machine")?"\u2699\uFE0F":t.includes("tutorial")||t.includes("hand")?"\u{1F446}":"\u{1F4E6}"}getAssetPreview(e){var i;if(!e)return null;let t=(i=e.render)==null?void 0:i.texture;return t&&(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg"))?t.startsWith("library/")||t.startsWith("/raw/")?`/raw/${t.replace(/^\/raw\//,"")}`:`/raw/${t}`:null}getColorIndicator(e){var i,n,a,r;if(!e)return"";let t=((i=e.render)==null?void 0:i.background_color)||((a=(n=e.gameplay)==null?void 0:n.tuning)==null?void 0:a.panel_bg_color)||((r=e.ui)==null?void 0:r.backgroundColor);return t?`<span class="scene-object-color-dot" style="background-color: ${t}" title="${t}"></span>`:""}getMetadata(e){var i,n,a,r;if(!e)return"";let t=[];return((i=e.render)==null?void 0:i.visible)===!1&&t.push("hidden"),((n=e.render)==null?void 0:n.z_index)!==void 0&&t.push(`z:${e.render.z_index}`),((a=e.interaction)!=null&&a.clickable||(r=e.ui)!=null&&r.button)&&t.push("clickable"),t.length>0?t.join(" \u2022 "):""}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refreshObjects()},400))}select(e){var t,i,n;this.selectedId=e,this.selectedIds.has(e)||this.selectedIds.add(e),this.updateLastSelectedIndex(e),this.updateSelectionUI(),(t=this.options)==null||t.onSelect(e),(n=(i=this.options)==null?void 0:i.onMultiSelect)==null||n.call(i,Array.from(this.selectedIds))}toggleBatchSelect(e){var t,i;this.selectedIds.has(e)?this.selectedIds.delete(e):this.selectedIds.add(e),this.updateSelectionUI(),(i=(t=this.options)==null?void 0:t.onMultiSelect)==null||i.call(t,Array.from(this.selectedIds))}toggleSelect(e){this.toggleBatchSelect(e)}selectRange(e,t){var r,o,l;let i=this.objectEntries.findIndex(c=>c.id===t);if(i===-1)return;let n=Math.min(e,i),a=Math.max(e,i);for(let c=n;c<=a;c++)c>=0&&c<this.objectEntries.length&&this.selectedIds.add(this.objectEntries[c].id);this.selectedId=t,this.updateLastSelectedIndex(t),this.updateSelectionUI(),(r=this.options)==null||r.onSelect(this.selectedId),(l=(o=this.options)==null?void 0:o.onMultiSelect)==null||l.call(o,Array.from(this.selectedIds))}updateLastSelectedIndex(e){this.lastSelectedIndex=this.objectEntries.findIndex(t=>t.id===e)}getDefaultScreenForCreate(){if(this.screenFilter!=="all")return this.screenFilter;let e=window.__HANDLER_ACTIVE_SCREEN;return e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"}async openAddObjectMenu(e){try{await new Li({onRefresh:()=>this.refreshObjects(),onClose:()=>{}}).open(e)}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectMenu:",t)}}async openAddObjectWizard(e){try{new Ai().open({screenId:e})}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectWizard:",t)}}async showContextMenu(e,t,i,n){if(!this.isContextMenuOpen){this.isContextMenuOpen=!0,this.selectedIds.has(e)||this.select(e);try{new Ti({objectId:e,screenId:t,onSelect:r=>{r&&this.select(r)},onRefresh:()=>this.refreshObjects(),onClose:()=>{this.isContextMenuOpen=!1},onDeleteRequest:r=>this.deleteObject(r),onMoveRequest:(r,o)=>this.moveObject(r,o)}).open({x:i,y:n})}catch(a){this.isContextMenuOpen=!1,console.warn("[SceneObjectsPanel] Failed to open context menu:",a)}}}async deleteObject(e){var n;let t=this.getSelectedIds();if(t.length>1&&t.includes(e)){if(!window.confirm(`Delete ${t.length} selected object${t.length!==1?"s":""}? This removes them from the screen configuration.`))return;await this.deleteMultipleObjects(t)}else{if(!window.confirm(`Delete "${e}"? This removes it from the screen configuration.`))return;try{let r=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e})}),o=await r.json().catch(()=>null);if(!r.ok||(o==null?void 0:o.success)===!1){let l=((n=o==null?void 0:o.errors)==null?void 0:n.join(`
619
619
  `))||(o==null?void 0:o.error)||"Delete failed.";alert(l);return}o!=null&&o.failedDeletions&&o.failedDeletions.length>0&&alert(`Warning: Some files could not be deleted:
620
620
  ${o.failedDeletions.join(`
621
- `)}`),o!=null&&o.deletedFiles&&o.deletedFiles.length>0&&console.log(`[SceneObjectsPanel] Successfully deleted files: ${o.deletedFiles.join(", ")}`),await this.syncScreens(),this.selectedIds.delete(e),this.selectedId===e&&(this.selectedId=null),this.refreshObjects()}catch(r){alert(`Delete failed: ${r instanceof Error?r.message:String(r)}`)}}}async deleteMultipleObjects(e){var a;let t=0,n=0,i=[];for(let r of e)try{let o=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:r})}),l=await o.json().catch(()=>null);if(o.ok&&(l==null?void 0:l.success)!==!1)t++,this.selectedIds.delete(r);else{n++;let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
622
- `))||(l==null?void 0:l.error)||"Delete failed.";i.push(`${r}: ${c}`)}}catch(o){n++,i.push(`${r}: ${o instanceof Error?o.message:String(o)}`)}if(n>0){let r=i.length>0?i.join(`
623
- `):`${n} object(s) failed to delete.`;alert(`Deleted ${t} object(s). Errors:
624
- ${r}`)}t===e.length&&console.log(`[SceneObjectsPanel] Successfully deleted ${t} object(s)`),this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null,await this.syncScreens(),this.refreshObjects()}async deleteSystemGroup(e){var l;let t=e.length;if(!window.confirm(`Delete all ${t} system object${t!==1?"s":""}? This will remove them from all screens.`))return;let i=e.map(c=>c.id),a=0,r=0,o=[];for(let c of i)try{let d=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:c})}),p=await d.json().catch(()=>null);if(d.ok&&(p==null?void 0:p.success)!==!1)a++;else{r++;let u=((l=p==null?void 0:p.errors)==null?void 0:l.join(`
621
+ `)}`),o!=null&&o.deletedFiles&&o.deletedFiles.length>0&&console.log(`[SceneObjectsPanel] Successfully deleted files: ${o.deletedFiles.join(", ")}`),await this.syncScreens(),this.selectedIds.delete(e),this.selectedId===e&&(this.selectedId=null),this.refreshObjects()}catch(r){alert(`Delete failed: ${r instanceof Error?r.message:String(r)}`)}}}async deleteMultipleObjects(e){var a;let t=0,i=0,n=[];for(let r of e)try{let o=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:r,skipSync:!0})}),l=await o.json().catch(()=>null);if(o.ok&&(l==null?void 0:l.success)!==!1)t++,this.selectedIds.delete(r);else{i++;let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
622
+ `))||(l==null?void 0:l.error)||"Delete failed.";n.push(`${r}: ${c}`)}}catch(o){i++,n.push(`${r}: ${o instanceof Error?o.message:String(o)}`)}if(i>0){let r=n.length>0?n.join(`
623
+ `):`${i} object(s) failed to delete.`;alert(`Deleted ${t} object(s). Errors:
624
+ ${r}`)}t===e.length&&console.log(`[SceneObjectsPanel] Successfully deleted ${t} object(s)`),this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null,await this.syncScreens(),this.refreshObjects()}async deleteSystemGroup(e){var l;let t=e.length;if(!window.confirm(`Delete all ${t} system object${t!==1?"s":""}? This will remove them from all screens.`))return;let n=e.map(c=>c.id),a=0,r=0,o=[];for(let c of n)try{let d=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:c})}),p=await d.json().catch(()=>null);if(d.ok&&(p==null?void 0:p.success)!==!1)a++;else{r++;let u=((l=p==null?void 0:p.errors)==null?void 0:l.join(`
625
625
  `))||(p==null?void 0:p.error)||"Delete failed.";o.push(`${c}: ${u}`)}}catch(d){r++,o.push(`${c}: ${d instanceof Error?d.message:String(d)}`)}if(r>0){let c=o.length>0?o.join(`
626
626
  `):`${r} object(s) failed to delete.`;alert(`Deleted ${a} object(s). Errors:
627
- ${c}`)}await this.syncScreens(),this.refreshObjects()}async moveObject(e,t){var a;let n=this.getSelectedIds();if(n.length>1&&n.includes(e))await this.moveMultipleObjects(n,t);else{let r=this.inferScreen(e,null);if(t===r)return;try{let o=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,fromScreenId:r,toScreenId:t})}),l=await o.json().catch(()=>({}));if(!o.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
628
- `))||(l==null?void 0:l.error)||"Move failed.";alert(c);return}this.refreshObjects()}catch(o){alert(`Move failed: ${o instanceof Error?o.message:String(o)}`)}}}async moveMultipleObjects(e,t){var r;let n=0,i=0,a=[];for(let o of e){let l=this.inferScreen(o,null);if(t===l){n++;continue}try{let c=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:o,fromScreenId:l,toScreenId:t})}),d=await c.json().catch(()=>({}));if(c.ok&&(d==null?void 0:d.success)!==!1)n++;else{i++;let p=((r=d==null?void 0:d.errors)==null?void 0:r.join(`
629
- `))||(d==null?void 0:d.error)||"Move failed.";a.push(`${o}: ${p}`)}}catch(c){i++,a.push(`${o}: ${c instanceof Error?c.message:String(c)}`)}}if(i>0){let o=a.length>0?a.join(`
630
- `):`${i} object(s) failed to move.`;alert(`Moved ${n} object(s). Errors:
631
- ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-screens",{method:"POST"})}catch(e){console.warn("[SceneObjectsPanel] Failed to sync screens:",e)}}};var Ln=class{constructor(){this.root=null;this.options=null;this.isCollapsed=!1}render(){return`
627
+ ${c}`)}await this.syncScreens(),this.refreshObjects()}async moveObject(e,t){var a;let i=this.getSelectedIds();if(i.length>1&&i.includes(e))await this.moveMultipleObjects(i,t);else{let r=this.inferScreen(e,null);if(t===r)return;try{let o=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,fromScreenId:r,toScreenId:t})}),l=await o.json().catch(()=>({}));if(!o.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
628
+ `))||(l==null?void 0:l.error)||"Move failed.";alert(c);return}this.refreshObjects()}catch(o){alert(`Move failed: ${o instanceof Error?o.message:String(o)}`)}}}async moveMultipleObjects(e,t){var r;let i=0,n=0,a=[];for(let o of e){let l=this.inferScreen(o,null);if(t===l){i++;continue}try{let c=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:o,fromScreenId:l,toScreenId:t})}),d=await c.json().catch(()=>({}));if(c.ok&&(d==null?void 0:d.success)!==!1)i++;else{n++;let p=((r=d==null?void 0:d.errors)==null?void 0:r.join(`
629
+ `))||(d==null?void 0:d.error)||"Move failed.";a.push(`${o}: ${p}`)}}catch(c){n++,a.push(`${o}: ${c instanceof Error?c.message:String(c)}`)}}if(n>0){let o=a.length>0?a.join(`
630
+ `):`${n} object(s) failed to move.`;alert(`Moved ${i} object(s). Errors:
631
+ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-screens",{method:"POST"})}catch(e){console.warn("[SceneObjectsPanel] Failed to sync screens:",e)}}};var Ii=class{constructor(){this.root=null;this.options=null;this.isCollapsed=!1}render(){return`
632
632
  <div class="scene-tools-corner-panel ${this.isCollapsed?"collapsed":""}" data-panel="scene-tools-corner">
633
633
  <div class="scene-tools-header" data-tools-header data-panel-handle>
634
634
  <span class="scene-tools-title">Scene Tools</span>
@@ -673,7 +673,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
673
673
  </div>
674
674
  </div>
675
675
  </div>
676
- `}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="scene-tools-corner"]'),!this.root)return;let n=localStorage.getItem("scene-tools-collapsed");n!==null&&(this.isCollapsed=n==="true",this.root.classList.toggle("collapsed",this.isCollapsed));let i=this.root.querySelector("[data-tools-collapse]");i==null||i.addEventListener("click",()=>{var c;this.isCollapsed=!this.isCollapsed,(c=this.root)==null||c.classList.toggle("collapsed",this.isCollapsed),localStorage.setItem("scene-tools-collapsed",String(this.isCollapsed))});let a=(c,d)=>{var u;let p=(u=this.root)==null?void 0:u.querySelector(`[data-status="${c}"]`);p&&p.classList.toggle("active",d)},r=this.root.querySelector("#debug-highlight-object");r==null||r.addEventListener("change",()=>{var c;(c=this.options)==null||c.onHighlightObject(!!r.checked),a("bounds",r.checked)});let o=this.root.querySelector("#debug-highlight-anchor");o==null||o.addEventListener("change",()=>{var c;(c=this.options)==null||c.onHighlightAnchor(!!o.checked),a("anchor",o.checked)});let l=this.root.querySelector("#debug-nudge-enabled");l==null||l.addEventListener("change",()=>{a("nudge",l.checked)})}updateInfo(e){}};var kn=class{constructor(){this.root=null;this.options=null}render(){return`
676
+ `}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="scene-tools-corner"]'),!this.root)return;let i=localStorage.getItem("scene-tools-collapsed");i!==null&&(this.isCollapsed=i==="true",this.root.classList.toggle("collapsed",this.isCollapsed));let n=this.root.querySelector("[data-tools-collapse]");n==null||n.addEventListener("click",()=>{var c;this.isCollapsed=!this.isCollapsed,(c=this.root)==null||c.classList.toggle("collapsed",this.isCollapsed),localStorage.setItem("scene-tools-collapsed",String(this.isCollapsed))});let a=(c,d)=>{var u;let p=(u=this.root)==null?void 0:u.querySelector(`[data-status="${c}"]`);p&&p.classList.toggle("active",d)},r=this.root.querySelector("#debug-highlight-object");r==null||r.addEventListener("change",()=>{var c;(c=this.options)==null||c.onHighlightObject(!!r.checked),a("bounds",r.checked)});let o=this.root.querySelector("#debug-highlight-anchor");o==null||o.addEventListener("change",()=>{var c;(c=this.options)==null||c.onHighlightAnchor(!!o.checked),a("anchor",o.checked)});let l=this.root.querySelector("#debug-nudge-enabled");l==null||l.addEventListener("change",()=>{a("nudge",l.checked)})}updateInfo(e){}};var Pi=class{constructor(){this.root=null;this.options=null}render(){return`
677
677
  <div class="nudge-panel hidden" data-panel="nudge-panel">
678
678
  <div class="nudge-panel-header" data-panel-handle>
679
679
  <span class="nudge-panel-title">Nudge Controls</span>
@@ -730,7 +730,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
730
730
  </div>
731
731
  </div>
732
732
  </div>
733
- `}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="nudge-panel"]'),!this.root)return;Array.from(this.root.querySelectorAll(".nudge-arrow-btn")).forEach(a=>{a.addEventListener("click",()=>{var l,c,d,p;let r=a.dataset.nudge,o=this.getNudgeStep();switch(r){case"up":(l=this.options)==null||l.onNudge(0,-o);break;case"down":(c=this.options)==null||c.onNudge(0,o);break;case"left":(d=this.options)==null||d.onNudge(-o,0);break;case"right":(p=this.options)==null||p.onNudge(o,0);break}})}),Array.from(this.root.querySelectorAll(".nudge-scale-btn")).forEach(a=>{a.addEventListener("click",()=>{var l;let o=a.dataset.scale==="up"?.1:-.1;(l=this.options)==null||l.onScale(o)})})}show(){var e;(e=this.root)==null||e.classList.remove("hidden")}hide(){var e;(e=this.root)==null||e.classList.add("hidden")}getNudgeStep(){var n,i;let e=(n=this.root)==null?void 0:n.querySelector("#nudge-step-input"),t=Number((i=e==null?void 0:e.value)!=null?i:10);return Number.isFinite(t)&&t>0?t:10}};var Pt=class{constructor(){this.root=null;this.slotsContainer=null;this.options=null;this.registry=null;this.expandedSlot=null}mergeRegistries(e,t){let n=e||{},i=t||{},a={slots:Array.isArray(i.slots)?[...i.slots]:[],libraryAssets:typeof i.libraryAssets=="object"&&i.libraryAssets?{...i.libraryAssets}:{},categories:Array.isArray(i.categories)?[...i.categories]:[]},r=Array.isArray(n.slots)?n.slots:[];if(r.length>0&&a.slots.length>0)for(let c of a.slots){let d=r.find(p=>(p==null?void 0:p.slotId)&&p.slotId===(c==null?void 0:c.slotId));d!=null&&d.currentAsset&&d.currentAsset!==(c==null?void 0:c.currentAsset)&&(c.currentAsset=d.currentAsset)}let o=n.libraryAssets||{};for(let[c,d]of Object.entries(o)){if(!Array.isArray(d))continue;a.libraryAssets[c]||(a.libraryAssets[c]=[]);let p=new Set((a.libraryAssets[c]||[]).map(u=>u==null?void 0:u.filename));for(let u of d){let g=u==null?void 0:u.filename;!g||p.has(g)||(a.libraryAssets[c].unshift(u),p.add(g))}}let l=new Set(a.categories||[]);for(let c of n.categories||[])typeof c=="string"&&l.add(c);return a.categories=Array.from(l),a}render(){return`
733
+ `}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="nudge-panel"]'),!this.root)return;Array.from(this.root.querySelectorAll(".nudge-arrow-btn")).forEach(a=>{a.addEventListener("click",()=>{var l,c,d,p;let r=a.dataset.nudge,o=this.getNudgeStep();switch(r){case"up":(l=this.options)==null||l.onNudge(0,-o);break;case"down":(c=this.options)==null||c.onNudge(0,o);break;case"left":(d=this.options)==null||d.onNudge(-o,0);break;case"right":(p=this.options)==null||p.onNudge(o,0);break}})}),Array.from(this.root.querySelectorAll(".nudge-scale-btn")).forEach(a=>{a.addEventListener("click",()=>{var l;let o=a.dataset.scale==="up"?.1:-.1;(l=this.options)==null||l.onScale(o)})})}show(){var e;(e=this.root)==null||e.classList.remove("hidden")}hide(){var e;(e=this.root)==null||e.classList.add("hidden")}getNudgeStep(){var i,n;let e=(i=this.root)==null?void 0:i.querySelector("#nudge-step-input"),t=Number((n=e==null?void 0:e.value)!=null?n:10);return Number.isFinite(t)&&t>0?t:10}};var $t=class{constructor(){this.root=null;this.slotsContainer=null;this.options=null;this.registry=null;this.expandedSlot=null}mergeRegistries(e,t){let i=e||{},n=t||{},a={slots:Array.isArray(n.slots)?[...n.slots]:[],libraryAssets:typeof n.libraryAssets=="object"&&n.libraryAssets?{...n.libraryAssets}:{},categories:Array.isArray(n.categories)?[...n.categories]:[]},r=Array.isArray(i.slots)?i.slots:[];if(r.length>0&&a.slots.length>0)for(let c of a.slots){let d=r.find(p=>(p==null?void 0:p.slotId)&&p.slotId===(c==null?void 0:c.slotId));d!=null&&d.currentAsset&&d.currentAsset!==(c==null?void 0:c.currentAsset)&&(c.currentAsset=d.currentAsset)}let o=i.libraryAssets||{};for(let[c,d]of Object.entries(o)){if(!Array.isArray(d))continue;a.libraryAssets[c]||(a.libraryAssets[c]=[]);let p=new Set((a.libraryAssets[c]||[]).map(u=>u==null?void 0:u.filename));for(let u of d){let g=u==null?void 0:u.filename;!g||p.has(g)||(a.libraryAssets[c].unshift(u),p.add(g))}}let l=new Set(a.categories||[]);for(let c of i.categories||[])typeof c=="string"&&l.add(c);return a.categories=Array.from(l),a}render(){return`
734
734
  <div class="scene-panel library-panel panel-accent-purple" data-panel="library">
735
735
  <div class="scene-panel-header" data-panel-handle>
736
736
  <div class="panel-title">
@@ -749,15 +749,15 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
749
749
  </div>
750
750
  <div class="panel-resize-handle" data-panel-resize></div>
751
751
  </div>
752
- `}initialize(e,t){var a,r,o;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(a=this.root)==null?void 0:a.querySelector("[data-library-slots]");let n=(r=this.root)==null?void 0:r.querySelector("[data-create-ai]");n==null||n.addEventListener("click",()=>{this.handleCreateWithAI()});let i=(o=this.root)==null?void 0:o.querySelector("[data-refresh-library]");i==null||i.addEventListener("click",()=>{i.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>i.classList.remove("pulse-anim"),500)}),this.loadAssetRegistry()}reRender(){console.log("[LIBRARY] Re-rendering slots..."),this.loadAssetRegistry()}async refresh(){console.log("[LIBRARY] Force refreshing asset registry...");try{let e=window.getEditableAssets,t=typeof e=="function"?e():null,n=await fetch(`/raw/assetRegistry.json?t=${Date.now()}`);if(n.ok){let i=await n.json(),a=this.mergeRegistries(t,i);window.getEditableAssets=()=>a,console.log("[LIBRARY] \u2705 Registry re-fetched successfully")}}catch(e){console.warn("[LIBRARY] Failed to re-fetch registry:",e)}this.loadAssetRegistry()}loadAssetRegistry(e=0){let t=window.getEditableAssets;if(typeof t=="function"){let n=t();if(n!=null&&n.slots&&Array.isArray(n.slots)&&n.slots.length>0){this.registry=n,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.renderSlots();return}}e<15?(console.log(`[LIBRARY] Waiting for asset registry... (attempt ${e+1}/15)`),setTimeout(()=>this.loadAssetRegistry(e+1),200)):(console.warn("[LIBRARY] Failed to load asset registry"),this.slotsContainer&&(this.slotsContainer.innerHTML='<div class="library-info">No editable assets available</div>'))}renderSlots(){if(!this.slotsContainer||!this.registry)return;let e={};for(let n of this.registry.slots)e[n.category]||(e[n.category]=[]),e[n.category].push(n);let t=Date.now();this.slotsContainer.innerHTML="";for(let n of this.registry.categories){let i=e[n]||[];if(i.length===0)continue;let a=document.createElement("div");a.className="library-category";let r=document.createElement("div");r.className="library-category-header",r.textContent=this.formatCategoryName(n),a.appendChild(r);let o=document.createElement("div");o.className="library-category-slots";for(let l of i){let c=this.createSlotElement(l,t);o.appendChild(c)}a.appendChild(o),this.slotsContainer.appendChild(a)}}createSlotElement(e,t){let n=this.expandedSlot===e.slotId,i=document.createElement("div");i.className=`library-slot ${n?"expanded":""}`,i.dataset.slotId=e.slotId;let a=document.createElement("div");a.className="slot-header";let r=document.createElement("div");r.className="slot-current";let o=document.createElement("img");o.src=`/raw/${e.currentAsset}?t=${t}`,o.alt=e.displayName,o.className="slot-thumbnail",o.onerror=()=>{o.style.display="none"},r.appendChild(o),a.appendChild(r);let l=document.createElement("div");l.className="slot-info";let c=document.createElement("div");c.className="slot-name",c.textContent=e.displayName;let d=document.createElement("div");d.className="slot-asset",d.textContent=e.currentAsset,l.appendChild(c),l.appendChild(d),a.appendChild(l);let p=document.createElement("div");p.className="slot-actions";let u=document.createElement("button");u.className="slot-ai-edit",u.title="Edit with AI",u.textContent="\u2728 AI",u.addEventListener("click",async m=>{m.stopPropagation(),await this.handleAIEdit(e)}),p.appendChild(u);let g=document.createElement("button");g.className="slot-upload",g.title="Upload new asset",g.textContent="\u{1F4E4}",g.addEventListener("click",async m=>{m.stopPropagation(),await this.handleUpload(e)}),p.appendChild(g);let f=document.createElement("button");f.className="slot-reset",f.title="Reset to default",f.textContent="\u21BA",f.addEventListener("click",async m=>{m.stopPropagation(),await this.handleReset(e)}),p.appendChild(f);let h=document.createElement("span");if(h.className="slot-expand-icon",h.textContent=n?"\u25BC":"\u25B6",p.appendChild(h),a.appendChild(p),a.addEventListener("click",()=>{this.expandedSlot=this.expandedSlot===e.slotId?null:e.slotId,this.renderSlots()}),i.appendChild(a),n){let m=this.createLibraryElement(e,t);i.appendChild(m)}return i}createLibraryElement(e,t){var a;let n=document.createElement("div");n.className="slot-library";let i=((a=this.registry)==null?void 0:a.libraryAssets[e.libraryFolder])||[];return this.fetchFolderAssets(e.libraryFolder,t).then(r=>{let o=new Map;for(let c of i)o.set(c.filename,c);for(let c of r)o.has(c.filename)||o.set(c.filename,c);let l=Array.from(o.values());if(l.length===0){n.innerHTML='<div class="library-empty">No alternative assets</div>';return}n.innerHTML="";for(let c of l){let d=document.createElement("div");d.className="library-item";let p=document.createElement("img");p.src=`/raw/library/${e.libraryFolder}/${c.filename}?t=${t}`,p.alt=c.displayName,p.className="library-thumbnail",p.onerror=()=>{p.style.opacity="0.3"},d.appendChild(p);let u=document.createElement("div");u.className="library-label",u.textContent=c.displayName,d.appendChild(u),d.addEventListener("click",async()=>{await this.handleApply(e,c.filename)}),n.appendChild(d)}}),n.innerHTML='<div class="library-loading">Loading assets...</div>',n}async fetchFolderAssets(e,t){try{let n=await fetch(`/raw/library/${e}/?t=${t}`);if(!n.ok)return[];let i=await n.text(),a=[],r=/href="([^"]+\.(png|jpg|jpeg))"/gi,o;for(;(o=r.exec(i))!==null;){let l=o[1];if(!l.startsWith("/")&&!l.startsWith("..")){let c=l.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");a.push({filename:l,displayName:c})}}return a}catch{return console.log("[LIBRARY] Could not fetch folder listing, using registry only"),[]}}async handleApply(e,t){var n;console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{let i=window.__wizardAssetPicker;if(i!=null&&i.onPick){let a=`raw/library/${e.libraryFolder}/${t}`;i.onPick(a),window.__wizardAssetPicker=null;return}await((n=this.options)==null?void 0:n.onApply(e.objectId,t,e.category)),e.currentAsset=t,this.renderSlots()}catch(i){console.error("[LIBRARY] Failed to apply asset:",i)}}async handleReset(e){var t;console.log("[LIBRARY] Resetting slot:",e.slotId,"to default:",e.defaultAsset);try{await((t=this.options)==null?void 0:t.onReset(e.objectId,e.defaultAsset,e.category)),e.currentAsset=e.defaultAsset,this.renderSlots()}catch(n){console.error("[LIBRARY] Failed to reset slot:",n)}}formatCategoryName(e){return e.replace(/_/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}async handleAIEdit(e){console.log("[Library] Opening AI Edit for slot:",e);let t=window.__openAiEditor;if(typeof t=="function"){let n=e.slotId||e.objectId,i="render.texture";e.category==="ui"&&(i="ui.image"),e.category==="audio"&&(i="audio.src"),t(n,`Edit ${e.displayName} with AI`,e.currentAsset,{objectId:e.objectId,path:i})}else console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded.")}async handleUpload(e){console.log("[Library] Opening file upload for slot:",e);let t=document.createElement("input");t.type="file",t.accept="image/*",t.style.display="none",t.addEventListener("change",async()=>{var i;let n=(i=t.files)==null?void 0:i[0];if(n){console.log("[Library] File selected:",n.name);try{let a=await this.fileToDataUrl(n);if(!a){alert("Failed to read file");return}let o=`${e.displayName.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,l=e.category;console.log("[Library] Saving uploaded file:",o,"to category:",l);let d=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:l,filename:`${o}.png`,data:a,overwrite:!0})})).json();if(d.success){console.log("[Library] \u2705 Upload saved:",d.path);let p=window.addAssetToRegistry;typeof p=="function"&&p(l,`${o}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(u){console.warn("[Library] Setup-library not available:",u)}await this.handleApply(e,`${o}.png`),e.currentAsset=`${o}.png`,await this.refresh(),setTimeout(()=>{this.highlightSlot(e.objectId,l)},500),console.log("[Library] \u2705 Upload complete and applied")}else console.error("[Library] \u274C Upload failed:",d.error),alert(`Upload failed: ${d.error}`)}catch(a){console.error("[Library] \u274C Upload error:",a),alert("Upload failed. Check console for details.")}finally{t.remove()}}}),document.body.appendChild(t),t.click()}fileToDataUrl(e){return new Promise(t=>{let n=new FileReader;n.onload=()=>t(n.result),n.onerror=()=>t(null),n.readAsDataURL(e)})}handleCreateWithAI(){console.log("[Library] Opening AI Create modal");let e=window.__openAiEditor;typeof e=="function"?e("new_asset","Create new asset with AI"):(console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded."))}highlightSlot(e,t){if(!this.registry||!this.slotsContainer)return;let n=e.startsWith("json.")?e.replace("json.",""):e,i=this.registry.slots.find(a=>(a.objectId===n||a.slotId===n)&&(!t||a.category===t));i?(console.log("[LIBRARY] Highlighting slot:",i.slotId),this.expandedSlot=i.slotId,this.renderSlots(),setTimeout(()=>{var r;let a=(r=this.slotsContainer)==null?void 0:r.querySelector(`[data-slot-id="${i.slotId}"]`);a&&(a.scrollIntoView({behavior:"smooth",block:"center"}),a.classList.add("highlight-pulse"),setTimeout(()=>a.classList.remove("highlight-pulse"),3e3))},100)):console.warn("[LIBRARY] No slot found for highlight:",e,t)}};var In=class{detectType(e,t,n){let i=e.toLowerCase();return i==="logic_id"||i==="logicid"?"select":typeof t=="string"&&t.match(/\.(png|jpg|jpeg|gif|webp)$/i)?"image":i.includes("color")||i.includes("tint")?"color":typeof t=="boolean"?"boolean":typeof t=="number"?"number":Array.isArray(t)?"array":typeof t=="object"&&t!==null?"object":"text"}isHexColor(e){return/^#[0-9a-fA-F]{6}$/i.test(e)}isImagePath(e){return/\.(png|jpg|jpeg|gif|svg)$/i.test(e)}};var jn=class{render(e,t,n,i){let a=this.formatLabel(t),r=n?this.getThumbnailUrl(n):"";return`
752
+ `}initialize(e,t){var a,r,o;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(a=this.root)==null?void 0:a.querySelector("[data-library-slots]");let i=(r=this.root)==null?void 0:r.querySelector("[data-create-ai]");i==null||i.addEventListener("click",()=>{this.handleCreateWithAI()});let n=(o=this.root)==null?void 0:o.querySelector("[data-refresh-library]");n==null||n.addEventListener("click",()=>{n.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>n.classList.remove("pulse-anim"),500)}),this.loadAssetRegistry()}reRender(){console.log("[LIBRARY] Re-rendering slots..."),this.loadAssetRegistry()}async refresh(){console.log("[LIBRARY] Force refreshing asset registry...");try{let e=window.getEditableAssets,t=typeof e=="function"?e():null,i=await fetch(`/raw/assetRegistry.json?t=${Date.now()}`);if(i.ok){let n=await i.json(),a=this.mergeRegistries(t,n);window.getEditableAssets=()=>a,console.log("[LIBRARY] \u2705 Registry re-fetched successfully")}}catch(e){console.warn("[LIBRARY] Failed to re-fetch registry:",e)}this.loadAssetRegistry()}loadAssetRegistry(e=0){let t=window.getEditableAssets;if(typeof t=="function"){let i=t();if(i!=null&&i.slots&&Array.isArray(i.slots)&&i.slots.length>0){this.registry=i,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.renderSlots();return}}e<15?(console.log(`[LIBRARY] Waiting for asset registry... (attempt ${e+1}/15)`),setTimeout(()=>this.loadAssetRegistry(e+1),200)):(console.warn("[LIBRARY] Failed to load asset registry"),this.slotsContainer&&(this.slotsContainer.innerHTML='<div class="library-info">No editable assets available</div>'))}renderSlots(){if(!this.slotsContainer||!this.registry)return;let e={};for(let i of this.registry.slots)e[i.category]||(e[i.category]=[]),e[i.category].push(i);let t=Date.now();this.slotsContainer.innerHTML="";for(let i of this.registry.categories){let n=e[i]||[];if(n.length===0)continue;let a=document.createElement("div");a.className="library-category";let r=document.createElement("div");r.className="library-category-header",r.textContent=this.formatCategoryName(i),a.appendChild(r);let o=document.createElement("div");o.className="library-category-slots";for(let l of n){let c=this.createSlotElement(l,t);o.appendChild(c)}a.appendChild(o),this.slotsContainer.appendChild(a)}}createSlotElement(e,t){let i=this.expandedSlot===e.slotId,n=document.createElement("div");n.className=`library-slot ${i?"expanded":""}`,n.dataset.slotId=e.slotId;let a=document.createElement("div");a.className="slot-header";let r=document.createElement("div");r.className="slot-current";let o=document.createElement("img");o.src=`/raw/${e.currentAsset}?t=${t}`,o.alt=e.displayName,o.className="slot-thumbnail",o.onerror=()=>{o.style.display="none"},r.appendChild(o),a.appendChild(r);let l=document.createElement("div");l.className="slot-info";let c=document.createElement("div");c.className="slot-name",c.textContent=e.displayName;let d=document.createElement("div");d.className="slot-asset",d.textContent=e.currentAsset,l.appendChild(c),l.appendChild(d),a.appendChild(l);let p=document.createElement("div");p.className="slot-actions";let u=document.createElement("button");u.className="slot-ai-edit",u.title="Edit with AI",u.textContent="\u2728 AI",u.addEventListener("click",async m=>{m.stopPropagation(),await this.handleAIEdit(e)}),p.appendChild(u);let g=document.createElement("button");g.className="slot-upload",g.title="Upload new asset",g.textContent="\u{1F4E4}",g.addEventListener("click",async m=>{m.stopPropagation(),await this.handleUpload(e)}),p.appendChild(g);let h=document.createElement("button");h.className="slot-reset",h.title="Reset to default",h.textContent="\u21BA",h.addEventListener("click",async m=>{m.stopPropagation(),await this.handleReset(e)}),p.appendChild(h);let f=document.createElement("span");if(f.className="slot-expand-icon",f.textContent=i?"\u25BC":"\u25B6",p.appendChild(f),a.appendChild(p),a.addEventListener("click",()=>{this.expandedSlot=this.expandedSlot===e.slotId?null:e.slotId,this.renderSlots()}),n.appendChild(a),i){let m=this.createLibraryElement(e,t);n.appendChild(m)}return n}createLibraryElement(e,t){var a;let i=document.createElement("div");i.className="slot-library";let n=((a=this.registry)==null?void 0:a.libraryAssets[e.libraryFolder])||[];return this.fetchFolderAssets(e.libraryFolder,t).then(r=>{let o=new Map;for(let c of n)o.set(c.filename,c);for(let c of r)o.has(c.filename)||o.set(c.filename,c);let l=Array.from(o.values());if(l.length===0){i.innerHTML='<div class="library-empty">No alternative assets</div>';return}i.innerHTML="";for(let c of l){let d=document.createElement("div");d.className="library-item";let p=document.createElement("img");p.src=`/raw/library/${e.libraryFolder}/${c.filename}?t=${t}`,p.alt=c.displayName,p.className="library-thumbnail",p.onerror=()=>{p.style.opacity="0.3"},d.appendChild(p);let u=document.createElement("div");u.className="library-label",u.textContent=c.displayName,d.appendChild(u),d.addEventListener("click",async()=>{await this.handleApply(e,c.filename)}),i.appendChild(d)}}),i.innerHTML='<div class="library-loading">Loading assets...</div>',i}async fetchFolderAssets(e,t){try{let i=await fetch(`/raw/library/${e}/?t=${t}`);if(!i.ok)return[];let n=await i.text(),a=[],r=/href="([^"]+\.(png|jpg|jpeg))"/gi,o;for(;(o=r.exec(n))!==null;){let l=o[1];if(!l.startsWith("/")&&!l.startsWith("..")){let c=l.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");a.push({filename:l,displayName:c})}}return a}catch{return console.log("[LIBRARY] Could not fetch folder listing, using registry only"),[]}}async handleApply(e,t){var i;console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{let n=window.__wizardAssetPicker;if(n!=null&&n.onPick){let a=`raw/library/${e.libraryFolder}/${t}`;n.onPick(a),window.__wizardAssetPicker=null;return}await((i=this.options)==null?void 0:i.onApply(e.objectId,t,e.category)),e.currentAsset=t,this.renderSlots()}catch(n){console.error("[LIBRARY] Failed to apply asset:",n)}}async handleReset(e){var t;console.log("[LIBRARY] Resetting slot:",e.slotId,"to default:",e.defaultAsset);try{await((t=this.options)==null?void 0:t.onReset(e.objectId,e.defaultAsset,e.category)),e.currentAsset=e.defaultAsset,this.renderSlots()}catch(i){console.error("[LIBRARY] Failed to reset slot:",i)}}formatCategoryName(e){return e.replace(/_/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}async handleAIEdit(e){console.log("[Library] Opening AI Edit for slot:",e);let t=window.__openAiEditor;if(typeof t=="function"){let i=e.slotId||e.objectId,n="render.texture";e.category==="ui"&&(n="ui.image"),e.category==="audio"&&(n="audio.src"),t(i,`Edit ${e.displayName} with AI`,e.currentAsset,{objectId:e.objectId,path:n})}else console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded.")}async handleUpload(e){console.log("[Library] Opening file upload for slot:",e);let t=document.createElement("input");t.type="file",t.accept="image/*",t.style.display="none",t.addEventListener("change",async()=>{var n;let i=(n=t.files)==null?void 0:n[0];if(i){console.log("[Library] File selected:",i.name);try{let a=await this.fileToDataUrl(i);if(!a){alert("Failed to read file");return}let o=`${e.displayName.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,l=e.category;console.log("[Library] Saving uploaded file:",o,"to category:",l);let d=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:l,filename:`${o}.png`,data:a,overwrite:!0})})).json();if(d.success){console.log("[Library] \u2705 Upload saved:",d.path);let p=window.addAssetToRegistry;typeof p=="function"&&p(l,`${o}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(u){console.warn("[Library] Setup-library not available:",u)}await this.handleApply(e,`${o}.png`),e.currentAsset=`${o}.png`,await this.refresh(),setTimeout(()=>{this.highlightSlot(e.objectId,l)},500),console.log("[Library] \u2705 Upload complete and applied")}else console.error("[Library] \u274C Upload failed:",d.error),alert(`Upload failed: ${d.error}`)}catch(a){console.error("[Library] \u274C Upload error:",a),alert("Upload failed. Check console for details.")}finally{t.remove()}}}),document.body.appendChild(t),t.click()}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}handleCreateWithAI(){console.log("[Library] Opening AI Create modal");let e=window.__openAiEditor;typeof e=="function"?e("new_asset","Create new asset with AI"):(console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded."))}highlightSlot(e,t){if(!this.registry||!this.slotsContainer)return;let i=e.startsWith("json.")?e.replace("json.",""):e,n=this.registry.slots.find(a=>(a.objectId===i||a.slotId===i)&&(!t||a.category===t));n?(console.log("[LIBRARY] Highlighting slot:",n.slotId),this.expandedSlot=n.slotId,this.renderSlots(),setTimeout(()=>{var r;let a=(r=this.slotsContainer)==null?void 0:r.querySelector(`[data-slot-id="${n.slotId}"]`);a&&(a.scrollIntoView({behavior:"smooth",block:"center"}),a.classList.add("highlight-pulse"),setTimeout(()=>a.classList.remove("highlight-pulse"),3e3))},100)):console.warn("[LIBRARY] No slot found for highlight:",e,t)}};var Mi=class{detectType(e,t,i){let n=e.toLowerCase();return n==="logic_id"||n==="logicid"?"select":typeof t=="string"&&t.match(/\.(png|jpg|jpeg|gif|webp)$/i)?"image":n.includes("color")||n.includes("tint")?"color":typeof t=="boolean"?"boolean":typeof t=="number"?"number":Array.isArray(t)?"array":typeof t=="object"&&t!==null?"object":"text"}isHexColor(e){return/^#[0-9a-fA-F]{6}$/i.test(e)}isImagePath(e){return/\.(png|jpg|jpeg|gif|svg)$/i.test(e)}};var ji=class{render(e,t,i,n){let a=this.formatLabel(t),r=i?this.getThumbnailUrl(i):"";return`
753
753
  <div class="inspector-property" data-property-type="image">
754
754
  <div class="inspector-property-header">
755
755
  <label class="inspector-label">${a}</label>
756
756
  <div class="inspector-quick-actions">
757
- <button class="debug-btn debug-btn-sm" data-action="library" data-path="${i}" data-object="${e}" title="Choose from Library">\u{1F3A8}</button>
758
- <button class="debug-btn debug-btn-sm" data-action="ai-edit" data-path="${i}" data-object="${e}" title="Edit with AI">\u2728</button>
759
- <button class="debug-btn debug-btn-sm" data-action="upload" data-path="${i}" data-object="${e}" title="Upload">\u{1F4E4}</button>
760
- <button class="debug-btn debug-btn-sm" data-action="reset" data-path="${i}" data-object="${e}" title="Reset">\u21BA</button>
757
+ <button class="debug-btn debug-btn-sm" data-action="library" data-path="${n}" data-object="${e}" title="Choose from Library">\u{1F3A8}</button>
758
+ <button class="debug-btn debug-btn-sm" data-action="ai-edit" data-path="${n}" data-object="${e}" title="Edit with AI">\u2728</button>
759
+ <button class="debug-btn debug-btn-sm" data-action="upload" data-path="${n}" data-object="${e}" title="Upload">\u{1F4E4}</button>
760
+ <button class="debug-btn debug-btn-sm" data-action="reset" data-path="${n}" data-object="${e}" title="Reset">\u21BA</button>
761
761
  </div>
762
762
  </div>
763
763
  ${r?`
@@ -771,73 +771,73 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
771
771
  </div>
772
772
  `}
773
773
  </div>
774
- `}getThumbnailUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("http")?e:`/raw/${e}?t=${Date.now()}`}escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Mn=class{render(e,t,n,i){let a=n||"#000000";return`
774
+ `}getThumbnailUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("http")?e:`/raw/${e}?t=${Date.now()}`}escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var _i=class{render(e,t,i,n){let a=i||"#000000";return`
775
775
  <div class="inspector-property inspector-property-color">
776
776
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
777
777
  <div class="inspector-color-group">
778
778
  <input type="color"
779
779
  class="inspector-color-picker"
780
780
  value="${a}"
781
- data-property-path="${i}"
781
+ data-property-path="${n}"
782
782
  data-object-id="${e}" />
783
783
  <input type="text"
784
784
  class="inspector-input inspector-color-text"
785
785
  value="${a}"
786
- data-property-path="${i}"
786
+ data-property-path="${n}"
787
787
  data-object-id="${e}" />
788
788
  </div>
789
789
  </div>
790
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Pn=class{render(e,t,n,i){return`
790
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Oi=class{render(e,t,i,n){return`
791
791
  <div class="inspector-property inspector-property-number">
792
792
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
793
793
  <input type="number"
794
794
  class="inspector-input"
795
- value="${n}"
796
- data-property-path="${i}"
795
+ value="${i}"
796
+ data-property-path="${n}"
797
797
  data-object-id="${e}"
798
798
  step="any" />
799
799
  </div>
800
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var _n=class{render(e,t,n,i){let a=String(n||"");return`
800
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ri=class{render(e,t,i,n){let a=String(i||"");return`
801
801
  <div class="inspector-property inspector-property-text">
802
802
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
803
803
  <div class="inspector-input-group">
804
804
  <input type="text"
805
805
  class="inspector-input"
806
806
  value="${a}"
807
- data-property-path="${i}"
807
+ data-property-path="${n}"
808
808
  data-object-id="${e}" />
809
809
  </div>
810
810
  </div>
811
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var On=class{render(e,t,n,i){return`
811
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var zi=class{render(e,t,i,n){return`
812
812
  <div class="inspector-property inspector-property-boolean">
813
813
  <label class="inspector-property-label">
814
814
  <input type="checkbox"
815
815
  class="inspector-checkbox"
816
- ${n?"checked":""}
817
- data-property-path="${i}"
816
+ ${i?"checked":""}
817
+ data-property-path="${n}"
818
818
  data-object-id="${e}" />
819
819
  <span>${this.formatLabel(t)}</span>
820
820
  </label>
821
821
  </div>
822
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Rn=class{constructor(e){this.registry=e}render(e,t,n,i){if(t==="logic"&&this.registry){let r=this.registry,o=Array.isArray(n)?n:[],l=o.map((d,p)=>{let u=`${i}.${p}`,g=`
822
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var $i=class{constructor(e){this.registry=e}render(e,t,i,n){if(t==="logic"&&this.registry){let r=this.registry,o=Array.isArray(i)?i:[],l=o.map((d,p)=>{let u=`${n}.${p}`,g=`
823
823
  <button class="inspector-button inspector-button-small"
824
824
  data-logic-remove="true"
825
825
  data-object-id="${e}"
826
- data-property-path="${i}"
826
+ data-property-path="${n}"
827
827
  data-index="${p}">
828
828
  Remove
829
829
  </button>
830
- `;if(d&&typeof d=="object"&&!Array.isArray(d)){let h=r.renderProperty(e,"logic",d,u);return`
830
+ `;if(d&&typeof d=="object"&&!Array.isArray(d)){let f=r.renderProperty(e,"logic",d,u);return`
831
831
  <div class="inspector-array-item inspector-logic-item">
832
832
  <div class="inspector-array-item-header">
833
833
  <span>Logic ${p+1}</span>
834
834
  ${g}
835
835
  </div>
836
836
  <div class="inspector-array-item-body">
837
- ${h}
837
+ ${f}
838
838
  </div>
839
839
  </div>
840
- `}let f=typeof d=="string"?d:JSON.stringify(d);return`
840
+ `}let h=typeof d=="string"?d:JSON.stringify(d);return`
841
841
  <div class="inspector-array-item inspector-logic-item">
842
842
  <div class="inspector-array-item-header">
843
843
  <span>Logic ${p+1}</span>
@@ -845,20 +845,20 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
845
845
  <button class="inspector-button inspector-button-small"
846
846
  data-logic-convert="true"
847
847
  data-object-id="${e}"
848
- data-property-path="${i}"
848
+ data-property-path="${n}"
849
849
  data-index="${p}">
850
850
  Convert
851
851
  </button>
852
852
  </div>
853
853
  <div class="inspector-array-item-body inspector-array-item-raw">
854
- ${f}
854
+ ${h}
855
855
  </div>
856
856
  </div>
857
857
  `}).join(""),c=`
858
858
  <button class="inspector-button"
859
859
  data-logic-add="true"
860
860
  data-object-id="${e}"
861
- data-property-path="${i}">
861
+ data-property-path="${n}">
862
862
  Add Logic
863
863
  </button>
864
864
  `;return`
@@ -871,19 +871,19 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
871
871
  ${c}
872
872
  </div>
873
873
  </div>
874
- `}if(!Array.isArray(n)||n.length===0)return`
874
+ `}if(!Array.isArray(i)||i.length===0)return`
875
875
  <div class="inspector-property inspector-property-array">
876
876
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
877
877
  <div class="inspector-array-empty">Empty array</div>
878
878
  </div>
879
- `;let a=n.map((r,o)=>typeof r=="string"?`<div class="inspector-array-item">\u2022 ${r}</div>`:typeof r=="object"?`<div class="inspector-array-item">\u2022 ${JSON.stringify(r)}</div>`:`<div class="inspector-array-item">\u2022 ${String(r)}</div>`).join("");return`
879
+ `;let a=i.map((r,o)=>typeof r=="string"?`<div class="inspector-array-item">\u2022 ${r}</div>`:typeof r=="object"?`<div class="inspector-array-item">\u2022 ${JSON.stringify(r)}</div>`:`<div class="inspector-array-item">\u2022 ${String(r)}</div>`).join("");return`
880
880
  <div class="inspector-property inspector-property-array">
881
- <label class="inspector-property-label">${this.formatLabel(t)} (${n.length} items)</label>
881
+ <label class="inspector-property-label">${this.formatLabel(t)} (${i.length} items)</label>
882
882
  <div class="inspector-array-list">
883
883
  ${a}
884
884
  </div>
885
885
  </div>
886
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var zn=class{constructor(e){this.registry=e}render(e,t,n,i){if(t==="logic"&&n&&typeof n=="object"&&!Array.isArray(n))return this.renderLogic(e,t,n,i);let a=[];for(let o in n){let l=n[o],c=`${i}.${o}`,d=this.registry.renderProperty(e,o,l,c);d&&a.push(d)}return a.length===0?"":a.length<=4&&a.every(o=>o.includes("inspector-property"))?`
886
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Di=class{constructor(e){this.registry=e}render(e,t,i,n){if(t==="logic"&&i&&typeof i=="object"&&!Array.isArray(i))return this.renderLogic(e,t,i,n);let a=[];for(let o in i){let l=i[o],c=`${n}.${o}`,d=this.registry.renderProperty(e,o,l,c);d&&a.push(d)}return a.length===0?"":a.length<=4&&a.every(o=>o.includes("inspector-property"))?`
887
887
  <div class="inspector-subsection">
888
888
  <div class="inspector-subsection-title">${this.formatLabel(t)}</div>
889
889
  <div class="inspector-subsection-content">
@@ -897,12 +897,12 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
897
897
  ${a.join("")}
898
898
  </div>
899
899
  </div>
900
- `}renderLogic(e,t,n,i){let a=[],r=typeof(n==null?void 0:n.id)=="string"?n.id:"",o={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},l=(()=>{let u=window,g=Array.isArray(u==null?void 0:u.__HANDLER_LOGIC_OPTIONS)?u.__HANDLER_LOGIC_OPTIONS:[],h=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...g].map(m=>String(m)).filter(m=>m.trim().length>0);return Array.from(new Set(h)).sort((m,b)=>m.localeCompare(b))})(),c=r&&!l.includes(r)?[r,...l]:l;a.push(`
900
+ `}renderLogic(e,t,i,n){let a=[],r=typeof(i==null?void 0:i.id)=="string"?i.id:"",o={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},l=(()=>{let u=window,g=Array.isArray(u==null?void 0:u.__HANDLER_LOGIC_OPTIONS)?u.__HANDLER_LOGIC_OPTIONS:[],f=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...g].map(m=>String(m)).filter(m=>m.trim().length>0);return Array.from(new Set(f)).sort((m,b)=>m.localeCompare(b))})(),c=r&&!l.includes(r)?[r,...l]:l;a.push(`
901
901
  <div class="inspector-property inspector-property-text">
902
902
  <label class="inspector-property-label">Id</label>
903
903
  <div class="inspector-input-group">
904
904
  <select class="inspector-component-select inspector-input"
905
- data-property-path="${i}.id"
905
+ data-property-path="${n}.id"
906
906
  data-object-id="${e}"
907
907
  data-logic-id-selector="true">
908
908
  <option value="" ${r?"":"selected"}>None</option>
@@ -910,15 +910,15 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
910
910
  </select>
911
911
  </div>
912
912
  </div>
913
- `);for(let u in n){if(u==="id")continue;let g=n[u],f=`${i}.${u}`;if(u==="props"&&g&&typeof g=="object"){let m=[];for(let b in g){let y=g[b],v=`${f}.${b}`,w=o[b];if(b==="targetId"||b==="inputId"){let E=this.registry.getObjectIds(),j=typeof y=="string"?y:"",z=j&&!E.includes(j)?[j,...E]:E;m.push(`
913
+ `);for(let u in i){if(u==="id")continue;let g=i[u],h=`${n}.${u}`;if(u==="props"&&g&&typeof g=="object"){let m=[];for(let b in g){let y=g[b],v=`${h}.${b}`,w=o[b];if(b==="targetId"||b==="inputId"){let E=this.registry.getObjectIds(),P=typeof y=="string"?y:"",M=P&&!E.includes(P)?[P,...E]:E;m.push(`
914
914
  <div class="inspector-property inspector-property-text">
915
915
  <label class="inspector-property-label">${this.formatLabel(b)}</label>
916
916
  <div class="inspector-input-group">
917
917
  <select class="inspector-component-select inspector-input"
918
918
  data-property-path="${v}"
919
919
  data-object-id="${e}">
920
- <option value="" ${j?"":"selected"}>None</option>
921
- ${z.map(S=>`<option value="${S}" ${S===j?"selected":""}>${S}</option>`).join("")}
920
+ <option value="" ${P?"":"selected"}>None</option>
921
+ ${M.map(x=>`<option value="${x}" ${x===P?"selected":""}>${x}</option>`).join("")}
922
922
  </select>
923
923
  </div>
924
924
  </div>
@@ -940,12 +940,12 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
940
940
  ${m.join("")}
941
941
  </div>
942
942
  </div>
943
- `);continue}let h=this.registry.renderProperty(e,u,g,f);h&&a.push(h)}if(a.length===0)return"";let p=/(^|\.)logic\.\d+$/.test(i)?"":`
943
+ `);continue}let f=this.registry.renderProperty(e,u,g,h);f&&a.push(f)}if(a.length===0)return"";let p=/(^|\.)logic\.\d+$/.test(n)?"":`
944
944
  <div class="inspector-array-actions" style="margin-top: 12px;">
945
945
  <button class="inspector-button"
946
946
  data-logic-add="true"
947
947
  data-object-id="${e}"
948
- data-property-path="${i}"
948
+ data-property-path="${n}"
949
949
  style="width: 100%;">
950
950
  \u2795 Add Another Logic
951
951
  </button>
@@ -958,45 +958,45 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
958
958
  ${p}
959
959
  </div>
960
960
  </div>
961
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var $n=class{render(e,t,n,i,a){let r=n==null?"":String(n),o=Array.from(new Set(a.map(c=>String(c)))),l=r&&!o.includes(r)?[r,...o]:o;return`
961
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Hi=class{render(e,t,i,n,a){let r=i==null?"":String(i),o=Array.from(new Set(a.map(c=>String(c)))),l=r&&!o.includes(r)?[r,...o]:o;return`
962
962
  <div class="inspector-property inspector-property-text">
963
963
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
964
964
  <div class="inspector-input-group">
965
965
  <select class="inspector-component-select inspector-input"
966
- data-property-path="${i}"
966
+ data-property-path="${n}"
967
967
  data-object-id="${e}">
968
968
  ${l.map(c=>`<option value="${c}" ${c===r?"selected":""}>${c}</option>`).join("")}
969
969
  </select>
970
970
  </div>
971
971
  </div>
972
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Dn=class{render(e,t,n,i){let a=this.safeStringify(n);return`
972
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ni=class{render(e,t,i,n){let a=this.safeStringify(i);return`
973
973
  <div class="inspector-property inspector-property-text">
974
974
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
975
975
  <div class="inspector-input-group">
976
976
  <textarea class="inspector-input"
977
- data-property-path="${i}"
977
+ data-property-path="${n}"
978
978
  data-object-id="${e}"
979
979
  data-json="true"
980
980
  rows="6">${a}</textarea>
981
981
  </div>
982
982
  </div>
983
- `}safeStringify(e){try{return JSON.stringify(e!=null?e:[],null,2)}catch{return"[]"}}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Hn=class{render(e,t,n,i){let r=(Array.isArray(n)?n:[]).map((o,l)=>{let c=typeof(o==null?void 0:o.x)=="number"?o.x:0,d=typeof(o==null?void 0:o.y)=="number"?o.y:0;return`
983
+ `}safeStringify(e){try{return JSON.stringify(e!=null?e:[],null,2)}catch{return"[]"}}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Fi=class{render(e,t,i,n){let r=(Array.isArray(i)?i:[]).map((o,l)=>{let c=typeof(o==null?void 0:o.x)=="number"?o.x:0,d=typeof(o==null?void 0:o.y)=="number"?o.y:0;return`
984
984
  <div class="inspector-row" style="gap:8px; align-items:center;">
985
985
  <input type="number"
986
986
  class="inspector-input"
987
987
  value="${c}"
988
- data-property-path="${i}.${l}.x"
988
+ data-property-path="${n}.${l}.x"
989
989
  data-object-id="${e}" />
990
990
  <input type="number"
991
991
  class="inspector-input"
992
992
  value="${d}"
993
- data-property-path="${i}.${l}.y"
993
+ data-property-path="${n}.${l}.y"
994
994
  data-object-id="${e}" />
995
995
  <button type="button"
996
996
  class="inspector-btn inspector-btn-sm"
997
997
  data-spawnpoints-remove="true"
998
998
  data-object-id="${e}"
999
- data-property-path="${i}"
999
+ data-property-path="${n}"
1000
1000
  data-index="${l}">Remove</button>
1001
1001
  </div>
1002
1002
  `}).join("");return`
@@ -1009,14 +1009,14 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
1009
1009
  class="inspector-btn inspector-btn-sm primary"
1010
1010
  data-spawnpoints-add="true"
1011
1011
  data-object-id="${e}"
1012
- data-property-path="${i}">Add Point</button>
1012
+ data-property-path="${n}">Add Point</button>
1013
1013
  </div>
1014
1014
  </div>
1015
1015
  </div>
1016
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Nn=class{constructor(e){this.registry=e}render(e,t,n,i){let a=Array.isArray(n)?n:[],o=["",...this.registry.getObjectIds()],l=a.map((c,d)=>{let p=typeof(c==null?void 0:c.templateId)=="string"?c.templateId:"",u=typeof(c==null?void 0:c.weight)=="number"?c.weight:1,g=o.map(f=>`<option value="${f}"${f===p?" selected":""}>${f||"(none)"}</option>`).join("");return`
1016
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Bi=class{constructor(e){this.registry=e}render(e,t,i,n){let a=Array.isArray(i)?i:[],o=["",...this.registry.getObjectIds()],l=a.map((c,d)=>{let p=typeof(c==null?void 0:c.templateId)=="string"?c.templateId:"",u=typeof(c==null?void 0:c.weight)=="number"?c.weight:1,g=o.map(h=>`<option value="${h}"${h===p?" selected":""}>${h||"(none)"}</option>`).join("");return`
1017
1017
  <div class="inspector-row" style="gap:8px; align-items:center;">
1018
1018
  <select class="inspector-select inspector-input"
1019
- data-property-path="${i}.${d}.templateId"
1019
+ data-property-path="${n}.${d}.templateId"
1020
1020
  data-object-id="${e}">
1021
1021
  ${g}
1022
1022
  </select>
@@ -1025,13 +1025,13 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
1025
1025
  style="width:72px;"
1026
1026
  value="${u}"
1027
1027
  placeholder="weight"
1028
- data-property-path="${i}.${d}.weight"
1028
+ data-property-path="${n}.${d}.weight"
1029
1029
  data-object-id="${e}" />
1030
1030
  <button type="button"
1031
1031
  class="inspector-btn inspector-btn-sm"
1032
1032
  data-spawntemplates-remove="true"
1033
1033
  data-object-id="${e}"
1034
- data-property-path="${i}"
1034
+ data-property-path="${n}"
1035
1035
  data-index="${d}">Remove</button>
1036
1036
  </div>
1037
1037
  `}).join("");return`
@@ -1044,21 +1044,21 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{await fetch("/api/sync-scre
1044
1044
  class="inspector-btn inspector-btn-sm primary"
1045
1045
  data-spawntemplates-add="true"
1046
1046
  data-object-id="${e}"
1047
- data-property-path="${i}">Add Template</button>
1047
+ data-property-path="${n}">Add Template</button>
1048
1048
  </div>
1049
1049
  </div>
1050
1050
  </div>
1051
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Fn=class{constructor(){this.typeDetector=new In,this.imageRenderer=new jn,this.colorRenderer=new Mn,this.numberRenderer=new Pn,this.textRenderer=new _n,this.booleanRenderer=new On,this.arrayRenderer=new Rn(this),this.objectRenderer=new zn(this),this.selectRenderer=new $n,this.jsonRenderer=new Dn,this.spawnPointsRenderer=new Hn,this.spawnTemplatesRenderer=new Nn(this)}getObjectIds(){try{let e=window,t=e==null?void 0:e.__editableConfig;if(!(t!=null&&t.objects))return[];let n=[];if(t.objects instanceof Map)for(let i of t.objects.keys())n.push(i);else typeof t.objects=="object"&&n.push(...Object.keys(t.objects));return n.sort()}catch{return[]}}getEnumOptionsFromSchemas(e){var t;try{let n=window,i=n==null?void 0:n.__editableConfig,a=i==null?void 0:i.schemas;if(!a)return null;let r=String(e||"").split(".").filter(Boolean);if(r.length<2)return null;let o=r[0],l=r.slice(1).join("."),c=a instanceof Map?a.get(o):a==null?void 0:a[o];if(!c)return null;let d=(t=c==null?void 0:c.types)==null?void 0:t[l];if(typeof d!="string"||!d.startsWith("enum:"))return null;let u=d.slice(5).split("|").map(g=>g.trim()).filter(Boolean);return u.length?u:null}catch{return null}}getLogicOptions(){try{let e=window,t=Array.isArray(e==null?void 0:e.__HANDLER_LOGIC_OPTIONS)?e.__HANDLER_LOGIC_OPTIONS:[],i=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...t].map(a=>String(a)).filter(a=>a.trim().length>0);return Array.from(new Set(i)).sort((a,r)=>a.localeCompare(r))}catch{return[]}}renderProperty(e,t,n,i){let a=t.toLowerCase(),r=a==="logic"||a==="logic_id"||a==="logicid",o=a==="id"&&i.toLowerCase().includes("logic");if((r||o)&&typeof n=="string"){let f=this.getLogicOptions(),h=this.selectRenderer.render(e,t,n,i,f);return r?`
1052
- ${h}
1051
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ui=class{constructor(){this.typeDetector=new Mi,this.imageRenderer=new ji,this.colorRenderer=new _i,this.numberRenderer=new Oi,this.textRenderer=new Ri,this.booleanRenderer=new zi,this.arrayRenderer=new $i(this),this.objectRenderer=new Di(this),this.selectRenderer=new Hi,this.jsonRenderer=new Ni,this.spawnPointsRenderer=new Fi,this.spawnTemplatesRenderer=new Bi(this)}getObjectIds(){try{let e=window,t=e==null?void 0:e.__editableConfig;if(!(t!=null&&t.objects))return[];let i=[];if(t.objects instanceof Map)for(let n of t.objects.keys())i.push(n);else typeof t.objects=="object"&&i.push(...Object.keys(t.objects));return i.sort()}catch{return[]}}getEnumOptionsFromSchemas(e){var t;try{let i=window,n=i==null?void 0:i.__editableConfig,a=n==null?void 0:n.schemas;if(!a)return null;let r=String(e||"").split(".").filter(Boolean);if(r.length<2)return null;let o=r[0],l=r.slice(1).join("."),c=a instanceof Map?a.get(o):a==null?void 0:a[o];if(!c)return null;let d=(t=c==null?void 0:c.types)==null?void 0:t[l];if(typeof d!="string"||!d.startsWith("enum:"))return null;let u=d.slice(5).split("|").map(g=>g.trim()).filter(Boolean);return u.length?u:null}catch{return null}}getLogicOptions(){try{let e=window,t=Array.isArray(e==null?void 0:e.__HANDLER_LOGIC_OPTIONS)?e.__HANDLER_LOGIC_OPTIONS:[],n=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...t].map(a=>String(a)).filter(a=>a.trim().length>0);return Array.from(new Set(n)).sort((a,r)=>a.localeCompare(r))}catch{return[]}}renderProperty(e,t,i,n){let a=t.toLowerCase(),r=a==="logic"||a==="logic_id"||a==="logicid",o=a==="id"&&n.toLowerCase().includes("logic");if((r||o)&&typeof i=="string"){let h=this.getLogicOptions(),f=this.selectRenderer.render(e,t,i,n,h);return r?`
1052
+ ${f}
1053
1053
  <div class="inspector-array-actions">
1054
1054
  <button class="inspector-button"
1055
1055
  data-logic-add="true"
1056
1056
  data-object-id="${e}"
1057
- data-property-path="${i}">
1057
+ data-property-path="${n}">
1058
1058
  Add Logic
1059
1059
  </button>
1060
1060
  </div>
1061
- `:h}let l={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},c={anchor:["center","top-left","top-center","top-right","bottom-left","bottom-center","bottom-right"]},d=l[t];if(d&&i.includes("logic.props"))return this.selectRenderer.render(e,t,n,i,d);let p=c[t];if(p&&(i.includes("transform")||i.includes("render"))&&!(t==="anchor"&&typeof n!="string"&&n!=null)){let f=t==="anchor"&&n==null?"center":n;return this.selectRenderer.render(e,t,f,i,p)}if(t==="spawnPoints"&&i.includes("logic.props"))return this.spawnPointsRenderer.render(e,t,n,i);if(t==="spawnTemplates"&&i.includes("logic.props"))return this.spawnTemplatesRenderer.render(e,t,n,i);if((t==="targetId"||t==="inputId"||t==="hitTemplateId"||t==="hpLabelId"||t==="hitPopupTemplateId")&&(n==null||typeof n=="string")){let f=this.getObjectIds(),h=this.selectRenderer.render(e,t,n!=null?n:"",i,["",...f]);return t==="hitTemplateId"&&i.includes("logic.props")?h+'<div class="inspector-text-sm" style="opacity:0.7; margin-top:4px;">Use template id (e.g. bullet_template), not spawner.</div>':h}if(i.includes("motion.")){if(t==="enabled")return this.booleanRenderer.render(e,t,!!n,i);if(t==="direction"&&(i.includes("continuousMove")||i.includes("continuousRotate")||i.includes("orbit"))){let h=["1","-1"],m=n==null?"1":String(n);return this.selectRenderer.render(e,t,m,i,h)}if(["speed","amplitude","intensity","minScale","maxScale","radius","lifetime","pivotOffsetX","pivotOffsetY","duration","delay","startScale","startAlpha","startYOffset","startXOffset"].includes(t)){let h=typeof n=="number"&&!Number.isNaN(n)?n:0;return this.numberRenderer.render(e,t,h,i)}}let u=this.getEnumOptionsFromSchemas(i);if(u)return this.selectRenderer.render(e,t,n,i,u);switch(this.typeDetector.detectType(t,n)){case"image":return this.imageRenderer.render(e,t,n,i);case"color":return this.colorRenderer.render(e,t,n,i);case"number":return this.numberRenderer.render(e,t,n,i);case"boolean":return this.booleanRenderer.render(e,t,n,i);case"array":return this.arrayRenderer.render(e,t,n,i);case"object":return this.objectRenderer.render(e,t,n,i);case"select":return this.selectRenderer.render(e,t,n,i,[]);default:return this.textRenderer.render(e,t,n,i)}}getTypeDetector(){return this.typeDetector}};function Ko(s,e){let t;return function(...i){let a=()=>{clearTimeout(t),s(...i)};clearTimeout(t),t=setTimeout(a,e)}}var Bn=class{constructor(){this.root=null;this.contentContainer=null;this.selectedObjectId=null;this.options=null;this.showAdvanced=!1;this.motionSimpleMode=!0;this.expandMotionOnNextRender=!1;this.rendererRegistry=new Fn,this.updateManager=new Me,this.quickActions=new En;try{let e=localStorage.getItem("inspector:motionSimple");e!==null&&(this.motionSimpleMode=e==="true")}catch{}window.addEventListener("inspector:refresh",()=>{this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),window.addEventListener("config:changed",()=>{})}render(){return`
1061
+ `:f}let l={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},c={anchor:["center","top-left","top-center","top-right","bottom-left","bottom-center","bottom-right"]},d=l[t];if(d&&n.includes("logic.props"))return this.selectRenderer.render(e,t,i,n,d);let p=c[t];if(p&&(n.includes("transform")||n.includes("render"))&&!(t==="anchor"&&typeof i!="string"&&i!=null)){let h=t==="anchor"&&i==null?"center":i;return this.selectRenderer.render(e,t,h,n,p)}if(t==="spawnPoints"&&n.includes("logic.props"))return this.spawnPointsRenderer.render(e,t,i,n);if(t==="spawnTemplates"&&n.includes("logic.props"))return this.spawnTemplatesRenderer.render(e,t,i,n);if((t==="targetId"||t==="inputId"||t==="hitTemplateId"||t==="hpLabelId"||t==="hitPopupTemplateId")&&(i==null||typeof i=="string")){let h=this.getObjectIds(),f=this.selectRenderer.render(e,t,i!=null?i:"",n,["",...h]);return t==="hitTemplateId"&&n.includes("logic.props")?f+'<div class="inspector-text-sm" style="opacity:0.7; margin-top:4px;">Use template id (e.g. bullet_template), not spawner.</div>':f}if(n.includes("motion.")){if(t==="enabled")return this.booleanRenderer.render(e,t,!!i,n);if(t==="direction"&&(n.includes("continuousMove")||n.includes("continuousRotate")||n.includes("orbit"))){let f=["1","-1"],m=i==null?"1":String(i);return this.selectRenderer.render(e,t,m,n,f)}if(["speed","amplitude","intensity","minScale","maxScale","radius","lifetime","pivotOffsetX","pivotOffsetY","duration","delay","startScale","startAlpha","startYOffset","startXOffset"].includes(t)){let f=typeof i=="number"&&!Number.isNaN(i)?i:0;return this.numberRenderer.render(e,t,f,n)}}let u=this.getEnumOptionsFromSchemas(n);if(u)return this.selectRenderer.render(e,t,i,n,u);switch(this.typeDetector.detectType(t,i)){case"image":return this.imageRenderer.render(e,t,i,n);case"color":return this.colorRenderer.render(e,t,i,n);case"number":return this.numberRenderer.render(e,t,i,n);case"boolean":return this.booleanRenderer.render(e,t,i,n);case"array":return this.arrayRenderer.render(e,t,i,n);case"object":return this.objectRenderer.render(e,t,i,n);case"select":return this.selectRenderer.render(e,t,i,n,[]);default:return this.textRenderer.render(e,t,i,n)}}getTypeDetector(){return this.typeDetector}};function tl(s,e){let t;return function(...n){let a=()=>{clearTimeout(t),s(...n)};clearTimeout(t),t=setTimeout(a,e)}}var Gi=class{constructor(){this.root=null;this.contentContainer=null;this.selectedObjectId=null;this.options=null;this.showAdvanced=!1;this.motionSimpleMode=!0;this.expandMotionOnNextRender=!1;this.rendererRegistry=new Ui,this.updateManager=new _e,this.quickActions=new Ci;try{let e=localStorage.getItem("inspector:motionSimple");e!==null&&(this.motionSimpleMode=e==="true")}catch{}window.addEventListener("inspector:refresh",()=>{this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),window.addEventListener("config:changed",()=>{})}render(){return`
1062
1062
  <div class="scene-panel inspector-panel panel-accent-violet" data-panel="inspector">
1063
1063
  <div class="scene-panel-header" data-panel-handle>
1064
1064
  <div class="panel-title">
@@ -1079,7 +1079,7 @@ ${h}
1079
1079
  </div>
1080
1080
  </div>
1081
1081
  </div>
1082
- `}initialize(e,t){var n;this.options=t,this.root=e.querySelector('[data-panel="inspector"]'),this.contentContainer=(n=this.root)==null?void 0:n.querySelector("[data-inspector-content]")}loadObject(e){this.selectedObjectId=e;let t=window.getEditableObjectConfig;if(typeof t!="function"){this.showError("Config system not ready");return}let n=t(e);if(!n){console.error("[InspectorPanel] Object not found in config system:",e),this.showError(`Object not found: ${e}`);return}this.renderProperties(e,n)}renderProperties(e,t){if(!this.contentContainer)return;let n=[],i=t.identity||{},a=i.id||e,r=i.category||"unknown";n.push(`
1082
+ `}initialize(e,t){var i;this.options=t,this.root=e.querySelector('[data-panel="inspector"]'),this.contentContainer=(i=this.root)==null?void 0:i.querySelector("[data-inspector-content]")}loadObject(e){this.selectedObjectId=e;let t=window.getEditableObjectConfig;if(typeof t!="function"){this.showError("Config system not ready");return}let i=t(e);if(!i){console.error("[InspectorPanel] Object not found in config system:",e),this.showError(`Object not found: ${e}`);return}this.renderProperties(e,i)}renderProperties(e,t){if(!this.contentContainer)return;let i=[],n=t.identity||{},a=n.id||e,r=n.category||"unknown";i.push(`
1083
1083
  <div class="inspector-header">
1084
1084
  <div class="inspector-header-info">
1085
1085
  <div class="inspector-object-name">${a}</div>
@@ -1087,7 +1087,7 @@ ${h}
1087
1087
  </div>
1088
1088
  ${this.renderConversionButtons(e,t)}
1089
1089
  </div>
1090
- `);let o=["transform","ui","render","gameplay","interaction","audio","effects","physics","motion","identity"];for(let l of o){let c=t[l];if(c){if(!this.showAdvanced&&!this.isSectionMeaningful(l,c,t))continue;n.push(this.renderSection(e,l,c,l))}}for(let l in t)if(!o.includes(l)&&typeof t[l]=="object"&&t[l]!==null){if(!this.showAdvanced&&!this.isSectionMeaningful(l,t[l],t))continue;n.push(this.renderSection(e,l,t[l],l))}this.contentContainer.innerHTML=n.join("")+this.renderFooter(t),this.attachEventListeners(),this.expandMotionOnNextRender=!1}renderConversionButtons(e,t){var o,l,c,d;let n=!!t.ui,i=((o=t.ui)==null?void 0:o.renderMode)==="png"||((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.type)==="image";if(!(n||e.includes("ui_endgame")||e.includes("splash")||e.includes("button")||e.includes("label"))||i)return"";let r=(d=t.ui)!=null&&d.text?"ui.text":"render.asset.path";return`
1090
+ `);let o=["transform","ui","render","gameplay","interaction","audio","effects","physics","motion","identity"];for(let l of o){let c=t[l];if(c){if(!this.showAdvanced&&!this.isSectionMeaningful(l,c,t))continue;i.push(this.renderSection(e,l,c,l))}}for(let l in t)if(!o.includes(l)&&typeof t[l]=="object"&&t[l]!==null){if(!this.showAdvanced&&!this.isSectionMeaningful(l,t[l],t))continue;i.push(this.renderSection(e,l,t[l],l))}this.contentContainer.innerHTML=i.join("")+this.renderFooter(t),this.attachEventListeners(),this.expandMotionOnNextRender=!1}renderConversionButtons(e,t){var o,l,c,d;let i=!!t.ui,n=((o=t.ui)==null?void 0:o.renderMode)==="png"||((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.type)==="image";if(!(i||e.includes("ui_endgame")||e.includes("splash")||e.includes("button")||e.includes("label"))||n)return"";let r=(d=t.ui)!=null&&d.text?"ui.text":"render.asset.path";return`
1091
1091
  <div class="inspector-quick-actions">
1092
1092
  <button class="debug-btn debug-btn-sm success ai-simple-btn" type="button" data-convert-toggle>
1093
1093
  \u2728 Convert to PNG
@@ -1098,17 +1098,17 @@ ${h}
1098
1098
  <button class="debug-btn debug-btn-sm" data-action="upload" data-path="render.asset.path" data-object="${e}">\u{1F4E4} Upload</button>
1099
1099
  </div>
1100
1100
  </div>
1101
- `}renderFooter(e){let t=["logic","motion","effects","ui","audio","physics","interaction","gameplay","visibility"],n=Object.keys(e),i=t.filter(a=>!n.includes(a));return i.length===0?"":`
1101
+ `}renderFooter(e){let t=["logic","motion","effects","ui","audio","physics","interaction","gameplay","visibility"],i=Object.keys(e),n=t.filter(a=>!i.includes(a));return n.length===0?"":`
1102
1102
  <div class="inspector-footer">
1103
1103
  <div class="inspector-add-component">
1104
1104
  <select class="inspector-component-select" data-inspector-component-select>
1105
1105
  <option value="" disabled selected>Add Component...</option>
1106
- ${i.map(a=>`<option value="${a}">${this.formatLabel(a)}</option>`).join("")}
1106
+ ${n.map(a=>`<option value="${a}">${this.formatLabel(a)}</option>`).join("")}
1107
1107
  </select>
1108
1108
  <button class="debug-btn debug-btn-sm primary" data-inspector-add-component-btn>Add</button>
1109
1109
  </div>
1110
1110
  </div>
1111
- `}renderSection(e,t,n,i){if(t==="motion")return this.renderMotionSection(e,n,i);if(t==="logic")return this.renderLogicSection(e,n,i);let a=[],r=["kind","renderMode","position_ratio","position_mode","responsive","slot_id","asset_type"];for(let c in n){if(!this.showAdvanced&&r.includes(c))continue;let d=n[c],p=`${i}.${c}`,u=this.rendererRegistry.renderProperty(e,c,d,p);u&&a.push(u)}return a.length===0?"":`
1111
+ `}renderSection(e,t,i,n){if(t==="motion")return this.renderMotionSection(e,i,n);if(t==="logic")return this.renderLogicSection(e,i,n);let a=[],r=["kind","renderMode","position_ratio","position_mode","responsive","slot_id","asset_type"];for(let c in i){if(!this.showAdvanced&&r.includes(c))continue;let d=i[c],p=`${n}.${c}`,u=this.rendererRegistry.renderProperty(e,c,d,p);u&&a.push(u)}return a.length===0?"":`
1112
1112
  <div class="inspector-section ${t==="transform"?"":"collapsed"}" data-section="${t}">
1113
1113
  <div class="inspector-section-header" data-section-toggle="${t}">
1114
1114
  <span class="inspector-section-arrow">\u25BC</span>
@@ -1119,7 +1119,7 @@ ${h}
1119
1119
  ${a.join("")}
1120
1120
  </div>
1121
1121
  </div>
1122
- `}renderLogicSection(e,t,n){let i=this.rendererRegistry.renderProperty(e,"logic",t,n);return i?`
1122
+ `}renderLogicSection(e,t,i){let n=this.rendererRegistry.renderProperty(e,"logic",t,i);return n?`
1123
1123
  <div class="inspector-section collapsed" data-section="logic">
1124
1124
  <div class="inspector-section-header" data-section-toggle="logic">
1125
1125
  <span class="inspector-section-arrow">\u25BC</span>
@@ -1127,10 +1127,10 @@ ${h}
1127
1127
  <span class="inspector-section-title">${this.formatLabel("logic")}</span>
1128
1128
  </div>
1129
1129
  <div class="inspector-section-body" data-section-body="logic">
1130
- ${i}
1130
+ ${n}
1131
1131
  </div>
1132
1132
  </div>
1133
- `:""}applyMotionDefaults(e,t){if(!t||typeof t!="object")return e!=null?e:{};let n={...e!=null?e:{}};for(let i of Object.keys(t)){let a=t[i],r=n[i];a!=null&&typeof a=="object"&&!Array.isArray(a)?n[i]=this.applyMotionDefaults(r,a):r===void 0&&(n[i]=a)}return n}renderMotionSection(e,t,n){var f;let i=[],a=this.getMotionDefaults(),r=this.applyMotionDefaults(t!=null?t:{},a!=null?a:{}),o=(f=r.intro)!=null?f:{},l=o.enabled===!0&&(typeof o.duration!="number"||o.duration<=0)?'<div class="inspector-warning">\u26A0\uFE0F Duration must be > 0 to play.</div>':"",c=`
1133
+ `:""}applyMotionDefaults(e,t){if(!t||typeof t!="object")return e!=null?e:{};let i={...e!=null?e:{}};for(let n of Object.keys(t)){let a=t[n],r=i[n];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[n]=this.applyMotionDefaults(r,a):r===void 0&&(i[n]=a)}return i}renderMotionSection(e,t,i){var h;let n=[],a=this.getMotionDefaults(),r=this.applyMotionDefaults(t!=null?t:{},a!=null?a:{}),o=(h=r.intro)!=null?h:{},l=o.enabled===!0&&(typeof o.duration!="number"||o.duration<=0)?'<div class="inspector-warning">\u26A0\uFE0F Duration must be > 0 to play.</div>':"",c=`
1134
1134
  <div class="inspector-motion-presets">
1135
1135
  <span class="inspector-subsection-title">Intro Motions</span>
1136
1136
  <div class="inspector-motion-buttons">
@@ -1147,7 +1147,7 @@ ${h}
1147
1147
  <button class="debug-btn debug-btn-sm ${this.motionSimpleMode?"primary":""}" data-motion-simple-toggle>
1148
1148
  ${this.motionSimpleMode?"Simple":"Advanced"}
1149
1149
  </button>
1150
- `,p='<button class="debug-btn debug-btn-sm success" data-motion-preview>Preview Intro</button>',u=h=>{let m=h.split(".").filter(Boolean),b=r;for(let w of m)b=b==null?void 0:b[w];let y=m[m.length-1],v=`${n}.${h}`;return this.rendererRegistry.renderProperty(e,y,b,v)};if(this.motionSimpleMode){let h=u("enabled");h&&i.push(h);let m=[],b=u("intro.enabled"),y=u("intro.type"),v=u("intro.duration"),w=u("intro.easing");b&&m.push(b),y&&m.push(y),v&&m.push(v),w&&m.push(w),m.length&&i.push(`
1150
+ `,p='<button class="debug-btn debug-btn-sm success" data-motion-preview>Preview Intro</button>',u=f=>{let m=f.split(".").filter(Boolean),b=r;for(let w of m)b=b==null?void 0:b[w];let y=m[m.length-1],v=`${i}.${f}`;return this.rendererRegistry.renderProperty(e,y,b,v)};if(this.motionSimpleMode){let f=u("enabled");f&&n.push(f);let m=[],b=u("intro.enabled"),y=u("intro.type"),v=u("intro.duration"),w=u("intro.easing");b&&m.push(b),y&&m.push(y),v&&m.push(v),w&&m.push(w),m.length&&n.push(`
1151
1151
  <div class="inspector-subsection">
1152
1152
  <div class="inspector-subsection-title">Intro</div>
1153
1153
  <div class="inspector-subsection-content">
@@ -1156,18 +1156,18 @@ ${h}
1156
1156
  ${m.join("")}
1157
1157
  </div>
1158
1158
  </div>
1159
- `);let E=[u("pulse.enabled"),u("pulse.speed"),u("pulse.intensity")].filter(Boolean),j=[u("swing.enabled"),u("swing.amplitude"),u("swing.speed"),u("swing.axis")].filter(Boolean),z=[u("continuousMove.enabled"),u("continuousMove.axis"),u("continuousMove.speed"),u("continuousMove.direction"),u("continuousMove.lifetime")].filter(Boolean),S=[u("continuousRotate.enabled"),u("continuousRotate.speed"),u("continuousRotate.direction")].filter(Boolean),P=[u("orbit.enabled"),u("orbit.radius"),u("orbit.speed"),u("orbit.direction"),u("orbit.pivotOffsetX"),u("orbit.pivotOffsetY")].filter(Boolean);if(E.length||j.length||z.length||S.length||P.length){let T=(M,k)=>k.length?`
1159
+ `);let E=[u("pulse.enabled"),u("pulse.speed"),u("pulse.intensity")].filter(Boolean),P=[u("swing.enabled"),u("swing.amplitude"),u("swing.speed"),u("swing.axis")].filter(Boolean),M=[u("continuousMove.enabled"),u("continuousMove.axis"),u("continuousMove.speed"),u("continuousMove.direction"),u("continuousMove.lifetime")].filter(Boolean),x=[u("continuousRotate.enabled"),u("continuousRotate.speed"),u("continuousRotate.direction")].filter(Boolean),_=[u("orbit.enabled"),u("orbit.radius"),u("orbit.speed"),u("orbit.direction"),u("orbit.pivotOffsetX"),u("orbit.pivotOffsetY")].filter(Boolean);if(E.length||P.length||M.length||x.length||_.length){let T=(j,k)=>k.length?`
1160
1160
  <div class="inspector-motion-continuous-group">
1161
- <div class="inspector-subsection-title">${M}</div>
1161
+ <div class="inspector-subsection-title">${j}</div>
1162
1162
  <div class="inspector-subsection-content">${k.join("")}</div>
1163
- </div>`:"",A=[T("Pulse",E),T("Swing",j),T("Move forever",z),T("Rotate (pivoting itself)",S),T("Rotate around",P)].filter(Boolean).join("");i.push(`
1163
+ </div>`:"",A=[T("Pulse",E),T("Swing",P),T("Move forever",M),T("Rotate (pivoting itself)",x),T("Rotate around",_)].filter(Boolean).join("");n.push(`
1164
1164
  <div class="inspector-subsection inspector-subsection-continuous">
1165
1165
  <div class="inspector-subsection-title">Continuous</div>
1166
1166
  <div class="inspector-subsection-content inspector-motion-continuous-groups">
1167
1167
  ${A}
1168
1168
  </div>
1169
1169
  </div>
1170
- `)}}else for(let h in r){let m=r[h],b=`${n}.${h}`,y=this.rendererRegistry.renderProperty(e,h,m,b);y&&i.push(y)}return i.length===0?"":`
1170
+ `)}}else for(let f in r){let m=r[f],b=`${i}.${f}`,y=this.rendererRegistry.renderProperty(e,f,m,b);y&&n.push(y)}return n.length===0?"":`
1171
1171
  <div class="inspector-section ${this.expandMotionOnNextRender?"":"collapsed"}" data-section="motion">
1172
1172
  <div class="inspector-section-header" data-section-toggle="motion">
1173
1173
  <span class="inspector-section-arrow">\u25BC</span>
@@ -1177,22 +1177,22 @@ ${h}
1177
1177
  </div>
1178
1178
  <div class="inspector-section-body" data-section-body="motion">
1179
1179
  ${c}
1180
- ${i.join("")}
1180
+ ${n.join("")}
1181
1181
  </div>
1182
1182
  </div>
1183
- `}attachEventListeners(){var w,E,j,z;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=Ko((S,P,R)=>{var T,A;this.updateManager.updateProperty(S,P,R),(A=(T=this.options)==null?void 0:T.onPropertyChange)==null||A.call(T,S,P,R)},300),n=S=>S?/(^|\.)logic(\.\d+)?\.id$/.test(S):!1;e.forEach(S=>{let P=T=>{var C,x;let A=T.target,M=A.dataset.propertyPath,k=A.dataset.objectId;if(M&&k){let I=A.value;if(A.type==="checkbox")I=A.checked;else if(A.type==="number"){if(I=parseFloat(A.value),isNaN(I))return}else if(A.dataset.json==="true")try{I=JSON.parse(A.value)}catch{return}A.type==="text"||A.type==="range"||A.tagName==="TEXTAREA"?t(k,M,I):(this.updateManager.updateProperty(k,M,I),(x=(C=this.options)==null?void 0:C.onPropertyChange)==null||x.call(C,k,M,I))}},R=S.dataset.propertyPath;n(R)?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",R),S.addEventListener("change",async T=>{var O;let A=T.target,M=A.dataset.propertyPath,k=A.dataset.objectId,C=A.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",C),!M||!k)return;await this.updateManager.updateProperty(k,M,C),console.log("[Inspector v1.0.0] Logic ID updated");let x=window,I=(O=x==null?void 0:x.__HANDLER_LOGIC_META)==null?void 0:O[C],L=this.getDefaultPropsForLogic(C,I);console.log("[Inspector v1.0.0] New logic default props:",L);let _=M.replace(/\.id$/,".props");await this.updateManager.updateProperty(k,_,L),console.log("[Inspector v1.0.0] Logic props updated to:",L),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(k)})):(S.addEventListener("change",P),(S.tagName==="INPUT"||S.tagName==="TEXTAREA")&&S.addEventListener("input",P))}),this.contentContainer.querySelectorAll("[data-action]").forEach(S=>{S.addEventListener("click",P=>{let R=P.target,T=R.dataset.action,A=R.dataset.path,M=R.dataset.object;T&&A&&M&&this.quickActions.handleAction(T,M,A)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(S=>{S.addEventListener("click",P=>{var A,M;let R=P.target,T=R.dataset.sectionToggle||((A=R.closest("[data-section-toggle]"))==null?void 0:A.getAttribute("data-section-toggle"));if(T){let k=(M=this.contentContainer)==null?void 0:M.querySelector(`[data-section="${T}"]`);k==null||k.classList.toggle("collapsed")}})}),this.contentContainer.querySelectorAll("[data-motion-preset]").forEach(S=>{S.addEventListener("click",async P=>{let T=P.currentTarget.dataset.motionPreset;!T||!this.selectedObjectId||await this.applyMotionPreset(this.selectedObjectId,T)})}),this.contentContainer.querySelectorAll("[data-motion-preview]").forEach(S=>{S.addEventListener("click",async()=>{this.selectedObjectId&&await this.previewMotionIntro(this.selectedObjectId)})});let l=this.contentContainer.querySelector("[data-motion-simple-toggle]");l==null||l.addEventListener("click",()=>{this.motionSimpleMode=!this.motionSimpleMode;try{localStorage.setItem("inspector:motionSimple",String(this.motionSimpleMode))}catch{}this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),this.contentContainer.querySelectorAll("[data-spawnpoints-add]").forEach(S=>{S.addEventListener("click",async P=>{let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath;if(!T||!A)return;let M=window.getEditableObjectConfig,k=M==null?void 0:M(T);if(!k)return;let C=this.updateManager.getNestedProperty(k,A),x=Array.isArray(C)?[...C]:[];x.push({x:0,y:0}),await this.updateManager.updateProperty(T,A,x),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-spawnpoints-remove]").forEach(S=>{S.addEventListener("click",async P=>{let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath,M=Number(R.dataset.index||"-1");if(!T||!A||M<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let x=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(x))return;let I=x.filter((L,_)=>_!==M);await this.updateManager.updateProperty(T,A,I),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-add]").forEach(S=>{S.addEventListener("click",async P=>{let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath;if(!T||!A)return;let M=window.getEditableObjectConfig,k=M==null?void 0:M(T);if(!k)return;let C=this.updateManager.getNestedProperty(k,A),x=Array.isArray(C)?[...C]:[];x.push({templateId:"",weight:1}),await this.updateManager.updateProperty(T,A,x),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-remove]").forEach(S=>{S.addEventListener("click",async P=>{var L;let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath,M=Number((L=R.dataset.index)!=null?L:-1);if(!T||!A||M<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let x=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(x))return;let I=x.filter((_,O)=>O!==M);await this.updateManager.updateProperty(T,A,I),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-logic-add]").forEach(S=>{S.addEventListener("click",async P=>{var H;let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath;if(!T||!A)return;let M=window.getEditableObjectConfig,k=M==null?void 0:M(T);if(!k)return;let C=this.updateManager.getNestedProperty(k,A),x;Array.isArray(C)?x=[...C]:C!=null?typeof C=="string"?x=[{id:C,props:{}}]:typeof C=="object"?x=[C]:x=[]:x=[];let I=this.getDefaultLogicId(),L=window,_=(H=L==null?void 0:L.__HANDLER_LOGIC_META)==null?void 0:H[I],O=this.getDefaultPropsForLogic(I,_);x.push({id:I,props:O}),console.log("[InspectorPanel] Adding logic to array:",{objectId:T,path:A,current:C,next:x}),await this.updateManager.updateProperty(T,A,x),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-logic-remove]").forEach(S=>{S.addEventListener("click",async P=>{var L;let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath,M=Number((L=R.dataset.index)!=null?L:-1);if(!T||!A||M<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let x=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(x))return;let I=x.filter((_,O)=>O!==M);await this.updateManager.updateProperty(T,A,I),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-logic-convert]").forEach(S=>{S.addEventListener("click",async P=>{var N,G;let R=P.target,T=R.dataset.objectId,A=R.dataset.propertyPath,M=Number((N=R.dataset.index)!=null?N:-1);if(!T||!A||M<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let x=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(x))return;let I=x[M];if(typeof I!="string")return;let L=window,_=(G=L==null?void 0:L.__HANDLER_LOGIC_META)==null?void 0:G[I],O=this.getDefaultPropsForLogic(I,_),H=[...x];H[M]={id:I,props:O},await this.updateManager.updateProperty(T,A,H),this.loadObject(T)})});let m=(w=this.root)==null?void 0:w.querySelector("[data-inspector-advanced]");m==null||m.addEventListener("click",()=>{this.showAdvanced=!this.showAdvanced,this.selectedObjectId&&this.loadObject(this.selectedObjectId)});let b=(E=this.root)==null?void 0:E.querySelector("[data-convert-toggle]");b==null||b.addEventListener("click",()=>{var P;let S=(P=this.root)==null?void 0:P.querySelector("[data-convert-menu]");S==null||S.classList.toggle("hidden")});let y=(j=this.contentContainer)==null?void 0:j.querySelector("[data-inspector-add-component-btn]"),v=(z=this.contentContainer)==null?void 0:z.querySelector("[data-inspector-component-select]");y==null||y.addEventListener("click",async()=>{let S=v.value;S&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,S)})}getMotionDefaults(){var n,i,a,r;let e=window.__editableConfig,t=e==null?void 0:e.schemas;return t instanceof Map?(i=(n=t.get("motion"))==null?void 0:n.defaults)!=null?i:{enabled:!0}:t&&typeof t=="object"?(r=(a=t.motion)==null?void 0:a.defaults)!=null?r:{enabled:!0}:{enabled:!0}}async applyMotionPreset(e,t){var l,c;let n=window.getEditableObjectConfig,i=n==null?void 0:n(e);if(!i)return;let a=this.getMotionDefaults(),r={...(l=i.motion)!=null?l:a},o={...(c=r.intro)!=null?c:{}};r.enabled=!0,o.enabled=!0,o.type=t,o.duration=typeof o.duration=="number"&&o.duration>0?o.duration:500,o.delay=typeof o.delay=="number"?o.delay:0,o.easing=typeof o.easing=="string"?o.easing:"easeOut",r.intro=o,await this.updateManager.updateProperty(e,"motion",r),this.expandMotionOnNextRender=!0,this.loadObject(e)}async previewMotionIntro(e){var o,l;let t=window.getEditableObjectConfig,n=t==null?void 0:t(e);if(!n)return;let i=this.getMotionDefaults(),a={...(o=n.motion)!=null?o:i},r={...(l=a.intro)!=null?l:{}};a.enabled=!0,r.enabled=!0,a.intro=r,await this.updateManager.updateProperty(e,"motion",{...a,intro:{...r,enabled:!1}}),await this.updateManager.updateProperty(e,"motion",{...a,intro:{...r,enabled:!0}}),this.loadObject(e)}async addComponent(e,t){console.log("[InspectorPanel] Adding component:",t,"to:",e);let n=window.getEditableObjectConfig,i=n==null?void 0:n(e);if(!i){console.error("[InspectorPanel] Failed to get config for:",e);return}if(t==="logic"){let c={id:"SwerveMove",props:this.getDefaultPropsForLogic("SwerveMove",null)};i[t]=c,await this.updateManager.updateProperty(e,t,c),this.loadObject(e),console.log("[InspectorPanel] Logic component added with default SwerveMove");return}t==="motion"&&(this.expandMotionOnNextRender=!0);let a=window.__editableConfig,r=a==null?void 0:a.schemas,o=null;r instanceof Map?o=r.get(t):r&&typeof r=="object"&&(o=r[t]),o||console.warn("[InspectorPanel] Schema not found for component:",t);let l=(o==null?void 0:o.defaults)||{enabled:!0};i[t]={...l},await this.updateManager.updateProperty(e,t,i[t]),this.loadObject(e),console.log("[InspectorPanel] Component added successfully")}isSectionMeaningful(e,t,n){var a,r;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((r=(a=n.render)==null?void 0:a.asset)==null?void 0:r.type)==="image")return!1;if(e==="interaction")return t.clickable===!0||t.draggable===!0;if(t.enabled===!0||t.active===!0||t.visible===!0)return!0;if(e==="ui")return!!(t.text||t.font||t.fontSize);let i=Object.keys(t);return i.length===0||i.length===1&&i[0]==="enabled"&&t.enabled===!1?!1:["audio","effects","physics","motion","gameplay"].includes(e)?t.enabled===!0:!0}showError(e){this.contentContainer&&(this.contentContainer.innerHTML=`
1183
+ `}attachEventListeners(){var w,E,P,M;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=tl((x,_,O)=>{var T,A;this.updateManager.updateProperty(x,_,O),(A=(T=this.options)==null?void 0:T.onPropertyChange)==null||A.call(T,x,_,O)},300),i=x=>x?/(^|\.)logic(\.\d+)?\.id$/.test(x):!1;e.forEach(x=>{let _=T=>{var C,S;let A=T.target,j=A.dataset.propertyPath,k=A.dataset.objectId;if(j&&k){let I=A.value;if(A.type==="checkbox")I=A.checked;else if(A.type==="number"){if(I=parseFloat(A.value),isNaN(I))return}else if(A.dataset.json==="true")try{I=JSON.parse(A.value)}catch{return}A.type==="text"||A.type==="range"||A.tagName==="TEXTAREA"?t(k,j,I):(this.updateManager.updateProperty(k,j,I),(S=(C=this.options)==null?void 0:C.onPropertyChange)==null||S.call(C,k,j,I))}},O=x.dataset.propertyPath;i(O)?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",O),x.addEventListener("change",async T=>{var z;let A=T.target,j=A.dataset.propertyPath,k=A.dataset.objectId,C=A.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",C),!j||!k)return;await this.updateManager.updateProperty(k,j,C),console.log("[Inspector v1.0.0] Logic ID updated");let S=window,I=(z=S==null?void 0:S.__HANDLER_LOGIC_META)==null?void 0:z[C],L=this.getDefaultPropsForLogic(C,I);console.log("[Inspector v1.0.0] New logic default props:",L);let R=j.replace(/\.id$/,".props");await this.updateManager.updateProperty(k,R,L),console.log("[Inspector v1.0.0] Logic props updated to:",L),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(k)})):(x.addEventListener("change",_),(x.tagName==="INPUT"||x.tagName==="TEXTAREA")&&x.addEventListener("input",_))}),this.contentContainer.querySelectorAll("[data-action]").forEach(x=>{x.addEventListener("click",_=>{let O=_.target,T=O.dataset.action,A=O.dataset.path,j=O.dataset.object;T&&A&&j&&this.quickActions.handleAction(T,j,A)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(x=>{x.addEventListener("click",_=>{var A,j;let O=_.target,T=O.dataset.sectionToggle||((A=O.closest("[data-section-toggle]"))==null?void 0:A.getAttribute("data-section-toggle"));if(T){let k=(j=this.contentContainer)==null?void 0:j.querySelector(`[data-section="${T}"]`);k==null||k.classList.toggle("collapsed")}})}),this.contentContainer.querySelectorAll("[data-motion-preset]").forEach(x=>{x.addEventListener("click",async _=>{let T=_.currentTarget.dataset.motionPreset;!T||!this.selectedObjectId||await this.applyMotionPreset(this.selectedObjectId,T)})}),this.contentContainer.querySelectorAll("[data-motion-preview]").forEach(x=>{x.addEventListener("click",async()=>{this.selectedObjectId&&await this.previewMotionIntro(this.selectedObjectId)})});let l=this.contentContainer.querySelector("[data-motion-simple-toggle]");l==null||l.addEventListener("click",()=>{this.motionSimpleMode=!this.motionSimpleMode;try{localStorage.setItem("inspector:motionSimple",String(this.motionSimpleMode))}catch{}this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),this.contentContainer.querySelectorAll("[data-spawnpoints-add]").forEach(x=>{x.addEventListener("click",async _=>{let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath;if(!T||!A)return;let j=window.getEditableObjectConfig,k=j==null?void 0:j(T);if(!k)return;let C=this.updateManager.getNestedProperty(k,A),S=Array.isArray(C)?[...C]:[];S.push({x:0,y:0}),await this.updateManager.updateProperty(T,A,S),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-spawnpoints-remove]").forEach(x=>{x.addEventListener("click",async _=>{let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath,j=Number(O.dataset.index||"-1");if(!T||!A||j<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let S=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(S))return;let I=S.filter((L,R)=>R!==j);await this.updateManager.updateProperty(T,A,I),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-add]").forEach(x=>{x.addEventListener("click",async _=>{let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath;if(!T||!A)return;let j=window.getEditableObjectConfig,k=j==null?void 0:j(T);if(!k)return;let C=this.updateManager.getNestedProperty(k,A),S=Array.isArray(C)?[...C]:[];S.push({templateId:"",weight:1}),await this.updateManager.updateProperty(T,A,S),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-remove]").forEach(x=>{x.addEventListener("click",async _=>{var L;let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath,j=Number((L=O.dataset.index)!=null?L:-1);if(!T||!A||j<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let S=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(S))return;let I=S.filter((R,z)=>z!==j);await this.updateManager.updateProperty(T,A,I),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-logic-add]").forEach(x=>{x.addEventListener("click",async _=>{var N;let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath;if(!T||!A)return;let j=window.getEditableObjectConfig,k=j==null?void 0:j(T);if(!k)return;let C=this.updateManager.getNestedProperty(k,A),S;Array.isArray(C)?S=[...C]:C!=null?typeof C=="string"?S=[{id:C,props:{}}]:typeof C=="object"?S=[C]:S=[]:S=[];let I=this.getDefaultLogicId(),L=window,R=(N=L==null?void 0:L.__HANDLER_LOGIC_META)==null?void 0:N[I],z=this.getDefaultPropsForLogic(I,R);S.push({id:I,props:z}),console.log("[InspectorPanel] Adding logic to array:",{objectId:T,path:A,current:C,next:S}),await this.updateManager.updateProperty(T,A,S),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-logic-remove]").forEach(x=>{x.addEventListener("click",async _=>{var L;let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath,j=Number((L=O.dataset.index)!=null?L:-1);if(!T||!A||j<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let S=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(S))return;let I=S.filter((R,z)=>z!==j);await this.updateManager.updateProperty(T,A,I),this.loadObject(T)})}),this.contentContainer.querySelectorAll("[data-logic-convert]").forEach(x=>{x.addEventListener("click",async _=>{var F,q;let O=_.target,T=O.dataset.objectId,A=O.dataset.propertyPath,j=Number((F=O.dataset.index)!=null?F:-1);if(!T||!A||j<0)return;let k=window.getEditableObjectConfig,C=k==null?void 0:k(T);if(!C)return;let S=this.updateManager.getNestedProperty(C,A);if(!Array.isArray(S))return;let I=S[j];if(typeof I!="string")return;let L=window,R=(q=L==null?void 0:L.__HANDLER_LOGIC_META)==null?void 0:q[I],z=this.getDefaultPropsForLogic(I,R),N=[...S];N[j]={id:I,props:z},await this.updateManager.updateProperty(T,A,N),this.loadObject(T)})});let m=(w=this.root)==null?void 0:w.querySelector("[data-inspector-advanced]");m==null||m.addEventListener("click",()=>{this.showAdvanced=!this.showAdvanced,this.selectedObjectId&&this.loadObject(this.selectedObjectId)});let b=(E=this.root)==null?void 0:E.querySelector("[data-convert-toggle]");b==null||b.addEventListener("click",()=>{var _;let x=(_=this.root)==null?void 0:_.querySelector("[data-convert-menu]");x==null||x.classList.toggle("hidden")});let y=(P=this.contentContainer)==null?void 0:P.querySelector("[data-inspector-add-component-btn]"),v=(M=this.contentContainer)==null?void 0:M.querySelector("[data-inspector-component-select]");y==null||y.addEventListener("click",async()=>{let x=v.value;x&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,x)})}getMotionDefaults(){var i,n,a,r;let e=window.__editableConfig,t=e==null?void 0:e.schemas;return t instanceof Map?(n=(i=t.get("motion"))==null?void 0:i.defaults)!=null?n:{enabled:!0}:t&&typeof t=="object"?(r=(a=t.motion)==null?void 0:a.defaults)!=null?r:{enabled:!0}:{enabled:!0}}async applyMotionPreset(e,t){var l,c;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n)return;let a=this.getMotionDefaults(),r={...(l=n.motion)!=null?l:a},o={...(c=r.intro)!=null?c:{}};r.enabled=!0,o.enabled=!0,o.type=t,o.duration=typeof o.duration=="number"&&o.duration>0?o.duration:500,o.delay=typeof o.delay=="number"?o.delay:0,o.easing=typeof o.easing=="string"?o.easing:"easeOut",r.intro=o,await this.updateManager.updateProperty(e,"motion",r),this.expandMotionOnNextRender=!0,this.loadObject(e)}async previewMotionIntro(e){var o,l;let t=window.getEditableObjectConfig,i=t==null?void 0:t(e);if(!i)return;let n=this.getMotionDefaults(),a={...(o=i.motion)!=null?o:n},r={...(l=a.intro)!=null?l:{}};a.enabled=!0,r.enabled=!0,a.intro=r,await this.updateManager.updateProperty(e,"motion",{...a,intro:{...r,enabled:!1}}),await this.updateManager.updateProperty(e,"motion",{...a,intro:{...r,enabled:!0}}),this.loadObject(e)}async addComponent(e,t){console.log("[InspectorPanel] Adding component:",t,"to:",e);let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n){console.error("[InspectorPanel] Failed to get config for:",e);return}if(t==="logic"){let c={id:"SwerveMove",props:this.getDefaultPropsForLogic("SwerveMove",null)};n[t]=c,await this.updateManager.updateProperty(e,t,c),this.loadObject(e),console.log("[InspectorPanel] Logic component added with default SwerveMove");return}t==="motion"&&(this.expandMotionOnNextRender=!0);let a=window.__editableConfig,r=a==null?void 0:a.schemas,o=null;r instanceof Map?o=r.get(t):r&&typeof r=="object"&&(o=r[t]),o||console.warn("[InspectorPanel] Schema not found for component:",t);let l=(o==null?void 0:o.defaults)||{enabled:!0};n[t]={...l},await this.updateManager.updateProperty(e,t,n[t]),this.loadObject(e),console.log("[InspectorPanel] Component added successfully")}isSectionMeaningful(e,t,i){var a,r;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((r=(a=i.render)==null?void 0:a.asset)==null?void 0:r.type)==="image")return!1;if(e==="interaction")return t.clickable===!0||t.draggable===!0;if(t.enabled===!0||t.active===!0||t.visible===!0)return!0;if(e==="ui")return!!(t.text||t.font||t.fontSize);let n=Object.keys(t);return n.length===0||n.length===1&&n[0]==="enabled"&&t.enabled===!1?!1:["audio","effects","physics","motion","gameplay"].includes(e)?t.enabled===!0:!0}showError(e){this.contentContainer&&(this.contentContainer.innerHTML=`
1184
1184
  <div class="inspector-empty">
1185
1185
  <span class="inspector-empty-icon">\u26A0\uFE0F</span>
1186
1186
  <span class="inspector-empty-text">${e}</span>
1187
1187
  </div>
1188
- `)}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}getDefaultLogicId(){try{let e=window,t=Array.isArray(e==null?void 0:e.__HANDLER_LOGIC_OPTIONS)?e.__HANDLER_LOGIC_OPTIONS:[],n=["SwerveMove","DragSnap","JoystickMove","DragToWin"],i=[...t,...n].map(a=>String(a)).filter(a=>a.trim().length>0);return i.length?i[0]:"SwerveMove"}catch{return"SwerveMove"}}getDefaultPropsForLogic(e,t){return{DragToWin:{targetDrags:3},DragSnap:{targetId:"",snapRadius:100,snapDuration:.5,returnOnMiss:!0,returnDuration:.3,ease:"power2.out"},SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},JoystickMove:{speed:200,zone:"bottom-center",offsetX:0,offsetY:-50,inputId:""},Tap:{maxTapDuration:300,maxTapDistance:10,tapCount:1,tapTimeout:500},Swipe:{inputId:"",direction:"any",minDistance:50,maxDuration:1e3},Hold:{holdDuration:500,visualFeedback:!0,feedbackColor:16777215},Collectable:{targetId:"",collectRadius:50,particleEffect:"",autoDestroy:!0,collectSound:""},Spawner:{templateId:"",spawnTemplates:[],spawnPattern:"continuous",spawnRate:1e3,poolSize:20,positionSource:"spawner",targetId:"",targetOffset:{x:0,y:0},customPosition:{x:0,y:0},randomBounds:{x:[-100,100],y:[-100,100]},spawnPoints:[],spawnPointMode:"cycle",movementMode:"velocity",velocity:{x:0,y:-300},lifetime:2e3},Damageable:{hitTemplateId:"",hitRadius:50,hp:1,invulnMs:150,flashAlpha:.3,flashDurationMs:100,hitScale:1,hitScaleDurationMs:120,knockback:{x:0,y:0},hpLabelId:"",autoDestroy:!0,hitEffect:"",destroyEffect:"",particleScale:1,particleColor:"",destroySound:"",hitEvent:"",destroyEvent:"",hitPopupText:"",hitPopupColor:"#ffffff",hitPopupFontSize:20,hitPopupDurationMs:600,hitPopupOffset:{x:0,y:-20},hitPopupRise:30,hitPopupTemplateId:""}}[e]||{}}getSectionIcon(e){return{identity:"\u{1F194}",transform:"\u{1F4D0}",render:"\u{1F3A8}",ui:"\u{1F4AC}",logic:"\u{1F3AE}",gameplay:"\u{1F3AE}",interaction:"\u{1F446}",audio:"\u{1F50A}",effects:"\u2728",motion:"\u{1F3AC}"}[e]||"\u{1F4E6}"}clear(){this.selectedObjectId=null,this.contentContainer&&(this.contentContainer.innerHTML=`
1188
+ `)}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}getDefaultLogicId(){try{let e=window,t=Array.isArray(e==null?void 0:e.__HANDLER_LOGIC_OPTIONS)?e.__HANDLER_LOGIC_OPTIONS:[],i=["SwerveMove","DragSnap","JoystickMove","DragToWin"],n=[...t,...i].map(a=>String(a)).filter(a=>a.trim().length>0);return n.length?n[0]:"SwerveMove"}catch{return"SwerveMove"}}getDefaultPropsForLogic(e,t){return{DragToWin:{targetDrags:3},DragSnap:{targetId:"",snapRadius:100,snapDuration:.5,returnOnMiss:!0,returnDuration:.3,ease:"power2.out"},SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},JoystickMove:{speed:200,zone:"bottom-center",offsetX:0,offsetY:-50,inputId:""},Tap:{maxTapDuration:300,maxTapDistance:10,tapCount:1,tapTimeout:500},Swipe:{inputId:"",direction:"any",minDistance:50,maxDuration:1e3},Hold:{holdDuration:500,visualFeedback:!0,feedbackColor:16777215},Collectable:{targetId:"",collectRadius:50,particleEffect:"",autoDestroy:!0,collectSound:""},Spawner:{templateId:"",spawnTemplates:[],spawnPattern:"continuous",spawnRate:1e3,poolSize:20,positionSource:"spawner",targetId:"",targetOffset:{x:0,y:0},customPosition:{x:0,y:0},randomBounds:{x:[-100,100],y:[-100,100]},spawnPoints:[],spawnPointMode:"cycle",movementMode:"velocity",velocity:{x:0,y:-300},lifetime:2e3},Damageable:{hitTemplateId:"",hitRadius:50,hp:1,invulnMs:150,flashAlpha:.3,flashDurationMs:100,hitScale:1,hitScaleDurationMs:120,knockback:{x:0,y:0},hpLabelId:"",autoDestroy:!0,hitEffect:"",destroyEffect:"",particleScale:1,particleColor:"",destroySound:"",hitEvent:"",destroyEvent:"",hitPopupText:"",hitPopupColor:"#ffffff",hitPopupFontSize:20,hitPopupDurationMs:600,hitPopupOffset:{x:0,y:-20},hitPopupRise:30,hitPopupTemplateId:""}}[e]||{}}getSectionIcon(e){return{identity:"\u{1F194}",transform:"\u{1F4D0}",render:"\u{1F3A8}",ui:"\u{1F4AC}",logic:"\u{1F3AE}",gameplay:"\u{1F3AE}",interaction:"\u{1F446}",audio:"\u{1F50A}",effects:"\u2728",motion:"\u{1F3AC}"}[e]||"\u{1F4E6}"}clear(){this.selectedObjectId=null,this.contentContainer&&(this.contentContainer.innerHTML=`
1189
1189
  <div class="inspector-empty">
1190
1190
  <span class="inspector-empty-icon">\u{1F3AF}</span>
1191
1191
  <span class="inspector-empty-text">Select an object to inspect</span>
1192
1192
  </div>
1193
- `)}};var tr=Ze(require("jszip"),1);function Ki(s){return new Promise((e,t)=>{let n=new FileReader;n.onerror=()=>t(new Error("FileReader failed")),n.onload=()=>e(String(n.result||"")),n.readAsDataURL(s)})}function Bs(s){var i;let[e,t]=s.split(","),n=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(i=n==null?void 0:n[1])!=null?i:"image/png"}}async function Us(s){return await new Promise(e=>{let t=new Image;t.onload=()=>e({width:t.naturalWidth||t.width,height:t.naturalHeight||t.height}),t.onerror=()=>e(null),t.src=s})}async function Un(s){var e,t;try{console.log("[ImageUtils] Fetching image data from URL:",s);let n=await fetch(s);if(!n.ok)return console.warn("[ImageUtils] Fetch failed with status:",n.status,s),null;let i=await n.blob();console.log("[ImageUtils] Blob received, size:",i.size,"type:",i.type);let a=await Ki(i),r=await Us(a),o=Bs(a);return console.log("[ImageUtils] Success resolution:",r==null?void 0:r.width,"x",r==null?void 0:r.height,"mime:",o.mimeType),{base64:o.base64,mimeType:o.mimeType,dataUrl:a,width:(e=r==null?void 0:r.width)!=null?e:0,height:(t=r==null?void 0:r.height)!=null?t:0}}catch(n){return console.error("[ImageUtils] Error fetching image data:",n),null}}async function Pe(s){var e,t;try{let n=await Ki(s),i=await Us(n),a=Bs(n);return{base64:a.base64,mimeType:a.mimeType,dataUrl:n,width:(e=i==null?void 0:i.width)!=null?e:0,height:(t=i==null?void 0:i.height)!=null?t:0}}catch{return null}}function Xi(s){return Ki(s).then(e=>e).catch(()=>null)}function Ji(s,e){var t;try{let[n,i]=s.split(","),a=n.match(/data:(.*?);base64/),r=(t=a==null?void 0:a[1])!=null?t:"image/png",o=atob(i),l=new Uint8Array(o.length);for(let c=0;c<o.length;c++)l[c]=o.charCodeAt(c);return new File([l],e,{type:r})}catch{return null}}async function at(s,e=30){try{console.log("[ImageUtils] Removing background color...");let t=await new Promise((p,u)=>{let g=new Image;g.onload=()=>p(g),g.onerror=()=>u(new Error("Failed to load image")),g.src=s}),n=document.createElement("canvas");n.width=t.width,n.height=t.height;let i=n.getContext("2d");if(!i)return console.error("[ImageUtils] Failed to get canvas context"),s;i.drawImage(t,0,0);let a=i.getImageData(0,0,n.width,n.height),r=a.data,l=[{name:"top-left",offset:0},{name:"top-right",offset:(n.width-1)*4},{name:"bottom-left",offset:(n.height-1)*n.width*4},{name:"bottom-right",offset:((n.height-1)*n.width+(n.width-1))*4}].map(p=>({r:r[p.offset],g:r[p.offset+1],b:r[p.offset+2]})),c=0;for(let p=0;p<r.length;p+=4){let u=r[p],g=r[p+1],f=r[p+2],h=!1;for(let m of l)if(Math.sqrt(Math.pow(u-m.r,2)+Math.pow(g-m.g,2)+Math.pow(f-m.b,2))<e){h=!0;break}h&&(r[p+3]=0,c++)}return console.log(`[ImageUtils] Removed background from ${c} pixels (4-corner sampling, tolerance: ${e})`),i.putImageData(a,0,0),n.toDataURL("image/png")}catch(t){return console.error("[ImageUtils] Error removing background:",t),s}}function Gs(s,e){if(!s||!e)return"1:1";let t=s/e;return t>1.3?"16:9":t<.77?"9:16":"1:1"}function Ee(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}function Y(s){return typeof s=="string"?s:void 0}function qs(s){return s.toLowerCase().endsWith(".png")?s.slice(0,-4):s}function Xo(s){var n,i,a;let e=(n=Y(s.id))!=null?n:Y(s.name);if(e)return e;let t=(i=Y(s.file))!=null?i:Y(s.asset);return t?qs((a=t.split("/").pop())!=null?a:t):void 0}function Jo(s,e,t){var n,i,a;if(typeof e=="string")return{id:s,file:e,role:t};if(Ee(e)){let r=(n=Y(e.file))!=null?n:Y(e.asset);return r?{id:(i=Y(e.id))!=null?i:s,file:r,role:(a=Y(e.role))!=null?a:t,dataUrl:Y(e.dataUrl),layout:e.layout}:null}return null}function Zi(s,e){var t,n,i;if(!s)return[];if(Array.isArray(s)){let a=[];for(let r of s){if(typeof r=="string"){let o=qs((t=r.split("/").pop())!=null?t:r);a.push({id:o,file:r,role:e});continue}if(Ee(r)){let o=Xo(r),l=(n=Y(r.file))!=null?n:Y(r.asset);if(!o||!l)continue;a.push({id:o,file:l,role:(i=Y(r.role))!=null?i:e,dataUrl:Y(r.dataUrl),layout:r.layout})}}return a}if(Ee(s)){let a=[];for(let[r,o]of Object.entries(s)){let l=Jo(r,o,e);l&&a.push(l)}return a}return[]}function Zo(s){var e,t;return(t=(e=Y(s.brand_name))!=null?e:Y(s.brandName))!=null?t:Y(s.name)}function Qo(s){if(Ee(s.brand_dna)&&Ee(s.brand_dna.colors))return s.brand_dna;if(Ee(s.colors)){let e={colors:s.colors};return typeof s.style=="string"&&(e.style=s.style),Ee(s.fonts)&&(e.fonts=s.fonts),e}}function el(s){var t;let e=new Map;for(let n of s){let i=e.get(n.id);if(!i){e.set(n.id,n);continue}e.set(n.id,{...i,...n,file:n.file||i.file,role:n.role||i.role,dataUrl:n.dataUrl||i.dataUrl,layout:(t=n.layout)!=null?t:i.layout})}return Array.from(e.values())}function Qi(s,e={}){var r,o,l;let t=s.filter(Ee),n=(o=(r=t.map(Zo).find(Boolean))!=null?r:e.defaultBrandName)!=null?o:"Imported Brand",i=(l=t.map(Qo).find(Boolean))!=null?l:{colors:{}},a=[];for(let c of t)"layers"in c&&a.push(...Zi(c.layers,"visual element")),"assets"in c&&a.push(...Zi(c.assets,"visual element")),Ee(c.endgame)&&"assets"in c.endgame&&a.push(...Zi(c.endgame.assets,"endgame"));return{version:"1.0",brand_name:n,brand_dna:i,assets:el(a)}}var Vs=require("@google/genai");async function Gn(s,e,t=[],n={}){var i,a,r,o,l,c,d;try{if(!(s!=null&&s.trim()))throw new Error("Gemini API key is required");if(!(e!=null&&e.trim()))throw new Error("Prompt is required");for(let b=0;b<t.length;b++){let y=t[b];if(!y.base64||!y.mimeType)throw new Error(`Image ${b+1} is missing required data`);if(y.base64.length<1e3&&console.warn(`Image ${b+1} data appears very small, may be corrupted`),!y.mimeType.startsWith("image/"))throw new Error(`Image ${b+1} has invalid MIME type: ${y.mimeType}`)}let p=new Vs.GoogleGenAI({apiKey:s}),u="gemini-2.5-flash",g=[e];t.length>0&&t.forEach((b,y)=>{g.push({inlineData:{data:b.base64,mimeType:b.mimeType}}),console.log(`[Gemini] Added image ${y+1}: ${b.mimeType}, size: ${Math.round(b.base64.length/1024)}KB`)}),console.log(`[Gemini] Making request with ${t.length} images and prompt length: ${e.length}`);let f=await p.models.generateContent({model:u,contents:g}),h="",m=(r=(a=(i=f.candidates)==null?void 0:i[0])==null?void 0:a.content)==null?void 0:r.parts;if(m)for(let b of m)b.text&&(h+=b.text);if(!h.trim())throw new Error("Empty response from Gemini API");return console.log(`[Gemini] Response received, length: ${h.length}`),h}catch(p){throw console.error("[Gemini] API error:",p),(o=p.message)!=null&&o.includes("Unable to process input image")?new Error("Unable to process the uploaded image. Please ensure it's a valid PNG, JPG, or JPEG file under 10MB and not corrupted."):(l=p.message)!=null&&l.includes("API_KEY_INVALID")?new Error("Invalid Gemini API key. Please check your API key configuration."):(c=p.message)!=null&&c.includes("QUOTA_EXCEEDED")?new Error("Gemini API quota exceeded. Please try again later or check your billing."):(d=p.message)!=null&&d.includes("SAFETY")?new Error("Content was flagged by Gemini safety filters. Please try with different images."):p}}var Ws=require("@google/genai");async function st(s,e,t=[],n={}){try{console.info("[GEMINI-REAL-SDK] Initializing GoogleGenAI...");let i=new Ws.GoogleGenAI({apiKey:s}),a=[{text:e}];t.length>0&&t.forEach((o,l)=>{console.info(`[GEMINI-REAL-SDK] Adding image part ${l}`),a.push({inlineData:{mimeType:o.mimeType,data:o.base64}})}),console.info("[GEMINI-REAL-SDK] Calling generateContent with model: gemini-2.5-flash-image");let r=await i.models.generateContent({model:"gemini-2.5-flash-image",contents:a});if(console.info("[GEMINI-REAL-SDK] Received response from model"),!r.candidates||!r.candidates[0]||!r.candidates[0].content||!r.candidates[0].content.parts)throw new Error("Gemini 2.5 Flash Image returned invalid response structure.");for(let o of r.candidates[0].content.parts)if(o.text)console.log(o.text);else if(o.inlineData){let l=o.inlineData.data,c=o.inlineData.mimeType||"image/png";return console.info("[GEMINI-REAL-SDK] Found inline image data in response"),`data:${c};base64,${l}`}throw new Error("Gemini 2.5 Flash Image returned no image data.")}catch(i){throw console.error("[GEMINI-REAL-SDK] Error in generateImageWithGemini25Flash:",JSON.stringify(i,Object.getOwnPropertyNames(i),2)),i}}function Ys(s){let e=s.brandAssets.map(a=>{let r=`- ${a.id}: ${a.role}`;return a.layout&&(r+=` [pos: ${a.layout.x.toFixed(0)},${a.layout.y.toFixed(0)}, size: ${a.layout.w.toFixed(0)}x${a.layout.h.toFixed(0)}, z: ${a.layout.z}, opacity: ${a.layout.opacity}]`),r}).join(`
1194
- `)||"None",t=s.brandDna?`Colors: ${JSON.stringify(s.brandDna.colors)}, Style: ${s.brandDna.style||"not specified"}`:"Not provided",n=s.gameObjects.map(a=>typeof a=="string"?`- id: ${a}`:`- id: ${a.id}${a.category?`, category: ${a.category}`:""}${a.type?`, type: ${a.type}`:""}`).join(`
1195
- `),i="";if(s.brandConfig){let a=s.brandConfig,r=[];a.splash&&r.push(`SPLASH: title="${a.splash.title||""}", subtitle="${a.splash.subtitle||""}", button="${a.splash.button_label||""}"`),a.endgame&&r.push(`ENDGAME: title="${a.endgame.title||""}", subtitle="${a.endgame.subtitle||""}", cta="${a.endgame.cta_label||""}"`),a.tutorial&&r.push(`TUTORIAL: text="${a.tutorial.label_text||""}", helper="${a.tutorial.helper_text||""}"`),r.length>0&&(i=`
1193
+ `)}};var ur=tt(require("jszip"),1);function ia(s){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(s)})}function Ws(s){var n;let[e,t]=s.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(n=i==null?void 0:i[1])!=null?n:"image/png"}}async function Ys(s){return await new Promise(e=>{let t=new Image;t.onload=()=>e({width:t.naturalWidth||t.width,height:t.naturalHeight||t.height}),t.onerror=()=>e(null),t.src=s})}async function qi(s){var e,t;try{console.log("[ImageUtils] Fetching image data from URL:",s);let i=await fetch(s);if(!i.ok)return console.warn("[ImageUtils] Fetch failed with status:",i.status,s),null;let n=await i.blob();console.log("[ImageUtils] Blob received, size:",n.size,"type:",n.type);let a=await ia(n),r=await Ys(a),o=Ws(a);return console.log("[ImageUtils] Success resolution:",r==null?void 0:r.width,"x",r==null?void 0:r.height,"mime:",o.mimeType),{base64:o.base64,mimeType:o.mimeType,dataUrl:a,width:(e=r==null?void 0:r.width)!=null?e:0,height:(t=r==null?void 0:r.height)!=null?t:0}}catch(i){return console.error("[ImageUtils] Error fetching image data:",i),null}}async function Oe(s){var e,t;try{let i=await ia(s),n=await Ys(i),a=Ws(i);return{base64:a.base64,mimeType:a.mimeType,dataUrl:i,width:(e=n==null?void 0:n.width)!=null?e:0,height:(t=n==null?void 0:n.height)!=null?t:0}}catch{return null}}function na(s){return ia(s).then(e=>e).catch(()=>null)}function aa(s,e){var t;try{let[i,n]=s.split(","),a=i.match(/data:(.*?);base64/),r=(t=a==null?void 0:a[1])!=null?t:"image/png",o=atob(n),l=new Uint8Array(o.length);for(let c=0;c<o.length;c++)l[c]=o.charCodeAt(c);return new File([l],e,{type:r})}catch{return null}}async function lt(s,e=30){try{console.log("[ImageUtils] Removing background color...");let t=await new Promise((p,u)=>{let g=new Image;g.onload=()=>p(g),g.onerror=()=>u(new Error("Failed to load image")),g.src=s}),i=document.createElement("canvas");i.width=t.width,i.height=t.height;let n=i.getContext("2d");if(!n)return console.error("[ImageUtils] Failed to get canvas context"),s;n.drawImage(t,0,0);let a=n.getImageData(0,0,i.width,i.height),r=a.data,l=[{name:"top-left",offset:0},{name:"top-right",offset:(i.width-1)*4},{name:"bottom-left",offset:(i.height-1)*i.width*4},{name:"bottom-right",offset:((i.height-1)*i.width+(i.width-1))*4}].map(p=>({r:r[p.offset],g:r[p.offset+1],b:r[p.offset+2]})),c=0;for(let p=0;p<r.length;p+=4){let u=r[p],g=r[p+1],h=r[p+2],f=!1;for(let m of l)if(Math.sqrt(Math.pow(u-m.r,2)+Math.pow(g-m.g,2)+Math.pow(h-m.b,2))<e){f=!0;break}f&&(r[p+3]=0,c++)}return console.log(`[ImageUtils] Removed background from ${c} pixels (4-corner sampling, tolerance: ${e})`),n.putImageData(a,0,0),i.toDataURL("image/png")}catch(t){return console.error("[ImageUtils] Error removing background:",t),s}}function Ks(s,e){if(!s||!e)return"1:1";let t=s/e;return t>1.3?"16:9":t<.77?"9:16":"1:1"}function Ae(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}function X(s){return typeof s=="string"?s:void 0}function Xs(s){return s.toLowerCase().endsWith(".png")?s.slice(0,-4):s}function il(s){var i,n,a;let e=(i=X(s.id))!=null?i:X(s.name);if(e)return e;let t=(n=X(s.file))!=null?n:X(s.asset);return t?Xs((a=t.split("/").pop())!=null?a:t):void 0}function nl(s,e,t){var i,n,a;if(typeof e=="string")return{id:s,file:e,role:t};if(Ae(e)){let r=(i=X(e.file))!=null?i:X(e.asset);return r?{id:(n=X(e.id))!=null?n:s,file:r,role:(a=X(e.role))!=null?a:t,dataUrl:X(e.dataUrl),layout:e.layout}:null}return null}function sa(s,e){var t,i,n;if(!s)return[];if(Array.isArray(s)){let a=[];for(let r of s){if(typeof r=="string"){let o=Xs((t=r.split("/").pop())!=null?t:r);a.push({id:o,file:r,role:e});continue}if(Ae(r)){let o=il(r),l=(i=X(r.file))!=null?i:X(r.asset);if(!o||!l)continue;a.push({id:o,file:l,role:(n=X(r.role))!=null?n:e,dataUrl:X(r.dataUrl),layout:r.layout})}}return a}if(Ae(s)){let a=[];for(let[r,o]of Object.entries(s)){let l=nl(r,o,e);l&&a.push(l)}return a}return[]}function al(s){var e,t;return(t=(e=X(s.brand_name))!=null?e:X(s.brandName))!=null?t:X(s.name)}function sl(s){if(Ae(s.brand_dna)&&Ae(s.brand_dna.colors))return s.brand_dna;if(Ae(s.colors)){let e={colors:s.colors};return typeof s.style=="string"&&(e.style=s.style),Ae(s.fonts)&&(e.fonts=s.fonts),e}}function rl(s){var t;let e=new Map;for(let i of s){let n=e.get(i.id);if(!n){e.set(i.id,i);continue}e.set(i.id,{...n,...i,file:i.file||n.file,role:i.role||n.role,dataUrl:i.dataUrl||n.dataUrl,layout:(t=i.layout)!=null?t:n.layout})}return Array.from(e.values())}function ra(s,e={}){var r,o,l;let t=s.filter(Ae),i=(o=(r=t.map(al).find(Boolean))!=null?r:e.defaultBrandName)!=null?o:"Imported Brand",n=(l=t.map(sl).find(Boolean))!=null?l:{colors:{}},a=[];for(let c of t)"layers"in c&&a.push(...sa(c.layers,"visual element")),"assets"in c&&a.push(...sa(c.assets,"visual element")),Ae(c.endgame)&&"assets"in c.endgame&&a.push(...sa(c.endgame.assets,"endgame"));return{version:"1.0",brand_name:i,brand_dna:n,assets:rl(a)}}var Js=require("@google/genai");async function Vi(s,e,t=[],i={}){var n,a,r,o,l,c,d;try{if(!(s!=null&&s.trim()))throw new Error("Gemini API key is required");if(!(e!=null&&e.trim()))throw new Error("Prompt is required");for(let b=0;b<t.length;b++){let y=t[b];if(!y.base64||!y.mimeType)throw new Error(`Image ${b+1} is missing required data`);if(y.base64.length<1e3&&console.warn(`Image ${b+1} data appears very small, may be corrupted`),!y.mimeType.startsWith("image/"))throw new Error(`Image ${b+1} has invalid MIME type: ${y.mimeType}`)}let p=new Js.GoogleGenAI({apiKey:s}),u="gemini-2.5-flash",g=[e];t.length>0&&t.forEach((b,y)=>{g.push({inlineData:{data:b.base64,mimeType:b.mimeType}}),console.log(`[Gemini] Added image ${y+1}: ${b.mimeType}, size: ${Math.round(b.base64.length/1024)}KB`)}),console.log(`[Gemini] Making request with ${t.length} images and prompt length: ${e.length}`);let h=await p.models.generateContent({model:u,contents:g}),f="",m=(r=(a=(n=h.candidates)==null?void 0:n[0])==null?void 0:a.content)==null?void 0:r.parts;if(m)for(let b of m)b.text&&(f+=b.text);if(!f.trim())throw new Error("Empty response from Gemini API");return console.log(`[Gemini] Response received, length: ${f.length}`),f}catch(p){throw console.error("[Gemini] API error:",p),(o=p.message)!=null&&o.includes("Unable to process input image")?new Error("Unable to process the uploaded image. Please ensure it's a valid PNG, JPG, or JPEG file under 10MB and not corrupted."):(l=p.message)!=null&&l.includes("API_KEY_INVALID")?new Error("Invalid Gemini API key. Please check your API key configuration."):(c=p.message)!=null&&c.includes("QUOTA_EXCEEDED")?new Error("Gemini API quota exceeded. Please try again later or check your billing."):(d=p.message)!=null&&d.includes("SAFETY")?new Error("Content was flagged by Gemini safety filters. Please try with different images."):p}}var Zs=require("@google/genai");async function ct(s,e,t=[],i={}){try{console.info("[GEMINI-REAL-SDK] Initializing GoogleGenAI...");let n=new Zs.GoogleGenAI({apiKey:s}),a=[{text:e}];t.length>0&&t.forEach((o,l)=>{console.info(`[GEMINI-REAL-SDK] Adding image part ${l}`),a.push({inlineData:{mimeType:o.mimeType,data:o.base64}})}),console.info("[GEMINI-REAL-SDK] Calling generateContent with model: gemini-2.5-flash-image");let r=await n.models.generateContent({model:"gemini-2.5-flash-image",contents:a});if(console.info("[GEMINI-REAL-SDK] Received response from model"),!r.candidates||!r.candidates[0]||!r.candidates[0].content||!r.candidates[0].content.parts)throw new Error("Gemini 2.5 Flash Image returned invalid response structure.");for(let o of r.candidates[0].content.parts)if(o.text)console.log(o.text);else if(o.inlineData){let l=o.inlineData.data,c=o.inlineData.mimeType||"image/png";return console.info("[GEMINI-REAL-SDK] Found inline image data in response"),`data:${c};base64,${l}`}throw new Error("Gemini 2.5 Flash Image returned no image data.")}catch(n){throw console.error("[GEMINI-REAL-SDK] Error in generateImageWithGemini25Flash:",JSON.stringify(n,Object.getOwnPropertyNames(n),2)),n}}function Qs(s){let e=s.brandAssets.map(a=>{let r=`- ${a.id}: ${a.role}`;return a.layout&&(r+=` [pos: ${a.layout.x.toFixed(0)},${a.layout.y.toFixed(0)}, size: ${a.layout.w.toFixed(0)}x${a.layout.h.toFixed(0)}, z: ${a.layout.z}, opacity: ${a.layout.opacity}]`),r}).join(`
1194
+ `)||"None",t=s.brandDna?`Colors: ${JSON.stringify(s.brandDna.colors)}, Style: ${s.brandDna.style||"not specified"}`:"Not provided",i=s.gameObjects.map(a=>typeof a=="string"?`- id: ${a}`:`- id: ${a.id}${a.category?`, category: ${a.category}`:""}${a.type?`, type: ${a.type}`:""}`).join(`
1195
+ `),n="";if(s.brandConfig){let a=s.brandConfig,r=[];a.splash&&r.push(`SPLASH: title="${a.splash.title||""}", subtitle="${a.splash.subtitle||""}", button="${a.splash.button_label||""}"`),a.endgame&&r.push(`ENDGAME: title="${a.endgame.title||""}", subtitle="${a.endgame.subtitle||""}", cta="${a.endgame.cta_label||""}"`),a.tutorial&&r.push(`TUTORIAL: text="${a.tutorial.label_text||""}", helper="${a.tutorial.helper_text||""}"`),r.length>0&&(n=`
1196
1196
  BRAND CONTENT:
1197
1197
  ${r.join(`
1198
1198
  `)}
@@ -1203,14 +1203,14 @@ GAME CONTEXT:
1203
1203
  ${s.gamePrompt||"Simple game"}
1204
1204
 
1205
1205
  GAME OBJECTS (need assets):
1206
- ${n}
1206
+ ${i}
1207
1207
 
1208
1208
  BRAND ASSETS PROVIDED:
1209
1209
  ${e}
1210
1210
 
1211
1211
  BRAND DNA:
1212
1212
  ${t}
1213
- ${i}
1213
+ ${n}
1214
1214
  VISUAL REFERENCE: [See attached flat design image]
1215
1215
 
1216
1216
  TASK:
@@ -1254,7 +1254,7 @@ OUTPUT ONLY VALID JSON (no markdown, no explanation):
1254
1254
  }
1255
1255
  ]
1256
1256
  }
1257
- `.trim()}function Ks(s){var i,a;let e=(i=s.brandDna)!=null&&i.colors?`Primary: ${s.brandDna.colors.primary}, Secondary: ${s.brandDna.colors.secondary||"N/A"}, Accent: ${s.brandDna.colors.accent||"N/A"}`:"Use provided reference colors",t=((a=s.brandDna)==null?void 0:a.style)||"modern gaming style",n=s.needsTransparency?"BACKGROUND: REQUIRED solid magenta #FF00FF (for transparency removal)":"BACKGROUND: Use brand colors naturally, fill the entire frame";return`
1257
+ `.trim()}function er(s){var n,a;let e=(n=s.brandDna)!=null&&n.colors?`Primary: ${s.brandDna.colors.primary}, Secondary: ${s.brandDna.colors.secondary||"N/A"}, Accent: ${s.brandDna.colors.accent||"N/A"}`:"Use provided reference colors",t=((a=s.brandDna)==null?void 0:a.style)||"modern gaming style",i=s.needsTransparency?"BACKGROUND: REQUIRED solid magenta #FF00FF (for transparency removal)":"BACKGROUND: Use brand colors naturally, fill the entire frame";return`
1258
1258
  TASK: ${s.prompt}
1259
1259
 
1260
1260
  BRAND STYLE:
@@ -1263,7 +1263,7 @@ BRAND STYLE:
1263
1263
 
1264
1264
  CHANGE_STRENGTH: 8/10
1265
1265
  REFERENCE: ${s.hasReference?"provided (use as style guide for colors and aesthetics)":"none"}
1266
- ${n}
1266
+ ${i}
1267
1267
 
1268
1268
  OUTPUT CONSTRAINTS (MUST FOLLOW):
1269
1269
  - Do NOT add extra text unless specifically requested
@@ -1275,7 +1275,92 @@ OUTPUT CONSTRAINTS (MUST FOLLOW):
1275
1275
 
1276
1276
  OUTPUT:
1277
1277
  Generate the requested asset matching the brand style.${s.needsTransparency?" Background MUST be solid magenta (#FF00FF).":""}
1278
- `.trim()}function Xs(s){return s.map(e=>{if(typeof e=="string"){let t=e,n,i;return t.includes("background")?(n="background",i="background"):t.includes("button")||t.includes("cta")?(n="ui",i="button"):t.includes("logo")?(n="ui",i="logo"):t.includes("title")||t.includes("subtitle")||t.includes("text")?(n="text",i="text"):t.includes("effect")||t.includes("confetti")||t.includes("particle")?(n="effects",i="effect"):t.includes("ui.")||t.includes("splash")||t.includes("endgame")?(n="ui",i="image"):(n="environment",i="interactive"),{id:t,category:n,type:i}}return e})}function Js(s,e){return!(s.includes("background")&&(s.includes("_1")||s.includes("splash")||s.includes("endgame")||s.includes("main"))||e==="text"||e==="effects"&&s.includes("particle"))}async function Zs(s){var r,o;let e=Xs(s.gameObjects),t={gamePrompt:s.gamePrompt,gameObjects:e,brandAssets:s.manifest.assets,brandDna:s.manifest.brand_dna,brandName:s.manifest.brand_name},n=Ys(t),i=[];if(s.flatDesignDataUrl)try{let l=Qs(s.flatDesignDataUrl);l&&l.base64&&l.mimeType?l.base64.length<100?console.warn("[Pipeline] Flat design data URL appears invalid (too short)"):(i.push(l),console.log("[Pipeline] Added flat design to analysis, size:",l.base64.length)):console.warn("[Pipeline] Failed to parse flat design data URL")}catch(l){console.warn("[Pipeline] Error processing flat design:",l)}console.log("[Pipeline] Running analysis chain with",i.length,"images...");let a;try{a=await Gn(s.apiKey,n,i,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(r=l.message)!=null&&r.includes("Unable to process input image")?new Error("Gemini API unable to process the uploaded images. Please try with different images or ensure they are valid PNG/JPG files under 10MB."):(o=l.message)!=null&&o.includes("image")?new Error("Image processing failed. Please ensure your images are valid and not corrupted."):l}return tl(a,s.gameObjects)}function tl(s,e){try{let t=s,n=s.match(/```(?:json)?\s*([\s\S]*?)```/);if(n)t=n[1].trim();else{let a=s.match(/\{[\s\S]*\}/);a&&(t=a[0])}let i=JSON.parse(t);return i.mappings&&Array.isArray(i.mappings)?{mappingResult:i,rawResponse:s,parsed:!0}:{mappingResult:{mappings:e.map(a=>({game_object:a,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:s,parsed:!1,parseError:"Missing mappings[] array"}}catch(t){return{mappingResult:{mappings:e.map(n=>({game_object:n,action:"KEEP",status:"Analysis response was not valid JSON"}))},rawResponse:s,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function ea(s,e,t={}){var i;let n=e.mappings.filter(a=>a.action==="GENERATE");if(n.length===0){console.log("[Pipeline] No assets to generate");return}console.log(`[Pipeline] Generating ${n.length} assets...`);for(let a=0;a<n.length;a++){let r=n[a];(i=t.onProgress)==null||i.call(t,a+1,n.length,r.game_object);try{let o=await nl(s,r);r.output_dataUrl=o,r.status="Generated \u2713"}catch(o){console.error(`[Pipeline] Failed to generate ${r.game_object}:`,o),r.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function nl(s,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&s.manifest){let o=s.manifest.assets.find(l=>l.id===e.reference_asset);if(o){let l=s.assetFiles.get(o.file);if(l){let c=await Pe(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(s.flatDesignDataUrl){let o=Qs(s.flatDesignDataUrl);o&&t.push(o)}let n=Js(e.game_object),i={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:s.manifest.brand_dna,needsTransparency:n},a=Ks(i);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${n})`);let r=await st(s.apiKey,a,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return n&&await at(r)||r}function Qs(s){let[e,t]=s.split(","),n=e==null?void 0:e.match(/data:(.*?);base64/);return t&&n?{base64:t,mimeType:n[1]}:null}async function er(s,e){let t=s.assets,n=[];Array.isArray(t)?n=t:t&&typeof t=="object"?n=Object.entries(t).map(([i,a])=>({id:i,file:String(a),role:"visual element"})):n=[],s.assets=n;for(let i of n){let a=e.get(i.file);if(a){let r=await Pe(a);r&&(i.dataUrl=r.dataUrl)}}}var qn=class{constructor(){this.root=null;this.currentTab="upload";this.uploadMethod="individual";this.uploadedJsons=new Map;this.normalizedManifest=null;this.flatDesignDataUrl=null;this.assetFiles=new Map;this.zipFile=null;this.mappingResult=null;this.analysisRawResponse=null;this.analysisParsedOk=null;this.analysisParseError=null;this.isAnalyzing=!1;this.isGenerating=!1}get manifest(){return this.normalizedManifest}render(){return`
1278
+ `.trim()}function tr(s){return s.map(e=>{if(typeof e=="string"){let t=e,i,n;return t.includes("background")?(i="background",n="background"):t.includes("button")||t.includes("cta")?(i="ui",n="button"):t.includes("logo")?(i="ui",n="logo"):t.includes("title")||t.includes("subtitle")||t.includes("text")?(i="text",n="text"):t.includes("effect")||t.includes("confetti")||t.includes("particle")?(i="effects",n="effect"):t.includes("ui.")||t.includes("splash")||t.includes("endgame")?(i="ui",n="image"):(i="environment",n="interactive"),{id:t,category:i,type:n}}return e})}function ir(s,e){return!(s.includes("background")&&(s.includes("_1")||s.includes("splash")||s.includes("endgame")||s.includes("main"))||e==="text"||e==="effects"&&s.includes("particle"))}async function nr(s){var r,o;let e=tr(s.gameObjects),t={gamePrompt:s.gamePrompt,gameObjects:e,brandAssets:s.manifest.assets,brandDna:s.manifest.brand_dna,brandName:s.manifest.brand_name},i=Qs(t),n=[];if(s.flatDesignDataUrl)try{let l=ar(s.flatDesignDataUrl);l&&l.base64&&l.mimeType?l.base64.length<100?console.warn("[Pipeline] Flat design data URL appears invalid (too short)"):(n.push(l),console.log("[Pipeline] Added flat design to analysis, size:",l.base64.length)):console.warn("[Pipeline] Failed to parse flat design data URL")}catch(l){console.warn("[Pipeline] Error processing flat design:",l)}console.log("[Pipeline] Running analysis chain with",n.length,"images...");let a;try{a=await Vi(s.apiKey,i,n,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(r=l.message)!=null&&r.includes("Unable to process input image")?new Error("Gemini API unable to process the uploaded images. Please try with different images or ensure they are valid PNG/JPG files under 10MB."):(o=l.message)!=null&&o.includes("image")?new Error("Image processing failed. Please ensure your images are valid and not corrupted."):l}return ol(a,s.gameObjects)}function ol(s,e){try{let t=s,i=s.match(/```(?:json)?\s*([\s\S]*?)```/);if(i)t=i[1].trim();else{let a=s.match(/\{[\s\S]*\}/);a&&(t=a[0])}let n=JSON.parse(t);return n.mappings&&Array.isArray(n.mappings)?{mappingResult:n,rawResponse:s,parsed:!0}:{mappingResult:{mappings:e.map(a=>({game_object:a,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:s,parsed:!1,parseError:"Missing mappings[] array"}}catch(t){return{mappingResult:{mappings:e.map(i=>({game_object:i,action:"KEEP",status:"Analysis response was not valid JSON"}))},rawResponse:s,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function oa(s,e,t={}){var n;let i=e.mappings.filter(a=>a.action==="GENERATE");if(i.length===0){console.log("[Pipeline] No assets to generate");return}console.log(`[Pipeline] Generating ${i.length} assets...`);for(let a=0;a<i.length;a++){let r=i[a];(n=t.onProgress)==null||n.call(t,a+1,i.length,r.game_object);try{let o=await ll(s,r);r.output_dataUrl=o,r.status="Generated \u2713"}catch(o){console.error(`[Pipeline] Failed to generate ${r.game_object}:`,o),r.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function ll(s,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&s.manifest){let o=s.manifest.assets.find(l=>l.id===e.reference_asset);if(o){let l=s.assetFiles.get(o.file);if(l){let c=await Oe(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(s.flatDesignDataUrl){let o=ar(s.flatDesignDataUrl);o&&t.push(o)}let i=ir(e.game_object),n={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:s.manifest.brand_dna,needsTransparency:i},a=er(n);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${i})`);let r=await ct(s.apiKey,a,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return i&&await lt(r)||r}function ar(s){let[e,t]=s.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return t&&i?{base64:t,mimeType:i[1]}:null}async function sr(s,e){let t=s.assets,i=[];Array.isArray(t)?i=t:t&&typeof t=="object"?i=Object.entries(t).map(([n,a])=>({id:n,file:String(a),role:"visual element"})):i=[],s.assets=i;for(let n of i){let a=e.get(n.file);if(a){let r=await Oe(a);r&&(n.dataUrl=r.dataUrl)}}}function rr(s){let e=new Map;if(!s)return e;if(s!=null&&s.layers&&Array.isArray(s.layers))for(let t of s.layers){let i=t.asset||t.id||t.name;i&&t.layout&&e.set(i,{position:t.layout.position||{x:0,y:0},scale:t.layout.scale||1,rotation:t.layout.rotation||0})}if(typeof s=="object"&&!Array.isArray(s)){for(let[t,i]of Object.entries(s))if(i&&typeof i=="object"&&"layout"in i){let n=i.layout;e.set(t,{position:(n==null?void 0:n.position)||{x:0,y:0},scale:(n==null?void 0:n.scale)||1,rotation:(n==null?void 0:n.rotation)||0})}}return e}function or(s,e){if(!s||e.size===0)return null;if(e.has(s))return e.get(s);let t=s.replace(/\.png$/i,"").replace(/\.jpg$/i,"").replace(/\.jpeg$/i,"");if(e.has(t))return e.get(t);for(let[i,n]of e.entries()){let a=i.toLowerCase(),r=t.toLowerCase();if(a===r||a.includes(r)||r.includes(a))return n}return null}function cl(s){return s.replace(/^json\./,"").replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase())}function lr(){var n,a,r,o,l,c,d;let s=window.getEditableObjectList,e=typeof s=="function"?s():[],t=window.getEditableObjectConfig;if(typeof t!="function")return[];let i=[];for(let p of e)try{let u=t(p);if(!u)continue;(((a=(n=u==null?void 0:u.render)==null?void 0:n.asset)==null?void 0:a.type)==="image"||(o=(r=u==null?void 0:u.render)==null?void 0:r.asset)!=null&&o.path||(l=u==null?void 0:u.render)!=null&&l.asset&&typeof u.render.asset=="string")&&i.push({id:p,name:cl(p),type:((d=(c=u==null?void 0:u.render)==null?void 0:c.asset)==null?void 0:d.type)||"sprite"})}catch(u){console.warn(`[CanvaZip] Failed to check object ${p}:`,u)}return i.sort((p,u)=>p.name.localeCompare(u.name))}var Dt=require("pixi.js");st();K();async function cr(s,e,t){var i,n;console.log("[LIBRARY] applyAssetChange called with:",e,t);try{let a=Date.now(),o=`/${`raw/library/${e}/${t}`}?t=${a}`;console.log("[LIBRARY] Loading texture from:",o);let l=await Dt.Assets.load(o);if(!l){console.error("[LIBRARY] Failed to load texture:",o);return}let c=window.CustomAssets,d=Object.keys(c||{}).filter(u=>{let g=e.replace(/s$/,"");return u.startsWith(g)||u.includes(g)});for(let u of d)pe[u]=l,console.log("[LIBRARY] \u2705 Updated AssetTextures."+u),(i=c[u])!=null&&i.texture&&(c[u].texture=l,console.log("[LIBRARY] \u2705 Updated CustomAssets."+u+".texture"));let p=window.gameObjectManager;if(p)for(let u of d){let g=p.get(u);if(g){let h=((n=g.getDisplayObject)==null?void 0:n.call(g))||g.pixiObject||g;h!=null&&h.texture&&(h.texture=l,console.log("[LIBRARY] \u2705 Applied to display object:",u))}}}catch(a){console.error("[LIBRARY] Error applying asset change:",a)}}async function dr(s,e){var t,i,n;console.log("[LIBRARY] resetAsset called for:",e);try{let a=window.getEditableAssets,r=typeof a=="function"?a():null,o=(t=r==null?void 0:r.slots)==null?void 0:t.find(m=>m.category===e),l=o==null?void 0:o.defaultAsset;if(!l){console.warn("[LIBRARY] Could not find default asset for:",e);return}let c=Date.now(),d=`/raw/${l}?t=${c}`;console.log("[LIBRARY] Loading default texture from:",d);let p=await Dt.Assets.load(d);if(!p){console.error("[LIBRARY] Failed to load default texture:",d);return}let u=window.CustomAssets,g=e.replace(/s$/,""),h=Object.keys(u||{}).filter(m=>m.startsWith(g)||m.includes(g));for(let m of h)pe[m]=p,console.log("[LIBRARY] \u2705 Reset AssetTextures."+m),(i=u[m])!=null&&i.texture&&(u[m].texture=p,console.log("[LIBRARY] \u2705 Reset CustomAssets."+m+" to default"));let f=window.gameObjectManager;if(f)for(let m of h){let b=f.get(m);if(b){let y=((n=b.getDisplayObject)==null?void 0:n.call(b))||b.pixiObject||b;y!=null&&y.texture&&(y.texture=p,console.log("[LIBRARY] \u2705 Reset display object:",m))}}}catch(a){console.error("[LIBRARY] Error resetting asset:",a)}}async function Wi(s,e,t,i){var n,a,r,o,l,c,d,p,u,g,h,f,m,b,y;console.log("[LIBRARY] applySlotAsset:",{objectId:e,assetFilename:t,category:i});try{let v=e.startsWith("json.")?e.replace("json.",""):e;console.log("[LIBRARY] Asset key:",v);let w=Date.now(),E=`/raw/library/${i}/${t}?t=${w}`;console.log("[LIBRARY] Loading texture from:",E);let P=await Dt.Assets.load(E);if(!P){console.error("[LIBRARY] Failed to load texture:",E);return}console.log("[LIBRARY] \u2705 Texture loaded"),pe[v]=P,console.log("[LIBRARY] \u2705 Updated AssetTextures."+v);let M=window.CustomAssets;M!=null&&M[v]&&(M[v].texture=P,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+v));let x=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!x),x){let O=Array.from(((n=x.keys)==null?void 0:n.call(x))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",O);let T=x.get(v);if(console.log("[LIBRARY] gameObject for "+v+"?",!!T),T){let A=((a=T.getDisplayObject)==null?void 0:a.call(T))||T.pixiObject||T.pixi||T,j=(r=A==null?void 0:A.constructor)==null?void 0:r.name;if(console.log("[LIBRARY] displayObject:",A),console.log("[LIBRARY] displayObject type:",j),console.log("[LIBRARY] has texture?",!!(A!=null&&A.texture)),A!=null&&A.texture)A.texture=P,console.log("[LIBRARY] \u2705 Applied to display object:",v);else if(j==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:k}=await import("pixi.js"),C=A.parent,S=(l=(o=C==null?void 0:C.getChildIndex)==null?void 0:o.call(C,A))!=null?l:0,I={x:A.x,y:A.y},L={x:(d=(c=A.anchor)==null?void 0:c.x)!=null?d:.5,y:(u=(p=A.anchor)==null?void 0:p.y)!=null?u:.5},R={x:(h=(g=A.scale)==null?void 0:g.x)!=null?h:1,y:(m=(f=A.scale)==null?void 0:f.y)!=null?m:1},z=(b=A.alpha)!=null?b:1,N=(y=A.visible)!=null?y:!0,F=new k(P);F.anchor.set(L.x,L.y),F.position.set(I.x,I.y),F.scale.set(R.x,R.y),F.alpha=z,F.visible=N,C&&(C.removeChild(A),C.addChildAt(F,S),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),T.pixiObject&&(T.pixiObject=F),T.pixi&&(T.pixi=F),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if(A!=null&&A.children){let k=A.children.find(C=>C.texture);k?(k.texture=P,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let _=`raw/library/${i}/${t}`;ne({objectId:v,path:"render.asset.path",value:_}),console.log("[LIBRARY] \u2705 Staged config override for:",v,"path:",_)}catch(v){console.error("[LIBRARY] Error applying slot asset:",v)}}async function pr(s,e,t,i){var n;console.log("[LIBRARY] resetSlotAsset:",{objectId:e,defaultAsset:t,category:i});try{let a=e.startsWith("json.")?e.replace("json.",""):e,r=Date.now(),o=`/raw/${t}?t=${r}`;console.log("[LIBRARY] Loading default texture from:",o);let l=await Dt.Assets.load(o);if(!l){console.error("[LIBRARY] Failed to load default texture:",o);return}pe[a]=l,console.log("[LIBRARY] \u2705 Reset AssetTextures."+a);let c=window.CustomAssets;c!=null&&c[a]&&(c[a].texture=l,console.log("[LIBRARY] \u2705 Reset CustomAssets."+a+" to default"));let d=window.gameObjectManager;if(d){let p=d.get(a);if(p){let u=((n=p.getDisplayObject)==null?void 0:n.call(p))||p.pixiObject||p;u!=null&&u.texture&&(u.texture=l,console.log("[LIBRARY] \u2705 Reset display object:",a))}}ne({objectId:a,path:"render.asset.path",value:t}),console.log("[LIBRARY] \u2705 Reset config override for:",a)}catch(a){console.error("[LIBRARY] Error resetting slot asset:",a)}}var Yi=class{constructor(){this.root=null;this.assets=[];this.positionMap=new Map;this.replaceableObjects=[];this.options=null;this.processedCount=0}render(){let e=this.assets.length,t=this.processedCount;return`
1279
+ <div class="canva-wizard-overlay" data-canva-wizard>
1280
+ <div class="canva-wizard-modal">
1281
+ <div class="canva-wizard-header">
1282
+ <div class="canva-wizard-title">
1283
+ <span class="canva-wizard-icon">\u{1F4E6}</span>
1284
+ <div>
1285
+ <h2>Review Extracted Assets</h2>
1286
+ <p class="canva-wizard-subtitle">Choose how to handle each asset from the Canva ZIP</p>
1287
+ </div>
1288
+ </div>
1289
+ <button class="canva-wizard-close" data-canva-wizard-close title="Cancel">\u2715</button>
1290
+ </div>
1291
+
1292
+ <div class="canva-wizard-progress">
1293
+ <div class="canva-wizard-progress-bar">
1294
+ <div class="canva-wizard-progress-fill" style="width: ${t/e*100}%"></div>
1295
+ </div>
1296
+ <span class="canva-wizard-progress-text">${t} of ${e} assets processed</span>
1297
+ </div>
1298
+
1299
+ <div class="canva-wizard-body">
1300
+ <div class="canva-wizard-gallery" data-canva-gallery>
1301
+ ${this.assets.map((i,n)=>this.renderAssetCard(i,n)).join("")}
1302
+ </div>
1303
+ </div>
1304
+
1305
+ <div class="canva-wizard-footer">
1306
+ <div class="canva-wizard-footer-info">
1307
+ <span class="canva-wizard-hint">\u{1F4A1} All assets will be saved to library</span>
1308
+ </div>
1309
+ <div class="canva-wizard-footer-actions">
1310
+ <button class="inspector-btn" data-canva-wizard-cancel>Cancel</button>
1311
+ <button class="inspector-btn primary" data-canva-wizard-apply-all>Apply All</button>
1312
+ </div>
1313
+ </div>
1314
+ </div>
1315
+ </div>
1316
+ `}renderAssetCard(e,t){let n=e.position&&e.scale?`x: ${e.position.x.toFixed(0)}, y: ${e.position.y.toFixed(0)}, scale: ${e.scale.toFixed(2)}`:"No position data",a=e.action==="add"||e.action==="replace"?"active":"",r=e.action==="replace"?this.renderReplaceDropdown(e,t):"";return`
1317
+ <div class="canva-asset-card ${a}" data-asset-index="${t}">
1318
+ <div class="canva-asset-preview">
1319
+ <img src="${e.dataUrl}" alt="${e.filename}" />
1320
+ </div>
1321
+ <div class="canva-asset-info">
1322
+ <div class="canva-asset-name" title="${e.filename}">${e.filename}</div>
1323
+ <div class="canva-asset-position">${n}</div>
1324
+ </div>
1325
+ <div class="canva-asset-category">
1326
+ <label>Category:</label>
1327
+ <select class="inspector-input inspector-input-sm" data-asset-category="${t}">
1328
+ <option value="environment" ${e.category==="environment"?"selected":""}>Environment</option>
1329
+ <option value="backgrounds" ${e.category==="backgrounds"?"selected":""}>Backgrounds</option>
1330
+ <option value="ui" ${e.category==="ui"?"selected":""}>UI</option>
1331
+ <option value="effects" ${e.category==="effects"?"selected":""}>Effects</option>
1332
+ <option value="products" ${e.category==="products"?"selected":""}>Products</option>
1333
+ <option value="misc" ${e.category==="misc"?"selected":""}>Misc</option>
1334
+ </select>
1335
+ </div>
1336
+ <div class="canva-asset-actions">
1337
+ <button class="inspector-btn inspector-btn-sm ${e.action==="add"?"primary":""}"
1338
+ data-asset-action="${t}" data-action="add"
1339
+ title="Add as new object to scene">
1340
+ \u2795 Add To Scene
1341
+ </button>
1342
+ <button class="inspector-btn inspector-btn-sm ${e.action==="replace"?"primary":""}"
1343
+ data-asset-action="${t}" data-action="replace"
1344
+ title="Replace existing object">
1345
+ \u{1F504} Replace
1346
+ </button>
1347
+ <button class="inspector-btn inspector-btn-sm ${e.action==="skip"?"primary":""}"
1348
+ data-asset-action="${t}" data-action="skip"
1349
+ title="Skip (save to library only)">
1350
+ \u23ED\uFE0F Do Nothing
1351
+ </button>
1352
+ </div>
1353
+ ${r}
1354
+ </div>
1355
+ `}renderReplaceDropdown(e,t){return this.replaceableObjects.length===0?'<div class="canva-asset-replace-hint">No replaceable objects found</div>':`
1356
+ <div class="canva-asset-replace" data-asset-replace="${t}">
1357
+ <label>Replace object:</label>
1358
+ <select class="inspector-input inspector-input-sm" data-asset-target="${t}">
1359
+ <option value="">Select object...</option>
1360
+ ${this.replaceableObjects.map(i=>`<option value="${i.id}" ${e.targetObjectId===i.id?"selected":""}>${i.name}</option>`).join("")}
1361
+ </select>
1362
+ </div>
1363
+ `}initialize(e,t,i,n){this.options=n,this.positionMap=rr(i),this.replaceableObjects=lr(),this.assets=t.map(a=>{let r=or(a.filename,this.positionMap);return{filename:a.filename,dataUrl:a.dataUrl,category:this.inferCategory(a.filename),position:r==null?void 0:r.position,scale:r==null?void 0:r.scale,rotation:r==null?void 0:r.rotation,action:void 0,targetObjectId:void 0}}),e.innerHTML=this.render(),this.root=e.querySelector("[data-canva-wizard]"),this.attachEventListeners()}attachEventListeners(){var e,t,i;this.root&&((e=this.root.querySelector("[data-canva-wizard-close]"))==null||e.addEventListener("click",()=>{this.close()}),(t=this.root.querySelector("[data-canva-wizard-cancel]"))==null||t.addEventListener("click",()=>{this.close()}),(i=this.root.querySelector("[data-canva-wizard-apply-all]"))==null||i.addEventListener("click",()=>{this.applyAll()}),this.root.querySelectorAll("[data-asset-action]").forEach(n=>{n.addEventListener("click",a=>{let r=a.target,o=parseInt(r.getAttribute("data-asset-action")||"0"),l=r.getAttribute("data-action");this.handleAction(o,l)})}),this.root.querySelectorAll("[data-asset-category]").forEach(n=>{n.addEventListener("change",a=>{let r=a.target,o=parseInt(r.getAttribute("data-asset-category")||"0"),l=r.value;this.assets[o]&&(this.assets[o].category=l)})}),this.root.querySelectorAll("[data-asset-target]").forEach(n=>{n.addEventListener("change",a=>{let r=a.target,o=parseInt(r.getAttribute("data-asset-target")||"0"),l=r.value;this.assets[o]&&(this.assets[o].targetObjectId=l)})}),this.root.addEventListener("click",n=>{n.target===this.root&&this.close()}))}handleAction(e,t){this.assets[e]&&(this.assets[e].action=t,t==="replace"?this.updateAssetCard(e):(this.assets[e].targetObjectId=void 0,this.updateAssetCard(e)))}updateAssetCard(e){var i,n;if(!this.root)return;let t=this.root.querySelector(`[data-asset-index="${e}"]`);if(t&&this.assets[e]){let a=this.assets[e],r=this.renderAssetCard(a,e);t.outerHTML=r;let o=this.root.querySelector(`[data-asset-index="${e}"]`);o&&(o.querySelectorAll("[data-asset-action]").forEach(l=>{l.addEventListener("click",c=>{let d=c.target,p=parseInt(d.getAttribute("data-asset-action")||"0"),u=d.getAttribute("data-action");this.handleAction(p,u)})}),(i=o.querySelector("[data-asset-category]"))==null||i.addEventListener("change",l=>{let d=l.target.value;this.assets[e]&&(this.assets[e].category=d)}),(n=o.querySelector("[data-asset-target]"))==null||n.addEventListener("change",l=>{let d=l.target.value;this.assets[e]&&(this.assets[e].targetObjectId=d)}))}}async applyAll(){if(this.options){for(let e of this.assets)e.action||(e.action="skip");this.processedCount=0,this.updateProgress();for(let e=0;e<this.assets.length;e++){let t=this.assets[e];try{let i=await this.saveAssetToLibrary(t);t.libraryPath=i,t.action==="add"?await this.addToScene(t):t.action==="replace"&&t.targetObjectId&&await this.replaceObject(t,t.targetObjectId),this.processedCount++,this.updateProgress()}catch(i){console.error(`[CanvaZip] Failed to process ${t.filename}:`,i)}}this.options.onComplete&&this.options.onComplete(this.assets),this.close()}}async saveAssetToLibrary(e){try{let i=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:e.category,filename:e.filename,data:e.dataUrl,overwrite:!0})})).json();if(i.success&&i.path)return console.log(`[CanvaZip] \u2705 Saved ${e.filename} to library: ${i.path}`),i.path;throw new Error(i.error||"Failed to save to library")}catch(t){throw console.error(`[CanvaZip] Failed to save ${e.filename} to library:`,t),t}}async addToScene(e){console.log(`[CanvaZip] Add to scene: ${e.filename}`,{position:e.position,scale:e.scale,category:e.category});let t=window.addObjectToScene;if(typeof t=="function")try{await t({filename:e.filename,libraryPath:e.libraryPath,position:e.position||{x:0,y:0},scale:e.scale||1,category:e.category}),console.log(`[CanvaZip] \u2705 Added ${e.filename} to scene`);return}catch(n){console.error("[CanvaZip] Failed to add object via API:",n)}console.warn(`[CanvaZip] Add To Scene feature requires backend API endpoint. Asset saved to library: ${e.libraryPath}`),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"));let i=window.refreshAssetLibrary;typeof i=="function"&&i()}async replaceObject(e,t){let i=window.__debugContext;if(!i){console.warn("[CanvaZip] No debug context available for replace");return}try{await Wi(i,t,e.filename,e.category),console.log(`[CanvaZip] \u2705 Replaced ${t} with ${e.filename}`)}catch(n){throw console.error(`[CanvaZip] Failed to replace ${t}:`,n),n}}updateProgress(){if(!this.root)return;let e=this.root.querySelector(".canva-wizard-progress-fill"),t=this.root.querySelector(".canva-wizard-progress-text");if(e){let i=this.processedCount/this.assets.length*100;e.style.width=`${i}%`}t&&(t.textContent=`${this.processedCount} of ${this.assets.length} assets processed`)}inferCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"environment"}close(){var e;(e=this.options)!=null&&e.onCancel&&this.options.onCancel(),this.root&&this.root.remove()}};var Ki=class{constructor(){this.root=null;this.currentTab="upload";this.uploadMethod="individual";this.uploadedJsons=new Map;this.normalizedManifest=null;this.flatDesignDataUrl=null;this.assetFiles=new Map;this.zipFile=null;this.mappingResult=null;this.analysisRawResponse=null;this.analysisParsedOk=null;this.analysisParseError=null;this.isAnalyzing=!1;this.isGenerating=!1}get manifest(){return this.normalizedManifest}render(){return`
1279
1364
  <div class="scene-panel brand-vision-panel panel-accent-violet" data-panel="brand-vision">
1280
1365
  <div class="scene-panel-header" data-panel-handle>
1281
1366
  <div class="panel-title">
@@ -1391,15 +1476,15 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1391
1476
  </div>
1392
1477
  <div class="panel-resize-handle" data-panel-resize></div>
1393
1478
  </div>
1394
- `}initialize(e,t){this.root=e.querySelector('[data-panel="brand-vision"]'),this.onClose=t,this.root&&(this.attachEventListeners(),this.setupResizeHandle())}attachEventListeners(){var t,n,i,a,r,o,l,c,d,p,u,g,f;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let h="/dashboard";window.location.pathname!==h&&(window.location.href=h)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(h=>{h.addEventListener("click",()=>{let m=h.dataset.visionTab;this.switchTab(m)})}),(n=this.root.querySelector("[data-vision-upload-method]"))==null||n.addEventListener("change",h=>{let m=h.target.value;this.switchUploadMethod(m)}),(i=this.root.querySelector("[data-vision-upload-manifest]"))==null||i.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-manifest-input]"))==null||m.click()}),(a=this.root.querySelector("[data-vision-upload-zip]"))==null||a.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-zip-input]"))==null||m.click()}),(r=this.root.querySelector("[data-vision-zip-input]"))==null||r.addEventListener("change",h=>{this.handleZipUpload(h)}),(o=this.root.querySelector("[data-vision-manifest-input]"))==null||o.addEventListener("change",h=>{this.handleManifestUpload(h)}),(l=this.root.querySelector("[data-vision-upload-assets]"))==null||l.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-assets-input]"))==null||m.click()}),(c=this.root.querySelector("[data-vision-assets-input]"))==null||c.addEventListener("change",h=>{this.handleAssetsUpload(h)}),(d=this.root.querySelector("[data-vision-upload-flat]"))==null||d.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-flat-input]"))==null||m.click()}),(p=this.root.querySelector("[data-vision-flat-input]"))==null||p.addEventListener("change",h=>{this.handleFlatDesignUpload(h)}),(u=this.root.querySelector("[data-vision-analyze]"))==null||u.addEventListener("click",()=>{this.runAnalysis()}),(g=this.root.querySelector("[data-vision-generate-all]"))==null||g.addEventListener("click",()=>{this.generateAllMissing()}),(f=this.root.querySelector("[data-vision-apply-all]"))==null||f.addEventListener("click",()=>{this.applyAll()});let e=this.root.querySelector("[data-vision-mappings]");e==null||e.addEventListener("click",h=>{let m=h.target;if(!m)return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;y&&(m.closest("[data-mapping-apply-one]")&&this.applyOne(y),m.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(y),m.closest("[data-mapping-edit-one]")&&this.openEditorForOne(y),m.closest("[data-mapping-generate-one]")&&this.generateOne(y),m.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",h=>{let m=h.target;if(!m||!this.mappingResult)return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;if(!y)return;let v=this.mappingResult.mappings.find(w=>w.game_object===y);v&&(m.matches("[data-mapping-action]")&&(v.action=String(m.value||"KEEP"),v.status="Edited",this.renderMappings()),m.matches("[data-mapping-brand-asset]")&&(v.brand_asset=String(m.value||""),v.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",h=>{let m=h.target;if(!m||!this.mappingResult||!m.matches("[data-mapping-prompt]"))return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;if(!y)return;let v=this.mappingResult.mappings.find(w=>w.game_object===y);v&&(v.generation_prompt=String(m.value||""),v.status="Edited")})}switchTab(e){var t,n;this.root&&(this.currentTab=e,this.root.querySelectorAll("[data-vision-tab]").forEach(i=>i.classList.remove("active")),this.root.querySelectorAll("[data-vision-content]").forEach(i=>i.classList.remove("active")),(t=this.root.querySelector(`[data-vision-tab="${e}"]`))==null||t.classList.add("active"),(n=this.root.querySelector(`[data-vision-content="${e}"]`))==null||n.classList.add("active"))}switchUploadMethod(e){var t;this.root&&(this.uploadMethod=e,this.root.querySelectorAll("[data-vision-upload-section]").forEach(n=>{n.classList.remove("active")}),(t=this.root.querySelector(`[data-vision-upload-section="${e}"]`))==null||t.classList.add("active"))}async handleZipUpload(e){var i;let n=(i=e.target.files)==null?void 0:i[0];if(n){this.zipFile=n,this.setStatus("zip",`Selected: ${n.name} (${(n.size/1024/1024).toFixed(2)} MB)`);try{await this.processZipFile(n)}catch(a){console.error("[BrandVision] ZIP processing failed:",a),this.setStatus("zip",`Error: ${a instanceof Error?a.message:"Unknown error"}`)}}}async processZipFile(e){var r,o;let t=await tr.loadAsync(e),n=[],i=[];t.forEach((l,c)=>{let d=l.toLowerCase();d.endsWith(".json")?n.push({name:l,content:null}):d.startsWith("assets/")&&d.endsWith(".png")&&i.push({name:l,file:c})});for(let l of n)try{let c=await((r=t.file(l.name))==null?void 0:r.async("text"));c&&(l.content=JSON.parse(c))}catch(c){console.warn(`Failed to parse ${l.name}:`,c)}let a=new Map;for(let l of i)try{let c=await l.file.async("uint8array"),d=new Blob([c],{type:"image/png"}),p=l.name.split("/").pop()||l.name;console.log(`Processing ${p}, uint8array length: ${c.length}, blob size: ${d.size}`);let u;try{u=await this.blobToDataUrl(d)}catch(m){console.warn(`FileReader failed for ${p}, using fallback:`,m),u=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(c)))}`}if(console.log(`Data URL length: ${u.length}, starts with: ${u.substring(0,50)}...`),!u.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${p}:`,u.substring(0,100));continue}let g=this.inferAssetCategory(p.replace(".png",""));console.log(`Saving ${p} to category: ${g}`);let h=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:g,filename:p,data:u,overwrite:!0})})).json();if(console.log(`Save result for ${p}:`,h),h.success){console.log(`\u2705 Saved PNG to library: ${p} (${g}) at ${h.path}`);let m=new File([d],p,{type:"image/png"});a.set(p,m)}else console.warn(`\u274C Failed to save ${p}:`,h.error)}catch(c){console.warn(`Failed to extract ${l.name}:`,c)}this.uploadedJsons.clear(),n.forEach(({name:l,content:c})=>{c&&this.uploadedJsons.set(l,c)}),this.assetFiles=a;try{this.normalizedManifest=Qi(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let l=[];for(let[d,p]of a){let u=await this.fileToDataUrl(p);l.push({id:d.replace(".png",""),filename:d,dataUrl:u,category:this.inferAssetCategory(d.replace(".png",""))})}this.normalizedManifest&&(this.normalizedManifest.assets=l);let c=l.length;this.setStatus("zip",`\u2705 Processed: ${n.length} JSONs, ${c} PNGs
1395
- \u{1F3F7}\uFE0F Brand: ${((o=this.normalizedManifest)==null?void 0:o.brand_name)||"Imported Brand"}`),this.addAssetsToRegistry(l),this.refreshLibrary()}catch(l){console.error("[BrandVision] Failed to normalize ZIP manifest:",l),this.normalizedManifest=null,this.setStatus("zip","\u274C Failed to normalize manifest")}}async fileToDataUrl(e){return new Promise((t,n)=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=n,i.readAsDataURL(e)})}async blobToDataUrl(e){return new Promise((t,n)=>{let i=new FileReader;i.onload=()=>{let a=i.result;console.log("FileReader result type:",typeof a,"length:",a.length),console.log("Data URL prefix:",a.substring(0,30)),t(a)},i.onerror=a=>{console.error("FileReader error:",a),n(a)},i.readAsDataURL(e)})}inferAssetCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"misc"}addAssetsToRegistry(e){let t=window.getEditableAssets;if(typeof t!="function")return;let n=t();if(!(n!=null&&n.libraryAssets))return;let i={};for(let a of e){let r=a.category||"misc";i[r]||(i[r]=[]),n.libraryAssets[r]||(n.libraryAssets[r]=[]),n.libraryAssets[r].some(l=>l.filename===a.filename)||(n.libraryAssets[r].unshift({filename:a.filename,displayName:a.id.replace(/_/g," ").replace(/\b\w/g,l=>l.toUpperCase())}),console.log(`[BrandVision] Added ${a.filename} to registry category ${r}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var a;let t=e.target,n=t.files;if(!n||n.length===0)return;this.uploadedJsons.clear(),this.normalizedManifest=null,this.mappingResult=null;let i="";for(let r of Array.from(n))try{let o=await r.text(),l=JSON.parse(o);this.uploadedJsons.set(r.name,l),l.layers?i+=`\u2705 Layers: ${r.name}
1396
- `:l.brand_dna||l.colors?i+=`\u2705 Brand: ${r.name}
1397
- `:i+=`\u2705 Loaded: ${r.name}
1398
- `}catch{i+=`\u274C Error in ${r.name}
1399
- `}try{this.normalizedManifest=Qi(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let r=Array.isArray((a=this.normalizedManifest)==null?void 0:a.assets)?this.normalizedManifest.assets.length:0;i+=`
1400
- \u{1F4E6} Normalized manifest: ${r} assets`,i+=`
1401
- \u{1F3F7}\uFE0F Brand: ${this.normalizedManifest.brand_name||"Imported Brand"}`,console.info("[BrandVision] Normalized manifest",{jsonFiles:Array.from(this.uploadedJsons.keys()),assetsType:typeof this.normalizedManifest.assets,assetsCount:r,brandName:this.normalizedManifest.brand_name})}catch(r){console.error("[BrandVision] Failed to normalize manifest:",r),this.normalizedManifest=null,i+=`
1402
- \u274C Failed to normalize manifest`}t.value="",this.setStatus("manifest",i.trim())}async handleAssetsUpload(e){let n=e.target.files;if(!(!n||n.length===0)){for(let i of Array.from(n))this.assetFiles.set(i.name,i);this.setStatus("assets",`${this.assetFiles.size} files loaded`)}}async handleFlatDesignUpload(e){var a,r;let n=(a=e.target.files)==null?void 0:a[0];if(!n)return;let i=await Pe(n);if(i){this.flatDesignDataUrl=i.dataUrl,this.setStatus("flat",n.name);let o=(r=this.root)==null?void 0:r.querySelector("[data-vision-flat-preview]");o&&(o.innerHTML=`<img src="${i.dataUrl}" style="max-width:100%;max-height:100px;border-radius:4px;">`)}}async runAnalysis(){var n,i,a,r,o,l,c;if(this.isAnalyzing)return;let e=(a=(i=(n=this.root)==null?void 0:n.querySelector("[data-vision-api-key]"))==null?void 0:i.value)==null?void 0:a.trim();if(!e){this.setStatus("upload","Missing API key");return}let t=this.manifest;if(!t){this.setStatus("upload","Upload manifest first");return}Array.isArray(t.assets)||console.warn("[BrandVision] Manifest assets not array at analysis time; continuing with normalization fallback.",{assets:t.assets}),this.isAnalyzing=!0,this.setStatus("upload","Analyzing...");try{await er(t,this.assetFiles);let d={apiKey:e,manifest:t,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()},p=await Zs(d);this.mappingResult=p.mappingResult,this.analysisRawResponse=p.rawResponse,this.analysisParsedOk=p.parsed,this.analysisParseError=(r=p.parseError)!=null?r:null,this.renderMappings(),p.parsed?(this.setStatus("upload","Analysis complete"),this.setStatus("mapping",`${(c=(l=(o=this.mappingResult)==null?void 0:o.mappings)==null?void 0:l.length)!=null?c:0} objects mapped`)):(this.setStatus("upload","Analysis response was not JSON"),this.setStatus("mapping",`Parse failed: ${p.parseError||"Unknown error"}`)),this.switchTab("mapping")}catch(d){console.error("[BrandVision] Analysis failed:",d),this.setStatus("upload","Analysis failed")}finally{this.isAnalyzing=!1}}async generateAllMissing(){var t,n,i;if(this.isGenerating||!this.mappingResult||!this.manifest)return;let e=(i=(n=(t=this.root)==null?void 0:t.querySelector("[data-vision-api-key]"))==null?void 0:n.value)==null?void 0:i.trim();if(!e){this.setStatus("apply","Missing API key");return}this.isGenerating=!0;try{let a={apiKey:e,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await ea(a,this.mappingResult,{onProgress:(r,o,l)=>{this.setStatus("apply",`Generating ${r}/${o}: ${l}`),this.renderMappings()}}),this.setStatus("apply","Generation complete"),this.renderMappings()}catch(a){console.error("[BrandVision] Generation failed:",a),this.setStatus("apply","Generation failed")}finally{this.isGenerating=!1}}renderMappings(){var o;let e=(o=this.root)==null?void 0:o.querySelector("[data-vision-mappings]");if(!e||!this.mappingResult)return;let t=this.manifest,n=this.getEngineAssets(),i=!!this.analysisRawResponse&&this.analysisParsedOk===!1,a=((t==null?void 0:t.assets)||[]).map(l=>`<option value="${l.id}">${l.id}</option>`).join(""),r=i?`
1479
+ `}initialize(e,t){this.root=e.querySelector('[data-panel="brand-vision"]'),this.onClose=t,this.root&&(this.attachEventListeners(),this.setupResizeHandle())}attachEventListeners(){var t,i,n,a,r,o,l,c,d,p,u,g,h;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let f="/dashboard";window.location.pathname!==f&&(window.location.href=f)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(f=>{f.addEventListener("click",()=>{let m=f.dataset.visionTab;this.switchTab(m)})}),(i=this.root.querySelector("[data-vision-upload-method]"))==null||i.addEventListener("change",f=>{let m=f.target.value;this.switchUploadMethod(m)}),(n=this.root.querySelector("[data-vision-upload-manifest]"))==null||n.addEventListener("click",()=>{var f,m;(m=(f=this.root)==null?void 0:f.querySelector("[data-vision-manifest-input]"))==null||m.click()}),(a=this.root.querySelector("[data-vision-upload-zip]"))==null||a.addEventListener("click",()=>{var f,m;(m=(f=this.root)==null?void 0:f.querySelector("[data-vision-zip-input]"))==null||m.click()}),(r=this.root.querySelector("[data-vision-zip-input]"))==null||r.addEventListener("change",f=>{this.handleZipUpload(f)}),(o=this.root.querySelector("[data-vision-manifest-input]"))==null||o.addEventListener("change",f=>{this.handleManifestUpload(f)}),(l=this.root.querySelector("[data-vision-upload-assets]"))==null||l.addEventListener("click",()=>{var f,m;(m=(f=this.root)==null?void 0:f.querySelector("[data-vision-assets-input]"))==null||m.click()}),(c=this.root.querySelector("[data-vision-assets-input]"))==null||c.addEventListener("change",f=>{this.handleAssetsUpload(f)}),(d=this.root.querySelector("[data-vision-upload-flat]"))==null||d.addEventListener("click",()=>{var f,m;(m=(f=this.root)==null?void 0:f.querySelector("[data-vision-flat-input]"))==null||m.click()}),(p=this.root.querySelector("[data-vision-flat-input]"))==null||p.addEventListener("change",f=>{this.handleFlatDesignUpload(f)}),(u=this.root.querySelector("[data-vision-analyze]"))==null||u.addEventListener("click",()=>{this.runAnalysis()}),(g=this.root.querySelector("[data-vision-generate-all]"))==null||g.addEventListener("click",()=>{this.generateAllMissing()}),(h=this.root.querySelector("[data-vision-apply-all]"))==null||h.addEventListener("click",()=>{this.applyAll()});let e=this.root.querySelector("[data-vision-mappings]");e==null||e.addEventListener("click",f=>{let m=f.target;if(!m)return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;y&&(m.closest("[data-mapping-apply-one]")&&this.applyOne(y),m.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(y),m.closest("[data-mapping-edit-one]")&&this.openEditorForOne(y),m.closest("[data-mapping-generate-one]")&&this.generateOne(y),m.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",f=>{let m=f.target;if(!m||!this.mappingResult)return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;if(!y)return;let v=this.mappingResult.mappings.find(w=>w.game_object===y);v&&(m.matches("[data-mapping-action]")&&(v.action=String(m.value||"KEEP"),v.status="Edited",this.renderMappings()),m.matches("[data-mapping-brand-asset]")&&(v.brand_asset=String(m.value||""),v.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",f=>{let m=f.target;if(!m||!this.mappingResult||!m.matches("[data-mapping-prompt]"))return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;if(!y)return;let v=this.mappingResult.mappings.find(w=>w.game_object===y);v&&(v.generation_prompt=String(m.value||""),v.status="Edited")})}switchTab(e){var t,i;this.root&&(this.currentTab=e,this.root.querySelectorAll("[data-vision-tab]").forEach(n=>n.classList.remove("active")),this.root.querySelectorAll("[data-vision-content]").forEach(n=>n.classList.remove("active")),(t=this.root.querySelector(`[data-vision-tab="${e}"]`))==null||t.classList.add("active"),(i=this.root.querySelector(`[data-vision-content="${e}"]`))==null||i.classList.add("active"))}switchUploadMethod(e){var t;this.root&&(this.uploadMethod=e,this.root.querySelectorAll("[data-vision-upload-section]").forEach(i=>{i.classList.remove("active")}),(t=this.root.querySelector(`[data-vision-upload-section="${e}"]`))==null||t.classList.add("active"))}async handleZipUpload(e){var n;let i=(n=e.target.files)==null?void 0:n[0];if(i){this.zipFile=i,this.setStatus("zip",`Selected: ${i.name} (${(i.size/1024/1024).toFixed(2)} MB)`);try{await this.processZipFile(i)}catch(a){console.error("[BrandVision] ZIP processing failed:",a),this.setStatus("zip",`Error: ${a instanceof Error?a.message:"Unknown error"}`)}}}async processZipFile(e){var l,c;let t=await ur.loadAsync(e),i=[],n=[];t.forEach((d,p)=>{let u=d.toLowerCase();u.endsWith(".json")?i.push({name:d,content:null}):u.startsWith("assets/")&&u.endsWith(".png")&&n.push({name:d,file:p})});for(let d of i)try{let p=await((l=t.file(d.name))==null?void 0:l.async("text"));p&&(d.content=JSON.parse(p))}catch(p){console.warn(`Failed to parse ${d.name}:`,p)}let a=[];for(let d of n)try{let p=await d.file.async("uint8array"),u=new Blob([p],{type:"image/png"}),g=d.name.split("/").pop()||d.name;console.log(`Processing ${g}, uint8array length: ${p.length}, blob size: ${u.size}`);let h;try{h=await this.blobToDataUrl(u)}catch(f){console.warn(`FileReader failed for ${g}, using fallback:`,f),h=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(p)))}`}if(!h.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${g}:`,h.substring(0,100));continue}a.push({filename:g,dataUrl:h})}catch(p){console.warn(`Failed to extract ${d.name}:`,p)}let r=null;for(let d of i){let p=d.name.toLowerCase();if(p.includes("positionnormalizedpack")||p.includes("positionnormalized")){r=d.content;break}}a.length>0&&await this.showCanvaZipWizard(a,r);let o=new Map;for(let d of a)try{let u=await(await fetch(d.dataUrl)).blob(),g=new File([u],d.filename,{type:"image/png"});o.set(d.filename,g)}catch(p){console.warn(`Failed to convert ${d.filename} to file:`,p)}this.uploadedJsons.clear(),i.forEach(({name:d,content:p})=>{p&&this.uploadedJsons.set(d,p)}),this.assetFiles=o;try{this.normalizedManifest=ra(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let d=[];for(let[u,g]of o){let h=await this.fileToDataUrl(g);d.push({id:u.replace(".png",""),filename:u,dataUrl:h,category:this.inferAssetCategory(u.replace(".png",""))})}this.normalizedManifest&&(this.normalizedManifest.assets=d);let p=d.length;this.setStatus("zip",`\u2705 Processed: ${i.length} JSONs, ${p} PNGs
1480
+ \u{1F3F7}\uFE0F Brand: ${((c=this.normalizedManifest)==null?void 0:c.brand_name)||"Imported Brand"}`),this.addAssetsToRegistry(d),this.refreshLibrary()}catch(d){console.error("[BrandVision] Failed to normalize ZIP manifest:",d),this.normalizedManifest=null,this.setStatus("zip","\u274C Failed to normalize manifest")}}async fileToDataUrl(e){return new Promise((t,i)=>{let n=new FileReader;n.onload=()=>t(n.result),n.onerror=i,n.readAsDataURL(e)})}async showCanvaZipWizard(e,t){return new Promise((i,n)=>{let a=document.createElement("div");document.body.appendChild(a),new Yi().initialize(a,e,t,{onComplete:o=>{console.log("[BrandVision] Wizard completed, processed assets:",o),a.remove(),i()},onCancel:()=>{console.log("[BrandVision] Wizard cancelled"),a.remove(),i()}})})}async blobToDataUrl(e){return new Promise((t,i)=>{let n=new FileReader;n.onload=()=>{let a=n.result;console.log("FileReader result type:",typeof a,"length:",a.length),console.log("Data URL prefix:",a.substring(0,30)),t(a)},n.onerror=a=>{console.error("FileReader error:",a),i(a)},n.readAsDataURL(e)})}inferAssetCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"misc"}addAssetsToRegistry(e){let t=window.getEditableAssets;if(typeof t!="function")return;let i=t();if(!(i!=null&&i.libraryAssets))return;let n={};for(let a of e){let r=a.category||"misc";n[r]||(n[r]=[]),i.libraryAssets[r]||(i.libraryAssets[r]=[]),i.libraryAssets[r].some(l=>l.filename===a.filename)||(i.libraryAssets[r].unshift({filename:a.filename,displayName:a.id.replace(/_/g," ").replace(/\b\w/g,l=>l.toUpperCase())}),console.log(`[BrandVision] Added ${a.filename} to registry category ${r}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var a;let t=e.target,i=t.files;if(!i||i.length===0)return;this.uploadedJsons.clear(),this.normalizedManifest=null,this.mappingResult=null;let n="";for(let r of Array.from(i))try{let o=await r.text(),l=JSON.parse(o);this.uploadedJsons.set(r.name,l),l.layers?n+=`\u2705 Layers: ${r.name}
1481
+ `:l.brand_dna||l.colors?n+=`\u2705 Brand: ${r.name}
1482
+ `:n+=`\u2705 Loaded: ${r.name}
1483
+ `}catch{n+=`\u274C Error in ${r.name}
1484
+ `}try{this.normalizedManifest=ra(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let r=Array.isArray((a=this.normalizedManifest)==null?void 0:a.assets)?this.normalizedManifest.assets.length:0;n+=`
1485
+ \u{1F4E6} Normalized manifest: ${r} assets`,n+=`
1486
+ \u{1F3F7}\uFE0F Brand: ${this.normalizedManifest.brand_name||"Imported Brand"}`,console.info("[BrandVision] Normalized manifest",{jsonFiles:Array.from(this.uploadedJsons.keys()),assetsType:typeof this.normalizedManifest.assets,assetsCount:r,brandName:this.normalizedManifest.brand_name})}catch(r){console.error("[BrandVision] Failed to normalize manifest:",r),this.normalizedManifest=null,n+=`
1487
+ \u274C Failed to normalize manifest`}t.value="",this.setStatus("manifest",n.trim())}async handleAssetsUpload(e){let i=e.target.files;if(!(!i||i.length===0)){for(let n of Array.from(i))this.assetFiles.set(n.name,n);this.setStatus("assets",`${this.assetFiles.size} files loaded`)}}async handleFlatDesignUpload(e){var a,r;let i=(a=e.target.files)==null?void 0:a[0];if(!i)return;let n=await Oe(i);if(n){this.flatDesignDataUrl=n.dataUrl,this.setStatus("flat",i.name);let o=(r=this.root)==null?void 0:r.querySelector("[data-vision-flat-preview]");o&&(o.innerHTML=`<img src="${n.dataUrl}" style="max-width:100%;max-height:100px;border-radius:4px;">`)}}async runAnalysis(){var i,n,a,r,o,l,c;if(this.isAnalyzing)return;let e=(a=(n=(i=this.root)==null?void 0:i.querySelector("[data-vision-api-key]"))==null?void 0:n.value)==null?void 0:a.trim();if(!e){this.setStatus("upload","Missing API key");return}let t=this.manifest;if(!t){this.setStatus("upload","Upload manifest first");return}Array.isArray(t.assets)||console.warn("[BrandVision] Manifest assets not array at analysis time; continuing with normalization fallback.",{assets:t.assets}),this.isAnalyzing=!0,this.setStatus("upload","Analyzing...");try{await sr(t,this.assetFiles);let d={apiKey:e,manifest:t,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()},p=await nr(d);this.mappingResult=p.mappingResult,this.analysisRawResponse=p.rawResponse,this.analysisParsedOk=p.parsed,this.analysisParseError=(r=p.parseError)!=null?r:null,this.renderMappings(),p.parsed?(this.setStatus("upload","Analysis complete"),this.setStatus("mapping",`${(c=(l=(o=this.mappingResult)==null?void 0:o.mappings)==null?void 0:l.length)!=null?c:0} objects mapped`)):(this.setStatus("upload","Analysis response was not JSON"),this.setStatus("mapping",`Parse failed: ${p.parseError||"Unknown error"}`)),this.switchTab("mapping")}catch(d){console.error("[BrandVision] Analysis failed:",d),this.setStatus("upload","Analysis failed")}finally{this.isAnalyzing=!1}}async generateAllMissing(){var t,i,n;if(this.isGenerating||!this.mappingResult||!this.manifest)return;let e=(n=(i=(t=this.root)==null?void 0:t.querySelector("[data-vision-api-key]"))==null?void 0:i.value)==null?void 0:n.trim();if(!e){this.setStatus("apply","Missing API key");return}this.isGenerating=!0;try{let a={apiKey:e,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await oa(a,this.mappingResult,{onProgress:(r,o,l)=>{this.setStatus("apply",`Generating ${r}/${o}: ${l}`),this.renderMappings()}}),this.setStatus("apply","Generation complete"),this.renderMappings()}catch(a){console.error("[BrandVision] Generation failed:",a),this.setStatus("apply","Generation failed")}finally{this.isGenerating=!1}}renderMappings(){var o;let e=(o=this.root)==null?void 0:o.querySelector("[data-vision-mappings]");if(!e||!this.mappingResult)return;let t=this.manifest,i=this.getEngineAssets(),n=!!this.analysisRawResponse&&this.analysisParsedOk===!1,a=((t==null?void 0:t.assets)||[]).map(l=>`<option value="${l.id}">${l.id}</option>`).join(""),r=n?`
1403
1488
  <div class="vision-raw-block">
1404
1489
  <div class="inspector-text-sm" style="white-space: pre-wrap;">
1405
1490
  \u26A0\uFE0F AI response was not valid JSON (${this.analysisParseError||"unknown error"}).
@@ -1409,7 +1494,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1409
1494
  </div>
1410
1495
  `:"";e.innerHTML=`
1411
1496
  ${r}
1412
- ${this.mappingResult.mappings.map(l=>{var b;let c=n[l.game_object]||"",d=l.brand_asset||"",p=(b=t==null?void 0:t.assets)==null?void 0:b.find(y=>y.id===d),u=(p==null?void 0:p.dataUrl)||"",g=l.output_dataUrl||"",f=l.action==="GENERATE"?g:l.action==="APPLY"?u:"",h=!!f,m=`
1497
+ ${this.mappingResult.mappings.map(l=>{var b;let c=i[l.game_object]||"",d=l.brand_asset||"",p=(b=t==null?void 0:t.assets)==null?void 0:b.find(y=>y.id===d),u=(p==null?void 0:p.dataUrl)||"",g=l.output_dataUrl||"",h=l.action==="GENERATE"?g:l.action==="APPLY"?u:"",f=!!h,m=`
1413
1498
  <select class="inspector-input" data-mapping-brand-asset style="flex:1; padding:6px 8px;">
1414
1499
  <option value="">Select brand asset\u2026</option>
1415
1500
  ${a.replace(`value="${d}"`,`value="${d}" selected`)}
@@ -1450,7 +1535,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1450
1535
  </div>
1451
1536
  <div class="vision-mapping-preview">
1452
1537
  <div class="inspector-text-sm" style="opacity:0.8;">Preview</div>
1453
- ${h?`<img src="${f}">`:'<div class="inspector-text-sm" style="opacity:0.6;">None</div>'}
1538
+ ${f?`<img src="${h}">`:'<div class="inspector-text-sm" style="opacity:0.6;">None</div>'}
1454
1539
  </div>
1455
1540
  </div>
1456
1541
 
@@ -1461,8 +1546,8 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1461
1546
  </div>
1462
1547
  </div>
1463
1548
  `}).join("")}
1464
- `}async applyAll(){let e=await this.stageOverridesFromMappings({saveToLibrary:!1});this.setStatus("apply",e>0?`Staged ${e} asset overrides`:"No assets to stage")}getEngineAssets(){let e=window.getEditableEngineConfig;if(typeof e!="function")return{};let t=e();return t!=null&&t.assets&&typeof t.assets=="object"?t.assets:{}}getPreviewValueForMapping(e){if(!this.mappingResult||!this.manifest)return{value:null,source:"none"};let t=this.mappingResult.mappings.find(n=>n.game_object===e);if(!t)return{value:null,source:"none"};if(t.action==="GENERATE"&&t.output_dataUrl)return{value:t.output_dataUrl,source:"generated"};if(t.action==="APPLY"&&t.brand_asset){let n=this.manifest.assets.find(i=>i.id===t.brand_asset);if(n!=null&&n.dataUrl)return{value:n.dataUrl,source:"brand"}}return{value:null,source:"none"}}async stageOverridesFromMappings(e){if(!this.mappingResult)return 0;let t=0;for(let n of this.mappingResult.mappings){if(n.action==="KEEP"||n.action==="APPLY"&&!n.brand_asset||n.action==="GENERATE"&&!n.output_dataUrl)continue;let i=n.game_object,a=this.getPreviewValueForMapping(i);if(!a.value)continue;let r=e.saveToLibrary?await this.saveToLibraryAndReturnPath(i,a.value):a.value;r&&(await this.stageEngineAssetOverride(i,r),n.status=e.saveToLibrary?"Saved + staged \u2713":"Staged \u2713",t++)}return this.renderMappings(),t}async applyOne(e){var i;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to apply for ${e}`);return}await this.stageEngineAssetOverride(e,t.value);let n=(i=this.mappingResult)==null?void 0:i.mappings.find(a=>a.game_object===e);n&&(n.status="Staged \u2713"),this.renderMappings(),this.setStatus("apply",`Staged override for ${e}`)}async saveAndApplyOne(e){var a;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to save for ${e}`);return}let n=await this.saveToLibraryAndReturnPath(e,t.value);if(!n){this.setStatus("apply",`Save failed for ${e}`);return}await this.stageEngineAssetOverride(e,n);let i=(a=this.mappingResult)==null?void 0:a.mappings.find(r=>r.game_object===e);i&&(i.status="Saved + staged \u2713"),this.renderMappings(),this.setStatus("apply",`Saved + staged ${e}`)}openEditorForOne(e){if(!this.mappingResult)return;let t=this.mappingResult.mappings.find(r=>r.game_object===e);if(!t)return;let n=this.getPreviewValueForMapping(e),i=window.__openAiEditor;if(typeof i!="function"){this.setStatus("apply","AI editor not available");return}let a=t.action==="GENERATE"?t.generation_prompt:void 0;i(e,a,n.value||void 0,{path:`assets.${e}`})}async generateOne(e){var i,a,r;if(!this.mappingResult||this.isGenerating)return;let t=this.mappingResult.mappings.find(o=>o.game_object===e);if(!t)return;if(t.action="GENERATE",!t.generation_prompt){t.status="Missing prompt",this.renderMappings();return}let n=(r=(a=(i=this.root)==null?void 0:i.querySelector("[data-vision-api-key]"))==null?void 0:a.value)==null?void 0:r.trim();if(!n||!this.manifest){this.setStatus("apply","Missing API key or manifest");return}this.isGenerating=!0,t.status="Generating\u2026",this.renderMappings();try{let o={apiKey:n,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await ea(o,{mappings:[t]}),t.status=t.output_dataUrl?"Generated \u2713":t.status||"Done"}catch(o){console.error("[BrandVision] generateOne failed:",o),t.status="Failed \u2717"}finally{this.isGenerating=!1,this.renderMappings()}}async stageEngineAssetOverride(e,t){let{applyConfigOverride:n}=await Promise.resolve().then(()=>(J(),Be));n({path:`assets.${e}`,value:t},{silent:!0});let i=window.applyEditableEngineConfig;typeof i=="function"&&i({assets:{[e]:t}})}async saveToLibraryAndReturnPath(e,t){if(!/^(data:|blob:)/.test(t))return t;let n=this.inferCategoryFromAssetKey(e),i=`${e.replace(/[^a-zA-Z0-9_-]/g,"_")}_vision_${Date.now()}.png`;try{let r=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:n,filename:i,data:t,overwrite:!0})})).json();if(!(r!=null&&r.success)||!(r!=null&&r.path))return console.error("[BrandVision] Save to library failed:",(r==null?void 0:r.error)||r),null;let o=window.addAssetToRegistry;typeof o=="function"&&o(n,i);let l=window.refreshAssetLibrary;return typeof l=="function"&&l(),String(r.path)}catch(a){return console.error("[BrandVision] Save to library error:",a),null}}inferCategoryFromAssetKey(e){let t=window.getEditableAssets;if(typeof t=="function"){let i=t();if(i!=null&&i.slots&&Array.isArray(i.slots)){let r=i.slots.find(o=>o.slotId===e||o.currentAsset===e);if(r!=null&&r.category)return String(r.category)}let a=i==null?void 0:i.categories;if(Array.isArray(a)&&a.length>0){let r=e.toLowerCase(),o=l=>a.find(c=>c.toLowerCase().includes(l));return r.includes("bg")||r.includes("background")?o("background")||a[0]:(r.includes("cta")||r.includes("button")||r.includes("ui")||r.includes("logo"))&&o("ui")||a[0]}}let n=e.toLowerCase();return n.includes("bg")||n.includes("background")?"backgrounds":n.includes("cta")||n.includes("button")||n.includes("ui")||n.includes("logo")?"ui":"misc"}async copyRawAnalysis(){if(this.analysisRawResponse)try{await navigator.clipboard.writeText(this.analysisRawResponse),this.setStatus("mapping","Copied raw analysis to clipboard")}catch{this.setStatus("mapping","Clipboard not available")}}setStatus(e,t){var a;let n={manifest:"[data-vision-manifest-status]",assets:"[data-vision-assets-status]",flat:"[data-vision-flat-status]",zip:"[data-vision-zip-status]",upload:"[data-vision-upload-status]",mapping:"[data-vision-mapping-status]",apply:"[data-vision-apply-status]"},i=(a=this.root)==null?void 0:a.querySelector(n[e]);i&&(i.textContent=t)}getGameObjects(){let e=window.getEditableObjectList;return typeof e=="function"?e():[]}async getGamePrompt(){try{let e=await fetch("./configs/engine/game.prompt.json");if(e.ok)return(await e.json()).game_prompt||""}catch{}return""}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");e&&e.addEventListener("pointerdown",t=>{let n=t.clientX,i=this.root.getBoundingClientRect().width,a=o=>{let l=Math.max(300,i+(o.clientX-n));this.root.style.width=`${l}px`},r=()=>{window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",r)};window.addEventListener("pointermove",a),window.addEventListener("pointerup",r)})}refresh(){}};function nr(s,e={}){let{includeReference:t=!1,includeMagenta:n=!0,changeLevel:i=5}=e;return[`TASK: ${s}`,`CHANGE_STRENGTH: ${i}/10`,t?"REFERENCE: provided":"REFERENCE: none",n?"BACKGROUND: solid magenta #FF00FF (if possible)":""].filter(Boolean).join(`
1465
- `)}var il=["background_color","text_color","cta_background","cta_text","warning_text_color","endgame_title_color","endgame_subtitle_color","endgame_cta_text_color","endgame_cta_hint_color","endgame_footer_color"],al=["cta_hint","cta_label_end"],ir=[{key:"warning_text",objectId:"label.warning",property:"ui.text"},{key:"endgame_title",objectId:"ui.endgame.title",property:"ui.text"},{key:"endgame_subtitle",objectId:"ui.endgame.subtitle",property:"ui.text"},{key:"endgame_cta_text",objectId:"ui.endgame.cta",property:"ui.text"},{key:"endgame_cta_hint_text",objectId:"ui.endgame.cta.hint",property:"ui.text"},{key:"endgame_footer_text",objectId:"ui.endgame.footer",property:"ui.text"}],sl=["brand.primary","brand.heading","brand.body","brand.warning"],Vn=class{constructor(){this.root=null;this.assetsContainer=null;this.colorsContainer=null;this.fontsContainer=null;this.textsContainer=null;this.audioContainer=null;this.options=null;this.previewModal=null;this.autoApplyTimer=null;this.activePreviewKey=null;this.activePreviewValue=null;this.activePreviewFileInput=null;this.retryTimer=null;this.aiModal=null;this.aiTargetKey=null;this.aiKeyInput=null;this.aiPromptInput=null;this.aiStrengthInput=null;this.aiStrengthValue=null;this.aiModelSelect=null;this.aiModalSubtitle=null;this.aiGalleryToggle=null;this.aiGalleryEl=null;this.aiGalleryGrid=null;this.aiReferenceInput=null;this.aiReferenceName=null;this.aiReferenceFile=null;this.aiRemoveBgToggle=null;this.aiUseOutputToggle=null;this.aiGenerateBtn=null;this.aiApplyBtn=null;this.aiSaveLibraryBtn=null;this.aiCropBtn=null;this.aiDownloadBtn=null;this.aiPreviewImg=null;this.aiStatusEl=null;this.aiOutputDataUrl=null;this.aiBaseDataUrl=null;this.aiBaseValue=null;this.aiOutputKey=null;this.aiContext=null;this.aiBgToleranceInput=null;this.aiBgToleranceValue=null;this.aiRawOutputDataUrl=null;this.aiLoadingEl=null}render(){return`
1549
+ `}async applyAll(){let e=await this.stageOverridesFromMappings({saveToLibrary:!1});this.setStatus("apply",e>0?`Staged ${e} asset overrides`:"No assets to stage")}getEngineAssets(){let e=window.getEditableEngineConfig;if(typeof e!="function")return{};let t=e();return t!=null&&t.assets&&typeof t.assets=="object"?t.assets:{}}getPreviewValueForMapping(e){if(!this.mappingResult||!this.manifest)return{value:null,source:"none"};let t=this.mappingResult.mappings.find(i=>i.game_object===e);if(!t)return{value:null,source:"none"};if(t.action==="GENERATE"&&t.output_dataUrl)return{value:t.output_dataUrl,source:"generated"};if(t.action==="APPLY"&&t.brand_asset){let i=this.manifest.assets.find(n=>n.id===t.brand_asset);if(i!=null&&i.dataUrl)return{value:i.dataUrl,source:"brand"}}return{value:null,source:"none"}}async stageOverridesFromMappings(e){if(!this.mappingResult)return 0;let t=0;for(let i of this.mappingResult.mappings){if(i.action==="KEEP"||i.action==="APPLY"&&!i.brand_asset||i.action==="GENERATE"&&!i.output_dataUrl)continue;let n=i.game_object,a=this.getPreviewValueForMapping(n);if(!a.value)continue;let r=e.saveToLibrary?await this.saveToLibraryAndReturnPath(n,a.value):a.value;r&&(await this.stageEngineAssetOverride(n,r),i.status=e.saveToLibrary?"Saved + staged \u2713":"Staged \u2713",t++)}return this.renderMappings(),t}async applyOne(e){var n;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to apply for ${e}`);return}await this.stageEngineAssetOverride(e,t.value);let i=(n=this.mappingResult)==null?void 0:n.mappings.find(a=>a.game_object===e);i&&(i.status="Staged \u2713"),this.renderMappings(),this.setStatus("apply",`Staged override for ${e}`)}async saveAndApplyOne(e){var a;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to save for ${e}`);return}let i=await this.saveToLibraryAndReturnPath(e,t.value);if(!i){this.setStatus("apply",`Save failed for ${e}`);return}await this.stageEngineAssetOverride(e,i);let n=(a=this.mappingResult)==null?void 0:a.mappings.find(r=>r.game_object===e);n&&(n.status="Saved + staged \u2713"),this.renderMappings(),this.setStatus("apply",`Saved + staged ${e}`)}openEditorForOne(e){if(!this.mappingResult)return;let t=this.mappingResult.mappings.find(r=>r.game_object===e);if(!t)return;let i=this.getPreviewValueForMapping(e),n=window.__openAiEditor;if(typeof n!="function"){this.setStatus("apply","AI editor not available");return}let a=t.action==="GENERATE"?t.generation_prompt:void 0;n(e,a,i.value||void 0,{path:`assets.${e}`})}async generateOne(e){var n,a,r;if(!this.mappingResult||this.isGenerating)return;let t=this.mappingResult.mappings.find(o=>o.game_object===e);if(!t)return;if(t.action="GENERATE",!t.generation_prompt){t.status="Missing prompt",this.renderMappings();return}let i=(r=(a=(n=this.root)==null?void 0:n.querySelector("[data-vision-api-key]"))==null?void 0:a.value)==null?void 0:r.trim();if(!i||!this.manifest){this.setStatus("apply","Missing API key or manifest");return}this.isGenerating=!0,t.status="Generating\u2026",this.renderMappings();try{let o={apiKey:i,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await oa(o,{mappings:[t]}),t.status=t.output_dataUrl?"Generated \u2713":t.status||"Done"}catch(o){console.error("[BrandVision] generateOne failed:",o),t.status="Failed \u2717"}finally{this.isGenerating=!1,this.renderMappings()}}async stageEngineAssetOverride(e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(K(),Ge));i({path:`assets.${e}`,value:t},{silent:!0});let n=window.applyEditableEngineConfig;typeof n=="function"&&n({assets:{[e]:t}})}async saveToLibraryAndReturnPath(e,t){if(!/^(data:|blob:)/.test(t))return t;let i=this.inferCategoryFromAssetKey(e),n=`${e.replace(/[^a-zA-Z0-9_-]/g,"_")}_vision_${Date.now()}.png`;try{let r=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:i,filename:n,data:t,overwrite:!0})})).json();if(!(r!=null&&r.success)||!(r!=null&&r.path))return console.error("[BrandVision] Save to library failed:",(r==null?void 0:r.error)||r),null;let o=window.addAssetToRegistry;typeof o=="function"&&o(i,n);let l=window.refreshAssetLibrary;return typeof l=="function"&&l(),String(r.path)}catch(a){return console.error("[BrandVision] Save to library error:",a),null}}inferCategoryFromAssetKey(e){let t=window.getEditableAssets;if(typeof t=="function"){let n=t();if(n!=null&&n.slots&&Array.isArray(n.slots)){let r=n.slots.find(o=>o.slotId===e||o.currentAsset===e);if(r!=null&&r.category)return String(r.category)}let a=n==null?void 0:n.categories;if(Array.isArray(a)&&a.length>0){let r=e.toLowerCase(),o=l=>a.find(c=>c.toLowerCase().includes(l));return r.includes("bg")||r.includes("background")?o("background")||a[0]:(r.includes("cta")||r.includes("button")||r.includes("ui")||r.includes("logo"))&&o("ui")||a[0]}}let i=e.toLowerCase();return i.includes("bg")||i.includes("background")?"backgrounds":i.includes("cta")||i.includes("button")||i.includes("ui")||i.includes("logo")?"ui":"misc"}async copyRawAnalysis(){if(this.analysisRawResponse)try{await navigator.clipboard.writeText(this.analysisRawResponse),this.setStatus("mapping","Copied raw analysis to clipboard")}catch{this.setStatus("mapping","Clipboard not available")}}setStatus(e,t){var a;let i={manifest:"[data-vision-manifest-status]",assets:"[data-vision-assets-status]",flat:"[data-vision-flat-status]",zip:"[data-vision-zip-status]",upload:"[data-vision-upload-status]",mapping:"[data-vision-mapping-status]",apply:"[data-vision-apply-status]"},n=(a=this.root)==null?void 0:a.querySelector(i[e]);n&&(n.textContent=t)}getGameObjects(){let e=window.getEditableObjectList;return typeof e=="function"?e():[]}async getGamePrompt(){try{let e=await fetch("./configs/engine/game.prompt.json");if(e.ok)return(await e.json()).game_prompt||""}catch{}return""}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");e&&e.addEventListener("pointerdown",t=>{let i=t.clientX,n=this.root.getBoundingClientRect().width,a=o=>{let l=Math.max(300,n+(o.clientX-i));this.root.style.width=`${l}px`},r=()=>{window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",r)};window.addEventListener("pointermove",a),window.addEventListener("pointerup",r)})}refresh(){}};function gr(s,e={}){let{includeReference:t=!1,includeMagenta:i=!0,changeLevel:n=5}=e;return[`TASK: ${s}`,`CHANGE_STRENGTH: ${n}/10`,t?"REFERENCE: provided":"REFERENCE: none",i?"BACKGROUND: solid magenta #FF00FF (if possible)":""].filter(Boolean).join(`
1550
+ `)}var dl=["background_color","text_color","cta_background","cta_text","warning_text_color","endgame_title_color","endgame_subtitle_color","endgame_cta_text_color","endgame_cta_hint_color","endgame_footer_color"],pl=["cta_hint","cta_label_end"],hr=[{key:"warning_text",objectId:"label.warning",property:"ui.text"},{key:"endgame_title",objectId:"ui.endgame.title",property:"ui.text"},{key:"endgame_subtitle",objectId:"ui.endgame.subtitle",property:"ui.text"},{key:"endgame_cta_text",objectId:"ui.endgame.cta",property:"ui.text"},{key:"endgame_cta_hint_text",objectId:"ui.endgame.cta.hint",property:"ui.text"},{key:"endgame_footer_text",objectId:"ui.endgame.footer",property:"ui.text"}],ul=["brand.primary","brand.heading","brand.body","brand.warning"],Xi=class{constructor(){this.root=null;this.assetsContainer=null;this.colorsContainer=null;this.fontsContainer=null;this.textsContainer=null;this.audioContainer=null;this.options=null;this.previewModal=null;this.autoApplyTimer=null;this.activePreviewKey=null;this.activePreviewValue=null;this.activePreviewFileInput=null;this.retryTimer=null;this.aiModal=null;this.aiTargetKey=null;this.aiKeyInput=null;this.aiPromptInput=null;this.aiStrengthInput=null;this.aiStrengthValue=null;this.aiModelSelect=null;this.aiModalSubtitle=null;this.aiGalleryToggle=null;this.aiGalleryEl=null;this.aiGalleryGrid=null;this.aiReferenceInput=null;this.aiReferenceName=null;this.aiReferenceFile=null;this.aiRemoveBgToggle=null;this.aiUseOutputToggle=null;this.aiGenerateBtn=null;this.aiApplyBtn=null;this.aiSaveLibraryBtn=null;this.aiCropBtn=null;this.aiDownloadBtn=null;this.aiPreviewImg=null;this.aiStatusEl=null;this.aiOutputDataUrl=null;this.aiBaseDataUrl=null;this.aiBaseValue=null;this.aiOutputKey=null;this.aiContext=null;this.aiBgToleranceInput=null;this.aiBgToleranceValue=null;this.aiRawOutputDataUrl=null;this.aiLoadingEl=null}render(){return`
1466
1551
  <div class="scene-panel customize-panel panel-accent-blue" data-panel="customize-settings">
1467
1552
  <div class="scene-panel-header" data-panel-handle>
1468
1553
  <div class="panel-title">
@@ -1520,17 +1605,17 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1520
1605
  </div>
1521
1606
  <div class="panel-resize-handle" data-panel-resize></div>
1522
1607
  </div>
1523
- `}initialize(e,t){var i,a,r,o,l,c;this.options=t,this.root=e.querySelector('[data-panel="customize-settings"]'),this.assetsContainer=(i=this.root)==null?void 0:i.querySelector("[data-customize-assets]"),this.colorsContainer=(a=this.root)==null?void 0:a.querySelector("[data-customize-colors]"),this.fontsContainer=(r=this.root)==null?void 0:r.querySelector("[data-customize-fonts]"),this.textsContainer=(o=this.root)==null?void 0:o.querySelector("[data-customize-texts]"),this.audioContainer=(l=this.root)==null?void 0:l.querySelector("[data-customize-audio]");let n=(c=this.root)==null?void 0:c.querySelector("[data-customize-apply]");n==null||n.addEventListener("click",()=>this.handleApply()),this.setupRenderModeHandlers(),this.setupResizeHandle(),this.refresh()}setupRenderModeHandlers(){var n,i;let e=(n=this.root)==null?void 0:n.querySelector('[data-render-mode="endgame-png"]'),t=(i=this.root)==null?void 0:i.querySelector('[data-render-mode="splash-png"]');e==null||e.addEventListener("change",()=>{this.applyEndgamePngMode(e.checked)}),t==null||t.addEventListener("change",()=>{this.applySplashPngMode(t.checked)})}applyEndgamePngMode(e){let t=window.getEditableObjectConfig,n=window.applyEditableObjectConfig;if(typeof t!="function"||typeof n!="function")return;let i=["ui_endgame_title_1","ui_endgame_subtitle_1","ui_endgame_logo_1","ui_endgame_cta_1"];for(let a of i){let r=t(a);r&&(r.ui||(r.ui={}),r.ui.renderMode=e?"png":"text",e&&(r.render||(r.render={}),r.render.asset||(r.render.asset={type:"image",path:""}),r.render.asset.type="image"),n(a,r))}console.log("[CustomizePanel] EndGame PNG mode:",e?"enabled":"disabled")}applySplashPngMode(e){let t=window.applyEditableEngineConfig;typeof t=="function"&&(t({splash:{type:e?"image":"text",image_path:e?"library/splash/splash.png":""}}),console.log("[CustomizePanel] Splash PNG mode:",e?"enabled":"disabled"))}openAiEditor(e,t,n,i){this.openAiModal(e,n,i),t&&this.aiPromptInput&&(this.aiPromptInput.value=t,this.setAiStatus("Prompt loaded."))}refresh(){var t,n,i,a,r,o,l,c;let e=this.getEngineSnapshot();if(console.log("[CustomizePanel] Refreshing with snapshot:",!!e),!e){this.scheduleRetry();return}console.log("[CustomizePanel] Snapshot assets count:",Object.keys(e.assets||{}).length),this.renderAssets(e.assets),this.renderColors((n=(t=e.runtime)==null?void 0:t.theme)!=null?n:{}),this.renderFonts((a=(i=e.runtime)==null?void 0:i.fonts)!=null?a:{}),this.renderTexts((o=(r=e.runtime)==null?void 0:r.ui)!=null?o:{}),this.renderAudio((c=(l=e.runtime)==null?void 0:l.audio)!=null?c:{})}getEngineSnapshot(){let e=window.getEditableEngineConfig;return typeof e!="function"?null:e()}renderAssets(e){if(!this.assetsContainer)return;this.assetsContainer.innerHTML="";let t=Object.entries(e!=null?e:{});if(!t.length){this.assetsContainer.innerHTML='<div class="customize-empty">No assets found.</div>',this.scheduleRetry();return}this.clearRetry(),t.forEach(([n,i])=>{var u;let a=document.createElement("div");a.className="customize-row";let r=document.createElement("span");r.className="customize-key",r.textContent=n;let o=document.createElement("input");o.type="text",o.value=i!=null?i:"",o.className="customize-input",o.dataset.assetKey=n,o.addEventListener("input",()=>{this.handleAssetValueChange(n,o)});let l=document.createElement("div");l.className="customize-actions";let c=document.createElement("button");c.type="button",c.className="customize-icon-btn",c.title="Preview asset",c.innerHTML=`
1608
+ `}initialize(e,t){var n,a,r,o,l,c;this.options=t,this.root=e.querySelector('[data-panel="customize-settings"]'),this.assetsContainer=(n=this.root)==null?void 0:n.querySelector("[data-customize-assets]"),this.colorsContainer=(a=this.root)==null?void 0:a.querySelector("[data-customize-colors]"),this.fontsContainer=(r=this.root)==null?void 0:r.querySelector("[data-customize-fonts]"),this.textsContainer=(o=this.root)==null?void 0:o.querySelector("[data-customize-texts]"),this.audioContainer=(l=this.root)==null?void 0:l.querySelector("[data-customize-audio]");let i=(c=this.root)==null?void 0:c.querySelector("[data-customize-apply]");i==null||i.addEventListener("click",()=>this.handleApply()),this.setupRenderModeHandlers(),this.setupResizeHandle(),this.refresh()}setupRenderModeHandlers(){var i,n;let e=(i=this.root)==null?void 0:i.querySelector('[data-render-mode="endgame-png"]'),t=(n=this.root)==null?void 0:n.querySelector('[data-render-mode="splash-png"]');e==null||e.addEventListener("change",()=>{this.applyEndgamePngMode(e.checked)}),t==null||t.addEventListener("change",()=>{this.applySplashPngMode(t.checked)})}applyEndgamePngMode(e){let t=window.getEditableObjectConfig,i=window.applyEditableObjectConfig;if(typeof t!="function"||typeof i!="function")return;let n=["ui_endgame_title_1","ui_endgame_subtitle_1","ui_endgame_logo_1","ui_endgame_cta_1"];for(let a of n){let r=t(a);r&&(r.ui||(r.ui={}),r.ui.renderMode=e?"png":"text",e&&(r.render||(r.render={}),r.render.asset||(r.render.asset={type:"image",path:""}),r.render.asset.type="image"),i(a,r))}console.log("[CustomizePanel] EndGame PNG mode:",e?"enabled":"disabled")}applySplashPngMode(e){let t=window.applyEditableEngineConfig;typeof t=="function"&&(t({splash:{type:e?"image":"text",image_path:e?"library/splash/splash.png":""}}),console.log("[CustomizePanel] Splash PNG mode:",e?"enabled":"disabled"))}openAiEditor(e,t,i,n){this.openAiModal(e,i,n),t&&this.aiPromptInput&&(this.aiPromptInput.value=t,this.setAiStatus("Prompt loaded."))}refresh(){var t,i,n,a,r,o,l,c;let e=this.getEngineSnapshot();if(console.log("[CustomizePanel] Refreshing with snapshot:",!!e),!e){this.scheduleRetry();return}console.log("[CustomizePanel] Snapshot assets count:",Object.keys(e.assets||{}).length),this.renderAssets(e.assets),this.renderColors((i=(t=e.runtime)==null?void 0:t.theme)!=null?i:{}),this.renderFonts((a=(n=e.runtime)==null?void 0:n.fonts)!=null?a:{}),this.renderTexts((o=(r=e.runtime)==null?void 0:r.ui)!=null?o:{}),this.renderAudio((c=(l=e.runtime)==null?void 0:l.audio)!=null?c:{})}getEngineSnapshot(){let e=window.getEditableEngineConfig;return typeof e!="function"?null:e()}renderAssets(e){if(!this.assetsContainer)return;this.assetsContainer.innerHTML="";let t=Object.entries(e!=null?e:{});if(!t.length){this.assetsContainer.innerHTML='<div class="customize-empty">No assets found.</div>',this.scheduleRetry();return}this.clearRetry(),t.forEach(([i,n])=>{var u;let a=document.createElement("div");a.className="customize-row";let r=document.createElement("span");r.className="customize-key",r.textContent=i;let o=document.createElement("input");o.type="text",o.value=n!=null?n:"",o.className="customize-input",o.dataset.assetKey=i,o.addEventListener("input",()=>{this.handleAssetValueChange(i,o)});let l=document.createElement("div");l.className="customize-actions";let c=document.createElement("button");c.type="button",c.className="customize-icon-btn",c.title="Preview asset",c.innerHTML=`
1524
1609
  <svg viewBox="0 0 24 24" aria-hidden="true">
1525
1610
  <path d="M12 5c5.2 0 9.2 3.7 10 6.8-.8 3.1-4.8 6.8-10 6.8S2.8 14.9 2 11.8C2.8 8.7 6.8 5 12 5z" />
1526
1611
  <circle cx="12" cy="12" r="3.2" />
1527
1612
  </svg>
1528
- `,c.addEventListener("click",()=>{this.previewAsset(n,o.value,o.dataset.assetType,p)});let d=document.createElement("button");d.type="button",d.className="customize-icon-btn",d.title="Upload asset",d.innerHTML=`
1613
+ `,c.addEventListener("click",()=>{this.previewAsset(i,o.value,o.dataset.assetType,p)});let d=document.createElement("button");d.type="button",d.className="customize-icon-btn",d.title="Upload asset",d.innerHTML=`
1529
1614
  <svg viewBox="0 0 24 24" aria-hidden="true">
1530
1615
  <path d="M12 3l4 4h-3v6h-2V7H8l4-4z" />
1531
1616
  <path d="M5 14v4h14v-4h2v6H3v-6h2z" />
1532
1617
  </svg>
1533
- `;let p=document.createElement("input");p.type="file",p.accept="image/*,audio/*,application/json",p.className="customize-file",p.addEventListener("change",()=>{var f;let g=(f=p.files)==null?void 0:f[0];g&&this.handleAssetUpload(g,o,n)}),d.addEventListener("click",()=>p.click()),l.appendChild(c),l.appendChild(d),l.appendChild(p),a.appendChild(r),a.appendChild(o),a.appendChild(l),(u=this.assetsContainer)==null||u.appendChild(a)})}renderColors(e){this.colorsContainer&&(this.colorsContainer.innerHTML="",il.forEach(t=>{var l,c,d;let n=(l=e==null?void 0:e[t])!=null?l:"#ffffff";if(t.includes("_text_color")||t.includes("_color")){let u={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[t];u&&(n=(c=this.getObjectPropertyValue(u.objectId,u.property))!=null?c:"#ffffff")}let i=document.createElement("label");i.className="customize-color-field";let a=document.createElement("span");a.textContent=t.replace(/_/g," ");let r=document.createElement("input");r.type="color",r.value=n,r.dataset.colorKey=t;let o=document.createElement("input");o.type="text",o.value=n,o.className="customize-color-text",o.dataset.colorTextKey=t,r.addEventListener("input",()=>{o.value=r.value}),o.addEventListener("input",()=>{/^#([0-9a-fA-F]{6})$/.test(o.value)&&(r.value=o.value)}),i.appendChild(a),i.appendChild(r),i.appendChild(o),(d=this.colorsContainer)==null||d.appendChild(i)}))}renderFonts(e){this.fontsContainer&&(this.fontsContainer.innerHTML="",sl.forEach(t=>{var r,o;let n=document.createElement("div");n.className="customize-row";let i=document.createElement("span");i.className="customize-key",i.textContent=t;let a=document.createElement("input");a.type="text",a.value=(r=e==null?void 0:e[t])!=null?r:t,a.className="customize-input",a.dataset.fontKey=t,n.appendChild(i),n.appendChild(a),(o=this.fontsContainer)==null||o.appendChild(n)}))}renderTexts(e){this.textsContainer&&(this.textsContainer.innerHTML="",al.forEach(t=>{var r,o;let n=document.createElement("div");n.className="customize-row";let i=document.createElement("span");i.className="customize-key",i.textContent=t;let a=document.createElement("input");a.type="text",a.value=(r=this.readUiValue(e,t))!=null?r:"",a.className="customize-input",a.dataset.textKey=t,n.appendChild(i),n.appendChild(a),(o=this.textsContainer)==null||o.appendChild(n)}),ir.forEach(({key:t,objectId:n})=>{var o,l;let i=document.createElement("div");i.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=t;let r=document.createElement("input");r.type="text",r.value=(o=this.getObjectTextValue(n))!=null?o:"",r.className="customize-input",r.dataset.objectTextKey=t,i.appendChild(a),i.appendChild(r),(l=this.textsContainer)==null||l.appendChild(i)}))}renderAudio(e){if(!this.audioContainer)return;this.audioContainer.innerHTML="",["background_file","background_volume","click_file","click_volume","success_file","success_volume","complete_file","complete_volume"].forEach(n=>{var o,l;let i=document.createElement("div");i.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=n.replace("_"," ");let r=document.createElement("input");r.type=n.includes("volume")?"number":"text",r.min="0",r.max="1",r.step="0.1",r.value=String((o=e==null?void 0:e[n])!=null?o:""),r.className="customize-input",r.dataset.audioKey=n,n.includes("file")&&(r.placeholder="audio file path"),i.appendChild(a),i.appendChild(r),(l=this.audioContainer)==null||l.appendChild(i)})}readUiValue(e,t){if(t.includes(".")){let i=t.split("."),a=e;for(let r of i){if(a==null)return null;a=a[r]}return typeof a=="string"?a:null}let n=e==null?void 0:e[t];return typeof n=="string"?n:null}getObjectTextValue(e){var i,a;let t=window.getEditableObjectConfig;if(typeof t!="function")return null;let n=t(e);return(a=(i=n==null?void 0:n.ui)==null?void 0:i.text)!=null?a:null}getObjectPropertyValue(e,t){let n=window.getEditableObjectConfig;if(typeof n!="function")return null;let i=n(e);if(!i)return null;let a=t.split("."),r=i;for(let o of a){if(r==null)return null;r=r[o]}return typeof r=="string"?r:null}handleApply(){this.handleApplyWithSource("manual")}handleApplyWithSource(e){if(console.log(`[CustomizePanel] handleApplyWithSource called with source: ${e}`),!this.root||!this.options)return;let t={};this.root.querySelectorAll("[data-asset-key]").forEach(o=>{let l=o;l.dataset.assetKey&&(t[l.dataset.assetKey]=l.value)}),console.log("[CustomizePanel] Assets being applied:",Object.keys(t).length,"total"),console.log("[CustomizePanel] Asset values:",t);let n={};this.root.querySelectorAll("[data-color-text-key]").forEach(o=>{let l=o,c=l.dataset.colorTextKey;c&&(c.includes("_text_color")||c.includes("_color")?this.applyTextColorToObject(c,l.value):n[c]=l.value)});let i={};this.root.querySelectorAll("[data-font-key]").forEach(o=>{let l=o,c=l.dataset.fontKey;c&&(i[c]=l.value)});let a={};this.root.querySelectorAll("[data-text-key]").forEach(o=>{let l=o,c=l.dataset.textKey;c&&(a[c]=l.value)});let r={};this.root.querySelectorAll("[data-audio-key]").forEach(o=>{let l=o,c=l.dataset.audioKey;if(c)if(c.includes("volume")){let d=parseFloat(l.value);r[c]=isNaN(d)?0:d}else r[c]=l.value}),this.root.querySelectorAll("[data-object-text-key]").forEach(o=>{let l=o,c=l.dataset.objectTextKey;if(!c)return;let d=ir.find(p=>p.key===c);d&&this.applyObjectPropertyValue(d.objectId,d.property,l.value)}),console.log("[CustomizePanel] Calling onApply callback to restart game with source:",e),this.options.onApply({assets:t,runtime:{theme:n,ui:a,fonts:i,audio:r}},{source:e})}setupAiPanel(){}setAiStatus(e){this.aiStatusEl&&(this.aiStatusEl.textContent=e)}getSelectedAssetKey(){return this.aiTargetKey}getSelectedAssetInput(){let e=this.getSelectedAssetKey();return!this.root||!e?null:this.root.querySelector(`input[data-asset-key="${e}"]`)}async getImageDataFromAsset(e){let t=this.resolveAssetUrls(e);console.log("[CustomizePanel] Resolving asset urls for AI:",e,t);for(let n of t)try{let i=await Un(n);if(i)return console.log("[CustomizePanel] Successfully fetched image data for AI"),{input:{base64:i.base64,mimeType:i.mimeType},dataUrl:i.dataUrl,width:i.width,height:i.height}}catch(i){console.warn("[CustomizePanel] Failed to fetch image data from:",n,i)}return console.error("[CustomizePanel] Could not load image data for AI from any URL"),null}async updateAiBasePreview(e){var i,a,r;let t=(e==null?void 0:e.trim())||"";if(!t){let o=this.getSelectedAssetInput();t=(a=(i=o==null?void 0:o.value)==null?void 0:i.trim())!=null?a:""}if(console.log("[CustomizePanel] updateAiBasePreview using value:",t),!t){this.aiBaseDataUrl=null,this.updateAiPreview();return}let n=await this.getImageDataFromAsset(t);this.aiBaseDataUrl=(r=n==null?void 0:n.dataUrl)!=null?r:null,this.updateAiPreview()}updateAiPreview(){if(!this.aiPreviewImg)return;let e=this.aiOutputDataUrl||this.aiBaseDataUrl||"";if(!e){this.aiPreviewImg.removeAttribute("src");return}this.aiPreviewImg.src=e}updateAiModalPreview(e,t){if(!e)return;let n=t!=null?t:this.activePreviewKey;if(!n||!this.aiOutputDataUrl||this.aiOutputKey!==n){e.classList.add("hidden");return}let i=e.querySelector(".asset-preview-ai-image");i&&(i.src=this.aiOutputDataUrl),e.classList.remove("hidden")}setAiLoading(e){this.aiLoadingEl&&this.aiLoadingEl.classList.toggle("active",e),this.aiGenerateBtn&&(this.aiGenerateBtn.disabled=e)}toggleAiGallery(){if(!this.aiGalleryEl||!this.aiGalleryToggle)return;let e=this.aiGalleryEl.classList.toggle("hidden");this.aiGalleryToggle.textContent=e?"Gallery":"Hide Gallery",e||this.renderAiGallery()}renderAiGallery(){if(!this.aiGalleryGrid)return;let e=this.getAiGalleryEntries();if(!e.length){this.aiGalleryGrid.innerHTML='<div class="ai-gallery-empty">No image assets found.</div>';return}this.aiGalleryGrid.innerHTML="",e.forEach(({key:t,value:n})=>{var l;let i=document.createElement("button");i.type="button",i.className="ai-gallery-item",t===this.aiTargetKey&&i.classList.add("active");let a=document.createElement("img");a.className="ai-gallery-thumb",a.alt=t;let r=this.resolveAssetUrls(n);r[0]&&(a.src=r[0]);let o=document.createElement("span");o.className="ai-gallery-label",o.textContent=t,i.appendChild(a),i.appendChild(o),i.addEventListener("click",()=>this.selectAiGalleryAsset(t)),(l=this.aiGalleryGrid)==null||l.appendChild(i)})}getAiGalleryEntries(){if(!this.root)return[];let e=[];return this.root.querySelectorAll("[data-asset-key]").forEach(t=>{var r,o;let n=t,i=n.dataset.assetKey,a=(o=(r=n.value)==null?void 0:r.trim())!=null?o:"";!i||!a||this.isAiGalleryImage(a)&&e.push({key:i,value:a})}),e}isAiGalleryImage(e){let t=e.trim();if(!t)return!1;if(/^(data:image|blob:)/.test(t))return!0;let n=t.split("?")[0].toLowerCase();return![".mp3",".wav",".ogg",".json"].some(i=>n.endsWith(i))}selectAiGalleryAsset(e){this.aiTargetKey!==e&&(this.aiTargetKey=e,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null,this.aiReferenceInput&&(this.aiReferenceInput.value=""),this.aiReferenceName&&(this.aiReferenceName.textContent="Optional"),this.aiModalSubtitle&&(this.aiModalSubtitle.textContent=e),this.setAiOutputButtonsEnabled(!1),this.updateAiBasePreview(),this.updateAiPreview(),this.renderAiGallery())}openAiModal(e,t,n){var o,l,c,d,p,u,g,f,h,m;this.closeAiModal(),this.aiTargetKey=e,this.aiBaseValue=t||null,this.aiContext=n||null,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null;let i=document.createElement("div");i.className="ai-modal",i.innerHTML=`
1618
+ `;let p=document.createElement("input");p.type="file",p.accept="image/*,audio/*,application/json",p.className="customize-file",p.addEventListener("change",()=>{var h;let g=(h=p.files)==null?void 0:h[0];g&&this.handleAssetUpload(g,o,i)}),d.addEventListener("click",()=>p.click()),l.appendChild(c),l.appendChild(d),l.appendChild(p),a.appendChild(r),a.appendChild(o),a.appendChild(l),(u=this.assetsContainer)==null||u.appendChild(a)})}renderColors(e){this.colorsContainer&&(this.colorsContainer.innerHTML="",dl.forEach(t=>{var l,c,d;let i=(l=e==null?void 0:e[t])!=null?l:"#ffffff";if(t.includes("_text_color")||t.includes("_color")){let u={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[t];u&&(i=(c=this.getObjectPropertyValue(u.objectId,u.property))!=null?c:"#ffffff")}let n=document.createElement("label");n.className="customize-color-field";let a=document.createElement("span");a.textContent=t.replace(/_/g," ");let r=document.createElement("input");r.type="color",r.value=i,r.dataset.colorKey=t;let o=document.createElement("input");o.type="text",o.value=i,o.className="customize-color-text",o.dataset.colorTextKey=t,r.addEventListener("input",()=>{o.value=r.value}),o.addEventListener("input",()=>{/^#([0-9a-fA-F]{6})$/.test(o.value)&&(r.value=o.value)}),n.appendChild(a),n.appendChild(r),n.appendChild(o),(d=this.colorsContainer)==null||d.appendChild(n)}))}renderFonts(e){this.fontsContainer&&(this.fontsContainer.innerHTML="",ul.forEach(t=>{var r,o;let i=document.createElement("div");i.className="customize-row";let n=document.createElement("span");n.className="customize-key",n.textContent=t;let a=document.createElement("input");a.type="text",a.value=(r=e==null?void 0:e[t])!=null?r:t,a.className="customize-input",a.dataset.fontKey=t,i.appendChild(n),i.appendChild(a),(o=this.fontsContainer)==null||o.appendChild(i)}))}renderTexts(e){this.textsContainer&&(this.textsContainer.innerHTML="",pl.forEach(t=>{var r,o;let i=document.createElement("div");i.className="customize-row";let n=document.createElement("span");n.className="customize-key",n.textContent=t;let a=document.createElement("input");a.type="text",a.value=(r=this.readUiValue(e,t))!=null?r:"",a.className="customize-input",a.dataset.textKey=t,i.appendChild(n),i.appendChild(a),(o=this.textsContainer)==null||o.appendChild(i)}),hr.forEach(({key:t,objectId:i})=>{var o,l;let n=document.createElement("div");n.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=t;let r=document.createElement("input");r.type="text",r.value=(o=this.getObjectTextValue(i))!=null?o:"",r.className="customize-input",r.dataset.objectTextKey=t,n.appendChild(a),n.appendChild(r),(l=this.textsContainer)==null||l.appendChild(n)}))}renderAudio(e){if(!this.audioContainer)return;this.audioContainer.innerHTML="",["background_file","background_volume","click_file","click_volume","success_file","success_volume","complete_file","complete_volume"].forEach(i=>{var o,l;let n=document.createElement("div");n.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=i.replace("_"," ");let r=document.createElement("input");r.type=i.includes("volume")?"number":"text",r.min="0",r.max="1",r.step="0.1",r.value=String((o=e==null?void 0:e[i])!=null?o:""),r.className="customize-input",r.dataset.audioKey=i,i.includes("file")&&(r.placeholder="audio file path"),n.appendChild(a),n.appendChild(r),(l=this.audioContainer)==null||l.appendChild(n)})}readUiValue(e,t){if(t.includes(".")){let n=t.split("."),a=e;for(let r of n){if(a==null)return null;a=a[r]}return typeof a=="string"?a:null}let i=e==null?void 0:e[t];return typeof i=="string"?i:null}getObjectTextValue(e){var n,a;let t=window.getEditableObjectConfig;if(typeof t!="function")return null;let i=t(e);return(a=(n=i==null?void 0:i.ui)==null?void 0:n.text)!=null?a:null}getObjectPropertyValue(e,t){let i=window.getEditableObjectConfig;if(typeof i!="function")return null;let n=i(e);if(!n)return null;let a=t.split("."),r=n;for(let o of a){if(r==null)return null;r=r[o]}return typeof r=="string"?r:null}handleApply(){this.handleApplyWithSource("manual")}handleApplyWithSource(e){if(console.log(`[CustomizePanel] handleApplyWithSource called with source: ${e}`),!this.root||!this.options)return;let t={};this.root.querySelectorAll("[data-asset-key]").forEach(o=>{let l=o;l.dataset.assetKey&&(t[l.dataset.assetKey]=l.value)}),console.log("[CustomizePanel] Assets being applied:",Object.keys(t).length,"total"),console.log("[CustomizePanel] Asset values:",t);let i={};this.root.querySelectorAll("[data-color-text-key]").forEach(o=>{let l=o,c=l.dataset.colorTextKey;c&&(c.includes("_text_color")||c.includes("_color")?this.applyTextColorToObject(c,l.value):i[c]=l.value)});let n={};this.root.querySelectorAll("[data-font-key]").forEach(o=>{let l=o,c=l.dataset.fontKey;c&&(n[c]=l.value)});let a={};this.root.querySelectorAll("[data-text-key]").forEach(o=>{let l=o,c=l.dataset.textKey;c&&(a[c]=l.value)});let r={};this.root.querySelectorAll("[data-audio-key]").forEach(o=>{let l=o,c=l.dataset.audioKey;if(c)if(c.includes("volume")){let d=parseFloat(l.value);r[c]=isNaN(d)?0:d}else r[c]=l.value}),this.root.querySelectorAll("[data-object-text-key]").forEach(o=>{let l=o,c=l.dataset.objectTextKey;if(!c)return;let d=hr.find(p=>p.key===c);d&&this.applyObjectPropertyValue(d.objectId,d.property,l.value)}),console.log("[CustomizePanel] Calling onApply callback to restart game with source:",e),this.options.onApply({assets:t,runtime:{theme:i,ui:a,fonts:n,audio:r}},{source:e})}setupAiPanel(){}setAiStatus(e){this.aiStatusEl&&(this.aiStatusEl.textContent=e)}getSelectedAssetKey(){return this.aiTargetKey}getSelectedAssetInput(){let e=this.getSelectedAssetKey();return!this.root||!e?null:this.root.querySelector(`input[data-asset-key="${e}"]`)}async getImageDataFromAsset(e){let t=this.resolveAssetUrls(e);console.log("[CustomizePanel] Resolving asset urls for AI:",e,t);for(let i of t)try{let n=await qi(i);if(n)return console.log("[CustomizePanel] Successfully fetched image data for AI"),{input:{base64:n.base64,mimeType:n.mimeType},dataUrl:n.dataUrl,width:n.width,height:n.height}}catch(n){console.warn("[CustomizePanel] Failed to fetch image data from:",i,n)}return console.error("[CustomizePanel] Could not load image data for AI from any URL"),null}async updateAiBasePreview(e){var n,a,r;let t=(e==null?void 0:e.trim())||"";if(!t){let o=this.getSelectedAssetInput();t=(a=(n=o==null?void 0:o.value)==null?void 0:n.trim())!=null?a:""}if(console.log("[CustomizePanel] updateAiBasePreview using value:",t),!t){this.aiBaseDataUrl=null,this.updateAiPreview();return}let i=await this.getImageDataFromAsset(t);this.aiBaseDataUrl=(r=i==null?void 0:i.dataUrl)!=null?r:null,this.updateAiPreview()}updateAiPreview(){if(!this.aiPreviewImg)return;let e=this.aiOutputDataUrl||this.aiBaseDataUrl||"";if(!e){this.aiPreviewImg.removeAttribute("src");return}this.aiPreviewImg.src=e}updateAiModalPreview(e,t){if(!e)return;let i=t!=null?t:this.activePreviewKey;if(!i||!this.aiOutputDataUrl||this.aiOutputKey!==i){e.classList.add("hidden");return}let n=e.querySelector(".asset-preview-ai-image");n&&(n.src=this.aiOutputDataUrl),e.classList.remove("hidden")}setAiLoading(e){this.aiLoadingEl&&this.aiLoadingEl.classList.toggle("active",e),this.aiGenerateBtn&&(this.aiGenerateBtn.disabled=e)}toggleAiGallery(){if(!this.aiGalleryEl||!this.aiGalleryToggle)return;let e=this.aiGalleryEl.classList.toggle("hidden");this.aiGalleryToggle.textContent=e?"Gallery":"Hide Gallery",e||this.renderAiGallery()}renderAiGallery(){if(!this.aiGalleryGrid)return;let e=this.getAiGalleryEntries();if(!e.length){this.aiGalleryGrid.innerHTML='<div class="ai-gallery-empty">No image assets found.</div>';return}this.aiGalleryGrid.innerHTML="",e.forEach(({key:t,value:i})=>{var l;let n=document.createElement("button");n.type="button",n.className="ai-gallery-item",t===this.aiTargetKey&&n.classList.add("active");let a=document.createElement("img");a.className="ai-gallery-thumb",a.alt=t;let r=this.resolveAssetUrls(i);r[0]&&(a.src=r[0]);let o=document.createElement("span");o.className="ai-gallery-label",o.textContent=t,n.appendChild(a),n.appendChild(o),n.addEventListener("click",()=>this.selectAiGalleryAsset(t)),(l=this.aiGalleryGrid)==null||l.appendChild(n)})}getAiGalleryEntries(){if(!this.root)return[];let e=[];return this.root.querySelectorAll("[data-asset-key]").forEach(t=>{var r,o;let i=t,n=i.dataset.assetKey,a=(o=(r=i.value)==null?void 0:r.trim())!=null?o:"";!n||!a||this.isAiGalleryImage(a)&&e.push({key:n,value:a})}),e}isAiGalleryImage(e){let t=e.trim();if(!t)return!1;if(/^(data:image|blob:)/.test(t))return!0;let i=t.split("?")[0].toLowerCase();return![".mp3",".wav",".ogg",".json"].some(n=>i.endsWith(n))}selectAiGalleryAsset(e){this.aiTargetKey!==e&&(this.aiTargetKey=e,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null,this.aiReferenceInput&&(this.aiReferenceInput.value=""),this.aiReferenceName&&(this.aiReferenceName.textContent="Optional"),this.aiModalSubtitle&&(this.aiModalSubtitle.textContent=e),this.setAiOutputButtonsEnabled(!1),this.updateAiBasePreview(),this.updateAiPreview(),this.renderAiGallery())}openAiModal(e,t,i){var o,l,c,d,p,u,g,h,f,m;this.closeAiModal(),this.aiTargetKey=e,this.aiBaseValue=t||null,this.aiContext=i||null,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null;let n=document.createElement("div");n.className="ai-modal",n.innerHTML=`
1534
1619
  <div class="ai-modal-card">
1535
1620
  <div class="ai-modal-header">
1536
1621
  <div>
@@ -1601,7 +1686,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1601
1686
  </div>
1602
1687
  </div>
1603
1688
  </div>
1604
- `;let a=i.querySelector(".ai-modal-close");a==null||a.addEventListener("click",()=>this.closeAiModal()),i.addEventListener("click",b=>{b.target===i&&this.closeAiModal()}),this.aiModal=i,this.aiKeyInput=i.querySelector("[data-ai-key]"),this.aiModelSelect=i.querySelector("[data-ai-model]"),this.aiPromptInput=i.querySelector("[data-ai-prompt]"),this.aiStrengthInput=i.querySelector("[data-ai-strength]"),this.aiStrengthValue=i.querySelector("[data-ai-strength-value]"),this.aiModalSubtitle=i.querySelector(".ai-modal-subtitle"),this.aiGalleryToggle=i.querySelector("[data-ai-gallery-toggle]"),this.aiGalleryEl=i.querySelector("[data-ai-gallery]"),this.aiGalleryGrid=i.querySelector("[data-ai-gallery-grid]"),this.aiReferenceInput=i.querySelector("[data-ai-ref-input]"),this.aiReferenceName=i.querySelector("[data-ai-ref-name]"),this.aiRemoveBgToggle=i.querySelector("[data-ai-remove-bg]"),this.aiUseOutputToggle=i.querySelector("[data-ai-use-output]"),this.aiGenerateBtn=i.querySelector("[data-ai-generate]"),this.aiApplyBtn=i.querySelector("[data-ai-apply]"),this.aiSaveLibraryBtn=i.querySelector("[data-ai-save-library]"),this.aiCropBtn=i.querySelector("[data-ai-crop]"),this.aiDownloadBtn=i.querySelector("[data-ai-download]"),this.aiPreviewImg=i.querySelector("[data-ai-preview]"),this.aiStatusEl=i.querySelector("[data-ai-status]"),this.aiLoadingEl=i.querySelector("[data-ai-loading]"),this.aiBgToleranceInput=i.querySelector("[data-ai-bg-tolerance]"),this.aiBgToleranceValue=i.querySelector("[data-ai-bg-tolerance-value]"),(o=this.aiRemoveBgToggle)==null||o.addEventListener("change",()=>{this.refreshAiOutputFromRaw()});let r=i.querySelector("[data-ai-ref-button]");r==null||r.addEventListener("click",()=>{var b;return(b=this.aiReferenceInput)==null?void 0:b.click()}),(l=this.aiGalleryToggle)==null||l.addEventListener("click",()=>this.toggleAiGallery()),(c=this.aiStrengthInput)==null||c.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiStrengthInput)==null?void 0:y.value)!=null?v:"5";this.aiStrengthValue&&(this.aiStrengthValue.textContent=b)}),(d=this.aiBgToleranceInput)==null||d.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiBgToleranceInput)==null?void 0:y.value)!=null?v:"30";this.aiBgToleranceValue&&(this.aiBgToleranceValue.textContent=b),this.refreshAiOutputFromRaw()}),(p=this.aiReferenceInput)==null||p.addEventListener("change",()=>{var y,v,w;let b=(w=(v=(y=this.aiReferenceInput)==null?void 0:y.files)==null?void 0:v[0])!=null?w:null;this.aiReferenceFile=b,this.aiReferenceName&&(this.aiReferenceName.textContent=b?`${b.name} (loaded)`:"Optional"),b&&this.setAiStatus(`Reference attached: ${b.name}`)}),(u=this.aiGenerateBtn)==null||u.addEventListener("click",()=>{this.handleAiGenerate()}),(g=this.aiApplyBtn)==null||g.addEventListener("click",()=>this.handleAiApply()),(f=this.aiSaveLibraryBtn)==null||f.addEventListener("click",()=>{this.handleAiSaveToLibrary()}),(h=this.aiCropBtn)==null||h.addEventListener("click",()=>{this.handleAiCrop()}),(m=this.aiDownloadBtn)==null||m.addEventListener("click",()=>this.handleAiDownload()),document.body.appendChild(i),this.setAiOutputButtonsEnabled(!1),this.setAiStatus("Ready."),this.updateAiBasePreview(t),this.updateAiPreview(),this.renderAiGallery()}closeAiModal(){this.aiModal&&(this.aiModal.remove(),this.aiModal=null),this.aiTargetKey=null,this.aiBaseValue=null,this.aiContext=null,this.aiKeyInput=null,this.aiModelSelect=null,this.aiPromptInput=null,this.aiStrengthInput=null,this.aiStrengthValue=null,this.aiModalSubtitle=null,this.aiGalleryToggle=null,this.aiGalleryEl=null,this.aiGalleryGrid=null,this.aiReferenceInput=null,this.aiReferenceName=null,this.aiReferenceFile=null,this.aiRemoveBgToggle=null,this.aiUseOutputToggle=null,this.aiGenerateBtn=null,this.aiApplyBtn=null,this.aiCropBtn=null,this.aiDownloadBtn=null,this.aiPreviewImg=null,this.aiStatusEl=null,this.aiLoadingEl=null,this.aiBgToleranceInput=null,this.aiBgToleranceValue=null}async handleAiGenerate(){var d,p,u,g,f,h,m,b,y,v,w,E,j,z,S,P,R,T,A,M;if(console.log("[CustomizePanel] handleAiGenerate clicked"),!this.aiGenerateBtn)return;let e=(u=(p=(d=this.aiKeyInput)==null?void 0:d.value)==null?void 0:p.trim())!=null?u:"",t=(f=(g=this.aiModelSelect)==null?void 0:g.value)!=null?f:"gemini-2.5-flash-image",n=(b=(m=(h=this.aiPromptInput)==null?void 0:h.value)==null?void 0:m.trim())!=null?b:"",i=(v=(y=this.aiRemoveBgToggle)==null?void 0:y.checked)!=null?v:!1,a=i,r=i,o=Number((E=(w=this.aiStrengthInput)==null?void 0:w.value)!=null?E:"5");if(!e){this.setAiStatus("Missing API key.");return}if(!n){this.setAiStatus("Add a prompt.");return}let l=this.getSelectedAssetInput(),c=((j=l==null?void 0:l.value)==null?void 0:j.trim())||((z=this.aiBaseValue)==null?void 0:z.trim())||"";if(!c&&!this.aiOutputDataUrl){this.setAiStatus("Select an asset first.");return}this.setAiLoading(!0),this.setAiStatus("Generating...");try{let k=null,C=(S=this.getSelectedAssetKey())!=null?S:"unknown",x=(P=this.aiUseOutputToggle)!=null&&P.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((R=this.aiUseOutputToggle)!=null&&R.checked&&this.aiOutputDataUrl){let G=Ji(this.aiOutputDataUrl,"ai-output.png");if(G){let K=await Pe(G);K&&(k={input:{base64:K.base64,mimeType:K.mimeType},dataUrl:K.dataUrl,width:K.width,height:K.height})}}if(k||(k=await this.getImageDataFromAsset(c)),!k){this.setAiStatus("Unable to load the base image.");return}let I=[k.input],L=!1;if(this.aiReferenceFile){let G=await Pe(this.aiReferenceFile);G?(I.push({base64:G.base64,mimeType:G.mimeType}),L=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let _=nr(n,{includeReference:L,includeMagenta:a,changeLevel:o}),O=(A=(T=this.aiReferenceFile)==null?void 0:T.name)!=null?A:"none";console.info("[AI] Final prompt:",_),console.info("[AI] Image sources:",{assetKey:C,base:x,reference:O});let H=Gs(k.width,k.height);console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let N=await st(e,_,I,{aspectRatio:H,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",N==null?void 0:N.length),this.aiRawOutputDataUrl=N,await this.refreshAiOutputFromRaw()}catch(k){console.error("[CustomizePanel] AI Generate Error:",k),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((M=this.aiStatusEl)==null?void 0:M.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var i,a,r,o;if(!this.aiRawOutputDataUrl)return;let e=(a=(i=this.aiRemoveBgToggle)==null?void 0:i.checked)!=null?a:!1,t=Number((o=(r=this.aiBgToleranceInput)==null?void 0:r.value)!=null?o:"30"),n=this.aiRawOutputDataUrl;if(e){let l=await at(this.aiRawOutputDataUrl,t);l&&(n=l)}this.setAiOutput(n),this.setAiStatus("Ready.")}setAiOutput(e){var n,i;this.aiOutputDataUrl=e,this.aiOutputKey=this.getSelectedAssetKey(),this.updateAiPreview(),this.setAiOutputButtonsEnabled(!0);let t=(n=this.previewModal)==null?void 0:n.querySelector("[data-asset-ai-preview]");this.updateAiModalPreview(t,(i=this.activePreviewKey)!=null?i:void 0)}setAiOutputButtonsEnabled(e){this.aiApplyBtn&&(this.aiApplyBtn.disabled=!e),this.aiSaveLibraryBtn&&(this.aiSaveLibraryBtn.disabled=!e),this.aiCropBtn&&(this.aiCropBtn.disabled=!e),this.aiDownloadBtn&&(this.aiDownloadBtn.disabled=!e)}handleAiApply(){var t,n,i;let e=this.getSelectedAssetInput();if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(e)console.log("[CustomizePanel] Applying AI output to brand asset:",e.dataset.assetKey),e.value=this.aiOutputDataUrl,this.handleAssetValueChange((t=e.dataset.assetKey)!=null?t:"",e),this.setAiStatus("Applied. Restarting game...");else{let a=((n=this.aiContext)==null?void 0:n.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),r=((i=this.aiContext)==null?void 0:i.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(a&&r)console.log("[CustomizePanel] Applying AI output directly to object:",a,r),this.applyObjectPropertyValue(a,r,this.aiOutputDataUrl),this.setAiStatus("Applied directly. Restarting game..."),window.dispatchEvent(new CustomEvent("inspector:refresh"));else{this.setAiStatus("No target input found to apply.");return}}setTimeout(()=>{this.closeAiModal()},500)}async handleAiSaveToLibrary(){var a,r,o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(!this.getSelectedAssetKey()){this.setAiStatus("No asset selected.");return}let n=`${(this.aiTargetKey||"asset").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_generated`,i=this.inferCategoryFromAssetKey(this.aiTargetKey||"");this.setAiStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:i,filename:`${n}.png`,data:this.aiOutputDataUrl,overwrite:!0})})).json();if(c.success){console.log("[CustomizePanel] \u2705 Saved to library:",c.path),this.setAiStatus(`Saved as ${n}.png. Refreshing library...`);let d=window.addAssetToRegistry;typeof d=="function"&&(console.log("[CustomizePanel] Adding to registry category:",i),d(i,`${n}.png`));try{console.log("[CustomizePanel] Triggering setup-library..."),(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[CustomizePanel] \u2705 Library setup completed"):console.warn("[CustomizePanel] Setup-library returned non-OK status")}catch(b){console.warn("[CustomizePanel] Setup-library endpoint not available:",b)}let p=window.refreshAssetLibrary;typeof p=="function"&&(console.log("[CustomizePanel] Refreshing library panel..."),await p());let u=window.__wizardAssetPicker;if(u!=null&&u.onPick){u.onPick(c.path),window.__wizardAssetPicker=null,this.setAiStatus("Saved to library and applied to wizard.");return}let g=((a=this.aiContext)==null?void 0:a.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),f=((r=this.aiContext)==null?void 0:r.path)||this.inferPathFromAssetKey(this.aiTargetKey||""),h=this.getSelectedAssetInput();if(h&&(h.value=c.path,this.handleAssetValueChange((o=h.dataset.assetKey)!=null?o:"",h)),g&&f){console.log("[CustomizePanel] Applying saved asset to object:",g,f);let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(f)||/\\.(png|jpg|jpeg)$/i.test(String(c.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(c.path);await b(g,v,i)}else this.applyObjectPropertyValue(g,f,c.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&g&&(console.log("[CustomizePanel] Highlighting slot in library:",g,i),setTimeout(()=>{m(g,i)},500)),this.setAiStatus(`\u2705 Saved and applied ${n}.png`),setTimeout(()=>{this.closeAiModal()},1500)}else console.error("[CustomizePanel] \u274C Save failed:",c.error),this.setAiStatus(`Save failed: ${c.error}`)}catch(l){console.error("[CustomizePanel] \u274C Save error:",l),this.setAiStatus("Save failed. Check console.")}}inferCategoryFromAssetKey(e){var r;let t=(r=this.aiContext)==null?void 0:r.objectId,n=e||this.aiTargetKey||"",i=window.getEditableAssets;if(typeof i=="function"){let o=i();if(o!=null&&o.slots){let l=o.slots.find(c=>t&&c.objectId===t||c.currentAsset===n||c.slotId===n||c.currentAsset&&c.currentAsset.includes(n)||n.includes(c.slotId));if(l){let c=l.libraryFolder||l.category;if(c)return c}}}let a=n.toLowerCase();return a.includes("background")?"backgrounds":a.includes("character")?"characters":a.includes("key")?"collectedkeys":a.includes("draggable")?"draggables":a.includes("environment")||a.includes("env")||a.includes("hand")||a.includes("prop")||a.includes("item")||a.includes("decor")||a.includes("object")?"environment":a.includes("machine")?"machines":a.includes("tutorial")?"tutorial":a.includes("ui")||a.includes("button")||a.includes("label")||a.includes("icon")||a.includes("logo")||a.includes("cta")||a.includes("menu")||a.includes("overlay")?"ui":a.includes("effect")||a.includes("confetti")||a.includes("particle")?"effects":"ui"}inferObjectIdFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let n=t();if(!(n!=null&&n.slots))return null;let i=n.slots.find(a=>a.currentAsset===e||a.slotId===e);return(i==null?void 0:i.objectId)||null}inferPathFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let n=t();if(!(n!=null&&n.slots))return null;let i=n.slots.find(r=>r.currentAsset===e||r.slotId===e);if(!i)return null;let a=i.category;return a==="render"||a==="backgrounds"||a==="characters"?"render.texture":a==="ui"?"ui.image":a==="audio"?"audio.src":"render.texture"}getFilenameFromPath(e){if(!e)return"";let t=e.split("/");return t[t.length-1]}async handleAiCrop(){var o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}let e=this.getSelectedAssetInput(),t=(o=e==null?void 0:e.value)!=null?o:"",n=await this.getImageDimensions(t);if(!n){this.setAiStatus("Unable to read target dimensions.");return}let i=Ji(this.aiOutputDataUrl,"ai-output.png");if(!i)return;let a=await this.showManualCropModal(i,n,t);if(!a)return;let r=await Xi(a);r&&this.setAiOutput(r)}handleAiDownload(){var n;if(!this.aiOutputDataUrl)return;let e=(n=this.getSelectedAssetKey())!=null?n:"ai-image",t=document.createElement("a");t.href=this.aiOutputDataUrl,t.download=`${e}-ai.png`,t.click()}handleAssetValueChange(e,t){this.previewModal&&this.closePreviewModal(),this.scheduleAutoApply(),this.updatePreviewIfOpen(e,t.value,t.dataset.assetType)}async handleAssetUpload(e,t,n){console.log("[CustomizePanel] Handling asset upload for:",n);let i=t.value,a=e;if(e.type.startsWith("image/")){let d=await this.getImageDimensions(i);if(d){let p=await this.showManualCropModal(e,d,i);if(!p)return;a=p}}let r=await Xi(a);if(!r){console.error("[CustomizePanel] Failed to convert file to data URL");return}let l=`${n.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,c=this.inferCategoryFromAssetKey(n);console.log("[CustomizePanel] Saving uploaded file to library:",l,"category:",c);try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:c,filename:`${l}.png`,data:r,overwrite:!0})})).json();if(p.success){console.log("[CustomizePanel] \u2705 Uploaded file saved to library:",p.path);let u=window.addAssetToRegistry;typeof u=="function"&&u(c,`${l}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(b){console.warn("[CustomizePanel] Setup-library not available:",b)}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),t.value=p.path,this.handleAssetValueChange(n,t);let f=this.inferObjectIdFromAssetKey(n),h=this.inferPathFromAssetKey(n);if(f&&h){let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(h)||/\\.(png|jpg|jpeg)$/i.test(String(p.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(p.path);await b(f,v,c)}else this.applyObjectPropertyValue(f,h,p.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&f&&setTimeout(()=>{m(f,c)},500),console.log("[CustomizePanel] \u2705 Upload complete:",l)}else console.error("[CustomizePanel] \u274C Upload save failed:",p.error),alert(`Failed to save uploaded file: ${p.error}`)}catch(d){console.error("[CustomizePanel] \u274C Upload error:",d),alert("Failed to save uploaded file. Check console for details.")}}scheduleAutoApply(){this.options&&(this.autoApplyTimer&&window.clearTimeout(this.autoApplyTimer),console.log("[CustomizePanel] Scheduling auto-apply in 250ms"),this.autoApplyTimer=window.setTimeout(()=>{this.autoApplyTimer=null,console.log("[CustomizePanel] Executing auto-apply now"),this.handleApplyWithSource("auto")},250))}previewAsset(e,t,n,i){if(!t)return;let a=this.resolveAssetUrls(t);if(a.length===0)return;let r=n||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=i!=null?i:null,this.openPreviewModal(e,t,a,r)}resolveAssetUrls(e){let t=e.trim();if(!t)return[];if(console.log("[CustomizePanel] Resolving asset urls for:",t),/^(blob:|data:|https?:|\/)/.test(t))return console.log("[CustomizePanel] Path is absolute or data/blob, using as is"),[t];let n=t.replace(/^\.?\//,""),i=[];return n.startsWith("raw/")?i=[`/${n}`,`/assets/${n}`]:n.startsWith("assets/")?i=[`/${n}`]:i=[`/raw/${n}`,`/assets/raw/${n}`,`/assets/${n}`,`/${n}`],console.log("[CustomizePanel] Resolved to possible paths:",i),i}guessMimeType(e){let t=e.toLowerCase();return t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".gif")||t.endsWith(".webp")||t.endsWith(".svg")?"image":t.endsWith(".mp3")||t.endsWith(".wav")||t.endsWith(".ogg")?"audio":t.endsWith(".json")?"json":"file"}openPreviewModal(e,t,n,i){this.closePreviewModal(!0);let a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
1689
+ `;let a=n.querySelector(".ai-modal-close");a==null||a.addEventListener("click",()=>this.closeAiModal()),n.addEventListener("click",b=>{b.target===n&&this.closeAiModal()}),this.aiModal=n,this.aiKeyInput=n.querySelector("[data-ai-key]"),this.aiModelSelect=n.querySelector("[data-ai-model]"),this.aiPromptInput=n.querySelector("[data-ai-prompt]"),this.aiStrengthInput=n.querySelector("[data-ai-strength]"),this.aiStrengthValue=n.querySelector("[data-ai-strength-value]"),this.aiModalSubtitle=n.querySelector(".ai-modal-subtitle"),this.aiGalleryToggle=n.querySelector("[data-ai-gallery-toggle]"),this.aiGalleryEl=n.querySelector("[data-ai-gallery]"),this.aiGalleryGrid=n.querySelector("[data-ai-gallery-grid]"),this.aiReferenceInput=n.querySelector("[data-ai-ref-input]"),this.aiReferenceName=n.querySelector("[data-ai-ref-name]"),this.aiRemoveBgToggle=n.querySelector("[data-ai-remove-bg]"),this.aiUseOutputToggle=n.querySelector("[data-ai-use-output]"),this.aiGenerateBtn=n.querySelector("[data-ai-generate]"),this.aiApplyBtn=n.querySelector("[data-ai-apply]"),this.aiSaveLibraryBtn=n.querySelector("[data-ai-save-library]"),this.aiCropBtn=n.querySelector("[data-ai-crop]"),this.aiDownloadBtn=n.querySelector("[data-ai-download]"),this.aiPreviewImg=n.querySelector("[data-ai-preview]"),this.aiStatusEl=n.querySelector("[data-ai-status]"),this.aiLoadingEl=n.querySelector("[data-ai-loading]"),this.aiBgToleranceInput=n.querySelector("[data-ai-bg-tolerance]"),this.aiBgToleranceValue=n.querySelector("[data-ai-bg-tolerance-value]"),(o=this.aiRemoveBgToggle)==null||o.addEventListener("change",()=>{this.refreshAiOutputFromRaw()});let r=n.querySelector("[data-ai-ref-button]");r==null||r.addEventListener("click",()=>{var b;return(b=this.aiReferenceInput)==null?void 0:b.click()}),(l=this.aiGalleryToggle)==null||l.addEventListener("click",()=>this.toggleAiGallery()),(c=this.aiStrengthInput)==null||c.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiStrengthInput)==null?void 0:y.value)!=null?v:"5";this.aiStrengthValue&&(this.aiStrengthValue.textContent=b)}),(d=this.aiBgToleranceInput)==null||d.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiBgToleranceInput)==null?void 0:y.value)!=null?v:"30";this.aiBgToleranceValue&&(this.aiBgToleranceValue.textContent=b),this.refreshAiOutputFromRaw()}),(p=this.aiReferenceInput)==null||p.addEventListener("change",()=>{var y,v,w;let b=(w=(v=(y=this.aiReferenceInput)==null?void 0:y.files)==null?void 0:v[0])!=null?w:null;this.aiReferenceFile=b,this.aiReferenceName&&(this.aiReferenceName.textContent=b?`${b.name} (loaded)`:"Optional"),b&&this.setAiStatus(`Reference attached: ${b.name}`)}),(u=this.aiGenerateBtn)==null||u.addEventListener("click",()=>{this.handleAiGenerate()}),(g=this.aiApplyBtn)==null||g.addEventListener("click",()=>this.handleAiApply()),(h=this.aiSaveLibraryBtn)==null||h.addEventListener("click",()=>{this.handleAiSaveToLibrary()}),(f=this.aiCropBtn)==null||f.addEventListener("click",()=>{this.handleAiCrop()}),(m=this.aiDownloadBtn)==null||m.addEventListener("click",()=>this.handleAiDownload()),document.body.appendChild(n),this.setAiOutputButtonsEnabled(!1),this.setAiStatus("Ready."),this.updateAiBasePreview(t),this.updateAiPreview(),this.renderAiGallery()}closeAiModal(){this.aiModal&&(this.aiModal.remove(),this.aiModal=null),this.aiTargetKey=null,this.aiBaseValue=null,this.aiContext=null,this.aiKeyInput=null,this.aiModelSelect=null,this.aiPromptInput=null,this.aiStrengthInput=null,this.aiStrengthValue=null,this.aiModalSubtitle=null,this.aiGalleryToggle=null,this.aiGalleryEl=null,this.aiGalleryGrid=null,this.aiReferenceInput=null,this.aiReferenceName=null,this.aiReferenceFile=null,this.aiRemoveBgToggle=null,this.aiUseOutputToggle=null,this.aiGenerateBtn=null,this.aiApplyBtn=null,this.aiCropBtn=null,this.aiDownloadBtn=null,this.aiPreviewImg=null,this.aiStatusEl=null,this.aiLoadingEl=null,this.aiBgToleranceInput=null,this.aiBgToleranceValue=null}async handleAiGenerate(){var d,p,u,g,h,f,m,b,y,v,w,E,P,M,x,_,O,T,A,j;if(console.log("[CustomizePanel] handleAiGenerate clicked"),!this.aiGenerateBtn)return;let e=(u=(p=(d=this.aiKeyInput)==null?void 0:d.value)==null?void 0:p.trim())!=null?u:"",t=(h=(g=this.aiModelSelect)==null?void 0:g.value)!=null?h:"gemini-2.5-flash-image",i=(b=(m=(f=this.aiPromptInput)==null?void 0:f.value)==null?void 0:m.trim())!=null?b:"",n=(v=(y=this.aiRemoveBgToggle)==null?void 0:y.checked)!=null?v:!1,a=n,r=n,o=Number((E=(w=this.aiStrengthInput)==null?void 0:w.value)!=null?E:"5");if(!e){this.setAiStatus("Missing API key.");return}if(!i){this.setAiStatus("Add a prompt.");return}let l=this.getSelectedAssetInput(),c=((P=l==null?void 0:l.value)==null?void 0:P.trim())||((M=this.aiBaseValue)==null?void 0:M.trim())||"";if(!c&&!this.aiOutputDataUrl){this.setAiStatus("Select an asset first.");return}this.setAiLoading(!0),this.setAiStatus("Generating...");try{let k=null,C=(x=this.getSelectedAssetKey())!=null?x:"unknown",S=(_=this.aiUseOutputToggle)!=null&&_.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((O=this.aiUseOutputToggle)!=null&&O.checked&&this.aiOutputDataUrl){let q=aa(this.aiOutputDataUrl,"ai-output.png");if(q){let J=await Oe(q);J&&(k={input:{base64:J.base64,mimeType:J.mimeType},dataUrl:J.dataUrl,width:J.width,height:J.height})}}if(k||(k=await this.getImageDataFromAsset(c)),!k){this.setAiStatus("Unable to load the base image.");return}let I=[k.input],L=!1;if(this.aiReferenceFile){let q=await Oe(this.aiReferenceFile);q?(I.push({base64:q.base64,mimeType:q.mimeType}),L=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let R=gr(i,{includeReference:L,includeMagenta:a,changeLevel:o}),z=(A=(T=this.aiReferenceFile)==null?void 0:T.name)!=null?A:"none";console.info("[AI] Final prompt:",R),console.info("[AI] Image sources:",{assetKey:C,base:S,reference:z});let N=Ks(k.width,k.height);console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let F=await ct(e,R,I,{aspectRatio:N,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",F==null?void 0:F.length),this.aiRawOutputDataUrl=F,await this.refreshAiOutputFromRaw()}catch(k){console.error("[CustomizePanel] AI Generate Error:",k),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((j=this.aiStatusEl)==null?void 0:j.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var n,a,r,o;if(!this.aiRawOutputDataUrl)return;let e=(a=(n=this.aiRemoveBgToggle)==null?void 0:n.checked)!=null?a:!1,t=Number((o=(r=this.aiBgToleranceInput)==null?void 0:r.value)!=null?o:"30"),i=this.aiRawOutputDataUrl;if(e){let l=await lt(this.aiRawOutputDataUrl,t);l&&(i=l)}this.setAiOutput(i),this.setAiStatus("Ready.")}setAiOutput(e){var i,n;this.aiOutputDataUrl=e,this.aiOutputKey=this.getSelectedAssetKey(),this.updateAiPreview(),this.setAiOutputButtonsEnabled(!0);let t=(i=this.previewModal)==null?void 0:i.querySelector("[data-asset-ai-preview]");this.updateAiModalPreview(t,(n=this.activePreviewKey)!=null?n:void 0)}setAiOutputButtonsEnabled(e){this.aiApplyBtn&&(this.aiApplyBtn.disabled=!e),this.aiSaveLibraryBtn&&(this.aiSaveLibraryBtn.disabled=!e),this.aiCropBtn&&(this.aiCropBtn.disabled=!e),this.aiDownloadBtn&&(this.aiDownloadBtn.disabled=!e)}handleAiApply(){var t,i,n;let e=this.getSelectedAssetInput();if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(e)console.log("[CustomizePanel] Applying AI output to brand asset:",e.dataset.assetKey),e.value=this.aiOutputDataUrl,this.handleAssetValueChange((t=e.dataset.assetKey)!=null?t:"",e),this.setAiStatus("Applied. Restarting game...");else{let a=((i=this.aiContext)==null?void 0:i.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),r=((n=this.aiContext)==null?void 0:n.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(a&&r)console.log("[CustomizePanel] Applying AI output directly to object:",a,r),this.applyObjectPropertyValue(a,r,this.aiOutputDataUrl),this.setAiStatus("Applied directly. Restarting game..."),window.dispatchEvent(new CustomEvent("inspector:refresh"));else{this.setAiStatus("No target input found to apply.");return}}setTimeout(()=>{this.closeAiModal()},500)}async handleAiSaveToLibrary(){var a,r,o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(!this.getSelectedAssetKey()){this.setAiStatus("No asset selected.");return}let i=`${(this.aiTargetKey||"asset").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_generated`,n=this.inferCategoryFromAssetKey(this.aiTargetKey||"");this.setAiStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:n,filename:`${i}.png`,data:this.aiOutputDataUrl,overwrite:!0})})).json();if(c.success){console.log("[CustomizePanel] \u2705 Saved to library:",c.path),this.setAiStatus(`Saved as ${i}.png. Refreshing library...`);let d=window.addAssetToRegistry;typeof d=="function"&&(console.log("[CustomizePanel] Adding to registry category:",n),d(n,`${i}.png`));try{console.log("[CustomizePanel] Triggering setup-library..."),(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[CustomizePanel] \u2705 Library setup completed"):console.warn("[CustomizePanel] Setup-library returned non-OK status")}catch(b){console.warn("[CustomizePanel] Setup-library endpoint not available:",b)}let p=window.refreshAssetLibrary;typeof p=="function"&&(console.log("[CustomizePanel] Refreshing library panel..."),await p());let u=window.__wizardAssetPicker;if(u!=null&&u.onPick){u.onPick(c.path),window.__wizardAssetPicker=null,this.setAiStatus("Saved to library and applied to wizard.");return}let g=((a=this.aiContext)==null?void 0:a.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),h=((r=this.aiContext)==null?void 0:r.path)||this.inferPathFromAssetKey(this.aiTargetKey||""),f=this.getSelectedAssetInput();if(f&&(f.value=c.path,this.handleAssetValueChange((o=f.dataset.assetKey)!=null?o:"",f)),g&&h){console.log("[CustomizePanel] Applying saved asset to object:",g,h);let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(h)||/\\.(png|jpg|jpeg)$/i.test(String(c.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(c.path);await b(g,v,n)}else this.applyObjectPropertyValue(g,h,c.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&g&&(console.log("[CustomizePanel] Highlighting slot in library:",g,n),setTimeout(()=>{m(g,n)},500)),this.setAiStatus(`\u2705 Saved and applied ${i}.png`),setTimeout(()=>{this.closeAiModal()},1500)}else console.error("[CustomizePanel] \u274C Save failed:",c.error),this.setAiStatus(`Save failed: ${c.error}`)}catch(l){console.error("[CustomizePanel] \u274C Save error:",l),this.setAiStatus("Save failed. Check console.")}}inferCategoryFromAssetKey(e){var r;let t=(r=this.aiContext)==null?void 0:r.objectId,i=e||this.aiTargetKey||"",n=window.getEditableAssets;if(typeof n=="function"){let o=n();if(o!=null&&o.slots){let l=o.slots.find(c=>t&&c.objectId===t||c.currentAsset===i||c.slotId===i||c.currentAsset&&c.currentAsset.includes(i)||i.includes(c.slotId));if(l){let c=l.libraryFolder||l.category;if(c)return c}}}let a=i.toLowerCase();return a.includes("background")?"backgrounds":a.includes("character")?"characters":a.includes("key")?"collectedkeys":a.includes("draggable")?"draggables":a.includes("environment")||a.includes("env")||a.includes("hand")||a.includes("prop")||a.includes("item")||a.includes("decor")||a.includes("object")?"environment":a.includes("machine")?"machines":a.includes("tutorial")?"tutorial":a.includes("ui")||a.includes("button")||a.includes("label")||a.includes("icon")||a.includes("logo")||a.includes("cta")||a.includes("menu")||a.includes("overlay")?"ui":a.includes("effect")||a.includes("confetti")||a.includes("particle")?"effects":"ui"}inferObjectIdFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(a=>a.currentAsset===e||a.slotId===e);return(n==null?void 0:n.objectId)||null}inferPathFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(r=>r.currentAsset===e||r.slotId===e);if(!n)return null;let a=n.category;return a==="render"||a==="backgrounds"||a==="characters"?"render.texture":a==="ui"?"ui.image":a==="audio"?"audio.src":"render.texture"}getFilenameFromPath(e){if(!e)return"";let t=e.split("/");return t[t.length-1]}async handleAiCrop(){var o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}let e=this.getSelectedAssetInput(),t=(o=e==null?void 0:e.value)!=null?o:"",i=await this.getImageDimensions(t);if(!i){this.setAiStatus("Unable to read target dimensions.");return}let n=aa(this.aiOutputDataUrl,"ai-output.png");if(!n)return;let a=await this.showManualCropModal(n,i,t);if(!a)return;let r=await na(a);r&&this.setAiOutput(r)}handleAiDownload(){var i;if(!this.aiOutputDataUrl)return;let e=(i=this.getSelectedAssetKey())!=null?i:"ai-image",t=document.createElement("a");t.href=this.aiOutputDataUrl,t.download=`${e}-ai.png`,t.click()}handleAssetValueChange(e,t){this.previewModal&&this.closePreviewModal(),this.scheduleAutoApply(),this.updatePreviewIfOpen(e,t.value,t.dataset.assetType)}async handleAssetUpload(e,t,i){console.log("[CustomizePanel] Handling asset upload for:",i);let n=t.value,a=e;if(e.type.startsWith("image/")){let d=await this.getImageDimensions(n);if(d){let p=await this.showManualCropModal(e,d,n);if(!p)return;a=p}}let r=await na(a);if(!r){console.error("[CustomizePanel] Failed to convert file to data URL");return}let l=`${i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,c=this.inferCategoryFromAssetKey(i);console.log("[CustomizePanel] Saving uploaded file to library:",l,"category:",c);try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:c,filename:`${l}.png`,data:r,overwrite:!0})})).json();if(p.success){console.log("[CustomizePanel] \u2705 Uploaded file saved to library:",p.path);let u=window.addAssetToRegistry;typeof u=="function"&&u(c,`${l}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(b){console.warn("[CustomizePanel] Setup-library not available:",b)}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),t.value=p.path,this.handleAssetValueChange(i,t);let h=this.inferObjectIdFromAssetKey(i),f=this.inferPathFromAssetKey(i);if(h&&f){let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(f)||/\\.(png|jpg|jpeg)$/i.test(String(p.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(p.path);await b(h,v,c)}else this.applyObjectPropertyValue(h,f,p.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&h&&setTimeout(()=>{m(h,c)},500),console.log("[CustomizePanel] \u2705 Upload complete:",l)}else console.error("[CustomizePanel] \u274C Upload save failed:",p.error),alert(`Failed to save uploaded file: ${p.error}`)}catch(d){console.error("[CustomizePanel] \u274C Upload error:",d),alert("Failed to save uploaded file. Check console for details.")}}scheduleAutoApply(){this.options&&(this.autoApplyTimer&&window.clearTimeout(this.autoApplyTimer),console.log("[CustomizePanel] Scheduling auto-apply in 250ms"),this.autoApplyTimer=window.setTimeout(()=>{this.autoApplyTimer=null,console.log("[CustomizePanel] Executing auto-apply now"),this.handleApplyWithSource("auto")},250))}previewAsset(e,t,i,n){if(!t)return;let a=this.resolveAssetUrls(t);if(a.length===0)return;let r=i||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=n!=null?n:null,this.openPreviewModal(e,t,a,r)}resolveAssetUrls(e){let t=e.trim();if(!t)return[];if(console.log("[CustomizePanel] Resolving asset urls for:",t),/^(blob:|data:|https?:|\/)/.test(t))return console.log("[CustomizePanel] Path is absolute or data/blob, using as is"),[t];let i=t.replace(/^\.?\//,""),n=[];return i.startsWith("raw/")?n=[`/${i}`,`/assets/${i}`]:i.startsWith("assets/")?n=[`/${i}`]:n=[`/raw/${i}`,`/assets/raw/${i}`,`/assets/${i}`,`/${i}`],console.log("[CustomizePanel] Resolved to possible paths:",n),n}guessMimeType(e){let t=e.toLowerCase();return t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".gif")||t.endsWith(".webp")||t.endsWith(".svg")?"image":t.endsWith(".mp3")||t.endsWith(".wav")||t.endsWith(".ogg")?"audio":t.endsWith(".json")?"json":"file"}openPreviewModal(e,t,i,n){this.closePreviewModal(!0);let a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
1605
1690
  <div class="asset-preview-card">
1606
1691
  <div class="asset-preview-header">
1607
1692
  <div class="asset-preview-title">${e}</div>
@@ -1617,12 +1702,12 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1617
1702
  <img class="asset-preview-ai-image" alt="AI output preview">
1618
1703
  </div>
1619
1704
  </div>
1620
- `;let r=a.querySelector(".asset-preview-body"),o=a.querySelector(".asset-preview-close"),l=a.querySelector(".asset-preview-change"),c=a.querySelector(".asset-preview-ai"),d=a.querySelector("[data-asset-ai-preview]");if(o==null||o.addEventListener("click",()=>this.closePreviewModal()),c==null||c.addEventListener("click",()=>{console.log("[CustomizePanel] AI Edit clicked for:",e),this.openAiModal(e,t)}),l==null||l.addEventListener("click",()=>{console.log("[CustomizePanel] Change clicked for:",e),this.activePreviewFileInput&&this.activePreviewFileInput.click()}),a.addEventListener("click",p=>{p.target===a&&this.closePreviewModal()}),r)if(i==="image"){let p=document.createElement("img");this.loadWithFallback(p,n),r.appendChild(p)}else if(i==="audio"){let p=document.createElement("audio");p.controls=!0,this.loadWithFallback(p,n),r.appendChild(p)}else if(i==="json"){let p=document.createElement("pre");this.fetchWithFallback(n).then(u=>{p.textContent=u!=null?u:"Unable to load JSON."}),r.appendChild(p)}else{let p=document.createElement("a");p.href=n[0],p.target="_blank",p.rel="noreferrer",p.textContent="Open asset",r.appendChild(p)}document.body.appendChild(a),this.previewModal=a,this.updateAiModalPreview(d,e)}loadWithFallback(e,t){if(t.length===0)return;let n=0,i=()=>{n>=t.length||(e.src=t[n],n+=1)};e.addEventListener("error",i),i()}async fetchWithFallback(e){for(let t of e)try{let n=await fetch(t);if(!n.ok)continue;return await n.text()}catch{}return null}applyObjectPropertyValue(e,t,n){let i=window.getEditableObjectConfig,a=window.applyEditableObjectConfig;if(typeof i!="function"||typeof a!="function")return;let r=i(e);if(!r)return;let o=JSON.parse(JSON.stringify(r)),l=t.split("."),c=o;for(let d=0;d<l.length-1;d++){let p=l[d];c[p]=c[p]||{},c=c[p]}c[l[l.length-1]]=n,a(e,o)}applyTextColorToObject(e,t){let i={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[e];i&&this.applyObjectPropertyValue(i.objectId,i.property,t)}closePreviewModal(e){this.previewModal&&(this.previewModal.remove(),this.previewModal=null),e||(this.activePreviewKey=null,this.activePreviewValue=null,this.activePreviewFileInput=null)}updatePreviewIfOpen(e,t,n){var a;if(!this.previewModal||this.activePreviewKey!==e)return;let i=t!=null?t:"";this.activePreviewValue!==i&&this.previewAsset(e,i,n,(a=this.activePreviewFileInput)!=null?a:void 0)}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refresh()},350))}clearRetry(){this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=null)}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");if(!e)return;let t=window.localStorage.getItem("customizePanelWidth"),n=t?Number(t):NaN;Number.isFinite(n)&&n>0&&(this.root.style.width=`${n}px`);let i=a=>{var u,g;a.preventDefault();let r=a.clientX,o=(g=(u=this.root)==null?void 0:u.getBoundingClientRect().width)!=null?g:0,l=260,c=620,d=f=>{let h=f.clientX-r,m=Math.min(c,Math.max(l,o+h));this.root&&(this.root.style.width=`${m}px`)},p=()=>{var h,m;window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p);let f=(m=(h=this.root)==null?void 0:h.getBoundingClientRect().width)!=null?m:0;f>0&&window.localStorage.setItem("customizePanelWidth",String(Math.round(f)))};window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)};e.addEventListener("pointerdown",i)}async getImageDimensions(e){let t=this.resolveAssetUrls(e);if(t.length===0)return null;for(let n of t){let i=await this.loadImage(n);if(i!=null&&i.naturalWidth&&(i!=null&&i.naturalHeight))return{width:i.naturalWidth,height:i.naturalHeight}}return null}async loadImage(e){return await new Promise(t=>{let n=new Image;n.onload=()=>t(n),n.onerror=()=>t(null),n.src=e})}async showManualCropModal(e,t,n){let i=t.width/t.height,a=URL.createObjectURL(e),r=await this.loadImage(a);try{URL.revokeObjectURL(a)}catch{}if(!(r!=null&&r.naturalWidth)||!(r!=null&&r.naturalHeight))return null;let o=await this.loadImageForValue(n);return await new Promise(l=>{let c=document.createElement("div");c.className="asset-crop-modal";let d=Math.min(860,window.innerWidth-60),f=Math.max(220,Math.floor((d-32-16)/2)),h=Math.min(520,window.innerHeight-240),m=f,b=m/i;b>h&&(b=h,m=b*i),c.innerHTML=`
1705
+ `;let r=a.querySelector(".asset-preview-body"),o=a.querySelector(".asset-preview-close"),l=a.querySelector(".asset-preview-change"),c=a.querySelector(".asset-preview-ai"),d=a.querySelector("[data-asset-ai-preview]");if(o==null||o.addEventListener("click",()=>this.closePreviewModal()),c==null||c.addEventListener("click",()=>{console.log("[CustomizePanel] AI Edit clicked for:",e),this.openAiModal(e,t)}),l==null||l.addEventListener("click",()=>{console.log("[CustomizePanel] Change clicked for:",e),this.activePreviewFileInput&&this.activePreviewFileInput.click()}),a.addEventListener("click",p=>{p.target===a&&this.closePreviewModal()}),r)if(n==="image"){let p=document.createElement("img");this.loadWithFallback(p,i),r.appendChild(p)}else if(n==="audio"){let p=document.createElement("audio");p.controls=!0,this.loadWithFallback(p,i),r.appendChild(p)}else if(n==="json"){let p=document.createElement("pre");this.fetchWithFallback(i).then(u=>{p.textContent=u!=null?u:"Unable to load JSON."}),r.appendChild(p)}else{let p=document.createElement("a");p.href=i[0],p.target="_blank",p.rel="noreferrer",p.textContent="Open asset",r.appendChild(p)}document.body.appendChild(a),this.previewModal=a,this.updateAiModalPreview(d,e)}loadWithFallback(e,t){if(t.length===0)return;let i=0,n=()=>{i>=t.length||(e.src=t[i],i+=1)};e.addEventListener("error",n),n()}async fetchWithFallback(e){for(let t of e)try{let i=await fetch(t);if(!i.ok)continue;return await i.text()}catch{}return null}applyObjectPropertyValue(e,t,i){let n=window.getEditableObjectConfig,a=window.applyEditableObjectConfig;if(typeof n!="function"||typeof a!="function")return;let r=n(e);if(!r)return;let o=JSON.parse(JSON.stringify(r)),l=t.split("."),c=o;for(let d=0;d<l.length-1;d++){let p=l[d];c[p]=c[p]||{},c=c[p]}c[l[l.length-1]]=i,a(e,o)}applyTextColorToObject(e,t){let n={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[e];n&&this.applyObjectPropertyValue(n.objectId,n.property,t)}closePreviewModal(e){this.previewModal&&(this.previewModal.remove(),this.previewModal=null),e||(this.activePreviewKey=null,this.activePreviewValue=null,this.activePreviewFileInput=null)}updatePreviewIfOpen(e,t,i){var a;if(!this.previewModal||this.activePreviewKey!==e)return;let n=t!=null?t:"";this.activePreviewValue!==n&&this.previewAsset(e,n,i,(a=this.activePreviewFileInput)!=null?a:void 0)}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refresh()},350))}clearRetry(){this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=null)}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");if(!e)return;let t=window.localStorage.getItem("customizePanelWidth"),i=t?Number(t):NaN;Number.isFinite(i)&&i>0&&(this.root.style.width=`${i}px`);let n=a=>{var u,g;a.preventDefault();let r=a.clientX,o=(g=(u=this.root)==null?void 0:u.getBoundingClientRect().width)!=null?g:0,l=260,c=620,d=h=>{let f=h.clientX-r,m=Math.min(c,Math.max(l,o+f));this.root&&(this.root.style.width=`${m}px`)},p=()=>{var f,m;window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p);let h=(m=(f=this.root)==null?void 0:f.getBoundingClientRect().width)!=null?m:0;h>0&&window.localStorage.setItem("customizePanelWidth",String(Math.round(h)))};window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)};e.addEventListener("pointerdown",n)}async getImageDimensions(e){let t=this.resolveAssetUrls(e);if(t.length===0)return null;for(let i of t){let n=await this.loadImage(i);if(n!=null&&n.naturalWidth&&(n!=null&&n.naturalHeight))return{width:n.naturalWidth,height:n.naturalHeight}}return null}async loadImage(e){return await new Promise(t=>{let i=new Image;i.onload=()=>t(i),i.onerror=()=>t(null),i.src=e})}async showManualCropModal(e,t,i){let n=t.width/t.height,a=URL.createObjectURL(e),r=await this.loadImage(a);try{URL.revokeObjectURL(a)}catch{}if(!(r!=null&&r.naturalWidth)||!(r!=null&&r.naturalHeight))return null;let o=await this.loadImageForValue(i);return await new Promise(l=>{let c=document.createElement("div");c.className="asset-crop-modal";let d=Math.min(860,window.innerWidth-60),h=Math.max(220,Math.floor((d-32-16)/2)),f=Math.min(520,window.innerHeight-240),m=h,b=m/n;b>f&&(b=f,m=b*n),c.innerHTML=`
1621
1706
  <div class="asset-crop-card" style="width:${d}px;">
1622
1707
  <div class="asset-crop-header">
1623
1708
  <div>
1624
1709
  <div class="asset-crop-title">Crop to match current asset</div>
1625
- <div class="asset-crop-subtitle">${t.width}\xD7${t.height}px \u2022 ${i.toFixed(3)} ratio</div>
1710
+ <div class="asset-crop-subtitle">${t.width}\xD7${t.height}px \u2022 ${n.toFixed(3)} ratio</div>
1626
1711
  </div>
1627
1712
  <button class="asset-crop-close" type="button">Close</button>
1628
1713
  </div>
@@ -1647,7 +1732,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1647
1732
  <button class="asset-crop-apply" type="button">Apply Crop</button>
1648
1733
  </div>
1649
1734
  </div>
1650
- `;let y=c.querySelector(".asset-crop-canvas"),v=c.querySelector(".asset-crop-preview"),w=c.querySelector(".asset-crop-zoom"),E=c.querySelector(".asset-crop-zoom-value"),j=c.querySelector(".asset-crop-close"),z=c.querySelector(".asset-crop-cancel"),S=c.querySelector(".asset-crop-apply"),P=c.querySelector(".asset-crop-reset");if(!y||!v||!w||!E){l(null);return}let R=y.getContext("2d"),T=v.getContext("2d");if(!R||!T){l(null);return}let A=r.naturalWidth,M=r.naturalHeight,k=Math.max(y.width/A,y.height/M),C=1,x=0,I=0,L=!1,_=0,O=0,H=0,N=0,G=()=>{let D=k*C,Z=Math.max(0,(A*D-y.width)/2),Ke=Math.max(0,(M*D-y.height)/2);x=Math.min(Z,Math.max(-Z,x)),I=Math.min(Ke,Math.max(-Ke,I))},K=()=>{let D=k*C;R.clearRect(0,0,y.width,y.height);let Z=y.width/2-A*D/2+x,Ke=y.height/2-M*D/2+I;if(R.drawImage(r,Z,Ke,A*D,M*D),T.clearRect(0,0,v.width,v.height),o!=null&&o.naturalWidth&&(o!=null&&o.naturalHeight)){let Je=Math.max(v.width/o.naturalWidth,v.height/o.naturalHeight),ui=v.width/2-o.naturalWidth*Je/2,yt=v.height/2-o.naturalHeight*Je/2;T.drawImage(o,ui,yt,o.naturalWidth*Je,o.naturalHeight*Je)}else T.fillStyle="rgba(255, 255, 255, 0.04)",T.fillRect(0,0,v.width,v.height),T.strokeStyle="rgba(255, 255, 255, 0.08)",T.strokeRect(4,4,v.width-8,v.height-8);let bt=v.width/y.width*(k*C),Xe=x*(v.width/y.width),Yt=I*(v.height/y.height),di=v.width/2-A*bt/2+Xe,pi=v.height/2-M*bt/2+Yt;T.save(),T.globalAlpha=.7,T.drawImage(r,di,pi,A*bt,M*bt),T.restore()},ze=()=>{x=0,I=0,G(),K()};w.addEventListener("input",()=>{C=Number(w.value),E.textContent=`${C.toFixed(2)}\xD7`,G(),K()}),y.addEventListener("pointerdown",D=>{L=!0,_=D.clientX,O=D.clientY,H=x,N=I,y.setPointerCapture(D.pointerId)}),y.addEventListener("pointermove",D=>{L&&(x=H+(D.clientX-_),I=N+(D.clientY-O),G(),K())}),y.addEventListener("pointerup",D=>{L=!1,y.releasePointerCapture(D.pointerId)}),y.addEventListener("pointerleave",()=>{L=!1});let ue=()=>{c.remove()},ge=()=>{ue(),l(null)},Ye=async()=>{let D=document.createElement("canvas");D.width=t.width,D.height=t.height;let Z=D.getContext("2d");if(!Z){ue(),l(null);return}let Ke=C,Xe=Math.max(D.width/A,D.height/M)*Ke,Yt=D.width/y.width,di=x*Yt,pi=I*Yt,Je=D.width/2-A*Xe/2+di,ui=D.height/2-M*Xe/2+pi;Z.drawImage(r,Je,ui,A*Xe,M*Xe);let yt=await new Promise(Vr=>{D.toBlob(Wr=>Vr(Wr),e.type||"image/png")});if(ue(),!yt){l(null);return}l(new File([yt],e.name,{type:yt.type}))};j==null||j.addEventListener("click",ge),z==null||z.addEventListener("click",ge),P==null||P.addEventListener("click",ze),S==null||S.addEventListener("click",()=>{Ye()}),c.addEventListener("click",D=>{D.target===c&&ge()}),document.body.appendChild(c),ze()})}async loadImageForValue(e){let t=this.resolveAssetUrls(e);if(!t.length)return null;for(let n of t){let i=await this.loadImage(n);if(i)return i}return null}};var Wn=class{constructor(){this.root=null;this.options=null}render(){return`
1735
+ `;let y=c.querySelector(".asset-crop-canvas"),v=c.querySelector(".asset-crop-preview"),w=c.querySelector(".asset-crop-zoom"),E=c.querySelector(".asset-crop-zoom-value"),P=c.querySelector(".asset-crop-close"),M=c.querySelector(".asset-crop-cancel"),x=c.querySelector(".asset-crop-apply"),_=c.querySelector(".asset-crop-reset");if(!y||!v||!w||!E){l(null);return}let O=y.getContext("2d"),T=v.getContext("2d");if(!O||!T){l(null);return}let A=r.naturalWidth,j=r.naturalHeight,k=Math.max(y.width/A,y.height/j),C=1,S=0,I=0,L=!1,R=0,z=0,N=0,F=0,q=()=>{let D=k*C,Q=Math.max(0,(A*D-y.width)/2),Ze=Math.max(0,(j*D-y.height)/2);S=Math.min(Q,Math.max(-Q,S)),I=Math.min(Ze,Math.max(-Ze,I))},J=()=>{let D=k*C;O.clearRect(0,0,y.width,y.height);let Q=y.width/2-A*D/2+S,Ze=y.height/2-j*D/2+I;if(O.drawImage(r,Q,Ze,A*D,j*D),T.clearRect(0,0,v.width,v.height),o!=null&&o.naturalWidth&&(o!=null&&o.naturalHeight)){let et=Math.max(v.width/o.naturalWidth,v.height/o.naturalHeight),vn=v.width/2-o.naturalWidth*et/2,St=v.height/2-o.naturalHeight*et/2;T.drawImage(o,vn,St,o.naturalWidth*et,o.naturalHeight*et)}else T.fillStyle="rgba(255, 255, 255, 0.04)",T.fillRect(0,0,v.width,v.height),T.strokeStyle="rgba(255, 255, 255, 0.08)",T.strokeRect(4,4,v.width-8,v.height-8);let xt=v.width/y.width*(k*C),Qe=S*(v.width/y.width),Zt=I*(v.height/y.height),bn=v.width/2-A*xt/2+Qe,yn=v.height/2-j*xt/2+Zt;T.save(),T.globalAlpha=.7,T.drawImage(r,bn,yn,A*xt,j*xt),T.restore()},De=()=>{S=0,I=0,q(),J()};w.addEventListener("input",()=>{C=Number(w.value),E.textContent=`${C.toFixed(2)}\xD7`,q(),J()}),y.addEventListener("pointerdown",D=>{L=!0,R=D.clientX,z=D.clientY,N=S,F=I,y.setPointerCapture(D.pointerId)}),y.addEventListener("pointermove",D=>{L&&(S=N+(D.clientX-R),I=F+(D.clientY-z),q(),J())}),y.addEventListener("pointerup",D=>{L=!1,y.releasePointerCapture(D.pointerId)}),y.addEventListener("pointerleave",()=>{L=!1});let fe=()=>{c.remove()},me=()=>{fe(),l(null)},Je=async()=>{let D=document.createElement("canvas");D.width=t.width,D.height=t.height;let Q=D.getContext("2d");if(!Q){fe(),l(null);return}let Ze=C,Qe=Math.max(D.width/A,D.height/j)*Ze,Zt=D.width/y.width,bn=S*Zt,yn=I*Zt,et=D.width/2-A*Qe/2+bn,vn=D.height/2-j*Qe/2+yn;Q.drawImage(r,et,vn,A*Qe,j*Qe);let St=await new Promise(Zr=>{D.toBlob(Qr=>Zr(Qr),e.type||"image/png")});if(fe(),!St){l(null);return}l(new File([St],e.name,{type:St.type}))};P==null||P.addEventListener("click",me),M==null||M.addEventListener("click",me),_==null||_.addEventListener("click",De),x==null||x.addEventListener("click",()=>{Je()}),c.addEventListener("click",D=>{D.target===c&&me()}),document.body.appendChild(c),De()})}async loadImageForValue(e){let t=this.resolveAssetUrls(e);if(!t.length)return null;for(let i of t){let n=await this.loadImage(i);if(n)return n}return null}};var Ji=class{constructor(){this.root=null;this.options=null}render(){return`
1651
1736
  <div class="scene-panel loading-screen-panel panel-accent-purple" data-panel="loading-screen">
1652
1737
  <div class="scene-panel-header" data-panel-handle>
1653
1738
  <div class="panel-title">
@@ -1713,10 +1798,10 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1713
1798
  </div>
1714
1799
  </div>
1715
1800
  </div>
1716
- `}initialize(e,t){var y,v,w,E,j,z,S,P,R,T,A,M,k,C,x,I;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let i=(()=>{var _;let L=window.getEditableEngineConfig;if(typeof L=="function"){let O=L();return(_=O==null?void 0:O.loading)!=null?_:{}}return{}})(),a=(y=this.root)==null?void 0:y.querySelector("#loading-screen-type");a&&(a.value=i.type==="image"?"image":"color",a.addEventListener("change",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onUpdateLoading)==null||_.call(L,{type:a.value}),this.updateFieldVisibility(a.value)}));let r=(v=this.root)==null?void 0:v.querySelector("#loading-background-color");r&&(r.value=i.background_color||"#160a17",r.addEventListener("input",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onUpdateLoading)==null||_.call(L,{background_color:r.value})}));let o=(w=this.root)==null?void 0:w.querySelector("#loading-overlay-alpha"),l=(E=this.root)==null?void 0:E.querySelector("#loading-overlay-alpha-value");o&&(o.value=String((j=i.overlay_alpha)!=null?j:1),l&&(l.textContent=Number(o.value).toFixed(2)),o.addEventListener("input",()=>{var _,O;let L=Number(o.value);l&&(l.textContent=L.toFixed(2)),(O=(_=this.options)==null?void 0:_.onUpdateLoading)==null||O.call(_,{overlay_alpha:L})}));let c=(z=this.root)==null?void 0:z.querySelector("#loading-text");c&&(c.value=i.text||"",c.addEventListener("input",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onUpdateLoading)==null||_.call(L,{text:c.value})}));let d=(S=this.root)==null?void 0:S.querySelector("#loading-text-scale"),p=(P=this.root)==null?void 0:P.querySelector("#loading-text-scale-value");d&&(d.value=String((R=i.text_scale)!=null?R:.6),p&&(p.textContent=Number(d.value).toFixed(2)),d.addEventListener("input",()=>{var _,O;let L=Number(d.value);p&&(p.textContent=L.toFixed(2)),(O=(_=this.options)==null?void 0:_.onUpdateLoading)==null||O.call(_,{text_scale:L})}));let u=(T=this.root)==null?void 0:T.querySelector("#loading-enabled");u&&(u.checked=i.enabled!==!1,u.addEventListener("change",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onUpdateLoading)==null||_.call(L,{enabled:u.checked})}));let g=(A=this.root)==null?void 0:A.querySelector("#loading-blur-enabled");g&&(g.checked=i.blur_enabled!==!1,g.addEventListener("change",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onUpdateLoading)==null||_.call(L,{blur_enabled:g.checked})}));let f=(M=this.root)==null?void 0:M.querySelector("#loading-blur-strength"),h=(k=this.root)==null?void 0:k.querySelector("#loading-blur-strength-value");f&&(f.value=String((C=i.blur_strength)!=null?C:8),h&&(h.textContent=f.value),f.addEventListener("input",()=>{var L,_;h&&(h.textContent=f.value),(_=(L=this.options)==null?void 0:L.onUpdateLoading)==null||_.call(L,{blur_strength:Number(f.value)})}));let m=(x=this.root)==null?void 0:x.querySelector("#loading-show-btn"),b=(I=this.root)==null?void 0:I.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onShowLoadingScreen)==null||_.call(L)}),b==null||b.addEventListener("click",()=>{var L,_;(_=(L=this.options)==null?void 0:L.onHideLoadingScreen)==null||_.call(L)}),this.updateFieldVisibility(i.type==="image"?"image":"color")}updateFieldVisibility(e){var i,a;let t=(i=this.root)==null?void 0:i.querySelector("#loading-color-field"),n=(a=this.root)==null?void 0:a.querySelector("#loading-alpha-field");e==="image"?(t&&(t.style.display="none"),n&&(n.style.display="none")):(t&&(t.style.display=""),n&&(n.style.display=""))}refresh(){}};var _t=require("pixi.js");nt();J();async function ar(s,e,t){var n,i;console.log("[LIBRARY] applyAssetChange called with:",e,t);try{let a=Date.now(),o=`/${`raw/library/${e}/${t}`}?t=${a}`;console.log("[LIBRARY] Loading texture from:",o);let l=await _t.Assets.load(o);if(!l){console.error("[LIBRARY] Failed to load texture:",o);return}let c=window.CustomAssets,d=Object.keys(c||{}).filter(u=>{let g=e.replace(/s$/,"");return u.startsWith(g)||u.includes(g)});for(let u of d)le[u]=l,console.log("[LIBRARY] \u2705 Updated AssetTextures."+u),(n=c[u])!=null&&n.texture&&(c[u].texture=l,console.log("[LIBRARY] \u2705 Updated CustomAssets."+u+".texture"));let p=window.gameObjectManager;if(p)for(let u of d){let g=p.get(u);if(g){let f=((i=g.getDisplayObject)==null?void 0:i.call(g))||g.pixiObject||g;f!=null&&f.texture&&(f.texture=l,console.log("[LIBRARY] \u2705 Applied to display object:",u))}}}catch(a){console.error("[LIBRARY] Error applying asset change:",a)}}async function sr(s,e){var t,n,i;console.log("[LIBRARY] resetAsset called for:",e);try{let a=window.getEditableAssets,r=typeof a=="function"?a():null,o=(t=r==null?void 0:r.slots)==null?void 0:t.find(m=>m.category===e),l=o==null?void 0:o.defaultAsset;if(!l){console.warn("[LIBRARY] Could not find default asset for:",e);return}let c=Date.now(),d=`/raw/${l}?t=${c}`;console.log("[LIBRARY] Loading default texture from:",d);let p=await _t.Assets.load(d);if(!p){console.error("[LIBRARY] Failed to load default texture:",d);return}let u=window.CustomAssets,g=e.replace(/s$/,""),f=Object.keys(u||{}).filter(m=>m.startsWith(g)||m.includes(g));for(let m of f)le[m]=p,console.log("[LIBRARY] \u2705 Reset AssetTextures."+m),(n=u[m])!=null&&n.texture&&(u[m].texture=p,console.log("[LIBRARY] \u2705 Reset CustomAssets."+m+" to default"));let h=window.gameObjectManager;if(h)for(let m of f){let b=h.get(m);if(b){let y=((i=b.getDisplayObject)==null?void 0:i.call(b))||b.pixiObject||b;y!=null&&y.texture&&(y.texture=p,console.log("[LIBRARY] \u2705 Reset display object:",m))}}}catch(a){console.error("[LIBRARY] Error resetting asset:",a)}}async function rr(s,e,t,n){var i,a,r,o,l,c,d,p,u,g,f,h,m,b,y;console.log("[LIBRARY] applySlotAsset:",{objectId:e,assetFilename:t,category:n});try{let v=e.startsWith("json.")?e.replace("json.",""):e;console.log("[LIBRARY] Asset key:",v);let w=Date.now(),E=`/raw/library/${n}/${t}?t=${w}`;console.log("[LIBRARY] Loading texture from:",E);let j=await _t.Assets.load(E);if(!j){console.error("[LIBRARY] Failed to load texture:",E);return}console.log("[LIBRARY] \u2705 Texture loaded"),le[v]=j,console.log("[LIBRARY] \u2705 Updated AssetTextures."+v);let z=window.CustomAssets;z!=null&&z[v]&&(z[v].texture=j,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+v));let S=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!S),S){let R=Array.from(((i=S.keys)==null?void 0:i.call(S))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",R);let T=S.get(v);if(console.log("[LIBRARY] gameObject for "+v+"?",!!T),T){let A=((a=T.getDisplayObject)==null?void 0:a.call(T))||T.pixiObject||T.pixi||T,M=(r=A==null?void 0:A.constructor)==null?void 0:r.name;if(console.log("[LIBRARY] displayObject:",A),console.log("[LIBRARY] displayObject type:",M),console.log("[LIBRARY] has texture?",!!(A!=null&&A.texture)),A!=null&&A.texture)A.texture=j,console.log("[LIBRARY] \u2705 Applied to display object:",v);else if(M==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:k}=await import("pixi.js"),C=A.parent,x=(l=(o=C==null?void 0:C.getChildIndex)==null?void 0:o.call(C,A))!=null?l:0,I={x:A.x,y:A.y},L={x:(d=(c=A.anchor)==null?void 0:c.x)!=null?d:.5,y:(u=(p=A.anchor)==null?void 0:p.y)!=null?u:.5},_={x:(f=(g=A.scale)==null?void 0:g.x)!=null?f:1,y:(m=(h=A.scale)==null?void 0:h.y)!=null?m:1},O=(b=A.alpha)!=null?b:1,H=(y=A.visible)!=null?y:!0,N=new k(j);N.anchor.set(L.x,L.y),N.position.set(I.x,I.y),N.scale.set(_.x,_.y),N.alpha=O,N.visible=H,C&&(C.removeChild(A),C.addChildAt(N,x),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),T.pixiObject&&(T.pixiObject=N),T.pixi&&(T.pixi=N),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if(A!=null&&A.children){let k=A.children.find(C=>C.texture);k?(k.texture=j,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let P=`raw/library/${n}/${t}`;ce({objectId:v,path:"render.asset.path",value:P}),console.log("[LIBRARY] \u2705 Staged config override for:",v,"path:",P)}catch(v){console.error("[LIBRARY] Error applying slot asset:",v)}}async function or(s,e,t,n){var i;console.log("[LIBRARY] resetSlotAsset:",{objectId:e,defaultAsset:t,category:n});try{let a=e.startsWith("json.")?e.replace("json.",""):e,r=Date.now(),o=`/raw/${t}?t=${r}`;console.log("[LIBRARY] Loading default texture from:",o);let l=await _t.Assets.load(o);if(!l){console.error("[LIBRARY] Failed to load default texture:",o);return}le[a]=l,console.log("[LIBRARY] \u2705 Reset AssetTextures."+a);let c=window.CustomAssets;c!=null&&c[a]&&(c[a].texture=l,console.log("[LIBRARY] \u2705 Reset CustomAssets."+a+" to default"));let d=window.gameObjectManager;if(d){let p=d.get(a);if(p){let u=((i=p.getDisplayObject)==null?void 0:i.call(p))||p.pixiObject||p;u!=null&&u.texture&&(u.texture=l,console.log("[LIBRARY] \u2705 Reset display object:",a))}}ce({objectId:a,path:"render.asset.path",value:t}),console.log("[LIBRARY] \u2705 Reset config override for:",a)}catch(a){console.error("[LIBRARY] Error resetting slot asset:",a)}}var zt=require("pixi.js");var ta=require("pixi.js"),_e=()=>window.debugConfig||{},lr=()=>window.resolveAnchorVec2||(s=>({x:.5,y:.5})),cr=()=>window.resolveScreenAnchorPoint||(()=>new ta.Point),dr=()=>window.resolveScreenRatioPoint||(()=>new ta.Point);function pr(s){Yn(s)&&(s.objectDebugRaf||(s.objectDebugRaf=window.requestAnimationFrame(()=>Kn(s))))}function ur(s){s.objectDebugRaf&&(window.cancelAnimationFrame(s.objectDebugRaf),s.objectDebugRaf=null),Rt(s)}function Yn(s){return s.isDebugOpen}function Kn(s){var a,r,o;if(!Yn(s)){s.objectDebugRaf=null;return}s.objectDebugRaf=window.requestAnimationFrame(()=>Kn(s));let e=na(s);if(!e){Ot(s,null),Rt(s);return}let t=ia(s,e);if(!t){Ot(s,null),Rt(s);return}let n=new zt.Point;(a=t.getGlobalPosition)==null||a.call(t,n);let i=aa(s,t);Ot(s,{instanceId:e,worldX:n.x,worldY:n.y,configX:(r=i==null?void 0:i.x)!=null?r:null,configY:(o=i==null?void 0:i.y)!=null?o:null}),s.highlightObject?la(s,t):da(s),s.highlightAnchor&&i?ca(s,i):pa(s)}function na(s){var i;let e=s.selectedObjectId;if(!e)return null;let t=window.__editableObjectInstances,n=(i=t==null?void 0:t.get)==null?void 0:i.call(t,e);return Array.isArray(n)&&n.length>0?n[0]:e}function ia(s,e){var i,a;let t=window.gameObjectManager,n=(i=t==null?void 0:t.get)==null?void 0:i.call(t,e);return n?((a=n.getDisplayObject)==null?void 0:a.call(n))||n.pixiObject||n:null}function $t(s){let e=s.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function aa(s,e){var r,o;let t=$t(s);if(!t)return null;let n=(r=t.transform)!=null?r:{},i=sa(s);if(!i)return null;if(n.position_ratio!=null)return dr()(i.width,i.height,n.position_ratio);let a=(o=n.anchor)!=null?o:"center";return cr()(i.width,i.height,a)}function sa(s){var a;let e=(a=s.container)==null?void 0:a.querySelector(".game-container"),t=Number(e==null?void 0:e.dataset.screenWidth),n=Number(e==null?void 0:e.dataset.screenHeight);if(Number.isFinite(t)&&t>0&&Number.isFinite(n)&&n>0)return{width:t,height:n};let i=window.gameApp;return i!=null&&i.renderer?{width:i.renderer.width,height:i.renderer.height}:null}function ra(s){let e=window.gameApp;return e!=null&&e.stage?(s.objectBoundsGfx&&s.objectBoundsGfx.parent!==e.stage&&(s.objectBoundsGfx.destroy(),s.objectBoundsGfx=null),s.objectBoundsGfx||(s.objectBoundsGfx=new zt.Graphics,s.objectBoundsGfx.zIndex=999999,e.stage.addChild(s.objectBoundsGfx)),s.objectBoundsGfx):null}function oa(s){let e=window.gameApp;return e!=null&&e.stage?(s.objectAnchorGfx&&s.objectAnchorGfx.parent!==e.stage&&(s.objectAnchorGfx.destroy(),s.objectAnchorGfx=null),s.objectAnchorGfx||(s.objectAnchorGfx=new zt.Graphics,s.objectAnchorGfx.zIndex=1e6,e.stage.addChild(s.objectAnchorGfx)),s.objectAnchorGfx):null}function la(s,e){var i;let t=ra(s);if(!t)return;let n=(i=e.getBounds)==null?void 0:i.call(e);n&&(t.clear(),t.rect(n.x,n.y,n.width,n.height).stroke({width:2,color:16726832,alpha:.9}))}function ca(s,e){let t=oa(s);if(!t)return;let n=6;t.clear(),t.moveTo(e.x-n,e.y),t.lineTo(e.x+n,e.y),t.moveTo(e.x,e.y-n),t.lineTo(e.x,e.y+n),t.stroke({width:2,color:3066993,alpha:.9})}function da(s){s.objectBoundsGfx&&s.objectBoundsGfx.clear()}function pa(s){s.objectAnchorGfx&&s.objectAnchorGfx.clear()}function Rt(s){s.objectBoundsGfx&&(s.objectBoundsGfx.destroy(),s.objectBoundsGfx=null),s.objectAnchorGfx&&(s.objectAnchorGfx.destroy(),s.objectAnchorGfx=null)}function Ot(s,e){s.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function gr(s,e){return e.split(".").reduce((t,n)=>t?t[n]:void 0,s)}function hr(s,e,t){var r;let n=e.split("."),i=n.pop(),a=s;for(let o of n)a[o]=(r=a[o])!=null?r:{},a=a[o];a[i]=t}function ua(s){var n,i,a,r,o;if(!s)return!1;if((n=s.transform)!=null&&n.offset)return!0;let e=((a=(i=s.identity)==null?void 0:i.category)!=null?a:"").toString().toLowerCase(),t=((o=(r=s.identity)==null?void 0:r.id)!=null?o:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function Jn(s){let e=_e();e.layout&&(e.layout.scale_multiplier=1,e.layout.position_offset={x:0,y:0},e.layout.debug_rect_visible=!0,e.layout.debug_rect_color=16711680,e.layout.debug_rect_thickness=4),e.engine&&(e.engine.scale=1,e.engine.background_scale=1.05,e.engine.label_pulse_speed=3,e.engine.label_pulse_intensity=.03),e.physics&&(e.physics.rope_length=420),window.location.reload()}function fr(s){window.location.reload()}function Zn(s){let e=JSON.stringify(_e(),null,2);navigator.clipboard.writeText(e).then(()=>{alert("Debug config copied to clipboard!")}).catch(()=>{console.log(e),alert("Config logged to console (clipboard not available)")})}async function mr(s,e){var t,n,i;if(!(!s.configViewer||!s.container))try{let a=window.getEditableObjectConfig,r=typeof a=="function"?a(e):null;if(!r){let{loadObjectCentricConfig:o,loadObjectConfig:l}=await Promise.resolve().then(()=>(wn(),Ns)),p=(((t=(await o("scene.main")).scene)==null?void 0:t.objects)||[]).find(g=>g.object_config===e||g.instance_id===e);if(!p)return;let u=await l(p.object_config);console.log("[PREVIEW] Loaded object config (fallback)",e,u),Xn(s,u),(n=s.configViewer)==null||n.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,r),Xn(s,r),(i=s.configViewer)==null||i.style.setProperty("display","block");return}catch(a){console.error("[DEBUG] Failed to load object config:",a)}}function Xn(s,e){var p,u,g,f,h,m,b,y,v,w;if(!s.container)return;let t=s.container.querySelector("#config-pos-x"),n=s.container.querySelector("#config-pos-y"),i=s.container.querySelector("#config-scale"),a=s.container.querySelector("#config-anchor-x"),r=s.container.querySelector("#config-anchor-y"),l=ua(e)?(p=e.transform)==null?void 0:p.offset:(u=e.transform)==null?void 0:u.position;t&&(t.value=String((g=l==null?void 0:l.x)!=null?g:0)),n&&(n.value=String((f=l==null?void 0:l.y)!=null?f:0)),i&&(i.value=String((m=(h=e.transform)==null?void 0:h.scale)!=null?m:1));let c=(w=(v=(b=e.transform)==null?void 0:b.anchor)!=null?v:(y=e.render)==null?void 0:y.anchor)!=null?w:{x:.5,y:.5},d=lr()(c);a&&(a.value=String(d.x)),r&&(r.value=String(d.y))}function br(s){var l,c,d,p,u,g,f,h,m,b;let e=s.selectedObjectId;if(!e||!s.container)return;let t=(c=(l=s.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",n=(p=(d=s.container.querySelector("#config-pos-y"))==null?void 0:d.value)!=null?p:"0",i=(g=(u=s.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",a=(h=(f=s.container.querySelector("#config-anchor-x"))==null?void 0:f.value)!=null?h:"0.5",r=(b=(m=s.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",o=`${e}:
1717
- position: (${t}, ${n})
1718
- scale: ${i}
1719
- anchor: (${a}, ${r})`;navigator.clipboard.writeText(o).then(()=>console.log("[DEBUG] Config values copied to clipboard")).catch(y=>console.error("[DEBUG] Failed to copy config values:",y))}async function ga(s,e){var p,u,g,f,h,m,b,y,v,w,E;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!s.container)return;let t=s.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let n=Number((u=(p=s.container.querySelector("#config-pos-x"))==null?void 0:p.value)!=null?u:0),i=Number((f=(g=s.container.querySelector("#config-pos-y"))==null?void 0:g.value)!=null?f:0),a=Number((m=(h=s.container.querySelector("#config-scale"))==null?void 0:h.value)!=null?m:1),r=Number((y=(b=s.container.querySelector("#config-anchor-x"))==null?void 0:b.value)!=null?y:.5),o=Number((w=(v=s.container.querySelector("#config-anchor-y"))==null?void 0:v.value)!=null?w:.5);console.log("[INSPECTOR] Applying config for:",t,{posX:n,posY:i,scale:a,anchorX:r,anchorY:o});let{applyConfigOverride:l}=await Promise.resolve().then(()=>(J(),Be));l({objectId:t,path:"transform.position",value:{x:n,y:i}},{silent:e==null?void 0:e.silent}),l({objectId:t,path:"transform.scale",value:a},{silent:e==null?void 0:e.silent}),l({objectId:t,path:"transform.anchor",value:{x:r,y:o}},{silent:e==null?void 0:e.silent});let c=$t(s);ua(c)&&l({objectId:t,path:"transform.offset",value:{x:n,y:i}},{silent:!0}),console.log("[INSPECTOR] Calling applyEditableObjectConfig...");let d=window.applyEditableObjectConfig;if(typeof d=="function"){let j=(E=window.getEditableObjectConfig)==null?void 0:E.call(window,t);j?(console.log("[INSPECTOR] \u2705 Calling applyEditableObjectConfig for:",t),d(t,j)):console.warn("[INSPECTOR] \u26A0\uFE0F No config found for:",t)}else console.warn("[INSPECTOR] \u26A0\uFE0F applyEditableObjectConfig not available")}async function yr(s,e,t){let{applyConfigOverride:n}=await Promise.resolve().then(()=>(J(),Be));Object.entries(e.assets).forEach(([l,c])=>{n({path:`assets.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.theme).forEach(([l,c])=>{n({path:`runtime.theme.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.ui).forEach(([l,c])=>{n({path:`runtime.ui.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.fonts).forEach(([l,c])=>{n({path:`runtime.fonts.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.audio).forEach(([l,c])=>{n({path:`runtime.audio.${l}`,value:c},{silent:!0})});let i=window.applyEditableEngineConfig;if(typeof i=="function"){let l={theme:e.runtime.theme,fonts:e.runtime.fonts,audio:e.runtime.audio},c={};Object.entries(e.runtime.ui).forEach(([d,p])=>{var u;if(d)if(d.includes(".")){let g=d.split("."),f=c;for(let h=0;h<g.length-1;h++){let m=g[h];f[m]=(u=f[m])!=null?u:{},f=f[m]}f[g[g.length-1]]=p}else c[d]=p}),l.ui=c,i({runtime:l,assets:e.assets})}let a=Object.values(e.assets).some(l=>/^(blob:|data:)/.test(l)),r=(t==null?void 0:t.source)!=="auto"&&!a,o=window.__previewShell;r&&(o!=null&&o.refresh)&&o.refresh()}function vr(s){s.selectedObjectId&&(s.objectAutoApplyTimer&&window.clearTimeout(s.objectAutoApplyTimer),s.objectAutoApplyTimer=window.setTimeout(()=>{s.objectAutoApplyTimer=null,ga(s,{silent:!0})},150))}var rl=3e3;function Dt(s,e,t){let n=t!=null?t:s.offsetParent;if(!n)return;e.style.cursor="move";let i=!1,a=0,r=0,o=0,l=0,c=0,d=0,p=g=>{if(!i)return;let f=n.getBoundingClientRect();s.style.left=`${g.clientX-f.left-c}px`,s.style.top=`${g.clientY-f.top-d}px`},u=()=>{i&&(i=!1,s.classList.remove("dragging"),window.removeEventListener("pointermove",p),window.removeEventListener("pointerup",u))};e.addEventListener("pointerdown",g=>{if(g.button!==0)return;let f=g.target;if(f!=null&&f.closest("button, input, select, textarea"))return;g.preventDefault();let h=s.getBoundingClientRect(),m=n.getBoundingClientRect();console.log("[DRAG] Panel:",s.className),console.log("[DRAG] Container:",n.className),console.log("[DRAG] panelRect:",{left:h.left,top:h.top,width:h.width,height:h.height}),console.log("[DRAG] containerRect:",{left:m.left,top:m.top,width:m.width,height:m.height}),console.log("[DRAG] mouse:",{x:g.clientX,y:g.clientY}),c=g.clientX-h.left,d=g.clientY-h.top,console.log("[DRAG] offset:",{x:c,y:d});let b=h.left-m.left,y=h.top-m.top;console.log("[DRAG] targetPosition:",{left:b,top:y}),s.style.left=`${b}px`,s.style.top=`${y}px`,s.style.right="auto",s.style.bottom="auto",s.style.zIndex=String(++rl),i=!0,s.classList.add("dragging"),window.addEventListener("pointermove",p),window.addEventListener("pointerup",u)})}function wr(s,e,t,n=280,i=200){e.style.cursor="nwse-resize";let a=0,r=0,o=0,l=0,c=!1,d=u=>{var y;if(!c)return;let g=u.clientX-o,f=u.clientY-l,h=Math.max(n,a+g),m=Math.max(i,r+f);s.style.width=`${h}px`,(y=s.closest(".preview-shell"))!=null&&y.classList.contains("layout-fixed")||(s.style.height=`${m}px`),t==null||t(h,m)},p=()=>{c&&(c=!1,window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p))};e.addEventListener("pointerdown",u=>{if(u.button!==0)return;u.preventDefault(),u.stopPropagation();let g=s.getBoundingClientRect();a=g.width,r=g.height,o=u.clientX,l=u.clientY,c=!0,window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)})}function ha(s,e){var h,m,b,y;let t=(b=(m=(h=s.container)==null?void 0:h.querySelector("#debug-overlay"))!=null?m:s.debugOverlay)!=null?b:e.offsetParent;if(!t||(y=s.container)!=null&&y.classList.contains("layout-fixed"))return;let n=t.getBoundingClientRect(),i=e.getBoundingClientRect(),a=12,r=Math.max(250,Math.floor(n.width-a*2)),o=Math.max(200,Math.floor(n.height-a*2));i.width>r&&(e.style.width=`${r}px`),i.height>o&&(e.style.height=`${o}px`);let l=e.getBoundingClientRect(),c=l.left-n.left,d=l.top-n.top,p=Math.max(a,n.width-l.width-a),u=Math.max(a,n.height-l.height-a),g=Math.min(Math.max(c,a),p),f=Math.min(Math.max(d,a),u);e.style.left=`${Math.round(g)}px`,e.style.top=`${Math.round(f)}px`,e.style.right="auto",e.style.bottom="auto"}function rt(s){var n,i;if(!s.container)return;let e=s.container.querySelector("#debug-workbench");if(!e)return;if(ha(s,e),(n=s.container)!=null&&n.classList.contains("layout-fixed")){let a=localStorage.getItem("preview_workbench_state"),r={activeTab:s.activeTab};if(a)try{r={...JSON.parse(a),activeTab:s.activeTab}}catch{}localStorage.setItem("preview_workbench_state",JSON.stringify(r));return}let t={activeTab:s.activeTab,width:e.style.width,height:(i=s.container)!=null&&i.classList.contains("layout-fixed")?"":e.style.height,left:e.style.left,top:e.style.top};localStorage.setItem("preview_workbench_state",JSON.stringify(t))}function Qn(s){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(s.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var i,a;let n=(i=s.container)==null?void 0:i.querySelector("#debug-workbench");if(n){let r=(a=s.container)==null?void 0:a.classList.contains("layout-fixed");t.width&&(n.style.width=t.width),t.height&&!r?n.style.height=t.height:r&&(n.style.height=""),t.left&&(n.style.left=t.left,n.style.right="auto"),t.top&&(n.style.top=t.top,n.style.bottom="auto"),ha(s,n)}})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function fa(s,e){let t=e.getBoundingClientRect();(t.left<0||t.top<0||t.right>window.innerWidth||t.bottom>window.innerHeight)&&(console.warn("[Workbench] Workbench positioned outside viewport, repositioning..."),e.style.left="16px",e.style.top="72px",e.style.right="auto",e.style.bottom="auto",ha(s,e),rt(s))}function xr(s){var i,a,r;if(!s.container)return;let e=s.container,t=e.querySelector("#debug-toggle");t||console.warn("[PREVIEW] Debug toggle not found in DOM"),t==null||t.addEventListener("click",()=>{var o;console.log("[PREVIEW] Debug toggle clicked"),(o=s.toggleDebug)==null||o.call(s)}),(i=e.querySelector("#debug-close"))==null||i.addEventListener("click",()=>{var o;return(o=s.toggleDebug)==null?void 0:o.call(s,!1)}),(a=e.querySelector("#debug-reset"))==null||a.addEventListener("click",()=>Jn(s)),(r=e.querySelector("#debug-export"))==null||r.addEventListener("click",()=>Zn(s)),e.querySelectorAll(".workbench-tab").forEach(o=>{o.addEventListener("click",()=>{let l=o.dataset.tab;s.activeTab=l,ma(s),rt(s)})}),ya(s,e),ba(s,e)}function ma(s){if(!s.container)return;let e=s.container;e.querySelectorAll(".workbench-tab").forEach(i=>{let a=i.dataset.tab;i.classList.toggle("active",a===s.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(i=>{let a=i.dataset.tabPanel;i.classList.toggle("active",a===s.activeTab)})}function ba(s,e){se(s,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),se(s,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),se(s,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),se(s,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),se(s,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),se(s,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),se(s,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),se(s,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),se(s,e,"debug-rope-length","physics.rope_length","#debug-rope-length-value");let t=e.querySelector("#debug-rect-visible");t==null||t.addEventListener("change",()=>{let i=_e();i.layout&&(i.layout.debug_rect_visible=!!t.checked)});let n=e.querySelector("#debug-rect-color");n==null||n.addEventListener("input",()=>{let i=n.value.replace("#",""),a=parseInt(i,16),r=_e();r.layout&&(r.layout.debug_rect_color=Number.isFinite(a)?a:16711680)})}function Er(s){if(!s.container||!s.debugOverlay)return;let e=s.container.querySelector("#debug-workbench"),t=s.container.querySelector("#workbench-handle");e&&t&&(!e.style.left&&!e.style.right&&!e.style.top&&!e.style.bottom&&(e.style.right="16px",e.style.top="72px"),Dt(e,t,s.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{rt(s),fa(s,e)},10)}));let n=s.container.querySelector('[data-panel="scene-objects"]'),i=n==null?void 0:n.querySelector("[data-panel-handle]"),a=n==null?void 0:n.querySelector("[data-panel-resize-v]");n&&i&&(!n.style.left&&!n.style.right&&!n.style.top&&!n.style.bottom&&(n.style.left="16px",n.style.top="72px"),Dt(n,i,s.debugOverlay),i.addEventListener("pointerup",()=>{setTimeout(()=>{fa(s,n)},10)})),n&&a&&wr(n,a);let r=s.container.querySelector('[data-panel="scene-tools-corner"]'),o=r==null?void 0:r.querySelector("[data-panel-handle]");r&&o&&Dt(r,o,s.debugOverlay);let l=s.container.querySelector('[data-panel="nudge-panel"]'),c=l==null?void 0:l.querySelector("[data-panel-handle]");l&&c&&Dt(l,c,s.debugOverlay),Qn(s)}function ya(s,e){Array.from(e.querySelectorAll("[data-panel-toggle]")).forEach(n=>{n.addEventListener("click",()=>{let i=n.closest(".scene-panel");i&&i.classList.toggle("collapsed")})})}function se(s,e,t,n,i){let a=e.querySelector(`#${t}`),r=e.querySelector(i);if(!a||!r)return;let o=gr(_e(),n);typeof o=="number"&&(a.value=String(o),r.textContent=String(o)),a.addEventListener("input",()=>{let l=Number(a.value);r.textContent=String(l),hr(_e(),n,l)})}J();var ei=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async forceResyncAfterApply(){var e;try{await fetch("/api/sync-screens",{method:"POST"})}catch(t){console.warn("[ConfigPersistence] sync-screens failed:",t)}try{let t=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof t=="function"?await t():window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}try{(e=window.refreshEditableConfigIndex)==null||e.call(window)}catch{}try{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}}async initialize(e){this.container=e,this.isDevelopmentMode=typeof window!="undefined"&&document.querySelector('script[type="module"][src*="/@vite/"]')!==null,await this.loadVersionsList(),window.addEventListener("config:changed",()=>{this.refreshPanel()}),this.refreshPanel()}render(){let e=Ie(),{hasChanges:t,overrideCount:n,overrides:i}=e,a={};for(let d of i){let p=d.objectId||"Engine";a[p]||(a[p]=[]),a[p].push(d)}let r=localStorage.getItem("handler_last_applied"),o=r?new Date(parseInt(r)).toLocaleString():"Never",l=this.currentVersion?`Version: ${this.currentVersion} (Active)`:"Original",c=this.currentVersion?`Versioned (${this.currentVersion})`:"Global";return`
1801
+ `}initialize(e,t){var y,v,w,E,P,M,x,_,O,T,A,j,k,C,S,I;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let n=(()=>{var R;let L=window.getEditableEngineConfig;if(typeof L=="function"){let z=L();return(R=z==null?void 0:z.loading)!=null?R:{}}return{}})(),a=(y=this.root)==null?void 0:y.querySelector("#loading-screen-type");a&&(a.value=n.type==="image"?"image":"color",a.addEventListener("change",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{type:a.value}),this.updateFieldVisibility(a.value)}));let r=(v=this.root)==null?void 0:v.querySelector("#loading-background-color");r&&(r.value=n.background_color||"#160a17",r.addEventListener("input",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{background_color:r.value})}));let o=(w=this.root)==null?void 0:w.querySelector("#loading-overlay-alpha"),l=(E=this.root)==null?void 0:E.querySelector("#loading-overlay-alpha-value");o&&(o.value=String((P=n.overlay_alpha)!=null?P:1),l&&(l.textContent=Number(o.value).toFixed(2)),o.addEventListener("input",()=>{var R,z;let L=Number(o.value);l&&(l.textContent=L.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{overlay_alpha:L})}));let c=(M=this.root)==null?void 0:M.querySelector("#loading-text");c&&(c.value=n.text||"",c.addEventListener("input",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{text:c.value})}));let d=(x=this.root)==null?void 0:x.querySelector("#loading-text-scale"),p=(_=this.root)==null?void 0:_.querySelector("#loading-text-scale-value");d&&(d.value=String((O=n.text_scale)!=null?O:.6),p&&(p.textContent=Number(d.value).toFixed(2)),d.addEventListener("input",()=>{var R,z;let L=Number(d.value);p&&(p.textContent=L.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{text_scale:L})}));let u=(T=this.root)==null?void 0:T.querySelector("#loading-enabled");u&&(u.checked=n.enabled!==!1,u.addEventListener("change",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{enabled:u.checked})}));let g=(A=this.root)==null?void 0:A.querySelector("#loading-blur-enabled");g&&(g.checked=n.blur_enabled!==!1,g.addEventListener("change",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{blur_enabled:g.checked})}));let h=(j=this.root)==null?void 0:j.querySelector("#loading-blur-strength"),f=(k=this.root)==null?void 0:k.querySelector("#loading-blur-strength-value");h&&(h.value=String((C=n.blur_strength)!=null?C:8),f&&(f.textContent=h.value),h.addEventListener("input",()=>{var L,R;f&&(f.textContent=h.value),(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{blur_strength:Number(h.value)})}));let m=(S=this.root)==null?void 0:S.querySelector("#loading-show-btn"),b=(I=this.root)==null?void 0:I.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onShowLoadingScreen)==null||R.call(L)}),b==null||b.addEventListener("click",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onHideLoadingScreen)==null||R.call(L)}),this.updateFieldVisibility(n.type==="image"?"image":"color")}updateFieldVisibility(e){var n,a;let t=(n=this.root)==null?void 0:n.querySelector("#loading-color-field"),i=(a=this.root)==null?void 0:a.querySelector("#loading-alpha-field");e==="image"?(t&&(t.style.display="none"),i&&(i.style.display="none")):(t&&(t.style.display=""),i&&(i.style.display=""))}refresh(){}};var Ft=require("pixi.js");var la=require("pixi.js"),Re=()=>window.debugConfig||{},fr=()=>window.resolveAnchorVec2||(s=>({x:.5,y:.5})),mr=()=>window.resolveScreenAnchorPoint||(()=>new la.Point),br=()=>window.resolveScreenRatioPoint||(()=>new la.Point);function yr(s){Zi(s)&&(s.objectDebugRaf||(s.objectDebugRaf=window.requestAnimationFrame(()=>Qi(s))))}function vr(s){s.objectDebugRaf&&(window.cancelAnimationFrame(s.objectDebugRaf),s.objectDebugRaf=null),Nt(s)}function Zi(s){return s.isDebugOpen}function Qi(s){var a,r,o;if(!Zi(s)){s.objectDebugRaf=null;return}s.objectDebugRaf=window.requestAnimationFrame(()=>Qi(s));let e=ca(s);if(!e){Ht(s,null),Nt(s);return}let t=da(s,e);if(!t){Ht(s,null),Nt(s);return}let i=new Ft.Point;(a=t.getGlobalPosition)==null||a.call(t,i);let n=pa(s,t);Ht(s,{instanceId:e,worldX:i.x,worldY:i.y,configX:(r=n==null?void 0:n.x)!=null?r:null,configY:(o=n==null?void 0:n.y)!=null?o:null}),s.highlightObject?fa(s,t):ba(s),s.highlightAnchor&&n?ma(s,n):ya(s)}function ca(s){var n;let e=s.selectedObjectId;if(!e)return null;let t=window.__editableObjectInstances,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return Array.isArray(i)&&i.length>0?i[0]:e}function da(s,e){var n,a;let t=window.gameObjectManager,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return i?((a=i.getDisplayObject)==null?void 0:a.call(i))||i.pixiObject||i:null}function Bt(s){let e=s.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function pa(s,e){var r,o;let t=Bt(s);if(!t)return null;let i=(r=t.transform)!=null?r:{},n=ua(s);if(!n)return null;if(i.position_ratio!=null)return br()(n.width,n.height,i.position_ratio);let a=(o=i.anchor)!=null?o:"center";return mr()(n.width,n.height,a)}function ua(s){var a;let e=(a=s.container)==null?void 0:a.querySelector(".game-container"),t=Number(e==null?void 0:e.dataset.screenWidth),i=Number(e==null?void 0:e.dataset.screenHeight);if(Number.isFinite(t)&&t>0&&Number.isFinite(i)&&i>0)return{width:t,height:i};let n=window.gameApp;return n!=null&&n.renderer?{width:n.renderer.width,height:n.renderer.height}:null}function ga(s){let e=window.gameApp;return e!=null&&e.stage?(s.objectBoundsGfx&&s.objectBoundsGfx.parent!==e.stage&&(s.objectBoundsGfx.destroy(),s.objectBoundsGfx=null),s.objectBoundsGfx||(s.objectBoundsGfx=new Ft.Graphics,s.objectBoundsGfx.zIndex=999999,e.stage.addChild(s.objectBoundsGfx)),s.objectBoundsGfx):null}function ha(s){let e=window.gameApp;return e!=null&&e.stage?(s.objectAnchorGfx&&s.objectAnchorGfx.parent!==e.stage&&(s.objectAnchorGfx.destroy(),s.objectAnchorGfx=null),s.objectAnchorGfx||(s.objectAnchorGfx=new Ft.Graphics,s.objectAnchorGfx.zIndex=1e6,e.stage.addChild(s.objectAnchorGfx)),s.objectAnchorGfx):null}function fa(s,e){var n;let t=ga(s);if(!t)return;let i=(n=e.getBounds)==null?void 0:n.call(e);i&&(t.clear(),t.rect(i.x,i.y,i.width,i.height).stroke({width:2,color:16726832,alpha:.9}))}function ma(s,e){let t=ha(s);if(!t)return;let i=6;t.clear(),t.moveTo(e.x-i,e.y),t.lineTo(e.x+i,e.y),t.moveTo(e.x,e.y-i),t.lineTo(e.x,e.y+i),t.stroke({width:2,color:3066993,alpha:.9})}function ba(s){s.objectBoundsGfx&&s.objectBoundsGfx.clear()}function ya(s){s.objectAnchorGfx&&s.objectAnchorGfx.clear()}function Nt(s){s.objectBoundsGfx&&(s.objectBoundsGfx.destroy(),s.objectBoundsGfx=null),s.objectAnchorGfx&&(s.objectAnchorGfx.destroy(),s.objectAnchorGfx=null)}function Ht(s,e){s.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function wr(s,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,s)}function xr(s,e,t){var r;let i=e.split("."),n=i.pop(),a=s;for(let o of i)a[o]=(r=a[o])!=null?r:{},a=a[o];a[n]=t}function va(s){var i,n,a,r,o;if(!s)return!1;if((i=s.transform)!=null&&i.offset)return!0;let e=((a=(n=s.identity)==null?void 0:n.category)!=null?a:"").toString().toLowerCase(),t=((o=(r=s.identity)==null?void 0:r.id)!=null?o:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function tn(s){let e=Re();e.layout&&(e.layout.scale_multiplier=1,e.layout.position_offset={x:0,y:0},e.layout.debug_rect_visible=!0,e.layout.debug_rect_color=16711680,e.layout.debug_rect_thickness=4),e.engine&&(e.engine.scale=1,e.engine.background_scale=1.05,e.engine.label_pulse_speed=3,e.engine.label_pulse_intensity=.03),e.physics&&(e.physics.rope_length=420),window.location.reload()}function Sr(s){window.location.reload()}function nn(s){let e=JSON.stringify(Re(),null,2);navigator.clipboard.writeText(e).then(()=>{alert("Debug config copied to clipboard!")}).catch(()=>{console.log(e),alert("Config logged to console (clipboard not available)")})}async function Er(s,e){var t,i,n;if(!(!s.configViewer||!s.container))try{let a=window.getEditableObjectConfig,r=typeof a=="function"?a(e):null;if(!r){let{loadObjectCentricConfig:o,loadObjectConfig:l}=await Promise.resolve().then(()=>(Si(),qs)),p=(((t=(await o("scene.main")).scene)==null?void 0:t.objects)||[]).find(g=>g.object_config===e||g.instance_id===e);if(!p)return;let u=await l(p.object_config);console.log("[PREVIEW] Loaded object config (fallback)",e,u),en(s,u),(i=s.configViewer)==null||i.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,r),en(s,r),(n=s.configViewer)==null||n.style.setProperty("display","block");return}catch(a){console.error("[DEBUG] Failed to load object config:",a)}}function en(s,e){var p,u,g,h,f,m,b,y,v,w;if(!s.container)return;let t=s.container.querySelector("#config-pos-x"),i=s.container.querySelector("#config-pos-y"),n=s.container.querySelector("#config-scale"),a=s.container.querySelector("#config-anchor-x"),r=s.container.querySelector("#config-anchor-y"),l=va(e)?(p=e.transform)==null?void 0:p.offset:(u=e.transform)==null?void 0:u.position;t&&(t.value=String((g=l==null?void 0:l.x)!=null?g:0)),i&&(i.value=String((h=l==null?void 0:l.y)!=null?h:0)),n&&(n.value=String((m=(f=e.transform)==null?void 0:f.scale)!=null?m:1));let c=(w=(v=(b=e.transform)==null?void 0:b.anchor)!=null?v:(y=e.render)==null?void 0:y.anchor)!=null?w:{x:.5,y:.5},d=fr()(c);a&&(a.value=String(d.x)),r&&(r.value=String(d.y))}function Cr(s){var l,c,d,p,u,g,h,f,m,b;let e=s.selectedObjectId;if(!e||!s.container)return;let t=(c=(l=s.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",i=(p=(d=s.container.querySelector("#config-pos-y"))==null?void 0:d.value)!=null?p:"0",n=(g=(u=s.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",a=(f=(h=s.container.querySelector("#config-anchor-x"))==null?void 0:h.value)!=null?f:"0.5",r=(b=(m=s.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",o=`${e}:
1802
+ position: (${t}, ${i})
1803
+ scale: ${n}
1804
+ anchor: (${a}, ${r})`;navigator.clipboard.writeText(o).then(()=>console.log("[DEBUG] Config values copied to clipboard")).catch(y=>console.error("[DEBUG] Failed to copy config values:",y))}async function wa(s,e){var p,u,g,h,f,m,b,y,v,w,E;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!s.container)return;let t=s.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let i=Number((u=(p=s.container.querySelector("#config-pos-x"))==null?void 0:p.value)!=null?u:0),n=Number((h=(g=s.container.querySelector("#config-pos-y"))==null?void 0:g.value)!=null?h:0),a=Number((m=(f=s.container.querySelector("#config-scale"))==null?void 0:f.value)!=null?m:1),r=Number((y=(b=s.container.querySelector("#config-anchor-x"))==null?void 0:b.value)!=null?y:.5),o=Number((w=(v=s.container.querySelector("#config-anchor-y"))==null?void 0:v.value)!=null?w:.5);console.log("[INSPECTOR] Applying config for:",t,{posX:i,posY:n,scale:a,anchorX:r,anchorY:o});let{applyConfigOverride:l}=await Promise.resolve().then(()=>(K(),Ge));l({objectId:t,path:"transform.position",value:{x:i,y:n}},{silent:e==null?void 0:e.silent}),l({objectId:t,path:"transform.scale",value:a},{silent:e==null?void 0:e.silent}),l({objectId:t,path:"transform.anchor",value:{x:r,y:o}},{silent:e==null?void 0:e.silent});let c=Bt(s);va(c)&&l({objectId:t,path:"transform.offset",value:{x:i,y:n}},{silent:!0}),console.log("[INSPECTOR] Calling applyEditableObjectConfig...");let d=window.applyEditableObjectConfig;if(typeof d=="function"){let P=(E=window.getEditableObjectConfig)==null?void 0:E.call(window,t);P?(console.log("[INSPECTOR] \u2705 Calling applyEditableObjectConfig for:",t),d(t,P)):console.warn("[INSPECTOR] \u26A0\uFE0F No config found for:",t)}else console.warn("[INSPECTOR] \u26A0\uFE0F applyEditableObjectConfig not available")}async function Ar(s,e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(K(),Ge));Object.entries(e.assets).forEach(([l,c])=>{i({path:`assets.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.theme).forEach(([l,c])=>{i({path:`runtime.theme.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.ui).forEach(([l,c])=>{i({path:`runtime.ui.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.fonts).forEach(([l,c])=>{i({path:`runtime.fonts.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.audio).forEach(([l,c])=>{i({path:`runtime.audio.${l}`,value:c},{silent:!0})});let n=window.applyEditableEngineConfig;if(typeof n=="function"){let l={theme:e.runtime.theme,fonts:e.runtime.fonts,audio:e.runtime.audio},c={};Object.entries(e.runtime.ui).forEach(([d,p])=>{var u;if(d)if(d.includes(".")){let g=d.split("."),h=c;for(let f=0;f<g.length-1;f++){let m=g[f];h[m]=(u=h[m])!=null?u:{},h=h[m]}h[g[g.length-1]]=p}else c[d]=p}),l.ui=c,n({runtime:l,assets:e.assets})}let a=Object.values(e.assets).some(l=>/^(blob:|data:)/.test(l)),r=(t==null?void 0:t.source)!=="auto"&&!a,o=window.__previewShell;r&&(o!=null&&o.refresh)&&o.refresh()}function Tr(s){s.selectedObjectId&&(s.objectAutoApplyTimer&&window.clearTimeout(s.objectAutoApplyTimer),s.objectAutoApplyTimer=window.setTimeout(()=>{s.objectAutoApplyTimer=null,wa(s,{silent:!0})},150))}var gl=3e3;function Ye(s,e,t){let i=t!=null?t:s.offsetParent;if(!i)return;e.style.cursor="move";let n=!1,a=0,r=0,o=0,l=0,c=0,d=0,p=g=>{if(!n)return;let h=i.getBoundingClientRect();s.style.left=`${g.clientX-h.left-c}px`,s.style.top=`${g.clientY-h.top-d}px`},u=()=>{n&&(n=!1,s.classList.remove("dragging"),window.removeEventListener("pointermove",p),window.removeEventListener("pointerup",u))};e.addEventListener("pointerdown",g=>{if(g.button!==0)return;let h=g.target;if(h!=null&&h.closest("button, input, select, textarea"))return;g.preventDefault();let f=s.getBoundingClientRect(),m=i.getBoundingClientRect();console.log("[DRAG] Panel:",s.className),console.log("[DRAG] Container:",i.className),console.log("[DRAG] panelRect:",{left:f.left,top:f.top,width:f.width,height:f.height}),console.log("[DRAG] containerRect:",{left:m.left,top:m.top,width:m.width,height:m.height}),console.log("[DRAG] mouse:",{x:g.clientX,y:g.clientY}),c=g.clientX-f.left,d=g.clientY-f.top,console.log("[DRAG] offset:",{x:c,y:d});let b=f.left-m.left,y=f.top-m.top;console.log("[DRAG] targetPosition:",{left:b,top:y}),s.style.left=`${b}px`,s.style.top=`${y}px`,s.style.right="auto",s.style.bottom="auto",s.style.zIndex=String(++gl),n=!0,s.classList.add("dragging"),window.addEventListener("pointermove",p),window.addEventListener("pointerup",u)})}function an(s,e,t,i=280,n=200){e.style.cursor="nwse-resize";let a=0,r=0,o=0,l=0,c=!1,d=u=>{var y;if(!c)return;let g=u.clientX-o,h=u.clientY-l,f=Math.max(i,a+g),m=Math.max(n,r+h);s.style.width=`${f}px`,(y=s.closest(".preview-shell"))!=null&&y.classList.contains("layout-fixed")||(s.style.height=`${m}px`),t==null||t(f,m)},p=()=>{c&&(c=!1,window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p))};e.addEventListener("pointerdown",u=>{if(u.button!==0)return;u.preventDefault(),u.stopPropagation();let g=s.getBoundingClientRect();a=g.width,r=g.height,o=u.clientX,l=u.clientY,c=!0,window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)})}function xa(s,e){var f,m,b,y;let t=(b=(m=(f=s.container)==null?void 0:f.querySelector("#debug-overlay"))!=null?m:s.debugOverlay)!=null?b:e.offsetParent;if(!t||(y=s.container)!=null&&y.classList.contains("layout-fixed"))return;let i=t.getBoundingClientRect(),n=e.getBoundingClientRect(),a=12,r=Math.max(250,Math.floor(i.width-a*2)),o=Math.max(200,Math.floor(i.height-a*2));n.width>r&&(e.style.width=`${r}px`),n.height>o&&(e.style.height=`${o}px`);let l=e.getBoundingClientRect(),c=l.left-i.left,d=l.top-i.top,p=Math.max(a,i.width-l.width-a),u=Math.max(a,i.height-l.height-a),g=Math.min(Math.max(c,a),p),h=Math.min(Math.max(d,a),u);e.style.left=`${Math.round(g)}px`,e.style.top=`${Math.round(h)}px`,e.style.right="auto",e.style.bottom="auto"}function dt(s){var i,n;if(!s.container)return;let e=s.container.querySelector("#debug-workbench");if(!e)return;if(xa(s,e),(i=s.container)!=null&&i.classList.contains("layout-fixed")){let a=localStorage.getItem("preview_workbench_state"),r={activeTab:s.activeTab};if(a)try{r={...JSON.parse(a),activeTab:s.activeTab}}catch{}localStorage.setItem("preview_workbench_state",JSON.stringify(r));return}let t={activeTab:s.activeTab,width:e.style.width,height:(n=s.container)!=null&&n.classList.contains("layout-fixed")?"":e.style.height,left:e.style.left,top:e.style.top};localStorage.setItem("preview_workbench_state",JSON.stringify(t))}function sn(s){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(s.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var n,a;let i=(n=s.container)==null?void 0:n.querySelector("#debug-workbench");if(i){let r=(a=s.container)==null?void 0:a.classList.contains("layout-fixed");t.width&&(i.style.width=t.width),t.height&&!r?i.style.height=t.height:r&&(i.style.height=""),t.left&&(i.style.left=t.left,i.style.right="auto"),t.top&&(i.style.top=t.top,i.style.bottom="auto"),xa(s,i)}})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function Sa(s,e){let t=e.getBoundingClientRect();(t.left<0||t.top<0||t.right>window.innerWidth||t.bottom>window.innerHeight)&&(console.warn("[Workbench] Workbench positioned outside viewport, repositioning..."),e.style.left="16px",e.style.top="72px",e.style.right="auto",e.style.bottom="auto",xa(s,e),dt(s))}function Lr(s){var n,a,r;if(!s.container)return;let e=s.container,t=e.querySelector("#debug-toggle");t||console.warn("[PREVIEW] Debug toggle not found in DOM"),t==null||t.addEventListener("click",()=>{var o;console.log("[PREVIEW] Debug toggle clicked"),(o=s.toggleDebug)==null||o.call(s)}),(n=e.querySelector("#debug-close"))==null||n.addEventListener("click",()=>{var o;return(o=s.toggleDebug)==null?void 0:o.call(s,!1)}),(a=e.querySelector("#debug-reset"))==null||a.addEventListener("click",()=>tn(s)),(r=e.querySelector("#debug-export"))==null||r.addEventListener("click",()=>nn(s)),e.querySelectorAll(".workbench-tab").forEach(o=>{o.addEventListener("click",()=>{let l=o.dataset.tab;s.activeTab=l,Ea(s),dt(s)})}),Aa(s,e),Ca(s,e)}function Ea(s){if(!s.container)return;let e=s.container;e.querySelectorAll(".workbench-tab").forEach(n=>{let a=n.dataset.tab;n.classList.toggle("active",a===s.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(n=>{let a=n.dataset.tabPanel;n.classList.toggle("active",a===s.activeTab)})}function Ca(s,e){oe(s,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),oe(s,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),oe(s,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),oe(s,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),oe(s,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),oe(s,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),oe(s,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),oe(s,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),oe(s,e,"debug-rope-length","physics.rope_length","#debug-rope-length-value");let t=e.querySelector("#debug-rect-visible");t==null||t.addEventListener("change",()=>{let n=Re();n.layout&&(n.layout.debug_rect_visible=!!t.checked)});let i=e.querySelector("#debug-rect-color");i==null||i.addEventListener("input",()=>{let n=i.value.replace("#",""),a=parseInt(n,16),r=Re();r.layout&&(r.layout.debug_rect_color=Number.isFinite(a)?a:16711680)})}function kr(s){if(!s.container||!s.debugOverlay)return;let e=s.container.querySelector("#debug-workbench"),t=s.container.querySelector("#workbench-handle");e&&t&&(!e.style.left&&!e.style.right&&!e.style.top&&!e.style.bottom&&(e.style.right="16px",e.style.top="72px"),Ye(e,t,s.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{dt(s),Sa(s,e)},10)}));let i=s.container.querySelector('[data-panel="scene-objects"]'),n=i==null?void 0:i.querySelector("[data-panel-handle]"),a=i==null?void 0:i.querySelector("[data-panel-resize-v]");i&&n&&(!i.style.left&&!i.style.right&&!i.style.top&&!i.style.bottom&&(i.style.left="16px",i.style.top="72px"),Ye(i,n,s.debugOverlay),n.addEventListener("pointerup",()=>{setTimeout(()=>{Sa(s,i)},10)})),i&&a&&an(i,a);let r=s.container.querySelector('[data-panel="scene-tools-corner"]'),o=r==null?void 0:r.querySelector("[data-panel-handle]");r&&o&&Ye(r,o,s.debugOverlay);let l=s.container.querySelector('[data-panel="nudge-panel"]'),c=l==null?void 0:l.querySelector("[data-panel-handle]");l&&c&&Ye(l,c,s.debugOverlay),sn(s)}function Aa(s,e){Array.from(e.querySelectorAll("[data-panel-toggle]")).forEach(i=>{i.addEventListener("click",()=>{let n=i.closest(".scene-panel");n&&n.classList.toggle("collapsed")})})}function oe(s,e,t,i,n){let a=e.querySelector(`#${t}`),r=e.querySelector(n);if(!a||!r)return;let o=wr(Re(),i);typeof o=="number"&&(a.value=String(o),r.textContent=String(o)),a.addEventListener("input",()=>{let l=Number(a.value);r.textContent=String(l),xr(Re(),i,l)})}K();var rn=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async forceResyncAfterApply(){var e;try{await fetch("/api/sync-screens",{method:"POST"})}catch(t){console.warn("[ConfigPersistence] sync-screens failed:",t)}try{let t=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof t=="function"?await t():window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}try{(e=window.refreshEditableConfigIndex)==null||e.call(window)}catch{}try{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}}async initialize(e){this.container=e,this.isDevelopmentMode=typeof window!="undefined"&&document.querySelector('script[type="module"][src*="/@vite/"]')!==null,await this.loadVersionsList(),window.addEventListener("config:changed",()=>{this.refreshPanel()}),this.refreshPanel()}render(){let e=Me(),{hasChanges:t,overrideCount:i,overrides:n}=e,a={};for(let d of n){let p=d.objectId||"Engine";a[p]||(a[p]=[]),a[p].push(d)}let r=localStorage.getItem("handler_last_applied"),o=r?new Date(parseInt(r)).toLocaleString():"Never",l=this.currentVersion?`Version: ${this.currentVersion} (Active)`:"Original",c=this.currentVersion?`Versioned (${this.currentVersion})`:"Global";return`
1720
1805
  <div class="config-persistence-panel">
1721
1806
  <!-- Status Footer (Always Visible) -->
1722
1807
  <div class="persistence-status-footer">
@@ -1726,7 +1811,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1726
1811
  </div>
1727
1812
  <div class="status-footer-row">
1728
1813
  <span class="status-footer-label">Overrides:</span>
1729
- <span class="status-footer-value">${n} staged</span>
1814
+ <span class="status-footer-value">${i} staged</span>
1730
1815
  </div>
1731
1816
  <div class="status-footer-row">
1732
1817
  <span class="status-footer-label">Assets:</span>
@@ -1749,7 +1834,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
1749
1834
  ${t?`
1750
1835
  <div class="status-box">
1751
1836
  <span class="status-badge">UNAPPLIED</span>
1752
- <span class="status-text">${n} staging changes</span>
1837
+ <span class="status-text">${i} staging changes</span>
1753
1838
  </div>
1754
1839
  <div class="status-action-hint">Review below before applying to project</div>
1755
1840
  `:`
@@ -1880,17 +1965,17 @@ This will delete generated config JSON files in configs/objects that are not ref
1880
1965
 
1881
1966
  It will NOT touch library/base configs.
1882
1967
 
1883
- Continue?`))try{e.textContent="\u23F3 Pruning...",e.setAttribute("disabled","true");let g=await fetch("/api/objects/prune-unused",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dryRun:!1})}),f=await g.json().catch(()=>({}));if(!g.ok||(f==null?void 0:f.success)===!1)throw new Error((f==null?void 0:f.error)||"Prune failed");await this.forceResyncAfterApply();let h=Array.isArray(f.deletedFiles)?f.deletedFiles.length:0,m=Array.isArray(f.removedAssetSlots)?f.removedAssetSlots.length:0;this.showSuccessNotification(`Pruned ${h} configs, ${m} asset slots`),this.refreshPanel()}catch(g){console.error("[ConfigPersistence] Prune unused failed:",g),alert(`\u274C Prune failed: ${g.message}`)}finally{e.textContent="\u{1F9F9} PRUNE UNUSED OBJECT CONFIGS",e.removeAttribute("disabled")}});let t=this.container.querySelector("#create-version-btn");t==null||t.addEventListener("click",async()=>{var f;if(t.getAttribute("disabled")!==null)return;if(!Ie().hasChanges){alert("No changes to save. Make some edits first.");return}if(confirm(`Save As New Version?
1968
+ Continue?`))try{e.textContent="\u23F3 Pruning...",e.setAttribute("disabled","true");let g=await fetch("/api/objects/prune-unused",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dryRun:!1})}),h=await g.json().catch(()=>({}));if(!g.ok||(h==null?void 0:h.success)===!1)throw new Error((h==null?void 0:h.error)||"Prune failed");await this.forceResyncAfterApply();let f=Array.isArray(h.deletedFiles)?h.deletedFiles.length:0,m=Array.isArray(h.removedAssetSlots)?h.removedAssetSlots.length:0;this.showSuccessNotification(`Pruned ${f} configs, ${m} asset slots`),this.refreshPanel()}catch(g){console.error("[ConfigPersistence] Prune unused failed:",g),alert(`\u274C Prune failed: ${g.message}`)}finally{e.textContent="\u{1F9F9} PRUNE UNUSED OBJECT CONFIGS",e.removeAttribute("disabled")}});let t=this.container.querySelector("#create-version-btn");t==null||t.addEventListener("click",async()=>{var h;if(t.getAttribute("disabled")!==null)return;if(!Me().hasChanges){alert("No changes to save. Make some edits first.");return}if(confirm(`Save As New Version?
1884
1969
 
1885
1970
  This will:
1886
1971
  \u2022 Create a new version snapshot
1887
1972
  \u2022 Include all current changes
1888
1973
  \u2022 Clear staged overrides after save
1889
- \u2022 Set the new version as active`))try{let h=localStorage.getItem("handler_last_version_name")||"",b=((f=prompt("Version name (e.g. v1.2.0, test_2024):",h))!=null?f:"").trim();if(!b){alert("Version name is required.");return}localStorage.setItem("handler_last_version_name",b),t.textContent="\u23F3 Creating version...",t.setAttribute("disabled","true"),await hn(b),ne(),await this.forceResyncAfterApply(),this.showSuccessNotification("Version created and set as active"),await this.loadVersionsList(),this.refreshPanel()}catch(h){console.error("[ConfigPersistence] Create version failed:",h),alert(`\u274C Failed to create version: ${h.message}`),t.textContent="\u{1F4DD} SAVE AS NEW VERSION",t.removeAttribute("disabled")}});let n=this.container.querySelector("#apply-current-btn");n==null||n.addEventListener("click",async()=>{if(n.getAttribute("disabled")!==null)return;let u=this.currentVersion?`version "${this.currentVersion}"`:"Original configs";if(confirm(`Apply to Current Source?
1974
+ \u2022 Set the new version as active`))try{let f=localStorage.getItem("handler_last_version_name")||"",b=((h=prompt("Version name (e.g. v1.2.0, test_2024):",f))!=null?h:"").trim();if(!b){alert("Version name is required.");return}localStorage.setItem("handler_last_version_name",b),t.textContent="\u23F3 Creating version...",t.setAttribute("disabled","true"),await mi(b),ae(),await this.forceResyncAfterApply(),this.showSuccessNotification("Version created and set as active"),await this.loadVersionsList(),this.refreshPanel()}catch(f){console.error("[ConfigPersistence] Create version failed:",f),alert(`\u274C Failed to create version: ${f.message}`),t.textContent="\u{1F4DD} SAVE AS NEW VERSION",t.removeAttribute("disabled")}});let i=this.container.querySelector("#apply-current-btn");i==null||i.addEventListener("click",async()=>{if(i.getAttribute("disabled")!==null)return;let u=this.currentVersion?`version "${this.currentVersion}"`:"Original configs";if(confirm(`Apply to Current Source?
1890
1975
 
1891
1976
  This will write all staged changes to ${u}.
1892
1977
 
1893
- After applying, staged overrides will be cleared.`))try{n.textContent="\u23F3 Applying...",n.setAttribute("disabled","true");let f=Fe(),h={};for(let[y,v]of Object.entries(f.objects)){let w=v,E=y;/^(json\.|ui\.|effects\.|engine\.)/.test(E)||(E=`json.${y}`),w&&typeof w=="object"&&(w.identity||(w.identity={}),w.identity.id=E),h[`objects/${E}.json`]=w}f.engine&&(f.engine.runtime&&(h["engine/engine.runtime.json"]=f.engine.runtime),f.engine.assets&&(h["engine/engine.assets.json"]=f.engine.assets),f.engine.splash&&(h["engine/engine.splash.json"]=f.engine.splash),f.engine.loading&&(h["engine/engine.loading.json"]=f.engine.loading),f.engine.start&&(h["engine/engine.start.json"]=f.engine.start),f.engine.tutorial&&(h["engine/engine.tutorial.json"]=f.engine.tutorial),f.engine.endgame&&(h["engine/engine.endgame.json"]=f.engine.endgame),!f.engine.runtime&&!f.engine.assets&&(h["engine/engine.json"]=f.engine));for(let[y,v]of Object.entries(f.scenes)){let w=y.startsWith("scene.")?y:`scene.${y}`;h[`scenes/${w}.json`]=v}let m=this.currentVersion?"/api/apply-current":"/api/apply-direct",b=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:h,assets:{},hadCacheAtApply:!0})});if(!b.ok){let y=await b.json();throw new Error(y.error||"Apply to current source failed")}ne(),this.showSuccessNotification("Applied to current source"),await this.loadVersionsList(),this.refreshPanel(),await this.forceResyncAfterApply()}catch(f){console.error("[ConfigPersistence] Apply current failed:",f),alert(`\u274C Apply to current source failed: ${f.message}`),n.textContent="\u{1F4BE} APPLY TO CURRENT SOURCE",n.removeAttribute("disabled")}});let i=this.container.querySelector("#apply-base-btn");i==null||i.addEventListener("click",async()=>{if(confirm(`\u26A0\uFE0F DANGER: APPLY TO BASE
1978
+ After applying, staged overrides will be cleared.`))try{i.textContent="\u23F3 Applying...",i.setAttribute("disabled","true");let h=Ue(),f={};for(let[y,v]of Object.entries(h.objects)){let w=v,E=y;/^(json\.|ui\.|effects\.|engine\.)/.test(E)||(E=`json.${y}`),w&&typeof w=="object"&&(w.identity||(w.identity={}),w.identity.id=E),f[`objects/${E}.json`]=w}h.engine&&(h.engine.runtime&&(f["engine/engine.runtime.json"]=h.engine.runtime),h.engine.assets&&(f["engine/engine.assets.json"]=h.engine.assets),h.engine.splash&&(f["engine/engine.splash.json"]=h.engine.splash),h.engine.loading&&(f["engine/engine.loading.json"]=h.engine.loading),h.engine.start&&(f["engine/engine.start.json"]=h.engine.start),h.engine.tutorial&&(f["engine/engine.tutorial.json"]=h.engine.tutorial),h.engine.endgame&&(f["engine/engine.endgame.json"]=h.engine.endgame),!h.engine.runtime&&!h.engine.assets&&(f["engine/engine.json"]=h.engine));for(let[y,v]of Object.entries(h.scenes)){let w=y.startsWith("scene.")?y:`scene.${y}`;f[`scenes/${w}.json`]=v}let m=this.currentVersion?"/api/apply-current":"/api/apply-direct",b=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:f,assets:{},hadCacheAtApply:!0})});if(!b.ok){let y=await b.json();throw new Error(y.error||"Apply to current source failed")}ae(),this.showSuccessNotification("Applied to current source"),await this.loadVersionsList(),this.refreshPanel(),await this.forceResyncAfterApply()}catch(h){console.error("[ConfigPersistence] Apply current failed:",h),alert(`\u274C Apply to current source failed: ${h.message}`),i.textContent="\u{1F4BE} APPLY TO CURRENT SOURCE",i.removeAttribute("disabled")}});let n=this.container.querySelector("#apply-base-btn");n==null||n.addEventListener("click",async()=>{if(confirm(`\u26A0\uFE0F DANGER: APPLY TO BASE
1894
1979
 
1895
1980
  This will DIRECTLY MODIFY base configuration files.
1896
1981
 
@@ -1900,25 +1985,25 @@ This is ONLY for active development.
1900
1985
 
1901
1986
  Make sure your project is under Git version control.
1902
1987
 
1903
- Continue?`))try{i.textContent="\u23F3 Writing to base...",i.setAttribute("disabled","true");let g=Fe(),f={};for(let[m,b]of Object.entries(g.objects)){let y=b,v=m;/^(json\.|ui\.|effects\.|engine\.)/.test(v)||(v=`json.${m}`),y&&typeof y=="object"&&(y.identity||(y.identity={}),y.identity.id=v),f[`objects/${v}.json`]=y}g.engine&&(g.engine.runtime&&(f["engine/engine.runtime.json"]=g.engine.runtime),g.engine.assets&&(f["engine/engine.assets.json"]=g.engine.assets),g.engine.splash&&(f["engine/engine.splash.json"]=g.engine.splash),g.engine.loading&&(f["engine/engine.loading.json"]=g.engine.loading),g.engine.start&&(f["engine/engine.start.json"]=g.engine.start),g.engine.tutorial&&(f["engine/engine.tutorial.json"]=g.engine.tutorial),g.engine.endgame&&(f["engine/engine.endgame.json"]=g.engine.endgame),!g.engine.runtime&&!g.engine.assets&&(f["engine/engine.json"]=g.engine));for(let[m,b]of Object.entries(g.scenes)){let y=m.startsWith("scene.")?m:`scene.${m}`;f[`scenes/${y}.json`]=b}let h=await fetch("/api/apply-direct",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:f,assets:{}})});if(!h.ok){let m=await h.json();throw new Error(m.error||"Apply to base failed")}ne(),this.showSuccessNotification(),this.refreshPanel(),await this.forceResyncAfterApply()}catch(g){console.error("[ConfigPersistence] Apply to base failed:",g),alert(`\u274C Apply to base failed: ${g.message}`),i.textContent="\u{1F527} APPLY TO BASE (No Version)",i.removeAttribute("disabled")}});let a=this.container.querySelector("#version-selector");a==null||a.addEventListener("change",async u=>{let f=u.target.value;await this.switchVersion(f)}),this.container.querySelectorAll(".item-remove").forEach(u=>{u.addEventListener("click",()=>{let g=u.dataset.removePath,f=u.dataset.removeId;Lt(f||void 0,g)})});let o=this.container.querySelector("#clear-all-overrides"),l=this.container.querySelector("#discard-all-overrides-btn"),c=()=>{confirm("Discard all staged changes? This will clear all overrides and reload from current Source.")&&(ne(),kt(),this.refreshPanel())};o==null||o.addEventListener("click",c),l==null||l.addEventListener("click",c);let d=this.container.querySelector("#reset-to-applied-btn");d==null||d.addEventListener("click",()=>{confirm("Discard changes and reload last applied state?")&&kt()});let p=this.container.querySelector("#reset-to-original-btn");p==null||p.addEventListener("click",async()=>{await fn()})}showSuccessNotification(e){let t=document.createElement("div");t.className="persistence-notification success";let n=e&&e.trim().length>0?e.trim():"Changes Applied!";t.innerHTML=`
1988
+ Continue?`))try{n.textContent="\u23F3 Writing to base...",n.setAttribute("disabled","true");let g=Ue(),h={};for(let[m,b]of Object.entries(g.objects)){let y=b,v=m;/^(json\.|ui\.|effects\.|engine\.)/.test(v)||(v=`json.${m}`),y&&typeof y=="object"&&(y.identity||(y.identity={}),y.identity.id=v),h[`objects/${v}.json`]=y}g.engine&&(g.engine.runtime&&(h["engine/engine.runtime.json"]=g.engine.runtime),g.engine.assets&&(h["engine/engine.assets.json"]=g.engine.assets),g.engine.splash&&(h["engine/engine.splash.json"]=g.engine.splash),g.engine.loading&&(h["engine/engine.loading.json"]=g.engine.loading),g.engine.start&&(h["engine/engine.start.json"]=g.engine.start),g.engine.tutorial&&(h["engine/engine.tutorial.json"]=g.engine.tutorial),g.engine.endgame&&(h["engine/engine.endgame.json"]=g.engine.endgame),!g.engine.runtime&&!g.engine.assets&&(h["engine/engine.json"]=g.engine));for(let[m,b]of Object.entries(g.scenes)){let y=m.startsWith("scene.")?m:`scene.${m}`;h[`scenes/${y}.json`]=b}let f=await fetch("/api/apply-direct",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:h,assets:{}})});if(!f.ok){let m=await f.json();throw new Error(m.error||"Apply to base failed")}ae(),this.showSuccessNotification(),this.refreshPanel(),await this.forceResyncAfterApply()}catch(g){console.error("[ConfigPersistence] Apply to base failed:",g),alert(`\u274C Apply to base failed: ${g.message}`),n.textContent="\u{1F527} APPLY TO BASE (No Version)",n.removeAttribute("disabled")}});let a=this.container.querySelector("#version-selector");a==null||a.addEventListener("change",async u=>{let h=u.target.value;await this.switchVersion(h)}),this.container.querySelectorAll(".item-remove").forEach(u=>{u.addEventListener("click",()=>{let g=u.dataset.removePath,h=u.dataset.removeId;jt(h||void 0,g)})});let o=this.container.querySelector("#clear-all-overrides"),l=this.container.querySelector("#discard-all-overrides-btn"),c=()=>{confirm("Discard all staged changes? This will clear all overrides and reload from current Source.")&&(ae(),_t(),this.refreshPanel())};o==null||o.addEventListener("click",c),l==null||l.addEventListener("click",c);let d=this.container.querySelector("#reset-to-applied-btn");d==null||d.addEventListener("click",()=>{confirm("Discard changes and reload last applied state?")&&_t()});let p=this.container.querySelector("#reset-to-original-btn");p==null||p.addEventListener("click",async()=>{await bi()})}showSuccessNotification(e){let t=document.createElement("div");t.className="persistence-notification success";let i=e&&e.trim().length>0?e.trim():"Changes Applied!";t.innerHTML=`
1904
1989
  <div class="notify-icon">\u2705</div>
1905
1990
  <div class="notify-content">
1906
- <strong>${n}</strong>
1991
+ <strong>${i}</strong>
1907
1992
  <span>Project files updated.</span>
1908
1993
  </div>
1909
- `,document.body.appendChild(t),setTimeout(()=>{t.classList.add("out"),setTimeout(()=>t.remove(),500)},3e3)}refreshPanel(){if(!this.container)return;let e=this.container.querySelector(".config-persistence-panel");e?e.outerHTML=this.render():this.container.innerHTML=this.render(),this.setupEventListeners()}async loadVersionsList(){try{let e=await fetch("/api/versions");if(!e.ok)throw new Error("Failed to fetch versions");let t=await e.json();this.availableVersions=t.versions||[],this.currentVersion=t.current||null}catch(e){console.error("[ConfigPersistence] Failed to load versions:",e),this.availableVersions=[],this.currentVersion=null}}async switchVersion(e){var i,a,r;let t=Ie();if(t.hasChanges){if(!confirm(`Switch to version "${e||"original"}"?
1994
+ `,document.body.appendChild(t),setTimeout(()=>{t.classList.add("out"),setTimeout(()=>t.remove(),500)},3e3)}refreshPanel(){if(!this.container)return;let e=this.container.querySelector(".config-persistence-panel");e?e.outerHTML=this.render():this.container.innerHTML=this.render(),this.setupEventListeners()}async loadVersionsList(){try{let e=await fetch("/api/versions");if(!e.ok)throw new Error("Failed to fetch versions");let t=await e.json();this.availableVersions=t.versions||[],this.currentVersion=t.current||null}catch(e){console.error("[ConfigPersistence] Failed to load versions:",e),this.availableVersions=[],this.currentVersion=null}}async switchVersion(e){var n,a,r;let t=Me();if(t.hasChanges){if(!confirm(`Switch to version "${e||"original"}"?
1910
1995
 
1911
1996
  You have ${t.overrideCount} staged changes that will be discarded.
1912
1997
 
1913
1998
  Options:
1914
1999
  OK = Discard staged overrides and switch
1915
- Cancel = Stay on current version`)){let l=(i=this.container)==null?void 0:i.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}}else if(!confirm(`Switch to version "${e||"original"}"?`)){let l=(a=this.container)==null?void 0:a.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}try{let o=await fetch("/api/switch-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({versionName:e||null})});if(!o.ok){let l=await o.json();throw new Error(l.error||"Failed to switch version")}ne(),localStorage.removeItem("handler_config_overrides"),localStorage.setItem("handler_preview_override_mode","false"),window.location.reload()}catch(o){alert(`\u274C Failed to switch version: ${o.message}`);let l=(r=this.container)==null?void 0:r.querySelector("#version-selector");l&&(l.value=this.currentVersion||"")}}async directApply(){if(!this.isDevelopmentMode){alert("Direct Apply is only available in development mode.");return}if(confirm(`\u26A0\uFE0F WARNING: Direct Apply
2000
+ Cancel = Stay on current version`)){let l=(n=this.container)==null?void 0:n.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}}else if(!confirm(`Switch to version "${e||"original"}"?`)){let l=(a=this.container)==null?void 0:a.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}try{let o=await fetch("/api/switch-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({versionName:e||null})});if(!o.ok){let l=await o.json();throw new Error(l.error||"Failed to switch version")}ae(),localStorage.removeItem("handler_config_overrides"),localStorage.setItem("handler_preview_override_mode","false"),window.location.reload()}catch(o){alert(`\u274C Failed to switch version: ${o.message}`);let l=(r=this.container)==null?void 0:r.querySelector("#version-selector");l&&(l.value=this.currentVersion||"")}}async directApply(){if(!this.isDevelopmentMode){alert("Direct Apply is only available in development mode.");return}if(confirm(`\u26A0\uFE0F WARNING: Direct Apply
1916
2001
 
1917
2002
  This will DIRECTLY MODIFY your base configuration files WITHOUT creating a snapshot.
1918
2003
 
1919
2004
  This cannot be undone unless you have git commits or backups.
1920
2005
 
1921
- Are you absolutely sure?`))try{let t=Fe(),n={};for(let[a,r]of Object.entries(t.objects)){let o=r,l=a;/^(json\.|ui\.|effects\.|engine\.)/.test(l)||(l=`json.${a}`),o&&typeof o=="object"&&(o.identity||(o.identity={}),o.identity.id=l),n[`objects/${l}.json`]=o}t.engine&&(t.engine.runtime&&(n["engine/engine.runtime.json"]=t.engine.runtime),t.engine.assets&&(n["engine/engine.assets.json"]=t.engine.assets),t.engine.splash&&(n["engine/engine.splash.json"]=t.engine.splash),t.engine.loading&&(n["engine/engine.loading.json"]=t.engine.loading),t.engine.start&&(n["engine/engine.start.json"]=t.engine.start),t.engine.tutorial&&(n["engine/engine.tutorial.json"]=t.engine.tutorial),t.engine.endgame&&(n["engine/engine.endgame.json"]=t.engine.endgame),!t.engine.runtime&&!t.engine.assets&&(n["engine/engine.json"]=t.engine));for(let[a,r]of Object.entries(t.scenes)){let o=a.startsWith("scene.")?a:`scene.${a}`;n[`scenes/${o}.json`]=r}let i=await fetch("/api/apply-direct",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:n,assets:{}})});if(!i.ok){let a=await i.json();throw new Error(a.error||"Direct apply failed")}ne(),this.showSuccessNotification(),this.refreshPanel()}catch(t){console.error("[ConfigPersistence] Direct apply failed:",t),alert(`\u274C Direct apply failed: ${t.message}`)}}};var Ht=class{constructor(){this.debugOverlay=null;this.isDebugOpen=!1;this.selectedObjectId=null;this.configViewer=null;this.container=null;this.objectAutoApplyTimer=null;this.objectDebugRaf=null;this.objectBoundsGfx=null;this.objectAnchorGfx=null;this.highlightObject=!1;this.highlightAnchor=!1;this.activeTab="hierarchy";this.sceneObjectsPanel=new Tn;this.sceneToolsPanel=new Ln;this.nudgePanel=new kn;this.inspectorPanel=new Bn;this.libraryPanel=new Pt;this.libraryPanelDocked=new Pt;this.brandVisionPanel=new qn;this.customizeSettingsPanel=new Vn;this.configPersistencePanel=new ei;this.loadingScreenPanel=new Wn}applyAssetChange(e,t){return ar(this,e,t)}resetAsset(e){return sr(this,e)}applySlotAsset(e,t,n){return rr(this,e,t,n)}resetSlotAsset(e,t,n){return or(this,e,t,n)}startObjectVisuals(){return pr(this)}stopObjectVisuals(){return ur(this)}shouldRunObjectVisuals(){return Yn(this)}updateObjectVisuals(){return Kn(this)}getSelectedInstanceId(){return na(this)}getDisplayObjectById(e){return ia(this,e)}getSelectedObjectConfig(){return $t(this)}getConfigAnchorWorldPoint(e){return aa(this,e)}getScreenSize(){return sa(this)}ensureBoundsGfx(){return ra(this)}ensureAnchorGfx(){return oa(this)}drawBounds(e){return la(this,e)}drawAnchor(e){return ca(this,e)}clearBounds(){return da(this)}clearAnchor(){return pa(this)}clearObjectVisuals(){return Rt(this)}updateObjectInfo(e){return Ot(this,e)}resetDebugConfig(){return Jn(this)}applyDebugConfig(){return fr(this)}exportDebugConfig(){return Zn(this)}loadObjectConfig(e){return mr(this,e)}fillConfigViewer(e){return Xn(this,e)}copyConfigValues(){return br(this)}applyObjectConfig(e){return ga(this,e)}applyCustomizeSettings(e,t){return yr(this,e,t)}scheduleObjectAutoApply(){return vr(this)}setupDebugEventListeners(){return xr(this)}setupDebugInputListeners(e){return ba(this,e)}setupPanelLayout(){return Er(this)}setupCollapsiblePanels(e){return ya(this,e)}setupRangeInput(e,t,n,i){return se(this,e,t,n,i)}updateWorkbenchTabs(){return ma(this)}saveWorkbenchState(){return rt(this)}loadWorkbenchState(){return Qn(this)}initialize(e){var i;this.container=e,this.debugOverlay=e.querySelector(".debug-overlay"),this.configViewer=e.querySelector("#config-viewer");try{let a=localStorage.getItem("preview_workbench_state");if(a){let r=JSON.parse(a);r.activeTab&&(this.activeTab=r.activeTab)}}catch(a){console.warn("[PREVIEW] Failed to load workbench tab state",a)}this.sceneObjectsPanel.initialize(e,{onSelect:a=>this.handleObjectSelect(a)}),this.libraryPanel.initialize(e,{onApply:(a,r,o)=>this.applySlotAsset(a,r,o),onReset:(a,r,o)=>this.resetSlotAsset(a,r,o)});let t=e.querySelector("#dock-library-content");t&&(t.innerHTML=this.libraryPanelDocked.render(),this.libraryPanelDocked.initialize(t,{onApply:(a,r,o)=>this.applySlotAsset(a,r,o),onReset:(a,r,o)=>this.resetSlotAsset(a,r,o)})),this.inspectorPanel.initialize(e,{onPropertyChange:(a,r,o)=>{console.log("[Inspector] Property changed:",a,r,o)}}),this.brandVisionPanel.initialize(e,()=>{this.toggleDebug(!1);let a="/dashboard";window.location.pathname!==a&&(window.location.href=a)}),this.customizeSettingsPanel.initialize(e,{onApply:(a,r)=>this.applyCustomizeSettings(a,r)}),this.sceneToolsPanel.initialize(e,{onHighlightObject:a=>{this.highlightObject=a,a?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onHighlightAnchor:a=>{this.highlightAnchor=a,a?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onNudge:(a,r)=>this.nudgeSelectedObject(a,r),onShowSplash:()=>{let a=window;typeof a.__previewShowSplash=="function"&&a.__previewShowSplash()},onUpdateSplash:a=>{let r=window;typeof r.applyEditableEngineConfig=="function"&&r.applyEditableEngineConfig({splash:a})}}),this.nudgePanel.initialize(e,{onNudge:async(a,r)=>{var g,f,h,m,b,y;if(!this.selectedObjectId)return;let o=this.getSelectedObjectConfig();if(!o)return;let l=(g=o.transform)==null?void 0:g.position,c=((f=l==null?void 0:l.x)!=null?f:0)+a,d=((h=l==null?void 0:l.y)!=null?h:0)+r,{applyConfigOverride:p}=await Promise.resolve().then(()=>(J(),Be));p({objectId:this.selectedObjectId,path:"transform.position",value:{x:c,y:d}},{silent:!0,emitEvent:!0});let u=window.applyEditableObjectConfig;if(typeof u=="function"){let v=window.__editableConfig,w=(y=(b=(m=v==null?void 0:v.objects)==null?void 0:m.get)==null?void 0:b.call(m,this.selectedObjectId))!=null?y:o;await u(this.selectedObjectId,w)}window.dispatchEvent(new CustomEvent("inspector:refresh"))},onScale:async a=>{var p,u,g,f,h;if(!this.selectedObjectId)return;let r=this.getSelectedObjectConfig();if(!r)return;let o=(u=(p=r.transform)==null?void 0:p.scale)!=null?u:1,l=Math.max(.1,o+a),{applyConfigOverride:c}=await Promise.resolve().then(()=>(J(),Be));c({objectId:this.selectedObjectId,path:"transform.scale",value:l},{silent:!0,emitEvent:!0});let d=window.applyEditableObjectConfig;if(typeof d=="function"){let m=window.__editableConfig,b=(h=(f=(g=m==null?void 0:m.objects)==null?void 0:g.get)==null?void 0:f.call(g,this.selectedObjectId))!=null?h:r;await d(this.selectedObjectId,b)}window.dispatchEvent(new CustomEvent("inspector:refresh"))}});let n=e.querySelector("#debug-nudge-enabled");n==null||n.addEventListener("change",()=>{n.checked?this.nudgePanel.show():this.nudgePanel.hide()}),this.configPersistencePanel.initialize(e),this.loadingScreenPanel.initialize(e,{onShowLoadingScreen:()=>{let a=window;typeof a.__previewShowLoading=="function"?a.__previewShowLoading():console.warn("[DEBUG] __previewShowLoading not available")},onHideLoadingScreen:()=>{let a=window;typeof a.__previewHideLoading=="function"?a.__previewHideLoading():console.warn("[DEBUG] __previewHideLoading not available")},onUpdateLoading:a=>{let r=window;typeof r.applyEditableEngineConfig=="function"&&r.applyEditableEngineConfig({loading:a}),typeof r.__previewUpdateLoading=="function"?r.__previewUpdateLoading(a):console.warn("[DEBUG] __previewUpdateLoading not available")}}),window.__openAiEditor=(a,r,o,l)=>{this.customizeSettingsPanel.openAiEditor(a,r,o,l)},this.setupPanelLayout(),this.updateWorkbenchTabs(),window.__debugContext=this,window.__updateWorkbenchTabs=()=>this.updateWorkbenchTabs(),this.isDebugOpen=!0,(i=this.debugOverlay)==null||i.classList.remove("hidden"),this.updateDebugBadge(),this.sceneObjectsPanel.refreshObjects(),window.__previewSelectObject=a=>this.selectObject(a),window.addEventListener("config:changed",a=>{var r,o;((r=a.detail)==null?void 0:r.action)!=="remove"&&((o=a.detail)==null?void 0:o.action)!=="clear_object"&&this.highlightChangesTab()}),window.applyAssetToSlot=(a,r,o)=>this.applySlotAsset(a,r,o),window.refreshAssetLibrary=()=>this.libraryPanel.refresh(),window.reRenderAssetLibrary=()=>this.libraryPanel.reRender(),window.getEngineSplashConfig=()=>{var r;let a=window.getActiveConfig;if(typeof a=="function"){let o=a();return((r=o==null?void 0:o.engine)==null?void 0:r.splash)||null}return null},window.addAssetToRegistry=(a,r)=>{let o=window.getEditableAssets;if(typeof o=="function"){let l=o();if(l!=null&&l.libraryAssets&&(l.libraryAssets[a]||(l.libraryAssets[a]=[]),!l.libraryAssets[a].some(d=>d.filename===r))){let d=r.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");l.libraryAssets[a].unshift({filename:r,displayName:d}),console.log(`[DEBUG] Added ${r} to registry category ${a}`)}}},window.__highlightLibrarySlot=(a,r)=>{this.libraryPanel.highlightSlot(a,r)}}selectObject(e){this.handleObjectSelect(e),this.activeTab!=="inspector"&&this.activeTab!=="ai"&&this.setActiveTab("inspector")}setActiveTab(e){this.activeTab=e,this.updateWorkbenchTabs(),this.saveWorkbenchState()}highlightChangesTab(){var t;let e=(t=this.container)==null?void 0:t.querySelector('[data-tab="changes"]');e&&e.classList.add("has-pending-changes")}getDebugOverlayHTML(){return`
2006
+ Are you absolutely sure?`))try{let t=Ue(),i={};for(let[a,r]of Object.entries(t.objects)){let o=r,l=a;/^(json\.|ui\.|effects\.|engine\.)/.test(l)||(l=`json.${a}`),o&&typeof o=="object"&&(o.identity||(o.identity={}),o.identity.id=l),i[`objects/${l}.json`]=o}t.engine&&(t.engine.runtime&&(i["engine/engine.runtime.json"]=t.engine.runtime),t.engine.assets&&(i["engine/engine.assets.json"]=t.engine.assets),t.engine.splash&&(i["engine/engine.splash.json"]=t.engine.splash),t.engine.loading&&(i["engine/engine.loading.json"]=t.engine.loading),t.engine.start&&(i["engine/engine.start.json"]=t.engine.start),t.engine.tutorial&&(i["engine/engine.tutorial.json"]=t.engine.tutorial),t.engine.endgame&&(i["engine/engine.endgame.json"]=t.engine.endgame),!t.engine.runtime&&!t.engine.assets&&(i["engine/engine.json"]=t.engine));for(let[a,r]of Object.entries(t.scenes)){let o=a.startsWith("scene.")?a:`scene.${a}`;i[`scenes/${o}.json`]=r}let n=await fetch("/api/apply-direct",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:i,assets:{}})});if(!n.ok){let a=await n.json();throw new Error(a.error||"Direct apply failed")}ae(),this.showSuccessNotification(),this.refreshPanel()}catch(t){console.error("[ConfigPersistence] Direct apply failed:",t),alert(`\u274C Direct apply failed: ${t.message}`)}}};var Ut=class{constructor(){this.debugOverlay=null;this.isDebugOpen=!1;this.selectedObjectId=null;this.configViewer=null;this.container=null;this.objectAutoApplyTimer=null;this.objectDebugRaf=null;this.objectBoundsGfx=null;this.objectAnchorGfx=null;this.highlightObject=!1;this.highlightAnchor=!1;this.activeTab="hierarchy";this.sceneObjectsPanel=new ki;this.sceneToolsPanel=new Ii;this.nudgePanel=new Pi;this.inspectorPanel=new Gi;this.libraryPanel=new $t;this.libraryPanelDocked=new $t;this.brandVisionPanel=new Ki;this.customizeSettingsPanel=new Xi;this.configPersistencePanel=new rn;this.loadingScreenPanel=new Ji}applyAssetChange(e,t){return cr(this,e,t)}resetAsset(e){return dr(this,e)}applySlotAsset(e,t,i){return Wi(this,e,t,i)}resetSlotAsset(e,t,i){return pr(this,e,t,i)}startObjectVisuals(){return yr(this)}stopObjectVisuals(){return vr(this)}shouldRunObjectVisuals(){return Zi(this)}updateObjectVisuals(){return Qi(this)}getSelectedInstanceId(){return ca(this)}getDisplayObjectById(e){return da(this,e)}getSelectedObjectConfig(){return Bt(this)}getConfigAnchorWorldPoint(e){return pa(this,e)}getScreenSize(){return ua(this)}ensureBoundsGfx(){return ga(this)}ensureAnchorGfx(){return ha(this)}drawBounds(e){return fa(this,e)}drawAnchor(e){return ma(this,e)}clearBounds(){return ba(this)}clearAnchor(){return ya(this)}clearObjectVisuals(){return Nt(this)}updateObjectInfo(e){return Ht(this,e)}resetDebugConfig(){return tn(this)}applyDebugConfig(){return Sr(this)}exportDebugConfig(){return nn(this)}loadObjectConfig(e){return Er(this,e)}fillConfigViewer(e){return en(this,e)}copyConfigValues(){return Cr(this)}applyObjectConfig(e){return wa(this,e)}applyCustomizeSettings(e,t){return Ar(this,e,t)}scheduleObjectAutoApply(){return Tr(this)}setupDebugEventListeners(){return Lr(this)}setupDebugInputListeners(e){return Ca(this,e)}setupPanelLayout(){return kr(this)}setupCollapsiblePanels(e){return Aa(this,e)}setupRangeInput(e,t,i,n){return oe(this,e,t,i,n)}updateWorkbenchTabs(){return Ea(this)}saveWorkbenchState(){return dt(this)}loadWorkbenchState(){return sn(this)}initialize(e){var n;this.container=e,this.debugOverlay=e.querySelector(".debug-overlay"),this.configViewer=e.querySelector("#config-viewer");try{let a=localStorage.getItem("preview_workbench_state");if(a){let r=JSON.parse(a);r.activeTab&&(this.activeTab=r.activeTab)}}catch(a){console.warn("[PREVIEW] Failed to load workbench tab state",a)}this.sceneObjectsPanel.initialize(e,{onSelect:a=>this.handleObjectSelect(a)}),this.libraryPanel.initialize(e,{onApply:(a,r,o)=>this.applySlotAsset(a,r,o),onReset:(a,r,o)=>this.resetSlotAsset(a,r,o)});let t=e.querySelector("#dock-library-content");t&&(t.innerHTML=this.libraryPanelDocked.render(),this.libraryPanelDocked.initialize(t,{onApply:(a,r,o)=>this.applySlotAsset(a,r,o),onReset:(a,r,o)=>this.resetSlotAsset(a,r,o)})),this.inspectorPanel.initialize(e,{onPropertyChange:(a,r,o)=>{console.log("[Inspector] Property changed:",a,r,o)}}),this.brandVisionPanel.initialize(e,()=>{this.toggleDebug(!1);let a="/dashboard";window.location.pathname!==a&&(window.location.href=a)}),this.customizeSettingsPanel.initialize(e,{onApply:(a,r)=>this.applyCustomizeSettings(a,r)}),this.sceneToolsPanel.initialize(e,{onHighlightObject:a=>{this.highlightObject=a,a?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onHighlightAnchor:a=>{this.highlightAnchor=a,a?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onNudge:(a,r)=>this.nudgeSelectedObject(a,r),onShowSplash:()=>{let a=window;typeof a.__previewShowSplash=="function"&&a.__previewShowSplash()},onUpdateSplash:a=>{let r=window;typeof r.applyEditableEngineConfig=="function"&&r.applyEditableEngineConfig({splash:a})}}),this.nudgePanel.initialize(e,{onNudge:async(a,r)=>{var g,h,f,m,b,y;if(!this.selectedObjectId)return;let o=this.getSelectedObjectConfig();if(!o)return;let l=(g=o.transform)==null?void 0:g.position,c=((h=l==null?void 0:l.x)!=null?h:0)+a,d=((f=l==null?void 0:l.y)!=null?f:0)+r,{applyConfigOverride:p}=await Promise.resolve().then(()=>(K(),Ge));p({objectId:this.selectedObjectId,path:"transform.position",value:{x:c,y:d}},{silent:!0,emitEvent:!0});let u=window.applyEditableObjectConfig;if(typeof u=="function"){let v=window.__editableConfig,w=(y=(b=(m=v==null?void 0:v.objects)==null?void 0:m.get)==null?void 0:b.call(m,this.selectedObjectId))!=null?y:o;await u(this.selectedObjectId,w)}window.dispatchEvent(new CustomEvent("inspector:refresh"))},onScale:async a=>{var p,u,g,h,f;if(!this.selectedObjectId)return;let r=this.getSelectedObjectConfig();if(!r)return;let o=(u=(p=r.transform)==null?void 0:p.scale)!=null?u:1,l=Math.max(.1,o+a),{applyConfigOverride:c}=await Promise.resolve().then(()=>(K(),Ge));c({objectId:this.selectedObjectId,path:"transform.scale",value:l},{silent:!0,emitEvent:!0});let d=window.applyEditableObjectConfig;if(typeof d=="function"){let m=window.__editableConfig,b=(f=(h=(g=m==null?void 0:m.objects)==null?void 0:g.get)==null?void 0:h.call(g,this.selectedObjectId))!=null?f:r;await d(this.selectedObjectId,b)}window.dispatchEvent(new CustomEvent("inspector:refresh"))}});let i=e.querySelector("#debug-nudge-enabled");i==null||i.addEventListener("change",()=>{i.checked?this.nudgePanel.show():this.nudgePanel.hide()}),this.configPersistencePanel.initialize(e),this.loadingScreenPanel.initialize(e,{onShowLoadingScreen:()=>{let a=window;typeof a.__previewShowLoading=="function"?a.__previewShowLoading():console.warn("[DEBUG] __previewShowLoading not available")},onHideLoadingScreen:()=>{let a=window;typeof a.__previewHideLoading=="function"?a.__previewHideLoading():console.warn("[DEBUG] __previewHideLoading not available")},onUpdateLoading:a=>{let r=window;typeof r.applyEditableEngineConfig=="function"&&r.applyEditableEngineConfig({loading:a}),typeof r.__previewUpdateLoading=="function"?r.__previewUpdateLoading(a):console.warn("[DEBUG] __previewUpdateLoading not available")}}),window.__openAiEditor=(a,r,o,l)=>{this.customizeSettingsPanel.openAiEditor(a,r,o,l)},this.setupPanelLayout(),this.updateWorkbenchTabs(),window.__debugContext=this,window.__updateWorkbenchTabs=()=>this.updateWorkbenchTabs(),this.isDebugOpen=!0,(n=this.debugOverlay)==null||n.classList.remove("hidden"),this.updateDebugBadge(),this.sceneObjectsPanel.refreshObjects(),window.__previewSelectObject=a=>this.selectObject(a),window.addEventListener("config:changed",a=>{var r,o;((r=a.detail)==null?void 0:r.action)!=="remove"&&((o=a.detail)==null?void 0:o.action)!=="clear_object"&&this.highlightChangesTab()}),window.applyAssetToSlot=(a,r,o)=>this.applySlotAsset(a,r,o),window.refreshAssetLibrary=()=>this.libraryPanel.refresh(),window.reRenderAssetLibrary=()=>this.libraryPanel.reRender(),window.getEngineSplashConfig=()=>{var r;let a=window.getActiveConfig;if(typeof a=="function"){let o=a();return((r=o==null?void 0:o.engine)==null?void 0:r.splash)||null}return null},window.addAssetToRegistry=(a,r)=>{let o=window.getEditableAssets;if(typeof o=="function"){let l=o();if(l!=null&&l.libraryAssets&&(l.libraryAssets[a]||(l.libraryAssets[a]=[]),!l.libraryAssets[a].some(d=>d.filename===r))){let d=r.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");l.libraryAssets[a].unshift({filename:r,displayName:d}),console.log(`[DEBUG] Added ${r} to registry category ${a}`)}}},window.__highlightLibrarySlot=(a,r)=>{this.libraryPanel.highlightSlot(a,r)}}selectObject(e){this.handleObjectSelect(e),this.activeTab!=="inspector"&&this.activeTab!=="ai"&&this.setActiveTab("inspector")}setActiveTab(e){this.activeTab=e,this.updateWorkbenchTabs(),this.saveWorkbenchState()}highlightChangesTab(){var t;let e=(t=this.container)==null?void 0:t.querySelector('[data-tab="changes"]');e&&e.classList.add("has-pending-changes")}getDebugOverlayHTML(){return`
1922
2007
  <div class="debug-overlay hidden" id="debug-overlay">
1923
2008
  <div class="debug-workbench" id="debug-workbench">
1924
2009
  <div class="workbench-header" id="workbench-handle">
@@ -1965,7 +2050,7 @@ Are you absolutely sure?`))try{let t=Fe(),n={};for(let[a,r]of Object.entries(t.o
1965
2050
  ${this.sceneToolsPanel.render()}
1966
2051
  ${this.nudgePanel.render()}
1967
2052
  </div>
1968
- `}refresh(){this.isDebugOpen&&(this.sceneObjectsPanel.refreshObjects(),this.libraryPanel.refresh(),this.libraryPanelDocked.refresh(),this.brandVisionPanel.refresh(),this.selectedObjectId&&this.handleObjectSelect(this.selectedObjectId))}toggleDebug(e){var t;this.isDebugOpen=e!=null?e:!this.isDebugOpen,(t=this.debugOverlay)==null||t.classList.toggle("hidden",!this.isDebugOpen),this.updateDebugBadge(),this.isDebugOpen?this.refresh():this.stopObjectVisuals()}updateDebugBadge(){if(!this.container)return;let e=this.container.querySelector("#debug-badge");e&&e.classList.toggle("active",this.isDebugOpen)}handleObjectSelect(e){this.selectedObjectId=e,this.sceneObjectsPanel.setSelected(e),this.inspectorPanel.loadObject(e),this.loadObjectConfig(e),this.startObjectVisuals()}async nudgeSelectedObject(e,t){var o,l,c,d;let n=this.sceneObjectsPanel.getSelectedIds();if(n.length===0)return;let i=this.nudgePanel.getNudgeStep();if(n.length===1&&this.container){let p=this.container.querySelector("#config-pos-x"),u=this.container.querySelector("#config-pos-y");if(p&&u){let g=Number((o=p.value)!=null?o:0),f=Number((l=u.value)!=null?l:0),h=g+e*i,m=f+t*i;p.value=String(h),u.value=String(m),(c=this.configViewer)==null||c.style.setProperty("display","block"),this.scheduleObjectAutoApply();return}}let a=window.getEditableObjectConfig;if(typeof a!="function")return;let r=new Me;for(let p of n){let u=a(p);if(!u)continue;let g=((d=u.transform)==null?void 0:d.position)||[0,0],f=Array.isArray(g)?g[0]:g.x||0,h=Array.isArray(g)?g[1]:g.y||0,m=f+e*i,b=h+t*i;await r.updateProperty(p,"transform.position",[m,b])}n.length===1&&this.selectedObjectId===n[0]&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}};function ol(s){return new Promise((e,t)=>{let n=new FileReader;n.onerror=()=>t(new Error("FileReader failed")),n.onload=()=>e(String(n.result||"")),n.readAsDataURL(s)})}function ll(s){var i;let[e,t]=s.split(","),n=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(i=n==null?void 0:n[1])!=null?i:"image/png"}}function cl(s){return`
2053
+ `}refresh(){this.isDebugOpen&&(this.sceneObjectsPanel.refreshObjects(),this.libraryPanel.refresh(),this.libraryPanelDocked.refresh(),this.brandVisionPanel.refresh(),this.selectedObjectId&&this.handleObjectSelect(this.selectedObjectId))}toggleDebug(e){var t;this.isDebugOpen=e!=null?e:!this.isDebugOpen,(t=this.debugOverlay)==null||t.classList.toggle("hidden",!this.isDebugOpen),this.updateDebugBadge(),this.isDebugOpen?this.refresh():this.stopObjectVisuals()}updateDebugBadge(){if(!this.container)return;let e=this.container.querySelector("#debug-badge");e&&e.classList.toggle("active",this.isDebugOpen)}handleObjectSelect(e){this.selectedObjectId=e,this.sceneObjectsPanel.setSelected(e),this.inspectorPanel.loadObject(e),this.loadObjectConfig(e),this.startObjectVisuals(),window.dispatchEvent(new CustomEvent("preview:select",{detail:{objectId:e}}))}async nudgeSelectedObject(e,t){var o,l,c,d;let i=this.sceneObjectsPanel.getSelectedIds();if(i.length===0)return;let n=this.nudgePanel.getNudgeStep();if(i.length===1&&this.container){let p=this.container.querySelector("#config-pos-x"),u=this.container.querySelector("#config-pos-y");if(p&&u){let g=Number((o=p.value)!=null?o:0),h=Number((l=u.value)!=null?l:0),f=g+e*n,m=h+t*n;p.value=String(f),u.value=String(m),(c=this.configViewer)==null||c.style.setProperty("display","block"),this.scheduleObjectAutoApply();return}}let a=window.getEditableObjectConfig;if(typeof a!="function")return;let r=new _e;for(let p of i){let u=a(p);if(!u)continue;let g=((d=u.transform)==null?void 0:d.position)||[0,0],h=Array.isArray(g)?g[0]:g.x||0,f=Array.isArray(g)?g[1]:g.y||0,m=h+e*n,b=f+t*n;await r.updateProperty(p,"transform.position",[m,b])}i.length===1&&this.selectedObjectId===i[0]&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}};function hl(s){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(s)})}function fl(s){var n;let[e,t]=s.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(n=i==null?void 0:i[1])!=null?n:"image/png"}}function ml(s){return`
1969
2054
  Analyze these screenshots of a brand or game and extract its "Brand DNA".
1970
2055
 
1971
2056
  Provide a concise summary (2-3 sentences) covering:
@@ -1982,9 +2067,9 @@ Palette: [#RRGGBB, #RRGGBB, ...]
1982
2067
  ${s?`
1983
2068
  ADDITIONAL RULES/NOTES:
1984
2069
  ${s}`:""}
1985
- `.trim()}function Sr(){let s=[],e="",t=null;return{async addSources(n){let i=[];for(let a of n){let r=await ol(a),o=ll(r),l={id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,name:a.name,base64:o.base64,mimeType:o.mimeType,dataUrl:r};s.push(l),i.push(l)}return i},getSources(){return s.slice()},async analyze(n,i,a){if(s.length===0)throw new Error("No screenshots to analyze.");let r=cl(i),o=s.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Gn(n,r,o,{model:a}),c=e,d=[],p=l.split(`
1986
- `);for(let u of p)if(u.toLowerCase().startsWith("summary:"))c=u.slice(8).trim();else if(u.toLowerCase().includes("palette:")){let g=u.match(/#[0-9A-Fa-f]{6}/g);g&&g.forEach(f=>{d.includes(f.toUpperCase())||d.push(f.toUpperCase())})}return(!c||c===e)&&(c=l.split(`
1987
- Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0,10)},t},setSummary(n){e=n,t&&(t={...t,summary:n})},getResult(){return t}}}var Ve="handler_api_key_";var ot=class{static setKey(e,t,n){try{let i={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:n||e},a=`${Ve}${e}`;localStorage.setItem(a,JSON.stringify(i))}catch(i){console.error("[ApiKeyStorage] Failed to store API key:",i)}}static getKey(e){try{let t=`${Ve}${e}`,n=localStorage.getItem(t);if(!n)return null;let i=JSON.parse(n);return i.lastUsed=Date.now(),localStorage.setItem(t,JSON.stringify(i)),this.decryptKey(i.key)}catch(t){return console.error("[ApiKeyStorage] Failed to retrieve API key:",t),null}}static hasKey(e){let t=`${Ve}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${Ve}${e}`;localStorage.removeItem(t)}catch(t){console.error("[ApiKeyStorage] Failed to remove API key:",t)}}static getStoredServices(){let e=[];try{for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);if(n&&n.startsWith(Ve)){let i=n.substring(Ve.length),a=localStorage.getItem(n);if(a){let r=JSON.parse(a);e.push({service:i,label:r.label,created:r.created,lastUsed:r.lastUsed})}}}}catch(t){console.error("[ApiKeyStorage] Failed to get stored services:",t)}return e.sort((t,n)=>n.lastUsed-t.lastUsed)}static clearAll(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n&&n.startsWith(Ve)&&e.push(n)}e.forEach(t=>localStorage.removeItem(t))}catch(e){console.error("[ApiKeyStorage] Failed to clear API keys:",e)}}static encryptKey(e){try{let n="handler_preview_salt_2024"+e;return btoa(n)}catch(t){return console.warn("[ApiKeyStorage] Encryption failed, storing as-is:",t),e}}static decryptKey(e){try{let t=atob(e),n="handler_preview_salt_2024";return t.startsWith(n)?t.substring(n.length):t}catch(t){return console.warn("[ApiKeyStorage] Decryption failed, returning as-is:",t),e}}},va=()=>ot.getKey("gemini"),wa=(s,e)=>ot.setKey("gemini",s,e),dl=()=>ot.hasKey("gemini");window.ApiKeyStorage=ot;window.getGeminiApiKey=va;window.setGeminiApiKey=wa;window.hasGeminiApiKey=dl;var Ea=class{constructor(){this.modal=null;this.options=null;this.analyzer=Sr();this.currentPrompt="";this.isGenerating=!1;this.generatedImages=[];this.selectedImageIndex=-1;this.promptInput=null;this.generateBtn=null;this.loadingEl=null;this.galleryEl=null;this.previewEl=null}open(e){this.options=e,this.currentPrompt=e.initialPrompt||"",this.generatedImages=[],this.selectedImageIndex=-1,this.isGenerating=!1,this.createModal(),document.body.appendChild(this.modal),setTimeout(()=>{var t,n;(t=this.promptInput)==null||t.focus(),(n=this.promptInput)==null||n.select()},100)}createModal(){var t;let e=document.createElement("div");e.className="ai-modal",e.innerHTML=`
2070
+ `.trim()}function Ir(){let s=[],e="",t=null;return{async addSources(i){let n=[];for(let a of i){let r=await hl(a),o=fl(r),l={id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,name:a.name,base64:o.base64,mimeType:o.mimeType,dataUrl:r};s.push(l),n.push(l)}return n},getSources(){return s.slice()},async analyze(i,n,a){if(s.length===0)throw new Error("No screenshots to analyze.");let r=ml(n),o=s.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Vi(i,r,o,{model:a}),c=e,d=[],p=l.split(`
2071
+ `);for(let u of p)if(u.toLowerCase().startsWith("summary:"))c=u.slice(8).trim();else if(u.toLowerCase().includes("palette:")){let g=u.match(/#[0-9A-Fa-f]{6}/g);g&&g.forEach(h=>{d.includes(h.toUpperCase())||d.push(h.toUpperCase())})}return(!c||c===e)&&(c=l.split(`
2072
+ Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0,10)},t},setSummary(i){e=i,t&&(t={...t,summary:i})},getResult(){return t}}}var Ke="handler_api_key_";var pt=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${Ke}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${Ke}${e}`,i=localStorage.getItem(t);if(!i)return null;let n=JSON.parse(i);return n.lastUsed=Date.now(),localStorage.setItem(t,JSON.stringify(n)),this.decryptKey(n.key)}catch(t){return console.error("[ApiKeyStorage] Failed to retrieve API key:",t),null}}static hasKey(e){let t=`${Ke}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${Ke}${e}`;localStorage.removeItem(t)}catch(t){console.error("[ApiKeyStorage] Failed to remove API key:",t)}}static getStoredServices(){let e=[];try{for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i&&i.startsWith(Ke)){let n=i.substring(Ke.length),a=localStorage.getItem(i);if(a){let r=JSON.parse(a);e.push({service:n,label:r.label,created:r.created,lastUsed:r.lastUsed})}}}}catch(t){console.error("[ApiKeyStorage] Failed to get stored services:",t)}return e.sort((t,i)=>i.lastUsed-t.lastUsed)}static clearAll(){try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i&&i.startsWith(Ke)&&e.push(i)}e.forEach(t=>localStorage.removeItem(t))}catch(e){console.error("[ApiKeyStorage] Failed to clear API keys:",e)}}static encryptKey(e){try{let i="handler_preview_salt_2024"+e;return btoa(i)}catch(t){return console.warn("[ApiKeyStorage] Encryption failed, storing as-is:",t),e}}static decryptKey(e){try{let t=atob(e),i="handler_preview_salt_2024";return t.startsWith(i)?t.substring(i.length):t}catch(t){return console.warn("[ApiKeyStorage] Decryption failed, returning as-is:",t),e}}},Ta=()=>pt.getKey("gemini"),La=(s,e)=>pt.setKey("gemini",s,e),bl=()=>pt.hasKey("gemini");window.ApiKeyStorage=pt;window.getGeminiApiKey=Ta;window.setGeminiApiKey=La;window.hasGeminiApiKey=bl;var Ia=class{constructor(){this.modal=null;this.options=null;this.analyzer=Ir();this.currentPrompt="";this.isGenerating=!1;this.generatedImages=[];this.selectedImageIndex=-1;this.promptInput=null;this.generateBtn=null;this.loadingEl=null;this.galleryEl=null;this.previewEl=null}open(e){this.options=e,this.currentPrompt=e.initialPrompt||"",this.generatedImages=[],this.selectedImageIndex=-1,this.isGenerating=!1,this.createModal(),document.body.appendChild(this.modal),setTimeout(()=>{var t,i;(t=this.promptInput)==null||t.focus(),(i=this.promptInput)==null||i.select()},100)}createModal(){var t;let e=document.createElement("div");e.className="ai-modal",e.innerHTML=`
1988
2073
  <div class="ai-modal-card">
1989
2074
  <div class="ai-modal-header">
1990
2075
  <div class="ai-modal-actions">
@@ -2063,17 +2148,17 @@ Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0
2063
2148
  <button class="ai-btn primary" data-action="apply" disabled>Apply</button>
2064
2149
  </div>
2065
2150
  </div>
2066
- `,this.modal=e,this.attachEventListeners(),this.updatePromptFromDna()}attachEventListeners(){var n;if(!this.modal)return;this.promptInput=this.modal.querySelector(".ai-textarea"),this.generateBtn=this.modal.querySelector('[data-action="generate"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),(n=this.promptInput)==null||n.addEventListener("input",()=>{var i;this.currentPrompt=((i=this.promptInput)==null?void 0:i.value)||"",this.updateGenerateButton()});let e=this.modal.querySelector('[data-strength="creativity"]'),t=this.modal.querySelector(".ai-strength-value");e==null||e.addEventListener("input",()=>{t.textContent=e.value}),this.modal.addEventListener("click",i=>{var o;let a=i.target;switch(a.dataset.action||((o=a.closest("[data-action]"))==null?void 0:o.getAttribute("data-action"))){case"generate":this.generateImage();break;case"apply":this.applySelectedImage();break;case"gallery":this.toggleGallery();break;case"close":case"cancel":this.close();break}}),this.modal.addEventListener("click",i=>{let a=i.target;if(a.classList.contains("ai-gallery-item")||a.closest(".ai-gallery-item")){let r=a.closest(".ai-gallery-item"),o=parseInt(r.dataset.index||"-1");o>=0&&this.selectImage(o)}}),this.modal.addEventListener("click",i=>{i.target===this.modal&&this.close()}),this.updateGenerateButton()}updateGenerateButton(){if(!this.generateBtn)return;let e=this.currentPrompt.trim().length>0;this.generateBtn.disabled=!e||this.isGenerating}async updatePromptFromDna(){var t;let e=(t=this.modal)==null?void 0:t.querySelector("#ai-use-dna");if(e!=null&&e.checked)try{let n=this.analyzer.getResult();if(n!=null&&n.summary&&this.promptInput){let i=`${this.currentPrompt}
2151
+ `,this.modal=e,this.attachEventListeners(),this.updatePromptFromDna()}attachEventListeners(){var i;if(!this.modal)return;this.promptInput=this.modal.querySelector(".ai-textarea"),this.generateBtn=this.modal.querySelector('[data-action="generate"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),(i=this.promptInput)==null||i.addEventListener("input",()=>{var n;this.currentPrompt=((n=this.promptInput)==null?void 0:n.value)||"",this.updateGenerateButton()});let e=this.modal.querySelector('[data-strength="creativity"]'),t=this.modal.querySelector(".ai-strength-value");e==null||e.addEventListener("input",()=>{t.textContent=e.value}),this.modal.addEventListener("click",n=>{var o;let a=n.target;switch(a.dataset.action||((o=a.closest("[data-action]"))==null?void 0:o.getAttribute("data-action"))){case"generate":this.generateImage();break;case"apply":this.applySelectedImage();break;case"gallery":this.toggleGallery();break;case"close":case"cancel":this.close();break}}),this.modal.addEventListener("click",n=>{let a=n.target;if(a.classList.contains("ai-gallery-item")||a.closest(".ai-gallery-item")){let r=a.closest(".ai-gallery-item"),o=parseInt(r.dataset.index||"-1");o>=0&&this.selectImage(o)}}),this.modal.addEventListener("click",n=>{n.target===this.modal&&this.close()}),this.updateGenerateButton()}updateGenerateButton(){if(!this.generateBtn)return;let e=this.currentPrompt.trim().length>0;this.generateBtn.disabled=!e||this.isGenerating}async updatePromptFromDna(){var t;let e=(t=this.modal)==null?void 0:t.querySelector("#ai-use-dna");if(e!=null&&e.checked)try{let i=this.analyzer.getResult();if(i!=null&&i.summary&&this.promptInput){let n=`${this.currentPrompt}
2067
2152
 
2068
- Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}catch(n){console.warn("[AiEditorModal] Failed to apply brand DNA:",n)}}async generateImage(){var e,t,n,i;if(!(!this.options||this.isGenerating)){this.isGenerating=!0,this.updateGenerateButton(),(e=this.loadingEl)==null||e.classList.remove("hidden"),(t=this.previewEl)==null||t.classList.add("hidden");try{let a=this.getApiKey();if(!a){alert("Please set your Gemini API key first. You can do this in the AI Creative Suite panel.");return}let r=[];if(this.options.currentValue&&this.options.currentValue.startsWith("data:"))try{let c=await Un(this.options.currentValue);c&&(r=[{base64:c.base64,mimeType:c.mimeType}])}catch(c){console.warn("[AiEditorModal] Failed to load current image:",c)}let o=await st(a,this.currentPrompt,r,{aspectRatio:"1:1"}),l=await at(o);this.generatedImages.push(l||o),this.selectedImageIndex=this.generatedImages.length-1,this.updateGallery(),this.updatePreview(),this.updateApplyButton()}catch(a){console.error("[AiEditorModal] Generation failed:",a),alert(`Generation failed: ${a instanceof Error?a.message:"Unknown error"}`)}finally{this.isGenerating=!1,(n=this.loadingEl)==null||n.classList.add("hidden"),(i=this.previewEl)==null||i.classList.remove("hidden"),this.updateGenerateButton()}}}updateGallery(){if(!this.galleryEl)return;let e=this.galleryEl.querySelector("[data-gallery-grid]");e&&(e.innerHTML=this.generatedImages.map((t,n)=>`
2069
- <div class="ai-gallery-item ${n===this.selectedImageIndex?"active":""}" data-index="${n}">
2070
- <img class="ai-gallery-thumb" src="${t}" alt="Generated ${n+1}" />
2071
- <div class="ai-gallery-label">#${n+1}</div>
2153
+ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}catch(i){console.warn("[AiEditorModal] Failed to apply brand DNA:",i)}}async generateImage(){var e,t,i,n;if(!(!this.options||this.isGenerating)){this.isGenerating=!0,this.updateGenerateButton(),(e=this.loadingEl)==null||e.classList.remove("hidden"),(t=this.previewEl)==null||t.classList.add("hidden");try{let a=this.getApiKey();if(!a){alert("Please set your Gemini API key first. You can do this in the AI Creative Suite panel.");return}let r=[];if(this.options.currentValue&&this.options.currentValue.startsWith("data:"))try{let c=await qi(this.options.currentValue);c&&(r=[{base64:c.base64,mimeType:c.mimeType}])}catch(c){console.warn("[AiEditorModal] Failed to load current image:",c)}let o=await ct(a,this.currentPrompt,r,{aspectRatio:"1:1"}),l=await lt(o);this.generatedImages.push(l||o),this.selectedImageIndex=this.generatedImages.length-1,this.updateGallery(),this.updatePreview(),this.updateApplyButton()}catch(a){console.error("[AiEditorModal] Generation failed:",a),alert(`Generation failed: ${a instanceof Error?a.message:"Unknown error"}`)}finally{this.isGenerating=!1,(i=this.loadingEl)==null||i.classList.add("hidden"),(n=this.previewEl)==null||n.classList.remove("hidden"),this.updateGenerateButton()}}}updateGallery(){if(!this.galleryEl)return;let e=this.galleryEl.querySelector("[data-gallery-grid]");e&&(e.innerHTML=this.generatedImages.map((t,i)=>`
2154
+ <div class="ai-gallery-item ${i===this.selectedImageIndex?"active":""}" data-index="${i}">
2155
+ <img class="ai-gallery-thumb" src="${t}" alt="Generated ${i+1}" />
2156
+ <div class="ai-gallery-label">#${i+1}</div>
2072
2157
  </div>
2073
- `).join(""))}updatePreview(){if(!this.previewEl||this.selectedImageIndex<0)return;let e=this.generatedImages[this.selectedImageIndex];this.previewEl.innerHTML=`<img src="${e}" alt="Selected image" />`}selectImage(e){e<0||e>=this.generatedImages.length||(this.selectedImageIndex=e,this.updateGallery(),this.updatePreview(),this.updateApplyButton())}toggleGallery(){this.galleryEl&&this.galleryEl.classList.toggle("hidden")}updateApplyButton(){var t;let e=(t=this.modal)==null?void 0:t.querySelector('[data-action="apply"]');e&&(e.disabled=this.selectedImageIndex<0)}applySelectedImage(){var t;if(this.selectedImageIndex<0||!((t=this.options)!=null&&t.onApply))return;let e=this.generatedImages[this.selectedImageIndex];this.options.onApply(e),this.close()}getApiKey(){let e=va();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return wa(t.apiKey,"From Brand DNA"),t.apiKey}catch(t){console.warn("[AiEditorModal] Failed to get API key from brand DNA:",t)}return null}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}},xa=null;window.__openAiEditor=function(s,e,t,n){xa||(xa=new Ea),xa.open({objectId:s,initialPrompt:e,currentValue:t,path:n==null?void 0:n.path,onApply:i=>{if(n!=null&&n.path){let a=window.updateManager;if(a)a.updateProperty(s,n.path,i);else{let r=window.getEditableObjectConfig,o=r==null?void 0:r(s);if(o){let l=n.path.split("."),c=o;for(let d=0;d<l.length-1;d++)c[l[d]]||(c[l[d]]={}),c=c[l[d]];c[l[l.length-1]]=i}}}window.dispatchEvent(new CustomEvent("inspector:refresh"))}})};Ca();var Aa=class{constructor(){this.modal=null;this.options=null}open(e){this.options=e,this.createModal(),document.body.appendChild(this.modal)}createModal(){if(!this.options)return;let{assetPath:e,assetType:t,objectId:n}=this.options,i=n||"Asset Preview",a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
2158
+ `).join(""))}updatePreview(){if(!this.previewEl||this.selectedImageIndex<0)return;let e=this.generatedImages[this.selectedImageIndex];this.previewEl.innerHTML=`<img src="${e}" alt="Selected image" />`}selectImage(e){e<0||e>=this.generatedImages.length||(this.selectedImageIndex=e,this.updateGallery(),this.updatePreview(),this.updateApplyButton())}toggleGallery(){this.galleryEl&&this.galleryEl.classList.toggle("hidden")}updateApplyButton(){var t;let e=(t=this.modal)==null?void 0:t.querySelector('[data-action="apply"]');e&&(e.disabled=this.selectedImageIndex<0)}applySelectedImage(){var t;if(this.selectedImageIndex<0||!((t=this.options)!=null&&t.onApply))return;let e=this.generatedImages[this.selectedImageIndex];this.options.onApply(e),this.close()}getApiKey(){let e=Ta();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return La(t.apiKey,"From Brand DNA"),t.apiKey}catch(t){console.warn("[AiEditorModal] Failed to get API key from brand DNA:",t)}return null}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}},ka=null;window.__openAiEditor=function(s,e,t,i){ka||(ka=new Ia),ka.open({objectId:s,initialPrompt:e,currentValue:t,path:i==null?void 0:i.path,onApply:n=>{if(i!=null&&i.path){let a=window.updateManager;if(a)a.updateProperty(s,i.path,n);else{let r=window.getEditableObjectConfig,o=r==null?void 0:r(s);if(o){let l=i.path.split("."),c=o;for(let d=0;d<l.length-1;d++)c[l[d]]||(c[l[d]]={}),c=c[l[d]];c[l[l.length-1]]=n}}}window.dispatchEvent(new CustomEvent("inspector:refresh"))}})};Ma();var ja=class{constructor(){this.modal=null;this.options=null}open(e){this.options=e,this.createModal(),document.body.appendChild(this.modal)}createModal(){if(!this.options)return;let{assetPath:e,assetType:t,objectId:i}=this.options,n=i||"Asset Preview",a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
2074
2159
  <div class="asset-preview-card">
2075
2160
  <div class="asset-preview-header">
2076
- <div class="asset-preview-title">${i}</div>
2161
+ <div class="asset-preview-title">${n}</div>
2077
2162
  <button class="asset-preview-close" data-action="close">\xD7</button>
2078
2163
  </div>
2079
2164
 
@@ -2091,13 +2176,13 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2091
2176
  ${t==="image"?'<button class="asset-preview-ai" data-action="edit">\u2728 AI Edit</button>':""}
2092
2177
  </div>
2093
2178
  </div>
2094
- `,this.modal=a,this.attachEventListeners()}renderAssetContent(e,t){if(!e)return'<div class="asset-preview-placeholder">No asset selected</div>';switch(t){case"image":return`<img src="${this.resolveAssetUrl(e)}" alt="Asset preview" style="max-width: 100%; max-height: 400px; object-fit: contain;" />`;case"audio":let i=this.resolveAssetUrl(e);return`
2179
+ `,this.modal=a,this.attachEventListeners()}renderAssetContent(e,t){if(!e)return'<div class="asset-preview-placeholder">No asset selected</div>';switch(t){case"image":return`<img src="${this.resolveAssetUrl(e)}" alt="Asset preview" style="max-width: 100%; max-height: 400px; object-fit: contain;" />`;case"audio":let n=this.resolveAssetUrl(e);return`
2095
2180
  <audio controls style="width: 100%;">
2096
- <source src="${i}" type="audio/mpeg">
2097
- <source src="${i}" type="audio/wav">
2181
+ <source src="${n}" type="audio/mpeg">
2182
+ <source src="${n}" type="audio/wav">
2098
2183
  Your browser does not support the audio element.
2099
2184
  </audio>
2100
- `;case"text":return`<pre style="background: rgba(0,0,0,0.2); padding: 16px; border-radius: 8px; max-height: 300px; overflow-y: auto; white-space: pre-wrap;">${e}</pre>`;default:return`<div class="asset-preview-placeholder">Cannot preview ${t} assets</div>`}}resolveAssetUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("/")?e:`/raw/${e}`}attachEventListeners(){if(!this.modal)return;this.modal.addEventListener("click",n=>{let i=n.target;(i.dataset.action==="close"||i===this.modal)&&this.close()});let e=this.modal.querySelector('[data-action="change"]');e&&e.addEventListener("click",()=>{this.openAssetEditor()});let t=this.modal.querySelector('[data-action="edit"]');t&&t.addEventListener("click",()=>{this.openAiEditor(),this.close()})}openAssetEditor(){this.options&&Promise.resolve().then(()=>(Ca(),Cr)).then(({AssetEditorModal:e})=>{new e().show(this.options.objectId||"unknown",this.options.propertyPath||"",this.options.assetPath,n=>{var i;(i=this.options)!=null&&i.onChange&&this.options.onChange(n),this.close()})})}openAiEditor(){if(!this.options||this.options.assetType!=="image")return;let e=window.__openAiEditor;typeof e=="function"&&e(this.options.objectId||"asset","Edit this image asset",this.options.assetPath,{path:this.options.propertyPath,onApply:t=>{var n;(n=this.options)!=null&&n.onChange&&this.options.onChange(t)}})}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}};window.openAssetPreview=function(s){new Aa().open(s)};var Ta=class{constructor(){this.modal=null;this.canvas=null;this.ctx=null;this.image=null;this.options=null;this.cropX=0;this.cropY=0;this.cropWidth=100;this.cropHeight=100;this.scale=1;this.panX=0;this.panY=0;this.isDragging=!1;this.dragStartX=0;this.dragStartY=0;this.lastPanX=0;this.lastPanY=0}open(e){this.options=e,this.createModal(),this.loadImage(),document.body.appendChild(this.modal)}createModal(){let e=document.createElement("div");e.className="asset-crop-modal",e.innerHTML=`
2185
+ `;case"text":return`<pre style="background: rgba(0,0,0,0.2); padding: 16px; border-radius: 8px; max-height: 300px; overflow-y: auto; white-space: pre-wrap;">${e}</pre>`;default:return`<div class="asset-preview-placeholder">Cannot preview ${t} assets</div>`}}resolveAssetUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("/")?e:`/raw/${e}`}attachEventListeners(){if(!this.modal)return;this.modal.addEventListener("click",i=>{let n=i.target;(n.dataset.action==="close"||n===this.modal)&&this.close()});let e=this.modal.querySelector('[data-action="change"]');e&&e.addEventListener("click",()=>{this.openAssetEditor()});let t=this.modal.querySelector('[data-action="edit"]');t&&t.addEventListener("click",()=>{this.openAiEditor(),this.close()})}openAssetEditor(){this.options&&Promise.resolve().then(()=>(Ma(),Pr)).then(({AssetEditorModal:e})=>{new e().show(this.options.objectId||"unknown",this.options.propertyPath||"",this.options.assetPath,i=>{var n;(n=this.options)!=null&&n.onChange&&this.options.onChange(i),this.close()})})}openAiEditor(){if(!this.options||this.options.assetType!=="image")return;let e=window.__openAiEditor;typeof e=="function"&&e(this.options.objectId||"asset","Edit this image asset",this.options.assetPath,{path:this.options.propertyPath,onApply:t=>{var i;(i=this.options)!=null&&i.onChange&&this.options.onChange(t)}})}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}};window.openAssetPreview=function(s){new ja().open(s)};var _a=class{constructor(){this.modal=null;this.canvas=null;this.ctx=null;this.image=null;this.options=null;this.cropX=0;this.cropY=0;this.cropWidth=100;this.cropHeight=100;this.scale=1;this.panX=0;this.panY=0;this.isDragging=!1;this.dragStartX=0;this.dragStartY=0;this.lastPanX=0;this.lastPanY=0}open(e){this.options=e,this.createModal(),this.loadImage(),document.body.appendChild(this.modal)}createModal(){let e=document.createElement("div");e.className="asset-crop-modal",e.innerHTML=`
2101
2186
  <div class="asset-crop-card">
2102
2187
  <div class="asset-crop-header">
2103
2188
  <div>
@@ -2148,7 +2233,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2148
2233
  <button class="asset-crop-apply primary" data-action="apply">Apply Crop</button>
2149
2234
  </div>
2150
2235
  </div>
2151
- `,this.modal=e,this.attachEventListeners(),this.initializeCanvas()}initializeCanvas(){this.modal&&(this.canvas=this.modal.querySelector(".asset-crop-canvas"),this.canvas&&(this.ctx=this.canvas.getContext("2d"),this.canvas.width=400,this.canvas.height=300))}loadImage(){this.options&&(this.image=new Image,this.image.crossOrigin="anonymous",this.image.onload=()=>{this.initializeCrop(),this.render()},this.image.src=this.options.imageSrc)}initializeCrop(){var n;if(!this.image||!this.canvas)return;let e=this.image.width/this.image.height,t=this.canvas.width/this.canvas.height;e>t?(this.cropHeight=this.image.height,this.cropWidth=this.cropHeight*t,this.cropX=(this.image.width-this.cropWidth)/2,this.cropY=0):(this.cropWidth=this.image.width,this.cropHeight=this.cropWidth/t,this.cropX=0,this.cropY=(this.image.height-this.cropHeight)/2),(n=this.options)!=null&&n.aspectRatio&&this.applyAspectRatio(this.options.aspectRatio),this.fitToCanvas()}applyAspectRatio(e){if(!this.image)return;let t=this.image.width/this.image.height,n=this.cropX+this.cropWidth/2,i=this.cropY+this.cropHeight/2;e>t?(this.cropWidth=Math.min(this.image.width,this.cropHeight*e),this.cropHeight=this.cropWidth/e):(this.cropHeight=Math.min(this.image.height,this.cropWidth/e),this.cropWidth=this.cropHeight*e),this.cropX=Math.max(0,Math.min(this.image.width-this.cropWidth,n-this.cropWidth/2)),this.cropY=Math.max(0,Math.min(this.image.height-this.cropHeight,i-this.cropHeight/2))}fitToCanvas(){if(!this.image||!this.canvas)return;let e=this.canvas.width/this.cropWidth,t=this.canvas.height/this.cropHeight;this.scale=Math.min(e,t)*.9,this.panX=(this.canvas.width-this.cropWidth*this.scale)/2,this.panY=(this.canvas.height-this.cropHeight*this.scale)/2}render(){!this.ctx||!this.image||!this.canvas||(this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(this.panX,this.panY),this.ctx.scale(this.scale,this.scale),this.ctx.drawImage(this.image,-this.cropX,-this.cropY,this.image.width,this.image.height),this.ctx.restore(),this.drawCropOverlay(),this.updatePreview())}drawCropOverlay(){if(!this.ctx||!this.canvas)return;let e=this.panX,t=this.panY,n=this.cropWidth*this.scale,i=this.cropHeight*this.scale;this.ctx.fillStyle="rgba(0, 0, 0, 0.5)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.clearRect(e,t,n,i),this.ctx.strokeStyle="#ffffff",this.ctx.lineWidth=2,this.ctx.strokeRect(e,t,n,i),this.ctx.fillStyle="#ffffff";let a=8;[[e,t],[e+n-a,t],[e,t+i-a],[e+n-a,t+i-a]].forEach(([o,l])=>{var c;(c=this.ctx)==null||c.fillRect(o,l,a,a)})}updatePreview(){if(!this.modal||!this.image)return;let e=this.modal.querySelector(".asset-crop-preview-canvas");if(!e)return;let t=e.getContext("2d");if(!t)return;let n=150;e.width=n,e.height=n;let i=n/this.cropWidth,a=n/this.cropHeight,r=Math.min(i,a),o=this.cropWidth*r,l=this.cropHeight*r,c=(n-o)/2,d=(n-l)/2;t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,d,o,l)}attachEventListeners(){if(!this.modal||!this.canvas)return;this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("wheel",this.handleWheel.bind(this)),this.canvas.addEventListener("touchstart",this.handleTouchStart.bind(this)),this.canvas.addEventListener("touchmove",this.handleTouchMove.bind(this)),this.canvas.addEventListener("touchend",this.handleTouchEnd.bind(this));let e=this.modal.querySelector(".asset-crop-zoom-slider");e==null||e.addEventListener("input",n=>{let i=parseFloat(n.target.value);this.setZoom(i)});let t=this.modal.querySelector(".asset-crop-aspect-select");t==null||t.addEventListener("change",n=>{let i=n.target.value;this.setAspectRatio(i)}),this.modal.addEventListener("click",n=>{switch(n.target.dataset.action){case"reset":this.reset();break;case"apply":this.applyCrop();break;case"cancel":case"close":this.close();break}}),this.modal.addEventListener("click",n=>{n.target===this.modal&&this.close()})}handleMouseDown(e){this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY,this.lastPanX=this.panX,this.lastPanY=this.panY,this.canvas.style.cursor="grabbing"}handleMouseMove(e){if(!this.isDragging)return;let t=e.clientX-this.dragStartX,n=e.clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+n,this.constrainPan(),this.render()}handleMouseUp(){this.isDragging=!1,this.canvas.style.cursor="grab"}handleWheel(e){e.preventDefault();let t=e.deltaY>0?.9:1.1;this.setZoom(this.scale*t)}handleTouchStart(e){e.touches.length===1&&(this.isDragging=!0,this.dragStartX=e.touches[0].clientX,this.dragStartY=e.touches[0].clientY,this.lastPanX=this.panX,this.lastPanY=this.panY)}handleTouchMove(e){if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0].clientX-this.dragStartX,n=e.touches[0].clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+n,this.constrainPan(),this.render()}handleTouchEnd(){this.isDragging=!1}setZoom(e){this.scale=Math.max(.1,Math.min(3,e)),this.updateZoomUI(),this.constrainPan(),this.render()}setAspectRatio(e){let t;switch(e){case"1:1":t=1;break;case"4:3":t=4/3;break;case"16:9":t=16/9;break;case"3:2":t=3/2;break;default:t=void 0}t&&this.applyAspectRatio(t),this.fitToCanvas(),this.render()}updateZoomUI(){if(!this.modal)return;let e=this.modal.querySelector(".asset-crop-zoom-value"),t=this.modal.querySelector(".asset-crop-zoom-slider");e&&(e.textContent=`${this.scale.toFixed(1)}x`),t&&(t.value=this.scale.toString())}constrainPan(){if(!this.canvas)return;let e=this.cropWidth*this.scale,t=this.cropHeight*this.scale;this.panX=Math.max(this.canvas.width-e,Math.min(0,this.panX)),this.panY=Math.max(this.canvas.height-t,Math.min(0,this.panY))}reset(){this.initializeCrop(),this.render()}applyCrop(){var i;if(!this.image||!((i=this.options)!=null&&i.onCrop))return;let e=document.createElement("canvas"),t=e.getContext("2d");if(!t)return;e.width=this.cropWidth,e.height=this.cropHeight,t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,0,0,this.cropWidth,this.cropHeight);let n=e.toDataURL("image/png");this.options.onCrop(n),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal);let e=this.options;this.modal=null,this.canvas=null,this.ctx=null,this.image=null,this.options=null,e!=null&&e.onCancel&&e.onCancel()}};window.openAssetCrop=function(s){new Ta().open(s)};J();var ti=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[qe("playable-portrait"),qe("iphone-14"),qe("ipad-mini")];this.activeCompareId="playable-portrait";this.compareViewports=new Map;this.resizeObserver=null;this.rafFitHandle=null;this.ignoreNextWindowResize=!1;this.frameDragOffsetX=0;this.frameDragOffsetY=0;this.frameDragActive=!1;this.frameDragStartX=0;this.frameDragStartY=0;this.frameDragOriginX=0;this.frameDragOriginY=0;this.isSpaceKeyPressed=!1;this.consolePanel=null;this.consoleMessages=[];this.isConsoleOpen=!1;this.originalConsole={log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console)};this.hasInitialFit=!1;this.isMounted=!1;this.isInitialized=!1;this.gameReady=!1;this.resizeListenersDisabled=!1;this.compareSnapshotTimer=null;this.hasUnsavedChanges=!1;this.onWindowResize=e=>{if(this.ignoreNextWindowResize){this.ignoreNextWindowResize=!1;return}this.resizeListenersDisabled||!this.gameReady||this.scheduleFit()};this.onFrameDragMove=e=>{if(!this.frameDragActive)return;let t=e.clientX-this.frameDragStartX,n=e.clientY-this.frameDragStartY;this.frameDragOffsetX=this.frameDragOriginX+t,this.frameDragOffsetY=this.frameDragOriginY+n,this.applyFrameDrag(),this.updateDragCursor()};this.onFrameDragEnd=()=>{this.frameDragActive&&(this.frameDragActive=!1,window.removeEventListener("pointermove",this.onFrameDragMove),window.removeEventListener("pointerup",this.onFrameDragEnd),this.updateDragCursor())};this.options=e,this.currentPreset=qe(e.defaultDevice||xn.id),this.debugPanel=new Ht,this.container=this.createShell(),this.previewContainer=this.mustQuery(".preview-container"),this.singleStage=this.mustQuery('[data-preview-stage="single"]'),this.compareStage=this.mustQuery('[data-preview-stage="compare"]'),this.frameDragger=this.mustQuery(".frame-dragger"),this.frameWrapper=this.mustQuery(".frame-wrapper"),this.deviceFrame=this.mustQuery(".device-frame"),this.gameContainer=this.mustQuery(".game-container"),this.lastSinglePresetId=this.currentPreset.id,this.consolePanel=this.container.querySelector(".console-panel"),this.debugPanel.initialize(this.container),this.debugPanel.setupDebugEventListeners(),this.applyDeviceFrameStyles(),this.setupCompareViewports(),this.setupConsoleInterceptor(),this.setupObserversAndListeners(),this.setupFrameDragging(),this.setupSpaceKeyListener(),this.setupShortcutListeners(),this.setupUnsavedChangesIndicator(),this.setDevice(this.currentPreset.id,{suppressCallback:!0}),this.updateDockState(),this.isInitialized=!0}getShortcutKey(){return typeof navigator!="undefined"&&navigator.platform.toUpperCase().indexOf("MAC")>=0?"CMD":"CTRL"}mount(e=document.body){e.innerHTML="",e.appendChild(this.container),this.isMounted=!0,this.scheduleFit()}destroy(){if(this.disableResizeListeners(),this.resizeObserver){try{this.resizeObserver.disconnect()}catch{}this.resizeObserver=null}window.removeEventListener("resize",this.onWindowResize),this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null),this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null),this.gameReady=!1}getGameContainer(){return this.gameContainer}getScreen(){let e=this.getEffectivePreset();return{width:e.width,height:e.height}}getEffectivePreset(){var e;return this.isLandscape?{...this.currentPreset,width:this.currentPreset.height,height:this.currentPreset.width,ratio:((e=this.currentPreset.ratio)==null?void 0:e.split(":").reverse().join(":"))||this.currentPreset.ratio}:this.currentPreset}notifyGameLoaded(){this.gameReady=!0,this.enableResizeListeners(),this.scheduleFit(),this.debugPanel.refresh(),requestAnimationFrame(()=>this.updatePanelPositions())}notifyGameDestroyed(){this.gameReady=!1,this.disableResizeListeners()}disableResizeListeners(){this.resizeListenersDisabled=!0,this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null)}enableResizeListeners(){this.resizeListenersDisabled=!1}refresh(){this.options.onRefresh?this.options.onRefresh():window.location.reload()}setDevice(e,t={}){var i,a;let n=this.autoScale*this.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=qe(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepVisibleScale:n}),t.suppressCallback||(a=(i=this.options).onDeviceChange)==null||a.call(i,this.getEffectivePreset()),this.emitScreenChange()}setTheme(e){e==="dark"?this.container.classList.add("theme-dark"):this.container.classList.remove("theme-dark"),requestAnimationFrame(()=>this.updatePanelPositions())}setLayoutMode(e){if(this.layoutMode===e)return;this.layoutMode=e,this.container.classList.toggle("layout-fixed",e==="fixed"),this.container.classList.toggle("layout-draggable",e==="draggable"),Array.from(this.container.querySelectorAll("[data-layout-toggle]")).forEach(i=>i.classList.toggle("active",i.dataset.layoutToggle===e)),Array.from(this.container.querySelectorAll(".debug-workbench, .scene-panel")).forEach(i=>{i.style.left="",i.style.top="",i.style.width="",i.style.height="",i.style.zIndex=""}),this.scheduleFit(),this.updateDockState(),this.updatePanelPositions(),window.dispatchEvent(new CustomEvent("inspector:refresh"))}updateDockState(){let e=this.container.querySelector("#bottom-dock");e==null||e.classList.remove("hidden");let t=this.container.querySelector("#console-messages"),n=this.container.querySelector("#dock-console-content");t&&n&&t.parentElement!==n&&n.appendChild(t)}makeBottomDockResizable(e,t){let n,i,a=o=>{let l=o.clientY-n,c=Math.max(100,Math.min(800,i-l));e.style.height=`${c}px`;let d=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:d})},r=()=>{document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",r),e.classList.remove("resizing")};t.addEventListener("pointerdown",o=>{o.preventDefault(),n=o.clientY,i=e.offsetHeight,document.addEventListener("pointermove",a),document.addEventListener("pointerup",r),e.classList.add("resizing")})}makeSidebarResizable(e,t,n){let i,a,r=l=>{let c=n==="left"?l.clientX-i:i-l.clientX,d=Math.max(200,Math.min(600,a+c));e.style.width=`${d}px`;let p=this.container.querySelector(".preview-main");if(p){let g=n==="left"?`${d}px`:p.style.gridTemplateColumns.split(" ")[0]||"300px",f=n==="right"?`${d}px`:p.style.gridTemplateColumns.split(" ")[2]||"350px";p.style.gridTemplateColumns=`${g} 1fr ${f}`}let u=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:u})},o=()=>{document.removeEventListener("pointermove",r),document.removeEventListener("pointerup",o),e.classList.remove("resizing")};t.addEventListener("pointerdown",l=>{l.preventDefault(),i=l.clientX,a=e.offsetWidth,document.addEventListener("pointermove",r),document.addEventListener("pointerup",o),e.classList.add("resizing")})}createShell(){var t;let e=document.createElement("div");return e.className="preview-shell layout-fixed",e.innerHTML=`
2236
+ `,this.modal=e,this.attachEventListeners(),this.initializeCanvas()}initializeCanvas(){this.modal&&(this.canvas=this.modal.querySelector(".asset-crop-canvas"),this.canvas&&(this.ctx=this.canvas.getContext("2d"),this.canvas.width=400,this.canvas.height=300))}loadImage(){this.options&&(this.image=new Image,this.image.crossOrigin="anonymous",this.image.onload=()=>{this.initializeCrop(),this.render()},this.image.src=this.options.imageSrc)}initializeCrop(){var i;if(!this.image||!this.canvas)return;let e=this.image.width/this.image.height,t=this.canvas.width/this.canvas.height;e>t?(this.cropHeight=this.image.height,this.cropWidth=this.cropHeight*t,this.cropX=(this.image.width-this.cropWidth)/2,this.cropY=0):(this.cropWidth=this.image.width,this.cropHeight=this.cropWidth/t,this.cropX=0,this.cropY=(this.image.height-this.cropHeight)/2),(i=this.options)!=null&&i.aspectRatio&&this.applyAspectRatio(this.options.aspectRatio),this.fitToCanvas()}applyAspectRatio(e){if(!this.image)return;let t=this.image.width/this.image.height,i=this.cropX+this.cropWidth/2,n=this.cropY+this.cropHeight/2;e>t?(this.cropWidth=Math.min(this.image.width,this.cropHeight*e),this.cropHeight=this.cropWidth/e):(this.cropHeight=Math.min(this.image.height,this.cropWidth/e),this.cropWidth=this.cropHeight*e),this.cropX=Math.max(0,Math.min(this.image.width-this.cropWidth,i-this.cropWidth/2)),this.cropY=Math.max(0,Math.min(this.image.height-this.cropHeight,n-this.cropHeight/2))}fitToCanvas(){if(!this.image||!this.canvas)return;let e=this.canvas.width/this.cropWidth,t=this.canvas.height/this.cropHeight;this.scale=Math.min(e,t)*.9,this.panX=(this.canvas.width-this.cropWidth*this.scale)/2,this.panY=(this.canvas.height-this.cropHeight*this.scale)/2}render(){!this.ctx||!this.image||!this.canvas||(this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(this.panX,this.panY),this.ctx.scale(this.scale,this.scale),this.ctx.drawImage(this.image,-this.cropX,-this.cropY,this.image.width,this.image.height),this.ctx.restore(),this.drawCropOverlay(),this.updatePreview())}drawCropOverlay(){if(!this.ctx||!this.canvas)return;let e=this.panX,t=this.panY,i=this.cropWidth*this.scale,n=this.cropHeight*this.scale;this.ctx.fillStyle="rgba(0, 0, 0, 0.5)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.clearRect(e,t,i,n),this.ctx.strokeStyle="#ffffff",this.ctx.lineWidth=2,this.ctx.strokeRect(e,t,i,n),this.ctx.fillStyle="#ffffff";let a=8;[[e,t],[e+i-a,t],[e,t+n-a],[e+i-a,t+n-a]].forEach(([o,l])=>{var c;(c=this.ctx)==null||c.fillRect(o,l,a,a)})}updatePreview(){if(!this.modal||!this.image)return;let e=this.modal.querySelector(".asset-crop-preview-canvas");if(!e)return;let t=e.getContext("2d");if(!t)return;let i=150;e.width=i,e.height=i;let n=i/this.cropWidth,a=i/this.cropHeight,r=Math.min(n,a),o=this.cropWidth*r,l=this.cropHeight*r,c=(i-o)/2,d=(i-l)/2;t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,d,o,l)}attachEventListeners(){if(!this.modal||!this.canvas)return;this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("wheel",this.handleWheel.bind(this)),this.canvas.addEventListener("touchstart",this.handleTouchStart.bind(this)),this.canvas.addEventListener("touchmove",this.handleTouchMove.bind(this)),this.canvas.addEventListener("touchend",this.handleTouchEnd.bind(this));let e=this.modal.querySelector(".asset-crop-zoom-slider");e==null||e.addEventListener("input",i=>{let n=parseFloat(i.target.value);this.setZoom(n)});let t=this.modal.querySelector(".asset-crop-aspect-select");t==null||t.addEventListener("change",i=>{let n=i.target.value;this.setAspectRatio(n)}),this.modal.addEventListener("click",i=>{switch(i.target.dataset.action){case"reset":this.reset();break;case"apply":this.applyCrop();break;case"cancel":case"close":this.close();break}}),this.modal.addEventListener("click",i=>{i.target===this.modal&&this.close()})}handleMouseDown(e){this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY,this.lastPanX=this.panX,this.lastPanY=this.panY,this.canvas.style.cursor="grabbing"}handleMouseMove(e){if(!this.isDragging)return;let t=e.clientX-this.dragStartX,i=e.clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleMouseUp(){this.isDragging=!1,this.canvas.style.cursor="grab"}handleWheel(e){e.preventDefault();let t=e.deltaY>0?.9:1.1;this.setZoom(this.scale*t)}handleTouchStart(e){e.touches.length===1&&(this.isDragging=!0,this.dragStartX=e.touches[0].clientX,this.dragStartY=e.touches[0].clientY,this.lastPanX=this.panX,this.lastPanY=this.panY)}handleTouchMove(e){if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0].clientX-this.dragStartX,i=e.touches[0].clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleTouchEnd(){this.isDragging=!1}setZoom(e){this.scale=Math.max(.1,Math.min(3,e)),this.updateZoomUI(),this.constrainPan(),this.render()}setAspectRatio(e){let t;switch(e){case"1:1":t=1;break;case"4:3":t=4/3;break;case"16:9":t=16/9;break;case"3:2":t=3/2;break;default:t=void 0}t&&this.applyAspectRatio(t),this.fitToCanvas(),this.render()}updateZoomUI(){if(!this.modal)return;let e=this.modal.querySelector(".asset-crop-zoom-value"),t=this.modal.querySelector(".asset-crop-zoom-slider");e&&(e.textContent=`${this.scale.toFixed(1)}x`),t&&(t.value=this.scale.toString())}constrainPan(){if(!this.canvas)return;let e=this.cropWidth*this.scale,t=this.cropHeight*this.scale;this.panX=Math.max(this.canvas.width-e,Math.min(0,this.panX)),this.panY=Math.max(this.canvas.height-t,Math.min(0,this.panY))}reset(){this.initializeCrop(),this.render()}applyCrop(){var n;if(!this.image||!((n=this.options)!=null&&n.onCrop))return;let e=document.createElement("canvas"),t=e.getContext("2d");if(!t)return;e.width=this.cropWidth,e.height=this.cropHeight,t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,0,0,this.cropWidth,this.cropHeight);let i=e.toDataURL("image/png");this.options.onCrop(i),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal);let e=this.options;this.modal=null,this.canvas=null,this.ctx=null,this.image=null,this.options=null,e!=null&&e.onCancel&&e.onCancel()}};window.openAssetCrop=function(s){new _a().open(s)};K();var H=require("pixi.js");K();var on=class{constructor(e){this.app=null;this.camera=new H.Container;this.mainContainer=new H.Container;this.gizmoLayer=new H.Container;this.screenFrame=new H.Graphics;this.objectMap=new Map;this.selectedId=null;this.dragMode=null;this.dragStartPointer=null;this.dragStartPos=null;this.dragStartScale=1;this.dragStartRotationDeg=0;this.dragStartAngle=0;this.dragStartDistance=1;this.dragAnchorLocal=null;this.dragStartValue=null;this.cameraScale=1;this.isPanning=!1;this.panStart=null;this.panStartCamera=null;this.hasUserCamera=!1;this.resizeObserver=null;this.gizmoOutline=new H.Graphics;this.moveHandle=new H.Graphics;this.scaleHandle=new H.Graphics;this.rotateHandle=new H.Graphics;this.isVisible=!0;this.applyQueued=!1;this.applyQueuedId=null;this.handleScreenChange=e=>{if(!(e!=null&&e.detail))return;let{width:t,height:i}=e.detail;!t||!i||(this.updateLayout({width:t,height:i}),this.updateGizmos(),this.syncFromConfig())};this.handleConfigChanged=e=>{if(!this.isVisible)return;this.updateLayout();let t=e==null?void 0:e.detail;if(!t){this.syncFromConfig();return}let i=t.objectId,n=t.objectIds;if(i){this.syncFromConfig([i]);return}if(Array.isArray(n)&&n.length>0){this.syncFromConfig(n);return}this.syncFromConfig()};this.handleSceneRefresh=()=>{this.isVisible&&this.syncFromConfig()};this.handlePreviewSelect=e=>{var i,n;let t=(n=(i=e==null?void 0:e.detail)==null?void 0:i.objectId)!=null?n:null;this.setSelected(t,{silent:!0})};this.onDragMove=e=>{if(!this.dragMode||!this.selectedId||!this.app)return;let t=this.objectMap.get(this.selectedId);if(!t)return;let i=this.getPointerInCamera(e.clientX,e.clientY);if(!(!i||!this.dragStartPointer||!this.dragStartPos)){if(this.dragMode==="move"){let n=i.x-this.dragStartPointer.x,a=i.y-this.dragStartPointer.y,r=this.dragStartPos.x+n,o=this.dragStartPos.y+a;t.displayObject.position.set(r,o),this.updateLiveConfigPosition(r,o)}else if(this.dragMode==="scale"){let n=new H.Point(this.dragStartPos.x,this.dragStartPos.y),a=Math.max(1,this.distance(i,n)),r=Math.max(.05,this.dragStartScale*(a/this.dragStartDistance));t.displayObject.scale.set(r),this.updateLiveConfigScale(r)}else if(this.dragMode==="rotate"){let n=new H.Point(this.dragStartPos.x,this.dragStartPos.y),r=Math.atan2(i.y-n.y,i.x-n.x)-this.dragStartAngle,o=this.dragStartRotationDeg+r*180/Math.PI;t.displayObject.rotation=o*Math.PI/180,this.updateLiveConfigRotation(o)}this.updateGizmos(),this.queueLiveApply(this.selectedId)}};this.onDragEnd=()=>{var i,n,a,r,o,l,c;if(!this.dragMode||!this.selectedId)return;let e=this.selectedId,t=this.getEditableObjectConfig(e);if(t){let d=(i=t.transform)!=null?i:{};if(t.transform||(t.transform=d),this.dragMode==="move"&&this.dragStartValue){let p=d.position,u=Array.isArray(p)?[Number((n=p[0])!=null?n:0),Number((a=p[1])!=null?a:0)]:{x:Number((r=p==null?void 0:p.x)!=null?r:0),y:Number((o=p==null?void 0:p.y)!=null?o:0)};this.applyFinalOverride(e,"transform.position",u,this.dragStartValue)}else this.dragMode==="scale"?this.applyFinalOverride(e,"transform.scale",(l=d.scale)!=null?l:1,this.dragStartValue):this.dragMode==="rotate"&&this.applyFinalOverride(e,"transform.rotation",(c=d.rotation)!=null?c:0,this.dragStartValue);this.queueLiveApply(e)}window.dispatchEvent(new CustomEvent("inspector:refresh")),this.dragMode=null,this.dragStartPointer=null,this.dragStartPos=null,this.dragAnchorLocal=null,this.dragStartValue=null,window.removeEventListener("pointermove",this.onDragMove),window.removeEventListener("pointerup",this.onDragEnd)};this.onWheel=e=>{if(!this.app||!this.isVisible)return;e.preventDefault();let i=Math.sign(e.deltaY)<0?1.1:.9,n=Math.min(6,Math.max(.1,this.cameraScale*i));this.cameraScale=n,this.camera.scale.set(n),this.hasUserCamera=!0,this.updateGizmos()};this.onPanStart=e=>{e.button===2&&(this.isPanning=!0,this.panStart={x:e.clientX,y:e.clientY},this.panStartCamera={x:this.camera.position.x,y:this.camera.position.y},this.hasUserCamera=!0)};this.onPanMove=e=>{if(!this.isPanning||!this.panStart||!this.panStartCamera)return;let t=e.clientX-this.panStart.x,i=e.clientY-this.panStart.y;this.camera.position.set(this.panStartCamera.x+t,this.panStartCamera.y+i)};this.onPanEnd=()=>{this.isPanning=!1,this.panStart=null,this.panStartCamera=null};this.root=e.root,this.getScreen=e.getScreen}async mount(){this.app||(this.app=new H.Application,await this.app.init({resizeTo:this.root,autoDensity:!0,resolution:window.devicePixelRatio||1,antialias:!0,backgroundAlpha:0}),this.root.innerHTML="",this.root.appendChild(this.app.canvas),this.root.style.position="relative",this.root.style.overflow="hidden",this.app.stage.sortableChildren=!0,this.app.stage.eventMode="static",this.camera.sortableChildren=!0,this.mainContainer.sortableChildren=!0,this.gizmoLayer.sortableChildren=!0,this.app.stage.addChild(this.camera),this.camera.addChild(this.screenFrame),this.camera.addChild(this.mainContainer),this.camera.addChild(this.gizmoLayer),this.screenFrame.zIndex=-1,this.gizmoLayer.zIndex=1e5,this.gizmoLayer.addChild(this.gizmoOutline),this.gizmoLayer.addChild(this.moveHandle),this.gizmoLayer.addChild(this.scaleHandle),this.gizmoLayer.addChild(this.rotateHandle),this.setupInteractions(),this.setupObservers(),this.updateLayout(),this.refresh(),this.isVisible||this.app.ticker.stop())}destroy(){this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),window.removeEventListener("handler-preview:screen",this.handleScreenChange),window.removeEventListener("config:changed",this.handleConfigChanged),window.removeEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.removeEventListener("preview:select",this.handlePreviewSelect),this.app&&(this.app.destroy(!0),this.app=null)}setVisible(e){this.isVisible=e,this.app&&(e?(this.app.ticker.start(),this.refresh()):this.app.ticker.stop())}refresh(){this.syncFromConfig()}setupObservers(){window.addEventListener("handler-preview:screen",this.handleScreenChange),window.addEventListener("config:changed",this.handleConfigChanged),window.addEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.addEventListener("preview:select",this.handlePreviewSelect),this.resizeObserver=new ResizeObserver(()=>{this.handleResize()}),this.resizeObserver.observe(this.root)}setupInteractions(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("contextmenu",t=>t.preventDefault()),e.addEventListener("wheel",this.onWheel,{passive:!1}),e.addEventListener("pointerdown",this.onPanStart),window.addEventListener("pointermove",this.onPanMove),window.addEventListener("pointerup",this.onPanEnd),this.moveHandle.eventMode="static",this.moveHandle.cursor="move",this.scaleHandle.eventMode="static",this.scaleHandle.cursor="nwse-resize",this.rotateHandle.eventMode="static",this.rotateHandle.cursor="crosshair",this.moveHandle.on("pointerdown",t=>this.startDrag("move",t)),this.scaleHandle.on("pointerdown",t=>this.startDrag("scale",t)),this.rotateHandle.on("pointerdown",t=>this.startDrag("rotate",t))}handleResize(){this.app&&(this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.updateGizmos())}getEditableConfig(){return window.__editableConfig||null}getEditableObjectConfig(e){var n,a;let t=window.getEditableObjectConfig;if(typeof t=="function")return t(e);let i=this.getEditableConfig();return i!=null&&i.objects?typeof i.objects.get=="function"?(n=i.objects.get(e))!=null?n:null:(a=i.objects[e])!=null?a:null:null}getEditableObjectIds(){let e=window.getEditableObjectList;if(typeof e=="function"){let i=e();if(Array.isArray(i))return i}let t=this.getEditableConfig();return t!=null&&t.objects?typeof t.objects.keys=="function"?Array.from(t.objects.keys()):Object.keys(t.objects):[]}async syncFromConfig(e){if(!this.app)return;let t=this.getEditableConfig();if(!(t!=null&&t.objects))return;let i=e!=null&&e.length?e:this.getEditableObjectIds(),n=new Set(i);if(!e)for(let a of Array.from(this.objectMap.keys()))n.has(a)||this.removeObject(a);for(let a of i){let r=this.getEditableObjectConfig(a);if(!r){this.removeObject(a);continue}await this.upsertObject(a,r)}this.updateGizmos()}removeObject(e){var i,n;let t=this.objectMap.get(e);if(t){try{(n=(i=t.displayObject)==null?void 0:i.destroy)==null||n.call(i)}catch{}this.objectMap.delete(e),this.selectedId===e&&this.setSelected(null,{silent:!0})}}async upsertObject(e,t){let i=this.getAssetKey(t),n=this.objectMap.get(e);if(!n||n.assetKey!==i){n&&this.removeObject(e);let r=await this.createDisplayObject(e,t);if(!r)return;this.mainContainer.addChild(r),this.objectMap.set(e,{id:e,displayObject:r,assetKey:i}),this.attachObjectInteraction(r,e)}let a=this.objectMap.get(e);a&&(this.applyVisualConfig(a.displayObject,t),this.updateObjectTransform(a.displayObject,t))}async createDisplayObject(e,t){var i,n,a,r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,E,P;if((i=t==null?void 0:t.render)!=null&&i.asset)try{if(((a=(n=t==null?void 0:t.render)==null?void 0:n.asset)==null?void 0:a.type)!=="json"){let x=await de.create(e,t,this.app);if(x instanceof H.Container)return x}}catch(M){console.warn("[SceneEditor] ObjectFactory failed for",e,M)}if((r=t==null?void 0:t.ui)!=null&&r.text||((o=t==null?void 0:t.ui)==null?void 0:o.kind)==="text"){let M=(p=(d=(l=t==null?void 0:t.ui)==null?void 0:l.color)!=null?d:(c=t==null?void 0:t.render)==null?void 0:c.tint)!=null?p:"#ffffff",x=new H.TextStyle({fontFamily:"Arial, sans-serif",fontSize:(g=(u=t==null?void 0:t.ui)==null?void 0:u.fontSize)!=null?g:16,fill:M,align:(f=(h=t==null?void 0:t.ui)==null?void 0:h.align)!=null?f:"center",letterSpacing:(b=(m=t==null?void 0:t.ui)==null?void 0:m.letterSpacing)!=null?b:0});return new H.Text({text:(v=(y=t==null?void 0:t.ui)==null?void 0:y.text)!=null?v:"",style:x})}if((w=t==null?void 0:t.effects)!=null&&w.width||(E=t==null?void 0:t.effects)!=null&&E.height){let M=new H.Graphics,x=typeof t.effects.width=="number"?t.effects.width:100,_=typeof t.effects.height=="number"?t.effects.height:100,O=(P=t.effects.fill_color)!=null?P:"#ffffff",T=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,A=Number.parseInt(String(O).replace("#",""),16);return M.rect(0,0,x,_).fill({color:Number.isFinite(A)?A:16777215,alpha:T}),M}return new H.Container}attachObjectInteraction(e,t){if(e){if(e.eventMode="static",e.cursor="pointer",!e.hitArea&&typeof e.getLocalBounds=="function"){let i=e.getLocalBounds();i&&i.width>0&&i.height>0&&(e.hitArea=i)}e.on("pointerdown",i=>{var a,r,o;((o=(r=(a=i==null?void 0:i.data)==null?void 0:a.originalEvent)==null?void 0:r.button)!=null?o:0)===0&&(this.setSelected(t),this.startDrag("move",i))})}}getAssetKey(e){var i;let t=(i=e==null?void 0:e.render)==null?void 0:i.asset;return t?`${t.type||"asset"}::${t.path||""}`:null}applyVisualConfig(e,t){var r,o,l,c,d,p,u;if(!e)return;let i=(r=t==null?void 0:t.render)!=null?r:{};typeof i.alpha=="number"&&(e.alpha=i.alpha),e.visible=i.visible!==!1,e.zIndex=typeof i.z_index=="number"?i.z_index:0;let n=(d=(c=(o=t==null?void 0:t.render)==null?void 0:o.anchor)!=null?c:(l=t==null?void 0:t.transform)==null?void 0:l.anchor)!=null?d:"center",a=rt(n,{x:.5,y:.5});if((p=e.anchor)!=null&&p.set)e.anchor.set(a.x,a.y);else if(e.pivot){let g=(u=e.getLocalBounds)==null?void 0:u.call(e);g&&e.pivot.set(g.width*a.x,g.height*a.y)}}updateObjectTransform(e,t){var l;if(!e)return;let i=(l=t==null?void 0:t.transform)!=null?l:{},n=this.getAnchorLocalPoint(i),a=this.getPositionOffset(i);n&&e.position.set(n.x+a.x,n.y+a.y);let r=typeof i.scale=="number"?i.scale:void 0;typeof r=="number"&&e.scale&&e.scale.set(r);let o=typeof i.rotation=="number"?i.rotation:0;typeof e.rotation=="number"&&(e.rotation=o*Math.PI/180)}getAnchorLocalPoint(e){var a;let t=this.getScreen();if(!(t!=null&&t.width)||!(t!=null&&t.height))return null;let i=(e==null?void 0:e.position_ratio)!=null?It(t.width,t.height,e.position_ratio):kt(t.width,t.height,(a=e==null?void 0:e.anchor)!=null?a:"center"),n=new H.Point;return this.mainContainer.toLocal(new H.Point(i.x,i.y),void 0,n),n}getPositionOffset(e){var l,c,d,p,u,g,h,f;let t=e==null?void 0:e.position,i=e==null?void 0:e.offset,n=Array.isArray(t)?Number((l=t[0])!=null?l:0):Number((c=t==null?void 0:t.x)!=null?c:0),a=Array.isArray(t)?Number((d=t[1])!=null?d:0):Number((p=t==null?void 0:t.y)!=null?p:0),r=Array.isArray(i)?Number((u=i[0])!=null?u:0):Number((g=i==null?void 0:i.x)!=null?g:0),o=Array.isArray(i)?Number((h=i[1])!=null?h:0):Number((f=i==null?void 0:i.y)!=null?f:0);return{x:n+r,y:a+o}}updateLayout(e){var f,m,b,y,v,w,E,P;let t=e!=null?e:this.getScreen();if(!(t!=null&&t.width)||!(t!=null&&t.height))return;let n=(((m=(f=this.getEditableConfig())==null?void 0:f.engine)==null?void 0:m.runtime)||{}).layout||{},a=t.width*((b=ue.layout.screen_scale_x)!=null?b:1),r=n.design_width_portrait||400,o=a/r;o=Math.min(o,1.15);let l=o*((y=ue.engine.scale)!=null?y:1);this.mainContainer.scale.set(l);let c=(v=n.main_container_anchor)!=null?v:"center",d=(w=n.main_container_position_ratio)!=null?w:{x:.5,y:.5},p=(E=n.main_container_offset)!=null?E:{x:0,y:0},u=n.main_container_position_ratio?It(t.width,t.height,d):kt(t.width,t.height,c),g=u.x+p.x+ue.layout.position_offset.x,h=u.y+p.y+ue.layout.position_offset.y;this.mainContainer.position.set(g,h),this.screenFrame.clear(),this.screenFrame.rect(0,0,t.width,t.height),this.screenFrame.stroke({width:2,color:2894892,alpha:.5}),(P=this.app)!=null&&P.stage&&(this.app.stage.hitArea=new H.Rectangle(0,0,t.width,t.height)),this.hasUserCamera||this.centerCamera()}centerCamera(){if(!this.app)return;let e=this.getScreen(),t=this.app.renderer.width,i=this.app.renderer.height;this.cameraScale=1,this.camera.scale.set(this.cameraScale),this.camera.position.set((t-e.width)/2,(i-e.height)/2)}updateGizmos(){var d,p;if(!this.selectedId||!this.isVisible){this.clearGizmos();return}let e=this.objectMap.get(this.selectedId);if(!(e!=null&&e.displayObject)){this.clearGizmos();return}let t=(p=(d=e.displayObject).getBounds)==null?void 0:p.call(d);if(!t||t.width<=0||t.height<=0){this.clearGizmos();return}let i=this.camera.toLocal(new H.Point(t.x,t.y)),n=this.camera.toLocal(new H.Point(t.x+t.width,t.y+t.height)),a=n.x-i.x,r=n.y-i.y,o=i.x+a/2,l=i.y+r/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(i.x,i.y,a,r),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});let c=10;this.moveHandle.clear(),this.moveHandle.circle(0,0,c/2),this.moveHandle.fill({color:16752394,alpha:.9}),this.moveHandle.position.set(o,l),this.scaleHandle.clear(),this.scaleHandle.rect(-c/2,-c/2,c,c),this.scaleHandle.fill({color:3900150,alpha:.9}),this.scaleHandle.position.set(n.x,n.y),this.rotateHandle.clear(),this.rotateHandle.circle(0,0,c/2),this.rotateHandle.fill({color:1096065,alpha:.9}),this.rotateHandle.position.set(o,i.y-20)}clearGizmos(){this.gizmoOutline.clear(),this.moveHandle.clear(),this.scaleHandle.clear(),this.rotateHandle.clear()}setSelected(e,t={}){if(this.selectedId!==e&&(this.selectedId=e,this.updateGizmos(),!t.silent&&e)){let i=window.__previewSelectObject;typeof i=="function"&&i(e)}}startDrag(e,t){var d,p,u,g,h;if(!this.selectedId||!e||!this.app||((u=(p=(d=t==null?void 0:t.data)==null?void 0:d.originalEvent)==null?void 0:p.button)!=null?u:0)!==0)return;let n=this.objectMap.get(this.selectedId);if(!n)return;let a=this.camera.toLocal(t.data.global),r=n.displayObject;this.dragMode=e,this.dragStartPointer=a.clone(),this.dragStartPos=new H.Point(r.position.x,r.position.y),this.dragStartScale=typeof((g=r.scale)==null?void 0:g.x)=="number"?r.scale.x:1;let o=this.getEditableObjectConfig(this.selectedId),l=(h=o==null?void 0:o.transform)!=null?h:{};this.dragStartRotationDeg=typeof l.rotation=="number"?l.rotation:0,this.dragAnchorLocal=this.getAnchorLocalPoint(l),this.dragStartValue=this.getDragStartValue(e,l);let c=new H.Point(r.position.x,r.position.y);this.dragStartAngle=Math.atan2(a.y-c.y,a.x-c.x),this.dragStartDistance=Math.max(1,this.distance(a,c)),window.addEventListener("pointermove",this.onDragMove),window.addEventListener("pointerup",this.onDragEnd)}getDragStartValue(e,t){var i,n,a;return e==="move"?(i=t==null?void 0:t.position)!=null?i:{x:0,y:0}:e==="scale"?(n=t==null?void 0:t.scale)!=null?n:1:e==="rotate"?(a=t==null?void 0:t.rotation)!=null?a:0:null}updateLiveConfigPosition(e,t){var p,u,g,h,f,m;if(!this.selectedId||!this.dragAnchorLocal)return;let i=e-this.dragAnchorLocal.x,n=t-this.dragAnchorLocal.y,a=this.getEditableObjectConfig(this.selectedId);if(!a)return;let r=(p=a.transform)!=null?p:{};a.transform||(a.transform=r);let o=(u=r.offset)!=null?u:{x:0,y:0},l=Array.isArray(o)?Number((g=o[0])!=null?g:0):Number((h=o==null?void 0:o.x)!=null?h:0),c=Array.isArray(o)?Number((f=o[1])!=null?f:0):Number((m=o==null?void 0:o.y)!=null?m:0),d=this.buildPositionValue(r,{x:i-l,y:n-c});this.setNestedValue(r,"position",d)}updateLiveConfigScale(e){var n;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(n=t.transform)!=null?n:{};t.transform||(t.transform=i),i.scale=e}updateLiveConfigRotation(e){var n;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(n=t.transform)!=null?n:{};t.transform||(t.transform=i),i.rotation=e}applyFinalOverride(e,t,i,n){let a=this.getEditableObjectConfig(e);a!=null&&a.transform&&this.setNestedValue(a.transform,t.replace("transform.",""),n),ne({objectId:e,path:t,value:i},{persist:!0,emitEvent:!0,trackHistory:!0})}queueLiveApply(e){this.applyQueuedId=e,!this.applyQueued&&(this.applyQueued=!0,requestAnimationFrame(()=>{this.applyQueued=!1;let t=this.applyQueuedId;if(!t)return;let i=this.getEditableObjectConfig(t),n=window.applyEditableObjectConfig;typeof n=="function"&&i&&n(t,i)}))}setNestedValue(e,t,i){let n=t.split("."),a=e;for(let r=0;r<n.length-1;r+=1){let o=n[r];(!a[o]||typeof a[o]!="object")&&(a[o]={}),a=a[o]}a[n[n.length-1]]=i}buildPositionValue(e,t){let i=e==null?void 0:e.position;return Array.isArray(i)?[t.x,t.y]:{x:t.x,y:t.y}}distance(e,t){let i=e.x-t.x,n=e.y-t.y;return Math.sqrt(i*i+n*n)}getPointerInCamera(e,t){if(!this.app)return null;let i=this.app.canvas.getBoundingClientRect(),n=(e-i.left)*(this.app.renderer.width/i.width),a=(t-i.top)*(this.app.renderer.height/i.height),r=new H.Point;return this.camera.toLocal(new H.Point(n,a),void 0,r),r}};var ln=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[We("playable-portrait"),We("iphone-14"),We("ipad-mini")];this.activeCompareId="playable-portrait";this.compareViewports=new Map;this.resizeObserver=null;this.rafFitHandle=null;this.ignoreNextWindowResize=!1;this.frameDragOffsetX=0;this.frameDragOffsetY=0;this.frameDragActive=!1;this.frameDragStartX=0;this.frameDragStartY=0;this.frameDragOriginX=0;this.frameDragOriginY=0;this.isSpaceKeyPressed=!1;this.consolePanel=null;this.consoleMessages=[];this.isConsoleOpen=!1;this.originalConsole={log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console)};this.sceneEditor=null;this.sceneVisiblePreference=!0;this.sceneVisible=!0;this.hasInitialFit=!1;this.isMounted=!1;this.isInitialized=!1;this.gameReady=!1;this.resizeListenersDisabled=!1;this.compareSnapshotTimer=null;this.hasUnsavedChanges=!1;this.onWindowResize=e=>{if(this.ignoreNextWindowResize){this.ignoreNextWindowResize=!1;return}this.resizeListenersDisabled||!this.gameReady||this.scheduleFit()};this.onFrameDragMove=e=>{if(!this.frameDragActive)return;let t=e.clientX-this.frameDragStartX,i=e.clientY-this.frameDragStartY;this.frameDragOffsetX=this.frameDragOriginX+t,this.frameDragOffsetY=this.frameDragOriginY+i,this.applyFrameDrag(),this.updateDragCursor()};this.onFrameDragEnd=()=>{this.frameDragActive&&(this.frameDragActive=!1,window.removeEventListener("pointermove",this.onFrameDragMove),window.removeEventListener("pointerup",this.onFrameDragEnd),this.updateDragCursor())};this.options=e,this.currentPreset=We(e.defaultDevice||Ei.id),this.debugPanel=new Ut,this.container=this.createShell(),this.previewContainer=this.mustQuery(".preview-container"),this.singleStage=this.mustQuery('[data-preview-stage="single"]'),this.compareStage=this.mustQuery('[data-preview-stage="compare"]'),this.frameDragger=this.mustQuery(".frame-dragger"),this.frameWrapper=this.mustQuery(".frame-wrapper"),this.deviceFrame=this.mustQuery(".device-frame"),this.gameContainer=this.mustQuery(".game-container"),this.scenePane=this.mustQuery("[data-scene-pane]"),this.sceneRoot=this.mustQuery("#scene-editor-root"),this.sceneSplitter=this.mustQuery("[data-scene-splitter]"),this.gameViewPane=this.mustQuery("[data-game-pane]"),this.lastSinglePresetId=this.currentPreset.id,this.consolePanel=this.container.querySelector(".console-panel"),this.debugPanel.initialize(this.container),this.debugPanel.setupDebugEventListeners();try{let t=window.localStorage.getItem(this.getSceneVisibilityStorageKey());this.sceneVisiblePreference=t===null?!0:t==="true"}catch{}this.sceneEditor=new on({root:this.sceneRoot,getScreen:()=>this.getScreen()}),this.sceneEditor.mount(),this.applyDeviceFrameStyles(),this.setupCompareViewports(),this.setupConsoleInterceptor(),this.setupObserversAndListeners(),this.setupFrameDragging(),this.setupSpaceKeyListener(),this.setupShortcutListeners(),this.setupUnsavedChangesIndicator(),this.setupScenePaneInteractions(),this.updateSceneVisibility(),this.setDevice(this.currentPreset.id,{suppressCallback:!0}),this.updateDockState(),this.isInitialized=!0}getShortcutKey(){return typeof navigator!="undefined"&&navigator.platform.toUpperCase().indexOf("MAC")>=0?"CMD":"CTRL"}mount(e=document.body){e.innerHTML="",e.appendChild(this.container),this.isMounted=!0,this.scheduleFit()}destroy(){if(this.disableResizeListeners(),this.resizeObserver){try{this.resizeObserver.disconnect()}catch{}this.resizeObserver=null}window.removeEventListener("resize",this.onWindowResize),this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null),this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null),this.gameReady=!1,this.sceneEditor&&(this.sceneEditor.destroy(),this.sceneEditor=null)}getGameContainer(){return this.gameContainer}getScreen(){let e=this.getEffectivePreset();return{width:e.width,height:e.height}}getEffectivePreset(){var e;return this.isLandscape?{...this.currentPreset,width:this.currentPreset.height,height:this.currentPreset.width,ratio:((e=this.currentPreset.ratio)==null?void 0:e.split(":").reverse().join(":"))||this.currentPreset.ratio}:this.currentPreset}notifyGameLoaded(){var e;this.gameReady=!0,this.enableResizeListeners(),this.scheduleFit(),this.debugPanel.refresh(),(e=this.sceneEditor)==null||e.refresh(),requestAnimationFrame(()=>this.updatePanelPositions())}notifyGameDestroyed(){this.gameReady=!1,this.disableResizeListeners()}disableResizeListeners(){this.resizeListenersDisabled=!0,this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null)}enableResizeListeners(){this.resizeListenersDisabled=!1}refresh(){this.options.onRefresh?this.options.onRefresh():window.location.reload()}setDevice(e,t={}){var n,a;let i=this.autoScale*this.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=We(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepVisibleScale:i}),t.suppressCallback||(a=(n=this.options).onDeviceChange)==null||a.call(n,this.getEffectivePreset()),this.emitScreenChange()}setTheme(e){e==="dark"?this.container.classList.add("theme-dark"):this.container.classList.remove("theme-dark"),requestAnimationFrame(()=>this.updatePanelPositions())}setLayoutMode(e){if(this.layoutMode===e)return;this.layoutMode=e,this.container.classList.toggle("layout-fixed",e==="fixed"),this.container.classList.toggle("layout-draggable",e==="draggable"),Array.from(this.container.querySelectorAll("[data-layout-toggle]")).forEach(n=>n.classList.toggle("active",n.dataset.layoutToggle===e)),Array.from(this.container.querySelectorAll(".debug-workbench, .scene-panel")).forEach(n=>{n.style.left="",n.style.top="",n.style.width="",n.style.height="",n.style.zIndex=""}),this.scheduleFit(),this.updateDockState(),this.updatePanelPositions(),this.updateSceneVisibility(),window.dispatchEvent(new CustomEvent("inspector:refresh"))}updateDockState(){let e=this.container.querySelector("#bottom-dock");e==null||e.classList.remove("hidden");let t=this.container.querySelector("#console-messages"),i=this.container.querySelector("#dock-console-content");t&&i&&t.parentElement!==i&&i.appendChild(t)}makeBottomDockResizable(e,t){let i,n,a=o=>{let l=o.clientY-i,c=Math.max(100,Math.min(800,n-l));e.style.height=`${c}px`;let d=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:d})},r=()=>{document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",r),e.classList.remove("resizing")};t.addEventListener("pointerdown",o=>{o.preventDefault(),i=o.clientY,n=e.offsetHeight,document.addEventListener("pointermove",a),document.addEventListener("pointerup",r),e.classList.add("resizing")})}makeSidebarResizable(e,t,i){let n,a,r=l=>{let c=i==="left"?l.clientX-n:n-l.clientX,d=Math.max(200,Math.min(600,a+c));e.style.width=`${d}px`;let p=this.container.querySelector(".preview-main");if(p){let g=i==="left"?`${d}px`:p.style.gridTemplateColumns.split(" ")[0]||"300px",h=i==="right"?`${d}px`:p.style.gridTemplateColumns.split(" ")[2]||"350px";p.style.gridTemplateColumns=`${g} 1fr ${h}`}let u=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:u})},o=()=>{document.removeEventListener("pointermove",r),document.removeEventListener("pointerup",o),e.classList.remove("resizing")};t.addEventListener("pointerdown",l=>{l.preventDefault(),n=l.clientX,a=e.offsetWidth,document.addEventListener("pointermove",r),document.addEventListener("pointerup",o),e.classList.add("resizing")})}getSceneVisibilityStorageKey(){return`handler_preview_scene_visible::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getSceneWidthStorageKey(){return`handler_preview_scene_width::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}setupScenePaneInteractions(){let e=this.scenePane.querySelector("[data-scene-drag-handle]"),t=this.scenePane.querySelector("[data-scene-resize]"),i=this.container.querySelector("[data-preview-split]");e&&Ye(this.scenePane,e,i!=null?i:this.previewContainer),t&&an(this.scenePane,t,void 0,260,200);let n=this.getStoredSceneWidth();n&&(this.scenePane.style.width=`${n}px`),this.sceneSplitter.addEventListener("pointerdown",a=>{if(this.layoutMode!=="fixed"||!this.sceneVisible)return;a.preventDefault();let r=a.clientX,o=this.scenePane.offsetWidth,l=Math.max(260,Math.min(720,this.previewContainer.clientWidth*.6)),c=p=>{let u=p.clientX-r,g=Math.max(240,Math.min(l,o+u));this.scenePane.style.width=`${g}px`;let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},d=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",d),this.storeSceneWidth(this.scenePane.offsetWidth)};document.addEventListener("pointermove",c),document.addEventListener("pointerup",d)})}storeSceneWidth(e){try{window.localStorage.setItem(this.getSceneWidthStorageKey(),String(e))}catch{}}getStoredSceneWidth(){try{let e=window.localStorage.getItem(this.getSceneWidthStorageKey()),t=e?Number(e):null;return Number.isFinite(t)&&t?t:null}catch{return null}}updateSceneVisibility(){let e=this.viewMode==="single"&&this.sceneVisiblePreference;this.setSceneVisible(e,{persist:!1});let t=this.container.querySelector("#scene-toggle");t&&(t.classList.toggle("active",this.sceneVisiblePreference),t.setAttribute("aria-pressed",String(this.sceneVisiblePreference)))}setSceneVisible(e,t={}){var i;if(this.sceneVisible=e,this.container.classList.toggle("scene-hidden",!e),(i=this.sceneEditor)==null||i.setVisible(e),t.persist!==!1){this.sceneVisiblePreference=e;try{window.localStorage.setItem(this.getSceneVisibilityStorageKey(),String(e))}catch{}}this.scheduleFit()}createShell(){var t;let e=document.createElement("div");return e.className="preview-shell layout-fixed",e.innerHTML=`
2152
2237
  <div class="preview-toolbar">
2153
2238
  <div class="preview-toolbar-left">
2154
2239
  <span class="preview-logo">PREVIEWER</span>
@@ -2157,11 +2242,11 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2157
2242
  <div class="preview-toolbar-center">
2158
2243
  <div class="device-selector-wrapper">
2159
2244
  <select class="device-dropdown" id="device-select">
2160
- ${Wi.map(n=>`
2161
- <optgroup label="${n.label}">
2162
- ${n.devices.map(i=>`
2163
- <option value="${i.id}" ${i.id===this.currentPreset.id?"selected":""}>
2164
- ${i.label} (${i.width}\xD7${i.height})
2245
+ ${ea.map(i=>`
2246
+ <optgroup label="${i.label}">
2247
+ ${i.devices.map(n=>`
2248
+ <option value="${n.id}" ${n.id===this.currentPreset.id?"selected":""}>
2249
+ ${n.label} (${n.width}\xD7${n.height})
2165
2250
  </option>
2166
2251
  `).join("")}
2167
2252
  </optgroup>
@@ -2226,6 +2311,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2226
2311
  Save <span class="preview-save-shortcut" id="preview-save-shortcut-text"></span>
2227
2312
  </button>
2228
2313
  <button class="preview-btn" id="refresh-btn">Restart</button>
2314
+ <button class="preview-btn scene-toggle" id="scene-toggle" aria-pressed="true">Scene View</button>
2229
2315
  <button class="preview-btn debug-toggle" id="debug-toggle">
2230
2316
  Scene Edit Panel <span class="debug-toggle-badge" id="debug-badge"></span>
2231
2317
  </button>
@@ -2236,42 +2322,61 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2236
2322
  </div>
2237
2323
 
2238
2324
  <div class="preview-main">
2239
-
2240
2325
  <div class="preview-container">
2241
- <div class="preview-stage" data-preview-stage="single">
2242
- <div class="frame-dragger">
2243
- <div class="frame-wrapper">
2244
- <div class="device-frame">
2245
- <div class="game-container"></div>
2326
+ <div class="preview-split" data-preview-split>
2327
+ <div class="scene-editor-pane" data-scene-pane>
2328
+ <div class="scene-editor-header">
2329
+ <div class="scene-editor-title">Scene View</div>
2330
+ <div class="scene-editor-actions">
2331
+ <button class="debug-btn debug-btn-sm" type="button" id="scene-hide-btn">Hide</button>
2332
+ </div>
2333
+ <div class="scene-editor-drag-handle" data-scene-drag-handle title="Drag Scene View">
2334
+ \u22EE\u22EE
2246
2335
  </div>
2247
2336
  </div>
2248
- </div>
2249
- </div>
2250
-
2251
- <div class="preview-stage hidden" data-preview-stage="compare">
2252
- <div class="compare-grid" data-compare-grid>
2253
- ${this.comparePresets.map(n=>`
2254
- <div class="compare-viewport" data-viewport="${n.id}">
2255
- <div class="compare-header">
2256
- <div class="compare-title">
2257
- <span class="compare-title-text">${n.label}</span>
2258
- <span class="compare-meta">${n.ratio} | ${n.width}x${n.height}</span>
2337
+ <div class="scene-editor-body">
2338
+ <div class="scene-editor-root" id="scene-editor-root"></div>
2339
+ </div>
2340
+ <div class="scene-editor-resize-handle" data-scene-resize></div>
2341
+ </div>
2342
+ <div class="scene-splitter" data-scene-splitter></div>
2343
+ <div class="game-view-pane" data-game-pane>
2344
+ <div class="preview-stage" data-preview-stage="single">
2345
+ <div class="frame-dragger">
2346
+ <div class="frame-wrapper">
2347
+ <div class="device-frame">
2348
+ <div class="game-container"></div>
2259
2349
  </div>
2260
- <button class="compare-focus" data-compare-focus type="button">Focus</button>
2261
2350
  </div>
2262
- <div class="compare-body">
2263
- <div class="compare-slot" data-compare-slot></div>
2264
- <div class="compare-ghost" data-compare-ghost>
2265
- <div class="frame-wrapper" data-compare-wrapper>
2266
- <div class="device-frame" data-compare-frame>
2267
- <canvas class="snapshot-canvas" data-compare-snapshot></canvas>
2351
+ </div>
2352
+ </div>
2353
+
2354
+ <div class="preview-stage hidden" data-preview-stage="compare">
2355
+ <div class="compare-grid" data-compare-grid>
2356
+ ${this.comparePresets.map(i=>`
2357
+ <div class="compare-viewport" data-viewport="${i.id}">
2358
+ <div class="compare-header">
2359
+ <div class="compare-title">
2360
+ <span class="compare-title-text">${i.label}</span>
2361
+ <span class="compare-meta">${i.ratio} | ${i.width}x${i.height}</span>
2268
2362
  </div>
2363
+ <button class="compare-focus" data-compare-focus type="button">Focus</button>
2364
+ </div>
2365
+ <div class="compare-body">
2366
+ <div class="compare-slot" data-compare-slot></div>
2367
+ <div class="compare-ghost" data-compare-ghost>
2368
+ <div class="frame-wrapper" data-compare-wrapper>
2369
+ <div class="device-frame" data-compare-frame>
2370
+ <canvas class="snapshot-canvas" data-compare-snapshot></canvas>
2371
+ </div>
2372
+ </div>
2373
+ </div>
2374
+ <div class="compare-overlay" data-compare-overlay>Click to focus</div>
2269
2375
  </div>
2270
2376
  </div>
2271
- <div class="compare-overlay" data-compare-overlay>Click to focus</div>
2272
- </div>
2377
+ `).join("")}
2273
2378
  </div>
2274
- `).join("")}
2379
+ </div>
2275
2380
  </div>
2276
2381
  </div>
2277
2382
  </div>
@@ -2318,7 +2423,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2318
2423
  </div>
2319
2424
 
2320
2425
  </div>
2321
- `,this.setupEventListeners(e),e}setupEventListeners(e){var g,f,h,m,b,y,v,w;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",E=>{if(this.viewMode==="compare")return;let j=E.target.value;this.setDevice(j)});let n=e.querySelector("#theme-select");n==null||n.addEventListener("change",E=>{let j=E.target.value;this.setTheme(j)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(E=>{E.addEventListener("click",()=>{let j=E.dataset.viewToggle;j&&this.setViewMode(j)})}),Array.from(e.querySelectorAll("[data-layout-toggle]")).forEach(E=>{E.addEventListener("click",()=>{let j=E.dataset.layoutToggle;j&&this.setLayoutMode(j)})}),(g=e.querySelector("#rotate-btn"))==null||g.addEventListener("click",()=>this.toggleRotation()),(f=e.querySelector("#zoom-in-btn"))==null||f.addEventListener("click",()=>this.adjustUserZoom(.1)),(h=e.querySelector("#zoom-out-btn"))==null||h.addEventListener("click",()=>this.adjustUserZoom(-.1)),(m=e.querySelector("#refresh-btn"))==null||m.addEventListener("click",()=>this.refresh());let r=e.querySelector("#bottom-dock"),o=e.querySelector("#bottom-dock-resize");r&&o&&this.makeBottomDockResizable(r,o);let l=Array.from(e.querySelectorAll(".bottom-dock-tab"));l.forEach(E=>{E.addEventListener("click",()=>{let j=E.dataset.dockTab;if(!j)return;l.forEach(S=>S.classList.remove("active")),E.classList.add("active"),Array.from(e.querySelectorAll(".bottom-dock-panel")).forEach(S=>{let P=S.dataset.dockPanel;S.classList.toggle("active",P===j)})})}),(b=e.querySelector("#console-clear"))==null||b.addEventListener("click",()=>this.clearConsole()),(y=e.querySelector("#corner-zoom-in-btn"))==null||y.addEventListener("click",()=>this.adjustUserZoom(.1)),(v=e.querySelector("#corner-zoom-out-btn"))==null||v.addEventListener("click",()=>this.adjustUserZoom(-.1)),(w=e.querySelector("#corner-grab-btn"))==null||w.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)});let c=e.querySelector(".scene-panel.scene-objects"),d=c==null?void 0:c.querySelector("[data-panel-resize-v]");c&&d&&this.makeSidebarResizable(c,d,"left");let p=e.querySelector(".debug-workbench"),u=p==null?void 0:p.querySelector("#workbench-resize-v");p&&u&&this.makeSidebarResizable(p,u,"right")}applyDeviceFrameStyles(){Object.assign(this.frameDragger.style,{display:"flex",justifyContent:"center",alignItems:"center",transform:"translate(0px, 0px)",touchAction:"none"}),Object.assign(this.frameWrapper.style,{display:"flex",justifyContent:"center",alignItems:"center",transformOrigin:"center center",transition:"transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)",boxShadow:"var(--ui-shadow-strong)",borderRadius:"0px",willChange:"transform"}),Object.assign(this.deviceFrame.style,{overflow:"hidden",position:"relative",borderRadius:"0px"}),Object.assign(this.gameContainer.style,{position:"relative",overflow:"hidden",minWidth:"0px",minHeight:"0px"})}setupObserversAndListeners(){this.resizeObserver=new ResizeObserver(()=>{this.resizeListenersDisabled||this.scheduleFit()}),this.resizeObserver.observe(this.previewContainer),window.addEventListener("resize",this.onWindowResize,{passive:!0})}scheduleFit(){this.rafFitHandle&&cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=requestAnimationFrame(()=>{this.rafFitHandle=null,this.fitToScreen()})}applyPresetDimensions(){let e=this.getEffectivePreset(),t=`${e.width}px`,n=`${e.height}px`;this.deviceFrame.style.width=t,this.deviceFrame.style.height=n,this.gameContainer.style.width=t,this.gameContainer.style.height=n,this.gameContainer.style.maxWidth=t,this.gameContainer.style.maxHeight=n,this.gameContainer.style.minWidth=t,this.gameContainer.style.minHeight=n,this.gameContainer.dataset.screenWidth=String(e.width),this.gameContainer.dataset.screenHeight=String(e.height),this.container.style.setProperty("--preview-screen-width",String(e.width)),this.container.style.setProperty("--preview-screen-height",String(e.height))}fitToScreen(e){if(!this.previewContainer)return;let t=this.getEffectivePreset(),n=this.getFitBounds(),i=Math.max(0,n.width),a=Math.max(0,n.height);if(i<=0||a<=0)return;this.applyPresetDimensions(),this.viewMode==="compare"&&this.applyCompareDimensions();let r=i/t.width,o=a/t.height;if(this.autoScale=Math.max(.01,Math.min(r,o)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}e!=null&&e.keepVisibleScale&&e.keepVisibleScale>0&&(this.userScaleMultiplier=e.keepVisibleScale/this.autoScale),this.applyTransform(),this.viewMode==="compare"&&this.fitCompareGhosts(),requestAnimationFrame(()=>this.updatePanelPositions()),this.emitScreenChange()}applyTransform(){let e=this.autoScale*this.userScaleMultiplier;this.frameWrapper.style.transform=`scale(${e})`;let t=this.container.querySelector("#zoom-label");t&&(t.textContent=`${Math.round(e*100)}%`),requestAnimationFrame(()=>this.updatePanelPositions())}applyFrameDrag(){this.frameDragger.style.transform=`translate(${this.frameDragOffsetX}px, ${this.frameDragOffsetY}px)`,requestAnimationFrame(()=>this.updatePanelPositions())}updatePanelPositions(){if(!this.gameReady||this.viewMode==="compare")return;let e=this.container.querySelector('[data-panel="scene-tools-corner"]'),t=this.container.querySelector('[data-panel="nudge-panel"]');if(this.layoutMode==="fixed"){let n=this.container.querySelector(".preview-container");n&&(e&&e.parentElement!==n&&n.appendChild(e),t&&t.parentElement!==n&&n.appendChild(t))}else{let n=this.container.querySelector(".preview-main");n&&(e&&e.parentElement!==n&&n.appendChild(e),t&&t.parentElement!==n&&n.appendChild(t))}e&&(e.style.zIndex="100"),t&&(t.style.position="absolute",t.style.left="50%",t.style.top="16px",t.style.transform="translateX(calc(-50% + 200px))",t.style.zIndex="100")}setupFrameDragging(){this.frameDragger.addEventListener("pointerdown",e=>{let t=!this.gameContainer.contains(e.target);!this.isSpaceKeyPressed&&!t||e.button===0&&(e.preventDefault(),this.frameDragActive=!0,this.frameDragStartX=e.clientX,this.frameDragStartY=e.clientY,this.frameDragOriginX=this.frameDragOffsetX,this.frameDragOriginY=this.frameDragOffsetY,window.addEventListener("pointermove",this.onFrameDragMove),window.addEventListener("pointerup",this.onFrameDragEnd))})}setupSpaceKeyListener(){window.addEventListener("keydown",e=>{e.code==="Space"&&!this.isInputFocused()&&(this.isSpaceKeyPressed||(this.isSpaceKeyPressed=!0,this.updateDragCursor(),e.preventDefault()))}),window.addEventListener("keyup",e=>{e.code==="Space"&&(this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd())}),window.addEventListener("blur",()=>{this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd()})}isInputFocused(){let e=document.activeElement;if(!e)return!1;let t=e.tagName.toLowerCase();return t==="input"||t==="textarea"||t==="select"||e.isContentEditable}setupShortcutListeners(){window.addEventListener("keydown",e=>{if(this.isInputFocused())return;let t=navigator.platform.toUpperCase().indexOf("MAC")>=0,n=e.ctrlKey||e.metaKey,i=e.shiftKey;if(n&&e.key==="s"&&!i){e.preventDefault();let a=document.querySelector("#apply-current-btn");a&&a.getAttribute("disabled")===null&&a.click();return}if(n&&e.key==="z"&&!i){e.preventDefault(),un();return}if(n&&(e.key==="z"&&i||e.key==="y"&&!i)){e.preventDefault(),gn();return}})}setupUnsavedChangesIndicator(){let e=this.container.querySelector("#preview-save-shortcut-text");e&&(e.textContent=`(${this.getShortcutKey()} + S)`),window.addEventListener("config:changed",()=>{this.updateUnsavedChangesIndicator()}),this.updateUnsavedChangesIndicator();let t=this.container.querySelector("#preview-save-btn");t==null||t.addEventListener("click",()=>{let n=document.querySelector("#apply-current-btn");n&&n.getAttribute("disabled")===null&&n.click()})}updateUnsavedChangesIndicator(){let t=Ie().hasChanges;if(t!==this.hasUnsavedChanges){this.hasUnsavedChanges=t;let n=this.container.querySelector("#preview-unsaved-star"),i=this.container.querySelector("#preview-save-btn");n&&(n.style.display=t?"inline-block":"none"),i&&(i.style.display=t?"inline-flex":"none")}}updateDragCursor(){this.isSpaceKeyPressed?(this.frameDragger.style.cursor="grab",this.frameDragActive&&(this.frameDragger.style.cursor="grabbing")):this.frameDragger.style.cursor=""}adjustUserZoom(e){this.userScaleMultiplier=Math.max(.1,Math.min(6,this.userScaleMultiplier+e)),this.applyTransform(),this.emitScreenChange()}toggleRotation(){var t,n;if(this.viewMode==="compare")return;let e=this.autoScale*this.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepVisibleScale:e}),(n=(t=this.options).onDeviceChange)==null||n.call(t,this.getEffectivePreset()),this.emitScreenChange()}emitScreenChange(){if(!this.gameReady)return;let e=this.getEffectivePreset(),t={width:e.width,height:e.height,dpr:Math.max(1,Math.floor(window.devicePixelRatio||1)),presetId:e.id,isLandscape:this.isLandscape};if(window.dispatchEvent(new CustomEvent("handler-preview:screen",{detail:t})),this.viewMode==="compare"&&this.refreshCompareSnapshots(),this.isInitialized&&this.isMounted&&this.gameReady){let n=window.gameApp;if(!(n!=null&&n.renderer))return;this.ignoreNextWindowResize=!0,window.dispatchEvent(new Event("resize"))}}safeStringify(e){var n;let t=new WeakSet;try{return JSON.stringify(e,(i,a)=>{if(typeof a=="object"&&a!==null){if(t.has(a))return"[Circular]";t.add(a)}return a},2)}catch{try{if(e&&((n=e.constructor)!=null&&n.name))return`[object ${e.constructor.name}]`}catch{}return String(e)}}setupConsoleInterceptor(){let e=(t,...n)=>{let i=n.map(r=>typeof r=="object"?this.safeStringify(r):String(r)).join(" ");this.consoleMessages.push({type:t,message:i,timestamp:new Date}),this.appendConsoleMessage(this.consoleMessages[this.consoleMessages.length-1]);let a=this.container.querySelector("#console-badge");if(a){let r=this.consoleMessages.filter(o=>o.type==="error").length;a.textContent=r>0?`${r}!`:"0",a.classList.toggle("has-errors",r>0)}};console.log=(...t)=>{this.originalConsole.log(...t),e("log",...t)},console.warn=(...t)=>{this.originalConsole.warn(...t),e("warn",...t)},console.error=(...t)=>{this.originalConsole.error(...t),e("error",...t)},console.info=(...t)=>{this.originalConsole.info(...t),e("info",...t)}}appendConsoleMessage(e){let t=this.container.querySelector("#console-messages");if(!t)return;let n=document.createElement("div");n.className=`console-msg type-${e.type}`;let i=e.timestamp.toLocaleTimeString();n.innerHTML=`<span class="time">${this.escapeHtml(i)}</span> <pre>${this.escapeHtml(e.message)}</pre>`,t.appendChild(n),t.scrollTop=t.scrollHeight}escapeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}toggleConsole(e){var t;if(this.layoutMode==="fixed"){let n=this.container.querySelector('[data-dock-tab="console"]');if(n){n.click();let i=this.container.querySelector("#bottom-dock");i==null||i.classList.remove("hidden")}return}this.isConsoleOpen=e!=null?e:!this.isConsoleOpen,(t=this.consolePanel)==null||t.classList.toggle("closed",!this.isConsoleOpen)}clearConsole(){this.consoleMessages=[];let e=this.container.querySelector("#console-messages");e&&(e.innerHTML="");let t=this.container.querySelector("#console-badge");t&&(t.textContent="0")}setupCompareViewports(){Array.from(this.container.querySelectorAll("[data-viewport]")).forEach(t=>{let n=t.dataset.viewport;if(!n)return;let i=this.comparePresets.find(p=>p.id===n);if(!i)return;let a=t.querySelector("[data-compare-slot]"),r=t.querySelector("[data-compare-ghost]"),o=t.querySelector("[data-compare-wrapper]"),l=t.querySelector("[data-compare-frame]"),c=t.querySelector("[data-compare-snapshot]"),d=t.querySelector("[data-compare-focus]");!a||!r||!o||!l||(t.addEventListener("click",p=>{let u=p.target;if(u!=null&&u.closest("[data-compare-focus]")){p.preventDefault(),this.activateCompareViewport(n);return}t.classList.contains("is-active")||this.activateCompareViewport(n)}),this.compareViewports.set(n,{preset:i,root:t,slot:a,ghost:r,wrapper:o,frame:l,canvas:c,focus:d}))})}setViewMode(e){if(this.viewMode===e)return;this.viewMode=e,this.container.classList.toggle("compare-mode",e==="compare"),this.singleStage.classList.toggle("hidden",e!=="single"),this.compareStage.classList.toggle("hidden",e!=="compare");let t=this.container.querySelector("#device-select");t&&(t.disabled=e==="compare");let n=this.container.querySelector("#rotate-btn");if(n&&(n.disabled=e==="compare"),this.updateViewToggleUI(),e==="compare"){this.lastSinglePresetId=this.currentPreset.id,this.activateCompareViewport(this.activeCompareId),this.refreshCompareSnapshots(),this.startCompareSnapshots();return}this.stopCompareSnapshots(),this.singleStage.appendChild(this.frameDragger),this.setDevice(this.lastSinglePresetId,{suppressCallback:!0}),this.fitToScreen()}updateViewToggleUI(){Array.from(this.container.querySelectorAll("[data-view-toggle]")).forEach(t=>{t.classList.toggle("active",t.dataset.viewToggle===this.viewMode)})}activateCompareViewport(e){var a,r;let t=this.compareViewports.get(e);if(!t)return;let n=this.autoScale*this.userScaleMultiplier,i=this.activeCompareId;i&&i!==e&&this.captureCompareSnapshot(i),this.activeCompareId=e,this.currentPreset=t.preset,this.isLandscape=!1,t.slot.appendChild(this.frameDragger),this.frameDragOffsetX=0,this.frameDragOffsetY=0,this.applyFrameDrag(),this.compareViewports.forEach((o,l)=>{o.root.classList.toggle("is-active",l===e),o.ghost.classList.toggle("hidden",l===e),o.focus&&(o.focus.textContent=l===e?"Live":"Focus")}),this.applyPresetDimensions(),this.applyCompareDimensions(),this.fitToScreen({keepVisibleScale:n}),(r=(a=this.options).onDeviceChange)==null||r.call(a,this.getEffectivePreset())}applyCompareDimensions(){this.compareViewports.forEach(e=>{let t=e.preset,n=`${t.width}px`,i=`${t.height}px`;e.frame.style.width=n,e.frame.style.height=i,e.canvas&&(e.canvas.width=t.width,e.canvas.height=t.height)})}fitCompareGhosts(){this.compareViewports.forEach(e=>{let t=e.root.querySelector(".compare-body");if(!t)return;let n=Math.max(0,t.clientWidth-24),i=Math.max(0,t.clientHeight-24);if(n<=0||i<=0)return;let a=n/e.preset.width,r=i/e.preset.height,o=Math.max(.01,Math.min(a,r));e.wrapper.style.transform=`scale(${o})`})}captureCompareSnapshot(e){let t=this.compareViewports.get(e);if(!(t!=null&&t.canvas))return;let n=this.gameContainer.querySelector("canvas");if(!n)return;let i=t.canvas.getContext("2d");if(!i)return;let a=t.canvas.width,r=t.canvas.height,o=Math.min(a/n.width,r/n.height),l=n.width*o,c=n.height*o,d=(a-l)/2,p=(r-c)/2;i.clearRect(0,0,a,r),i.drawImage(n,d,p,l,c)}refreshCompareSnapshots(){this.compareViewports.forEach((e,t)=>{t!==this.activeCompareId&&this.captureCompareSnapshot(t)})}startCompareSnapshots(){this.compareSnapshotTimer||(this.compareSnapshotTimer=window.setInterval(()=>{this.viewMode==="compare"&&this.refreshCompareSnapshots()},500))}stopCompareSnapshots(){this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null)}getFitBounds(){if(this.viewMode!=="compare")return{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40};let e=this.compareViewports.get(this.activeCompareId),t=e==null?void 0:e.root.querySelector(".compare-body");return t?{width:t.clientWidth-24,height:t.clientHeight-24}:{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40}}mustQuery(e){let t=this.container.querySelector(e);if(!t)throw new Error(`PreviewShell missing element: ${e}`);return t}};function La(s={}){let e=new ti(s);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}J();function ka(s){try{if(s&&typeof s.keys=="function")return Array.from(s.keys())}catch{}return[]}function Ar(s){var e;return s?((e=s.getDisplayObject)==null?void 0:e.call(s))||s.pixiObject||s:null}function pl(s,e){if(!s||!(e!=null&&e.interaction))return;let t=e.interaction,n=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);s.eventMode=n?"static":"none",s.interactive=n,n&&(s.cursor=t.draggable?"move":"pointer")}function Tr(s,e){var l,c,d;if(!s||!e)return;let t=e.transform||{};pl(s,e);let n=t.position||{},i=t.offset||{},a=(typeof n.x=="number"?n.x:0)+(typeof i.x=="number"?i.x:0),r=(typeof n.y=="number"?n.y:0)+(typeof i.y=="number"?i.y:0);(l=s.position)!=null&&l.set?s.position.set(a,r):(typeof s.x=="number"&&(s.x=a),typeof s.y=="number"&&(s.y=r)),typeof t.scale=="number"&&((c=s.scale)!=null&&c.set?s.scale.set(t.scale):s.scale&&(s.scale.x=t.scale,s.scale.y=t.scale));let o=t.anchor;if(o&&((d=s.anchor)!=null&&d.set)){let p=null;typeof window!="undefined"&&window.resolveAnchorVec2?p=window.resolveAnchorVec2(o):typeof o=="object"&&o.x!==void 0&&o.y!==void 0?p=o:Array.isArray(o)&&o.length===2&&(p={x:o[0],y:o[1]}),p&&typeof p.x=="number"&&typeof p.y=="number"&&s.anchor.set(p.x,p.y)}}function Lr(s){if(typeof window=="undefined")return;let e=s==null?void 0:s.objects,t=ka(e),n=a=>{try{let r=window.__HANDLER_ACTIVE_SCREEN;if(!r||r==="all")return a;let o=window.__HANDLER_SCREEN_INDEX,l=o==null?void 0:o.instanceToScreen;return l?a.filter(c=>l[c]===r):a}catch{return a}};window.__editableObjectConfigs=e;let i=new Map;t.forEach(a=>i.set(a,[a])),window.__editableObjectInstances=i,window.refreshEditableConfigIndex=()=>Lr(window.__editableConfig),window.getEditableObjectList=()=>{var a;return n(ka((a=window.__editableConfig)==null?void 0:a.objects))},window.getEditableObjectListAll=()=>{var a;return ka((a=window.__editableConfig)==null?void 0:a.objects)},window.getEditableObjectConfig=a=>{var d,p,u,g,f;let r=(g=(u=(p=(d=window.__editableConfig)==null?void 0:d.objects)==null?void 0:p.get)==null?void 0:u.call(p,a))!=null?g:null,o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return r;let l=window.__HANDLER_SCREEN_INDEX,c=(f=l==null?void 0:l.instanceToScreen)==null?void 0:f[a];return c&&c===o?r:null},window.getEditableEngineConfig=()=>{let a=window.__editableConfig;if(console.log("[BRIDGE] getEditableEngineConfig called, cfg present:",!!a),!a)return null;if(a.engine&&a.objects instanceof Map){console.log("[BRIDGE] Detected ObjectCentricConfig, flattening...");let r={...a.engine,objects:a.objects,scene:a.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(r.assets||{})),r}return a}}function ul(){if(typeof window=="undefined")return;let s=t=>{let n=String(t||"").trim();return n?/^(data:|blob:|https?:)/.test(n)||n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`:""},e=async(t,n)=>{var a,r,o;let i=s(n);if(i)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),Promise.resolve().then(()=>(nt(),Ss))]),d=Date.now(),p=/^(data:|blob:)/.test(i)?i:i+(i.includes("?")?`&t=${d}`:`?t=${d}`),u=await l.load(p);if(!u)return;c[t]=u;let g=window.CustomAssets;(a=g==null?void 0:g[t])!=null&&a.texture&&(g[t].texture=u);let f=window.gameObjectManager,h=(r=f==null?void 0:f.get)==null?void 0:r.call(f,t);if(h){let m=((o=h.getDisplayObject)==null?void 0:o.call(h))||h.pixiObject||h.pixi||h;if(m!=null&&m.texture)m.texture=u;else if(m!=null&&m.children){let b=m.children.find(y=>y==null?void 0:y.texture);b!=null&&b.texture&&(b.texture=u)}}}catch(l){console.warn("[LIVE-EDIT] Failed to reload Pixi texture for",t,l)}};window.applyLiveEditOverrides=t=>{try{let n=X();Array.isArray(n)&&n.length&&(window.__editableConfig=t,ke(n,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let n=X();Array.isArray(n)&&n.length&&(window.__editableConfig=t,ke(n,{silent:!0,persist:!1}))}catch{}},window.applyEditableEngineConfig=t=>{let n=window.__editableConfig;if(!(n!=null&&n.engine))return;let i=[];if(t.runtime)for(let[a,r]of Object.entries(t.runtime))i.push({path:`runtime.${a}`,value:r});if(t.assets)for(let[a,r]of Object.entries(t.assets))i.push({path:`assets.${a}`,value:r}),typeof r=="string"&&e(a,r);if(t.splash)for(let[a,r]of Object.entries(t.splash))i.push({path:`splash.${a}`,value:r});if(t.loading)for(let[a,r]of Object.entries(t.loading))i.push({path:`loading.${a}`,value:r});if(t.start)for(let[a,r]of Object.entries(t.start))i.push({path:`start.${a}`,value:r});i.length&&ke(i,{silent:!0,persist:!0,emitEvent:!0})}}function ni(s){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:n}=s;t&&(t.onObjectRebuildRequired=async(a,r)=>{console.log(`[LIVE-EDIT] \u{1F3D7}\uFE0F Rebuilding object ${a} due to type change...`);let o=t.get(a),l=o==null?void 0:o.pixiObject,c=l==null?void 0:l.parent,d=c==null?void 0:c.children.indexOf(l);o?t.remove(a):l&&l.destroy();let p=window.gameApp,u=await Le.create(a,r,p);c&&(d!==void 0&&d!==-1?c.addChildAt(u,d):c.addChild(u));let g=t.create(a,u);return console.log(`[LIVE-EDIT] \u2705 Rebuild complete for ${a}`),g}),typeof window!="undefined"&&(ul(),window.applyEditableObjectConfig=(a,r)=>{var o,l,c;console.log("[LIVE-EDIT] \u{1F504} applyEditableObjectConfig called for:",a);try{let d=window.__editableConfig;(o=d==null?void 0:d.objects)!=null&&o.set&&(d.objects.set(a,r),console.log("[LIVE-EDIT] \u2705 Updated config in __editableConfig"));let p=(l=t==null?void 0:t.get)==null?void 0:l.call(t,a);if(console.log("[LIVE-EDIT] gameObject found?",!!p),p&&(console.log("[LIVE-EDIT] gameObject type:",(c=p.constructor)==null?void 0:c.name),console.log("[LIVE-EDIT] has updateConfig?",typeof p.updateConfig=="function"),console.log("[LIVE-EDIT] has onConfigUpdate?",typeof p.onConfigUpdate=="function")),p&&typeof p.updateConfig=="function")console.log("[LIVE-EDIT] \u2705 Calling updateConfig()"),p.updateConfig(r);else if(p&&typeof p.onConfigUpdate=="function")console.log("[LIVE-EDIT] \u2705 Calling onConfigUpdate()"),p.onConfigUpdate();else{console.log("[LIVE-EDIT] \u26A0\uFE0F No updateConfig or onConfigUpdate, applying transform directly");let u=Ar(p);Tr(u,r)}}catch(d){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",d)}});let i={async applyObjectConfig(a,r){var d,p;console.log("[BRIDGE] \u{1F504} applyObjectConfig called for:",a);let o=e();(d=o==null?void 0:o.objects)!=null&&d.set&&(o.objects.set(a,r),console.log("[BRIDGE] \u2705 Updated config"));let l=(p=t==null?void 0:t.get)==null?void 0:p.call(t,a);if(console.log("[BRIDGE] gameObject found?",!!l),l&&(console.log("[BRIDGE] has updateConfig?",typeof l.updateConfig=="function"),console.log("[BRIDGE] has onConfigUpdate?",typeof l.onConfigUpdate=="function")),l&&typeof l.updateConfig=="function")console.log("[BRIDGE] \u2705 Calling updateConfig()"),l.updateConfig(r);else if(l&&typeof l.onConfigUpdate=="function")console.log("[BRIDGE] \u2705 Calling onConfigUpdate()"),l.onConfigUpdate();else{console.log("[BRIDGE] \u26A0\uFE0F Applying transform directly");let u=Ar(l);Tr(u,r)}let c=[a];n==null||n(a,r,c)},rebuildIndexes(){let a=e();typeof window!="undefined"&&(window.__editableConfig=a,Lr(a))}};return i.rebuildIndexes(),i}J();var jr=Ze(require("lottie-web"),1);vi(bi);typeof window!="undefined"&&!window.lottie&&(window.lottie=jr.default);var lt=null,gl=async()=>{if(!lt){let s=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(s==null?void 0:s["handler.config"])||(s==null?void 0:s["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let n=atob(e.split(",")[1]);lt=JSON.parse(n)}else lt=JSON.parse(e);return lt}catch(n){console.warn("[CONFIG] Failed to parse inline handler.config.json:",n)}lt=await(await fetch("./handler.config.json")).json()}return lt},Pa,Ft,Mr,ct,ja,Ma;function hl(s){Pa=s.initGame,Ft=s.CustomAssets,Mr=s.updateScreenState,ct=s.globalResponsiveMultipliers,ja=s.layout,Ma=s.clearResponsiveElements}var ii="web_embed",Nt="https://example.com",kr={profile_id:ii},Oe=null,de=null,Ia={width:0,height:0},fl=!0,ml=async()=>{var c,d,p,u;document.title="Handler Pixi Game";let s=await gl();kr={...s.ids||{},profile_id:ii},Nt=s.destination_url||((d=(c=s.export_profiles)==null?void 0:c[ii])==null?void 0:d.destination_url)||Nt,$e.init({ids:kr,profile:ii,destinationUrl:Nt});let e=$e.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),de=La({onDeviceChange:f=>{console.log(`[PREVIEW] Device switched to ${f.width}x${f.height}, restarting game...`),Ir()},onRefresh:Ir});let g=de.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",f=>{var v,w,E,j,z,S,P,R,T,A,M;let h=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=f.detail;if(Ia.width=b,Ia.height=y,Mr(b,y),!(!h||!h.renderer)){m&&o(h,m);try{h.renderer.resize(b,y);let k=h.view;k&&(k.style.width="100%",k.style.height="100%",k.style.display="block")}catch(k){console.warn("[SCREEN] Error resizing renderer:",k);return}if(t&&m&&ja)try{let k=(v=window.__mainContainer)!=null?v:h.stage,C=(P=(S=(j=window.__tutorialLabel)!=null?j:(E=(w=m.get("label_1"))==null?void 0:w.getDisplayObject)==null?void 0:E.call(w))!=null?S:(z=m.get("label_1"))==null?void 0:z.pixiObject)!=null?P:m.get("label_1"),x=m.get("background_1"),I=(M=(A=(T=window.__background)!=null?T:(R=x==null?void 0:x.getDisplayObject)==null?void 0:R.call(x))!=null?A:x==null?void 0:x.pixiObject)!=null?M:x;if(k){let L=k===h.stage;ja({mainContainer:k,label:C,background:I,backgroundTexture:(I==null?void 0:I.texture)||null,app:h},t,0,Ia,m,{skipMainContainerTransform:L})}}catch(k){console.warn("[SCREEN] Error in layout:",k)}}})}let t=await xe("scene.main");window.__editableConfig=t,r(),window.__editableConfigBaseline||(window.__editableConfigBaseline=W(t),console.log("[BOOTSTRAP] Frozen config baseline for persistence")),(u=(p=t.engine.runtime)==null?void 0:p.layout)!=null&&u.design_width_portrait||(console.warn("[BOOTSTRAP] Config layout missing, retrying..."),await new Promise(g=>setTimeout(g,100)),t=await xe("scene.main"));let n=await Pa(e,t,Nt,de);Oe=n.app;let i=n.gameObjectManager;window.gameApp=Oe,window.gameObjectManager=i;try{window.__liveEditBridge=ni({getConfig:()=>window.__editableConfig,gameObjectManager:i,assets:Ft})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}de&&de.notifyGameLoaded();let a=window.__debugScale;a&&typeof a=="number"&&(ct.scale=a,console.log(`[DEBUG] Applied persisted debug scale: ${a}`)),o(Oe,i);async function r(){try{let g=async y=>{let v=y.startsWith("/")?y:`/${y}`,w=await fetch(v,{cache:"no-cache"});if(!w.ok)return null;let E=await w.text();try{return JSON.parse(E)}catch{return null}},f=await g("configs/flow/app.flow.json");if(!f||typeof f!="object")return;let h=f.screens;if(!h||typeof h!="object")return;let m={},b={};for(let[y,v]of Object.entries(h)){let w=v==null?void 0:v.source;if(typeof w!="string")continue;let E=await g(w),j=E==null?void 0:E.elements;if(!Array.isArray(j))continue;let z=j.map(S=>S==null?void 0:S.instance_id).filter(S=>typeof S=="string");m[y]=z;for(let S of z)b[S]||(b[S]=y)}window.__HANDLER_APP_FLOW=f,window.__HANDLER_SCREEN_INDEX={screenToInstances:m,instanceToScreen:b},window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}}function o(g,f){if(fl){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${ct.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let v=" ".repeat(y);b.children.forEach((w,E)=>{if(w&&w.zIndex===9999){console.log(`${v}[RESPONSIVE] Skipping debug border (zIndex 9999)`);return}if(w&&w.scale){let j=w.scale.x||1,z=w.scale.y||1;w.__originalScale||(w.__originalScale={x:j,y:z},console.log(`${v}[RESPONSIVE] Stored original scale for child[${E}]: ${j.toFixed(3)}, ${z.toFixed(3)}`));let S=w.__originalScale.x*ct.scale,P=w.__originalScale.y*ct.scale;typeof w.scale.set=="function"?w.scale.set(S,P):(w.scale.x=S,w.scale.y=P),console.log(`${v}[RESPONSIVE] Child[${E}] scale: ${j.toFixed(3)}\u2192${w.scale.x.toFixed(3)} (type: ${w.constructor.name})`),m(w,y+1)}else w&&console.log(`${v}[RESPONSIVE] Child[${E}] has no scale (type: ${w.constructor.name})`)})};var h=m;console.log("[RESPONSIVE] Applying scale to PIXI stage children"),m(g.stage)}else console.warn("[RESPONSIVE] No app.stage found!");console.log("[REDDEBUG] Debug border left unscaled (fixed boundaries)"),console.log("[RESPONSIVE] ===== GLOBAL RESPONSIVE SCALING COMPLETE =====")}function l(g){if(g!==void 0){ct.scale=g,console.log(`[RESPONSIVE] Updated global scale multiplier to: ${g.toFixed(3)}`);let f=window.gameApp,h=window.gameObjectManager;f&&h?(o(f,h),f.renderer&&(f.renderer.render(f.stage),console.log("[RESPONSIVE] Forced PIXI renderer update"))):console.warn(`[RESPONSIVE] No gameApp (${!!f}) or gameObjectManager (${!!h}) found in window for live update`)}}window.updateGlobalResponsiveMultipliers=l,$e.start()},Ir=async()=>{var e,t,n,i;console.log("[PREVIEW] Restarting game in 1 seconds...");let s=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(s){let a=((t=s.getDisplayObject)==null?void 0:t.call(s))||s;a&&a.scale&&console.log(`[CHARACTER] Before restart - Current scale - x: ${((n=a.scale.x)!=null?n:1).toFixed(3)}, y: ${((i=a.scale.y)!=null?i:1).toFixed(3)}`)}if(de){de.notifyGameDestroyed();try{Ma&&Ma()}catch(a){console.warn("Failed to clear responsive elements",a)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let a=de.getGameContainer(),r=window.gameObjectManager;if(r&&typeof r.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),r.clear()),Oe){try{Oe.destroy(!0,{children:!0,texture:!1})}catch(o){console.warn("[PREVIEW] Destroy warning:",o)}Oe=null}window.gameApp=null,window.gameObjectManager=null,a&&(a.innerHTML="");try{typeof Ft.resetScene=="function"&&Ft.resetScene()}catch(o){console.warn("Asset reset failed",o)}setTimeout(()=>{xe("scene.main").then(o=>{window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=W(o)),Pa(a,o,Nt).then(l=>{Oe=l.app,window.gameApp=Oe,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=ni({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:Ft})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}de&&de.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{$e.start()}catch{}})})},100)},1e3)}};wn();J();var pe={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Pr=1.25,_r={fontFamily:"Inter, system-ui, sans-serif"};var ai=class{constructor(e={}){this.currentProgress=0;var t;this.currentProgress=(t=e.progress)!=null?t:0,this.container=this.createContainer()}createContainer(){let e=document.createElement("div");e.className="handler-loading-screen",e.style.cssText=`
2426
+ `,this.setupEventListeners(e),e}setupEventListeners(e){var f,m,b,y,v,w,E,P;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",M=>{if(this.viewMode==="compare")return;let x=M.target.value;this.setDevice(x)});let i=e.querySelector("#theme-select");i==null||i.addEventListener("change",M=>{let x=M.target.value;this.setTheme(x)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(M=>{M.addEventListener("click",()=>{let x=M.dataset.viewToggle;x&&this.setViewMode(x)})}),Array.from(e.querySelectorAll("[data-layout-toggle]")).forEach(M=>{M.addEventListener("click",()=>{let x=M.dataset.layoutToggle;x&&this.setLayoutMode(x)})});let r=e.querySelector("#scene-toggle");r==null||r.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!this.sceneVisiblePreference),this.updateSceneVisibility())});let o=e.querySelector("#scene-hide-btn");o==null||o.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!1),this.updateSceneVisibility())}),(f=e.querySelector("#rotate-btn"))==null||f.addEventListener("click",()=>this.toggleRotation()),(m=e.querySelector("#zoom-in-btn"))==null||m.addEventListener("click",()=>this.adjustUserZoom(.1)),(b=e.querySelector("#zoom-out-btn"))==null||b.addEventListener("click",()=>this.adjustUserZoom(-.1)),(y=e.querySelector("#refresh-btn"))==null||y.addEventListener("click",()=>this.refresh());let l=e.querySelector("#bottom-dock"),c=e.querySelector("#bottom-dock-resize");l&&c&&this.makeBottomDockResizable(l,c);let d=Array.from(e.querySelectorAll(".bottom-dock-tab"));d.forEach(M=>{M.addEventListener("click",()=>{let x=M.dataset.dockTab;if(!x)return;d.forEach(O=>O.classList.remove("active")),M.classList.add("active"),Array.from(e.querySelectorAll(".bottom-dock-panel")).forEach(O=>{let T=O.dataset.dockPanel;O.classList.toggle("active",T===x)})})}),(v=e.querySelector("#console-clear"))==null||v.addEventListener("click",()=>this.clearConsole()),(w=e.querySelector("#corner-zoom-in-btn"))==null||w.addEventListener("click",()=>this.adjustUserZoom(.1)),(E=e.querySelector("#corner-zoom-out-btn"))==null||E.addEventListener("click",()=>this.adjustUserZoom(-.1)),(P=e.querySelector("#corner-grab-btn"))==null||P.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)});let p=e.querySelector(".scene-panel.scene-objects"),u=p==null?void 0:p.querySelector("[data-panel-resize-v]");p&&u&&this.makeSidebarResizable(p,u,"left");let g=e.querySelector(".debug-workbench"),h=g==null?void 0:g.querySelector("#workbench-resize-v");g&&h&&this.makeSidebarResizable(g,h,"right")}applyDeviceFrameStyles(){Object.assign(this.frameDragger.style,{display:"flex",justifyContent:"center",alignItems:"center",transform:"translate(0px, 0px)",touchAction:"none"}),Object.assign(this.frameWrapper.style,{display:"flex",justifyContent:"center",alignItems:"center",transformOrigin:"center center",transition:"transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)",boxShadow:"var(--ui-shadow-strong)",borderRadius:"0px",willChange:"transform"}),Object.assign(this.deviceFrame.style,{overflow:"hidden",position:"relative",borderRadius:"0px"}),Object.assign(this.gameContainer.style,{position:"relative",overflow:"hidden",minWidth:"0px",minHeight:"0px"})}setupObserversAndListeners(){this.resizeObserver=new ResizeObserver(()=>{this.resizeListenersDisabled||this.scheduleFit()}),this.resizeObserver.observe(this.previewContainer),window.addEventListener("resize",this.onWindowResize,{passive:!0})}scheduleFit(){this.rafFitHandle&&cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=requestAnimationFrame(()=>{this.rafFitHandle=null,this.fitToScreen()})}applyPresetDimensions(){let e=this.getEffectivePreset(),t=`${e.width}px`,i=`${e.height}px`;this.deviceFrame.style.width=t,this.deviceFrame.style.height=i,this.gameContainer.style.width=t,this.gameContainer.style.height=i,this.gameContainer.style.maxWidth=t,this.gameContainer.style.maxHeight=i,this.gameContainer.style.minWidth=t,this.gameContainer.style.minHeight=i,this.gameContainer.dataset.screenWidth=String(e.width),this.gameContainer.dataset.screenHeight=String(e.height),this.container.style.setProperty("--preview-screen-width",String(e.width)),this.container.style.setProperty("--preview-screen-height",String(e.height))}fitToScreen(e){if(!this.previewContainer)return;let t=this.getEffectivePreset(),i=this.getFitBounds(),n=Math.max(0,i.width),a=Math.max(0,i.height);if(n<=0||a<=0)return;this.applyPresetDimensions(),this.viewMode==="compare"&&this.applyCompareDimensions();let r=n/t.width,o=a/t.height;if(this.autoScale=Math.max(.01,Math.min(r,o)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}e!=null&&e.keepVisibleScale&&e.keepVisibleScale>0&&(this.userScaleMultiplier=e.keepVisibleScale/this.autoScale),this.applyTransform(),this.viewMode==="compare"&&this.fitCompareGhosts(),requestAnimationFrame(()=>this.updatePanelPositions()),this.emitScreenChange()}applyTransform(){let e=this.autoScale*this.userScaleMultiplier;this.frameWrapper.style.transform=`scale(${e})`;let t=this.container.querySelector("#zoom-label");t&&(t.textContent=`${Math.round(e*100)}%`),requestAnimationFrame(()=>this.updatePanelPositions())}applyFrameDrag(){this.frameDragger.style.transform=`translate(${this.frameDragOffsetX}px, ${this.frameDragOffsetY}px)`,requestAnimationFrame(()=>this.updatePanelPositions())}updatePanelPositions(){if(!this.gameReady||this.viewMode==="compare")return;let e=this.container.querySelector('[data-panel="scene-tools-corner"]'),t=this.container.querySelector('[data-panel="nudge-panel"]');if(this.layoutMode==="fixed"){let i=this.gameViewPane||this.container.querySelector(".preview-container");i&&(e&&e.parentElement!==i&&i.appendChild(e),t&&t.parentElement!==i&&i.appendChild(t))}else{let i=this.container.querySelector(".preview-main");i&&(e&&e.parentElement!==i&&i.appendChild(e),t&&t.parentElement!==i&&i.appendChild(t))}e&&(e.style.zIndex="100"),t&&(t.style.position="absolute",t.style.left="50%",t.style.top="16px",t.style.transform="translateX(calc(-50% + 200px))",t.style.zIndex="100")}setupFrameDragging(){this.frameDragger.addEventListener("pointerdown",e=>{let t=!this.gameContainer.contains(e.target);!this.isSpaceKeyPressed&&!t||e.button===0&&(e.preventDefault(),this.frameDragActive=!0,this.frameDragStartX=e.clientX,this.frameDragStartY=e.clientY,this.frameDragOriginX=this.frameDragOffsetX,this.frameDragOriginY=this.frameDragOffsetY,window.addEventListener("pointermove",this.onFrameDragMove),window.addEventListener("pointerup",this.onFrameDragEnd))})}setupSpaceKeyListener(){window.addEventListener("keydown",e=>{e.code==="Space"&&!this.isInputFocused()&&(this.isSpaceKeyPressed||(this.isSpaceKeyPressed=!0,this.updateDragCursor(),e.preventDefault()))}),window.addEventListener("keyup",e=>{e.code==="Space"&&(this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd())}),window.addEventListener("blur",()=>{this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd()})}isInputFocused(){let e=document.activeElement;if(!e)return!1;let t=e.tagName.toLowerCase();return t==="input"||t==="textarea"||t==="select"||e.isContentEditable}setupShortcutListeners(){window.addEventListener("keydown",e=>{if(this.isInputFocused())return;let t=navigator.platform.toUpperCase().indexOf("MAC")>=0,i=e.ctrlKey||e.metaKey,n=e.shiftKey;if(i&&e.key==="s"&&!n){e.preventDefault();let a=document.querySelector("#apply-current-btn");a&&a.getAttribute("disabled")===null&&a.click();return}if(i&&e.key==="z"&&!n){e.preventDefault(),hi();return}if(i&&(e.key==="z"&&n||e.key==="y"&&!n)){e.preventDefault(),fi();return}})}setupUnsavedChangesIndicator(){let e=this.container.querySelector("#preview-save-shortcut-text");e&&(e.textContent=`(${this.getShortcutKey()} + S)`),window.addEventListener("config:changed",()=>{this.updateUnsavedChangesIndicator()}),this.updateUnsavedChangesIndicator();let t=this.container.querySelector("#preview-save-btn");t==null||t.addEventListener("click",()=>{let i=document.querySelector("#apply-current-btn");i&&i.getAttribute("disabled")===null&&i.click()})}updateUnsavedChangesIndicator(){let t=Me().hasChanges;if(t!==this.hasUnsavedChanges){this.hasUnsavedChanges=t;let i=this.container.querySelector("#preview-unsaved-star"),n=this.container.querySelector("#preview-save-btn");i&&(i.style.display=t?"inline-block":"none"),n&&(n.style.display=t?"inline-flex":"none")}}updateDragCursor(){this.isSpaceKeyPressed?(this.frameDragger.style.cursor="grab",this.frameDragActive&&(this.frameDragger.style.cursor="grabbing")):this.frameDragger.style.cursor=""}adjustUserZoom(e){this.userScaleMultiplier=Math.max(.1,Math.min(6,this.userScaleMultiplier+e)),this.applyTransform(),this.emitScreenChange()}toggleRotation(){var t,i;if(this.viewMode==="compare")return;let e=this.autoScale*this.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepVisibleScale:e}),(i=(t=this.options).onDeviceChange)==null||i.call(t,this.getEffectivePreset()),this.emitScreenChange()}emitScreenChange(){if(!this.gameReady)return;let e=this.getEffectivePreset(),t={width:e.width,height:e.height,dpr:Math.max(1,Math.floor(window.devicePixelRatio||1)),presetId:e.id,isLandscape:this.isLandscape};if(window.dispatchEvent(new CustomEvent("handler-preview:screen",{detail:t})),this.viewMode==="compare"&&this.refreshCompareSnapshots(),this.isInitialized&&this.isMounted&&this.gameReady){let i=window.gameApp;if(!(i!=null&&i.renderer))return;this.ignoreNextWindowResize=!0,window.dispatchEvent(new Event("resize"))}}safeStringify(e){var i;let t=new WeakSet;try{return JSON.stringify(e,(n,a)=>{if(typeof a=="object"&&a!==null){if(t.has(a))return"[Circular]";t.add(a)}return a},2)}catch{try{if(e&&((i=e.constructor)!=null&&i.name))return`[object ${e.constructor.name}]`}catch{}return String(e)}}setupConsoleInterceptor(){let e=(t,...i)=>{let n=i.map(r=>typeof r=="object"?this.safeStringify(r):String(r)).join(" ");this.consoleMessages.push({type:t,message:n,timestamp:new Date}),this.appendConsoleMessage(this.consoleMessages[this.consoleMessages.length-1]);let a=this.container.querySelector("#console-badge");if(a){let r=this.consoleMessages.filter(o=>o.type==="error").length;a.textContent=r>0?`${r}!`:"0",a.classList.toggle("has-errors",r>0)}};console.log=(...t)=>{this.originalConsole.log(...t),e("log",...t)},console.warn=(...t)=>{this.originalConsole.warn(...t),e("warn",...t)},console.error=(...t)=>{this.originalConsole.error(...t),e("error",...t)},console.info=(...t)=>{this.originalConsole.info(...t),e("info",...t)}}appendConsoleMessage(e){let t=this.container.querySelector("#console-messages");if(!t)return;let i=document.createElement("div");i.className=`console-msg type-${e.type}`;let n=e.timestamp.toLocaleTimeString();i.innerHTML=`<span class="time">${this.escapeHtml(n)}</span> <pre>${this.escapeHtml(e.message)}</pre>`,t.appendChild(i),t.scrollTop=t.scrollHeight}escapeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}toggleConsole(e){var t;if(this.layoutMode==="fixed"){let i=this.container.querySelector('[data-dock-tab="console"]');if(i){i.click();let n=this.container.querySelector("#bottom-dock");n==null||n.classList.remove("hidden")}return}this.isConsoleOpen=e!=null?e:!this.isConsoleOpen,(t=this.consolePanel)==null||t.classList.toggle("closed",!this.isConsoleOpen)}clearConsole(){this.consoleMessages=[];let e=this.container.querySelector("#console-messages");e&&(e.innerHTML="");let t=this.container.querySelector("#console-badge");t&&(t.textContent="0")}setupCompareViewports(){Array.from(this.container.querySelectorAll("[data-viewport]")).forEach(t=>{let i=t.dataset.viewport;if(!i)return;let n=this.comparePresets.find(p=>p.id===i);if(!n)return;let a=t.querySelector("[data-compare-slot]"),r=t.querySelector("[data-compare-ghost]"),o=t.querySelector("[data-compare-wrapper]"),l=t.querySelector("[data-compare-frame]"),c=t.querySelector("[data-compare-snapshot]"),d=t.querySelector("[data-compare-focus]");!a||!r||!o||!l||(t.addEventListener("click",p=>{let u=p.target;if(u!=null&&u.closest("[data-compare-focus]")){p.preventDefault(),this.activateCompareViewport(i);return}t.classList.contains("is-active")||this.activateCompareViewport(i)}),this.compareViewports.set(i,{preset:n,root:t,slot:a,ghost:r,wrapper:o,frame:l,canvas:c,focus:d}))})}setViewMode(e){if(this.viewMode===e)return;this.viewMode=e,this.container.classList.toggle("compare-mode",e==="compare"),this.singleStage.classList.toggle("hidden",e!=="single"),this.compareStage.classList.toggle("hidden",e!=="compare");let t=this.container.querySelector("#device-select");t&&(t.disabled=e==="compare");let i=this.container.querySelector("#rotate-btn");i&&(i.disabled=e==="compare");let n=this.container.querySelector("#scene-toggle");if(n&&(n.disabled=e==="compare"),this.updateViewToggleUI(),e==="compare"){this.lastSinglePresetId=this.currentPreset.id,this.activateCompareViewport(this.activeCompareId),this.refreshCompareSnapshots(),this.startCompareSnapshots(),this.updateSceneVisibility();return}this.stopCompareSnapshots(),this.singleStage.appendChild(this.frameDragger),this.setDevice(this.lastSinglePresetId,{suppressCallback:!0}),this.fitToScreen(),this.updateSceneVisibility()}updateViewToggleUI(){Array.from(this.container.querySelectorAll("[data-view-toggle]")).forEach(t=>{t.classList.toggle("active",t.dataset.viewToggle===this.viewMode)})}activateCompareViewport(e){var a,r;let t=this.compareViewports.get(e);if(!t)return;let i=this.autoScale*this.userScaleMultiplier,n=this.activeCompareId;n&&n!==e&&this.captureCompareSnapshot(n),this.activeCompareId=e,this.currentPreset=t.preset,this.isLandscape=!1,t.slot.appendChild(this.frameDragger),this.frameDragOffsetX=0,this.frameDragOffsetY=0,this.applyFrameDrag(),this.compareViewports.forEach((o,l)=>{o.root.classList.toggle("is-active",l===e),o.ghost.classList.toggle("hidden",l===e),o.focus&&(o.focus.textContent=l===e?"Live":"Focus")}),this.applyPresetDimensions(),this.applyCompareDimensions(),this.fitToScreen({keepVisibleScale:i}),(r=(a=this.options).onDeviceChange)==null||r.call(a,this.getEffectivePreset())}applyCompareDimensions(){this.compareViewports.forEach(e=>{let t=e.preset,i=`${t.width}px`,n=`${t.height}px`;e.frame.style.width=i,e.frame.style.height=n,e.canvas&&(e.canvas.width=t.width,e.canvas.height=t.height)})}fitCompareGhosts(){this.compareViewports.forEach(e=>{let t=e.root.querySelector(".compare-body");if(!t)return;let i=Math.max(0,t.clientWidth-24),n=Math.max(0,t.clientHeight-24);if(i<=0||n<=0)return;let a=i/e.preset.width,r=n/e.preset.height,o=Math.max(.01,Math.min(a,r));e.wrapper.style.transform=`scale(${o})`})}captureCompareSnapshot(e){let t=this.compareViewports.get(e);if(!(t!=null&&t.canvas))return;let i=this.gameContainer.querySelector("canvas");if(!i)return;let n=t.canvas.getContext("2d");if(!n)return;let a=t.canvas.width,r=t.canvas.height,o=Math.min(a/i.width,r/i.height),l=i.width*o,c=i.height*o,d=(a-l)/2,p=(r-c)/2;n.clearRect(0,0,a,r),n.drawImage(i,d,p,l,c)}refreshCompareSnapshots(){this.compareViewports.forEach((e,t)=>{t!==this.activeCompareId&&this.captureCompareSnapshot(t)})}startCompareSnapshots(){this.compareSnapshotTimer||(this.compareSnapshotTimer=window.setInterval(()=>{this.viewMode==="compare"&&this.refreshCompareSnapshots()},500))}stopCompareSnapshots(){this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null)}getFitBounds(){if(this.viewMode!=="compare"){let i=this.gameViewPane||this.previewContainer;return{width:i.clientWidth-40,height:i.clientHeight-40}}let e=this.compareViewports.get(this.activeCompareId),t=e==null?void 0:e.root.querySelector(".compare-body");return t?{width:t.clientWidth-24,height:t.clientHeight-24}:{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40}}mustQuery(e){let t=this.container.querySelector(e);if(!t)throw new Error(`PreviewShell missing element: ${e}`);return t}};function Oa(s={}){let e=new ln(s);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}K();function Ra(s){try{if(s&&typeof s.keys=="function")return Array.from(s.keys())}catch{}return[]}function Mr(s){var e;return s?((e=s.getDisplayObject)==null?void 0:e.call(s))||s.pixiObject||s:null}function yl(s,e){if(!s||!(e!=null&&e.interaction))return;let t=e.interaction,i=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);s.eventMode=i?"static":"none",s.interactive=i,i&&(s.cursor=t.draggable?"move":"pointer")}function jr(s,e){var l,c,d;if(!s||!e)return;let t=e.transform||{};yl(s,e);let i=t.position||{},n=t.offset||{},a=(typeof i.x=="number"?i.x:0)+(typeof n.x=="number"?n.x:0),r=(typeof i.y=="number"?i.y:0)+(typeof n.y=="number"?n.y:0);(l=s.position)!=null&&l.set?s.position.set(a,r):(typeof s.x=="number"&&(s.x=a),typeof s.y=="number"&&(s.y=r)),typeof t.scale=="number"&&((c=s.scale)!=null&&c.set?s.scale.set(t.scale):s.scale&&(s.scale.x=t.scale,s.scale.y=t.scale));let o=t.anchor;if(o&&((d=s.anchor)!=null&&d.set)){let p=null;typeof window!="undefined"&&window.resolveAnchorVec2?p=window.resolveAnchorVec2(o):typeof o=="object"&&o.x!==void 0&&o.y!==void 0?p=o:Array.isArray(o)&&o.length===2&&(p={x:o[0],y:o[1]}),p&&typeof p.x=="number"&&typeof p.y=="number"&&s.anchor.set(p.x,p.y)}}function _r(s){if(typeof window=="undefined")return;let e=s==null?void 0:s.objects,t=Ra(e),i=a=>{try{let r=window.__HANDLER_ACTIVE_SCREEN;if(!r||r==="all")return a;let o=window.__HANDLER_SCREEN_INDEX,l=o==null?void 0:o.instanceToScreen;return l?a.filter(c=>l[c]===r):a}catch{return a}};window.__editableObjectConfigs=e;let n=new Map;t.forEach(a=>n.set(a,[a])),window.__editableObjectInstances=n,window.refreshEditableConfigIndex=()=>_r(window.__editableConfig),window.getEditableObjectList=()=>{var a;return i(Ra((a=window.__editableConfig)==null?void 0:a.objects))},window.getEditableObjectListAll=()=>{var a;return Ra((a=window.__editableConfig)==null?void 0:a.objects)},window.getEditableObjectConfig=a=>{var d,p,u,g,h;let r=(g=(u=(p=(d=window.__editableConfig)==null?void 0:d.objects)==null?void 0:p.get)==null?void 0:u.call(p,a))!=null?g:null,o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return r;let l=window.__HANDLER_SCREEN_INDEX,c=(h=l==null?void 0:l.instanceToScreen)==null?void 0:h[a];return c&&c===o?r:null},window.getEditableEngineConfig=()=>{let a=window.__editableConfig;if(console.log("[BRIDGE] getEditableEngineConfig called, cfg present:",!!a),!a)return null;if(a.engine&&a.objects instanceof Map){console.log("[BRIDGE] Detected ObjectCentricConfig, flattening...");let r={...a.engine,objects:a.objects,scene:a.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(r.assets||{})),r}return a}}function vl(){if(typeof window=="undefined")return;let s=t=>{let i=String(t||"").trim();return i?/^(data:|blob:|https?:)/.test(i)||i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`:""},e=async(t,i)=>{var a,r,o;let n=s(i);if(n)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),Promise.resolve().then(()=>(st(),Ps))]),d=Date.now(),p=/^(data:|blob:)/.test(n)?n:n+(n.includes("?")?`&t=${d}`:`?t=${d}`),u=await l.load(p);if(!u)return;c[t]=u;let g=window.CustomAssets;(a=g==null?void 0:g[t])!=null&&a.texture&&(g[t].texture=u);let h=window.gameObjectManager,f=(r=h==null?void 0:h.get)==null?void 0:r.call(h,t);if(f){let m=((o=f.getDisplayObject)==null?void 0:o.call(f))||f.pixiObject||f.pixi||f;if(m!=null&&m.texture)m.texture=u;else if(m!=null&&m.children){let b=m.children.find(y=>y==null?void 0:y.texture);b!=null&&b.texture&&(b.texture=u)}}}catch(l){console.warn("[LIVE-EDIT] Failed to reload Pixi texture for",t,l)}};window.applyLiveEditOverrides=t=>{try{let i=Z();Array.isArray(i)&&i.length&&(window.__editableConfig=t,Pe(i,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let i=Z();Array.isArray(i)&&i.length&&(window.__editableConfig=t,Pe(i,{silent:!0,persist:!1}))}catch{}},window.applyEditableEngineConfig=t=>{let i=window.__editableConfig;if(!(i!=null&&i.engine))return;let n=[];if(t.runtime)for(let[a,r]of Object.entries(t.runtime))n.push({path:`runtime.${a}`,value:r});if(t.assets)for(let[a,r]of Object.entries(t.assets))n.push({path:`assets.${a}`,value:r}),typeof r=="string"&&e(a,r);if(t.splash)for(let[a,r]of Object.entries(t.splash))n.push({path:`splash.${a}`,value:r});if(t.loading)for(let[a,r]of Object.entries(t.loading))n.push({path:`loading.${a}`,value:r});if(t.start)for(let[a,r]of Object.entries(t.start))n.push({path:`start.${a}`,value:r});n.length&&Pe(n,{silent:!0,persist:!0,emitEvent:!0})}}function cn(s){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:i}=s;t&&(t.onObjectRebuildRequired=async(a,r)=>{console.log(`[LIVE-EDIT] \u{1F3D7}\uFE0F Rebuilding object ${a} due to type change...`);let o=t.get(a),l=o==null?void 0:o.pixiObject,c=l==null?void 0:l.parent,d=c==null?void 0:c.children.indexOf(l);o?t.remove(a):l&&l.destroy();let p=window.gameApp,u=await de.create(a,r,p);c&&(d!==void 0&&d!==-1?c.addChildAt(u,d):c.addChild(u));let g=t.create(a,u);return console.log(`[LIVE-EDIT] \u2705 Rebuild complete for ${a}`),g}),typeof window!="undefined"&&(vl(),window.applyEditableObjectConfig=(a,r)=>{var o,l,c;console.log("[LIVE-EDIT] \u{1F504} applyEditableObjectConfig called for:",a);try{let d=window.__editableConfig;(o=d==null?void 0:d.objects)!=null&&o.set&&(d.objects.set(a,r),console.log("[LIVE-EDIT] \u2705 Updated config in __editableConfig"));let p=(l=t==null?void 0:t.get)==null?void 0:l.call(t,a);if(console.log("[LIVE-EDIT] gameObject found?",!!p),p&&(console.log("[LIVE-EDIT] gameObject type:",(c=p.constructor)==null?void 0:c.name),console.log("[LIVE-EDIT] has updateConfig?",typeof p.updateConfig=="function"),console.log("[LIVE-EDIT] has onConfigUpdate?",typeof p.onConfigUpdate=="function")),p&&typeof p.updateConfig=="function")console.log("[LIVE-EDIT] \u2705 Calling updateConfig()"),p.updateConfig(r);else if(p&&typeof p.onConfigUpdate=="function")console.log("[LIVE-EDIT] \u2705 Calling onConfigUpdate()"),p.onConfigUpdate();else{console.log("[LIVE-EDIT] \u26A0\uFE0F No updateConfig or onConfigUpdate, applying transform directly");let u=Mr(p);jr(u,r)}}catch(d){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",d)}});let n={async applyObjectConfig(a,r){var d,p;console.log("[BRIDGE] \u{1F504} applyObjectConfig called for:",a);let o=e();(d=o==null?void 0:o.objects)!=null&&d.set&&(o.objects.set(a,r),console.log("[BRIDGE] \u2705 Updated config"));let l=(p=t==null?void 0:t.get)==null?void 0:p.call(t,a);if(console.log("[BRIDGE] gameObject found?",!!l),l&&(console.log("[BRIDGE] has updateConfig?",typeof l.updateConfig=="function"),console.log("[BRIDGE] has onConfigUpdate?",typeof l.onConfigUpdate=="function")),l&&typeof l.updateConfig=="function")console.log("[BRIDGE] \u2705 Calling updateConfig()"),l.updateConfig(r);else if(l&&typeof l.onConfigUpdate=="function")console.log("[BRIDGE] \u2705 Calling onConfigUpdate()"),l.onConfigUpdate();else{console.log("[BRIDGE] \u26A0\uFE0F Applying transform directly");let u=Mr(l);jr(u,r)}let c=[a];i==null||i(a,r,c)},rebuildIndexes(){let a=e();typeof window!="undefined"&&(window.__editableConfig=a,_r(a))}};return n.rebuildIndexes(),n}K();var zr=tt(require("lottie-web"),1);Tn(Cn);typeof window!="undefined"&&!window.lottie&&(window.lottie=zr.default);var ut=null,wl=async()=>{if(!ut){let s=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(s==null?void 0:s["handler.config"])||(s==null?void 0:s["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let i=atob(e.split(",")[1]);ut=JSON.parse(i)}else ut=JSON.parse(e);return ut}catch(i){console.warn("[CONFIG] Failed to parse inline handler.config.json:",i)}ut=await(await fetch("./handler.config.json")).json()}return ut},Ha,qt,$r,gt,$a,Da;function xl(s){Ha=s.initGame,qt=s.CustomAssets,$r=s.updateScreenState,gt=s.globalResponsiveMultipliers,$a=s.layout,Da=s.clearResponsiveElements}var dn="web_embed",Gt="https://example.com",Or={profile_id:dn},ze=null,ge=null,za={width:0,height:0},Sl=!0,El=async()=>{var c,d,p,u;document.title="Handler Pixi Game";let s=await wl();Or={...s.ids||{},profile_id:dn},Gt=s.destination_url||((d=(c=s.export_profiles)==null?void 0:c[dn])==null?void 0:d.destination_url)||Gt,He.init({ids:Or,profile:dn,destinationUrl:Gt});let e=He.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),ge=Oa({onDeviceChange:h=>{console.log(`[PREVIEW] Device switched to ${h.width}x${h.height}, restarting game...`),Rr()},onRefresh:Rr});let g=ge.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",h=>{var v,w,E,P,M,x,_,O,T,A,j;let f=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=h.detail;if(za.width=b,za.height=y,$r(b,y),!(!f||!f.renderer)){m&&o(f,m);try{f.renderer.resize(b,y);let k=f.view;k&&(k.style.width="100%",k.style.height="100%",k.style.display="block")}catch(k){console.warn("[SCREEN] Error resizing renderer:",k);return}if(t&&m&&$a)try{let k=(v=window.__mainContainer)!=null?v:f.stage,C=(_=(x=(P=window.__tutorialLabel)!=null?P:(E=(w=m.get("label_1"))==null?void 0:w.getDisplayObject)==null?void 0:E.call(w))!=null?x:(M=m.get("label_1"))==null?void 0:M.pixiObject)!=null?_:m.get("label_1"),S=m.get("background_1"),I=(j=(A=(T=window.__background)!=null?T:(O=S==null?void 0:S.getDisplayObject)==null?void 0:O.call(S))!=null?A:S==null?void 0:S.pixiObject)!=null?j:S;if(k){let L=k===f.stage;$a({mainContainer:k,label:C,background:I,backgroundTexture:(I==null?void 0:I.texture)||null,app:f},t,0,za,m,{skipMainContainerTransform:L})}}catch(k){console.warn("[SCREEN] Error in layout:",k)}}})}let t=await Ce("scene.main");window.__editableConfig=t,r(),window.__editableConfigBaseline||(window.__editableConfigBaseline=Y(t),console.log("[BOOTSTRAP] Frozen config baseline for persistence")),(u=(p=t.engine.runtime)==null?void 0:p.layout)!=null&&u.design_width_portrait||(console.warn("[BOOTSTRAP] Config layout missing, retrying..."),await new Promise(g=>setTimeout(g,100)),t=await Ce("scene.main"));let i=await Ha(e,t,Gt,ge);ze=i.app;let n=i.gameObjectManager;window.gameApp=ze,window.gameObjectManager=n;try{window.__liveEditBridge=cn({getConfig:()=>window.__editableConfig,gameObjectManager:n,assets:qt})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}ge&&ge.notifyGameLoaded();let a=window.__debugScale;a&&typeof a=="number"&&(gt.scale=a,console.log(`[DEBUG] Applied persisted debug scale: ${a}`)),o(ze,n);async function r(){try{let g=async y=>{let v=y.startsWith("/")?y:`/${y}`,w=await fetch(v,{cache:"no-cache"});if(!w.ok)return null;let E=await w.text();try{return JSON.parse(E)}catch{return null}},h=await g("configs/flow/app.flow.json");if(!h||typeof h!="object")return;let f=h.screens;if(!f||typeof f!="object")return;let m={},b={};for(let[y,v]of Object.entries(f)){let w=v==null?void 0:v.source;if(typeof w!="string")continue;let E=await g(w),P=E==null?void 0:E.elements;if(!Array.isArray(P))continue;let M=P.map(x=>x==null?void 0:x.instance_id).filter(x=>typeof x=="string");m[y]=M;for(let x of M)b[x]||(b[x]=y)}window.__HANDLER_APP_FLOW=h,window.__HANDLER_SCREEN_INDEX={screenToInstances:m,instanceToScreen:b},window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}}function o(g,h){if(Sl){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${gt.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let v=" ".repeat(y);b.children.forEach((w,E)=>{if(w&&w.zIndex===9999){console.log(`${v}[RESPONSIVE] Skipping debug border (zIndex 9999)`);return}if(w&&w.scale){let P=w.scale.x||1,M=w.scale.y||1;w.__originalScale||(w.__originalScale={x:P,y:M},console.log(`${v}[RESPONSIVE] Stored original scale for child[${E}]: ${P.toFixed(3)}, ${M.toFixed(3)}`));let x=w.__originalScale.x*gt.scale,_=w.__originalScale.y*gt.scale;typeof w.scale.set=="function"?w.scale.set(x,_):(w.scale.x=x,w.scale.y=_),console.log(`${v}[RESPONSIVE] Child[${E}] scale: ${P.toFixed(3)}\u2192${w.scale.x.toFixed(3)} (type: ${w.constructor.name})`),m(w,y+1)}else w&&console.log(`${v}[RESPONSIVE] Child[${E}] has no scale (type: ${w.constructor.name})`)})};var f=m;console.log("[RESPONSIVE] Applying scale to PIXI stage children"),m(g.stage)}else console.warn("[RESPONSIVE] No app.stage found!");console.log("[REDDEBUG] Debug border left unscaled (fixed boundaries)"),console.log("[RESPONSIVE] ===== GLOBAL RESPONSIVE SCALING COMPLETE =====")}function l(g){if(g!==void 0){gt.scale=g,console.log(`[RESPONSIVE] Updated global scale multiplier to: ${g.toFixed(3)}`);let h=window.gameApp,f=window.gameObjectManager;h&&f?(o(h,f),h.renderer&&(h.renderer.render(h.stage),console.log("[RESPONSIVE] Forced PIXI renderer update"))):console.warn(`[RESPONSIVE] No gameApp (${!!h}) or gameObjectManager (${!!f}) found in window for live update`)}}window.updateGlobalResponsiveMultipliers=l,He.start()},Rr=async()=>{var e,t,i,n;console.log("[PREVIEW] Restarting game in 1 seconds...");let s=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(s){let a=((t=s.getDisplayObject)==null?void 0:t.call(s))||s;a&&a.scale&&console.log(`[CHARACTER] Before restart - Current scale - x: ${((i=a.scale.x)!=null?i:1).toFixed(3)}, y: ${((n=a.scale.y)!=null?n:1).toFixed(3)}`)}if(ge){ge.notifyGameDestroyed();try{Da&&Da()}catch(a){console.warn("Failed to clear responsive elements",a)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let a=ge.getGameContainer(),r=window.gameObjectManager;if(r&&typeof r.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),r.clear()),ze){try{ze.destroy(!0,{children:!0,texture:!1})}catch(o){console.warn("[PREVIEW] Destroy warning:",o)}ze=null}window.gameApp=null,window.gameObjectManager=null,a&&(a.innerHTML="");try{typeof qt.resetScene=="function"&&qt.resetScene()}catch(o){console.warn("Asset reset failed",o)}setTimeout(()=>{Ce("scene.main").then(o=>{window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Y(o)),Ha(a,o,Gt).then(l=>{ze=l.app,window.gameApp=ze,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=cn({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:qt})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}ge&&ge.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{He.start()}catch{}})})},100)},1e3)}};Si();K();var he={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Dr=1.25,Hr={fontFamily:"Inter, system-ui, sans-serif"};var pn=class{constructor(e={}){this.currentProgress=0;var t;this.currentProgress=(t=e.progress)!=null?t:0,this.container=this.createContainer()}createContainer(){let e=document.createElement("div");e.className="handler-loading-screen",e.style.cssText=`
2322
2427
  position: fixed;
2323
2428
  inset: 0;
2324
2429
  display: flex;
@@ -2327,21 +2432,21 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2327
2432
  z-index: 50;
2328
2433
  user-select: none;
2329
2434
  overflow: hidden;
2330
- background-color: ${pe.background};
2435
+ background-color: ${he.background};
2331
2436
  `;let t=document.createElement("div");t.style.cssText=`
2332
2437
  position: relative;
2333
2438
  width: 288px;
2334
2439
  display: flex;
2335
2440
  flex-direction: column;
2336
2441
  align-items: center;
2337
- `;let n=document.createElement("div");n.style.cssText=`
2442
+ `;let i=document.createElement("div");i.style.cssText=`
2338
2443
  position: absolute;
2339
2444
  top: -96px;
2340
2445
  width: 96px;
2341
2446
  height: 96px;
2342
2447
  opacity: 0.9;
2343
2448
  transform: scale(0.9);
2344
- `,n.innerHTML='<div class="boxLoading"></div>',t.appendChild(n);let i=document.createElement("div");i.style.cssText=`
2449
+ `,i.innerHTML='<div class="boxLoading"></div>',t.appendChild(i);let n=document.createElement("div");n.style.cssText=`
2345
2450
  width: 100%;
2346
2451
  position: relative;
2347
2452
  display: flex;
@@ -2357,12 +2462,12 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2357
2462
  font-size: 12px;
2358
2463
  font-weight: 900;
2359
2464
  letter-spacing: 0.15em;
2360
- color: ${pe.ink};
2465
+ color: ${he.ink};
2361
2466
  `,r.innerHTML='LOADING<span class="loading-dots" style="animation: pulse 1.5s infinite;">..</span>',this.progressText=document.createElement("span"),this.progressText.style.cssText=`
2362
2467
  font-size: 10px;
2363
2468
  font-family: monospace;
2364
2469
  font-weight: bold;
2365
- color: ${pe.primaryAccent};
2470
+ color: ${he.primaryAccent};
2366
2471
  `,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,a.appendChild(r),a.appendChild(this.progressText);let o=document.createElement("div");o.style.cssText=`
2367
2472
  height: 4px;
2368
2473
  width: 100%;
@@ -2377,7 +2482,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2377
2482
  border-radius: 9999px;
2378
2483
  position: relative;
2379
2484
  width: ${this.currentProgress}%;
2380
- background-color: ${pe.primaryAccent};
2485
+ background-color: ${he.primaryAccent};
2381
2486
  `;let l=document.createElement("div");l.style.cssText=`
2382
2487
  position: absolute;
2383
2488
  inset: 0;
@@ -2397,7 +2502,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2397
2502
  width: 1.5px;
2398
2503
  background-color: black;
2399
2504
  height: ${u%4===0?"6px":"2px"};
2400
- `,c.appendChild(g)}i.appendChild(a),i.appendChild(o),i.appendChild(c);let d=document.createElement("div");return d.id="handler-load-centered",d.style.cssText=`
2505
+ `,c.appendChild(g)}n.appendChild(a),n.appendChild(o),n.appendChild(c);let d=document.createElement("div");return d.id="handler-load-centered",d.style.cssText=`
2401
2506
  position: absolute;
2402
2507
  top: 48px;
2403
2508
  width: 600px;
@@ -2406,7 +2511,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2406
2511
  left: 50%;
2407
2512
  transform: translateX(-50%);
2408
2513
  overflow: visible;
2409
- `,"HANDLER".split("").forEach((u,g)=>{let f=document.createElement("div");f.textContent=u,f.style.cssText=`
2514
+ `,"HANDLER".split("").forEach((u,g)=>{let h=document.createElement("div");h.textContent=u,h.style.cssText=`
2410
2515
  position: absolute;
2411
2516
  width: 28px;
2412
2517
  height: 40px;
@@ -2416,12 +2521,12 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2416
2521
  font-size: 24px;
2417
2522
  letter-spacing: -0.05em;
2418
2523
  animation: handlerMove 2.5s linear infinite;
2419
- color: ${pe.ink};
2524
+ color: ${he.ink};
2420
2525
  display: flex;
2421
2526
  align-items: center;
2422
2527
  justify-content: center;
2423
2528
  animation-delay: ${[1.05,.875,.7,.525,.35,.175,0][g]}s;
2424
- `,d.appendChild(f)}),t.appendChild(i),t.appendChild(d),this.authSeq=document.createElement("div"),this.authSeq.style.cssText=`
2529
+ `,d.appendChild(h)}),t.appendChild(n),t.appendChild(d),this.authSeq=document.createElement("div"),this.authSeq.style.cssText=`
2425
2530
  position: absolute;
2426
2531
  bottom: 48px;
2427
2532
  font-size: 8px;
@@ -2429,7 +2534,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2429
2534
  letter-spacing: 0.3em;
2430
2535
  opacity: 0.2;
2431
2536
  text-transform: uppercase;
2432
- color: ${pe.ink};
2537
+ color: ${he.ink};
2433
2538
  `,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`,e.appendChild(t),e.appendChild(this.authSeq),this.injectStyles(),e}injectStyles(){if(document.getElementById("handler-loading-screen-styles"))return;let e=document.createElement("style");e.id="handler-loading-screen-styles",e.textContent=`
2434
2539
  /* Box Loading Styles */
2435
2540
  .boxLoading {
@@ -2460,7 +2565,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2460
2565
  content: '';
2461
2566
  width: 50px;
2462
2567
  height: 50px;
2463
- background: ${pe.primaryAccent};
2568
+ background: ${he.primaryAccent};
2464
2569
  animation: animate 0.5s linear infinite;
2465
2570
  position: absolute;
2466
2571
  top: 0;
@@ -2517,7 +2622,7 @@ Style guidelines: ${n.summary}`;this.promptInput.value=i,this.currentPrompt=i}}c
2517
2622
  0%, 100% { opacity: 1; }
2518
2623
  50% { opacity: 0.3; }
2519
2624
  }
2520
- `,document.head.appendChild(e)}setProgress(e){this.currentProgress=Math.max(0,Math.min(100,e)),this.progressBar.style.width=`${this.currentProgress}%`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`}mount(e=document.body){e.appendChild(this.container)}unmount(){this.container.parentElement&&this.container.parentElement.removeChild(this.container)}getElement(){return this.container}};var _a=Qa.version,bl=new Set(["init","boot","view","ready","start","pause","resume","complete","error","engagement","first_interaction","retry","cta_show","cta_click","cta_dismiss","clickout","conversion","session_time","level_time","load_time","level_start","level_complete","level_fail","checkpoint","reward","tutorial_start","tutorial_complete","tutorial_skip","ab_assign","fps","memory","asset_load_start","asset_load_complete"]);Za();var Nr={mechanic_id:"TODO_mechanic_id",variant_id:"TODO_variant_id",deployment_id:"TODO_deployment_id",export_id:"TODO_export_id",profile_id:"TODO_profile_id",instance_id:"default"},Fr=Math.random().toString(36).slice(2),ut=null,dt={...Nr},Br="web_embed",$a={},Ut,Oa=!1,Bt=!1,qt=!1,Ur=!1,Fa=1,ri=0,ci=!1,Se=!1,pt="",gt=Math.floor(window.innerWidth),ht=Math.floor(window.innerHeight),Da=gt>ht,Ce=!1,Gt=!1,Or=!1,Rr=!1,Ra=!1,oi=null,We=null,Ha=!1,Na=!1,si=new Map;function Gr(){if(!We)return null;let s=Date.now()-We;return!Number.isFinite(s)||s<0?null:s}function za(s){if(Ha)return;let e=Gr();e!==null&&(Ha=!0,$("session_time",{duration_ms:e,reason:s}))}function zr(){if(ut)return ut;let s=document.createElement("div");return s.id="handler-root",s.setAttribute("data-handler-root","true"),document.body.appendChild(s),ut=s,s}function li(s){switch(s){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return s}}function qr(s,e){return{event_name:s,ts:Date.now(),session_id:Fr,deployment_id:dt.deployment_id,variant_id:dt.variant_id,export_profile_id:dt.profile_id,instance_id:dt.instance_id||"default",env:Br==="mraid"?"mraid":"web",attribution:Ut,payload:e}}function $(s,e){let t=li(s),n=qr(t,e);hi(n,!!$a.analytics),Jt(t,n),t!==s&&Jt(s,n)}function Vt(){oi&&(oi(gt,ht),oi=null)}function ft(s){Fa=s,$("volume",s)}function mt(s){s&&(Ur=!0),!qt&&(qt=!0,$("pause"),ft(0))}function Wt(s){!s&&Ur||qt&&(qt=!1,$("resume"),ft(Fa))}function Re(s,e){gt=Math.floor(s||window.innerWidth),ht=Math.floor(e||window.innerHeight),Da=gt>ht,$("resize",{width:gt,height:ht})}function yl(){if(ps())try{let s=mraid.getMaxSize();Re(s.width,s.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?Wt():mt()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();Re(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();ft(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&ft(t>0?1:0)}),mraid.addEventListener("error",(t,n)=>{console.warn("mraid error:",t,"action:",n)}),ci=!0,mraid.isViewable()&&mraid.getState()!=="hidden")Ce=!0,$("boot"),$("view"),$("ready"),Se=!0,Vt();else{let t=()=>{Ce=!0,$("boot"),$("view"),$("ready"),Se=!0,Vt()};mraid.addEventListener("ready",t)}}catch(s){console.warn("MRAID hook skipped",s)}}function vl(){if(us())try{let s=dapi.getScreenSize();Re(s.width,s.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?Wt():mt()}),dapi.addEventListener("adResized",t=>{let n=dapi.getScreenSize();Re(t.width||n.width,t.height||n.height)});let e=dapi.getAudioVolume();if(ft(e?1:0),dapi.addEventListener("audioVolumeChange",t=>ft(t?1:0)),ci=!0,dapi.isViewable())Ce=!0,$("boot"),$("view"),$("ready"),Se=!0,Vt();else{let t=()=>{Ce=!0,$("boot"),$("view"),$("ready"),Se=!0,Vt()};dapi.addEventListener("ready",t)}}catch(s){console.warn("DAPI hook skipped",s)}}function $r(){let s=()=>{Ce||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(Ce=!0,$("boot"),$("view"),$("ready"),Se=!0,Vt(),Gt&&(Gt=!1,re.start()))};window.addEventListener("resize",()=>Re()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(Wt(),s()):mt()}),document.readyState==="complete"||document.readyState==="interactive"?s():window.addEventListener("load",s),ci=!0}function wl(){let s=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Or=!0),!(Or&&e instanceof MouseEvent)&&(ri+=1,Na||(Na=!0,$("first_interaction",{count:ri})),$("interaction",ri))};document.addEventListener("mousedown",s),document.addEventListener("touchstart",s)}function Dr(s){var n,i,a,r,o,l,c,d,p,u,g,f;let e=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none";if((typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed")==="google")try{(n=window.ExitApi)==null||n.exit();return}catch{}if(e==="mraid"&&typeof mraid!="undefined")mraid.open(s||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(tt())(a=(i=window.TJ_API)==null?void 0:i.click)==null||a.call(i);else if(gs())(o=(r=window.FbPlayableAd)==null?void 0:r.onCTAClick)==null||o.call(r);else if(bs())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(ms())try{(p=(d=window.smxTracking)==null?void 0:d.redirect)==null||p.call(d)}catch(h){console.warn("Smadex redirect failed",h)}else if(hs()){let h=window.ExitApi;h&&typeof h.exit=="function"?h.exit(s||pt||""):s&&window.open(s)}else et()?(u=window.install)==null||u.call(window):fs()?(g=window.openAppStore)==null||g.call(window):fi()?(f=parent==null?void 0:parent.postMessage)==null||f.call(parent,"download","*"):s&&window.open(s)}function xl(){let s=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let n=new Image;n.src=t};if(s==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;Q("view",()=>e(t.mraid_viewable)),Q("start",()=>e(t.game_viewable)),Q("engagement",()=>e(t.engagement));let n=()=>e(t.complete);Q("complete",n),Xt("engagement",i=>{var a;((a=i==null?void 0:i.payload)==null?void 0:a.count)>3&&n()}),Q("cta_click",()=>e(t.click))}else if(s==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;Q("view",()=>e(t.Ad_Load_Start)),Q("start",()=>e(t.Ad_Viewable)),Q("engagement",()=>e(t.First_Engagement)),Q("complete",()=>e(t.Gameplay_Complete)),Q("cta_click",()=>e(t.DSP_Click)),Q("start",()=>{[5,10,15,20,25,30].forEach(n=>setTimeout(()=>e(t[`Spent_${n}_Seconds`]),n*1e3))})}}function El(){if(!tt())return;let s=window.TJ_API;s&&s.setPlayableAPI&&s.setPlayableAPI({skipAd:()=>{try{re.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function Hr(){var e,t,n;let s=window.TJ_API;(e=s==null?void 0:s.objectiveComplete)==null||e.call(s),(t=s==null?void 0:s.playableFinished)==null||t.call(s),(n=s==null?void 0:s.gameplayFinished)==null||n.call(s)}function Sl(){et()&&(window.mintGameStart=()=>{Wt(!0),Re()},window.mintGameClose=()=>{mt(!0)})}function Cl(){if(!mi())return;let s=window.NUC;!s||!s.trigger||(re.on("cta_click",()=>{var e,t;return(t=(e=s.trigger).convert)==null?void 0:t.call(e,pt)}),re.on("complete",()=>{var e,t;return(t=(e=s.trigger).tryAgain)==null?void 0:t.call(e)}))}var re={init(s={},e){var t;if(Br=s.profile||"web_embed",$a=s.consent||{},dt={...Nr,...s.ids||{}},ut=s.rootEl||ut,Ut=void 0,qa((t=s.telemetry)!=null&&t.endpoint?s.telemetry:null),We=null,Ha=!1,Na=!1,si.clear(),pt=s.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(oi=e),$("init"),document.body.oncontextmenu=()=>!1,zr(),Tl(ut),ys(),yl(),vl(),!ci){if(document.readyState==="complete")$r();else if(!Rr){Rr=!0;let n=()=>{$r(),window.removeEventListener("load",n),document.removeEventListener("DOMContentLoaded",n)};window.addEventListener("load",n),document.addEventListener("DOMContentLoaded",n)}}wl(),xl(),El(),Sl(),Cl(),console.log(`%c @handler/playable-sdk %c v${_a} `,"background: var(--ui-console-info); color: var(--ui-white); font-size: 14px; padding: 4px 8px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;","background: var(--ui-console-bg); color: var(--ui-console-text); font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"),Ce&&!Se&&($("boot"),$("view"),$("ready"),Gt&&(Gt=!1,re.start()),Se=!0),Se=Ce},getRoot(){return zr()},get version(){return _a},get maxWidth(){return gt},get maxHeight(){return ht},get isLandscape(){return Da},get isReady(){return Se},get isStarted(){return Oa},get isPaused(){return qt},get isFinished(){return Bt},get volume(){return Fa},get interactions(){return ri},on(s,e){Xt(li(s),e)},off(s,e){gi(li(s),e)},start(){var s,e;if(!Oa){if(!Ce){Gt=!0;return}if(Oa=!0,We||(We=Date.now()),$("start"),Re(),et())mt(),(s=window.gameReady)==null||s.call(window);else if(tt()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:Da?"landscape":"portrait",buildID:_a})}}},finish(){var s,e;Bt||(Bt=!0,$("complete"),za("complete"),et()?(s=window.gameEnd)==null||s.call(window):fi()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):tt()&&Hr())},install(s){if(!Bt){Bt=!0,tt()?(Hr(),setTimeout(()=>re.install(s),300)):($("complete"),setTimeout(()=>re.install(s),0));return}Ra||(Ra=!0,setTimeout(()=>Ra=!1,500),$("cta_click"),$("conversion"),za("cta"),Dr(s||pt))},emit(s,e){let t=li(s);if(!bl.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${s} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let n=qr(t,e);hi(n,!!$a.analytics),Jt(t,n)},gameStart(){re.start()},gameEnd(){re.finish()},ctaClick(s,e){$("cta_click",{url:s||pt,manual:!0}),(e==null?void 0:e.open)!==!1&&Dr(s||pt)},ctaShow(s){$("cta_show",s)},ctaDismiss(s){$("cta_dismiss",s)},getGameTimeMs(){return Gr()},endSession(s="manual"){za(s)},setAttribution(s){Ut=s},abTest(s,e){if(!s)throw new Error("abTest requires experimentId");if(!Array.isArray(e)||e.length<2)throw new Error("abTest requires at least 2 variants");let t=Math.abs(Al(`${Fr}:${s}`))%e.length,n=e[t];return Ut={...Ut||{},experiment_id:s},dt.variant_id=n,$("ab_assign",{experiment_id:s,variant_id:n}),n},levelStart(s,e){We||(We=Date.now()),$("level_start",{level_id:s,...e})},levelComplete(s,e){$("level_complete",{level_id:s,...e})},levelFail(s,e){$("level_fail",{level_id:s,...e})},checkpoint(s,e){$("checkpoint",{checkpoint_id:s,...e})},reward(s,e){$("reward",{reward_id:s,...e})},tutorialStart(s,e){$("tutorial_start",{step_id:s,...e})},tutorialComplete(s,e){$("tutorial_complete",{step_id:s,...e})},tutorialSkip(s,e){$("tutorial_skip",{step_id:s,...e})},timerStart(s){s&&si.set(s,Date.now())},timerEnd(s,e="custom",t){if(!s)return;let n=si.get(s);if(!n)return;si.delete(s);let i=Date.now()-n;if(!(!Number.isFinite(i)||i<0)){if(e==="custom"){$("engagement",{action:"timer",key:s,duration_ms:i,...t});return}$(e,{key:s,duration_ms:i,...t})}},fps(s,e){$("fps",{value:s,...e})},memory(s,e){$("memory",{bytes:s,...e})},assetLoadStart(s,e){$("asset_load_start",{asset_id:s,...e})},assetLoadComplete(s,e){$("asset_load_complete",{asset_id:s,...e})},reportError(s,e,t){$("error",{code:s,message:e,...t})},retry(){var s,e,t;if(et())(s=window.gameRetry)==null||s.call(window);else if(mi()){let n=window.NUC;(t=(e=n==null?void 0:n.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}$("engagement",{action:"retry"})},pause(){mt(!0)},resume(){Wt(!0)},resize(s,e){Re(s,e)}},$e=re;function Al(s){let e=2166136261;for(let t=0;t<s.length;t++)e^=s.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function Tl(s){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
2625
+ `,document.head.appendChild(e)}setProgress(e){this.currentProgress=Math.max(0,Math.min(100,e)),this.progressBar.style.width=`${this.currentProgress}%`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`}mount(e=document.body){e.appendChild(this.container)}unmount(){this.container.parentElement&&this.container.parentElement.removeChild(this.container)}getElement(){return this.container}};var Na=rs.version,Cl=new Set(["init","boot","view","ready","start","pause","resume","complete","error","engagement","first_interaction","retry","cta_show","cta_click","cta_dismiss","clickout","conversion","session_time","level_time","load_time","level_start","level_complete","level_fail","checkpoint","reward","tutorial_start","tutorial_complete","tutorial_skip","ab_assign","fps","memory","asset_load_start","asset_load_complete"]);ss();var Vr={mechanic_id:"TODO_mechanic_id",variant_id:"TODO_variant_id",deployment_id:"TODO_deployment_id",export_id:"TODO_export_id",profile_id:"TODO_profile_id",instance_id:"default"},Wr=Math.random().toString(36).slice(2),mt=null,ht={...Vr},Yr="web_embed",Ga={},Wt,Fa=!1,Vt=!1,Kt=!1,Kr=!1,Ya=1,gn=0,mn=!1,Te=!1,ft="",bt=Math.floor(window.innerWidth),yt=Math.floor(window.innerHeight),qa=bt>yt,Le=!1,Yt=!1,Nr=!1,Fr=!1,Ba=!1,hn=null,Xe=null,Va=!1,Wa=!1,un=new Map;function Xr(){if(!Xe)return null;let s=Date.now()-Xe;return!Number.isFinite(s)||s<0?null:s}function Ua(s){if(Va)return;let e=Xr();e!==null&&(Va=!0,$("session_time",{duration_ms:e,reason:s}))}function Br(){if(mt)return mt;let s=document.createElement("div");return s.id="handler-root",s.setAttribute("data-handler-root","true"),document.body.appendChild(s),mt=s,s}function fn(s){switch(s){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return s}}function Jr(s,e){return{event_name:s,ts:Date.now(),session_id:Wr,deployment_id:ht.deployment_id,variant_id:ht.variant_id,export_profile_id:ht.profile_id,instance_id:ht.instance_id||"default",env:Yr==="mraid"?"mraid":"web",attribution:Wt,payload:e}}function $(s,e){let t=fn(s),i=Jr(t,e);xn(i,!!Ga.analytics),ti(t,i),t!==s&&ti(s,i)}function Xt(){hn&&(hn(bt,yt),hn=null)}function vt(s){Ya=s,$("volume",s)}function wt(s){s&&(Kr=!0),!Kt&&(Kt=!0,$("pause"),vt(0))}function Jt(s){!s&&Kr||Kt&&(Kt=!1,$("resume"),vt(Ya))}function $e(s,e){bt=Math.floor(s||window.innerWidth),yt=Math.floor(e||window.innerHeight),qa=bt>yt,$("resize",{width:bt,height:yt})}function Al(){if(ys())try{let s=mraid.getMaxSize();$e(s.width,s.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?Jt():wt()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();$e(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();vt(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&vt(t>0?1:0)}),mraid.addEventListener("error",(t,i)=>{console.warn("mraid error:",t,"action:",i)}),mn=!0,mraid.isViewable()&&mraid.getState()!=="hidden")Le=!0,$("boot"),$("view"),$("ready"),Te=!0,Xt();else{let t=()=>{Le=!0,$("boot"),$("view"),$("ready"),Te=!0,Xt()};mraid.addEventListener("ready",t)}}catch(s){console.warn("MRAID hook skipped",s)}}function Tl(){if(vs())try{let s=dapi.getScreenSize();$e(s.width,s.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?Jt():wt()}),dapi.addEventListener("adResized",t=>{let i=dapi.getScreenSize();$e(t.width||i.width,t.height||i.height)});let e=dapi.getAudioVolume();if(vt(e?1:0),dapi.addEventListener("audioVolumeChange",t=>vt(t?1:0)),mn=!0,dapi.isViewable())Le=!0,$("boot"),$("view"),$("ready"),Te=!0,Xt();else{let t=()=>{Le=!0,$("boot"),$("view"),$("ready"),Te=!0,Xt()};dapi.addEventListener("ready",t)}}catch(s){console.warn("DAPI hook skipped",s)}}function Ur(){let s=()=>{Le||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(Le=!0,$("boot"),$("view"),$("ready"),Te=!0,Xt(),Yt&&(Yt=!1,le.start()))};window.addEventListener("resize",()=>$e()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(Jt(),s()):wt()}),document.readyState==="complete"||document.readyState==="interactive"?s():window.addEventListener("load",s),mn=!0}function Ll(){let s=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Nr=!0),!(Nr&&e instanceof MouseEvent)&&(gn+=1,Wa||(Wa=!0,$("first_interaction",{count:gn})),$("interaction",gn))};document.addEventListener("mousedown",s),document.addEventListener("touchstart",s)}function Gr(s){var i,n,a,r,o,l,c,d,p,u,g,h;let e=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none";if((typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed")==="google")try{(i=window.ExitApi)==null||i.exit();return}catch{}if(e==="mraid"&&typeof mraid!="undefined")mraid.open(s||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(at())(a=(n=window.TJ_API)==null?void 0:n.click)==null||a.call(n);else if(ws())(o=(r=window.FbPlayableAd)==null?void 0:r.onCTAClick)==null||o.call(r);else if(Cs())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(Es())try{(p=(d=window.smxTracking)==null?void 0:d.redirect)==null||p.call(d)}catch(f){console.warn("Smadex redirect failed",f)}else if(xs()){let f=window.ExitApi;f&&typeof f.exit=="function"?f.exit(s||ft||""):s&&window.open(s)}else nt()?(u=window.install)==null||u.call(window):Ss()?(g=window.openAppStore)==null||g.call(window):Sn()?(h=parent==null?void 0:parent.postMessage)==null||h.call(parent,"download","*"):s&&window.open(s)}function kl(){let s=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let i=new Image;i.src=t};if(s==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;ee("view",()=>e(t.mraid_viewable)),ee("start",()=>e(t.game_viewable)),ee("engagement",()=>e(t.engagement));let i=()=>e(t.complete);ee("complete",i),ei("engagement",n=>{var a;((a=n==null?void 0:n.payload)==null?void 0:a.count)>3&&i()}),ee("cta_click",()=>e(t.click))}else if(s==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;ee("view",()=>e(t.Ad_Load_Start)),ee("start",()=>e(t.Ad_Viewable)),ee("engagement",()=>e(t.First_Engagement)),ee("complete",()=>e(t.Gameplay_Complete)),ee("cta_click",()=>e(t.DSP_Click)),ee("start",()=>{[5,10,15,20,25,30].forEach(i=>setTimeout(()=>e(t[`Spent_${i}_Seconds`]),i*1e3))})}}function Il(){if(!at())return;let s=window.TJ_API;s&&s.setPlayableAPI&&s.setPlayableAPI({skipAd:()=>{try{le.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function qr(){var e,t,i;let s=window.TJ_API;(e=s==null?void 0:s.objectiveComplete)==null||e.call(s),(t=s==null?void 0:s.playableFinished)==null||t.call(s),(i=s==null?void 0:s.gameplayFinished)==null||i.call(s)}function Pl(){nt()&&(window.mintGameStart=()=>{Jt(!0),$e()},window.mintGameClose=()=>{wt(!0)})}function Ml(){if(!En())return;let s=window.NUC;!s||!s.trigger||(le.on("cta_click",()=>{var e,t;return(t=(e=s.trigger).convert)==null?void 0:t.call(e,ft)}),le.on("complete",()=>{var e,t;return(t=(e=s.trigger).tryAgain)==null?void 0:t.call(e)}))}var le={init(s={},e){var t;if(Yr=s.profile||"web_embed",Ga=s.consent||{},ht={...Vr,...s.ids||{}},mt=s.rootEl||mt,Wt=void 0,Za((t=s.telemetry)!=null&&t.endpoint?s.telemetry:null),Xe=null,Va=!1,Wa=!1,un.clear(),ft=s.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(hn=e),$("init"),document.body.oncontextmenu=()=>!1,Br(),_l(mt),As(),Al(),Tl(),!mn){if(document.readyState==="complete")Ur();else if(!Fr){Fr=!0;let i=()=>{Ur(),window.removeEventListener("load",i),document.removeEventListener("DOMContentLoaded",i)};window.addEventListener("load",i),document.addEventListener("DOMContentLoaded",i)}}Ll(),kl(),Il(),Pl(),Ml(),console.log(`%c @handler/playable-sdk %c v${Na} `,"background: var(--ui-console-info); color: var(--ui-white); font-size: 14px; padding: 4px 8px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;","background: var(--ui-console-bg); color: var(--ui-console-text); font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"),Le&&!Te&&($("boot"),$("view"),$("ready"),Yt&&(Yt=!1,le.start()),Te=!0),Te=Le},getRoot(){return Br()},get version(){return Na},get maxWidth(){return bt},get maxHeight(){return yt},get isLandscape(){return qa},get isReady(){return Te},get isStarted(){return Fa},get isPaused(){return Kt},get isFinished(){return Vt},get volume(){return Ya},get interactions(){return gn},on(s,e){ei(fn(s),e)},off(s,e){wn(fn(s),e)},start(){var s,e;if(!Fa){if(!Le){Yt=!0;return}if(Fa=!0,Xe||(Xe=Date.now()),$("start"),$e(),nt())wt(),(s=window.gameReady)==null||s.call(window);else if(at()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:qa?"landscape":"portrait",buildID:Na})}}},finish(){var s,e;Vt||(Vt=!0,$("complete"),Ua("complete"),nt()?(s=window.gameEnd)==null||s.call(window):Sn()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):at()&&qr())},install(s){if(!Vt){Vt=!0,at()?(qr(),setTimeout(()=>le.install(s),300)):($("complete"),setTimeout(()=>le.install(s),0));return}Ba||(Ba=!0,setTimeout(()=>Ba=!1,500),$("cta_click"),$("conversion"),Ua("cta"),Gr(s||ft))},emit(s,e){let t=fn(s);if(!Cl.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${s} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let i=Jr(t,e);xn(i,!!Ga.analytics),ti(t,i)},gameStart(){le.start()},gameEnd(){le.finish()},ctaClick(s,e){$("cta_click",{url:s||ft,manual:!0}),(e==null?void 0:e.open)!==!1&&Gr(s||ft)},ctaShow(s){$("cta_show",s)},ctaDismiss(s){$("cta_dismiss",s)},getGameTimeMs(){return Xr()},endSession(s="manual"){Ua(s)},setAttribution(s){Wt=s},abTest(s,e){if(!s)throw new Error("abTest requires experimentId");if(!Array.isArray(e)||e.length<2)throw new Error("abTest requires at least 2 variants");let t=Math.abs(jl(`${Wr}:${s}`))%e.length,i=e[t];return Wt={...Wt||{},experiment_id:s},ht.variant_id=i,$("ab_assign",{experiment_id:s,variant_id:i}),i},levelStart(s,e){Xe||(Xe=Date.now()),$("level_start",{level_id:s,...e})},levelComplete(s,e){$("level_complete",{level_id:s,...e})},levelFail(s,e){$("level_fail",{level_id:s,...e})},checkpoint(s,e){$("checkpoint",{checkpoint_id:s,...e})},reward(s,e){$("reward",{reward_id:s,...e})},tutorialStart(s,e){$("tutorial_start",{step_id:s,...e})},tutorialComplete(s,e){$("tutorial_complete",{step_id:s,...e})},tutorialSkip(s,e){$("tutorial_skip",{step_id:s,...e})},timerStart(s){s&&un.set(s,Date.now())},timerEnd(s,e="custom",t){if(!s)return;let i=un.get(s);if(!i)return;un.delete(s);let n=Date.now()-i;if(!(!Number.isFinite(n)||n<0)){if(e==="custom"){$("engagement",{action:"timer",key:s,duration_ms:n,...t});return}$(e,{key:s,duration_ms:n,...t})}},fps(s,e){$("fps",{value:s,...e})},memory(s,e){$("memory",{bytes:s,...e})},assetLoadStart(s,e){$("asset_load_start",{asset_id:s,...e})},assetLoadComplete(s,e){$("asset_load_complete",{asset_id:s,...e})},reportError(s,e,t){$("error",{code:s,message:e,...t})},retry(){var s,e,t;if(nt())(s=window.gameRetry)==null||s.call(window);else if(En()){let i=window.NUC;(t=(e=i==null?void 0:i.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}$("engagement",{action:"retry"})},pause(){wt(!0)},resume(){Jt(!0)},resize(s,e){$e(s,e)}},He=le;function jl(s){let e=2166136261;for(let t=0;t<s.length;t++)e^=s.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function _l(s){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
2521
2626
  (function(){
2522
2627
  var events = ['touchstart','touchend','mousedown','keydown'];
2523
2628
  function unlock(){