handler-playable-sdk 1.0.95 → 1.0.100

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.
Files changed (47) hide show
  1. package/dist/{ConfigOverride-2HOZGV6G.js → ConfigOverride-LXAXXQFN.js} +1 -1
  2. package/dist/chunk-IPD3J7SW.js +1 -0
  3. package/dist/chunk-KICIZV5O.js +1 -0
  4. package/dist/{chunk-LWADIFXM.js → chunk-Z5ZUUE46.js} +124 -121
  5. package/dist/cli/brand-dna.mjs +1 -1
  6. package/dist/cli/canva-import.mjs +1 -1
  7. package/dist/cli/cleanup-assets.mjs +1 -1
  8. package/dist/cli/fix-scales.mjs +1 -1
  9. package/dist/cli/index.js +1 -1
  10. package/dist/cli/screen-helper.mjs +1 -1
  11. package/dist/cli/setup-library.mjs +1 -1
  12. package/dist/cli/student-helper/add-logic.mjs +1 -1
  13. package/dist/cli/student-helper/add-object.mjs +1 -1
  14. package/dist/cli/student-helper/arg-parsing.mjs +1 -1
  15. package/dist/cli/student-helper/asset-registry.mjs +1 -1
  16. package/dist/cli/student-helper/bullet-system.mjs +1 -1
  17. package/dist/cli/student-helper/collectable-system.mjs +1 -1
  18. package/dist/cli/student-helper/constants.mjs +1 -1
  19. package/dist/cli/student-helper/drag-snap-couples.mjs +1 -1
  20. package/dist/cli/student-helper/endgame-screen.mjs +1 -1
  21. package/dist/cli/student-helper/fs-io.mjs +1 -1
  22. package/dist/cli/student-helper/logic-defaults.mjs +1 -1
  23. package/dist/cli/student-helper/print-help.mjs +1 -1
  24. package/dist/cli/student-helper/prompts.mjs +1 -1
  25. package/dist/cli/student-helper/scratch-card.mjs +1 -1
  26. package/dist/cli/student-helper/screen-utils.mjs +1 -1
  27. package/dist/cli/student-helper/snippets.mjs +1 -1
  28. package/dist/cli/student-helper/start-screen.mjs +1 -1
  29. package/dist/cli/student-helper/swerve-collect.mjs +1 -1
  30. package/dist/cli/student-helper/tap-destroy.mjs +1 -1
  31. package/dist/cli/student-helper/template-packs.mjs +1 -1
  32. package/dist/cli/student-helper.mjs +1 -1
  33. package/dist/cli/sync-screens.mjs +1 -1
  34. package/dist/cli/validate-assets.mjs +1 -1
  35. package/dist/cli/validate.mjs +1 -1
  36. package/dist/{config-VJNOXXCC.js → config-ZZMHC7I4.js} +1 -1
  37. package/dist/index.cjs +151 -148
  38. package/dist/index.d.cts +1 -3
  39. package/dist/index.d.ts +1 -3
  40. package/dist/index.js +1 -1
  41. package/dist/pixi/index.cjs +12 -12
  42. package/dist/pixi/index.js +1 -1
  43. package/dist/three/index.cjs +22 -22
  44. package/dist/three/index.js +1 -1
  45. package/package.json +1 -1
  46. package/dist/chunk-5IRAZMOA.js +0 -1
  47. package/dist/chunk-SDFKEAA5.js +0 -1
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var ar=Object.create;var ni=Object.defineProperty;var sr=Object.getOwnPropertyDescriptor;var or=Object.getOwnPropertyNames;var rr=Object.getPrototypeOf,lr=Object.prototype.hasOwnProperty;var be=(o,e)=>()=>(o&&(e=o(o=0)),e);var at=(o,e)=>{for(var t in e)ni(o,t,{get:e[t],enumerable:!0})},Za=(o,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of or(e))!lr.call(o,n)&&n!==t&&ni(o,n,{get:()=>e[n],enumerable:!(i=sr(e,n))||i.enumerable});return o};var st=(o,e,t)=>(t=o!=null?ar(rr(o)):{},Za(e||!o||!o.__esModule?ni(t,"default",{value:o,enumerable:!0}):t,o)),cr=o=>Za(ni({},"__esModule",{value:!0}),o);var ce,ri=be(()=>{"use strict";ce=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()}};ce.store=new Map});function br(){var o,e;try{let t=typeof window!="undefined"&&(document.querySelector('script[src*="inline-assets.js"]')||((e=(o=document.querySelector("script"))==null?void 0:o.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 yr(){try{if(typeof window!="undefined"){let o=await fetch("./build-settings.json");if(o.ok){let e=await o.json();return console.log("[AssetLoader] Loaded build settings:",e),e}}}catch{}return null}function vr(){try{if(typeof window!="undefined"){let o=new XMLHttpRequest;if(o.open("GET","./build-settings.json",!1),o.send(),o.status===200&&o.responseText){let e=JSON.parse(o.responseText);return console.log("[AssetLoader] Loaded build settings (sync):",e),e}}}catch{}return null}async function wr(){if(console.log(`[AssetLoader] getInlineAssets() called - Effective mode: ${Y}`),Object.keys(Ce).length>0)return console.log("[AssetLoader] Returning cached inline assets:",Object.keys(Ce)),Ce;if(typeof window!="undefined"&&window.INLINE_ASSETS)return console.log("[AssetLoader] Using pre-loaded INLINE_ASSETS from window:",Object.keys(window.INLINE_ASSETS)),Ce={...window.INLINE_ASSETS},Ce;if(!(Y==="publish"&&ye!==!1))return console.log("[AssetLoader] Inline assets disabled for this build mode."),Ce;if(!jn){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),jn=(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 s=new Function("return "+a)();return console.log("[AssetLoader] Parsed inline assets:",Object.keys(s)),s}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 Ce=await jn,console.log("[AssetLoader] Final inline assets cache:",Object.keys(Ce)),Ce}function _n(o){return o===null||typeof o!="object"||(Object.freeze(o),Object.values(o).forEach(e=>_n(e))),o}function xr(o=64,e=64,t=16711680){let i=document.createElement("canvas");i.width=o,i.height=e;let n=i.getContext("2d");return n.fillStyle=`#${t.toString(16).padStart(6,"0")}`,n.fillRect(0,0,o,e),n.strokeStyle="#000",n.strokeRect(0,0,o,e),n.fillStyle="#fff",n.font="10px sans-serif",n.textAlign="center",n.fillText("MISSING",o/2,e/2),Ae.Texture.from(i)}function On(o,e){Ms.set(o,e)}var Ae,Is,Ps,Ye,Y,ye,$e,Ce,jn,Ms,We,li=be(()=>{"use strict";Ae=require("pixi.js");ri();Is=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Ps=br(),Ye=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,Y=Ps?"publish":Is,ye=Ye==null?void 0:Ye.assetsInlined;Ye!=null&&Ye.buildMode&&(Y=Ye.buildMode,console.log(`[AssetLoader] Build mode overridden by inline settings: ${Y}`));$e=vr();$e!=null&&$e.buildMode&&(Y=$e.buildMode,console.log(`[AssetLoader] Build mode overridden by sync settings: ${Y}`));($e==null?void 0:$e.assetsInlined)!==void 0&&(ye=$e.assetsInlined);yr().then(o=>{o!=null&&o.buildMode&&o.buildMode!==Y&&(Y=o.buildMode,console.log(`[AssetLoader] Build mode overridden by settings: ${Y}`)),(o==null?void 0:o.assetsInlined)!==void 0&&(ye=o.assetsInlined)}).catch(()=>{});console.log(`[AssetLoader] MODULE LOADED - Compile: ${Is}, Runtime: ${Ps?"publish":"dev"}, Effective: ${Y}`);Ce={},jn=null;Ms=new Map;We=class{static async load(e,t,i,n){let a=`${e}:${t.path}`,s=ce.get(a);if(s!==void 0)return s;console.log(`[AssetLoader] Loading asset: ${e}, type: ${t.type}, Effective mode: ${Y}`),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 r=await wr(),l=r[e];if(!l&&n&&(l=r[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];r[u]&&(l=r[u],console.log(`[AssetLoader] Found inline data for ${e} using assetName: ${u}`))}}if(console.log("[AssetLoader] Inline data for",e,":",l?"FOUND":"NOT FOUND"),Y==="publish"&&ye!==!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=Ms.get(t.type);if(d)try{let p=await d(t.path,l,e,i);return ce.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=_n(p);break;default:throw new Error(`Unknown asset type: ${t.type}`)}return ce.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}}static async loadImage(e,t){let i=Y==="publish",n=i&&ye!==!1;if(console.log(`[AssetLoader] loadImage - Effective mode: ${Y}, 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 Ae.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 Ae.Assets.load(t)}catch(a){return console.error("[AssetLoader] Failed to load texture from data URI, falling back to path:",a),await Ae.Assets.load(e)}return await Ae.Assets.load(e)}static async loadJSON(e,t){let i=Y==="publish",n=i&&ye!==!1;if(console.log(`[AssetLoader] loadJSON - Effective mode: ${Y}, 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 s=atob(t.split(",")[1]);return JSON.parse(s)}return JSON.parse(t)}if(t){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let s=atob(t.split(",")[1]);return JSON.parse(s)}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(Y==="dev"){let a=t==="image"?xr():_n({__placeholder:!0,type:t});return ce.set(e+":"+((i==null?void 0:i.path)||"missing"),a),a}throw i}};On("image",async(o,e)=>{let t=Y==="publish",i=t&&ye!==!1,n=Y==="brand",a=t&&ye===!1;if(console.log(`[AssetLoader] registerType('image') - Effective mode: ${Y}, 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: ${o}`);if(typeof e!="string"||!e.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof e}`);return Ae.Assets.load(e)}let s=o;return(n||a)&&o&&!o.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(s=o,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${o}" as-is`)):(s=`assets/${o}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${o}" -> "${s}"`))),Ae.Assets.load(e||s)});On("json",async(o,e)=>{let t=Y==="publish",i=t&&ye!==!1,n=Y==="brand",a=t&&ye===!1;if(console.log(`[AssetLoader] registerType('json') - Effective mode: ${Y}, 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: ${o}`);return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e)}let s=o;if((n||a)&&o&&!o.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(s=o,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${o}" as-is`)):(s=`assets/${o}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${o}" -> "${s}"`))),e)return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e);let r=await fetch(s);if(!r.ok)throw new Error(`JSON fetch failed: ${o}`);return r.json()})});var _s={};at(_s,{AssetTextures:()=>we,initAssetTextures:()=>$n});function $n(o,e){js.init(o,e),typeof window!="undefined"&&(window.__AssetTextures=we)}var zn,js,we,ct=be(()=>{"use strict";li();zn=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 s;console.log("[AssetTextures] Loading all assets...");let i=new Set(["background_loading_1"]),n=[],a=[];for(let[r,l]of e.objects.entries()){let c=(s=l.render)==null?void 0:s.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}: ${r} (${u})`);let g=await We.load(r,c,t,u);this.textures.set(r,g),console.log(`[AssetTextures] \u2713 Loaded: ${r}`)}catch(u){console.error(`[AssetTextures] \u2717 Failed to load: ${r}`,u)}finally{this.attempted.add(r);try{for(let u of Array.from(this.waiters))u()}catch{}}};i.has(r)?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(r=>typeof r=="string"&&r))).filter(r=>{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,r);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(r=>this.textures.has(r)||this.attempted.has(r));if(a())return;let s=typeof t.timeoutMs=="number"?t.timeoutMs:15e3;await new Promise(r=>{let l=!1,c=()=>{l||a()&&(l=!0,this.waiters.delete(c),r())};this.waiters.add(c),c(),s>0&&setTimeout(()=>{l||(l=!0,this.waiters.delete(c),console.warn("[AssetTextures] waitFor timed out; continuing",{ids:n}),r())},s)})}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())}},js=new zn,we=new Proxy(js,{get(o,e){return e in o&&typeof o[e]=="function"?o[e].bind(o):o.get(e)},set(o,e,t){return o.set(e,t),!0}})});var Ie={};at(Ie,{applyConfigOverride:()=>oe,applyConfigOverrides:()=>Ne,applyConfigsToDisk:()=>xi,clearConfigOverrides:()=>pe,clearConfigOverridesForObject:()=>Ds,configOverrideManager:()=>Ns,deepClone:()=>X,exportConfigsAsJSON:()=>Je,getConfigOverrides:()=>se,getConfigStateSummary:()=>He,getOverrideMode:()=>Rt,redoLastConfigChange:()=>wi,removeConfigOverride:()=>zt,resetToApplied:()=>$t,resetToOriginal:()=>Si,setOverrideMode:()=>Vn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Fs,undoLastConfigChange:()=>vi});function mi(){return typeof window=="undefined"?null:window.__editableConfig||null}function Bn(){return typeof window=="undefined"?null:window.__editableConfigBaseline||null}function Fn(o,e){var t,i;if(!o)return null;try{if(o instanceof Map)return(t=o.get(e))!=null?t:null;if(typeof o=="object")return(i=o[e])!=null?i:null}catch{}return null}function Wr(o,e,t){if(o){if(o instanceof Map){o.set(e,t);return}typeof o=="object"&&(o[e]=t)}}function zs(o,e){for(let t of e)Ot(o,t.path,t.value)}function bi(o){var r;if(typeof window=="undefined")return;let e=mi();if(!e)return;let t=Bn(),i=(r=t?Fn(t.objects,o):null)!=null?r:Fn(e.objects,o);if(!i)return;let n=X(i),a=se().filter(l=>l.objectId===o);try{zs(n,a)}catch(l){console.error("[CONFIG] Failed to reapply overrides for object",o,l);return}Wr(e.objects,o,n);let s=window.applyEditableObjectConfig;if(typeof s=="function")try{s(o,n)}catch{}}function Gn(){var n;if(typeof window=="undefined")return;let o=mi();if(!(o!=null&&o.engine))return;let e=Bn(),t=X(((n=e==null?void 0:e.engine)!=null?n:o.engine)||{}),i=se().filter(a=>!a.objectId&&!a.sceneId);try{zs(t,i)}catch(a){console.error("[CONFIG] Failed to reapply engine overrides",a);return}try{let a=o.engine;for(let s of Object.keys(a))s in t||delete a[s];for(let[s,r]of Object.entries(t))a[s]=r}catch{o.engine=t}}function Kr(){if(typeof window=="undefined")return"unknown";let o=window;return typeof o.__HANDLER_PROJECT_ID=="string"?o.__HANDLER_PROJECT_ID:"handler-default"}function Un(){return`handler_preview_config_overrides::${Kr()}`}function Xr(){if(typeof window=="undefined")return[];try{let o=window.localStorage.getItem(Un());if(!o)return[];let e=JSON.parse(o);return Array.isArray(e)?e:[]}catch{return[]}}function yi(o){if(typeof window!="undefined")try{window.localStorage.setItem(Un(),JSON.stringify(o))}catch{}}function Rt(){return typeof window=="undefined"?!1:window.__enableConfigOverrides===!0}function Vn(o){if(typeof window!="undefined"){window.__enableConfigOverrides=o;try{window.localStorage.setItem($s,o?"true":"false")}catch{}}}function oe(o,e={}){var u,g;let{objectId:t,path:i,value:n}=o,{silent:a=!1,persist:s=!0,emitEvent:r=!0}=e,l=mi();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=Bs(c,i),Ot(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>qn&&h.shift(),window.__configChangeRedo=[]}if(s){let h=se(),f=h.findIndex(y=>y.objectId===t&&y.sceneId===o.sceneId&&y.path===i);f>=0?(console.log(`[CONFIG] Updating existing override at index ${f}:`,{objectId:t,path:i,oldValue:h[f].value,newValue:n}),h[f].value=n):(console.log("[CONFIG] Adding new override:",{objectId:t,path:i,value:typeof n=="string"?n.substring(0,50):n}),h.push(o)),window.__configOverrides=h,yi(h);let m=Un(),b=typeof window!="undefined"?window.localStorage.getItem(m):null;if(b){let y=JSON.parse(b);y.find(w=>w.objectId===t&&w.path===i)?console.log(`[CONFIG] \u2705 Override persisted to localStorage successfully. Total overrides: ${y.length}`):console.error("[CONFIG] \u274C Override NOT found in localStorage after persist!")}else console.error(`[CONFIG] \u274C localStorage key ${m} is empty after persist!`);Rt()||(console.log("[CONFIG] Override mode was disabled, enabling it now to ensure overrides apply on reload"),Vn(!0))}a||console.log("[CONFIG] Applied override:",o),r&&typeof window!="undefined"&&window.dispatchEvent(new CustomEvent("config:changed",{detail:{...o,oldValue:d}}))}function Ne(o,e={}){let t=e.emitEvent!==!1,i=[];for(let n of o)n!=null&&n.objectId&&typeof n.objectId=="string"&&i.push(n.objectId),oe(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:o.length}}))}}function pe(){window.__configOverrides=[],window.__configChanges=[],window.__configChangeRedo=[],yi([]),console.log("[CONFIG] Cleared all overrides")}function Ds(o){let e=se().filter(i=>i.objectId!==o);window.__configOverrides=e,yi(e);let t=window.__configChanges||[];window.__configChanges=t.filter(i=>i.objectId!==o),bi(o),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"clear_object",objectId:o}}))}function zt(o,e){let t=se().filter(n=>n.objectId!==o||n.path!==e);window.__configOverrides=t,yi(t);let i=window.__configChanges||[];window.__configChanges=i.filter(n=>n.objectId!==o||n.path!==e),o?bi(o):Gn(),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"remove",objectId:o,path:e}}))}function se(){return typeof window=="undefined"?[]:(window.__configOverrides||(window.__configOverrides=Xr()),window.__configOverrides||[])}function vi(){var a;if(typeof window=="undefined")return!1;let o=window.__configChanges||[];if(o.length===0)return!1;let e=o.pop();window.__configChangeRedo=window.__configChangeRedo||[];let t=window.__configChangeRedo;if(e.changeType==="object_create"){let{screenId:s}=e.metadata||{};return e.objectId&&s&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:s})}).catch(r=>console.error("[CONFIG] Failed to delete object on undo:",r)),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:s,objectConfigId:r}=e.metadata||{},l=e.oldValue;return e.objectId&&s&&l&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:s,instanceId:e.objectId,objectConfigId:r||((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=Bn(),n=!1;if(i){let s=e.objectId?Fn(i.objects,e.objectId):i.engine;if(s){let r=Bs(s,e.path);JSON.stringify(r)===JSON.stringify(e.oldValue)&&(n=!0)}}return n?zt(e.objectId,e.path):(oe({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?bi(e.objectId):Gn()),console.log("[CONFIG] Undo:",e.path),!0}function wi(){var i;if(typeof window=="undefined")return!1;let o=window.__configChangeRedo||[];if(o.length===0)return!1;let e=o.pop();if(e.changeType==="object_create"){let{screenId:n,objectConfigId:a}=e.metadata||{},s=e.newValue;return e.objectId&&n&&s&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,instanceId:e.objectId,objectConfigId:a||((i=s==null?void 0:s.identity)==null?void 0:i.id),config:s})}).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(s=>console.error("[CONFIG] Failed to delete object on redo:",s)),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}),oe({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?bi(e.objectId):Gn(),console.log("[CONFIG] Redo:",e.path),!0}function Hs(o,e,t){var n;if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:o,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>qn&&i.shift(),console.log("[CONFIG] Tracked object creation:",o)}function Fs(o,e,t){if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:o,path:"__object_delete__",oldValue:t,newValue:null,ts:Date.now(),changeType:"object_delete",metadata:{screenId:e}}),window.__configChangeRedo=[],i.length>qn&&i.shift(),console.log("[CONFIG] Tracked object deletion:",o)}function Ot(o,e,t){var s;let i=e.split("."),n=i.pop(),a=o;for(let r of i){if(a[r]!==void 0&&typeof a[r]!="object")throw new Error(`Invalid override path: ${e} (hit primitive at ${r})`);a[r]=(s=a[r])!=null?s:{},a=a[r]}a[n]=t}function Bs(o,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,o)}function X(o){if(o===null||typeof o!="object")return o;if(o instanceof Date)return new Date(o.getTime());if(o instanceof Set)return new Set([...o].map(t=>X(t)));if(ArrayBuffer.isView(o))return o.slice();if(o instanceof Array)return o.map(t=>X(t));if(o instanceof Map){let t=new Map;return o.forEach((i,n)=>t.set(n,X(i))),t}let e={};for(let t in o)Object.prototype.hasOwnProperty.call(o,t)&&(e[t]=X(o[t]));return e}function Je(){let o=window.__editableConfigBaseline;if(!o){let e=window.__editableConfig;if(!e)throw new Error("Cannot export: no config loaded");return Rs(e)}return Rs(o)}function Rs(o){let e={objects:{},scenes:{},engine:X(o.engine||{})},t=o.objects;if(t instanceof Map)t.forEach((a,s)=>{e.objects[s]=X(a)});else if(t&&typeof t=="object")for(let a in t)e.objects[a]=X(t[a]);let i=o.scenes;if(i instanceof Map)i.forEach((a,s)=>{e.scenes[s]=X(a)});else if(i&&typeof i=="object")for(let a in i)e.scenes[a]=X(i[a]);let n=se();for(let a of n)a.objectId?(e.objects[a.objectId]||(e.objects[a.objectId]={}),Ot(e.objects[a.objectId],a.path,a.value)):a.sceneId?(e.scenes[a.sceneId]||(e.scenes[a.sceneId]={}),Ot(e.scenes[a.sceneId],a.path,a.value)):Ot(e.engine,a.path,a.value);return e}function He(){let o=se(),e=new Set;for(let t of o)t.objectId?e.add(t.objectId):e.add("__engine__");return{modifiedObjects:Array.from(e),overrideCount:o.length,hasChanges:o.length>0,overrides:o}}async function xi(o){let e=Je(),t={};for(let[n,a]of Object.entries(e.objects)){let s=a,r=n;/^(json\.|ui\.|effects\.|engine\.)/.test(r)||(r=`json.${n}`),s&&typeof s=="object"&&(s.identity||(s.identity={}),s.identity.id=r),t[`objects/${r}.json`]=s}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 s=n.startsWith("scene.")?n:`scene.${n}`;t[`scenes/${s}.json`]=a}let i=await fetch("/api/apply",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:t,assets:{},hadCacheAtApply:se().length>0,versionName:o})});if(!i.ok){let n=await i.json();throw new Error(`Apply failed: ${n.error||"Unknown error"}`)}pe();try{let n=mi();n&&(window.__editableConfigBaseline=X(n))}catch{}localStorage.setItem("handler_last_applied",Date.now().toString()),console.log("[Config Persistence] \u2705 Applied to disk successfully")}function $t(){pe(),window.location.reload()}async function Si(){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"}`)}pe(),window.location.reload()}var $s,qn,Ns,Q=be(()=>{"use strict";$s="handler_preview_override_mode";if(typeof window!="undefined"){let o=window.localStorage.getItem($s);window.__enableConfigOverrides=o===null?!0:o==="true"}qn=500;Ns={getCurrentConfig(){return window.__editableConfig||null},getChanges(){return window.__configChanges||[]},clearChanges(){window.__configChanges=[],window.__configChangeRedo=[]}}});function Jr(o,e){try{if(typeof o=="object"&&o!==null)return o;if(typeof o!="string")return null;if(o.startsWith("data:")){let i=o.indexOf(",");if(i===-1)return null;let n=o.slice(0,i);if(!n.includes("application/json")&&!n.includes("text/plain"))return null;let a=o.slice(i+1),s=n.includes("base64")?typeof atob=="function"?atob(a):a:decodeURIComponent(a);return JSON.parse(s)}let t=o.trim();return t.startsWith("{")||t.startsWith("[")?JSON.parse(o):null}catch{return null}}function Zr(o){if(typeof window=="undefined"||!window.INLINE_ASSETS)return null;let e=window.INLINE_ASSETS,t=o.replace(/^\.\/+/,""),i=t.split("/").pop()||t,n=[t,i,t.replace(/\.json$/,""),i.replace(/\.json$/,"")];for(let a of n){let s=e[a];if(s){let r=Jr(s,a);if(r!==null)return r}}return null}async function Dt(o){if(Yn.has(o)&&!Wn)return console.log(`[CONFIG] Using cached config for: "${o}"`),Yn.get(o);if(console.log(`[CONFIG] loadConfigFile called with: "${o}", MODE: ${V.toUpperCase()}, CACHE: ${Wn?"DISABLED":"ENABLED"}`),V==="publish"){let i=Zr(o);return i?(console.log(`[CONFIG] \u2713 Loaded ${o} via INLINE_ASSETS`),i):(console.log(`[CONFIG] \u2139\uFE0F Optional config ${o} not in INLINE_ASSETS, skipping fetch in publish mode`),{})}V==="brand"||console.log(`[CONFIG] DEV MODE: Trying nested paths first, then flattened for "${o}"`);let e;V==="brand"?e=[`./${o.split("/").pop()||o}`,`./${o}`,`./${o.replace(/^configs\//,"")}`,`./${o.replace(/^configs\//,"").replace(/\//g,".")}`]:e=[`./${o}`,`./${o.replace(/^configs\//,"")}`,`./${o.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=Wn?"no-store":"force-cache";for(let n of e)try{let a=await fetch(n,{cache:i});if(!a.ok)continue;let s=await a.json();return console.log(`[CONFIG] \u2713 Loaded ${o} via ${n}`,s),s}catch(a){console.warn(`[CONFIG] \u2717 Failed to load ${n} (mode: ${V}):`,a)}return console.warn(`[CONFIG] \u2717 All attempts failed for ${o}; using defaults`),{}})();return Yn.set(o,t),t}async function Ei(){console.log("[CONFIG] Loading component schemas...");let o=["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 o)try{let i=V==="publish"||V==="brand"?t.split("/").pop()||t:`configs/${t}`,n=await Dt(i);n.component&&(e.set(n.component,n),console.log(`[CONFIG] \u2713 Schema loaded: ${n.component} ${V==="publish"||V==="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 Fe(o){console.log(`[CONFIG] Loading object config: ${o}`);let e=V==="publish"||V==="brand"?`${o}.json`:`configs/objects/${o}.json`;return await Dt(e)}async function Ci(o){let e=new Map;if(o.objects&&Array.isArray(o.objects)){for(let t of o.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 Fe(i);(!n||Object.keys(n).length===0)&&i!==t.instance_id&&(n=await Fe(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 Fe(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 Ai(){console.log("[CONFIG] Loading engine configs...");let o=["runtime","assets","splash","loading","start","tutorial","endgame"],e=await Promise.all(o.map(i=>{let n=`engine.${i}.json`,a=V==="publish"||V==="brand"?n:`configs/engine/${n}`;return Dt(a)})),t=Object.fromEntries(o.map((i,n)=>[i,e[n]]));return console.log("[CONFIG] Engine configs loaded:",Object.fromEntries(o.map(i=>{var s;let n=(s=t[i])!=null?s:{},a=Object.keys(n);return[i,a.length>0?a:"empty"]}))),t}async function Kn(){return await Dt(V==="publish"||V==="brand"?"game.prompt.json":"configs/engine/game.prompt.json")}async function Li(o="scene.main"){console.log(`[CONFIG] Loading scene config: ${o}`);let e=V==="publish"||V==="brand"?`${o}.json`:`configs/scenes/${o}.json`;return await Dt(e)}function pt(o,e){let t=[];if(!o.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||[])o.identity[n]||t.push(`Missing required identity field: ${n}`);for(let[n,a]of Object.entries(o)){if(n==="identity")continue;let s=e.get(n);if(s&&a&&typeof a=="object"){let r=a;for(let l of s.required||[])r[l]===void 0&&t.push(`Missing required field in ${n}: ${l}`);if(s.constraints&&typeof s.constraints=="object")for(let[l,c]of Object.entries(s.constraints)){let d=r[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 Ze(o,e){let t={...o},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 ue(o,e,t,i){return typeof o!="number"||!Number.isFinite(o)?e:Math.min(Math.max(o,t),i)}function Us(o,e){if(Array.isArray(o))return{x:ue(o[0],e.x,-2e3,2e3),y:ue(o[1],e.y,-2e3,2e3)};if(!o||typeof o!="object")return e;let{x:t,y:i}=o;return{x:ue(t,e.x,-2e3,2e3),y:ue(i,e.y,-2e3,2e3)}}function Qr(o,e){if(Array.isArray(o))return{x:ue(o[0],e.x,0,1),y:ue(o[1],e.y,0,1)};if(!o||typeof o!="object")return e;let{x:t,y:i}=o;return{x:ue(t,e.x,0,1),y:ue(i,e.y,0,1)}}function el(o){if(Array.isArray(o))return{x:ue(o[0],.5,-10,10),y:ue(o[1],.5,-10,10)};if(o&&typeof o=="object"){let{x:e,y:t}=o;return{x:ue(e,.5,-10,10),y:ue(t,.5,-10,10)}}return typeof o=="string"?o:null}async function Pe(o="scene.main",e){var c,d,p,u,g,h,f,m,b,y,v,w,I,P,_;console.log("[CONFIG] ===== Starting Object-Centric Config Load =====");let t=await Ei(),i=se(),n=Rt();console.log(`[CONFIG] Loader: Found ${i.length} persisted overrides, override mode: ${n}`),i.length>0&&console.log("[CONFIG] Override details:",i.map(T=>({objectId:T.objectId,path:T.path,value:typeof T.value=="string"?T.value.substring(0,50):T.value})));let a=await Li(o);console.log(`[CONFIG] Scene config loaded: ${((c=a.objects)==null?void 0:c.length)||0} objects`);let s=await Ai();console.log("[CONFIG] Loading object configs...");let r=await Ci(a);console.log(`[CONFIG] Loaded ${r.size} object configs:`,Array.from(r.keys()));for(let[T,M]of r.entries()){let k=Ze(M,t),A=pt(k,t);A.valid||console.warn(`Object ${T} validation errors:`,A.errors),(d=k.transform)!=null&&d.position&&(k.transform.position=Us(k.transform.position,{x:0,y:0})),(p=k.transform)!=null&&p.offset&&(k.transform.offset=Us(k.transform.offset,{x:0,y:0})),((u=k.transform)==null?void 0:u.anchor)!==void 0&&(k.transform.anchor=el(k.transform.anchor)),((g=k.transform)==null?void 0:g.position_ratio)!==void 0&&k.transform.position_ratio!==null&&(k.transform.position_ratio=Qr(k.transform.position_ratio,{x:.5,y:.5})),r.set(T,k)}if(e){if(e.objects)for(let[T,M]of e.objects.entries())r.set(T,M);e.engine&&(s.runtime={...s.runtime,...e.engine.runtime},s.assets={...s.assets,...e.engine.assets},s.splash={...(h=s.splash)!=null?h:{},...(f=e.engine.splash)!=null?f:{}})}let l={objects:r,engine:s,scene:a,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=l,window.__editableConfigBaseline||(window.__editableConfigBaseline=Ze(l,t))),i.length>0&&n?(console.log(`[CONFIG] \u2705 Applying ${i.length} persisted overrides on startup`),Ne(i,{silent:!1,persist:!1}),console.log("[CONFIG] \u2705 Overrides applied. Current config state:",{objectCount:((m=l.objects)==null?void 0:m.size)||0,sampleOverrides:i.slice(0,3).map(T=>`${T.objectId||"engine"}.${T.path} = ${typeof T.value=="string"?T.value.substring(0,30):JSON.stringify(T.value).substring(0,30)}`)})):i.length>0&&!n?console.warn(`[CONFIG] \u26A0\uFE0F Found ${i.length} persisted overrides but override mode is DISABLED. Overrides will NOT be applied.`):i.length===0&&console.log("[CONFIG] No persisted overrides found in localStorage"),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((b=s.runtime)!=null?b:{}),assets:Object.keys((y=s.assets)!=null?y:{}),splash:Object.keys((v=s.splash)!=null?v:{}),loading:Object.keys((w=s.loading)!=null?w:{}),start:Object.keys((I=s.start)!=null?I:{}),tutorial:Object.keys((P=s.tutorial)!=null?P:{}),endgame:Object.keys((_=s.endgame)!=null?_:{})},scene:a.scene_id||"unknown"}),l}function Xn(o){var t,i,n,a,s,r,l,c,d,p,u,g,h,f,m,b,y,v,w,I,P,_,T,M,k,A,C,L,x,E,S,O,j;let e={gameplay:{},ui:{},theme:{},assets:{}};for(let[R,z]of o.objects.entries()){let D=((t=z.identity)==null?void 0:t.id)||R;D.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=((s=(a=z.gameplay)==null?void 0:a.tuning)==null?void 0:s.anim_speed)||.003,e.gameplay.character_relief_scale=((l=(r=z.gameplay)==null?void 0:r.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),(D.includes("gun")||D.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)||{}),D.includes("diamond")&&(e.gameplay.diamond=z),D.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||{}),D.includes("water")&&(e.gameplay.water_drops=z),D.includes("crack")&&(e.gameplay.crack=z),D.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=((I=z.transform)==null?void 0:I.scale)||1.5),D.includes("hazard")&&(e.gameplay.hazard=((P=z.gameplay)==null?void 0:P.tuning)||{},e.gameplay.danger_pos=((_=z.transform)==null?void 0:_.danger_pos)||{x:0,y:235},e.gameplay.danger_pulse=((M=(T=z.gameplay)==null?void 0:T.tuning)==null?void 0:M.danger_pulse)||{},e.gameplay.hazard_height=((A=(k=z.gameplay)==null?void 0:k.tuning)==null?void 0:A.hazard_height)||140)}return e.gameplay.timeline=((C=o.engine.runtime)==null?void 0:C.timeline)||{},e.gameplay.drag_surface=((L=o.engine.runtime)==null?void 0:L.drag_surface)||{},e.gameplay.background=((x=o.engine.runtime)==null?void 0:x.background)||{},e.gameplay.ui_styles=((E=o.engine.runtime)==null?void 0:E.ui_styles)||{},e.gameplay.label_pulse=((S=o.engine.runtime)==null?void 0:S.label_pulse)||{},e.ui=((O=o.engine.runtime)==null?void 0:O.ui)||{},e.theme=((j=o.engine.runtime)==null?void 0:j.theme)||{},e.assets=o.engine.assets||{},e}var Gs,V,Yn,Wn,Jn=be(()=>{"use strict";Q();Gs=null,V="dev";if(typeof window!="undefined"){let o=window.__BUILD_SETTINGS__;if(o!=null&&o.buildMode)Gs=o,V=o.buildMode,console.log("[CONFIG] Loaded inline build settings:",o,"buildMode:",V);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);Gs=t,V=t.buildMode||"dev",console.log("[CONFIG] Loaded build settings:",t,"buildMode:",V)}else console.log("[CONFIG] No build-settings.json found, using default buildMode:",V)}catch(e){console.log("[CONFIG] Failed to load build-settings.json:",e instanceof Error?e.message:String(e))}}console.log("[CONFIG] Final buildMode:",V);Yn=new Map,Wn=V==="dev"||typeof window!="undefined"&&window.location.search.includes("hot-reload")});function Zn(o,e){let t=[];function i(n,a,s=""){if(n!==a){if(typeof n!=typeof a){t.push(`${s}: type changed`);return}if(typeof n=="object"&&n!==null&&a!==null){let r=new Set([...Object.keys(n),...Object.keys(a)]);for(let l of r){let c=s?`${s}.${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(`${s}: changed`)}}return i(o,e),t}function Qn(o,e,t,i){let n={...t};for(let[a,s]of i.entries())n[a]&&s.defaults&&(n[a]={...s.defaults,...n[a]});return n}var Nt,Qe,ea=be(()=>{"use strict";Nt=class{shouldFullReload(e){return e.type==="component"||e.type==="scene"}getAffectedObjects(e){return e.type==="object"&&e.objectId?[e.objectId]:[]}},Qe=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(),s=this.hashString(a),r=this.fileHashes.get(e);if(r&&r!==s&&console.log(`[HOT-RELOAD] File changed: ${e}`),r&&r!==s){console.log(`[HOT-RELOAD] File changed: ${e}`);let l=this.determineEventType(e);t(l),this.fileHashes.set(e,s)}else r||this.fileHashes.set(e,s)}}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 ia(o){if(typeof window=="undefined")return;let e=typeof ta!="undefined"&&!!ta.hot,t=window.location.search.includes("hot-reload");if(!(e||t))return;let n=null,a=!1,s=null;if(t){s=new Qe;let h=window.__configWatcher;h!=null&&h.stop&&h.stop(),window.__configWatcher=s}let r=new Set,l=h=>{var b,y;if(!s)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 r)f.has(v)||s.unwatch(v);for(let v of f)r.has(v)||s.watch(v,w=>g(w));r=f},c=new Set,d=!1,p=async h=>{let f=await Fe(h),m=Ze(f,o.activeConfig.schemas),b=pt(m,o.activeConfig.schemas);b.valid||console.warn(`[HOT-RELOAD] ${h} validation errors:`,b.errors),await o.liveEditBridge.applyObjectConfig(h,m)};async function u(h){if(!a){a=!0;try{if(d||c.size===0){o.audioSystem.destroy();let f=await Pe("scene.main");o.setActiveConfig(f),o.gameObjectManager.updateConfig(f),o.CustomAssets.updateConfig(f),await o.CustomAssets.ready();let m=o.createAudioSystem(f);o.setAudioSystem(m),window.__audioSystem=m,await m.start(),o.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&&ta.hot.on("config-change",()=>{g({type:"hmr"})}),t&&(l(o.activeConfig),console.log(`[GAME] Hot-reload watcher enabled (${r.size} files)`))}var ta,qs=be(()=>{"use strict";ea();Jn();ta={}});var Vs={};at(Vs,{ConfigWatcher:()=>Qe,DefaultReloadStrategy:()=>Nt,applyDefaults:()=>Ze,diffConfigs:()=>Zn,loadAllObjectConfigs:()=>Ci,loadComponentSchemas:()=>Ei,loadEngineConfig:()=>Ai,loadGamePromptConfig:()=>Kn,loadObjectCentricConfig:()=>Pe,loadObjectConfig:()=>Fe,loadSceneConfig:()=>Li,rehydrateObject:()=>Qn,setupHotReload:()=>ia,toLegacyFormat:()=>Xn,validateObjectConfig:()=>pt});var Ti=be(()=>{"use strict";Jn();ea();qs()});var Ht={};at(Ht,{AssetEditorModal:()=>ra});var ra,ut=be(()=>{"use strict";ra=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=`
1
+ "use strict";var ao=Object.create;var ai=Object.defineProperty;var so=Object.getOwnPropertyDescriptor;var ro=Object.getOwnPropertyNames;var oo=Object.getPrototypeOf,lo=Object.prototype.hasOwnProperty;var ye=(r,e)=>()=>(r&&(e=r(r=0)),e);var st=(r,e)=>{for(var t in e)ai(r,t,{get:e[t],enumerable:!0})},Qa=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ro(e))!lo.call(r,n)&&n!==t&&ai(r,n,{get:()=>e[n],enumerable:!(i=so(e,n))||i.enumerable});return r};var rt=(r,e,t)=>(t=r!=null?ao(oo(r)):{},Qa(e||!r||!r.__esModule?ai(t,"default",{value:r,enumerable:!0}):t,r)),co=r=>Qa(ai({},"__esModule",{value:!0}),r);var pe,li=ye(()=>{"use strict";pe=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()}};pe.store=new Map});function yo(){var r,e;try{let t=typeof window!="undefined"&&(document.querySelector('script[src*="inline-assets.js"]')||((e=(r=document.querySelector("script"))==null?void 0:r.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 vo(){try{if(typeof window!="undefined"){let r=await fetch("./build-settings.json");if(r.ok){let e=await r.json();return console.log("[AssetLoader] Loaded build settings:",e),e}}}catch{}return null}function wo(){try{if(typeof window!="undefined"){let r=new XMLHttpRequest;if(r.open("GET","./build-settings.json",!1),r.send(),r.status===200&&r.responseText){let e=JSON.parse(r.responseText);return console.log("[AssetLoader] Loaded build settings (sync):",e),e}}}catch{}return null}async function xo(){if(console.log(`[AssetLoader] getInlineAssets() called - Effective mode: ${X}`),Object.keys(Ae).length>0)return console.log("[AssetLoader] Returning cached inline assets:",Object.keys(Ae)),Ae;if(typeof window!="undefined"&&window.INLINE_ASSETS)return console.log("[AssetLoader] Using pre-loaded INLINE_ASSETS from window:",Object.keys(window.INLINE_ASSETS)),Ae={...window.INLINE_ASSETS},Ae;if(!(X==="publish"&&ve!==!1))return console.log("[AssetLoader] Inline assets disabled for this build mode."),Ae;if(!_n){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),_n=(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 s=new Function("return "+a)();return console.log("[AssetLoader] Parsed inline assets:",Object.keys(s)),s}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 Ae=await _n,console.log("[AssetLoader] Final inline assets cache:",Object.keys(Ae)),Ae}function On(r){return r===null||typeof r!="object"||(Object.freeze(r),Object.values(r).forEach(e=>On(e))),r}function So(r=64,e=64,t=16711680){let i=document.createElement("canvas");i.width=r,i.height=e;let n=i.getContext("2d");return n.fillStyle=`#${t.toString(16).padStart(6,"0")}`,n.fillRect(0,0,r,e),n.strokeStyle="#000",n.strokeRect(0,0,r,e),n.fillStyle="#fff",n.font="10px sans-serif",n.textAlign="center",n.fillText("MISSING",r/2,e/2),Le.Texture.from(i)}function Rn(r,e){js.set(r,e)}var Le,Ps,Ms,We,X,ve,De,Ae,_n,js,Ke,ci=ye(()=>{"use strict";Le=require("pixi.js");li();Ps=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Ms=yo(),We=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,X=Ms?"publish":Ps,ve=We==null?void 0:We.assetsInlined;We!=null&&We.buildMode&&(X=We.buildMode,console.log(`[AssetLoader] Build mode overridden by inline settings: ${X}`));De=wo();De!=null&&De.buildMode&&(X=De.buildMode,console.log(`[AssetLoader] Build mode overridden by sync settings: ${X}`));(De==null?void 0:De.assetsInlined)!==void 0&&(ve=De.assetsInlined);vo().then(r=>{r!=null&&r.buildMode&&r.buildMode!==X&&(X=r.buildMode,console.log(`[AssetLoader] Build mode overridden by settings: ${X}`)),(r==null?void 0:r.assetsInlined)!==void 0&&(ve=r.assetsInlined)}).catch(()=>{});console.log(`[AssetLoader] MODULE LOADED - Compile: ${Ps}, Runtime: ${Ms?"publish":"dev"}, Effective: ${X}`);Ae={},_n=null;js=new Map;Ke=class{static async load(e,t,i,n){let a=`${e}:${t.path}`,s=pe.get(a);if(s!==void 0)return s;console.log(`[AssetLoader] Loading asset: ${e}, type: ${t.type}, Effective mode: ${X}`),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 xo(),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"),X==="publish"&&ve!==!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=js.get(t.type);if(d)try{let p=await d(t.path,l,e,i);return pe.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=On(p);break;default:throw new Error(`Unknown asset type: ${t.type}`)}return pe.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}}static async loadImage(e,t){let i=X==="publish",n=i&&ve!==!1;if(console.log(`[AssetLoader] loadImage - Effective mode: ${X}, 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 Le.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 Le.Assets.load(t)}catch(a){return console.error("[AssetLoader] Failed to load texture from data URI, falling back to path:",a),await Le.Assets.load(e)}return await Le.Assets.load(e)}static async loadJSON(e,t){let i=X==="publish",n=i&&ve!==!1;if(console.log(`[AssetLoader] loadJSON - Effective mode: ${X}, 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 s=atob(t.split(",")[1]);return JSON.parse(s)}return JSON.parse(t)}if(t){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let s=atob(t.split(",")[1]);return JSON.parse(s)}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(X==="dev"){let a=t==="image"?So():On({__placeholder:!0,type:t});return pe.set(e+":"+((i==null?void 0:i.path)||"missing"),a),a}throw i}};Rn("image",async(r,e)=>{let t=X==="publish",i=t&&ve!==!1,n=X==="brand",a=t&&ve===!1;if(console.log(`[AssetLoader] registerType('image') - Effective mode: ${X}, 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: ${r}`);if(typeof e!="string"||!e.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof e}`);return Le.Assets.load(e)}let s=r;return(n||a)&&r&&!r.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(s=r,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${r}" as-is`)):(s=`assets/${r}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${r}" -> "${s}"`))),Le.Assets.load(e||s)});Rn("json",async(r,e)=>{let t=X==="publish",i=t&&ve!==!1,n=X==="brand",a=t&&ve===!1;if(console.log(`[AssetLoader] registerType('json') - Effective mode: ${X}, 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: ${r}`);return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e)}let s=r;if((n||a)&&r&&!r.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(s=r,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${r}" as-is`)):(s=`assets/${r}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${r}" -> "${s}"`))),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(s);if(!o.ok)throw new Error(`JSON fetch failed: ${r}`);return o.json()})});var Os={};st(Os,{AssetTextures:()=>xe,initAssetTextures:()=>Dn});function Dn(r,e){_s.init(r,e),typeof window!="undefined"&&(window.__AssetTextures=xe)}var $n,_s,xe,dt=ye(()=>{"use strict";ci();$n=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 s;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=(s=l.render)==null?void 0:s.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 Ke.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 s=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(),s>0&&setTimeout(()=>{l||(l=!0,this.waiters.delete(c),console.warn("[AssetTextures] waitFor timed out; continuing",{ids:n}),o())},s)})}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())}},_s=new $n,xe=new Proxy(_s,{get(r,e){return e in r&&typeof r[e]=="function"?r[e].bind(r):r.get(e)},set(r,e,t){return r.set(e,t),!0}})});var Pe={};st(Pe,{applyConfigOverride:()=>le,applyConfigOverrides:()=>He,applyConfigsToDisk:()=>Si,clearConfigOverrides:()=>ge,clearConfigOverridesForObject:()=>Ns,configOverrideManager:()=>Hs,deepClone:()=>te,exportConfigsAsJSON:()=>Ze,getConfigOverrides:()=>re,getConfigStateSummary:()=>Fe,getOverrideMode:()=>zt,redoLastConfigChange:()=>xi,removeConfigOverride:()=>$t,resetToApplied:()=>Dt,resetToOriginal:()=>Ei,setOverrideMode:()=>Yn,trackObjectCreation:()=>Fs,trackObjectDeletion:()=>Bs,undoLastConfigChange:()=>wi});function bi(){return typeof window=="undefined"?null:window.__editableConfig||null}function Gn(){return typeof window=="undefined"?null:window.__editableConfigBaseline||null}function Bn(r,e){var t,i;if(!r)return null;try{if(r instanceof Map)return(t=r.get(e))!=null?t:null;if(typeof r=="object")return(i=r[e])!=null?i:null}catch{}return null}function Ko(r,e,t){if(r){if(r instanceof Map){r.set(e,t);return}typeof r=="object"&&(r[e]=t)}}function $s(r,e){for(let t of e)Rt(r,t.path,t.value)}function yi(r){var o;if(typeof window=="undefined")return;let e=bi();if(!e)return;let t=Gn(),i=(o=t?Bn(t.objects,r):null)!=null?o:Bn(e.objects,r);if(!i)return;let n=te(i),a=re().filter(l=>l.objectId===r);try{$s(n,a)}catch(l){console.error("[CONFIG] Failed to reapply overrides for object",r,l);return}Ko(e.objects,r,n);let s=window.applyEditableObjectConfig;if(typeof s=="function")try{s(r,n)}catch{}}function Un(){var n;if(typeof window=="undefined")return;let r=bi();if(!(r!=null&&r.engine))return;let e=Gn(),t=te(((n=e==null?void 0:e.engine)!=null?n:r.engine)||{}),i=re().filter(a=>!a.objectId&&!a.sceneId);try{$s(t,i)}catch(a){console.error("[CONFIG] Failed to reapply engine overrides",a);return}try{let a=r.engine;for(let s of Object.keys(a))s in t||delete a[s];for(let[s,o]of Object.entries(t))a[s]=o}catch{r.engine=t}}function Xo(){if(typeof window=="undefined")return"unknown";let r=window;return typeof r.__HANDLER_PROJECT_ID=="string"?r.__HANDLER_PROJECT_ID:"handler-default"}function qn(){return`handler_preview_config_overrides::${Xo()}`}function Jo(){if(typeof window=="undefined")return[];try{let r=window.localStorage.getItem(qn());if(!r)return[];let e=JSON.parse(r);return Array.isArray(e)?e:[]}catch{return[]}}function vi(r){if(typeof window!="undefined")try{window.localStorage.setItem(qn(),JSON.stringify(r))}catch{}}function zt(){return typeof window=="undefined"?!1:window.__enableConfigOverrides===!0}function Yn(r){if(typeof window!="undefined"){window.__enableConfigOverrides=r;try{window.localStorage.setItem(Ds,r?"true":"false")}catch{}}}function le(r,e={}){var u,g;let{objectId:t,path:i,value:n}=r,{silent:a=!1,persist:s=!0,emitEvent:o=!0}=e,l=bi();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=Gs(c,i),Rt(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>Vn&&h.shift(),window.__configChangeRedo=[]}if(s){let h=re(),f=h.findIndex(y=>y.objectId===t&&y.sceneId===r.sceneId&&y.path===i);f>=0?(console.log(`[CONFIG] Updating existing override at index ${f}:`,{objectId:t,path:i,oldValue:h[f].value,newValue:n}),h[f].value=n):(console.log("[CONFIG] Adding new override:",{objectId:t,path:i,value:typeof n=="string"?n.substring(0,50):n}),h.push(r)),window.__configOverrides=h,vi(h);let m=qn(),b=typeof window!="undefined"?window.localStorage.getItem(m):null;if(b){let y=JSON.parse(b);y.find(v=>v.objectId===t&&v.path===i)?console.log(`[CONFIG] \u2705 Override persisted to localStorage successfully. Total overrides: ${y.length}`):console.error("[CONFIG] \u274C Override NOT found in localStorage after persist!")}else console.error(`[CONFIG] \u274C localStorage key ${m} is empty after persist!`);zt()||(console.log("[CONFIG] Override mode was disabled, enabling it now to ensure overrides apply on reload"),Yn(!0))}a||console.log("[CONFIG] Applied override:",r),o&&typeof window!="undefined"&&window.dispatchEvent(new CustomEvent("config:changed",{detail:{...r,oldValue:d}}))}function He(r,e={}){let t=e.emitEvent!==!1,i=[];for(let n of r)n!=null&&n.objectId&&typeof n.objectId=="string"&&i.push(n.objectId),le(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:r.length}}))}}function ge(){window.__configOverrides=[],window.__configChanges=[],window.__configChangeRedo=[],vi([]),console.log("[CONFIG] Cleared all overrides")}function Ns(r){let e=re().filter(i=>i.objectId!==r);window.__configOverrides=e,vi(e);let t=window.__configChanges||[];window.__configChanges=t.filter(i=>i.objectId!==r),yi(r),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"clear_object",objectId:r}}))}function $t(r,e){let t=re().filter(n=>n.objectId!==r||n.path!==e);window.__configOverrides=t,vi(t);let i=window.__configChanges||[];window.__configChanges=i.filter(n=>n.objectId!==r||n.path!==e),r?yi(r):Un(),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"remove",objectId:r,path:e}}))}function re(){return typeof window=="undefined"?[]:(window.__configOverrides||(window.__configOverrides=Jo()),window.__configOverrides||[])}function wi(){var a;if(typeof window=="undefined")return!1;let r=window.__configChanges||[];if(r.length===0)return!1;let e=r.pop();window.__configChangeRedo=window.__configChangeRedo||[];let t=window.__configChangeRedo;if(e.changeType==="object_create"){let{screenId:s}=e.metadata||{};return e.objectId&&s&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:s})}).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:s,objectConfigId:o}=e.metadata||{},l=e.oldValue;return e.objectId&&s&&l&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:s,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=Gn(),n=!1;if(i){let s=e.objectId?Bn(i.objects,e.objectId):i.engine;if(s){let o=Gs(s,e.path);JSON.stringify(o)===JSON.stringify(e.oldValue)&&(n=!0)}}return n?$t(e.objectId,e.path):(le({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?yi(e.objectId):Un()),console.log("[CONFIG] Undo:",e.path),!0}function xi(){var i;if(typeof window=="undefined")return!1;let r=window.__configChangeRedo||[];if(r.length===0)return!1;let e=r.pop();if(e.changeType==="object_create"){let{screenId:n,objectConfigId:a}=e.metadata||{},s=e.newValue;return e.objectId&&n&&s&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,instanceId:e.objectId,objectConfigId:a||((i=s==null?void 0:s.identity)==null?void 0:i.id),config:s})}).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(s=>console.error("[CONFIG] Failed to delete object on redo:",s)),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}),le({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?yi(e.objectId):Un(),console.log("[CONFIG] Redo:",e.path),!0}function Fs(r,e,t){var n;if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:r,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>Vn&&i.shift(),console.log("[CONFIG] Tracked object creation:",r)}function Bs(r,e,t){if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:r,path:"__object_delete__",oldValue:t,newValue:null,ts:Date.now(),changeType:"object_delete",metadata:{screenId:e}}),window.__configChangeRedo=[],i.length>Vn&&i.shift(),console.log("[CONFIG] Tracked object deletion:",r)}function Rt(r,e,t){var s;let i=e.split("."),n=i.pop(),a=r;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]=(s=a[o])!=null?s:{},a=a[o]}a[n]=t}function Gs(r,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,r)}function te(r){if(r===null||typeof r!="object")return r;if(r instanceof Date)return new Date(r.getTime());if(r instanceof Set)return new Set([...r].map(t=>te(t)));if(ArrayBuffer.isView(r))return r.slice();if(r instanceof Array)return r.map(t=>te(t));if(r instanceof Map){let t=new Map;return r.forEach((i,n)=>t.set(n,te(i))),t}let e={};for(let t in r)Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=te(r[t]));return e}function Ze(){let r=window.__editableConfigBaseline;if(!r){let e=window.__editableConfig;if(!e)throw new Error("Cannot export: no config loaded");return zs(e)}return zs(r)}function zs(r){let e={objects:{},scenes:{},engine:te(r.engine||{})},t=r.objects;if(t instanceof Map)t.forEach((o,l)=>{e.objects[l]=te(o)});else if(t&&typeof t=="object")for(let o in t)e.objects[o]=te(t[o]);let i=r.scenes;if(i instanceof Map)i.forEach((o,l)=>{e.scenes[l]=te(o)});else if(i&&typeof i=="object")for(let o in i)e.scenes[o]=te(i[o]);let n=re();console.log(`[CONFIG] Export: Applying ${n.length} overrides to baseline`);let a=new Map;for(let o of n){let l=o.objectId||(o.sceneId?`scene:${o.sceneId}`:"__engine__");a.has(l)||a.set(l,[]),a.get(l).push(o)}let s=new Map;for(let o of n)if(o.path==="render.asset.path"&&o.objectId){let l=o.value;s.has(l)||s.set(l,[]),s.get(l).push(o.objectId)}for(let[o,l]of s.entries())l.length>1&&console.log(`[CONFIG] \u26A0\uFE0F Multiple objects sharing same asset: ${o} used by ${l.join(", ")}`);for(let o of n)o.objectId?(e.objects[o.objectId]||(console.warn(`[CONFIG] \u26A0\uFE0F Override references non-existent object: ${o.objectId}`),e.objects[o.objectId]={}),console.log(`[CONFIG] Export: Applying override to ${o.objectId}.${o.path} = ${typeof o.value=="string"?o.value.substring(0,50):o.value}`),Rt(e.objects[o.objectId],o.path,o.value)):o.sceneId?(e.scenes[o.sceneId]||(e.scenes[o.sceneId]={}),Rt(e.scenes[o.sceneId],o.path,o.value)):Rt(e.engine,o.path,o.value);return e}function Fe(){let r=re(),e=new Set;for(let t of r)t.objectId?e.add(t.objectId):e.add("__engine__");return{modifiedObjects:Array.from(e),overrideCount:r.length,hasChanges:r.length>0,overrides:r}}async function Si(r){let e=Ze(),t={};for(let[n,a]of Object.entries(e.objects)){let s=a,o=n;/^(json\.|ui\.|effects\.|engine\.)/.test(o)||(o=`json.${n}`),s&&typeof s=="object"&&(s.identity||(s.identity={}),s.identity.id=o),t[`objects/${o}.json`]=s}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 s=n.startsWith("scene.")?n:`scene.${n}`;t[`scenes/${s}.json`]=a}let i=await fetch("/api/apply",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:t,assets:{},hadCacheAtApply:re().length>0,versionName:r})});if(!i.ok){let n=await i.json();throw new Error(`Apply failed: ${n.error||"Unknown error"}`)}ge();try{let n=bi();n&&(window.__editableConfigBaseline=te(n))}catch{}localStorage.setItem("handler_last_applied",Date.now().toString()),console.log("[Config Persistence] \u2705 Applied to disk successfully")}function Dt(){ge(),window.location.reload()}async function Ei(){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"}`)}ge(),window.location.reload()}var Ds,Vn,Hs,ne=ye(()=>{"use strict";Ds="handler_preview_override_mode";if(typeof window!="undefined"){let r=window.localStorage.getItem(Ds);window.__enableConfigOverrides=r===null?!0:r==="true"}Vn=500;Hs={getCurrentConfig(){return window.__editableConfig||null},getChanges(){return window.__configChanges||[]},clearChanges(){window.__configChanges=[],window.__configChangeRedo=[]}}});function Zo(r,e){try{if(typeof r=="object"&&r!==null)return r;if(typeof r!="string")return null;if(r.startsWith("data:")){let i=r.indexOf(",");if(i===-1)return null;let n=r.slice(0,i);if(!n.includes("application/json")&&!n.includes("text/plain"))return null;let a=r.slice(i+1),s=n.includes("base64")?typeof atob=="function"?atob(a):a:decodeURIComponent(a);return JSON.parse(s)}let t=r.trim();return t.startsWith("{")||t.startsWith("[")?JSON.parse(r):null}catch{return null}}function Qo(r){if(typeof window=="undefined"||!window.INLINE_ASSETS)return null;let e=window.INLINE_ASSETS,t=r.replace(/^\.\/+/,""),i=t.split("/").pop()||t,n=[t,i,t.replace(/\.json$/,""),i.replace(/\.json$/,"")];for(let a of n){let s=e[a];if(s){let o=Zo(s,a);if(o!==null)return o}}return null}async function Nt(r){if(Wn.has(r)&&!Kn)return console.log(`[CONFIG] Using cached config for: "${r}"`),Wn.get(r);if(console.log(`[CONFIG] loadConfigFile called with: "${r}", MODE: ${K.toUpperCase()}, CACHE: ${Kn?"DISABLED":"ENABLED"}`),K==="publish"){let i=Qo(r);return i?(console.log(`[CONFIG] \u2713 Loaded ${r} via INLINE_ASSETS`),i):(console.log(`[CONFIG] \u2139\uFE0F Optional config ${r} not in INLINE_ASSETS, skipping fetch in publish mode`),{})}K==="brand"||console.log(`[CONFIG] DEV MODE: Trying nested paths first, then flattened for "${r}"`);let e;K==="brand"?e=[`./${r.split("/").pop()||r}`,`./${r}`,`./${r.replace(/^configs\//,"")}`,`./${r.replace(/^configs\//,"").replace(/\//g,".")}`]:e=[`./${r}`,`./${r.replace(/^configs\//,"")}`,`./${r.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=Kn?"no-store":"force-cache";for(let n of e)try{let a=await fetch(n,{cache:i});if(!a.ok)continue;let s=await a.json();return console.log(`[CONFIG] \u2713 Loaded ${r} via ${n}`,s),s}catch(a){console.warn(`[CONFIG] \u2717 Failed to load ${n} (mode: ${K}):`,a)}return console.warn(`[CONFIG] \u2717 All attempts failed for ${r}; using defaults`),{}})();return Wn.set(r,t),t}async function Ci(){console.log("[CONFIG] Loading component schemas...");let r=["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 r)try{let i=K==="publish"||K==="brand"?t.split("/").pop()||t:`configs/${t}`,n=await Nt(i);n.component&&(e.set(n.component,n),console.log(`[CONFIG] \u2713 Schema loaded: ${n.component} ${K==="publish"||K==="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 Be(r){console.log(`[CONFIG] Loading object config: ${r}`);let e=K==="publish"||K==="brand"?`${r}.json`:`configs/objects/${r}.json`;return await Nt(e)}async function Ai(r){let e=new Map;if(r.objects&&Array.isArray(r.objects)){for(let t of r.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 Be(i);(!n||Object.keys(n).length===0)&&i!==t.instance_id&&(n=await Be(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 Be(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 Li(){console.log("[CONFIG] Loading engine configs...");let r=["runtime","assets","splash","loading","start","tutorial","endgame"],e=await Promise.all(r.map(i=>{let n=`engine.${i}.json`,a=K==="publish"||K==="brand"?n:`configs/engine/${n}`;return Nt(a)})),t=Object.fromEntries(r.map((i,n)=>[i,e[n]]));return console.log("[CONFIG] Engine configs loaded:",Object.fromEntries(r.map(i=>{var s;let n=(s=t[i])!=null?s:{},a=Object.keys(n);return[i,a.length>0?a:"empty"]}))),t}async function Xn(){return await Nt(K==="publish"||K==="brand"?"game.prompt.json":"configs/engine/game.prompt.json")}async function Ti(r="scene.main"){console.log(`[CONFIG] Loading scene config: ${r}`);let e=K==="publish"||K==="brand"?`${r}.json`:`configs/scenes/${r}.json`;return await Nt(e)}function ut(r,e){let t=[];if(!r.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||[])r.identity[n]||t.push(`Missing required identity field: ${n}`);for(let[n,a]of Object.entries(r)){if(n==="identity")continue;let s=e.get(n);if(s&&a&&typeof a=="object"){let o=a;for(let l of s.required||[])o[l]===void 0&&t.push(`Missing required field in ${n}: ${l}`);if(s.constraints&&typeof s.constraints=="object")for(let[l,c]of Object.entries(s.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(r,e){let t={...r},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 he(r,e,t,i){return typeof r!="number"||!Number.isFinite(r)?e:Math.min(Math.max(r,t),i)}function qs(r,e){if(Array.isArray(r))return{x:he(r[0],e.x,-2e3,2e3),y:he(r[1],e.y,-2e3,2e3)};if(!r||typeof r!="object")return e;let{x:t,y:i}=r;return{x:he(t,e.x,-2e3,2e3),y:he(i,e.y,-2e3,2e3)}}function el(r,e){if(Array.isArray(r))return{x:he(r[0],e.x,0,1),y:he(r[1],e.y,0,1)};if(!r||typeof r!="object")return e;let{x:t,y:i}=r;return{x:he(t,e.x,0,1),y:he(i,e.y,0,1)}}function tl(r){if(Array.isArray(r))return{x:he(r[0],.5,-10,10),y:he(r[1],.5,-10,10)};if(r&&typeof r=="object"){let{x:e,y:t}=r;return{x:he(e,.5,-10,10),y:he(t,.5,-10,10)}}return typeof r=="string"?r:null}async function Me(r="scene.main",e){var c,d,p,u,g,h,f,m,b,y,w,v,P,I,_,k,j,L;console.log("[CONFIG] ===== Starting Object-Centric Config Load =====");let t=await Ci(),i=re(),n=zt();console.log(`[CONFIG] Loader: Found ${i.length} persisted overrides, override mode: ${n}`),i.length>0&&console.log("[CONFIG] Override details:",i.map(x=>({objectId:x.objectId,path:x.path,value:typeof x.value=="string"?x.value.substring(0,50):x.value})));let a=await Ti(r);console.log(`[CONFIG] Scene config loaded: ${((c=a.objects)==null?void 0:c.length)||0} objects`);let s=await Li();console.log("[CONFIG] Loading object configs...");let o=await Ai(a);console.log(`[CONFIG] Loaded ${o.size} object configs:`,Array.from(o.keys()));for(let[x,S]of o.entries()){let E=Qe(S,t),C=ut(E,t);C.valid||console.warn(`Object ${x} validation errors:`,C.errors),(d=E.transform)!=null&&d.position&&(E.transform.position=qs(E.transform.position,{x:0,y:0})),(p=E.transform)!=null&&p.offset&&(E.transform.offset=qs(E.transform.offset,{x:0,y:0})),((u=E.transform)==null?void 0:u.anchor)!==void 0&&(E.transform.anchor=tl(E.transform.anchor)),((g=E.transform)==null?void 0:g.position_ratio)!==void 0&&E.transform.position_ratio!==null&&(E.transform.position_ratio=el(E.transform.position_ratio,{x:.5,y:.5})),o.set(x,E)}if(e){if(e.objects)for(let[x,S]of e.objects.entries())o.set(x,S);e.engine&&(s.runtime={...s.runtime,...e.engine.runtime},s.assets={...s.assets,...e.engine.assets},s.splash={...(h=s.splash)!=null?h:{},...(f=e.engine.splash)!=null?f:{}})}let l={objects:o,engine:s,scene:a,schemas:t,theme:{background_color:"#ffffff",text_color:"#000000",square_color:"#cccccc",cta_background:"#007bff",cta_text:"#ffffff"},gameplay:{}};if(typeof window!="undefined"&&(window.__editableConfig=l,window.__editableConfigBaseline||(window.__editableConfigBaseline=Qe(l,t))),i.length>0&&n){console.log(`[CONFIG] \u2705 Applying ${i.length} persisted overrides on startup`);let x=new Map;for(let C of i)if(C.path==="render.asset.path"&&C.objectId){let A=C.value;x.has(A)||x.set(A,[]),x.get(A).push(C.objectId)}for(let[C,A]of x.entries())A.length>1&&console.log(`[CONFIG] \u{1F4CB} Multiple objects sharing asset on startup: "${C}" used by: ${A.join(", ")}`);let S=new Map;for(let C of i){let A=C.objectId||"__engine__";S.has(A)||S.set(A,[]),S.get(A).push(C)}console.log("[CONFIG] Override distribution:",{totalOverrides:i.length,objectsWithOverrides:Array.from(S.keys()),overridesPerObject:Array.from(S.entries()).map(([C,A])=>({objectId:C,count:A.length,paths:A.map(T=>T.path)}))}),He(i,{silent:!1,persist:!1});let E=window.__editableConfig;if(E){for(let C of i.slice(0,5))if(C.objectId){let A=((b=(m=E.objects)==null?void 0:m.get)==null?void 0:b.call(m,C.objectId))||((y=E.objects)==null?void 0:y[C.objectId]);if(A){let T=C.path.split(".").reduce((O,M)=>O==null?void 0:O[M],A);T===C.value?console.log(`[CONFIG] \u2705 Verified override applied: ${C.objectId}.${C.path} = ${typeof C.value=="string"?C.value.substring(0,40):"\u2713"}`):console.error(`[CONFIG] \u274C Override NOT applied correctly: ${C.objectId}.${C.path}. Expected: ${C.value}, Got: ${T}`)}else console.error(`[CONFIG] \u274C Object not found after override application: ${C.objectId}`)}}console.log("[CONFIG] \u2705 Overrides applied. Current config state:",{objectCount:((w=l.objects)==null?void 0:w.size)||0,sampleOverrides:i.slice(0,3).map(C=>`${C.objectId||"engine"}.${C.path} = ${typeof C.value=="string"?C.value.substring(0,30):JSON.stringify(C.value).substring(0,30)}`)})}else i.length>0&&!n?console.warn(`[CONFIG] \u26A0\uFE0F Found ${i.length} persisted overrides but override mode is DISABLED. Overrides will NOT be applied.`):i.length===0&&console.log("[CONFIG] No persisted overrides found in localStorage");return console.log("[CONFIG] ===== Object-Centric Config Load Complete ====="),console.log("[CONFIG] Summary:",{schemas:Array.from(t.keys()),objects:Array.from(o.keys()),engine:{runtime:Object.keys((v=s.runtime)!=null?v:{}),assets:Object.keys((P=s.assets)!=null?P:{}),splash:Object.keys((I=s.splash)!=null?I:{}),loading:Object.keys((_=s.loading)!=null?_:{}),start:Object.keys((k=s.start)!=null?k:{}),tutorial:Object.keys((j=s.tutorial)!=null?j:{}),endgame:Object.keys((L=s.endgame)!=null?L:{})},scene:a.scene_id||"unknown"}),l}function Jn(r){var t,i,n,a,s,o,l,c,d,p,u,g,h,f,m,b,y,w,v,P,I,_,k,j,L,x,S,E,C,A,T,O,M;let e={gameplay:{},ui:{},theme:{},assets:{}};for(let[R,z]of r.objects.entries()){let F=((t=z.identity)==null?void 0:t.id)||R;F.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=((s=(a=z.gameplay)==null?void 0:a.tuning)==null?void 0:s.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),(F.includes("gun")||F.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)||{}),F.includes("diamond")&&(e.gameplay.diamond=z),F.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||{}),F.includes("water")&&(e.gameplay.water_drops=z),F.includes("crack")&&(e.gameplay.crack=z),F.includes("hand")&&(e.gameplay.hand=((w=z.gameplay)==null?void 0:w.tuning)||{},e.gameplay.brush_start_pos=((v=z.transform)==null?void 0:v.brush_start_pos)||{x:0,y:-120},e.gameplay.hand_scale=((P=z.transform)==null?void 0:P.scale)||1.5),F.includes("hazard")&&(e.gameplay.hazard=((I=z.gameplay)==null?void 0:I.tuning)||{},e.gameplay.danger_pos=((_=z.transform)==null?void 0:_.danger_pos)||{x:0,y:235},e.gameplay.danger_pulse=((j=(k=z.gameplay)==null?void 0:k.tuning)==null?void 0:j.danger_pulse)||{},e.gameplay.hazard_height=((x=(L=z.gameplay)==null?void 0:L.tuning)==null?void 0:x.hazard_height)||140)}return e.gameplay.timeline=((S=r.engine.runtime)==null?void 0:S.timeline)||{},e.gameplay.drag_surface=((E=r.engine.runtime)==null?void 0:E.drag_surface)||{},e.gameplay.background=((C=r.engine.runtime)==null?void 0:C.background)||{},e.gameplay.ui_styles=((A=r.engine.runtime)==null?void 0:A.ui_styles)||{},e.gameplay.label_pulse=((T=r.engine.runtime)==null?void 0:T.label_pulse)||{},e.ui=((O=r.engine.runtime)==null?void 0:O.ui)||{},e.theme=((M=r.engine.runtime)==null?void 0:M.theme)||{},e.assets=r.engine.assets||{},e}var Us,K,Wn,Kn,Zn=ye(()=>{"use strict";ne();Us=null,K="dev";if(typeof window!="undefined"){let r=window.__BUILD_SETTINGS__;if(r!=null&&r.buildMode)Us=r,K=r.buildMode,console.log("[CONFIG] Loaded inline build settings:",r,"buildMode:",K);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);Us=t,K=t.buildMode||"dev",console.log("[CONFIG] Loaded build settings:",t,"buildMode:",K)}else console.log("[CONFIG] No build-settings.json found, using default buildMode:",K)}catch(e){console.log("[CONFIG] Failed to load build-settings.json:",e instanceof Error?e.message:String(e))}}console.log("[CONFIG] Final buildMode:",K);Wn=new Map,Kn=K==="dev"||typeof window!="undefined"&&window.location.search.includes("hot-reload")});function Qn(r,e){let t=[];function i(n,a,s=""){if(n!==a){if(typeof n!=typeof a){t.push(`${s}: 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=s?`${s}.${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(`${s}: changed`)}}return i(r,e),t}function ea(r,e,t,i){let n={...t};for(let[a,s]of i.entries())n[a]&&s.defaults&&(n[a]={...s.defaults,...n[a]});return n}var Ht,et,ta=ye(()=>{"use strict";Ht=class{shouldFullReload(e){return e.type==="component"||e.type==="scene"}getAffectedObjects(e){return e.type==="object"&&e.objectId?[e.objectId]:[]}},et=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(),s=this.hashString(a),o=this.fileHashes.get(e);if(o&&o!==s&&console.log(`[HOT-RELOAD] File changed: ${e}`),o&&o!==s){console.log(`[HOT-RELOAD] File changed: ${e}`);let l=this.determineEventType(e);t(l),this.fileHashes.set(e,s)}else o||this.fileHashes.set(e,s)}}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 na(r){if(typeof window=="undefined")return;let e=typeof ia!="undefined"&&!!ia.hot,t=window.location.search.includes("hot-reload");if(!(e||t))return;let n=null,a=!1,s=null;if(t){s=new et;let h=window.__configWatcher;h!=null&&h.stop&&h.stop(),window.__configWatcher=s}let o=new Set,l=h=>{var b,y;if(!s)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 w of m)w!=null&&w.object_config&&f.add(`configs/objects/${w.object_config}.json`);for(let w of o)f.has(w)||s.unwatch(w);for(let w of f)o.has(w)||s.watch(w,v=>g(v));o=f},c=new Set,d=!1,p=async h=>{let f=await Be(h),m=Qe(f,r.activeConfig.schemas),b=ut(m,r.activeConfig.schemas);b.valid||console.warn(`[HOT-RELOAD] ${h} validation errors:`,b.errors),await r.liveEditBridge.applyObjectConfig(h,m)};async function u(h){if(!a){a=!0;try{if(d||c.size===0){r.audioSystem.destroy();let f=await Me("scene.main");r.setActiveConfig(f),r.gameObjectManager.updateConfig(f),r.CustomAssets.updateConfig(f),await r.CustomAssets.ready();let m=r.createAudioSystem(f);r.setAudioSystem(m),window.__audioSystem=m,await m.start(),r.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&&ia.hot.on("config-change",()=>{g({type:"hmr"})}),t&&(l(r.activeConfig),console.log(`[GAME] Hot-reload watcher enabled (${o.size} files)`))}var ia,Vs=ye(()=>{"use strict";ta();Zn();ia={}});var Ys={};st(Ys,{ConfigWatcher:()=>et,DefaultReloadStrategy:()=>Ht,applyDefaults:()=>Qe,diffConfigs:()=>Qn,loadAllObjectConfigs:()=>Ai,loadComponentSchemas:()=>Ci,loadEngineConfig:()=>Li,loadGamePromptConfig:()=>Xn,loadObjectCentricConfig:()=>Me,loadObjectConfig:()=>Be,loadSceneConfig:()=>Ti,rehydrateObject:()=>ea,setupHotReload:()=>na,toLegacyFormat:()=>Jn,validateObjectConfig:()=>ut});var Ii=ye(()=>{"use strict";Zn();ta();Vs()});var Ft={};st(Ft,{AssetEditorModal:()=>la});var la,gt=ye(()=>{"use strict";la=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=i}attachModalListeners(){if(!this.modal)return;this.modal.querySelectorAll("[data-modal-close]").forEach(s=>{s.addEventListener("click",()=>this.close())}),this.modal.querySelectorAll("[data-tab]").forEach(s=>{s.addEventListener("click",r=>{let c=r.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",s=>{s.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 Ws={};at(Ws,{AssetCropModal:()=>Mi});var Mi,la=be(()=>{"use strict";Mi=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=`
46
+ `,this.modal=i}attachModalListeners(){if(!this.modal)return;this.modal.querySelectorAll("[data-modal-close]").forEach(s=>{s.addEventListener("click",()=>this.close())}),this.modal.querySelectorAll("[data-tab]").forEach(s=>{s.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",s=>{s.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 Ks={};st(Ks,{AssetCropModal:()=>ji});var ji,ca=ye(()=>{"use strict";ji=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=`
47
47
  <div class="asset-crop-card">
48
48
  <div class="asset-crop-header">
49
49
  <div>
@@ -94,7 +94,7 @@
94
94
  <button class="asset-crop-apply primary" data-action="apply">Apply Crop</button>
95
95
  </div>
96
96
  </div>
97
- `,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.image&&this.image.naturalWidth>0&&this.image.naturalHeight>0?(console.log("[AssetCropModal] Image loaded:",this.image.naturalWidth,"x",this.image.naturalHeight),this.initializeCrop(),this.render()):(console.error("[AssetCropModal] Image loaded but invalid dimensions"),this.showError("Failed to load image"))},this.image.onerror=e=>{console.error("[AssetCropModal] Image load error:",e),this.showError("Failed to load image. Please check the image URL.")},this.image.src=this.options.imageSrc,this.canvas&&this.ctx&&(this.ctx.fillStyle="rgba(128, 128, 128, 0.3)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="rgba(255, 255, 255, 0.7)",this.ctx.font="14px sans-serif",this.ctx.textAlign="center",this.ctx.fillText("Loading image...",this.canvas.width/2,this.canvas.height/2)))}showError(e){var i;if(!this.canvas||!this.ctx)return;this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="rgba(255, 0, 0, 0.2)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="#ff4444",this.ctx.font="14px sans-serif",this.ctx.textAlign="center",this.ctx.fillText(e,this.canvas.width/2,this.canvas.height/2);let t=(i=this.modal)==null?void 0:i.querySelector(".asset-crop-preview-canvas");if(t){let n=t.getContext("2d");n&&(n.fillStyle="rgba(255, 0, 0, 0.2)",n.fillRect(0,0,t.width,t.height))}}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(){if(!(!this.ctx||!this.canvas)){if(!this.image||!this.image.complete||this.image.naturalWidth===0||this.image.naturalHeight===0){console.warn("[AssetCropModal] Image not ready for rendering"),this.showError("Image not loaded");return}this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);try{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()}catch(e){console.error("[AssetCropModal] Error drawing image:",e),this.showError("Error drawing image");return}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(([r,l])=>{var c;(c=this.ctx)==null||c.fillRect(r,l,a,a)})}updatePreview(){if(!this.modal||!this.image||!this.image.complete||this.image.naturalWidth===0||this.image.naturalHeight===0)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,t.clearRect(0,0,i,i);let n=i/this.cropWidth,a=i/this.cropHeight,s=Math.min(n,a),r=this.cropWidth*s,l=this.cropHeight*s,c=(i-r)/2,d=(i-l)/2;try{t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,d,r,l)}catch(p){console.error("[AssetCropModal] Error drawing preview:",p),t.fillStyle="rgba(255, 0, 0, 0.2)",t.fillRect(0,0,i,i)}}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(o){new Mi().open(o)}});var Nl={};at(Nl,{COLORS:()=>Ee,ConfigWatcher:()=>Qe,DebugPanel:()=>Yt,DefaultReloadStrategy:()=>Nt,Handler:()=>me,PlayableLoadingScreen:()=>mn,PreviewShell:()=>gn,STROKE_WIDTH:()=>Bo,THEME:()=>Go,applyConfigOverride:()=>oe,applyConfigOverrides:()=>Ne,applyConfigsToDisk:()=>xi,applyDefaults:()=>Ze,baseLottie:()=>In,bootstrap:()=>kl,clearConfigOverrides:()=>pe,clearConfigOverridesForObject:()=>Ds,configOverrideManager:()=>Ns,createPreviewShell:()=>Da,deepClone:()=>X,default:()=>Ve,defaultPreset:()=>ki,deviceGroups:()=>sa,devicePresets:()=>aa,diffConfigs:()=>Zn,exportConfigsAsJSON:()=>Je,getConfigOverrides:()=>se,getConfigStateSummary:()=>He,getOverrideMode:()=>Rt,getPresetById:()=>et,getPresetsByCategory:()=>tl,loadAllObjectConfigs:()=>Ci,loadComponentSchemas:()=>Ei,loadEngineConfig:()=>Ai,loadGamePromptConfig:()=>Kn,loadObjectCentricConfig:()=>Pe,loadObjectConfig:()=>Fe,loadSceneConfig:()=>Li,redoLastConfigChange:()=>wi,rehydrateObject:()=>Qn,removeConfigOverride:()=>zt,resetToApplied:()=>$t,resetToOriginal:()=>Si,setBootstrapDependencies:()=>Ll,setOverrideMode:()=>Vn,setupHotReload:()=>ia,setupLiveEditBridge:()=>hn,toLegacyFormat:()=>Xn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Fs,undoLastConfigChange:()=>vi,validateObjectConfig:()=>pt});module.exports=cr(Nl);var ze={};function ai(o,e,t=!1){ze[o]||(ze[o]=[]),ze[o].push({fn:e,once:t})}function An(o,e){if(ze[o]){if(!e){delete ze[o];return}ze[o]=ze[o].filter(t=>t.fn!==e)}}function si(o,...e){let t=ze[o];if(t)for(let i of[...t])i.fn(...e),i.once&&An(o,i.fn)}function re(o,e){ai(o,e,!0)}var K=null,he=[],ot=null;function ts(o){K=o,he=[],ot!==null&&(clearTimeout(ot),ot=null)}function is(){var o,e,t;return{endpoint:(K==null?void 0:K.endpoint)||"",transport:(K==null?void 0:K.transport)||"beacon",batchSize:(o=K==null?void 0:K.batchSize)!=null?o:10,flushIntervalMs:(e=K==null?void 0:K.flushIntervalMs)!=null?e:300,maxQueue:(t=K==null?void 0:K.maxQueue)!=null?t:200,debug:!!(K!=null&&K.debug)}}async function Qa(o,e,t,i){let n=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let a=navigator.sendBeacon(o,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(o,{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 Ln(o,e){let t=is();if(e&&t.endpoint){if(he.push(o),he.length>t.maxQueue&&(he=he.slice(he.length-t.maxQueue)),he.length>=t.batchSize){es();return}ot===null&&(ot=window.setTimeout(()=>{ot=null,es()},t.flushIntervalMs))}}async function es(){let o=is();if(!o.endpoint||he.length===0)return;let e=he.splice(0,o.batchSize);await Qa(o.endpoint,{events:e},o.transport,o.debug),he.length>0&&await Qa(o.endpoint,{events:he.splice(0,o.batchSize)},o.transport,o.debug)}function ns(o){return Math.max(0,Math.min(1,o))}function dr(o){let e=String(o!=null?o:"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 It(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function pr(o,e){let t=o==null?void 0:o[e];return typeof t=="number"?t:0}function as(o,e,t){try{o[e]=t}catch{}}function ur(o){let e=o==null?void 0:o.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 ss(o,e){let t=o==null?void 0:o.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 os(o,e){let t=ur(o);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 rs(){let o=new Set,e=new WeakMap,t=null,i=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,r(),o.size>0&&i()})},n=d=>{var u;o.add(d);let p=(u=e.get(d.target))!=null?u:new Set;p.add(d),e.set(d.target,p),i()},a=d=>{o.delete(d);let p=e.get(d.target);p&&(p.delete(d),p.size===0&&e.delete(d.target))},s=d=>{d.killed||(d.killed=!0,a(d))},r=()=>{var p,u;let d=It();for(let g of Array.from(o)){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=ns(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 I=f-y;m=ns(I)}let v=g.ease(m);g.yoyo&&y%2===1&&(v=1-v);for(let I of g.props)as(g.target,I.key,I.from+(I.to-I.from)*v);g.scaleFrom&&g.scaleTo&&ss(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){s(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var I;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+((I=u==null?void 0:u.delayMsOverride)!=null?I:0)),f=dr(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 _=p[P];typeof _=="number"&&v.push({key:P,from:pr(d,P),to:_})}let w=os(d,p);return{target:d,startMs:It(),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:()=>s(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=It())},resume:()=>{var f;if(!u.paused)return;let g=(f=u.pauseAtMs)!=null?f:It(),h=It()-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"&&as(d,g,h)}let u=os(d,p);u.to&&ss(d,u.to)},killTweensOf(d){let p=e.get(d);if(p)for(let u of Array.from(p))s(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,I){return m({kind:"fromTo",target:y,vars:w,from:v,atMs:f(I)}),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 ls(){if(typeof window=="undefined")return;let o=window;if(!o.gsap)try{o.gsap=rs()}catch{}}var cs={name:"handler-playable-sdk",version:"1.0.95",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 --external jszip && 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/ && mkdir -p dist/cli/student-helper && cp src/cli/student-helper/*.mjs dist/cli/student-helper/ && chmod +x dist/cli/*.mjs dist/cli/student-helper/*.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 --external jszip && 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 dist/cli/student-helper/*.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 le=0,hr=le++,ds=le++,ps=le++,us=le++,gs=le++,hs=le++,fs=le++,ms=le++,bs=le++,ys=le++,vs=le++,ws=le++,W=hr;function xs(){return W===ds}function Ss(){return W===ps}function Es(){return W===us}function Cs(){return W===gs}function rt(){return W===hs}function lt(){return W===fs}function As(){return W===ms}function Ls(){return W===bs}function Ts(){return W===ys}function Tn(){return W===vs}function kn(){return W===ws}function ks(){let o=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(o==="mraid")try{mraid.getState(),W=ds;return}catch{}else if(o==="dapi")try{dapi.isReady(),W=ps;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(W=us)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(W=gs)}catch{}else if(e==="mintegral")window.gameReady&&(W=hs);else if(e==="tapjoy")window.TJ_API&&(W=fs);else if(e==="tiktok")window.openAppStore&&(W=ms);else if(e==="smadex")try{window.smxTracking&&(W=bs)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(W=ys)}catch{}else e==="vungle"?W=vs:(o==="nucleo"||e==="nucleo")&&(W=ws)}var oi=st(require("lottie-web"),1),In=oi.default;typeof window!="undefined"&&(window.lottie=oi.default,window.__baseLottie=oi.default);var fr=require("pixi.js");var Pn=require("pixi.js");var mr=null;function Mn(o){mr=o}li();ri();var Pt=require("pixi.js");li();var Sr=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Rn=Sr;if(typeof window!="undefined")try{let o=new XMLHttpRequest;if(o.open("GET","./build-settings.json",!1),o.send(),o.status===200&&o.responseText){let e=JSON.parse(o.responseText);e!=null&&e.buildMode&&(Rn=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Rn}`))}}catch{}function Er(o){var t,i,n,a,s;if(typeof window!="undefined"&&window.resolveAnchorVec2)return window.resolveAnchorVec2(o);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(o))return{x:(t=o[0])!=null?t:.5,y:(i=o[1])!=null?i:.5};if(o&&typeof o=="object"&&"x"in o&&"y"in o)return{x:(n=o.x)!=null?n:.5,y:(a=o.y)!=null?a:.5};if(typeof o=="string"){let r=o.trim().toLowerCase();return(s=e[r])!=null?s:{x:.5,y:.5}}return null}var ve=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Rn}`);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 Pt.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 s=await We.load(e,n,i,a);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(d=s==null?void 0:s.constructor)==null?void 0:d.name}`);let r;if(n.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",s,"for object:",e),r=new Pt.Sprite(s),console.log("[ObjectFactory] Created object:",r,"type:",(p=r==null?void 0:r.constructor)==null?void 0:p.name),this.applyTransform(r,t==null?void 0:t.transform,t);else if(n.type==="json")if(console.log("[ObjectFactory] JSON asset for",e,"rawAsset type:",(u=s==null?void 0:s.constructor)==null?void 0:u.name,s),s&&(((g=s.constructor)==null?void 0:g.name)==="Container"||s instanceof Pt.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){r=await y.json(),console.log("[ObjectFactory] Reloaded JSON directly from:",b,"type:",(h=r==null?void 0:r.constructor)==null?void 0:h.name),m=!0;break}}catch{continue}m||(console.error("[ObjectFactory] Failed to reload JSON from any path"),r=s)}else r=s;else r=s,r&&typeof r=="object"&&("x"in r||"position"in r)&&this.applyTransform(r,t==null?void 0:t.transform,t);return r}static applyTransform(e,t,i){var n,a,s,r;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((s=t.position.x)!=null?s:0,(r=t.position.y)!=null?r: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=Er(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 Mt=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 Lr=st(require("pixi.js"),1);typeof window!="undefined"&&(window.__basePixi=Lr);ct();var ci=require("pixi.js");ct();var Dn=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new Mt}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 r;let s=this.registry.get(a);if(!s){console.warn("[Assets] No config found for object:",a);return}try{let l=await ve.create(a,s,this.app);this.instanceCache.set(a,l),console.log("[Assets] Loaded object:",a,(r=l==null?void 0:l.constructor)==null?void 0:r.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 ve.create(e,t,this.app);this.instanceCache.set(e,i)}}get(e){return this.instanceCache.get(e)}},Tr=new Dn,kr=new Proxy(Tr,{get(o,e){if(e in o&&typeof o[e]=="function")return o[e].bind(o);if(o.get(e))return o.get(e)}});ct();var Pr=require("pixi.js"),Le={width:400,height:600,designWidth:400,scaleFactor:1},pi={scale:1,position:1},Hn=[];function Mr(o,e,t,i,n,a,s){Hn.push({element:o,originalScale:a,positionHelper:e,heightPercent:n}),e(o,t,i,n,a,s,!1)}function jr(){Hn.forEach(({element:o,originalScale:e,positionHelper:t,heightPercent:i})=>{let n=e*Le.scaleFactor;t(o,Le.width,Le.height,i,n,!0,!1)})}function Nn(o,e){console.log(`[SCREEN] updateScreenState called: ${o}x${e}`),Le.width=o,Le.height=e,Le.scaleFactor=Math.min(o/Le.designWidth,1.15),pi.scale=Le.scaleFactor,pi.position=1,console.log(`[SCREEN] Global multipliers - scale: ${pi.scale.toFixed(3)}`),jr()}var _t={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 _r(o,e,t){let i=_t[o];i&&i[e]!==void 0&&(i[e]=t,console.log(`Updated ${o}.${e} = ${t}`))}function Or(){return _t}var Rr={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 di(o,e){return typeof o=="number"&&Number.isFinite(o)?o:e}function Xe(o,e={x:.5,y:.5}){var t;if(Array.isArray(o))return{x:di(o[0],e.x),y:di(o[1],e.y)};if(o&&typeof o=="object"){let i=o;return{x:di(i.x,e.x),y:di(i.y,e.y)}}if(typeof o=="string"){let i=o.trim().toLowerCase();return(t=Rr[i])!=null?t:e}return e}function De(o,e,t,i={}){var g,h,f,m,b,y;let n=Xe(t),a=(g=i.inset)!=null?g:{},s=(h=i.padding)!=null?h:{x:0,y:0},r=((f=a.left)!=null?f:0)+s.x,l=((m=a.right)!=null?m:0)+s.x,c=((b=a.top)!=null?b:0)+s.y,d=((y=a.bottom)!=null?y:0)+s.y,p=Math.max(0,o-r-l),u=Math.max(0,e-c-d);return{x:r+p*n.x,y:c+u*n.y}}function dt(o,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},s=((b=n.left)!=null?b:0)+a.x,r=((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,o-s-r),p=Math.max(0,e-l-c),u=Xe(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:s+d*g,y:l+p*h}}if(typeof window!="undefined"){let o=window.innerWidth,e=window.innerHeight,t=()=>{let i=window.innerWidth,n=window.innerHeight;(i!==o||n!==e)&&(o=i,e=n,Nn(i,n))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),Nn(window.innerWidth,window.innerHeight),window.updateDebugConfig=_r,window.getDebugConfig=Or,window.copyConfig=Vr,window.applyConfig=jt,window.applyConfigForRatio=Yr,window.positionAtBottom=Os,window.positionAtTop=Dr,window.positionAtCenter=Nr,window.positionAtLeft=Hr,window.positionAtRight=Fr,window.positionAtBottomLeft=Br,window.positionAtBottomRight=Gr,window.positionAtTopLeft=Ur,window.positionAtTopRight=qr,window.applyPositionContract=$r,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 ui(o,e,t=0){return o*e+t}function gi(o,e,t=0){return o*(1-e)+t}function hi(o,e,t=0){return o*e+t}function fi(o,e,t=0){return o*(1-e)+t}function de(o,e=0){return o/2+e}function zr(o,e){return o*e}function $r(o,e,t,i){var s,r,l,c,d,p,u,g,h,f,m,b,y,v,w,I,P,_,T,M;let n=0,a=0;switch(i.type){case"top":n=de(e,(r=(s=i.offset)==null?void 0:s.x)!=null?r:0),a=ui(t,i.percent,(c=(l=i.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":n=de(e,(p=(d=i.offset)==null?void 0:d.x)!=null?p:0),a=gi(t,i.percent,(g=(u=i.offset)==null?void 0:u.y)!=null?g:0);break;case"left":n=hi(e,i.percent,(f=(h=i.offset)==null?void 0:h.x)!=null?f:0),a=de(t,(b=(m=i.offset)==null?void 0:m.y)!=null?b:0);break;case"right":n=fi(e,i.percent,(v=(y=i.offset)==null?void 0:y.x)!=null?v:0),a=de(t,(I=(w=i.offset)==null?void 0:w.y)!=null?I:0);break;case"center":n=de(e,(_=(P=i.offset)==null?void 0:P.x)!=null?_:0),a=de(t,(M=(T=i.offset)==null?void 0:T.y)!=null?M:0);break}o.position?o.position.set(n,a):(o.x=n,o.y=a),i.scale!==void 0&&i.scale!==1&&o.scale&&(typeof o.scale.set=="function"?o.scale.set(i.scale,i.scale):(o.scale.x=i.scale,o.scale.y=i.scale))}function Os(o,e,t,i=.2,n=1,a=!0,s=!1){let r=zr(t,i),l=gi(t,i/2);Te(o,de(e),l);let c=a?n*Le.scaleFactor:n;ke(o,c),s&&!Hn.find(d=>d.element===o)&&Mr(o,Os,e,t,i,n,a)}function Dr(o,e,t,i=.1,n=1){Te(o,de(e),ui(t,i)),ke(o,n)}function Nr(o,e,t,i=0,n=0,a=1){Te(o,de(e,i),de(t,n)),ke(o,a)}function Hr(o,e,t,i=.1,n=1){Te(o,hi(e,i),de(t)),ke(o,n)}function Fr(o,e,t,i=.1,n=1){Te(o,fi(e,i),de(t)),ke(o,n)}function Br(o,e,t,i=.05,n=.05,a=1){Te(o,hi(e,n),gi(t,i)),ke(o,a)}function Gr(o,e,t,i=.05,n=.05,a=1){Te(o,fi(e,n),gi(t,i)),ke(o,a)}function Ur(o,e,t,i=.05,n=.05,a=1){Te(o,hi(e,n),ui(t,i)),ke(o,a)}function qr(o,e,t,i=.05,n=.05,a=1){Te(o,fi(e,n),ui(t,i)),ke(o,a)}function Te(o,e,t){o&&o.position?typeof o.position.set=="function"?o.position.set(e,t):(o.position.x=e,o.position.y=t):o&&(o.x=e,o.y=t)}function ke(o,e){e!==1&&o&&o.scale&&(typeof o.scale.set=="function"?o.scale.set(e,e):o.scale.x!==void 0&&o.scale.y!==void 0&&(o.scale.x=e,o.scale.y=e))}var Ke={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 Vr(o){return o&&Ke[o]?JSON.parse(JSON.stringify(Ke[o])):JSON.parse(JSON.stringify(_t))}function jt(o){Object.keys(o).forEach(e=>{let t=e;_t[t]&&o[t]&&Object.assign(_t[t],o[t])}),console.log("Config applied:",o)}function Yr(o,e){let t=o/e;t>1.6?(jt(Ke.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(jt(Ke.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(jt(Ke.square),console.log("Applied SQUARE config for ratio:",t)):(jt(Ke.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let o=window;o.configPresets=Ke,o.resolveAnchorVec2=o.resolveAnchorVec2||Xe,o.resolveScreenAnchorPoint=o.resolveScreenAnchorPoint||De,o.resolveScreenRatioPoint=o.resolveScreenRatioPoint||dt}Ti();function J(o,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(o,e);return`${o/i}:${e/i}`}var hd=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:J(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:J(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:J(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:J(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:J(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:J(360,780)}],fd=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:J(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:J(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:J(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:J(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:J(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:J(412,915)}],md=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:J(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:J(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:J(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:J(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:J(800,1280)}],na=[{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:J(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:J(768,1024),mraidScale:.7}];var aa=[...na],sa=[{category:"playable",label:"Playable Ad",devices:na}],ki=na[0];function et(o){return aa.find(e=>e.id===o)||ki}function tl(o){return aa.filter(e=>e.category===o)}Q();var xe=class{async updateProperty(e,t,i,n={}){var l,c,d,p,u,g,h,f,m,b,y,v;console.log("[PropertyUpdateManager] Updating:",e,t,i);let a=window.getEditableObjectConfig;if(typeof a!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let s=a(e);if(!s){console.error("[PropertyUpdateManager] Config not found for:",e);return}if(oe({objectId:e,path:t,value:i},{persist:!0}),t==="transform"||t.startsWith("transform.")){console.log("[DEBUG FALLBACK] PropertyUpdateManager SKIP applyEditableObjectConfig (transform path)",t,e);let w=s==null?void 0:s.motion;if(w&&typeof w=="object"&&w.enabled!==!1&&(((p=w==null?void 0:w.intro)==null?void 0:p.enabled)===!0||((u=w==null?void 0:w.pulse)==null?void 0:u.enabled)===!0||((g=w==null?void 0:w.swing)==null?void 0:g.enabled)===!0||((h=w==null?void 0:w.continuousMove)==null?void 0:h.enabled)===!0||((f=w==null?void 0:w.continuousRotate)==null?void 0:f.enabled)===!0||((m=w==null?void 0:w.orbit)==null?void 0:m.enabled)===!0)){let _=window.applyEditableObjectConfig;if(typeof _=="function"){let T=window.__editableConfig,M=(v=(y=(b=T==null?void 0:T.objects)==null?void 0:b.get)==null?void 0:y.call(b,e))!=null?v:s;await _(e,M),console.log("[PropertyUpdateManager] Applied config for motion object")}}n.refreshInspector||requestAnimationFrame(()=>{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e}}))})}else{let w=window.applyEditableObjectConfig;if(typeof w=="function"){let I=window.__editableConfig,P=(d=(c=(l=I==null?void 0:I.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:s;await w(e,P),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 oa(o){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()=>{var g,h,f,m;let s=n.result;if(!s||typeof s!="string"){alert("Failed to read file: Invalid data URL"),console.error("[QuickActionsBar] Invalid data URL:",typeof s,s==null?void 0:s.substring(0,50));return}if(!s.startsWith("data:image/")){alert("Invalid file format: Not an image file"),console.error("[QuickActionsBar] Invalid data URL format:",s.substring(0,100));return}let r=s.match(/^data:image\/[^;]+;base64,(.+)$/);if(!r||!r[1]||r[1].length===0){alert("Failed to read file: Invalid base64 data"),console.error("[QuickActionsBar] Invalid base64 data in data URL");return}try{let b=r[1],y=atob(b.substring(0,Math.min(100,b.length)));if(!y||y.length===0)throw new Error("Base64 decode test failed");console.log("[QuickActionsBar] \u2705 Data URL validated, length:",s.length)}catch(b){alert("Failed to read file: Corrupted image data"),console.error("[QuickActionsBar] Base64 validation failed:",b);return}let l=o.category||"misc",c=(o.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),d=((g=i.name.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/))==null?void 0:g[1])||"png",p=d==="jpg"?"jpeg":d,u=`${c||"new_asset"}_uploaded_${Date.now()}.${p}`;console.log("[QuickActionsBar] Uploading file:",u,"to category:",l,"data URL length:",s.length);try{let y=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:l,filename:u,data:s,overwrite:!0})})).json();if(!(y!=null&&y.success)){alert(`Upload failed: ${(y==null?void 0:y.error)||"Unknown error"}`);return}await new Promise(A=>setTimeout(A,100));let v=window.addAssetToRegistry;typeof v=="function"&&(v(l,u),console.log("[QuickActionsBar] \u2705 Added to registry:",l,u));let w=window.getEditableAssets;if(typeof w=="function"){let A=w();A&&!A.categories&&(A.categories=[]),A!=null&&A.categories&&!A.categories.includes(l)&&(A.categories.push(l),console.log(`[QuickActionsBar] Added category ${l} to registry`))}let I=!1,P=0,_=10;for(;!I&&P<_;){P++,console.log(`[QuickActionsBar] Refresh attempt ${P}/${_}...`);try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&console.log("[QuickActionsBar] \u2705 Registry rebuilt from disk")}catch{}await new Promise(x=>setTimeout(x,300));let A=window.refreshAssetLibrary;typeof A=="function"&&(console.log("[QuickActionsBar] Refreshing library panel..."),await A());let C=window.reRenderAssetLibrary;typeof C=="function"&&(console.log("[QuickActionsBar] Re-rendering library panel..."),C());let L=window.getEditableAssets;if(typeof L=="function"){let x=L(),E=((h=x==null?void 0:x.libraryAssets)==null?void 0:h[l])||[];E.some(O=>(O==null?void 0:O.filename)===u)?(console.log("[QuickActionsBar] \u2705 Asset found in registry!"),I=!0):(console.log(`[QuickActionsBar] Asset not found yet, retrying... (found ${E.length} assets in ${l})`),await new Promise(O=>setTimeout(O,500)))}else P>=2&&(I=!0)}I||console.warn("[QuickActionsBar] \u26A0\uFE0F Asset not found in registry after retries, proceeding anyway..."),setTimeout(()=>{try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[QuickActionsBar] Dispatched config:changed event")}catch(A){console.warn("[QuickActionsBar] Failed to refresh textures:",A)}},300),console.log("[QuickActionsBar] Applying asset to object:",y.path);let T=!1,M=0,k=5;for(;!T&&M<k;){M++;try{await o.onApply(y.path),await new Promise(C=>setTimeout(C,200));let A=window.getEditableObjectConfig;if(typeof A=="function"){let C=A(o.objectId),L=((m=(f=C==null?void 0:C.render)==null?void 0:f.asset)==null?void 0:m.path)||"";L===y.path||L.includes(u)?(console.log("[QuickActionsBar] \u2705 Asset confirmed applied to object"),T=!0):(console.log(`[QuickActionsBar] Asset not applied yet (attempt ${M}), retrying...`),await new Promise(x=>setTimeout(x,300)))}else T=!0}catch(A){console.error(`[QuickActionsBar] Apply attempt ${M} failed:`,A),M<k&&await new Promise(C=>setTimeout(C,500))}}T?console.log("[QuickActionsBar] \u2705 Asset upload and apply complete!"):console.warn("[QuickActionsBar] \u26A0\uFE0F Asset may not have been applied, but upload succeeded")}catch(b){console.error("[QuickActionsBar] Upload error:",b),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var Ii=class{constructor(){this.updateManager=new xe}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 s=this.updateManager.getNestedProperty(a,i);if(e==="ai-convert"||e==="upload"||e==="library"){let r=i==="ui.text"||i==="render.asset.path",l=i==="render.asset.path";r&&(await this.prepareForImageConversion(t,a),e==="ai-convert"&&i!=="render.asset.path"&&(i="render.asset.path"))}switch(e){case"library":this.openLibrary(t,i,s);break;case"ai-edit":this.openAIEditor(t,i,s);break;case"upload":this.openUpload(t,i);break;case"reset":await this.resetToDefault(t,i);break;case"ai-convert":this.handleAiConvert(t,i,s);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 s=((n=(i=t.transform)==null?void 0:i.scale)!=null?n:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",s),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",s)}this.ensureSlotInRegistry(e,t)}ensureSlotInRegistry(e,t){var r,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=((r=t.identity)==null?void 0:r.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 s=window.__updateWorkbenchTabs;typeof s=="function"&&s()}if(n.libraryPanel){let s=window.getEditableObjectConfig,r=s==null?void 0:s(e),l=(a=r==null?void 0:r.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 s;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e),a=((s=n==null?void 0:n.identity)==null?void 0:s.category)||(t.split(".")[0]==="render"?"environment":"ui");oa({objectId:e,category:a,onApply:async r=>{var g,h;console.log("[QuickActionsBar] Upload complete, applying asset:",r);let l=window.applyAssetToSlot,c=this.getFilenameFromPath(r),d=/render\.asset\.path/i.test(t)||/\.(png|jpg|jpeg|gif|webp)$/i.test(r);if(typeof l=="function"&&c&&d){console.log("[QuickActionsBar] Applying asset to slot:",e,c,a);try{await l(e,c,a),console.log("[QuickActionsBar] \u2705 Asset applied to slot")}catch(f){console.error("[QuickActionsBar] Failed to apply asset to slot:",f)}}console.log("[QuickActionsBar] Updating property:",e,t,r);try{await this.updateManager.updateProperty(e,t,r),console.log("[QuickActionsBar] \u2705 Property updated")}catch(f){console.error("[QuickActionsBar] Failed to update property:",f)}let p=window.__debugContext;(h=(g=p==null?void 0:p.options)==null?void 0:g.onPropertyChange)==null||h.call(g,e,t,r);let u=window.__highlightLibrarySlot;typeof u=="function"&&setTimeout(()=>{u(e,a)},1e3),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e,action:"update",path:t}})),console.log("[QuickActionsBar] \u2705 Upload and apply complete")}})}getFilenameFromPath(e){if(!e)return"";let t=e.split("?")[0].replace(/\\/g,"/");return t.split("/").pop()||t}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),s=window.__editableConfig;if(!(s!=null&&s.schemas))return;let r=null;if(s.schemas instanceof Map?r=s.schemas.get(n):typeof s.schemas=="object"&&(r=s.schemas[n]),!(r!=null&&r.defaults))return;let l=r.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 s=`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.`,r="render.asset.path";console.log("[QuickActionsBar] AI Convert for:",e,"from:",t,"to:",r),n(e,s,"",{objectId:e,path:r});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 il=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],nl=["environment","ui","character","system","backgrounds"],al=["bg","world","ui"],Ys={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}}},Pi=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=`
97
+ `,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.image&&this.image.naturalWidth>0&&this.image.naturalHeight>0?(console.log("[AssetCropModal] Image loaded:",this.image.naturalWidth,"x",this.image.naturalHeight),this.initializeCrop(),this.render()):(console.error("[AssetCropModal] Image loaded but invalid dimensions"),this.showError("Failed to load image"))},this.image.onerror=e=>{console.error("[AssetCropModal] Image load error:",e),this.showError("Failed to load image. Please check the image URL.")},this.image.src=this.options.imageSrc,this.canvas&&this.ctx&&(this.ctx.fillStyle="rgba(128, 128, 128, 0.3)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="rgba(255, 255, 255, 0.7)",this.ctx.font="14px sans-serif",this.ctx.textAlign="center",this.ctx.fillText("Loading image...",this.canvas.width/2,this.canvas.height/2)))}showError(e){var i;if(!this.canvas||!this.ctx)return;this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="rgba(255, 0, 0, 0.2)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="#ff4444",this.ctx.font="14px sans-serif",this.ctx.textAlign="center",this.ctx.fillText(e,this.canvas.width/2,this.canvas.height/2);let t=(i=this.modal)==null?void 0:i.querySelector(".asset-crop-preview-canvas");if(t){let n=t.getContext("2d");n&&(n.fillStyle="rgba(255, 0, 0, 0.2)",n.fillRect(0,0,t.width,t.height))}}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(){if(!(!this.ctx||!this.canvas)){if(!this.image||!this.image.complete||this.image.naturalWidth===0||this.image.naturalHeight===0){console.warn("[AssetCropModal] Image not ready for rendering"),this.showError("Image not loaded");return}this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);try{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()}catch(e){console.error("[AssetCropModal] Error drawing image:",e),this.showError("Error drawing image");return}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||!this.image.complete||this.image.naturalWidth===0||this.image.naturalHeight===0)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,t.clearRect(0,0,i,i);let n=i/this.cropWidth,a=i/this.cropHeight,s=Math.min(n,a),o=this.cropWidth*s,l=this.cropHeight*s,c=(i-o)/2,d=(i-l)/2;try{t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,d,o,l)}catch(p){console.error("[AssetCropModal] Error drawing preview:",p),t.fillStyle="rgba(255, 0, 0, 0.2)",t.fillRect(0,0,i,i)}}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(r){new ji().open(r)}});var Nl={};st(Nl,{COLORS:()=>Ce,ConfigWatcher:()=>et,DebugPanel:()=>Wt,DefaultReloadStrategy:()=>Ht,Handler:()=>be,PlayableLoadingScreen:()=>yn,PreviewShell:()=>fn,STROKE_WIDTH:()=>Br,THEME:()=>Gr,applyConfigOverride:()=>le,applyConfigOverrides:()=>He,applyConfigsToDisk:()=>Si,applyDefaults:()=>Qe,baseLottie:()=>Pn,bootstrap:()=>Il,clearConfigOverrides:()=>ge,clearConfigOverridesForObject:()=>Ns,configOverrideManager:()=>Hs,createPreviewShell:()=>Na,deepClone:()=>te,default:()=>Ye,defaultPreset:()=>ki,deviceGroups:()=>ra,devicePresets:()=>sa,diffConfigs:()=>Qn,exportConfigsAsJSON:()=>Ze,getConfigOverrides:()=>re,getConfigStateSummary:()=>Fe,getOverrideMode:()=>zt,getPresetById:()=>tt,getPresetsByCategory:()=>il,loadAllObjectConfigs:()=>Ai,loadComponentSchemas:()=>Ci,loadEngineConfig:()=>Li,loadGamePromptConfig:()=>Xn,loadObjectCentricConfig:()=>Me,loadObjectConfig:()=>Be,loadSceneConfig:()=>Ti,redoLastConfigChange:()=>xi,rehydrateObject:()=>ea,removeConfigOverride:()=>$t,resetToApplied:()=>Dt,resetToOriginal:()=>Ei,setBootstrapDependencies:()=>Ll,setOverrideMode:()=>Yn,setupHotReload:()=>na,setupLiveEditBridge:()=>mn,toLegacyFormat:()=>Jn,trackObjectCreation:()=>Fs,trackObjectDeletion:()=>Bs,undoLastConfigChange:()=>wi,validateObjectConfig:()=>ut});module.exports=co(Nl);var $e={};function si(r,e,t=!1){$e[r]||($e[r]=[]),$e[r].push({fn:e,once:t})}function Ln(r,e){if($e[r]){if(!e){delete $e[r];return}$e[r]=$e[r].filter(t=>t.fn!==e)}}function ri(r,...e){let t=$e[r];if(t)for(let i of[...t])i.fn(...e),i.once&&Ln(r,i.fn)}function ce(r,e){si(r,e,!0)}var ee=null,fe=[],ot=null;function is(r){ee=r,fe=[],ot!==null&&(clearTimeout(ot),ot=null)}function ns(){var r,e,t;return{endpoint:(ee==null?void 0:ee.endpoint)||"",transport:(ee==null?void 0:ee.transport)||"beacon",batchSize:(r=ee==null?void 0:ee.batchSize)!=null?r:10,flushIntervalMs:(e=ee==null?void 0:ee.flushIntervalMs)!=null?e:300,maxQueue:(t=ee==null?void 0:ee.maxQueue)!=null?t:200,debug:!!(ee!=null&&ee.debug)}}async function es(r,e,t,i){let n=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let a=navigator.sendBeacon(r,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(r,{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 Tn(r,e){let t=ns();if(e&&t.endpoint){if(fe.push(r),fe.length>t.maxQueue&&(fe=fe.slice(fe.length-t.maxQueue)),fe.length>=t.batchSize){ts();return}ot===null&&(ot=window.setTimeout(()=>{ot=null,ts()},t.flushIntervalMs))}}async function ts(){let r=ns();if(!r.endpoint||fe.length===0)return;let e=fe.splice(0,r.batchSize);await es(r.endpoint,{events:e},r.transport,r.debug),fe.length>0&&await es(r.endpoint,{events:fe.splice(0,r.batchSize)},r.transport,r.debug)}function as(r){return Math.max(0,Math.min(1,r))}function po(r){let e=String(r!=null?r:"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 Pt(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function uo(r,e){let t=r==null?void 0:r[e];return typeof t=="number"?t:0}function ss(r,e,t){try{r[e]=t}catch{}}function go(r){let e=r==null?void 0:r.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 rs(r,e){let t=r==null?void 0:r.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 os(r,e){let t=go(r);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 ls(){let r=new Set,e=new WeakMap,t=null,i=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,o(),r.size>0&&i()})},n=d=>{var u;r.add(d);let p=(u=e.get(d.target))!=null?u:new Set;p.add(d),e.set(d.target,p),i()},a=d=>{r.delete(d);let p=e.get(d.target);p&&(p.delete(d),p.size===0&&e.delete(d.target))},s=d=>{d.killed||(d.killed=!0,a(d))},o=()=>{var p,u;let d=Pt();for(let g of Array.from(r)){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=as(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 P=f-y;m=as(P)}let w=g.ease(m);g.yoyo&&y%2===1&&(w=1-w);for(let P of g.props)ss(g.target,P.key,P.from+(P.to-P.from)*w);g.scaleFrom&&g.scaleTo&&rs(g.target,{x:g.scaleFrom.x+(g.scaleTo.x-g.scaleFrom.x)*w,y:g.scaleFrom.y+(g.scaleTo.y-g.scaleFrom.y)*w});try{(p=g.onUpdate)==null||p.call(g)}catch{}if(f>=b){s(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var P;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+((P=u==null?void 0:u.delayMsOverride)!=null?P:0)),f=po(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"]),w=[];for(let I of Object.keys(p)){if(y.has(I))continue;let _=p[I];typeof _=="number"&&w.push({key:I,from:uo(d,I),to:_})}let v=os(d,p);return{target:d,startMs:Pt(),delayMs:h,durationMs:g,ease:f,props:w,scaleFrom:v.from,scaleTo:v.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:()=>s(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=Pt())},resume:()=>{var f;if(!u.paused)return;let g=(f=u.pauseAtMs)!=null?f:Pt(),h=Pt()-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"&&ss(d,g,h)}let u=os(d,p);u.to&&rs(d,u.to)},killTweensOf(d){let p=e.get(d);if(p)for(let u of Array.from(p))s(u)},timeline(d={}){let p=[],u=0,g=!1,h=[],f=y=>{if(typeof y=="number")return Math.max(0,y*1e3);let w=typeof y=="string"?y.trim():"";return w.startsWith("+=")?u+Math.max(0,Number(w.slice(2))*1e3||0):w?Math.max(0,Number(w)*1e3||0):u},m=y=>{p.push(y);let w=Math.max(0,(typeof y.vars.duration=="number"?y.vars.duration:.5)*1e3);u=Math.max(u,y.atMs+w)},b={to(y,w,v){return m({kind:"to",target:y,vars:w,atMs:f(v)}),b},fromTo(y,w,v,P){return m({kind:"fromTo",target:y,vars:v,from:w,atMs:f(P)}),b},play(){var y,w;if(g)return b;g=!0,h=[];for(let v of p)v.kind==="fromTo"&&c.set(v.target,(y=v.from)!=null?y:{}),h.push(c.to(v.target,{...v.vars,delay:v.atMs/1e3+((w=v.vars.delay)!=null?w: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 cs(){if(typeof window=="undefined")return;let r=window;if(!r.gsap)try{r.gsap=ls()}catch{}}var ds={name:"handler-playable-sdk",version:"1.0.100",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 --external jszip && 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/ && mkdir -p dist/cli/student-helper && cp src/cli/student-helper/*.mjs dist/cli/student-helper/ && chmod +x dist/cli/*.mjs dist/cli/student-helper/*.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 --external jszip && 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 dist/cli/student-helper/*.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 de=0,fo=de++,ps=de++,us=de++,gs=de++,hs=de++,fs=de++,ms=de++,bs=de++,ys=de++,vs=de++,ws=de++,xs=de++,J=fo;function Ss(){return J===ps}function Es(){return J===us}function Cs(){return J===gs}function As(){return J===hs}function lt(){return J===fs}function ct(){return J===ms}function Ls(){return J===bs}function Ts(){return J===ys}function Is(){return J===vs}function In(){return J===ws}function kn(){return J===xs}function ks(){let r=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(r==="mraid")try{mraid.getState(),J=ps;return}catch{}else if(r==="dapi")try{dapi.isReady(),J=us;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(J=gs)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(J=hs)}catch{}else if(e==="mintegral")window.gameReady&&(J=fs);else if(e==="tapjoy")window.TJ_API&&(J=ms);else if(e==="tiktok")window.openAppStore&&(J=bs);else if(e==="smadex")try{window.smxTracking&&(J=ys)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(J=vs)}catch{}else e==="vungle"?J=ws:(r==="nucleo"||e==="nucleo")&&(J=xs)}var oi=rt(require("lottie-web"),1),Pn=oi.default;typeof window!="undefined"&&(window.lottie=oi.default,window.__baseLottie=oi.default);var mo=require("pixi.js");var Mn=require("pixi.js");var bo=null;function jn(r){bo=r}ci();li();var Mt=require("pixi.js");ci();var Eo=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",zn=Eo;if(typeof window!="undefined")try{let r=new XMLHttpRequest;if(r.open("GET","./build-settings.json",!1),r.send(),r.status===200&&r.responseText){let e=JSON.parse(r.responseText);e!=null&&e.buildMode&&(zn=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${zn}`))}}catch{}function Co(r){var t,i,n,a,s;if(typeof window!="undefined"&&window.resolveAnchorVec2)return window.resolveAnchorVec2(r);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(r))return{x:(t=r[0])!=null?t:.5,y:(i=r[1])!=null?i:.5};if(r&&typeof r=="object"&&"x"in r&&"y"in r)return{x:(n=r.x)!=null?n:.5,y:(a=r.y)!=null?a:.5};if(typeof r=="string"){let o=r.trim().toLowerCase();return(s=e[o])!=null?s:{x:.5,y:.5}}return null}var we=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${zn}`);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 Mt.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 s=await Ke.load(e,n,i,a);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(d=s==null?void 0:s.constructor)==null?void 0:d.name}`);let o;if(n.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",s,"for object:",e),o=new Mt.Sprite(s),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=s==null?void 0:s.constructor)==null?void 0:u.name,s),s&&(((g=s.constructor)==null?void 0:g.name)==="Container"||s instanceof Mt.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=s)}else o=s;else o=s,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,s,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((s=t.position.x)!=null?s: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=Co(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 jt=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 To=rt(require("pixi.js"),1);typeof window!="undefined"&&(window.__basePixi=To);dt();var di=require("pixi.js");dt();var Nn=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new jt}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 s=this.registry.get(a);if(!s){console.warn("[Assets] No config found for object:",a);return}try{let l=await we.create(a,s,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 we.create(e,t,this.app);this.instanceCache.set(e,i)}}get(e){return this.instanceCache.get(e)}},Io=new Nn,ko=new Proxy(Io,{get(r,e){if(e in r&&typeof r[e]=="function")return r[e].bind(r);if(r.get(e))return r.get(e)}});dt();var Mo=require("pixi.js"),Te={width:400,height:600,designWidth:400,scaleFactor:1},ui={scale:1,position:1},Fn=[];function jo(r,e,t,i,n,a,s){Fn.push({element:r,originalScale:a,positionHelper:e,heightPercent:n}),e(r,t,i,n,a,s,!1)}function _o(){Fn.forEach(({element:r,originalScale:e,positionHelper:t,heightPercent:i})=>{let n=e*Te.scaleFactor;t(r,Te.width,Te.height,i,n,!0,!1)})}function Hn(r,e){console.log(`[SCREEN] updateScreenState called: ${r}x${e}`),Te.width=r,Te.height=e,Te.scaleFactor=Math.min(r/Te.designWidth,1.15),ui.scale=Te.scaleFactor,ui.position=1,console.log(`[SCREEN] Global multipliers - scale: ${ui.scale.toFixed(3)}`),_o()}var Ot={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 Oo(r,e,t){let i=Ot[r];i&&i[e]!==void 0&&(i[e]=t,console.log(`Updated ${r}.${e} = ${t}`))}function Ro(){return Ot}var zo={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 pi(r,e){return typeof r=="number"&&Number.isFinite(r)?r:e}function Je(r,e={x:.5,y:.5}){var t;if(Array.isArray(r))return{x:pi(r[0],e.x),y:pi(r[1],e.y)};if(r&&typeof r=="object"){let i=r;return{x:pi(i.x,e.x),y:pi(i.y,e.y)}}if(typeof r=="string"){let i=r.trim().toLowerCase();return(t=zo[i])!=null?t:e}return e}function Ne(r,e,t,i={}){var g,h,f,m,b,y;let n=Je(t),a=(g=i.inset)!=null?g:{},s=(h=i.padding)!=null?h:{x:0,y:0},o=((f=a.left)!=null?f:0)+s.x,l=((m=a.right)!=null?m:0)+s.x,c=((b=a.top)!=null?b:0)+s.y,d=((y=a.bottom)!=null?y:0)+s.y,p=Math.max(0,r-o-l),u=Math.max(0,e-c-d);return{x:o+p*n.x,y:c+u*n.y}}function pt(r,e,t,i={}){var f,m,b,y,w,v;let n=(f=i.inset)!=null?f:{},a=(m=i.padding)!=null?m:{x:0,y:0},s=((b=n.left)!=null?b:0)+a.x,o=((y=n.right)!=null?y:0)+a.x,l=((w=n.top)!=null?w:0)+a.y,c=((v=n.bottom)!=null?v:0)+a.y,d=Math.max(0,r-s-o),p=Math.max(0,e-l-c),u=Je(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:s+d*g,y:l+p*h}}if(typeof window!="undefined"){let r=window.innerWidth,e=window.innerHeight,t=()=>{let i=window.innerWidth,n=window.innerHeight;(i!==r||n!==e)&&(r=i,e=n,Hn(i,n))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),Hn(window.innerWidth,window.innerHeight),window.updateDebugConfig=Oo,window.getDebugConfig=Ro,window.copyConfig=Yo,window.applyConfig=_t,window.applyConfigForRatio=Wo,window.positionAtBottom=Rs,window.positionAtTop=No,window.positionAtCenter=Ho,window.positionAtLeft=Fo,window.positionAtRight=Bo,window.positionAtBottomLeft=Go,window.positionAtBottomRight=Uo,window.positionAtTopLeft=qo,window.positionAtTopRight=Vo,window.applyPositionContract=Do,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 gi(r,e,t=0){return r*e+t}function hi(r,e,t=0){return r*(1-e)+t}function fi(r,e,t=0){return r*e+t}function mi(r,e,t=0){return r*(1-e)+t}function ue(r,e=0){return r/2+e}function $o(r,e){return r*e}function Do(r,e,t,i){var s,o,l,c,d,p,u,g,h,f,m,b,y,w,v,P,I,_,k,j;let n=0,a=0;switch(i.type){case"top":n=ue(e,(o=(s=i.offset)==null?void 0:s.x)!=null?o:0),a=gi(t,i.percent,(c=(l=i.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":n=ue(e,(p=(d=i.offset)==null?void 0:d.x)!=null?p:0),a=hi(t,i.percent,(g=(u=i.offset)==null?void 0:u.y)!=null?g:0);break;case"left":n=fi(e,i.percent,(f=(h=i.offset)==null?void 0:h.x)!=null?f:0),a=ue(t,(b=(m=i.offset)==null?void 0:m.y)!=null?b:0);break;case"right":n=mi(e,i.percent,(w=(y=i.offset)==null?void 0:y.x)!=null?w:0),a=ue(t,(P=(v=i.offset)==null?void 0:v.y)!=null?P:0);break;case"center":n=ue(e,(_=(I=i.offset)==null?void 0:I.x)!=null?_:0),a=ue(t,(j=(k=i.offset)==null?void 0:k.y)!=null?j:0);break}r.position?r.position.set(n,a):(r.x=n,r.y=a),i.scale!==void 0&&i.scale!==1&&r.scale&&(typeof r.scale.set=="function"?r.scale.set(i.scale,i.scale):(r.scale.x=i.scale,r.scale.y=i.scale))}function Rs(r,e,t,i=.2,n=1,a=!0,s=!1){let o=$o(t,i),l=hi(t,i/2);Ie(r,ue(e),l);let c=a?n*Te.scaleFactor:n;ke(r,c),s&&!Fn.find(d=>d.element===r)&&jo(r,Rs,e,t,i,n,a)}function No(r,e,t,i=.1,n=1){Ie(r,ue(e),gi(t,i)),ke(r,n)}function Ho(r,e,t,i=0,n=0,a=1){Ie(r,ue(e,i),ue(t,n)),ke(r,a)}function Fo(r,e,t,i=.1,n=1){Ie(r,fi(e,i),ue(t)),ke(r,n)}function Bo(r,e,t,i=.1,n=1){Ie(r,mi(e,i),ue(t)),ke(r,n)}function Go(r,e,t,i=.05,n=.05,a=1){Ie(r,fi(e,n),hi(t,i)),ke(r,a)}function Uo(r,e,t,i=.05,n=.05,a=1){Ie(r,mi(e,n),hi(t,i)),ke(r,a)}function qo(r,e,t,i=.05,n=.05,a=1){Ie(r,fi(e,n),gi(t,i)),ke(r,a)}function Vo(r,e,t,i=.05,n=.05,a=1){Ie(r,mi(e,n),gi(t,i)),ke(r,a)}function Ie(r,e,t){r&&r.position?typeof r.position.set=="function"?r.position.set(e,t):(r.position.x=e,r.position.y=t):r&&(r.x=e,r.y=t)}function ke(r,e){e!==1&&r&&r.scale&&(typeof r.scale.set=="function"?r.scale.set(e,e):r.scale.x!==void 0&&r.scale.y!==void 0&&(r.scale.x=e,r.scale.y=e))}var Xe={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 Yo(r){return r&&Xe[r]?JSON.parse(JSON.stringify(Xe[r])):JSON.parse(JSON.stringify(Ot))}function _t(r){Object.keys(r).forEach(e=>{let t=e;Ot[t]&&r[t]&&Object.assign(Ot[t],r[t])}),console.log("Config applied:",r)}function Wo(r,e){let t=r/e;t>1.6?(_t(Xe.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(_t(Xe.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(_t(Xe.square),console.log("Applied SQUARE config for ratio:",t)):(_t(Xe.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let r=window;r.configPresets=Xe,r.resolveAnchorVec2=r.resolveAnchorVec2||Je,r.resolveScreenAnchorPoint=r.resolveScreenAnchorPoint||Ne,r.resolveScreenRatioPoint=r.resolveScreenRatioPoint||pt}Ii();function ie(r,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(r,e);return`${r/i}:${e/i}`}var hd=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:ie(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:ie(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:ie(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:ie(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:ie(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:ie(360,780)}],fd=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:ie(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:ie(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:ie(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:ie(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:ie(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:ie(412,915)}],md=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:ie(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:ie(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:ie(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:ie(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:ie(800,1280)}],aa=[{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:ie(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:ie(768,1024),mraidScale:.7}];var sa=[...aa],ra=[{category:"playable",label:"Playable Ad",devices:aa}],ki=aa[0];function tt(r){return sa.find(e=>e.id===r)||ki}function il(r){return sa.filter(e=>e.category===r)}ne();var Se=class{async updateProperty(e,t,i,n={}){var l,c,d,p,u,g,h,f,m,b,y,w;console.log("[PropertyUpdateManager] Updating:",e,t,i);let a=window.getEditableObjectConfig;if(typeof a!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let s=a(e);if(!s){console.error("[PropertyUpdateManager] Config not found for:",e);return}if(le({objectId:e,path:t,value:i},{persist:!0}),t==="transform"||t.startsWith("transform.")){console.log("[DEBUG FALLBACK] PropertyUpdateManager SKIP applyEditableObjectConfig (transform path)",t,e);let v=s==null?void 0:s.motion;if(v&&typeof v=="object"&&v.enabled!==!1&&(((p=v==null?void 0:v.intro)==null?void 0:p.enabled)===!0||((u=v==null?void 0:v.pulse)==null?void 0:u.enabled)===!0||((g=v==null?void 0:v.swing)==null?void 0:g.enabled)===!0||((h=v==null?void 0:v.continuousMove)==null?void 0:h.enabled)===!0||((f=v==null?void 0:v.continuousRotate)==null?void 0:f.enabled)===!0||((m=v==null?void 0:v.orbit)==null?void 0:m.enabled)===!0)){let _=window.applyEditableObjectConfig;if(typeof _=="function"){let k=window.__editableConfig,j=(w=(y=(b=k==null?void 0:k.objects)==null?void 0:b.get)==null?void 0:y.call(b,e))!=null?w:s;await _(e,j),console.log("[PropertyUpdateManager] Applied config for motion object")}}n.refreshInspector||requestAnimationFrame(()=>{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e}}))})}else{let v=window.applyEditableObjectConfig;if(typeof v=="function"){let P=window.__editableConfig,I=(d=(c=(l=P==null?void 0:P.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:s;await v(e,I),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 oa(r){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()=>{var g,h,f,m;let s=n.result;if(!s||typeof s!="string"){alert("Failed to read file: Invalid data URL"),console.error("[QuickActionsBar] Invalid data URL:",typeof s,s==null?void 0:s.substring(0,50));return}if(!s.startsWith("data:image/")){alert("Invalid file format: Not an image file"),console.error("[QuickActionsBar] Invalid data URL format:",s.substring(0,100));return}let o=s.match(/^data:image\/[^;]+;base64,(.+)$/);if(!o||!o[1]||o[1].length===0){alert("Failed to read file: Invalid base64 data"),console.error("[QuickActionsBar] Invalid base64 data in data URL");return}try{let b=o[1],y=atob(b.substring(0,Math.min(100,b.length)));if(!y||y.length===0)throw new Error("Base64 decode test failed");console.log("[QuickActionsBar] \u2705 Data URL validated, length:",s.length)}catch(b){alert("Failed to read file: Corrupted image data"),console.error("[QuickActionsBar] Base64 validation failed:",b);return}let l=r.category||"misc",c=(r.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),d=((g=i.name.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/))==null?void 0:g[1])||"png",p=d==="jpg"?"jpeg":d,u=`${c||"new_asset"}_uploaded_${Date.now()}.${p}`;console.log("[QuickActionsBar] Uploading file:",u,"to category:",l,"data URL length:",s.length);try{let y=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:l,filename:u,data:s,overwrite:!0})})).json();if(!(y!=null&&y.success)){alert(`Upload failed: ${(y==null?void 0:y.error)||"Unknown error"}`);return}await new Promise(x=>setTimeout(x,100));let w=window.addAssetToRegistry;typeof w=="function"&&(w(l,u),console.log("[QuickActionsBar] \u2705 Added to registry:",l,u));let v=window.getEditableAssets;if(typeof v=="function"){let x=v();x&&!x.categories&&(x.categories=[]),x!=null&&x.categories&&!x.categories.includes(l)&&(x.categories.push(l),console.log(`[QuickActionsBar] Added category ${l} to registry`))}let P=!1,I=0,_=10;for(;!P&&I<_;){I++,console.log(`[QuickActionsBar] Refresh attempt ${I}/${_}...`);try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&console.log("[QuickActionsBar] \u2705 Registry rebuilt from disk")}catch{}await new Promise(C=>setTimeout(C,300));let x=window.refreshAssetLibrary;typeof x=="function"&&(console.log("[QuickActionsBar] Refreshing library panel..."),await x());let S=window.reRenderAssetLibrary;typeof S=="function"&&(console.log("[QuickActionsBar] Re-rendering library panel..."),S());let E=window.getEditableAssets;if(typeof E=="function"){let C=E(),A=((h=C==null?void 0:C.libraryAssets)==null?void 0:h[l])||[];A.some(O=>(O==null?void 0:O.filename)===u)?(console.log("[QuickActionsBar] \u2705 Asset found in registry!"),P=!0):(console.log(`[QuickActionsBar] Asset not found yet, retrying... (found ${A.length} assets in ${l})`),await new Promise(O=>setTimeout(O,500)))}else I>=2&&(P=!0)}P||console.warn("[QuickActionsBar] \u26A0\uFE0F Asset not found in registry after retries, proceeding anyway..."),setTimeout(()=>{try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[QuickActionsBar] Dispatched config:changed event")}catch(x){console.warn("[QuickActionsBar] Failed to refresh textures:",x)}},300),console.log("[QuickActionsBar] Applying asset to object:",y.path);let k=!1,j=0,L=5;for(;!k&&j<L;){j++;try{await r.onApply(y.path),await new Promise(S=>setTimeout(S,200));let x=window.getEditableObjectConfig;if(typeof x=="function"){let S=x(r.objectId),E=((m=(f=S==null?void 0:S.render)==null?void 0:f.asset)==null?void 0:m.path)||"";E===y.path||E.includes(u)?(console.log("[QuickActionsBar] \u2705 Asset confirmed applied to object"),k=!0):(console.log(`[QuickActionsBar] Asset not applied yet (attempt ${j}), retrying...`),await new Promise(C=>setTimeout(C,300)))}else k=!0}catch(x){console.error(`[QuickActionsBar] Apply attempt ${j} failed:`,x),j<L&&await new Promise(S=>setTimeout(S,500))}}k?console.log("[QuickActionsBar] \u2705 Asset upload and apply complete!"):console.warn("[QuickActionsBar] \u26A0\uFE0F Asset may not have been applied, but upload succeeded")}catch(b){console.error("[QuickActionsBar] Upload error:",b),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var Pi=class{constructor(){this.updateManager=new Se}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 s=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,s);break;case"ai-edit":this.openAIEditor(t,i,s);break;case"upload":this.openUpload(t,i);break;case"reset":await this.resetToDefault(t,i);break;case"ai-convert":this.handleAiConvert(t,i,s);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 s=((n=(i=t.transform)==null?void 0:i.scale)!=null?n:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",s),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",s)}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 s=window.__updateWorkbenchTabs;typeof s=="function"&&s()}if(n.libraryPanel){let s=window.getEditableObjectConfig,o=s==null?void 0:s(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 s;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e),a=((s=n==null?void 0:n.identity)==null?void 0:s.category)||(t.split(".")[0]==="render"?"environment":"ui");oa({objectId:e,category:a,onApply:async o=>{var g,h;console.log("[QuickActionsBar] Upload complete, applying asset:",o);let l=window.applyAssetToSlot,c=this.getFilenameFromPath(o),d=/render\.asset\.path/i.test(t)||/\.(png|jpg|jpeg|gif|webp)$/i.test(o);if(typeof l=="function"&&c&&d){console.log("[QuickActionsBar] Applying asset to slot:",e,c,a);try{await l(e,c,a),console.log("[QuickActionsBar] \u2705 Asset applied to slot")}catch(f){console.error("[QuickActionsBar] Failed to apply asset to slot:",f)}}console.log("[QuickActionsBar] Updating property:",e,t,o);try{await this.updateManager.updateProperty(e,t,o),console.log("[QuickActionsBar] \u2705 Property updated")}catch(f){console.error("[QuickActionsBar] Failed to update property:",f)}let p=window.__debugContext;(h=(g=p==null?void 0:p.options)==null?void 0:g.onPropertyChange)==null||h.call(g,e,t,o);let u=window.__highlightLibrarySlot;typeof u=="function"&&setTimeout(()=>{u(e,a)},1e3),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e,action:"update",path:t}})),console.log("[QuickActionsBar] \u2705 Upload and apply complete")}})}getFilenameFromPath(e){if(!e)return"";let t=e.split("?")[0].replace(/\\/g,"/");return t.split("/").pop()||t}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),s=window.__editableConfig;if(!(s!=null&&s.schemas))return;let o=null;if(s.schemas instanceof Map?o=s.schemas.get(n):typeof s.schemas=="object"&&(o=s.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 s=`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,s,"",{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 nl=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],al=["environment","ui","character","system","backgrounds"],sl=["bg","world","ui"],Ws={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}}},Mi=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=`
98
98
  <div class="wizard-card">
99
99
  <div class="wizard-header">
100
100
  <div class="wizard-title">
@@ -146,19 +146,19 @@
146
146
  <div class="wizard-field-group">
147
147
  <label class="wizard-label required">Category</label>
148
148
  <select class="wizard-select" data-field="category">
149
- ${nl.map(e=>`<option value="${e}">${e}</option>`).join("")}
149
+ ${al.map(e=>`<option value="${e}">${e}</option>`).join("")}
150
150
  </select>
151
151
  </div>
152
152
  <div class="wizard-field-group">
153
153
  <label class="wizard-label required">Screen</label>
154
154
  <select class="wizard-select" data-field="screenId" required>
155
- ${il.map(e=>`<option value="${e.value}">${e.label}</option>`).join("")}
155
+ ${nl.map(e=>`<option value="${e.value}">${e.label}</option>`).join("")}
156
156
  </select>
157
157
  </div>
158
158
  <div class="wizard-field-group">
159
159
  <label class="wizard-label required">Layer</label>
160
160
  <select class="wizard-select" data-field="layer">
161
- ${al.map(e=>`<option value="${e}">${e}</option>`).join("")}
161
+ ${sl.map(e=>`<option value="${e}">${e}</option>`).join("")}
162
162
  </select>
163
163
  </div>
164
164
  </div>
@@ -321,7 +321,7 @@
321
321
  <label class="wizard-label">Logic Component</label>
322
322
  <select class="wizard-select" data-field="logicId">
323
323
  <option value="">None</option>
324
- ${Object.keys(Ys).map(e=>`<option value="${e}">${e}</option>`).join("")}
324
+ ${Object.keys(Ws).map(e=>`<option value="${e}">${e}</option>`).join("")}
325
325
  </select>
326
326
  </div>
327
327
  <div class="wizard-field-group">
@@ -348,14 +348,14 @@
348
348
  <div class="wizard-type-icon">${t}</div>
349
349
  <div class="wizard-type-name">${i}</div>
350
350
  </button>
351
- `}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";oa({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={"top-left":[0,0],"top-center":[.5,0],"top-right":[1,0],"left-center":[0,.5],center:[.5,.5],"right-center":[1,.5],"bottom-left":[0,1],"bottom-center":[.5,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=Ys[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`
351
+ `}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";oa({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={"top-left":[0,0],"top-center":[.5,0],"top-right":[1,0],"left-center":[0,.5],center:[.5,.5],"right-center":[1,.5],"bottom-left":[0,1],"bottom-center":[.5,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=Ws[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`
352
352
  <div class="wizard-step-indicator">
353
353
  <span class="wizard-step-dot ${a===this.state.step?"active":a<this.state.step?"completed":""}"></span>
354
354
  <span class="wizard-step-label">Step ${a}</span>
355
355
  </div>
356
- `});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,r=a==="sprite"&&(e==="sprite"||e==="ui-image")||a===e;n.style.display=r?"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 s=e[a];n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked=!!s:typeof s!="undefined"&&(n.value=String(s))}),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(`
356
+ `});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 s=e[a];n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked=!!s:typeof s!="undefined"&&(n.value=String(s))}),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(`
357
357
  `)):(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),forceSync:!0}}buildObjectConfig(e){if(!this.state)return{};let t=this.state.category||"environment",i={identity:{id:e,category:t},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:this.state.anchorPreset==="custom"?{x:this.state.anchorX,y:this.state.anchorY}:this.state.anchorPreset,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")&&(i.render.asset={type:"image",path:this.normalizeAssetPath(this.state.assetPath.trim())}),this.state.objectType==="ui-text"&&(i.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"},i.render.tint=null),this.state.objectType==="graphics"&&(i.effects={width:this.state.graphicsWidth,height:this.state.graphicsHeight,fill_color:this.state.graphicsFill,fill_alpha:this.state.graphicsAlpha}),this.state.interactionEnabled&&(i.interaction={enabled:!0,drag:{enabled:this.state.dragEnabled},hover:{enabled:this.state.hoverEnabled},click:{enabled:this.state.clickEnabled}}),this.state.logicId&&(i.logic={id:this.state.logicId,props:this.parseLogicProps(this.state.logicPropsRaw)}),i}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 s=((i=a==null?void 0:a.errors)==null?void 0:i.join(`
358
- `))||(a==null?void 0:a.error)||"Failed to create object.";alert(s);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{let e=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[AddObjectWizard] Failed to sync screens:",e)}}};var gt=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=`
358
+ `))||(a==null?void 0:a.error)||"Failed to create object.";alert(s);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{let e=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[AddObjectWizard] Failed to sync screens:",e)}}};var ht=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=`
359
359
  <div class="context-menu-item" data-action="add-logic">\u2699\uFE0F Add Logic</div>
360
360
  <div class="context-menu-separator"></div>
361
361
  <div class="context-menu-item-wrapper">
@@ -380,11 +380,11 @@
380
380
  <div class="context-menu-item" data-action="inspect">\u{1F50D} Open in Inspector</div>
381
381
  <div class="context-menu-separator"></div>
382
382
  <div class="context-menu-item danger" data-action="delete">\u{1F5D1}\uFE0F Delete</div>
383
- `,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,s=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),s>0&&(this.menu.style.top=`${i-s-8}px`)}attachListeners(){if(!this.menu)return;let e=this.menu.querySelector('[data-action="image-menu"]'),t=this.menu.querySelector('[data-submenu="image-menu"]'),i=e==null?void 0:e.parentElement;if(e&&t&&i){i.style.position="relative",e.addEventListener("mouseenter",()=>{t.style.display="block"}),t.addEventListener("mouseenter",()=>{t.style.display="block"});let n=()=>{setTimeout(()=>{!t.matches(":hover")&&!e.matches(":hover")&&(t.style.display="none")},100)};e.addEventListener("mouseleave",n),t.addEventListener("mouseleave",()=>{t.style.display="none"})}this.menu.addEventListener("click",n=>{let s=n.target.dataset.action;s&&(n.stopPropagation(),this.handleAction(s))}),this.closeHandler=n=>{let a=n.target;this.menu&&a&&this.menu.contains(a)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=n=>{n.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler)}handleAction(e){var t,i;switch(e){case"image-menu":return;case"change-image":this.handleChangeImage();break;case"edit-image-crop":this.handleEditImageCrop();break;case"edit-image-ai":this.handleEditImageAI();break;case"upload-image":this.handleUploadImage();break;case"go-to-library":this.handleGoToLibrary();break;case"add-logic":this.handleAddLogic();break;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,s,r,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?
383
+ `,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,s=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),s>0&&(this.menu.style.top=`${i-s-8}px`)}attachListeners(){if(!this.menu)return;let e=this.menu.querySelector('[data-action="image-menu"]'),t=this.menu.querySelector('[data-submenu="image-menu"]'),i=e==null?void 0:e.parentElement;if(e&&t&&i){i.style.position="relative",e.addEventListener("mouseenter",()=>{t.style.display="block"}),t.addEventListener("mouseenter",()=>{t.style.display="block"});let n=()=>{setTimeout(()=>{!t.matches(":hover")&&!e.matches(":hover")&&(t.style.display="none")},100)};e.addEventListener("mouseleave",n),t.addEventListener("mouseleave",()=>{t.style.display="none"})}this.menu.addEventListener("click",n=>{let s=n.target.dataset.action;s&&(n.stopPropagation(),this.handleAction(s))}),this.closeHandler=n=>{let a=n.target;this.menu&&a&&this.menu.contains(a)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=n=>{n.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler)}handleAction(e){var t,i;switch(e){case"image-menu":return;case"change-image":this.handleChangeImage();break;case"edit-image-crop":this.handleEditImageCrop();break;case"edit-image-ai":this.handleEditImageAI();break;case"upload-image":this.handleUploadImage();break;case"go-to-library":this.handleGoToLibrary();break;case"add-logic":this.handleAddLogic();break;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,s,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?
384
384
  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(`
385
- `))||(d==null?void 0:d.error)||"Duplicate failed.";alert(p);return}(s=(a=this.options).onRefresh)==null||s.call(a),(l=(r=this.options).onSelect)==null||l.call(r,t),this.close()}catch(c){alert(`Duplicate failed: ${c instanceof Error?c.message:String(c)}`)}}async handleRename(){var t,i,n,a,s;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 r=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 r.json().catch(()=>({}));if(!r.ok||(l==null?void 0:l.success)===!1){let c=((t=l==null?void 0:l.errors)==null?void 0:t.join(`
386
- `))||(l==null?void 0:l.error)||"Rename failed.";alert(c);return}(n=(i=this.options).onRefresh)==null||n.call(i),(s=(a=this.options).onSelect)==null||s.call(a,e),this.close()}catch(r){alert(`Rename failed: ${r instanceof Error?r.message:String(r)}`)}}}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 s=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})}),r=await s.json().catch(()=>({}));if(!s.ok||(r==null?void 0:r.success)===!1){let l=((i=r==null?void 0:r.errors)==null?void 0:i.join(`
387
- `))||(r==null?void 0:r.error)||"Move failed.";alert(l);return}(a=(n=this.options).onRefresh)==null||a.call(n),this.close()}catch(s){alert(`Move failed: ${s instanceof Error?s.message:String(s)}`)}}}handleCopyConfig(){var n,a;let e=window.getEditableObjectConfig,t=typeof e=="function"?e(this.options.objectId):null;if(!t){let s=window.__editableObjectConfigs;s&&typeof s.get=="function"&&(t=(n=s.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()}handleChangeImage(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,r=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",r),(d=(c=this.options).onRefresh)==null||d.call(c))})}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),this.handleGoToLibrary()}),this.close()}handleEditImageCrop(){var n,a;let e=this.getObjectConfig(),t=(a=(n=e==null?void 0:e.render)==null?void 0:n.asset)==null?void 0:a.path;if(!t){alert("No image asset found for this object."),this.close();return}let i;t.startsWith("http")||t.startsWith("data:")?i=t:t.startsWith("raw/")||t.startsWith("/raw/")?i=t.startsWith("/")?t:`/${t}`:i=`/raw/${t}`,console.log("[ObjectContextMenu] Opening crop modal with image:",i),Promise.resolve().then(()=>(la(),Ws)).then(({AssetCropModal:s})=>{new s().open({imageSrc:i,onCrop:async l=>{var c,d,p;try{let u=((c=e==null?void 0:e.identity)==null?void 0:c.category)||"ui",g=this.options.objectId.replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),f=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:u,filename:`${g}_cropped_${Date.now()}.png`,data:l,overwrite:!0})})).json();if(f.success&&f.path){console.log("[ObjectContextMenu] \u2705 Cropped image saved:",f.path);let m=window.addAssetToRegistry;if(typeof m=="function"){let v=f.path.split("/").pop()||"";m(u,v)}let b=window.refreshAssetLibrary;typeof b=="function"&&await b();let y=window.applyAssetToSlot;if(typeof y=="function"){let v=f.path.split("/").pop()||"";await y(this.options.objectId,v,u)}else{let{applyConfigOverride:v}=await Promise.resolve().then(()=>(Q(),Ie));v({objectId:this.options.objectId,path:"render.asset.path",value:f.path},{persist:!0,emitEvent:!0})}window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:this.options.objectId,action:"update",path:"render.asset.path"}})),(p=(d=this.options).onRefresh)==null||p.call(d),console.log("[ObjectContextMenu] \u2705 Cropped image applied")}else alert(`Failed to save cropped image: ${f.error||"Unknown error"}`)}catch(u){alert(`Failed to save cropped image: ${u instanceof Error?u.message:String(u)}`)}},onCancel:()=>{}})}).catch(s=>{console.error("Failed to load AssetCropModal:",s),alert("Crop editor not available.")}),this.close()}handleEditImageAI(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,r=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",r),(d=(c=this.options).onRefresh)==null||d.call(c))}),setTimeout(()=>{let r=document.querySelector('.asset-editor-tab[data-tab="ai"]');r==null||r.click()},100)}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),alert("AI editor not available.")}),this.close()}handleUploadImage(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,r=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",r),(d=(c=this.options).onRefresh)==null||d.call(c))}),setTimeout(()=>{let r=document.querySelector('.asset-editor-tab[data-tab="upload"]');r==null||r.click()},100)}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),alert("Upload not available.")}),this.close()}handleGoToLibrary(){var t;let e=window.__debugContext;if(e){(t=e.setActiveTab)==null||t.call(e,"library");let i=window.__highlightLibrarySlot;typeof i=="function"&&i(this.options.objectId)}this.close()}handleAddLogic(){this.handleOpenInspector(),setTimeout(()=>{var t,i,n;let e=document.querySelector('[data-path="logic.id"]');if(e)(t=e.focus)==null||t.call(e),(i=e.scrollIntoView)==null||i.call(e,{behavior:"smooth",block:"center"});else{let a=document.querySelector('[data-section="logic"]');(n=a==null?void 0:a.scrollIntoView)==null||n.call(a,{behavior:"smooth",block:"center"})}},100),this.close()}getObjectConfig(){var i;let e=window.getEditableObjectConfig;if(typeof e=="function")return e(this.options.objectId);let t=window.__editableObjectConfigs;return t&&typeof t.get=="function"&&(i=t.get(this.options.objectId))!=null?i:null}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 Ft=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],ji=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,s=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),s>0&&(this.menu.style.top=`${i-s-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||!Ft.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,s=i.dataset.systemType,r=i.dataset.templateId,l=i.dataset.screenId,c=l!=null?l:this.targetScreen;n==="object"&&a?this.handleCreateObject(a,c):n==="system"&&s?this.handleCreateSystem(s,c):n==="template"&&r&&this.handleCreateFromTemplate(r,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=`
385
+ `))||(d==null?void 0:d.error)||"Duplicate failed.";alert(p);return}(s=(a=this.options).onRefresh)==null||s.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,s;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(`
386
+ `))||(l==null?void 0:l.error)||"Rename failed.";alert(c);return}(n=(i=this.options).onRefresh)==null||n.call(i),(s=(a=this.options).onSelect)==null||s.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 s=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 s.json().catch(()=>({}));if(!s.ok||(o==null?void 0:o.success)===!1){let l=((i=o==null?void 0:o.errors)==null?void 0:i.join(`
387
+ `))||(o==null?void 0:o.error)||"Move failed.";alert(l);return}(a=(n=this.options).onRefresh)==null||a.call(n),this.close()}catch(s){alert(`Move failed: ${s instanceof Error?s.message:String(s)}`)}}}handleCopyConfig(){var n,a;let e=window.getEditableObjectConfig,t=typeof e=="function"?e(this.options.objectId):null;if(!t){let s=window.__editableObjectConfigs;s&&typeof s.get=="function"&&(t=(n=s.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()}handleChangeImage(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(gt(),Ft)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,o=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",o),(d=(c=this.options).onRefresh)==null||d.call(c))})}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),this.handleGoToLibrary()}),this.close()}handleEditImageCrop(){var n,a;let e=this.getObjectConfig(),t=(a=(n=e==null?void 0:e.render)==null?void 0:n.asset)==null?void 0:a.path;if(!t){alert("No image asset found for this object."),this.close();return}let i;t.startsWith("http")||t.startsWith("data:")?i=t:t.startsWith("raw/")||t.startsWith("/raw/")?i=t.startsWith("/")?t:`/${t}`:i=`/raw/${t}`,console.log("[ObjectContextMenu] Opening crop modal with image:",i),Promise.resolve().then(()=>(ca(),Ks)).then(({AssetCropModal:s})=>{new s().open({imageSrc:i,onCrop:async l=>{var c,d,p;try{let u=((c=e==null?void 0:e.identity)==null?void 0:c.category)||"ui",g=this.options.objectId.replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),f=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:u,filename:`${g}_cropped_${Date.now()}.png`,data:l,overwrite:!0})})).json();if(f.success&&f.path){console.log("[ObjectContextMenu] \u2705 Cropped image saved:",f.path);let m=window.addAssetToRegistry;if(typeof m=="function"){let w=f.path.split("/").pop()||"";m(u,w)}let b=window.refreshAssetLibrary;typeof b=="function"&&await b();let y=window.applyAssetToSlot;if(typeof y=="function"){let w=f.path.split("/").pop()||"";await y(this.options.objectId,w,u)}else{let{applyConfigOverride:w}=await Promise.resolve().then(()=>(ne(),Pe));w({objectId:this.options.objectId,path:"render.asset.path",value:f.path},{persist:!0,emitEvent:!0})}window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:this.options.objectId,action:"update",path:"render.asset.path"}})),(p=(d=this.options).onRefresh)==null||p.call(d),console.log("[ObjectContextMenu] \u2705 Cropped image applied")}else alert(`Failed to save cropped image: ${f.error||"Unknown error"}`)}catch(u){alert(`Failed to save cropped image: ${u instanceof Error?u.message:String(u)}`)}},onCancel:()=>{}})}).catch(s=>{console.error("Failed to load AssetCropModal:",s),alert("Crop editor not available.")}),this.close()}handleEditImageAI(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(gt(),Ft)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,o=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",o),(d=(c=this.options).onRefresh)==null||d.call(c))}),setTimeout(()=>{let o=document.querySelector('.asset-editor-tab[data-tab="ai"]');o==null||o.click()},100)}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),alert("AI editor not available.")}),this.close()}handleUploadImage(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(gt(),Ft)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,o=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",o),(d=(c=this.options).onRefresh)==null||d.call(c))}),setTimeout(()=>{let o=document.querySelector('.asset-editor-tab[data-tab="upload"]');o==null||o.click()},100)}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),alert("Upload not available.")}),this.close()}handleGoToLibrary(){var t;let e=window.__debugContext;if(e){(t=e.setActiveTab)==null||t.call(e,"library");let i=window.__highlightLibrarySlot;typeof i=="function"&&i(this.options.objectId)}this.close()}handleAddLogic(){this.handleOpenInspector(),setTimeout(()=>{var t,i,n;let e=document.querySelector('[data-path="logic.id"]');if(e)(t=e.focus)==null||t.call(e),(i=e.scrollIntoView)==null||i.call(e,{behavior:"smooth",block:"center"});else{let a=document.querySelector('[data-section="logic"]');(n=a==null?void 0:a.scrollIntoView)==null||n.call(a,{behavior:"smooth",block:"center"})}},100),this.close()}getObjectConfig(){var i;let e=window.getEditableObjectConfig;if(typeof e=="function")return e(this.options.objectId);let t=window.__editableObjectConfigs;return t&&typeof t.get=="function"&&(i=t.get(this.options.objectId))!=null?i:null}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 Bt=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],_i=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,s=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),s>0&&(this.menu.style.top=`${i-s-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||!Bt.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,s=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"&&s?this.handleCreateSystem(s,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=`
388
388
  <div class="add-menu-modal">
389
389
  <div class="add-menu-modal-header">
390
390
  <div class="add-menu-modal-title">${this.escapeHtml(e)}</div>
@@ -393,7 +393,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
393
393
  <div class="add-menu-modal-body">
394
394
  <label class="add-menu-modal-label">Screen:</label>
395
395
  <select class="add-menu-modal-select" id="screen-select" required>
396
- ${Ft.map((u,g)=>`<option value="${this.escapeHtml(u.value)}" ${g===2?"selected":""}>${this.escapeHtml(u.label)}</option>`).join("")}
396
+ ${Bt.map((u,g)=>`<option value="${this.escapeHtml(u.value)}" ${g===2?"selected":""}>${this.escapeHtml(u.label)}</option>`).join("")}
397
397
  </select>
398
398
  </div>
399
399
  <div class="add-menu-modal-footer">
@@ -401,7 +401,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
401
401
  <button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Confirm</button>
402
402
  </div>
403
403
  </div>
404
- `;let n=()=>{i.parentNode&&i.parentNode.removeChild(i)},a=()=>{let g=i.querySelector("#screen-select").value.trim();if(!g||!Ft.some(h=>h.value===g)){alert("Please select a valid screen.");return}n(),t(g)},s=()=>{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",s),(p=i.querySelector(".add-menu-modal-close"))==null||p.addEventListener("click",s),i.addEventListener("click",u=>{u.target===i&&s()});let l=i.querySelector("#screen-select");l.addEventListener("keydown",u=>{u.key==="Enter"?(u.preventDefault(),a()):u.key==="Escape"&&(u.preventDefault(),s())}),document.body.appendChild(i),l.focus()})}loadTargetScreen(){try{let t=(window.localStorage.getItem(this.getTargetScreenStorageKey())||"").trim();Ft.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 s=((t=a==null?void 0:a.errors)==null?void 0:t.join(`
404
+ `;let n=()=>{i.parentNode&&i.parentNode.removeChild(i)},a=()=>{let g=i.querySelector("#screen-select").value.trim();if(!g||!Bt.some(h=>h.value===g)){alert("Please select a valid screen.");return}n(),t(g)},s=()=>{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",s),(p=i.querySelector(".add-menu-modal-close"))==null||p.addEventListener("click",s),i.addEventListener("click",u=>{u.target===i&&s()});let l=i.querySelector("#screen-select");l.addEventListener("keydown",u=>{u.key==="Enter"?(u.preventDefault(),a()):u.key==="Escape"&&(u.preventDefault(),s())}),document.body.appendChild(i),l.focus()})}loadTargetScreen(){try{let t=(window.localStorage.getItem(this.getTargetScreenStorageKey())||"").trim();Bt.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 s=((t=a==null?void 0:a.errors)==null?void 0:t.join(`
405
405
  `))||(a==null?void 0:a.error)||"Failed to install templates.";alert(s);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`
406
406
  ${this.renderTargetScreenSection()}
407
407
  <div class="context-menu-section-title">Objects</div>
@@ -414,22 +414,22 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
414
414
  <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>
415
415
  <div class="context-menu-item context-menu-submenu" data-action="open-view" data-view="screens">\u{1FA9F} Screens</div>
416
416
  <div class="context-menu-item context-menu-submenu" data-action="open-view" data-view="systems">\u{1F9E9} Systems</div>
417
- `}renderTemplatesView(){let e=(this.templateQuery||"").trim().toLowerCase(),t=this.groupTemplates(this.templates),i=["UI Templates","Screen Templates","Gameplay Templates","Effects","Other"];if(e){let r=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`
417
+ `}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`
418
418
  <div class="context-menu-item context-menu-back" data-action="back">\u2190 Back</div>
419
419
  <div class="context-menu-section-title">Templates</div>
420
420
  <input class="context-menu-search" type="text" placeholder="Search templates\u2026" value="${this.escapeHtml(this.templateQuery)}" />
421
- ${r||'<div class="context-menu-item disabled">No matches</div>'}
422
- `}let n=i.map(s=>{var d,p;let r=(p=(d=t.get(s))==null?void 0:d.length)!=null?p:0,l=s==="UI Templates"||s==="Screen Templates";return r<=0&&!l?`<div class="context-menu-item disabled">${this.escapeHtml(s)} <span class="context-menu-subtle">0</span></div>`:`<div class="${r>0,"context-menu-item context-menu-submenu"}" data-action="open-template-group" data-template-group="${this.escapeHtml(s)}">${this.escapeHtml(s)} <span class="context-menu-subtle">${r}</span></div>`}).join(""),a=this.templates.length>0?"":'<div class="context-menu-item disabled">No templates available</div>';return`
421
+ ${o||'<div class="context-menu-item disabled">No matches</div>'}
422
+ `}let n=i.map(s=>{var d,p;let o=(p=(d=t.get(s))==null?void 0:d.length)!=null?p:0,l=s==="UI Templates"||s==="Screen Templates";return o<=0&&!l?`<div class="context-menu-item disabled">${this.escapeHtml(s)} <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(s)}">${this.escapeHtml(s)} <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`
423
423
  <div class="context-menu-item context-menu-back" data-action="back">\u2190 Back</div>
424
424
  <div class="context-menu-section-title">Templates</div>
425
425
  <input class="context-menu-search" type="text" placeholder="Search templates\u2026" value="${this.escapeHtml(this.templateQuery)}" />
426
426
  ${n||a}
427
- `}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""})(),r=(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`
427
+ `}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`
428
428
  <div class="context-menu-item context-menu-back" data-action="open-view" data-view="templates">\u2190 Back</div>
429
429
  <div class="context-menu-section-title">${this.escapeHtml(e||"Templates")}</div>
430
430
  <input class="context-menu-search" type="text" placeholder="Search\u2026" value="${this.escapeHtml(this.templateQuery)}" />
431
431
  ${a?`${a}<div class="context-menu-separator"></div>`:""}
432
- ${r||'<div class="context-menu-item disabled">No templates in this group</div>'}
432
+ ${o||'<div class="context-menu-item disabled">No templates in this group</div>'}
433
433
  `}renderScreensView(){return`
434
434
  <div class="context-menu-item context-menu-back" data-action="back">\u2190 Back</div>
435
435
  <div class="context-menu-section-title">Screens</div>
@@ -450,14 +450,14 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
450
450
  `}renderTargetScreenSection(){return`
451
451
  <div class="context-menu-section-title">Target Screen</div>
452
452
  <div class="context-menu-screen-grid">
453
- ${Ft.map(e=>`
453
+ ${Bt.map(e=>`
454
454
  <button class="context-menu-screen-chip ${e.value===this.targetScreen?"active":""}" type="button" data-action="set-screen" data-screen-id="${this.escapeHtml(e.value)}">
455
455
  ${this.escapeHtml(e.label)}
456
456
  </button>
457
457
  `).join("")}
458
458
  </div>
459
459
  <div class="context-menu-separator"></div>
460
- `}groupTemplates(e){let t=new Map,i=(n,a)=>{var r;let s=(r=t.get(n))!=null?r:[];s.push(a),t.set(n,s)};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=`
460
+ `}groupTemplates(e){let t=new Map,i=(n,a)=>{var o;let s=(o=t.get(n))!=null?o:[];s.push(a),t.set(n,s)};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=`
461
461
  <div class="add-menu-modal">
462
462
  <div class="add-menu-modal-header">
463
463
  <div class="add-menu-modal-title">${this.escapeHtml(t)}</div>
@@ -473,7 +473,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
473
473
  <button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Confirm</button>
474
474
  </div>
475
475
  </div>
476
- `;let a=()=>{n.parentNode&&n.parentNode.removeChild(n)},s=()=>{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)},r=()=>{a(),i(null)};n.querySelector(".add-menu-modal").addEventListener("click",g=>{g.stopPropagation()}),(d=n.querySelector('[data-action="confirm"]'))==null||d.addEventListener("click",s),(p=n.querySelector('[data-action="cancel"]'))==null||p.addEventListener("click",r),(u=n.querySelector(".add-menu-modal-close"))==null||u.addEventListener("click",r),n.addEventListener("click",g=>{g.target===n&&r()});let c=n.querySelector("#name-input");c.addEventListener("keydown",g=>{g.key==="Enter"?(g.preventDefault(),s()):g.key==="Escape"&&(g.preventDefault(),r())}),c.select(),document.body.appendChild(n),c.focus()})}async promptSpawnerConfig(){return new Promise(e=>{var m,b,y;let t=document.createElement("div");t.className="add-menu-modal-overlay";let i="template_id",n=`${i}_spawner_1`,a="",s=JSON.stringify([{x:-120,y:-120},{x:0,y:-120},{x:120,y:-120}],null,2),r=JSON.stringify({x:[-240,240],y:[-170,-170]},null,2),l="";t.innerHTML=`
476
+ `;let a=()=>{n.parentNode&&n.parentNode.removeChild(n)},s=()=>{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",s),(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(),s()):g.key==="Escape"&&(g.preventDefault(),o())}),c.select(),document.body.appendChild(n),c.focus()})}async promptSpawnerConfig(){return new Promise(e=>{var m,b,y;let t=document.createElement("div");t.className="add-menu-modal-overlay";let i="template_id",n=`${i}_spawner_1`,a="",s=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=`
477
477
  <div class="add-menu-modal add-menu-modal-wide">
478
478
  <div class="add-menu-modal-header">
479
479
  <div class="add-menu-modal-title">
@@ -603,18 +603,18 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
603
603
  <button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Create Spawner</button>
604
604
  </div>
605
605
  </div>
606
- `;let c=()=>{t.parentNode&&t.parentNode.removeChild(t)},d=t.querySelectorAll(".add-menu-modal-tab"),p=t.querySelectorAll(".add-menu-modal-tab-content");d.forEach(v=>{v.addEventListener("click",()=>{var I;let w=v.dataset.tab;d.forEach(P=>P.classList.remove("active")),p.forEach(P=>P.classList.remove("active")),v.classList.add("active"),(I=t.querySelector(`[data-tab-content="${w}"]`))==null||I.classList.add("active")})});let u=v=>{let w=v.trim();if(!w)return null;try{return JSON.parse(w)}catch{return null}},g=()=>{var B;let v=t.querySelector("#spawner-instance-id").value.trim(),w=t.querySelector("#spawner-template-id").value.trim(),I=t.querySelector("#spawner-spawn-templates").value,P=t.querySelector("#spawner-position-source").value.trim(),_=t.querySelector("#spawner-point-mode").value.trim(),T=t.querySelector("#spawner-spawn-points").value,M=t.querySelector("#spawner-pattern").value.trim(),k=Number(t.querySelector("#spawner-rate").value.trim()),A=Number(t.querySelector("#spawner-pool").value.trim()),C=Number(t.querySelector("#spawner-lifetime").value.trim()),L=t.querySelector("#spawner-return-on-invisible").checked,x=t.querySelector("#spawner-movement").value.trim(),E=Number(t.querySelector("#spawner-vel-x").value.trim()),S=Number(t.querySelector("#spawner-vel-y").value.trim()),O=t.querySelector("#spawner-velocity-range").value,j=u(I),R=Array.isArray(j)&&j.length?j:null,z=typeof((B=R==null?void 0:R[0])==null?void 0:B.templateId)=="string"?String(R[0].templateId):w;if(!v){alert("Instance ID is required.");return}if(!z){alert("Template ID is required.");return}let D={templateId:z,spawnPattern:M,spawnRate:Number.isFinite(k)?k:650,poolSize:Number.isFinite(A)?A:18,returnOnInvisible:L,positionSource:P,spawnPointMode:_,movementMode:x,lifetime:Number.isFinite(C)?C:5e3};R&&(D.spawnTemplates=R);let q=u(T);Array.isArray(q)&&(D.spawnPoints=q),Number.isFinite(E)&&Number.isFinite(S)&&(D.velocity={x:E,y:S});let G=u(O);G&&typeof G=="object"&&(D.velocityRange=G),c(),e({templateId:z,instanceId:v,spawnerProps:D})},h=()=>{c(),e(null)};t.querySelector(".add-menu-modal").addEventListener("click",v=>v.stopPropagation()),(m=t.querySelector('[data-action="confirm"]'))==null||m.addEventListener("click",g),(b=t.querySelector('[data-action="cancel"]'))==null||b.addEventListener("click",h),(y=t.querySelector(".add-menu-modal-close"))==null||y.addEventListener("click",h),t.addEventListener("click",v=>{v.target===t&&h()}),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:"center",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 s=a,r=this.buildDefaultConfig(e,s,a);try{let p=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:s,objectConfigId:r.identity.id,layer:e==="ui-image"||e==="ui-text"?"ui":"world",config:r,forceSync:!0})}),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(`
607
- `))||(u==null?void 0:u.error)||"Failed to create object.";alert(h);return}let{trackObjectCreation:g}=await Promise.resolve().then(()=>(Q(),Ie));g(s,i,r),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 s,r,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,forceSync:!0})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((s=d==null?void 0:d.errors)==null?void 0:s.join(`
608
- `))||(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=(r=this.options).onRefresh)==null||l.call(r)}catch(c){alert(`Failed to create from template: ${c instanceof Error?c.message:String(c)}`)}}async handleCreateSystem(e,t){var n,a,s,r,l,c,d,p,u,g,h,f,m,b,y,v,w,I,P,_,T,M,k,A,C,L,x;this.close();let i=t!=null?t:await this.promptScreen();if(i){if(e==="collectable-system")try{let E=await fetch("/api/systems/collectable-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await E.json().catch(()=>({}));if(!E.ok||(S==null?void 0:S.success)===!1){let O=((n=S==null?void 0:S.errors)==null?void 0:n.join(`
609
- `))||(S==null?void 0:S.error)||"Failed to create collectable system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(s=(a=this.options).onRefresh)==null||s.call(a)}catch(E){alert(`Failed to create collectable system: ${E instanceof Error?E.message:String(E)}`)}if(e==="drag-snap-couples")try{let E=await fetch("/api/systems/drag-snap-couples",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await E.json().catch(()=>({}));if(!E.ok||(S==null?void 0:S.success)===!1){let O=((r=S==null?void 0:S.errors)==null?void 0:r.join(`
610
- `))||(S==null?void 0:S.error)||"Failed to create drag-snap system.";alert(O);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(E){alert(`Failed to create drag-snap system: ${E instanceof Error?E.message:String(E)}`)}if(e==="swerve-collect")try{let E=await fetch("/api/systems/swerve-collect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await E.json().catch(()=>({}));if(!E.ok||(S==null?void 0:S.success)===!1){let O=((d=S==null?void 0:S.errors)==null?void 0:d.join(`
611
- `))||(S==null?void 0:S.error)||"Failed to create swerve collect system.";alert(O);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(E){alert(`Failed to create swerve collect system: ${E instanceof Error?E.message:String(E)}`)}if(e==="tap-destroy")try{let E=await fetch("/api/systems/tap-destroy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await E.json().catch(()=>({}));if(!E.ok||(S==null?void 0:S.success)===!1){let O=((g=S==null?void 0:S.errors)==null?void 0:g.join(`
612
- `))||(S==null?void 0:S.error)||"Failed to create tap destroy system.";alert(O);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(E){alert(`Failed to create tap destroy system: ${E instanceof Error?E.message:String(E)}`)}if(e==="scratch-card")try{let E=await fetch("/api/systems/scratch-card",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await E.json().catch(()=>({}));if(!E.ok||(S==null?void 0:S.success)===!1){let O=((m=S==null?void 0:S.errors)==null?void 0:m.join(`
613
- `))||(S==null?void 0:S.error)||"Failed to create scratch card system.";alert(O);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(E){alert(`Failed to create scratch card system: ${E instanceof Error?E.message:String(E)}`)}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"})}),O=await S.json().catch(()=>({}));if(!S.ok||(O==null?void 0:O.success)===!1){let j=((v=O==null?void 0:O.errors)==null?void 0:v.join(`
614
- `))||(O==null?void 0:O.error)||"Failed to create start screen template.";alert(j);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(I=(w=this.options).onRefresh)==null||I.call(w)}catch(E){alert(`Failed to create start screen template: ${E instanceof Error?E.message:String(E)}`)}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"})}),O=await S.json().catch(()=>({}));if(!S.ok||(O==null?void 0:O.success)===!1){let j=((P=O==null?void 0:O.errors)==null?void 0:P.join(`
615
- `))||(O==null?void 0:O.error)||"Failed to create endgame screen template.";alert(j);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(T=(_=this.options).onRefresh)==null||T.call(_)}catch(E){alert(`Failed to create endgame screen template: ${E instanceof Error?E.message:String(E)}`)}if(e==="bullet-system")try{let E=await fetch("/api/systems/bullet-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),S=await E.json().catch(()=>({}));if(!E.ok||(S==null?void 0:S.success)===!1){let O=((M=S==null?void 0:S.errors)==null?void 0:M.join(`
616
- `))||(S==null?void 0:S.error)||"Failed to create bullet system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(A=(k=this.options).onRefresh)==null||A.call(k)}catch(E){alert(`Failed to create bullet system: ${E instanceof Error?E.message:String(E)}`)}if(e==="spawner"){let E=await this.promptSpawnerConfig();if(!E)return;let{templateId:S,instanceId:O,spawnerProps:j}=E;try{let R=await fetch("/api/systems/spawner",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,templateId:S,instanceId:O,spawnerProps:j,forceSync:!0})}),z=await R.json().catch(()=>({}));if(!R.ok||(z==null?void 0:z.success)===!1){let D=((C=z==null?void 0:z.errors)==null?void 0:C.join(`
617
- `))||(z==null?void 0:z.error)||"Failed to create spawner.";alert(D);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(x=(L=this.options).onRefresh)==null||x.call(L)}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{let e=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[AddObjectMenu] Failed to sync screens:",e)}}};var _i=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.isContextMenuOpen=!1;this.systemBundles=new Map;this.collapsedGroups=new Set}getScreenFilterStorageKey(){return`handler_preview_screen_filter::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getCollapseStorageKey(){return`handler_preview_scene_collapsed::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}loadCollapsedGroups(){try{let e=window.localStorage.getItem(this.getCollapseStorageKey());if(!e)return;let t=JSON.parse(e);Array.isArray(t)&&(this.collapsedGroups=new Set(t.filter(i=>typeof i=="string")))}catch{}}persistCollapsedGroups(){try{window.localStorage.setItem(this.getCollapseStorageKey(),JSON.stringify(Array.from(this.collapsedGroups)))}catch{}}isCollapsed(e){return this.collapsedGroups.has(e)}setCollapsed(e,t){t?this.collapsedGroups.add(e):this.collapsedGroups.delete(e),this.persistCollapsedGroups()}getCollapseKey(e){return encodeURIComponent(e)}getSystemBundleKey(e,t){return this.getCollapseKey(`bundle:${e}::${t}`)}render(){return`
606
+ `;let c=()=>{t.parentNode&&t.parentNode.removeChild(t)},d=t.querySelectorAll(".add-menu-modal-tab"),p=t.querySelectorAll(".add-menu-modal-tab-content");d.forEach(w=>{w.addEventListener("click",()=>{var P;let v=w.dataset.tab;d.forEach(I=>I.classList.remove("active")),p.forEach(I=>I.classList.remove("active")),w.classList.add("active"),(P=t.querySelector(`[data-tab-content="${v}"]`))==null||P.classList.add("active")})});let u=w=>{let v=w.trim();if(!v)return null;try{return JSON.parse(v)}catch{return null}},g=()=>{var H;let w=t.querySelector("#spawner-instance-id").value.trim(),v=t.querySelector("#spawner-template-id").value.trim(),P=t.querySelector("#spawner-spawn-templates").value,I=t.querySelector("#spawner-position-source").value.trim(),_=t.querySelector("#spawner-point-mode").value.trim(),k=t.querySelector("#spawner-spawn-points").value,j=t.querySelector("#spawner-pattern").value.trim(),L=Number(t.querySelector("#spawner-rate").value.trim()),x=Number(t.querySelector("#spawner-pool").value.trim()),S=Number(t.querySelector("#spawner-lifetime").value.trim()),E=t.querySelector("#spawner-return-on-invisible").checked,C=t.querySelector("#spawner-movement").value.trim(),A=Number(t.querySelector("#spawner-vel-x").value.trim()),T=Number(t.querySelector("#spawner-vel-y").value.trim()),O=t.querySelector("#spawner-velocity-range").value,M=u(P),R=Array.isArray(M)&&M.length?M:null,z=typeof((H=R==null?void 0:R[0])==null?void 0:H.templateId)=="string"?String(R[0].templateId):v;if(!w){alert("Instance ID is required.");return}if(!z){alert("Template ID is required.");return}let F={templateId:z,spawnPattern:j,spawnRate:Number.isFinite(L)?L:650,poolSize:Number.isFinite(x)?x:18,returnOnInvisible:E,positionSource:I,spawnPointMode:_,movementMode:C,lifetime:Number.isFinite(S)?S:5e3};R&&(F.spawnTemplates=R);let q=u(k);Array.isArray(q)&&(F.spawnPoints=q),Number.isFinite(A)&&Number.isFinite(T)&&(F.velocity={x:A,y:T});let N=u(O);N&&typeof N=="object"&&(F.velocityRange=N),c(),e({templateId:z,instanceId:w,spawnerProps:F})},h=()=>{c(),e(null)};t.querySelector(".add-menu-modal").addEventListener("click",w=>w.stopPropagation()),(m=t.querySelector('[data-action="confirm"]'))==null||m.addEventListener("click",g),(b=t.querySelector('[data-action="cancel"]'))==null||b.addEventListener("click",h),(y=t.querySelector(".add-menu-modal-close"))==null||y.addEventListener("click",h),t.addEventListener("click",w=>{w.target===t&&h()}),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:"center",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 s=a,o=this.buildDefaultConfig(e,s,a);try{let p=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:s,objectConfigId:o.identity.id,layer:e==="ui-image"||e==="ui-text"?"ui":"world",config:o,forceSync:!0})}),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(`
607
+ `))||(u==null?void 0:u.error)||"Failed to create object.";alert(h);return}let{trackObjectCreation:g}=await Promise.resolve().then(()=>(ne(),Pe));g(s,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 s,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,forceSync:!0})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((s=d==null?void 0:d.errors)==null?void 0:s.join(`
608
+ `))||(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,s,o,l,c,d,p,u,g,h,f,m,b,y,w,v,P,I,_,k,j,L,x,S,E,C;this.close();let i=t!=null?t:await this.promptScreen();if(i){if(e==="collectable-system")try{let A=await fetch("/api/systems/collectable-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),T=await A.json().catch(()=>({}));if(!A.ok||(T==null?void 0:T.success)===!1){let O=((n=T==null?void 0:T.errors)==null?void 0:n.join(`
609
+ `))||(T==null?void 0:T.error)||"Failed to create collectable system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(s=(a=this.options).onRefresh)==null||s.call(a)}catch(A){alert(`Failed to create collectable system: ${A instanceof Error?A.message:String(A)}`)}if(e==="drag-snap-couples")try{let A=await fetch("/api/systems/drag-snap-couples",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),T=await A.json().catch(()=>({}));if(!A.ok||(T==null?void 0:T.success)===!1){let O=((o=T==null?void 0:T.errors)==null?void 0:o.join(`
610
+ `))||(T==null?void 0:T.error)||"Failed to create drag-snap system.";alert(O);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(A){alert(`Failed to create drag-snap system: ${A instanceof Error?A.message:String(A)}`)}if(e==="swerve-collect")try{let A=await fetch("/api/systems/swerve-collect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),T=await A.json().catch(()=>({}));if(!A.ok||(T==null?void 0:T.success)===!1){let O=((d=T==null?void 0:T.errors)==null?void 0:d.join(`
611
+ `))||(T==null?void 0:T.error)||"Failed to create swerve collect system.";alert(O);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(A){alert(`Failed to create swerve collect system: ${A instanceof Error?A.message:String(A)}`)}if(e==="tap-destroy")try{let A=await fetch("/api/systems/tap-destroy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),T=await A.json().catch(()=>({}));if(!A.ok||(T==null?void 0:T.success)===!1){let O=((g=T==null?void 0:T.errors)==null?void 0:g.join(`
612
+ `))||(T==null?void 0:T.error)||"Failed to create tap destroy system.";alert(O);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(A){alert(`Failed to create tap destroy system: ${A instanceof Error?A.message:String(A)}`)}if(e==="scratch-card")try{let A=await fetch("/api/systems/scratch-card",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),T=await A.json().catch(()=>({}));if(!A.ok||(T==null?void 0:T.success)===!1){let O=((m=T==null?void 0:T.errors)==null?void 0:m.join(`
613
+ `))||(T==null?void 0:T.error)||"Failed to create scratch card system.";alert(O);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(A){alert(`Failed to create scratch card system: ${A instanceof Error?A.message:String(A)}`)}if(e==="start-screen"||e==="start-screen-no-hand")try{let T=await fetch("/api/systems/start-screen",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,withHand:e==="start-screen"})}),O=await T.json().catch(()=>({}));if(!T.ok||(O==null?void 0:O.success)===!1){let M=((w=O==null?void 0:O.errors)==null?void 0:w.join(`
614
+ `))||(O==null?void 0:O.error)||"Failed to create start screen template.";alert(M);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(P=(v=this.options).onRefresh)==null||P.call(v)}catch(A){alert(`Failed to create start screen template: ${A instanceof Error?A.message:String(A)}`)}if(e==="endgame-screen"||e==="endgame-screen-no-hand")try{let T=await fetch("/api/systems/endgame-screen",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,withHand:e==="endgame-screen"})}),O=await T.json().catch(()=>({}));if(!T.ok||(O==null?void 0:O.success)===!1){let M=((I=O==null?void 0:O.errors)==null?void 0:I.join(`
615
+ `))||(O==null?void 0:O.error)||"Failed to create endgame screen template.";alert(M);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(k=(_=this.options).onRefresh)==null||k.call(_)}catch(A){alert(`Failed to create endgame screen template: ${A instanceof Error?A.message:String(A)}`)}if(e==="bullet-system")try{let A=await fetch("/api/systems/bullet-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),T=await A.json().catch(()=>({}));if(!A.ok||(T==null?void 0:T.success)===!1){let O=((j=T==null?void 0:T.errors)==null?void 0:j.join(`
616
+ `))||(T==null?void 0:T.error)||"Failed to create bullet system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(x=(L=this.options).onRefresh)==null||x.call(L)}catch(A){alert(`Failed to create bullet system: ${A instanceof Error?A.message:String(A)}`)}if(e==="spawner"){let A=await this.promptSpawnerConfig();if(!A)return;let{templateId:T,instanceId:O,spawnerProps:M}=A;try{let R=await fetch("/api/systems/spawner",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,templateId:T,instanceId:O,spawnerProps:M,forceSync:!0})}),z=await R.json().catch(()=>({}));if(!R.ok||(z==null?void 0:z.success)===!1){let F=((S=z==null?void 0:z.errors)==null?void 0:S.join(`
617
+ `))||(z==null?void 0:z.error)||"Failed to create spawner.";alert(F);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(C=(E=this.options).onRefresh)==null||C.call(E)}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{let e=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[AddObjectMenu] Failed to sync screens:",e)}}};var Oi=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.isContextMenuOpen=!1;this.systemBundles=new Map;this.collapsedGroups=new Set}getScreenFilterStorageKey(){return`handler_preview_screen_filter::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getCollapseStorageKey(){return`handler_preview_scene_collapsed::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}loadCollapsedGroups(){try{let e=window.localStorage.getItem(this.getCollapseStorageKey());if(!e)return;let t=JSON.parse(e);Array.isArray(t)&&(this.collapsedGroups=new Set(t.filter(i=>typeof i=="string")))}catch{}}persistCollapsedGroups(){try{window.localStorage.setItem(this.getCollapseStorageKey(),JSON.stringify(Array.from(this.collapsedGroups)))}catch{}}isCollapsed(e){return this.collapsedGroups.has(e)}setCollapsed(e,t){t?this.collapsedGroups.add(e):this.collapsedGroups.delete(e),this.persistCollapsedGroups()}getCollapseKey(e){return encodeURIComponent(e)}getSystemBundleKey(e,t){return this.getCollapseKey(`bundle:${e}::${t}`)}render(){return`
618
618
  <div class="scene-panel scene-objects panel-accent-teal" data-panel="scene-objects">
619
619
  <div class="scene-panel-header" data-panel-handle>
620
620
  <div class="panel-title">
@@ -649,13 +649,13 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
649
649
  </div>
650
650
  <div class="panel-resize-handle-v" data-panel-resize-v></div>
651
651
  </div>
652
- `}initialize(e,t){var a,s,r,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="scene-objects"]'),this.listContainer=(a=this.root)==null?void 0:a.querySelector("[data-object-list]"),this.searchInput=(s=this.root)==null?void 0:s.querySelector("#scene-object-search"),(r=this.searchInput)==null||r.addEventListener("input",()=>this.refreshObjects()),this.loadCollapsedGroups(),(l=this.listContainer)==null||l.addEventListener("click",g=>{var w;let h=g.target,f=h==null?void 0:h.closest("[data-collapse-key]");if(f){let I=f.dataset.collapseKey||"";if(!I)return;let P=(w=this.listContainer)==null?void 0:w.querySelector(`[data-collapse-content="${I}"]`),_=this.isCollapsed(I);P&&(P.style.display=_?"":"none"),f.textContent=_?"\u25BE":"\u25B8",this.setCollapsed(I,!_),g.preventDefault(),g.stopPropagation();return}let m=h==null?void 0:h.closest("[data-object-visibility-toggle][data-object-id]");if(m){let I=m.dataset.objectId;if(!I)return;g.preventDefault(),g.stopPropagation(),this.toggleObjectVisibility(I);return}let b=h==null?void 0:h.closest("[data-system-bundle-action][data-system-bundle-id]");if(!b)return;g.preventDefault(),g.stopPropagation();let y=b.dataset.systemBundleAction,v=b.dataset.systemBundleId;if(!(!y||!v)){if(y==="toggle-visibility"){this.toggleSystemBundleVisibility(v);return}y==="delete"&&this.deleteSystemBundle(v)}});let i=(c=this.root)==null?void 0:c.querySelector("[data-add-object]");i==null||i.addEventListener("click",g=>{g.stopPropagation();let h=i.getBoundingClientRect();this.openAddObjectMenu({x:h.left,y:h.bottom+4})});let n=(d=this.root)==null?void 0:d.querySelector("#scene-screen-filter");if(n){try{let g=window.localStorage.getItem(this.getScreenFilterStorageKey());g&&(this.screenFilter=g)}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{}try{let g=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof g=="function"&&g().catch(()=>{})}catch{}n.addEventListener("change",()=>{let g=n.value||"all";this.screenFilter=g;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{}try{let h=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof h=="function"&&h().catch(()=>{})}catch{}this.refreshObjects()})}(p=this.root)==null||p.addEventListener("click",g=>{let h=g.target;if(!h||h.closest("[data-context-menu]"))return;if(h.tagName==="INPUT"&&h.classList.contains("scene-object-checkbox")){let w=h.dataset.objectId;if(!w)return;g.stopPropagation(),this.toggleBatchSelect(w);return}let f=h.closest(".scene-object-item[data-object-id]");if(!f)return;let m=f.dataset.objectId;if(!m)return;let b=g.ctrlKey||g.metaKey;g.shiftKey&&this.lastSelectedIndex>=0?this.selectRange(this.lastSelectedIndex,m):b?this.toggleBatchSelect(m):this.select(m)}),(u=this.listContainer)==null||u.addEventListener("contextmenu",g=>{var w;let h=g.target,f=h==null?void 0:h.closest("[data-object-id]");if(!f)return;let m=f.dataset.objectId;if(!m)return;g.preventDefault();let b=window.getEditableObjectConfig,y=typeof b=="function"?b(m):null;if(!y){let I=window.__editableObjectConfigs;I&&typeof I.get=="function"&&(y=(w=I.get(m))!=null?w:null)}let v=this.inferScreen(m,y);this.showContextMenu(m,v,g.clientX,g.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,s,r,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=(s=this.root)==null?void 0:s.querySelector("[data-breadcrumb-screen]"),n=(r=this.root)==null?void 0:r.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 u;if(!this.listContainer)return;let e=window.getEditableObjectList,t=window.getEditableObjectListAll,i=window.refreshEditableConfigIndex;if(typeof i=="function"&&i(),typeof e!="function"&&typeof t!="function"){this.scheduleRetry();return}let n=typeof t=="function"?t():e();if(!Array.isArray(n)||n.length===0){let g=window.__editableObjectConfigs;g&&typeof g.keys=="function"&&(n=Array.from(g.keys()))}if(!Array.isArray(n)||n.length===0){this.scheduleRetry();return}let a=(((u=this.searchInput)==null?void 0:u.value)||"").trim().toLowerCase(),s=["loading","start","gameplay","tutorial","endgame"],r={loading:{templates:[],systems:[],objects:[],bundles:new Map},start:{templates:[],systems:[],objects:[],bundles:new Map},gameplay:{templates:[],systems:[],objects:[],bundles:new Map},tutorial:{templates:[],systems:[],objects:[],bundles:new Map},endgame:{templates:[],systems:[],objects:[],bundles:new Map}};this.systemBundles=new Map;let l=g=>{var m,b,y,v,w;let h=(v=(y=(b=(m=window.__editableConfig)==null?void 0:m.objects)==null?void 0:b.get)==null?void 0:y.call(b,g))!=null?v:null;if(h)return h;let f=window.__editableObjectConfigs;return f&&typeof f.get=="function"&&(w=f.get(g))!=null?w:null};n.forEach(g=>{var x,E,S,O,j,R,z;let h=l(g),f=(((x=h==null?void 0:h.identity)==null?void 0:x.category)||"scene").toString(),m=(((E=h==null?void 0:h.identity)==null?void 0:E.id)||g).toString(),b=f.toLowerCase(),y=m.toLowerCase(),v=b.includes("ui")||y.startsWith("ui")||y.includes("label"),w=b==="system",I=((S=h==null?void 0:h.identity)==null?void 0:S.is_template)===!0||y.includes(".template")||g.toLowerCase().includes(".template"),P=typeof((O=h==null?void 0:h.identity)==null?void 0:O.system_group)=="string"?h.identity.system_group:null,_=typeof((j=h==null?void 0:h.identity)==null?void 0:j.system_label)=="string"?h.identity.system_label:P?this.formatDisplayName(P):null,T=this.formatDisplayName(m||g),M=((R=h==null?void 0:h.render)==null?void 0:R.visible)===!1||(h==null?void 0:h.enabled)===!1,k=this.getObjectType(h),A={id:g,label:T,category:f,isUi:v,isTemplate:I,isUnused:M,objectType:k,systemGroupId:P,systemLabel:_},C=this.inferScreen(A.id,h);if(!(this.screenFilter!=="all"&&C!==this.screenFilter||!(!a||A.id.toLowerCase().includes(a)||A.label.toLowerCase().includes(a)))){if(P){let D=this.getSystemBundleKey(C,P),q=_!=null?_:P,G=r[C],B=G.bundles.get(D);B?(B.entries.push(A),B.objectIds.push(g)):G.bundles.set(D,{key:D,label:q,objectIds:[g],entries:[A]});let F=(z=this.systemBundles.get(D))!=null?z:{label:q,objectIds:[]};F.label=q,F.objectIds.push(g),this.systemBundles.set(D,F);return}if(I){r[C].templates.push(A);return}w?r[C].systems.push(A):r[C].objects.push(A)}});let c={loading:"Loading Screen",start:"Start Screen",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},d=this.screenFilter==="all"?s:[this.screenFilter],p=d.map(g=>this.renderScreenGroup(g,c[g],r[g])).join("");this.listContainer.innerHTML=p,this.objectEntries=[];for(let g of d){let h=r[g];this.objectEntries.push(...h.templates),h.bundles.forEach(f=>this.objectEntries.push(...f.entries)),this.objectEntries.push(...h.systems),this.objectEntries.push(...h.objects)}for(let g of d){let h=r[g];if(!h.systems.length)continue;let f=this.listContainer.querySelector(`[data-delete-system-group="${g}"]`);f==null||f.addEventListener("click",m=>{m.stopPropagation(),this.deleteSystemGroup(h.systems)})}this.updateSelectionUI()}renderSystemBundle(e,t,i,n){let a=this.isBundleAllHidden(i),s=a?"Show all objects in this system":"Hide all objects in this system",r=a?"is-hidden":"",l=n.map(g=>this.renderEntryItem(g)).join(""),c=this.escapeHtml(e),d=this.getCollapseKey(`system:${e}`),p=this.isCollapsed(d);return`
652
+ `}initialize(e,t){var a,s,o,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="scene-objects"]'),this.listContainer=(a=this.root)==null?void 0:a.querySelector("[data-object-list]"),this.searchInput=(s=this.root)==null?void 0:s.querySelector("#scene-object-search"),(o=this.searchInput)==null||o.addEventListener("input",()=>this.refreshObjects()),this.loadCollapsedGroups(),(l=this.listContainer)==null||l.addEventListener("click",g=>{var v;let h=g.target,f=h==null?void 0:h.closest("[data-collapse-key]");if(f){let P=f.dataset.collapseKey||"";if(!P)return;let I=(v=this.listContainer)==null?void 0:v.querySelector(`[data-collapse-content="${P}"]`),_=this.isCollapsed(P);I&&(I.style.display=_?"":"none"),f.textContent=_?"\u25BE":"\u25B8",this.setCollapsed(P,!_),g.preventDefault(),g.stopPropagation();return}let m=h==null?void 0:h.closest("[data-object-visibility-toggle][data-object-id]");if(m){let P=m.dataset.objectId;if(!P)return;g.preventDefault(),g.stopPropagation(),this.toggleObjectVisibility(P);return}let b=h==null?void 0:h.closest("[data-system-bundle-action][data-system-bundle-id]");if(!b)return;g.preventDefault(),g.stopPropagation();let y=b.dataset.systemBundleAction,w=b.dataset.systemBundleId;if(!(!y||!w)){if(y==="toggle-visibility"){this.toggleSystemBundleVisibility(w);return}y==="delete"&&this.deleteSystemBundle(w)}});let i=(c=this.root)==null?void 0:c.querySelector("[data-add-object]");i==null||i.addEventListener("click",g=>{g.stopPropagation();let h=i.getBoundingClientRect();this.openAddObjectMenu({x:h.left,y:h.bottom+4})});let n=(d=this.root)==null?void 0:d.querySelector("#scene-screen-filter");if(n){try{let g=window.localStorage.getItem(this.getScreenFilterStorageKey());g&&(this.screenFilter=g)}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{}try{let g=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof g=="function"&&g().catch(()=>{})}catch{}n.addEventListener("change",()=>{let g=n.value||"all";this.screenFilter=g;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{}try{let h=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof h=="function"&&h().catch(()=>{})}catch{}this.refreshObjects()})}(p=this.root)==null||p.addEventListener("click",g=>{let h=g.target;if(!h||h.closest("[data-context-menu]"))return;if(h.tagName==="INPUT"&&h.classList.contains("scene-object-checkbox")){let v=h.dataset.objectId;if(!v)return;g.stopPropagation(),this.toggleBatchSelect(v);return}let f=h.closest(".scene-object-item[data-object-id]");if(!f)return;let m=f.dataset.objectId;if(!m)return;let b=g.ctrlKey||g.metaKey;g.shiftKey&&this.lastSelectedIndex>=0?this.selectRange(this.lastSelectedIndex,m):b?this.toggleBatchSelect(m):this.select(m)}),(u=this.listContainer)==null||u.addEventListener("contextmenu",g=>{var v;let h=g.target,f=h==null?void 0:h.closest("[data-object-id]");if(!f)return;let m=f.dataset.objectId;if(!m)return;g.preventDefault();let b=window.getEditableObjectConfig,y=typeof b=="function"?b(m):null;if(!y){let P=window.__editableObjectConfigs;P&&typeof P.get=="function"&&(y=(v=P.get(m))!=null?v:null)}let w=this.inferScreen(m,y);this.showContextMenu(m,w,g.clientX,g.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,s,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=(s=this.root)==null?void 0:s.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 u;if(!this.listContainer)return;let e=window.getEditableObjectList,t=window.getEditableObjectListAll,i=window.refreshEditableConfigIndex;if(typeof i=="function"&&i(),typeof e!="function"&&typeof t!="function"){this.scheduleRetry();return}let n=typeof t=="function"?t():e();if(!Array.isArray(n)||n.length===0){let g=window.__editableObjectConfigs;g&&typeof g.keys=="function"&&(n=Array.from(g.keys()))}if(!Array.isArray(n)||n.length===0){this.scheduleRetry();return}let a=(((u=this.searchInput)==null?void 0:u.value)||"").trim().toLowerCase(),s=["loading","start","gameplay","tutorial","endgame"],o={loading:{templates:[],systems:[],objects:[],bundles:new Map},start:{templates:[],systems:[],objects:[],bundles:new Map},gameplay:{templates:[],systems:[],objects:[],bundles:new Map},tutorial:{templates:[],systems:[],objects:[],bundles:new Map},endgame:{templates:[],systems:[],objects:[],bundles:new Map}};this.systemBundles=new Map;let l=g=>{var m,b,y,w,v;let h=(w=(y=(b=(m=window.__editableConfig)==null?void 0:m.objects)==null?void 0:b.get)==null?void 0:y.call(b,g))!=null?w:null;if(h)return h;let f=window.__editableObjectConfigs;return f&&typeof f.get=="function"&&(v=f.get(g))!=null?v:null};n.forEach(g=>{var C,A,T,O,M,R,z;let h=l(g),f=(((C=h==null?void 0:h.identity)==null?void 0:C.category)||"scene").toString(),m=(((A=h==null?void 0:h.identity)==null?void 0:A.id)||g).toString(),b=f.toLowerCase(),y=m.toLowerCase(),w=b.includes("ui")||y.startsWith("ui")||y.includes("label"),v=b==="system",P=((T=h==null?void 0:h.identity)==null?void 0:T.is_template)===!0||y.includes(".template")||g.toLowerCase().includes(".template"),I=typeof((O=h==null?void 0:h.identity)==null?void 0:O.system_group)=="string"?h.identity.system_group:null,_=typeof((M=h==null?void 0:h.identity)==null?void 0:M.system_label)=="string"?h.identity.system_label:I?this.formatDisplayName(I):null,k=this.formatDisplayName(m||g),j=((R=h==null?void 0:h.render)==null?void 0:R.visible)===!1||(h==null?void 0:h.enabled)===!1,L=this.getObjectType(h),x={id:g,label:k,category:f,isUi:w,isTemplate:P,isUnused:j,objectType:L,systemGroupId:I,systemLabel:_},S=this.inferScreen(x.id,h);if(!(this.screenFilter!=="all"&&S!==this.screenFilter||!(!a||x.id.toLowerCase().includes(a)||x.label.toLowerCase().includes(a)))){if(I){let F=this.getSystemBundleKey(S,I),q=_!=null?_:I,N=o[S],H=N.bundles.get(F);H?(H.entries.push(x),H.objectIds.push(g)):N.bundles.set(F,{key:F,label:q,objectIds:[g],entries:[x]});let $=(z=this.systemBundles.get(F))!=null?z:{label:q,objectIds:[]};$.label=q,$.objectIds.push(g),this.systemBundles.set(F,$);return}if(P){o[S].templates.push(x);return}v?o[S].systems.push(x):o[S].objects.push(x)}});let c={loading:"Loading Screen",start:"Start Screen",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},d=this.screenFilter==="all"?s:[this.screenFilter],p=d.map(g=>this.renderScreenGroup(g,c[g],o[g])).join("");this.listContainer.innerHTML=p,this.objectEntries=[];for(let g of d){let h=o[g];this.objectEntries.push(...h.templates),h.bundles.forEach(f=>this.objectEntries.push(...f.entries)),this.objectEntries.push(...h.systems),this.objectEntries.push(...h.objects)}for(let g of d){let h=o[g];if(!h.systems.length)continue;let f=this.listContainer.querySelector(`[data-delete-system-group="${g}"]`);f==null||f.addEventListener("click",m=>{m.stopPropagation(),this.deleteSystemGroup(h.systems)})}this.updateSelectionUI()}renderSystemBundle(e,t,i,n){let a=this.isBundleAllHidden(i),s=a?"Show all objects in this system":"Hide all objects in this system",o=a?"is-hidden":"",l=n.map(g=>this.renderEntryItem(g)).join(""),c=this.escapeHtml(e),d=this.getCollapseKey(`system:${e}`),p=this.isCollapsed(d);return`
653
653
  <div class="scene-object-group scene-object-group-bundle" data-system-bundle="${c}">
654
654
  <div class="scene-object-group-title">
655
655
  <button class="scene-object-group-toggle" type="button" data-collapse-key="${d}">${p?"\u25B8":"\u25BE"}</button>
656
656
  <span>${this.escapeHtml(t)} <span class="scene-object-count">${i.length}</span></span>
657
657
  <div class="scene-object-group-actions">
658
- <button class="scene-object-group-action scene-object-group-visibility ${r}" data-system-bundle-action="toggle-visibility" data-system-bundle-id="${c}" type="button" title="${s}">\u{1F441}\uFE0F</button>
658
+ <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="${s}">\u{1F441}\uFE0F</button>
659
659
  <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>
660
660
  </div>
661
661
  </div>
@@ -674,7 +674,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
674
674
  <span class="scene-object-badge ${e.isUi?"ui":"scene"}">${e.category}</span>
675
675
  </button>
676
676
  </div>
677
- `}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 s,r,l;let a=(r=(s=t==null?void 0:t.get)==null?void 0:s.call(t,n))!=null?r:null;return((l=a==null?void 0:a.render)==null?void 0:l.visible)===!1})}toggleSystemBundleVisibility(e){var r;let t=this.systemBundles.get(e);if(!t)return;let i=t.objectIds||[];if(!i.length)return;let n=(r=window.__editableConfig)==null?void 0:r.objects;if(!n||typeof n.get!="function")return;let s=this.isBundleAllHidden(i);i.forEach(l=>{let c=n.get(l);c&&(c.render||(c.render={}),c.render.visible=s)});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 r,l;let i=window.__HANDLER_SCREEN_INDEX,n=(r=i==null?void 0:i.instanceToScreen)==null?void 0:r[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(),s=`${e} ${a}`.toLowerCase();return s.includes("loading")?"loading":s.includes("start")?"start":s.includes("tutorial")?"tutorial":s.includes("endgame")||s.includes("end_card")||s.includes("endcard")?"endgame":"gameplay"}getObjectType(e){var t,i,n,a,s,r,l,c,d,p;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":((r=(s=e.render)==null?void 0:s.asset)==null?void 0:r.type)==="image"||(l=e.render)!=null&&l.texture?"sprite":(d=(c=e.gameplay)==null?void 0:c.tuning)!=null&&d.panel_width||(p=e.effects)!=null&&p.width?"graphics":"container":"container"}renderEntriesList(e){return e.length?e.map(t=>this.renderEntryItem(t)).join(""):""}renderCollapsibleGroup(e){var a;let t=this.isCollapsed(e.key),i=t?"\u25B8":"\u25BE",n=e.actionsHtml?`<div class="scene-object-group-actions">${e.actionsHtml}</div>`:"";return`
677
+ `}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 s,o,l;let a=(o=(s=t==null?void 0:t.get)==null?void 0:s.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 s=this.isBundleAllHidden(i);i.forEach(l=>{let c=n.get(l);c&&(c.render||(c.render={}),c.render.visible=s)});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(),s=`${e} ${a}`.toLowerCase();return s.includes("loading")?"loading":s.includes("start")?"start":s.includes("tutorial")?"tutorial":s.includes("endgame")||s.includes("end_card")||s.includes("endcard")?"endgame":"gameplay"}getObjectType(e){var t,i,n,a,s,o,l,c,d,p;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=(s=e.render)==null?void 0:s.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||(p=e.effects)!=null&&p.width?"graphics":"container":"container"}renderEntriesList(e){return e.length?e.map(t=>this.renderEntryItem(t)).join(""):""}renderCollapsibleGroup(e){var a;let t=this.isCollapsed(e.key),i=t?"\u25B8":"\u25BE",n=e.actionsHtml?`<div class="scene-object-group-actions">${e.actionsHtml}</div>`:"";return`
678
678
  <div class="scene-object-group ${(a=e.className)!=null?a:""}">
679
679
  <div class="scene-object-group-title">
680
680
  <button class="scene-object-group-toggle" type="button" data-collapse-key="${e.key}">${i}</button>
@@ -685,20 +685,20 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
685
685
  ${e.content}
686
686
  </div>
687
687
  </div>
688
- `}renderScreenGroup(e,t,i){let n=this.getCollapseKey(`screen:${e}`),a=[];if(i.templates.length){let r=this.getCollapseKey(`screen:${e}:templates`);a.push(this.renderCollapsibleGroup({key:r,title:"Templates",count:i.templates.length,content:this.renderEntriesList(i.templates),className:"scene-object-group-sub"}))}if(i.bundles.size||i.systems.length){let r=this.getCollapseKey(`screen:${e}:systems`),l=Array.from(i.bundles.values()).sort((p,u)=>p.label.localeCompare(u.label)).map(p=>this.renderSystemBundle(p.key,p.label,p.objectIds,p.entries)).join(""),c=i.systems.length?this.renderEntriesList(i.systems):"",d=i.systems.length?`<button class="scene-object-group-delete" data-delete-system-group="${e}" type="button" title="Delete all system objects">\u{1F5D1}\uFE0F</button>`:"";a.push(this.renderCollapsibleGroup({key:r,title:"Systems",count:i.bundles.size+i.systems.length,content:`${l}${c}`,className:"scene-object-group-system",actionsHtml:d}))}if(i.objects.length){let r=this.getCollapseKey(`screen:${e}:objects`);a.push(this.renderCollapsibleGroup({key:r,title:"Objects",count:i.objects.length,content:this.renderEntriesList(i.objects),className:"scene-object-group"}))}let s=a.join("");return s?this.renderCollapsibleGroup({key:n,title:t,count:i.templates.length+i.systems.length+i.objects.length+i.bundles.size,content:s,className:"scene-object-group-screen"}):""}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 s,r,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(),(s=this.options)==null||s.onSelect(this.selectedId),(l=(r=this.options)==null?void 0:r.onMultiSelect)==null||l.call(r,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 ji({onRefresh:()=>this.refreshObjects(),onClose:()=>{}}).open(e)}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectMenu:",t)}}async openAddObjectWizard(e){try{new Pi().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 gt({objectId:e,screenId:t,onSelect:s=>{s&&this.select(s)},onRefresh:()=>this.refreshObjects(),onClose:()=>{this.isContextMenuOpen=!1},onDeleteRequest:s=>this.deleteObject(s),onMoveRequest:(s,r)=>this.moveObject(s,r)}).open({x:i,y:n})}catch(a){this.isContextMenuOpen=!1,console.warn("[SceneObjectsPanel] Failed to open context menu:",a)}}}async deleteObject(e){var a;let t=this.getSelectedIds(),i=t.length>1&&t.includes(e),n=this.getActiveScreenForSync();if(i){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,screenId:n,forceSync:!0})}),l=await r.json().catch(()=>null);if(!r.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
688
+ `}renderScreenGroup(e,t,i){let n=this.getCollapseKey(`screen:${e}`),a=[];if(i.templates.length){let o=this.getCollapseKey(`screen:${e}:templates`);a.push(this.renderCollapsibleGroup({key:o,title:"Templates",count:i.templates.length,content:this.renderEntriesList(i.templates),className:"scene-object-group-sub"}))}if(i.bundles.size||i.systems.length){let o=this.getCollapseKey(`screen:${e}:systems`),l=Array.from(i.bundles.values()).sort((p,u)=>p.label.localeCompare(u.label)).map(p=>this.renderSystemBundle(p.key,p.label,p.objectIds,p.entries)).join(""),c=i.systems.length?this.renderEntriesList(i.systems):"",d=i.systems.length?`<button class="scene-object-group-delete" data-delete-system-group="${e}" type="button" title="Delete all system objects">\u{1F5D1}\uFE0F</button>`:"";a.push(this.renderCollapsibleGroup({key:o,title:"Systems",count:i.bundles.size+i.systems.length,content:`${l}${c}`,className:"scene-object-group-system",actionsHtml:d}))}if(i.objects.length){let o=this.getCollapseKey(`screen:${e}:objects`);a.push(this.renderCollapsibleGroup({key:o,title:"Objects",count:i.objects.length,content:this.renderEntriesList(i.objects),className:"scene-object-group"}))}let s=a.join("");return s?this.renderCollapsibleGroup({key:n,title:t,count:i.templates.length+i.systems.length+i.objects.length+i.bundles.size,content:s,className:"scene-object-group-screen"}):""}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 s,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(),(s=this.options)==null||s.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 _i({onRefresh:()=>this.refreshObjects(),onClose:()=>{}}).open(e)}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectMenu:",t)}}async openAddObjectWizard(e){try{new Mi().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 ht({objectId:e,screenId:t,onSelect:s=>{s&&this.select(s)},onRefresh:()=>this.refreshObjects(),onClose:()=>{this.isContextMenuOpen=!1},onDeleteRequest:s=>this.deleteObject(s),onMoveRequest:(s,o)=>this.moveObject(s,o)}).open({x:i,y:n})}catch(a){this.isContextMenuOpen=!1,console.warn("[SceneObjectsPanel] Failed to open context menu:",a)}}}async deleteObject(e){var a;let t=this.getSelectedIds(),i=t.length>1&&t.includes(e),n=this.getActiveScreenForSync();if(i){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 o=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,screenId:n,forceSync:!0})}),l=await o.json().catch(()=>null);if(!o.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
689
689
  `))||(l==null?void 0:l.error)||"Delete failed.";alert(c);return}l!=null&&l.failedDeletions&&l.failedDeletions.length>0&&alert(`Warning: Some files could not be deleted:
690
690
  ${l.failedDeletions.join(`
691
- `)}`),l!=null&&l.deletedFiles&&l.deletedFiles.length>0&&console.log(`[SceneObjectsPanel] Successfully deleted files: ${l.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 s;let t=0,i=0,n=[],a=this.getActiveScreenForSync();for(let r of e)try{let l=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:r,skipSync:!0,screenId:a,forceSync:!0})}),c=await l.json().catch(()=>null);if(l.ok&&(c==null?void 0:c.success)!==!1)t++,this.selectedIds.delete(r);else{i++;let d=((s=c==null?void 0:c.errors)==null?void 0:s.join(`
692
- `))||(c==null?void 0:c.error)||"Delete failed.";n.push(`${r}: ${d}`)}}catch(l){i++,n.push(`${r}: ${l instanceof Error?l.message:String(l)}`)}if(i>0){let r=n.length>0?n.join(`
691
+ `)}`),l!=null&&l.deletedFiles&&l.deletedFiles.length>0&&console.log(`[SceneObjectsPanel] Successfully deleted files: ${l.deletedFiles.join(", ")}`),await this.syncScreens(),this.selectedIds.delete(e),this.selectedId===e&&(this.selectedId=null),this.refreshObjects()}catch(o){alert(`Delete failed: ${o instanceof Error?o.message:String(o)}`)}}}async deleteMultipleObjects(e){var s;let t=0,i=0,n=[],a=this.getActiveScreenForSync();for(let o of e)try{let l=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:o,skipSync:!0,screenId:a,forceSync:!0})}),c=await l.json().catch(()=>null);if(l.ok&&(c==null?void 0:c.success)!==!1)t++,this.selectedIds.delete(o);else{i++;let d=((s=c==null?void 0:c.errors)==null?void 0:s.join(`
692
+ `))||(c==null?void 0:c.error)||"Delete failed.";n.push(`${o}: ${d}`)}}catch(l){i++,n.push(`${o}: ${l instanceof Error?l.message:String(l)}`)}if(i>0){let o=n.length>0?n.join(`
693
693
  `):`${i} object(s) failed to delete.`;alert(`Deleted ${t} object(s). Errors:
694
- ${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 c;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(d=>d.id),a=0,s=0,r=[],l=this.getActiveScreenForSync();for(let d of n)try{let p=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:d,screenId:l,forceSync:!0})}),u=await p.json().catch(()=>null);if(p.ok&&(u==null?void 0:u.success)!==!1)a++;else{s++;let g=((c=u==null?void 0:u.errors)==null?void 0:c.join(`
695
- `))||(u==null?void 0:u.error)||"Delete failed.";r.push(`${d}: ${g}`)}}catch(p){s++,r.push(`${d}: ${p instanceof Error?p.message:String(p)}`)}if(s>0){let d=r.length>0?r.join(`
694
+ ${o}`)}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 c;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(d=>d.id),a=0,s=0,o=[],l=this.getActiveScreenForSync();for(let d of n)try{let p=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:d,screenId:l,forceSync:!0})}),u=await p.json().catch(()=>null);if(p.ok&&(u==null?void 0:u.success)!==!1)a++;else{s++;let g=((c=u==null?void 0:u.errors)==null?void 0:c.join(`
695
+ `))||(u==null?void 0:u.error)||"Delete failed.";o.push(`${d}: ${g}`)}}catch(p){s++,o.push(`${d}: ${p instanceof Error?p.message:String(p)}`)}if(s>0){let d=o.length>0?o.join(`
696
696
  `):`${s} object(s) failed to delete.`;alert(`Deleted ${a} object(s). Errors:
697
- ${d}`)}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 s=this.inferScreen(e,null);if(t===s)return;try{let r=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,fromScreenId:s,toScreenId:t})}),l=await r.json().catch(()=>({}));if(!r.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
698
- `))||(l==null?void 0:l.error)||"Move failed.";alert(c);return}this.refreshObjects()}catch(r){alert(`Move failed: ${r instanceof Error?r.message:String(r)}`)}}}async moveMultipleObjects(e,t){var s;let i=0,n=0,a=[];for(let r of e){let l=this.inferScreen(r,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:r,fromScreenId:l,toScreenId:t})}),d=await c.json().catch(()=>({}));if(c.ok&&(d==null?void 0:d.success)!==!1)i++;else{n++;let p=((s=d==null?void 0:d.errors)==null?void 0:s.join(`
699
- `))||(d==null?void 0:d.error)||"Move failed.";a.push(`${r}: ${p}`)}}catch(c){n++,a.push(`${r}: ${c instanceof Error?c.message:String(c)}`)}}if(n>0){let r=a.length>0?a.join(`
697
+ ${d}`)}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 s=this.inferScreen(e,null);if(t===s)return;try{let o=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,fromScreenId:s,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(`
698
+ `))||(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 s;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=((s=d==null?void 0:d.errors)==null?void 0:s.join(`
699
+ `))||(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(`
700
700
  `):`${n} object(s) failed to move.`;alert(`Moved ${i} object(s). Errors:
701
- ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenForSync();await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[SceneObjectsPanel] Failed to sync screens:",e)}}getActiveScreenForSync(){let e=window.__HANDLER_ACTIVE_SCREEN;return e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:this.screenFilter!=="all"?this.screenFilter:"gameplay"}};var Oi=class{constructor(){this.root=null;this.options=null;this.isCollapsed=!1}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}render(){return`
701
+ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenForSync();await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[SceneObjectsPanel] Failed to sync screens:",e)}}getActiveScreenForSync(){let e=window.__HANDLER_ACTIVE_SCREEN;return e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:this.screenFilter!=="all"?this.screenFilter:"gameplay"}};var Ri=class{constructor(){this.root=null;this.options=null;this.isCollapsed=!1}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}render(){return`
702
702
  <div class="scene-tools-corner-panel ${this.isCollapsed?"collapsed":""}" data-panel="scene-tools-corner">
703
703
  <div class="scene-tools-header" data-tools-header data-panel-handle>
704
704
  <span class="scene-tools-title">Scene Tools</span>
@@ -781,7 +781,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
781
781
  </div>
782
782
  </div>
783
783
  </div>
784
- `}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,L)=>{var E;let x=(E=this.root)==null?void 0:E.querySelector(`[data-status="${C}"]`);x&&x.classList.toggle("active",L)},s=this.root.querySelector("#debug-highlight-object");s==null||s.addEventListener("change",()=>{var C;(C=this.options)==null||C.onHighlightObject(!!s.checked),a("bounds",s.checked)});let r=this.root.querySelector("#debug-highlight-anchor");r==null||r.addEventListener("change",()=>{var C;(C=this.options)==null||C.onHighlightAnchor(!!r.checked),a("anchor",r.checked),window.dispatchEvent(new CustomEvent("scene-editor:highlight-anchor",{detail:{enabled:r.checked}}));try{localStorage.setItem(this.getSceneStorageKey("highlight_anchor"),r.checked?"true":"false")}catch{}});let l=this.root.querySelector("#debug-nudge-enabled");l==null||l.addEventListener("change",()=>{a("nudge",l.checked)});let c=this.root.querySelector("#scene-grid-enabled"),d=this.root.querySelector("#scene-grid-gap"),p=this.root.querySelector("#scene-grid-alpha"),u=this.root.querySelector("#scene-grid-alpha-value"),g=this.root.querySelector("#scene-play-mode"),h=this.root.querySelector("#scene-background-cover"),f=this.root.querySelector("#scene-background-lock"),m=this.root.querySelector("[data-grid-toggle-btn]"),b=this.root.querySelector("[data-play-toggle-btn]"),y=()=>{if(!p)return .25;let C=Number(p.value),L=Number.isFinite(C)?Math.min(1,Math.max(0,C)):.25;return p.value=String(L),u&&(u.textContent=`${Math.round(L*100)}%`),L},v=(C,L,x)=>{var S,O;let E=x!==void 0?x:y();(O=(S=this.options)==null?void 0:S.onGridToggle)==null||O.call(S,C,L,E),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:C,gap:L,alpha:E}}))},w=C=>{var x,E;let L=y();(E=(x=this.options)==null?void 0:x.onGridGapChange)==null||E.call(x,C),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:!!(c!=null&&c.checked),gap:C,alpha:L}}))},I=C=>{var L,x;(x=(L=this.options)==null?void 0:L.onGridAlphaChange)==null||x.call(L,C),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:!!(c!=null&&c.checked),gap:M(),alpha:C}}))},P=C=>{var L,x;(x=(L=this.options)==null?void 0:L.onPlayModeChange)==null||x.call(L,C),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:C}}))},_=C=>{var L,x;(x=(L=this.options)==null?void 0:L.onBackgroundCoverChange)==null||x.call(L,C),window.dispatchEvent(new CustomEvent("scene-editor:background-cover",{detail:{enabled:C}}))},T=C=>{var L,x;(x=(L=this.options)==null?void 0:L.onBackgroundLockChange)==null||x.call(L,C),window.dispatchEvent(new CustomEvent("scene-editor:background-lock",{detail:{enabled:C}}))},M=()=>{if(!d)return 50;let C=Number(d.value),L=Number.isFinite(C)?Math.min(200,Math.max(4,C)):50;return d.value=String(L),L},k=C=>{c&&(c.checked=C),d&&(d.disabled=!C),p&&(p.disabled=!C),m==null||m.classList.toggle("active",C)},A=C=>{g&&(g.checked=C),b==null||b.classList.toggle("active",C)};try{let C=localStorage.getItem(this.getSceneStorageKey("grid_enabled")),L=localStorage.getItem(this.getSceneStorageKey("grid_gap")),x=localStorage.getItem(this.getSceneStorageKey("grid_alpha")),E=localStorage.getItem(this.getSceneStorageKey("highlight_anchor")),S=localStorage.getItem(this.getSceneStorageKey("background_cover")),O=localStorage.getItem(this.getSceneStorageKey("background_lock")),j=C?C==="true":!1;k(j),d&&(d.value=L||"50",d.disabled=!j),p&&(p.value=x||"0.25",p.disabled=!j,y()),r&&(r.checked=E==="true",a("anchor",r.checked));let R=!0;A(R),g&&(g.disabled=!0),b&&(b.disabled=!0);try{localStorage.setItem(this.getSceneStorageKey("play_mode"),R?"true":"false")}catch{}v(j,M(),y()),P(R);let z=S?S==="true":!0,D=O?O==="true":!0;h&&(h.checked=z),f&&(f.checked=D),_(z),T(D),r&&window.dispatchEvent(new CustomEvent("scene-editor:highlight-anchor",{detail:{enabled:r.checked}}))}catch{}c==null||c.addEventListener("change",()=>{let C=M(),L=y();d&&(d.disabled=!c.checked),p&&(p.disabled=!c.checked),m==null||m.classList.toggle("active",c.checked);try{localStorage.setItem(this.getSceneStorageKey("grid_enabled"),c.checked?"true":"false"),localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(C)),localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(L))}catch{}v(c.checked,C,L)}),d==null||d.addEventListener("input",()=>{let C=M(),L=y();try{localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(C)),localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(L))}catch{}w(C)}),p==null||p.addEventListener("input",()=>{let C=y(),L=M();try{localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(C)),localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(L))}catch{}I(C)}),g==null||g.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("play_mode"),g.checked?"true":"false")}catch{}b==null||b.classList.toggle("active",g.checked),P(g.checked)}),h==null||h.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("background_cover"),h.checked?"true":"false")}catch{}_(h.checked)}),f==null||f.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("background_lock"),f.checked?"true":"false")}catch{}T(f.checked)}),m==null||m.addEventListener("click",()=>{c&&(c.checked=!c.checked,c.dispatchEvent(new Event("change")))}),b==null||b.addEventListener("click",()=>{g&&(g.checked=!g.checked,g.dispatchEvent(new Event("change")))})}updateInfo(e){}};var Ri=class{constructor(){this.root=null;this.options=null}render(){return`
784
+ `}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 S;this.isCollapsed=!this.isCollapsed,(S=this.root)==null||S.classList.toggle("collapsed",this.isCollapsed),localStorage.setItem("scene-tools-collapsed",String(this.isCollapsed))});let a=(S,E)=>{var A;let C=(A=this.root)==null?void 0:A.querySelector(`[data-status="${S}"]`);C&&C.classList.toggle("active",E)},s=this.root.querySelector("#debug-highlight-object");s==null||s.addEventListener("change",()=>{var S;(S=this.options)==null||S.onHighlightObject(!!s.checked),a("bounds",s.checked)});let o=this.root.querySelector("#debug-highlight-anchor");o==null||o.addEventListener("change",()=>{var S;(S=this.options)==null||S.onHighlightAnchor(!!o.checked),a("anchor",o.checked),window.dispatchEvent(new CustomEvent("scene-editor:highlight-anchor",{detail:{enabled:o.checked}}));try{localStorage.setItem(this.getSceneStorageKey("highlight_anchor"),o.checked?"true":"false")}catch{}});let l=this.root.querySelector("#debug-nudge-enabled");l==null||l.addEventListener("change",()=>{a("nudge",l.checked)});let c=this.root.querySelector("#scene-grid-enabled"),d=this.root.querySelector("#scene-grid-gap"),p=this.root.querySelector("#scene-grid-alpha"),u=this.root.querySelector("#scene-grid-alpha-value"),g=this.root.querySelector("#scene-play-mode"),h=this.root.querySelector("#scene-background-cover"),f=this.root.querySelector("#scene-background-lock"),m=this.root.querySelector("[data-grid-toggle-btn]"),b=this.root.querySelector("[data-play-toggle-btn]"),y=()=>{if(!p)return .25;let S=Number(p.value),E=Number.isFinite(S)?Math.min(1,Math.max(0,S)):.25;return p.value=String(E),u&&(u.textContent=`${Math.round(E*100)}%`),E},w=(S,E,C)=>{var T,O;let A=C!==void 0?C:y();(O=(T=this.options)==null?void 0:T.onGridToggle)==null||O.call(T,S,E,A),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:S,gap:E,alpha:A}}))},v=S=>{var C,A;let E=y();(A=(C=this.options)==null?void 0:C.onGridGapChange)==null||A.call(C,S),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:!!(c!=null&&c.checked),gap:S,alpha:E}}))},P=S=>{var E,C;(C=(E=this.options)==null?void 0:E.onGridAlphaChange)==null||C.call(E,S),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:!!(c!=null&&c.checked),gap:j(),alpha:S}}))},I=S=>{var E,C;(C=(E=this.options)==null?void 0:E.onPlayModeChange)==null||C.call(E,S),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:S}}))},_=S=>{var E,C;(C=(E=this.options)==null?void 0:E.onBackgroundCoverChange)==null||C.call(E,S),window.dispatchEvent(new CustomEvent("scene-editor:background-cover",{detail:{enabled:S}}))},k=S=>{var E,C;(C=(E=this.options)==null?void 0:E.onBackgroundLockChange)==null||C.call(E,S),window.dispatchEvent(new CustomEvent("scene-editor:background-lock",{detail:{enabled:S}}))},j=()=>{if(!d)return 50;let S=Number(d.value),E=Number.isFinite(S)?Math.min(200,Math.max(4,S)):50;return d.value=String(E),E},L=S=>{c&&(c.checked=S),d&&(d.disabled=!S),p&&(p.disabled=!S),m==null||m.classList.toggle("active",S)},x=S=>{g&&(g.checked=S),b==null||b.classList.toggle("active",S)};try{let S=localStorage.getItem(this.getSceneStorageKey("grid_enabled")),E=localStorage.getItem(this.getSceneStorageKey("grid_gap")),C=localStorage.getItem(this.getSceneStorageKey("grid_alpha")),A=localStorage.getItem(this.getSceneStorageKey("highlight_anchor")),T=localStorage.getItem(this.getSceneStorageKey("background_cover")),O=localStorage.getItem(this.getSceneStorageKey("background_lock")),M=S?S==="true":!1;L(M),d&&(d.value=E||"50",d.disabled=!M),p&&(p.value=C||"0.25",p.disabled=!M,y()),o&&(o.checked=A==="true",a("anchor",o.checked));let R=!0;x(R),g&&(g.disabled=!0),b&&(b.disabled=!0);try{localStorage.setItem(this.getSceneStorageKey("play_mode"),R?"true":"false")}catch{}w(M,j(),y()),I(R);let z=T?T==="true":!0,F=O?O==="true":!0;h&&(h.checked=z),f&&(f.checked=F),_(z),k(F),o&&window.dispatchEvent(new CustomEvent("scene-editor:highlight-anchor",{detail:{enabled:o.checked}}))}catch{}c==null||c.addEventListener("change",()=>{let S=j(),E=y();d&&(d.disabled=!c.checked),p&&(p.disabled=!c.checked),m==null||m.classList.toggle("active",c.checked);try{localStorage.setItem(this.getSceneStorageKey("grid_enabled"),c.checked?"true":"false"),localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(S)),localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(E))}catch{}w(c.checked,S,E)}),d==null||d.addEventListener("input",()=>{let S=j(),E=y();try{localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(S)),localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(E))}catch{}v(S)}),p==null||p.addEventListener("input",()=>{let S=y(),E=j();try{localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(S)),localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(E))}catch{}P(S)}),g==null||g.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("play_mode"),g.checked?"true":"false")}catch{}b==null||b.classList.toggle("active",g.checked),I(g.checked)}),h==null||h.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("background_cover"),h.checked?"true":"false")}catch{}_(h.checked)}),f==null||f.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("background_lock"),f.checked?"true":"false")}catch{}k(f.checked)}),m==null||m.addEventListener("click",()=>{c&&(c.checked=!c.checked,c.dispatchEvent(new Event("change")))}),b==null||b.addEventListener("click",()=>{g&&(g.checked=!g.checked,g.dispatchEvent(new Event("change")))})}updateInfo(e){}};var zi=class{constructor(){this.root=null;this.options=null}render(){return`
785
785
  <div class="nudge-panel hidden" data-panel="nudge-panel">
786
786
  <div class="nudge-panel-header" data-panel-handle>
787
787
  <span class="nudge-panel-title">Nudge Controls</span>
@@ -838,7 +838,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
838
838
  </div>
839
839
  </div>
840
840
  </div>
841
- `}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 s=a.dataset.nudge,r=this.getNudgeStep();switch(s){case"up":(l=this.options)==null||l.onNudge(0,-r);break;case"down":(c=this.options)==null||c.onNudge(0,r);break;case"left":(d=this.options)==null||d.onNudge(-r,0);break;case"right":(p=this.options)==null||p.onNudge(r,0);break}})}),Array.from(this.root.querySelectorAll(".nudge-scale-btn")).forEach(a=>{a.addEventListener("click",()=>{var l;let r=a.dataset.scale==="up"?.1:-.1;(l=this.options)==null||l.onScale(r)})})}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 Bt=class{constructor(){this.root=null;this.slotsContainer=null;this.assetsContainer=null;this.assetSearchInput=null;this.slotSearchInput=null;this.options=null;this.registry=null;this.selectedSlotId=null;this.cachedAssets={};this.pendingAssetFetches={};this.cacheBust=0;this.missingPreviewPaths=new Set;this.slotSearchDebounce=null;this.assetSearchDebounce=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]:[]},s=Array.isArray(i.slots)?i.slots:[];if(s.length>0&&a.slots.length>0)for(let c of a.slots){let d=s.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 r=i.libraryAssets||{};for(let[c,d]of Object.entries(r)){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`
841
+ `}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 s=a.dataset.nudge,o=this.getNudgeStep();switch(s){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 Gt=class{constructor(){this.root=null;this.slotsContainer=null;this.assetsContainer=null;this.assetSearchInput=null;this.slotSearchInput=null;this.options=null;this.registry=null;this.selectedSlotId=null;this.cachedAssets={};this.pendingAssetFetches={};this.cacheBust=0;this.missingPreviewPaths=new Set;this.slotSearchDebounce=null;this.assetSearchDebounce=null;this.isApplying=!1}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]:[]},s=Array.isArray(i.slots)?i.slots:[];if(s.length>0&&a.slots.length>0)for(let c of a.slots){let d=s.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`
842
842
  <div class="scene-panel library-panel panel-accent-purple" data-panel="library">
843
843
  <div class="scene-panel-header" data-panel-handle>
844
844
  <div class="panel-title">
@@ -866,7 +866,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
866
866
  </div>
867
867
  <div class="panel-resize-handle" data-panel-resize></div>
868
868
  </div>
869
- `}initialize(e,t){var a,s,r,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(a=this.root)==null?void 0:a.querySelector("[data-library-slots]"),this.assetsContainer=(s=this.root)==null?void 0:s.querySelector("[data-library-assets]"),this.assetSearchInput=(r=this.root)==null?void 0:r.querySelector("[data-library-asset-search]"),this.slotSearchInput=(l=this.root)==null?void 0:l.querySelector("[data-library-slot-search]");let i=(c=this.root)==null?void 0:c.querySelector("[data-create-ai]");i==null||i.addEventListener("click",()=>{this.handleCreateWithAI()});let n=(d=this.root)==null?void 0:d.querySelector("[data-refresh-library]");n==null||n.addEventListener("click",()=>{n.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>n.classList.remove("pulse-anim"),500)}),(p=this.assetSearchInput)==null||p.addEventListener("input",()=>this.scheduleRenderAssets()),(u=this.slotSearchInput)==null||u.addEventListener("input",()=>this.scheduleRenderSlots()),window.addEventListener("preview:select",g=>{var f;let h=(f=g.detail)==null?void 0:f.objectId;h&&this.highlightCurrentObject(h)}),this.loadAssetRegistry()}highlightCurrentObject(e){if(!this.registry)return;let t=this.registry.slots.find(i=>i.objectId===e);t&&(this.selectedSlotId=t.slotId,this.scheduleRenderSlots(),setTimeout(()=>{var n;let i=(n=this.slotsContainer)==null?void 0:n.querySelector(`[data-slot-id="${t.slotId}"]`);i&&i.scrollIntoView({behavior:"smooth",block:"center"})},100))}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()}resetSearch(){this.assetSearchInput&&(this.assetSearchInput.value=""),this.slotSearchInput&&(this.slotSearchInput.value=""),this.scheduleRenderAssets(),this.scheduleRenderSlots()}loadAssetRegistry(e=0){var i,n,a,s;let t=window.getEditableAssets;if(typeof t=="function"){let r=t();if(r!=null&&r.slots&&Array.isArray(r.slots)&&r.slots.length>0){if(this.registry=r,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.cacheBust=Date.now(),this.cachedAssets={},this.pendingAssetFetches={},this.missingPreviewPaths.clear(),!(this.selectedSlotId&&this.registry.slots.some(c=>c.slotId===this.selectedSlotId))){let c=window.__getSelectedObjectId,d=typeof c=="function"?c():null;if(d){let p=this.registry.slots.find(u=>u.objectId===d);p?this.selectedSlotId=p.slotId:this.selectedSlotId=(n=(i=this.registry.slots[0])==null?void 0:i.slotId)!=null?n:null}else this.selectedSlotId=(s=(a=this.registry.slots[0])==null?void 0:a.slotId)!=null?s:null}this.renderSlots(),this.renderAssets();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(){var n;if(!this.slotsContainer||!this.registry)return;let e={};for(let a of this.registry.slots)e[a.category]||(e[a.category]=[]),e[a.category].push(a);let t=this.cacheBust||Date.now(),i=(((n=this.slotSearchInput)==null?void 0:n.value)||"").trim().toLowerCase();this.slotsContainer.innerHTML="";for(let a of this.getCategories()){let s=(e[a]||[]).filter(d=>i?`${d.displayName} ${d.slotId} ${d.objectId} ${d.currentAsset}`.toLowerCase().includes(i):!0);if(s.length===0)continue;let r=document.createElement("div");r.className="library-category";let l=document.createElement("div");l.className="library-category-header",l.textContent=this.formatCategoryName(a),r.appendChild(l);let c=document.createElement("div");c.className="library-category-slots";for(let d of s){let p=this.createSlotElement(d,t);c.appendChild(p)}r.appendChild(c),this.slotsContainer.appendChild(r)}if(!this.slotsContainer.hasChildNodes()){let a=document.createElement("div");a.className="library-info",a.textContent=i?"No slots match your search":"No editable slots available",this.slotsContainer.appendChild(a)}}createSlotElement(e,t){var y,v;let i=this.selectedSlotId===e.slotId,n=window.__getSelectedObjectId,s=(typeof n=="function"?n():null)===e.objectId,r=document.createElement("div");r.className=`library-slot ${i?"expanded":""} ${s?"current-object":""}`,r.dataset.slotId=e.slotId,r.dataset.objectId=e.objectId;let l=document.createElement("div");l.className="slot-header";let c=document.createElement("div");if(c.className="slot-current",(y=e.currentAsset)==null?void 0:y.toLowerCase().endsWith(".json")){let w=document.createElement("div");w.className="slot-thumbnail slot-thumbnail-json",w.textContent="\u{1F3AC}",w.title="Lottie/JSON Animation",c.appendChild(w)}else{let w=document.createElement("img"),I=this.resolveSlotPreviewPaths(e),P=I.primary,_=(v=I.fallback)!=null?v:null;if(!P)w.style.display="none";else if(this.missingPreviewPaths.has(P.key)&&(!_||this.missingPreviewPaths.has(_.key)))w.style.display="none";else{w.src=P.src(t),w.alt=e.displayName,w.className="slot-thumbnail",w.loading="lazy";let T=!1;w.onerror=()=>{if(T){w.onerror=null,w.style.display="none";return}if(this.missingPreviewPaths.add(P.key),_&&!this.missingPreviewPaths.has(_.key)){T=!0,w.src=_.src(t);return}_&&this.missingPreviewPaths.add(_.key),w.style.display="none"}}c.appendChild(w)}l.appendChild(c);let p=document.createElement("div");p.className="slot-info";let u=document.createElement("div");u.className="slot-name",u.textContent=e.displayName;let g=document.createElement("div");g.className="slot-asset",g.textContent=e.currentAsset,p.appendChild(u),p.appendChild(g),l.appendChild(p);let h=document.createElement("div");h.className="slot-actions";let f=document.createElement("button");f.className="slot-ai-edit",f.title="Edit with AI",f.textContent="\u2728 AI",f.addEventListener("click",async w=>{w.stopPropagation(),await this.handleAIEdit(e)}),h.appendChild(f);let m=document.createElement("button");m.className="slot-upload",m.title="Upload new asset",m.textContent="\u{1F4E4}",m.addEventListener("click",async w=>{w.stopPropagation(),await this.handleUpload(e)}),h.appendChild(m);let b=document.createElement("button");return b.className="slot-reset",b.title="Reset to default",b.textContent="\u21BA",b.addEventListener("click",async w=>{w.stopPropagation(),await this.handleReset(e)}),h.appendChild(b),l.appendChild(h),l.addEventListener("click",()=>{this.selectedSlotId=e.slotId,this.renderSlots(),this.renderAssets()}),r.appendChild(l),r}renderAssets(){var l;if(!this.assetsContainer||!this.registry)return;let e=this.cacheBust||Date.now(),t=(((l=this.assetSearchInput)==null?void 0:l.value)||"").trim().toLowerCase(),i=this.getSelectedSlot();this.assetsContainer.innerHTML="";let n=document.createElement("div");n.className="library-selected",n.textContent=i?`Selected slot: ${i.displayName} (${i.currentAsset||"no asset"})`:"Select a slot to apply assets",n.style.gridColumn="1 / -1",this.assetsContainer.appendChild(n);let a=this.getCategories(),s=!1,r=!1;for(let c of a){let d=this.getCategoryAssets(c,e);if(!d){let f=document.createElement("div");f.className="library-empty",f.textContent=`Loading ${this.formatCategoryName(c)} assets...`,this.assetsContainer.appendChild(f),r=!0;continue}let p=d.filter(f=>t?`${f.displayName} ${f.filename} ${c}`.toLowerCase().includes(t):!0);if(p.length===0)continue;let u=document.createElement("div");u.className="library-category";let g=document.createElement("div");g.className="library-category-header",g.textContent=this.formatCategoryName(c),u.appendChild(g);let h=document.createElement("div");h.className="slot-library",h.style.borderTop="none",h.style.padding="10px";for(let f of p){let m=document.createElement("div");m.className="library-item",i&&i.currentAsset===f.filename&&i.libraryFolder===c&&m.classList.add("selected");let b=document.createElement("img"),y=this.resolveLibraryAssetPath(c,f.filename);this.missingPreviewPaths.has(y.key)?b.style.display="none":b.src=y.src(e),b.alt=f.displayName,b.className="library-thumbnail",b.loading="lazy",b.onerror=()=>{this.missingPreviewPaths.add(y.key),b.style.opacity="0.3"},m.appendChild(b);let v=document.createElement("div");v.className="library-label",v.textContent=f.displayName,m.appendChild(v),m.addEventListener("click",async()=>{if(!i){alert("Select a slot first to apply an asset.");return}await this.handleApply(i,f.filename,c)}),h.appendChild(m),s=!0}u.appendChild(h),this.assetsContainer.appendChild(u)}if(!s&&!r){let c=document.createElement("div");c.className="library-empty",c.textContent=t?"No assets match your search":"No assets available",this.assetsContainer.appendChild(c)}}getCategoryAssets(e,t){var i;if(this.cachedAssets[e])return this.cachedAssets[e];if(!this.pendingAssetFetches[e]){let n=((i=this.registry)==null?void 0:i.libraryAssets[e])||[];this.pendingAssetFetches[e]=this.fetchFolderAssets(e,t).then(a=>{let s=new Map;for(let r of n)s.set(r.filename,r);for(let r of a)s.has(r.filename)||s.set(r.filename,r);return this.cachedAssets[e]=Array.from(s.values()),delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]}).catch(()=>(this.cachedAssets[e]=n,delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]))}return null}async fetchFolderAssets(e,t){try{let i=await fetch(`/raw/library/${e}/?t=${t}`);if(!i.ok)return[];let n=await i.text(),a=[],s=/href="([^"]+\.(png|jpg|jpeg))"/gi,r;for(;(r=s.exec(n))!==null;){let l=r[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,i){var n;console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{let a=window.__wizardAssetPicker;if(a!=null&&a.onPick){let l=`raw/library/${i||e.libraryFolder||e.category}/${t}`;a.onPick(l),window.__wizardAssetPicker=null;return}let s=i||e.libraryFolder||e.category;await((n=this.options)==null?void 0:n.onApply(e.objectId,t,s)),e.currentAsset=t,e.libraryFolder=s,this.renderSlots(),this.renderAssets()}catch(a){console.error("[LIBRARY] Failed to apply asset:",a)}}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(),this.renderAssets()}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(" ")}getCategories(){if(!this.registry)return[];let e=new Set;if(Array.isArray(this.registry.categories))for(let t of this.registry.categories)t&&e.add(t);for(let t of Object.keys(this.registry.libraryAssets||{}))t&&e.add(t);for(let t of this.registry.slots||[])t!=null&&t.category&&e.add(t.category);return Array.from(e)}getSelectedSlot(){return!this.registry||!this.selectedSlotId?null:this.registry.slots.find(e=>e.slotId===this.selectedSlotId)||null}scheduleRenderSlots(){this.slotSearchDebounce&&window.clearTimeout(this.slotSearchDebounce),this.slotSearchDebounce=window.setTimeout(()=>{this.slotSearchDebounce=null,this.renderSlots()},150)}scheduleRenderAssets(){this.assetSearchDebounce&&window.clearTimeout(this.assetSearchDebounce),this.assetSearchDebounce=window.setTimeout(()=>{this.assetSearchDebounce=null,this.renderAssets()},150)}resolveSlotPreviewPaths(e){let t=(e.currentAsset||"").trim();if(!t)return{primary:null,fallback:null};let i=t.replace(/^\/+/,""),n=null,a=null;return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:e.libraryFolder?(n=`raw/library/${e.libraryFolder}/${i}`,a=`raw/${i}`):n=`raw/${i}`,{primary:n?{key:n,src:l=>`/${n}?t=${l}`}:null,fallback:a?{key:a,src:l=>`/${a}?t=${l}`}:null}}resolveLibraryAssetPath(e,t){let i=t.replace(/^\/+/,""),n="";return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:n=`raw/library/${e}/${i}`,{key:n,src:a=>`/${n}?t=${a}`}}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,a,s,r,l;let i=(n=t.files)==null?void 0:n[0];if(i){console.log("[Library] File selected:",i.name);try{let c=await this.fileToDataUrl(i);if(!c){alert("Failed to read file");return}let d=e.displayName.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),p=((a=i.name.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/))==null?void 0:a[1])||"png",u=p==="jpg"?"jpeg":p,g=`${d}_uploaded_${Date.now()}.${u}`,h=e.category;console.log("[Library] Saving uploaded file:",g,"to category:",h);let m=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:h,filename:g,data:c,overwrite:!0})})).json();if(m.success){console.log("[Library] \u2705 Upload saved:",m.path),await new Promise(M=>setTimeout(M,100));let b=window.addAssetToRegistry;typeof b=="function"&&(b(h,g),console.log("[Library] \u2705 Added to registry:",h,g));let y=window.getEditableAssets;if(typeof y=="function"){let M=y();M&&!M.categories&&(M.categories=[]),M!=null&&M.categories&&!M.categories.includes(h)&&(M.categories.push(h),console.log(`[Library] Added category ${h} to registry`))}let v=!1,w=0,I=10;for(;!v&&w<I;){w++,console.log(`[Library] Refresh attempt ${w}/${I}...`);try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&console.log("[Library] \u2705 Registry rebuilt from disk")}catch(A){console.warn("[Library] Setup-library not available:",A)}await new Promise(A=>setTimeout(A,300)),await this.refresh();let M=window.reRenderAssetLibrary;typeof M=="function"&&(console.log("[Library] Re-rendering library panel..."),M());let k=window.getEditableAssets;if(typeof k=="function"){let A=k(),C=((s=A==null?void 0:A.libraryAssets)==null?void 0:s[h])||[];C.some(x=>(x==null?void 0:x.filename)===g)?(console.log("[Library] \u2705 Asset found in registry!"),v=!0):(console.log(`[Library] Asset not found yet, retrying... (found ${C.length} assets in ${h})`),await new Promise(x=>setTimeout(x,500)))}else w>=2&&(v=!0)}v||console.warn("[Library] \u26A0\uFE0F Asset not found in registry after retries, proceeding anyway...");let P=!1,_=0,T=5;for(;!P&&_<T;){_++;try{console.log(`[Library] Applying asset attempt ${_}/${T}...`),await this.handleApply(e,g,e.category),await new Promise(k=>setTimeout(k,200));let M=window.getEditableObjectConfig;if(typeof M=="function"){let k=M(e.objectId),A=((l=(r=k==null?void 0:k.render)==null?void 0:r.asset)==null?void 0:l.path)||"";A===m.path||A.includes(g)?(console.log("[Library] \u2705 Asset confirmed applied to object"),P=!0):(console.log(`[Library] Asset not applied yet (attempt ${_}), retrying...`),await new Promise(C=>setTimeout(C,300)))}else P=!0}catch(M){console.error(`[Library] Apply attempt ${_} failed:`,M),_<T&&await new Promise(k=>setTimeout(k,500))}}e.currentAsset=g,await this.refresh(),setTimeout(()=>{try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[Library] Dispatched config:changed event")}catch(M){console.warn("[Library] Failed to refresh textures:",M)}},300),setTimeout(()=>{this.highlightSlot(e.objectId,h)},1e3),P?console.log("[Library] \u2705 Upload complete and applied!"):console.warn("[Library] \u26A0\uFE0F Upload succeeded but apply may have failed")}else console.error("[Library] \u274C Upload failed:",m.error),alert(`Upload failed: ${m.error}`)}catch(c){console.error("[Library] \u274C Upload error:",c),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.selectedSlotId=n.slotId,this.renderSlots(),this.renderAssets(),setTimeout(()=>{var s;let a=(s=this.slotsContainer)==null?void 0:s.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 zi=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 $i=class{render(e,t,i,n){let a=this.formatLabel(t),s=i?this.getThumbnailUrl(i):"";return`
869
+ `}initialize(e,t){var a,s,o,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(a=this.root)==null?void 0:a.querySelector("[data-library-slots]"),this.assetsContainer=(s=this.root)==null?void 0:s.querySelector("[data-library-assets]"),this.assetSearchInput=(o=this.root)==null?void 0:o.querySelector("[data-library-asset-search]"),this.slotSearchInput=(l=this.root)==null?void 0:l.querySelector("[data-library-slot-search]");let i=(c=this.root)==null?void 0:c.querySelector("[data-create-ai]");i==null||i.addEventListener("click",()=>{this.handleCreateWithAI()});let n=(d=this.root)==null?void 0:d.querySelector("[data-refresh-library]");n==null||n.addEventListener("click",()=>{n.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>n.classList.remove("pulse-anim"),500)}),(p=this.assetSearchInput)==null||p.addEventListener("input",()=>this.scheduleRenderAssets()),(u=this.slotSearchInput)==null||u.addEventListener("input",()=>this.scheduleRenderSlots()),window.addEventListener("preview:select",g=>{var f;let h=(f=g.detail)==null?void 0:f.objectId;h&&this.highlightCurrentObject(h)}),this.loadAssetRegistry()}highlightCurrentObject(e){if(!this.registry)return;let t=this.registry.slots.find(i=>i.objectId===e);t&&(this.selectedSlotId=t.slotId,this.scheduleRenderSlots(),setTimeout(()=>{var n;let i=(n=this.slotsContainer)==null?void 0:n.querySelector(`[data-slot-id="${t.slotId}"]`);i&&i.scrollIntoView({behavior:"smooth",block:"center"})},100))}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()}resetSearch(){this.assetSearchInput&&(this.assetSearchInput.value=""),this.slotSearchInput&&(this.slotSearchInput.value=""),this.scheduleRenderAssets(),this.scheduleRenderSlots()}loadAssetRegistry(e=0){var i,n,a,s;let t=window.getEditableAssets;if(typeof t=="function"){let o=t();if(o!=null&&o.slots&&Array.isArray(o.slots)&&o.slots.length>0){if(this.registry=o,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.cacheBust=Date.now(),this.cachedAssets={},this.pendingAssetFetches={},this.missingPreviewPaths.clear(),!(this.selectedSlotId&&this.registry.slots.some(c=>c.slotId===this.selectedSlotId))){let c=window.__getSelectedObjectId,d=typeof c=="function"?c():null;if(d){let p=this.registry.slots.find(u=>u.objectId===d);p?this.selectedSlotId=p.slotId:this.selectedSlotId=(n=(i=this.registry.slots[0])==null?void 0:i.slotId)!=null?n:null}else this.selectedSlotId=(s=(a=this.registry.slots[0])==null?void 0:a.slotId)!=null?s:null}this.renderSlots(),this.renderAssets();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(){var n;if(!this.slotsContainer||!this.registry)return;let e={};for(let a of this.registry.slots)e[a.category]||(e[a.category]=[]),e[a.category].push(a);let t=this.cacheBust||Date.now(),i=(((n=this.slotSearchInput)==null?void 0:n.value)||"").trim().toLowerCase();this.slotsContainer.innerHTML="";for(let a of this.getCategories()){let s=(e[a]||[]).filter(d=>i?`${d.displayName} ${d.slotId} ${d.objectId} ${d.currentAsset}`.toLowerCase().includes(i):!0);if(s.length===0)continue;let o=document.createElement("div");o.className="library-category";let l=document.createElement("div");l.className="library-category-header",l.textContent=this.formatCategoryName(a),o.appendChild(l);let c=document.createElement("div");c.className="library-category-slots";for(let d of s){let p=this.createSlotElement(d,t);c.appendChild(p)}o.appendChild(c),this.slotsContainer.appendChild(o)}if(!this.slotsContainer.hasChildNodes()){let a=document.createElement("div");a.className="library-info",a.textContent=i?"No slots match your search":"No editable slots available",this.slotsContainer.appendChild(a)}}createSlotElement(e,t){var y,w;let i=this.selectedSlotId===e.slotId,n=window.__getSelectedObjectId,s=(typeof n=="function"?n():null)===e.objectId,o=document.createElement("div");o.className=`library-slot ${i?"expanded":""} ${s?"current-object":""}`,o.dataset.slotId=e.slotId,o.dataset.objectId=e.objectId;let l=document.createElement("div");l.className="slot-header";let c=document.createElement("div");if(c.className="slot-current",(y=e.currentAsset)==null?void 0:y.toLowerCase().endsWith(".json")){let v=document.createElement("div");v.className="slot-thumbnail slot-thumbnail-json",v.textContent="\u{1F3AC}",v.title="Lottie/JSON Animation",c.appendChild(v)}else{let v=document.createElement("img"),P=this.resolveSlotPreviewPaths(e),I=P.primary,_=(w=P.fallback)!=null?w:null;if(!I)v.style.display="none";else if(this.missingPreviewPaths.has(I.key)&&(!_||this.missingPreviewPaths.has(_.key)))v.style.display="none";else{v.src=I.src(t),v.alt=e.displayName,v.className="slot-thumbnail",v.loading="lazy";let k=!1;v.onerror=()=>{if(k){v.onerror=null,v.style.display="none";return}if(this.missingPreviewPaths.add(I.key),_&&!this.missingPreviewPaths.has(_.key)){k=!0,v.src=_.src(t);return}_&&this.missingPreviewPaths.add(_.key),v.style.display="none"}}c.appendChild(v)}l.appendChild(c);let p=document.createElement("div");p.className="slot-info";let u=document.createElement("div");u.className="slot-name",u.textContent=e.displayName;let g=document.createElement("div");g.className="slot-asset",g.textContent=e.currentAsset,p.appendChild(u),p.appendChild(g),l.appendChild(p);let h=document.createElement("div");h.className="slot-actions";let f=document.createElement("button");f.className="slot-ai-edit",f.title="Edit with AI",f.textContent="\u2728 AI",f.addEventListener("click",async v=>{v.stopPropagation(),await this.handleAIEdit(e)}),h.appendChild(f);let m=document.createElement("button");m.className="slot-upload",m.title="Upload new asset",m.textContent="\u{1F4E4}",m.addEventListener("click",async v=>{v.stopPropagation(),await this.handleUpload(e)}),h.appendChild(m);let b=document.createElement("button");return b.className="slot-reset",b.title="Reset to default",b.textContent="\u21BA",b.addEventListener("click",async v=>{v.stopPropagation(),await this.handleReset(e)}),h.appendChild(b),l.appendChild(h),l.addEventListener("click",()=>{this.selectedSlotId=e.slotId,this.renderSlots(),this.renderAssets()}),o.appendChild(l),o}renderAssets(){var l;if(!this.assetsContainer||!this.registry)return;let e=this.cacheBust||Date.now(),t=(((l=this.assetSearchInput)==null?void 0:l.value)||"").trim().toLowerCase(),i=this.getSelectedSlot();this.assetsContainer.innerHTML="";let n=document.createElement("div");n.className="library-selected",n.textContent=i?`Selected slot: ${i.displayName} (${i.currentAsset||"no asset"})`:"Select a slot to apply assets",n.style.gridColumn="1 / -1",this.assetsContainer.appendChild(n);let a=this.getCategories(),s=!1,o=!1;for(let c of a){let d=this.getCategoryAssets(c,e);if(!d){let f=document.createElement("div");f.className="library-empty",f.textContent=`Loading ${this.formatCategoryName(c)} assets...`,this.assetsContainer.appendChild(f),o=!0;continue}let p=d.filter(f=>t?`${f.displayName} ${f.filename} ${c}`.toLowerCase().includes(t):!0);if(p.length===0)continue;let u=document.createElement("div");u.className="library-category";let g=document.createElement("div");g.className="library-category-header",g.textContent=this.formatCategoryName(c),u.appendChild(g);let h=document.createElement("div");h.className="slot-library",h.style.borderTop="none",h.style.padding="10px";for(let f of p){let m=document.createElement("div");m.className="library-item",i&&i.currentAsset===f.filename&&i.libraryFolder===c&&m.classList.add("selected");let b=document.createElement("img"),y=this.resolveLibraryAssetPath(c,f.filename);this.missingPreviewPaths.has(y.key)?b.style.display="none":b.src=y.src(e),b.alt=f.displayName,b.className="library-thumbnail",b.loading="lazy",b.onerror=()=>{this.missingPreviewPaths.add(y.key),b.style.opacity="0.3"},m.appendChild(b);let w=document.createElement("div");w.className="library-label",w.textContent=f.displayName,m.appendChild(w),m.addEventListener("click",async()=>{if(!i){alert("Select a slot first to apply an asset.");return}await this.handleApply(i,f.filename,c)}),h.appendChild(m),s=!0}u.appendChild(h),this.assetsContainer.appendChild(u)}if(!s&&!o){let c=document.createElement("div");c.className="library-empty",c.textContent=t?"No assets match your search":"No assets available",this.assetsContainer.appendChild(c)}}getCategoryAssets(e,t){var i;if(this.cachedAssets[e])return this.cachedAssets[e];if(!this.pendingAssetFetches[e]){let n=((i=this.registry)==null?void 0:i.libraryAssets[e])||[];this.pendingAssetFetches[e]=this.fetchFolderAssets(e,t).then(a=>{let s=new Map;for(let o of n)s.set(o.filename,o);for(let o of a)s.has(o.filename)||s.set(o.filename,o);return this.cachedAssets[e]=Array.from(s.values()),delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]}).catch(()=>(this.cachedAssets[e]=n,delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]))}return null}async fetchFolderAssets(e,t){try{let i=await fetch(`/raw/library/${e}/?t=${t}`);if(!i.ok)return[];let n=await i.text(),a=[],s=/href="([^"]+\.(png|jpg|jpeg))"/gi,o;for(;(o=s.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,i){var n,a,s;if(this.isApplying){console.warn("[LIBRARY] \u26A0\uFE0F Apply already in progress, ignoring duplicate click");return}this.isApplying=!0,console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{let o=window.__wizardAssetPicker;if(o!=null&&o.onPick){let d=`raw/library/${i||e.libraryFolder||e.category}/${t}`;o.onPick(d),window.__wizardAssetPicker=null;return}let l=i||e.libraryFolder||e.category;if((n=this.options)!=null&&n.onApply){await this.options.onApply(e.objectId,t,l),await new Promise(d=>setTimeout(d,200));let c=window.getEditableObjectConfig;if(typeof c=="function"){let d=c(e.objectId),p=((s=(a=d==null?void 0:d.render)==null?void 0:a.asset)==null?void 0:s.path)||"",u=`raw/library/${l}/${t}`;if(p===u||p.includes(t))console.log("[LIBRARY] \u2705 Asset confirmed applied:",p);else throw console.error("[LIBRARY] \u274C Asset NOT applied! Expected:",u,"Got:",p),new Error(`Asset was not applied correctly. Expected: ${u}, Got: ${p}`)}}e.currentAsset=t,e.libraryFolder=l,this.renderSlots(),this.renderAssets()}catch(o){throw console.error("[LIBRARY] \u274C Failed to apply asset:",o),alert(`Failed to apply asset: ${o instanceof Error?o.message:String(o)}`),o}finally{this.isApplying=!1}}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(),this.renderAssets()}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(" ")}getCategories(){if(!this.registry)return[];let e=new Set;if(Array.isArray(this.registry.categories))for(let t of this.registry.categories)t&&e.add(t);for(let t of Object.keys(this.registry.libraryAssets||{}))t&&e.add(t);for(let t of this.registry.slots||[])t!=null&&t.category&&e.add(t.category);return Array.from(e)}getSelectedSlot(){return!this.registry||!this.selectedSlotId?null:this.registry.slots.find(e=>e.slotId===this.selectedSlotId)||null}scheduleRenderSlots(){this.slotSearchDebounce&&window.clearTimeout(this.slotSearchDebounce),this.slotSearchDebounce=window.setTimeout(()=>{this.slotSearchDebounce=null,this.renderSlots()},150)}scheduleRenderAssets(){this.assetSearchDebounce&&window.clearTimeout(this.assetSearchDebounce),this.assetSearchDebounce=window.setTimeout(()=>{this.assetSearchDebounce=null,this.renderAssets()},150)}resolveSlotPreviewPaths(e){let t=(e.currentAsset||"").trim();if(!t)return{primary:null,fallback:null};let i=t.replace(/^\/+/,""),n=null,a=null;return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:e.libraryFolder?(n=`raw/library/${e.libraryFolder}/${i}`,a=`raw/${i}`):n=`raw/${i}`,{primary:n?{key:n,src:l=>`/${n}?t=${l}`}:null,fallback:a?{key:a,src:l=>`/${a}?t=${l}`}:null}}resolveLibraryAssetPath(e,t){let i=t.replace(/^\/+/,""),n="";return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:n=`raw/library/${e}/${i}`,{key:n,src:a=>`/${n}?t=${a}`}}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,a,s,o,l;let i=(n=t.files)==null?void 0:n[0];if(i){console.log("[Library] File selected:",i.name);try{let c=await this.fileToDataUrl(i);if(!c){alert("Failed to read file");return}let d=e.displayName.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),p=((a=i.name.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/))==null?void 0:a[1])||"png",u=p==="jpg"?"jpeg":p,g=`${d}_uploaded_${Date.now()}.${u}`,h=e.category;console.log("[Library] Saving uploaded file:",g,"to category:",h);let m=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:h,filename:g,data:c,overwrite:!0})})).json();if(m.success){console.log("[Library] \u2705 Upload saved:",m.path),await new Promise(j=>setTimeout(j,100));let b=window.addAssetToRegistry;typeof b=="function"&&(b(h,g),console.log("[Library] \u2705 Added to registry:",h,g));let y=window.getEditableAssets;if(typeof y=="function"){let j=y();j&&!j.categories&&(j.categories=[]),j!=null&&j.categories&&!j.categories.includes(h)&&(j.categories.push(h),console.log(`[Library] Added category ${h} to registry`))}let w=!1,v=0,P=10;for(;!w&&v<P;){v++,console.log(`[Library] Refresh attempt ${v}/${P}...`);try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&console.log("[Library] \u2705 Registry rebuilt from disk")}catch(x){console.warn("[Library] Setup-library not available:",x)}await new Promise(x=>setTimeout(x,300)),await this.refresh();let j=window.reRenderAssetLibrary;typeof j=="function"&&(console.log("[Library] Re-rendering library panel..."),j());let L=window.getEditableAssets;if(typeof L=="function"){let x=L(),S=((s=x==null?void 0:x.libraryAssets)==null?void 0:s[h])||[];S.some(C=>(C==null?void 0:C.filename)===g)?(console.log("[Library] \u2705 Asset found in registry!"),w=!0):(console.log(`[Library] Asset not found yet, retrying... (found ${S.length} assets in ${h})`),await new Promise(C=>setTimeout(C,500)))}else v>=2&&(w=!0)}w||console.warn("[Library] \u26A0\uFE0F Asset not found in registry after retries, proceeding anyway...");let I=!1,_=0,k=5;for(;!I&&_<k;){_++;try{console.log(`[Library] Applying asset attempt ${_}/${k}...`),await this.handleApply(e,g,e.category),await new Promise(L=>setTimeout(L,200));let j=window.getEditableObjectConfig;if(typeof j=="function"){let L=j(e.objectId),x=((l=(o=L==null?void 0:L.render)==null?void 0:o.asset)==null?void 0:l.path)||"";x===m.path||x.includes(g)?(console.log("[Library] \u2705 Asset confirmed applied to object"),I=!0):(console.log(`[Library] Asset not applied yet (attempt ${_}), retrying...`),await new Promise(S=>setTimeout(S,300)))}else I=!0}catch(j){console.error(`[Library] Apply attempt ${_} failed:`,j),_<k&&await new Promise(L=>setTimeout(L,500))}}e.currentAsset=g,await this.refresh(),setTimeout(()=>{try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[Library] Dispatched config:changed event")}catch(j){console.warn("[Library] Failed to refresh textures:",j)}},300),setTimeout(()=>{this.highlightSlot(e.objectId,h)},1e3),I?console.log("[Library] \u2705 Upload complete and applied!"):console.warn("[Library] \u26A0\uFE0F Upload succeeded but apply may have failed")}else console.error("[Library] \u274C Upload failed:",m.error),alert(`Upload failed: ${m.error}`)}catch(c){console.error("[Library] \u274C Upload error:",c),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.selectedSlotId=n.slotId,this.renderSlots(),this.renderAssets(),setTimeout(()=>{var s;let a=(s=this.slotsContainer)==null?void 0:s.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 $i=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 Di=class{render(e,t,i,n){let a=this.formatLabel(t),s=i?this.getThumbnailUrl(i):"";return`
870
870
  <div class="inspector-property" data-property-type="image">
871
871
  <div class="inspector-property-header">
872
872
  <label class="inspector-label">${a}</label>
@@ -888,7 +888,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
888
888
  </div>
889
889
  `}
890
890
  </div>
891
- `}getThumbnailUrl(e){if(e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("http"))return e;let t=`t=${Date.now()}`,i=e.replace(/^\.?\//,"");if(i.startsWith("raw/")||i.startsWith("assets/")||i.startsWith("library/")){let n=`/${i}`;return n.includes("?")?`${n}&${t}`:`${n}?${t}`}return`/raw/${i}?${t}`}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 Di=class{render(e,t,i,n){let a=i||"#000000";return`
891
+ `}getThumbnailUrl(e){if(e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("http"))return e;let t=`t=${Date.now()}`,i=e.replace(/^\.?\//,"");if(i.startsWith("raw/")||i.startsWith("assets/")||i.startsWith("library/")){let n=`/${i}`;return n.includes("?")?`${n}&${t}`:`${n}?${t}`}return`/raw/${i}?${t}`}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 Ni=class{render(e,t,i,n){let a=i||"#000000";return`
892
892
  <div class="inspector-property inspector-property-color">
893
893
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
894
894
  <div class="inspector-color-group">
@@ -904,7 +904,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
904
904
  data-object-id="${e}" />
905
905
  </div>
906
906
  </div>
907
- `}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){return`
907
+ `}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){return`
908
908
  <div class="inspector-property inspector-property-number">
909
909
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
910
910
  <input type="number"
@@ -914,7 +914,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
914
914
  data-object-id="${e}"
915
915
  step="any" />
916
916
  </div>
917
- `}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){let a=String(i||"");return`
917
+ `}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 a=String(i||"");return`
918
918
  <div class="inspector-property inspector-property-text">
919
919
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
920
920
  <div class="inspector-input-group">
@@ -925,7 +925,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
925
925
  data-object-id="${e}" />
926
926
  </div>
927
927
  </div>
928
- `}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){return`
928
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Bi=class{render(e,t,i,n){return`
929
929
  <div class="inspector-property inspector-property-boolean">
930
930
  <label class="inspector-property-label">
931
931
  <input type="checkbox"
@@ -936,7 +936,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
936
936
  <span>${this.formatLabel(t)}</span>
937
937
  </label>
938
938
  </div>
939
- `}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){if(t==="logic"&&this.registry){let s=this.registry,r=Array.isArray(i)?i:[],l=r.map((d,p)=>{let u=`${n}.${p}`,g=`
939
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Gi=class{constructor(e){this.registry=e}render(e,t,i,n){if(t==="logic"&&this.registry){let s=this.registry,o=Array.isArray(i)?i:[],l=o.map((d,p)=>{let u=`${n}.${p}`,g=`
940
940
  <button class="inspector-button inspector-button-small"
941
941
  data-logic-remove="true"
942
942
  data-object-id="${e}"
@@ -980,7 +980,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
980
980
  </button>
981
981
  `;return`
982
982
  <div class="inspector-property inspector-property-array">
983
- <label class="inspector-property-label">${this.formatLabel(t)} (${r.length} items)</label>
983
+ <label class="inspector-property-label">${this.formatLabel(t)} (${o.length} items)</label>
984
984
  <div class="inspector-array-list">
985
985
  ${l||'<div class="inspector-array-empty">Empty array</div>'}
986
986
  </div>
@@ -993,14 +993,14 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
993
993
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
994
994
  <div class="inspector-array-empty">Empty array</div>
995
995
  </div>
996
- `;let a=i.map((s,r)=>typeof s=="string"?`<div class="inspector-array-item">\u2022 ${s}</div>`:typeof s=="object"?`<div class="inspector-array-item">\u2022 ${JSON.stringify(s)}</div>`:`<div class="inspector-array-item">\u2022 ${String(s)}</div>`).join("");return`
996
+ `;let a=i.map((s,o)=>typeof s=="string"?`<div class="inspector-array-item">\u2022 ${s}</div>`:typeof s=="object"?`<div class="inspector-array-item">\u2022 ${JSON.stringify(s)}</div>`:`<div class="inspector-array-item">\u2022 ${String(s)}</div>`).join("");return`
997
997
  <div class="inspector-property inspector-property-array">
998
998
  <label class="inspector-property-label">${this.formatLabel(t)} (${i.length} items)</label>
999
999
  <div class="inspector-array-list">
1000
1000
  ${a}
1001
1001
  </div>
1002
1002
  </div>
1003
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Gi=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 r in i){let l=i[r],c=`${n}.${r}`,d=this.registry.renderProperty(e,r,l,c);d&&a.push(d)}return a.length===0?"":a.length<=4&&a.every(r=>r.includes("inspector-property"))?`
1003
+ `}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(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"))?`
1004
1004
  <div class="inspector-subsection">
1005
1005
  <div class="inspector-subsection-title">${this.formatLabel(t)}</div>
1006
1006
  <div class="inspector-subsection-content">
@@ -1014,7 +1014,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1014
1014
  ${a.join("")}
1015
1015
  </div>
1016
1016
  </div>
1017
- `}renderLogic(e,t,i,n){let a=[],s=typeof(i==null?void 0:i.id)=="string"?i.id:"",r={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=s&&!l.includes(s)?[s,...l]:l;a.push(`
1017
+ `}renderLogic(e,t,i,n){let a=[],s=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=s&&!l.includes(s)?[s,...l]:l;a.push(`
1018
1018
  <div class="inspector-property inspector-property-text">
1019
1019
  <label class="inspector-property-label">Id</label>
1020
1020
  <div class="inspector-input-group">
@@ -1027,30 +1027,30 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1027
1027
  </select>
1028
1028
  </div>
1029
1029
  </div>
1030
- `);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=r[b];if(b==="targetId"||b==="inputId"){let I=this.registry.getObjectIds(),P=typeof y=="string"?y:"",_=P&&!I.includes(P)?[P,...I]:I;m.push(`
1030
+ `);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],w=`${h}.${b}`,v=o[b];if(b==="targetId"||b==="inputId"){let P=this.registry.getObjectIds(),I=typeof y=="string"?y:"",_=I&&!P.includes(I)?[I,...P]:P;m.push(`
1031
1031
  <div class="inspector-property inspector-property-text">
1032
1032
  <label class="inspector-property-label">${this.formatLabel(b)}</label>
1033
1033
  <div class="inspector-input-group">
1034
1034
  <select class="inspector-component-select inspector-input"
1035
- data-property-path="${v}"
1035
+ data-property-path="${w}"
1036
1036
  data-object-id="${e}">
1037
- <option value="" ${P?"":"selected"}>None</option>
1038
- ${_.map(T=>`<option value="${T}" ${T===P?"selected":""}>${T}</option>`).join("")}
1037
+ <option value="" ${I?"":"selected"}>None</option>
1038
+ ${_.map(k=>`<option value="${k}" ${k===I?"selected":""}>${k}</option>`).join("")}
1039
1039
  </select>
1040
1040
  </div>
1041
1041
  </div>
1042
- `);continue}if(Array.isArray(w)&&w.length)m.push(`
1042
+ `);continue}if(Array.isArray(v)&&v.length)m.push(`
1043
1043
  <div class="inspector-property inspector-property-text">
1044
1044
  <label class="inspector-property-label">${this.formatLabel(b)}</label>
1045
1045
  <div class="inspector-input-group">
1046
1046
  <select class="inspector-component-select inspector-input"
1047
- data-property-path="${v}"
1047
+ data-property-path="${w}"
1048
1048
  data-object-id="${e}">
1049
- ${w.map(I=>`<option value="${String(I)}" ${String(I)===String(y)?"selected":""}>${String(I)}</option>`).join("")}
1049
+ ${v.map(P=>`<option value="${String(P)}" ${String(P)===String(y)?"selected":""}>${String(P)}</option>`).join("")}
1050
1050
  </select>
1051
1051
  </div>
1052
1052
  </div>
1053
- `);else{let I=this.registry.renderProperty(e,b,y,v);I&&m.push(I)}}m.length&&a.push(`
1053
+ `);else{let P=this.registry.renderProperty(e,b,y,w);P&&m.push(P)}}m.length&&a.push(`
1054
1054
  <div class="inspector-property inspector-property-object">
1055
1055
  <div class="inspector-object-header">Props</div>
1056
1056
  <div class="inspector-object-body">
@@ -1075,7 +1075,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1075
1075
  ${p}
1076
1076
  </div>
1077
1077
  </div>
1078
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ui=class{render(e,t,i,n,a){let s=i==null?"":String(i),r=Array.from(new Set(a.map(c=>String(c)))),l=s&&!r.includes(s)?[s,...r]:r;return`
1078
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var qi=class{render(e,t,i,n,a){let s=i==null?"":String(i),o=Array.from(new Set(a.map(c=>String(c)))),l=s&&!o.includes(s)?[s,...o]:o;return`
1079
1079
  <div class="inspector-property inspector-property-text">
1080
1080
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
1081
1081
  <div class="inspector-input-group">
@@ -1086,7 +1086,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1086
1086
  </select>
1087
1087
  </div>
1088
1088
  </div>
1089
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var qi=class{render(e,t,i,n){let a=this.safeStringify(i);return`
1089
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Vi=class{render(e,t,i,n){let a=this.safeStringify(i);return`
1090
1090
  <div class="inspector-property inspector-property-text">
1091
1091
  <label class="inspector-property-label">${this.formatLabel(t)}</label>
1092
1092
  <div class="inspector-input-group">
@@ -1097,7 +1097,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1097
1097
  rows="6">${a}</textarea>
1098
1098
  </div>
1099
1099
  </div>
1100
- `}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 Vi=class{render(e,t,i,n){let s=(Array.isArray(i)?i:[]).map((r,l)=>{let c=typeof(r==null?void 0:r.x)=="number"?r.x:0,d=typeof(r==null?void 0:r.y)=="number"?r.y:0;return`
1100
+ `}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 Yi=class{render(e,t,i,n){let s=(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`
1101
1101
  <div class="inspector-row" style="gap:8px; align-items:center;">
1102
1102
  <input type="number"
1103
1103
  class="inspector-input"
@@ -1130,7 +1130,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1130
1130
  </div>
1131
1131
  </div>
1132
1132
  </div>
1133
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Yi=class{constructor(e){this.registry=e}render(e,t,i,n){let a=Array.isArray(i)?i:[],r=["",...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=r.map(h=>`<option value="${h}"${h===p?" selected":""}>${h||"(none)"}</option>`).join("");return`
1133
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Wi=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`
1134
1134
  <div class="inspector-row" style="gap:8px; align-items:center;">
1135
1135
  <select class="inspector-select inspector-input"
1136
1136
  data-property-path="${n}.${d}.templateId"
@@ -1165,7 +1165,7 @@ ${r}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
1165
1165
  </div>
1166
1166
  </div>
1167
1167
  </div>
1168
- `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Wi=class{constructor(){this.typeDetector=new zi,this.imageRenderer=new $i,this.colorRenderer=new Di,this.numberRenderer=new Ni,this.textRenderer=new Hi,this.booleanRenderer=new Fi,this.arrayRenderer=new Bi(this),this.objectRenderer=new Gi(this),this.selectRenderer=new Ui,this.jsonRenderer=new qi,this.spawnPointsRenderer=new Vi,this.spawnTemplatesRenderer=new Yi(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 s=String(e||"").split(".").filter(Boolean);if(s.length<2)return null;let r=s[0],l=s.slice(1).join("."),c=a instanceof Map?a.get(r):a==null?void 0:a[r];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,s)=>a.localeCompare(s))}catch{return[]}}renderProperty(e,t,i,n){let a=t.toLowerCase(),s=a==="logic"||a==="logic_id"||a==="logicid",r=a==="id"&&n.toLowerCase().includes("logic");if((s||r)&&typeof i=="string"){let h=this.getLogicOptions(),f=this.selectRenderer.render(e,t,i,n,h);return s?`
1168
+ `}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ki=class{constructor(){this.typeDetector=new $i,this.imageRenderer=new Di,this.colorRenderer=new Ni,this.numberRenderer=new Hi,this.textRenderer=new Fi,this.booleanRenderer=new Bi,this.arrayRenderer=new Gi(this),this.objectRenderer=new Ui(this),this.selectRenderer=new qi,this.jsonRenderer=new Vi,this.spawnPointsRenderer=new Yi,this.spawnTemplatesRenderer=new Wi(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 s=String(e||"").split(".").filter(Boolean);if(s.length<2)return null;let o=s[0],l=s.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,s)=>a.localeCompare(s))}catch{return[]}}renderProperty(e,t,i,n){let a=t.toLowerCase(),s=a==="logic"||a==="logic_id"||a==="logicid",o=a==="id"&&n.toLowerCase().includes("logic");if((s||o)&&typeof i=="string"){let h=this.getLogicOptions(),f=this.selectRenderer.render(e,t,i,n,h);return s?`
1169
1169
  ${f}
1170
1170
  <div class="inspector-array-actions">
1171
1171
  <button class="inspector-button"
@@ -1175,7 +1175,7 @@ ${f}
1175
1175
  Add Logic
1176
1176
  </button>
1177
1177
  </div>
1178
- `: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","left-center","right-center","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"))){let h;if(typeof i=="string")h=i;else if(i==null)h="center";else{let m=Xe(i);h=p.find(y=>{let v=Xe(y);return Math.abs(v.x-m.x)<.001&&Math.abs(v.y-m.y)<.001})||"custom"}let f=[...p];return h==="custom"&&!f.includes("custom")&&f.push("custom"),this.selectRenderer.render(e,t,h,n,f)}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 sl(o,e){let t;return function(...n){let a=()=>{clearTimeout(t),o(...n)};clearTimeout(t),t=setTimeout(a,e)}}var Ki=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 Wi,this.updateManager=new xe,this.quickActions=new Ii;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`
1178
+ `: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","left-center","right-center","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"))){let h;if(typeof i=="string")h=i;else if(i==null)h="center";else{let m=Je(i);h=p.find(y=>{let w=Je(y);return Math.abs(w.x-m.x)<.001&&Math.abs(w.y-m.y)<.001})||"custom"}let f=[...p];return h==="custom"&&!f.includes("custom")&&f.push("custom"),this.selectRenderer.render(e,t,h,n,f)}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 rl(r,e){let t;return function(...n){let a=()=>{clearTimeout(t),r(...n)};clearTimeout(t),t=setTimeout(a,e)}}var Xi=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 Ki,this.updateManager=new Se,this.quickActions=new Pi;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`
1179
1179
  <div class="scene-panel inspector-panel panel-accent-violet" data-panel="inspector">
1180
1180
  <div class="scene-panel-header" data-panel-handle>
1181
1181
  <div class="panel-title">
@@ -1204,7 +1204,7 @@ ${f}
1204
1204
  </div>
1205
1205
  ${this.renderConversionButtons(e,t)}
1206
1206
  </div>
1207
- `);let r=["transform","ui","render","gameplay","interaction","audio","effects","physics","motion","identity"];for(let l of r){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(!r.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 r,l,c,d;let i=!!t.ui,n=((r=t.ui)==null?void 0:r.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 s=(d=t.ui)!=null&&d.text?"ui.text":"render.asset.path";return`
1207
+ `);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 s=(d=t.ui)!=null&&d.text?"ui.text":"render.asset.path";return`
1208
1208
  <div class="inspector-quick-actions">
1209
1209
  <button class="debug-btn debug-btn-sm success ai-simple-btn" type="button" data-convert-toggle>
1210
1210
  \u2728 Convert to PNG
@@ -1247,7 +1247,7 @@ ${f}
1247
1247
  ${n}
1248
1248
  </div>
1249
1249
  </div>
1250
- `:""}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],s=i[n];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[n]=this.applyMotionDefaults(s,a):s===void 0&&(i[n]=a)}return i}renderMotionSection(e,t,i){var h;let n=[],a=this.getMotionDefaults(),s=this.applyMotionDefaults(t!=null?t:{},a!=null?a:{}),r=(h=s.intro)!=null?h:{},l=r.enabled===!0&&(typeof r.duration!="number"||r.duration<=0)?'<div class="inspector-warning">\u26A0\uFE0F Duration must be > 0 to play.</div>':"",c=`
1250
+ `:""}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],s=i[n];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[n]=this.applyMotionDefaults(s,a):s===void 0&&(i[n]=a)}return i}renderMotionSection(e,t,i){var h;let n=[],a=this.getMotionDefaults(),s=this.applyMotionDefaults(t!=null?t:{},a!=null?a:{}),o=(h=s.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=`
1251
1251
  <div class="inspector-motion-presets">
1252
1252
  <span class="inspector-subsection-title">Intro Motions</span>
1253
1253
  <div class="inspector-motion-buttons">
@@ -1264,7 +1264,7 @@ ${f}
1264
1264
  <button class="debug-btn debug-btn-sm ${this.motionSimpleMode?"primary":""}" data-motion-simple-toggle>
1265
1265
  ${this.motionSimpleMode?"Simple":"Advanced"}
1266
1266
  </button>
1267
- `,p='<button class="debug-btn debug-btn-sm success" data-motion-preview>Preview Intro</button>',u=f=>{let m=f.split(".").filter(Boolean),b=s;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(`
1267
+ `,p='<button class="debug-btn debug-btn-sm success" data-motion-preview>Preview Intro</button>',u=f=>{let m=f.split(".").filter(Boolean),b=s;for(let v of m)b=b==null?void 0:b[v];let y=m[m.length-1],w=`${i}.${f}`;return this.rendererRegistry.renderProperty(e,y,b,w)};if(this.motionSimpleMode){let f=u("enabled");f&&n.push(f);let m=[],b=u("intro.enabled"),y=u("intro.type"),w=u("intro.duration"),v=u("intro.easing");b&&m.push(b),y&&m.push(y),w&&m.push(w),v&&m.push(v),m.length&&n.push(`
1268
1268
  <div class="inspector-subsection">
1269
1269
  <div class="inspector-subsection-title">Intro</div>
1270
1270
  <div class="inspector-subsection-content">
@@ -1273,15 +1273,15 @@ ${f}
1273
1273
  ${m.join("")}
1274
1274
  </div>
1275
1275
  </div>
1276
- `);let I=[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),_=[u("continuousMove.enabled"),u("continuousMove.axis"),u("continuousMove.speed"),u("continuousMove.direction"),u("continuousMove.lifetime")].filter(Boolean),T=[u("continuousRotate.enabled"),u("continuousRotate.speed"),u("continuousRotate.direction")].filter(Boolean),M=[u("orbit.enabled"),u("orbit.radius"),u("orbit.speed"),u("orbit.direction"),u("orbit.pivotOffsetX"),u("orbit.pivotOffsetY")].filter(Boolean);if(I.length||P.length||_.length||T.length||M.length){let A=(L,x)=>x.length?`
1276
+ `);let P=[u("pulse.enabled"),u("pulse.speed"),u("pulse.intensity")].filter(Boolean),I=[u("swing.enabled"),u("swing.amplitude"),u("swing.speed"),u("swing.axis")].filter(Boolean),_=[u("continuousMove.enabled"),u("continuousMove.axis"),u("continuousMove.speed"),u("continuousMove.direction"),u("continuousMove.lifetime")].filter(Boolean),k=[u("continuousRotate.enabled"),u("continuousRotate.speed"),u("continuousRotate.direction")].filter(Boolean),j=[u("orbit.enabled"),u("orbit.radius"),u("orbit.speed"),u("orbit.direction"),u("orbit.pivotOffsetX"),u("orbit.pivotOffsetY")].filter(Boolean);if(P.length||I.length||_.length||k.length||j.length){let x=(E,C)=>C.length?`
1277
1277
  <div class="inspector-motion-continuous-group">
1278
- <div class="inspector-subsection-title">${L}</div>
1279
- <div class="inspector-subsection-content">${x.join("")}</div>
1280
- </div>`:"",C=[A("Pulse",I),A("Swing",P),A("Move forever",_),A("Rotate (pivoting itself)",T),A("Rotate around",M)].filter(Boolean).join("");n.push(`
1278
+ <div class="inspector-subsection-title">${E}</div>
1279
+ <div class="inspector-subsection-content">${C.join("")}</div>
1280
+ </div>`:"",S=[x("Pulse",P),x("Swing",I),x("Move forever",_),x("Rotate (pivoting itself)",k),x("Rotate around",j)].filter(Boolean).join("");n.push(`
1281
1281
  <div class="inspector-subsection inspector-subsection-continuous">
1282
1282
  <div class="inspector-subsection-title">Continuous</div>
1283
1283
  <div class="inspector-subsection-content inspector-motion-continuous-groups">
1284
- ${C}
1284
+ ${S}
1285
1285
  </div>
1286
1286
  </div>
1287
1287
  `)}}else for(let f in s){let m=s[f],b=`${i}.${f}`,y=this.rendererRegistry.renderProperty(e,f,m,b);y&&n.push(y)}return n.length===0?"":`
@@ -1297,7 +1297,7 @@ ${f}
1297
1297
  ${n.join("")}
1298
1298
  </div>
1299
1299
  </div>
1300
- `}attachEventListeners(){var w,I,P,_;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=sl((T,M,k)=>{var A,C;this.updateManager.updateProperty(T,M,k),(C=(A=this.options)==null?void 0:A.onPropertyChange)==null||C.call(A,T,M,k)},300),i=T=>T?/(^|\.)logic(\.\d+)?\.id$/.test(T):!1;e.forEach(T=>{let M=C=>{var S,O;let L=C.target,x=L.dataset.propertyPath,E=L.dataset.objectId;if(x&&E){let j=L.value;if(L.type==="checkbox")j=L.checked;else if(L.type==="number"){if(j=parseFloat(L.value),isNaN(j))return}else if(L.dataset.json==="true")try{j=JSON.parse(L.value)}catch{return}L.type==="text"||L.type==="range"||L.tagName==="TEXTAREA"?t(E,x,j):(this.updateManager.updateProperty(E,x,j),(O=(S=this.options)==null?void 0:S.onPropertyChange)==null||O.call(S,E,x,j))}},k=T.dataset.propertyPath;k&&(k.includes("transform.anchor")||k.includes("render.anchor"))&&T.tagName==="SELECT"?T.addEventListener("change",async C=>{var O,j,R,z,D;let L=C.target,x=L.dataset.propertyPath,E=L.dataset.objectId,S=L.value;if(!(!x||!E)&&S!=="custom")if(x.includes("transform.anchor")){let q=window.getEditableObjectConfig,G=typeof q=="function"?q(E):null,B=(O=G==null?void 0:G.transform)==null?void 0:O.anchor,F=B!=null&&B!==""?B:"top-left",U=S;await this.updateManager.updateProperty(E,x,S),(R=(j=this.options)==null?void 0:j.onPropertyChange)==null||R.call(j,E,x,S),F!==U&&window.dispatchEvent(new CustomEvent("scene-editor:anchor-changed",{detail:{objectId:E,previousAnchor:F,nextAnchor:U}}))}else await this.updateManager.updateProperty(E,x,S),(D=(z=this.options)==null?void 0:z.onPropertyChange)==null||D.call(z,E,x,S)}):i(k)?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",k),T.addEventListener("change",async C=>{var D;let L=C.target,x=L.dataset.propertyPath,E=L.dataset.objectId,S=L.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",S),!x||!E)return;await this.updateManager.updateProperty(E,x,S),console.log("[Inspector v1.0.0] Logic ID updated");let O=window,j=(D=O==null?void 0:O.__HANDLER_LOGIC_META)==null?void 0:D[S],R=this.getDefaultPropsForLogic(S,j);console.log("[Inspector v1.0.0] New logic default props:",R);let z=x.replace(/\.id$/,".props");await this.updateManager.updateProperty(E,z,R),console.log("[Inspector v1.0.0] Logic props updated to:",R),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(E)})):(T.addEventListener("change",M),(T.tagName==="INPUT"||T.tagName==="TEXTAREA")&&T.addEventListener("input",M))}),this.contentContainer.querySelectorAll("[data-action]").forEach(T=>{T.addEventListener("click",M=>{let k=M.target,A=k.dataset.action,C=k.dataset.path,L=k.dataset.object;A&&C&&L&&this.quickActions.handleAction(A,L,C)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(T=>{T.addEventListener("click",M=>{var C,L;let k=M.target,A=k.dataset.sectionToggle||((C=k.closest("[data-section-toggle]"))==null?void 0:C.getAttribute("data-section-toggle"));if(A){let x=(L=this.contentContainer)==null?void 0:L.querySelector(`[data-section="${A}"]`);x==null||x.classList.toggle("collapsed")}})}),this.contentContainer.querySelectorAll("[data-motion-preset]").forEach(T=>{T.addEventListener("click",async M=>{let A=M.currentTarget.dataset.motionPreset;!A||!this.selectedObjectId||await this.applyMotionPreset(this.selectedObjectId,A)})}),this.contentContainer.querySelectorAll("[data-motion-preview]").forEach(T=>{T.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(T=>{T.addEventListener("click",async M=>{let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath;if(!A||!C)return;let L=window.getEditableObjectConfig,x=L==null?void 0:L(A);if(!x)return;let E=this.updateManager.getNestedProperty(x,C),S=Array.isArray(E)?[...E]:[];S.push({x:0,y:0}),await this.updateManager.updateProperty(A,C,S),this.loadObject(A)})}),this.contentContainer.querySelectorAll("[data-spawnpoints-remove]").forEach(T=>{T.addEventListener("click",async M=>{let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath,L=Number(k.dataset.index||"-1");if(!A||!C||L<0)return;let x=window.getEditableObjectConfig,E=x==null?void 0:x(A);if(!E)return;let S=this.updateManager.getNestedProperty(E,C);if(!Array.isArray(S))return;let O=S.filter((j,R)=>R!==L);await this.updateManager.updateProperty(A,C,O),this.loadObject(A)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-add]").forEach(T=>{T.addEventListener("click",async M=>{let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath;if(!A||!C)return;let L=window.getEditableObjectConfig,x=L==null?void 0:L(A);if(!x)return;let E=this.updateManager.getNestedProperty(x,C),S=Array.isArray(E)?[...E]:[];S.push({templateId:"",weight:1}),await this.updateManager.updateProperty(A,C,S),this.loadObject(A)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-remove]").forEach(T=>{T.addEventListener("click",async M=>{var j;let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath,L=Number((j=k.dataset.index)!=null?j:-1);if(!A||!C||L<0)return;let x=window.getEditableObjectConfig,E=x==null?void 0:x(A);if(!E)return;let S=this.updateManager.getNestedProperty(E,C);if(!Array.isArray(S))return;let O=S.filter((R,z)=>z!==L);await this.updateManager.updateProperty(A,C,O),this.loadObject(A)})}),this.contentContainer.querySelectorAll("[data-logic-add]").forEach(T=>{T.addEventListener("click",async M=>{var D;let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath;if(!A||!C)return;let L=window.getEditableObjectConfig,x=L==null?void 0:L(A);if(!x)return;let E=this.updateManager.getNestedProperty(x,C),S;Array.isArray(E)?S=[...E]:E!=null?typeof E=="string"?S=[{id:E,props:{}}]:typeof E=="object"?S=[E]:S=[]:S=[];let O=this.getDefaultLogicId(),j=window,R=(D=j==null?void 0:j.__HANDLER_LOGIC_META)==null?void 0:D[O],z=this.getDefaultPropsForLogic(O,R);S.push({id:O,props:z}),console.log("[InspectorPanel] Adding logic to array:",{objectId:A,path:C,current:E,next:S}),await this.updateManager.updateProperty(A,C,S),this.loadObject(A)})}),this.contentContainer.querySelectorAll("[data-logic-remove]").forEach(T=>{T.addEventListener("click",async M=>{var j;let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath,L=Number((j=k.dataset.index)!=null?j:-1);if(!A||!C||L<0)return;let x=window.getEditableObjectConfig,E=x==null?void 0:x(A);if(!E)return;let S=this.updateManager.getNestedProperty(E,C);if(!Array.isArray(S))return;let O=S.filter((R,z)=>z!==L);await this.updateManager.updateProperty(A,C,O),this.loadObject(A)})}),this.contentContainer.querySelectorAll("[data-logic-convert]").forEach(T=>{T.addEventListener("click",async M=>{var q,G;let k=M.target,A=k.dataset.objectId,C=k.dataset.propertyPath,L=Number((q=k.dataset.index)!=null?q:-1);if(!A||!C||L<0)return;let x=window.getEditableObjectConfig,E=x==null?void 0:x(A);if(!E)return;let S=this.updateManager.getNestedProperty(E,C);if(!Array.isArray(S))return;let O=S[L];if(typeof O!="string")return;let j=window,R=(G=j==null?void 0:j.__HANDLER_LOGIC_META)==null?void 0:G[O],z=this.getDefaultPropsForLogic(O,R),D=[...S];D[L]={id:O,props:z},await this.updateManager.updateProperty(A,C,D),this.loadObject(A)})});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=(I=this.root)==null?void 0:I.querySelector("[data-convert-toggle]");b==null||b.addEventListener("click",()=>{var M;let T=(M=this.root)==null?void 0:M.querySelector("[data-convert-menu]");T==null||T.classList.toggle("hidden")});let y=(P=this.contentContainer)==null?void 0:P.querySelector("[data-inspector-add-component-btn]"),v=(_=this.contentContainer)==null?void 0:_.querySelector("[data-inspector-component-select]");y==null||y.addEventListener("click",async()=>{let T=v.value;T&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,T)})}getMotionDefaults(){var i,n,a,s;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"?(s=(a=t.motion)==null?void 0:a.defaults)!=null?s:{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(),s={...(l=n.motion)!=null?l:a},r={...(c=s.intro)!=null?c:{}};s.enabled=!0,r.enabled=!0,r.type=t,r.duration=typeof r.duration=="number"&&r.duration>0?r.duration:500,r.delay=typeof r.delay=="number"?r.delay:0,r.easing=typeof r.easing=="string"?r.easing:"easeOut",s.intro=r,await this.updateManager.updateProperty(e,"motion",s),this.expandMotionOnNextRender=!0,this.loadObject(e)}async previewMotionIntro(e){var r,l;let t=window.getEditableObjectConfig,i=t==null?void 0:t(e);if(!i)return;let n=this.getMotionDefaults(),a={...(r=i.motion)!=null?r:n},s={...(l=a.intro)!=null?l:{}};a.enabled=!0,s.enabled=!0,a.intro=s,await this.updateManager.updateProperty(e,"motion",{...a,intro:{...s,enabled:!1}}),await this.updateManager.updateProperty(e,"motion",{...a,intro:{...s,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,s=a==null?void 0:a.schemas,r=null;s instanceof Map?r=s.get(t):s&&typeof s=="object"&&(r=s[t]),r||console.warn("[InspectorPanel] Schema not found for component:",t);let l=(r==null?void 0:r.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,s;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((s=(a=i.render)==null?void 0:a.asset)==null?void 0:s.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=`
1300
+ `}attachEventListeners(){var v,P,I,_;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=rl((k,j,L)=>{var x,S;this.updateManager.updateProperty(k,j,L),(S=(x=this.options)==null?void 0:x.onPropertyChange)==null||S.call(x,k,j,L)},300),i=k=>k?/(^|\.)logic(\.\d+)?\.id$/.test(k):!1;e.forEach(k=>{let j=S=>{var T,O;let E=S.target,C=E.dataset.propertyPath,A=E.dataset.objectId;if(C&&A){let M=E.value;if(E.type==="checkbox")M=E.checked;else if(E.type==="number"){if(M=parseFloat(E.value),isNaN(M))return}else if(E.dataset.json==="true")try{M=JSON.parse(E.value)}catch{return}E.type==="text"||E.type==="range"||E.tagName==="TEXTAREA"?t(A,C,M):(this.updateManager.updateProperty(A,C,M),(O=(T=this.options)==null?void 0:T.onPropertyChange)==null||O.call(T,A,C,M))}},L=k.dataset.propertyPath;L&&(L.includes("transform.anchor")||L.includes("render.anchor"))&&k.tagName==="SELECT"?k.addEventListener("change",async S=>{var O,M,R,z,F;let E=S.target,C=E.dataset.propertyPath,A=E.dataset.objectId,T=E.value;if(!(!C||!A)&&T!=="custom")if(C.includes("transform.anchor")){let q=window.getEditableObjectConfig,N=typeof q=="function"?q(A):null,H=(O=N==null?void 0:N.transform)==null?void 0:O.anchor,$=H!=null&&H!==""?H:"top-left",U=T;await this.updateManager.updateProperty(A,C,T),(R=(M=this.options)==null?void 0:M.onPropertyChange)==null||R.call(M,A,C,T),$!==U&&window.dispatchEvent(new CustomEvent("scene-editor:anchor-changed",{detail:{objectId:A,previousAnchor:$,nextAnchor:U}}))}else await this.updateManager.updateProperty(A,C,T),(F=(z=this.options)==null?void 0:z.onPropertyChange)==null||F.call(z,A,C,T)}):i(L)?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",L),k.addEventListener("change",async S=>{var F;let E=S.target,C=E.dataset.propertyPath,A=E.dataset.objectId,T=E.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",T),!C||!A)return;await this.updateManager.updateProperty(A,C,T),console.log("[Inspector v1.0.0] Logic ID updated");let O=window,M=(F=O==null?void 0:O.__HANDLER_LOGIC_META)==null?void 0:F[T],R=this.getDefaultPropsForLogic(T,M);console.log("[Inspector v1.0.0] New logic default props:",R);let z=C.replace(/\.id$/,".props");await this.updateManager.updateProperty(A,z,R),console.log("[Inspector v1.0.0] Logic props updated to:",R),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(A)})):(k.addEventListener("change",j),(k.tagName==="INPUT"||k.tagName==="TEXTAREA")&&k.addEventListener("input",j))}),this.contentContainer.querySelectorAll("[data-action]").forEach(k=>{k.addEventListener("click",j=>{let L=j.target,x=L.dataset.action,S=L.dataset.path,E=L.dataset.object;x&&S&&E&&this.quickActions.handleAction(x,E,S)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(k=>{k.addEventListener("click",j=>{var S,E;let L=j.target,x=L.dataset.sectionToggle||((S=L.closest("[data-section-toggle]"))==null?void 0:S.getAttribute("data-section-toggle"));if(x){let C=(E=this.contentContainer)==null?void 0:E.querySelector(`[data-section="${x}"]`);C==null||C.classList.toggle("collapsed")}})}),this.contentContainer.querySelectorAll("[data-motion-preset]").forEach(k=>{k.addEventListener("click",async j=>{let x=j.currentTarget.dataset.motionPreset;!x||!this.selectedObjectId||await this.applyMotionPreset(this.selectedObjectId,x)})}),this.contentContainer.querySelectorAll("[data-motion-preview]").forEach(k=>{k.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(k=>{k.addEventListener("click",async j=>{let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath;if(!x||!S)return;let E=window.getEditableObjectConfig,C=E==null?void 0:E(x);if(!C)return;let A=this.updateManager.getNestedProperty(C,S),T=Array.isArray(A)?[...A]:[];T.push({x:0,y:0}),await this.updateManager.updateProperty(x,S,T),this.loadObject(x)})}),this.contentContainer.querySelectorAll("[data-spawnpoints-remove]").forEach(k=>{k.addEventListener("click",async j=>{let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath,E=Number(L.dataset.index||"-1");if(!x||!S||E<0)return;let C=window.getEditableObjectConfig,A=C==null?void 0:C(x);if(!A)return;let T=this.updateManager.getNestedProperty(A,S);if(!Array.isArray(T))return;let O=T.filter((M,R)=>R!==E);await this.updateManager.updateProperty(x,S,O),this.loadObject(x)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-add]").forEach(k=>{k.addEventListener("click",async j=>{let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath;if(!x||!S)return;let E=window.getEditableObjectConfig,C=E==null?void 0:E(x);if(!C)return;let A=this.updateManager.getNestedProperty(C,S),T=Array.isArray(A)?[...A]:[];T.push({templateId:"",weight:1}),await this.updateManager.updateProperty(x,S,T),this.loadObject(x)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-remove]").forEach(k=>{k.addEventListener("click",async j=>{var M;let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath,E=Number((M=L.dataset.index)!=null?M:-1);if(!x||!S||E<0)return;let C=window.getEditableObjectConfig,A=C==null?void 0:C(x);if(!A)return;let T=this.updateManager.getNestedProperty(A,S);if(!Array.isArray(T))return;let O=T.filter((R,z)=>z!==E);await this.updateManager.updateProperty(x,S,O),this.loadObject(x)})}),this.contentContainer.querySelectorAll("[data-logic-add]").forEach(k=>{k.addEventListener("click",async j=>{var F;let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath;if(!x||!S)return;let E=window.getEditableObjectConfig,C=E==null?void 0:E(x);if(!C)return;let A=this.updateManager.getNestedProperty(C,S),T;Array.isArray(A)?T=[...A]:A!=null?typeof A=="string"?T=[{id:A,props:{}}]:typeof A=="object"?T=[A]:T=[]:T=[];let O=this.getDefaultLogicId(),M=window,R=(F=M==null?void 0:M.__HANDLER_LOGIC_META)==null?void 0:F[O],z=this.getDefaultPropsForLogic(O,R);T.push({id:O,props:z}),console.log("[InspectorPanel] Adding logic to array:",{objectId:x,path:S,current:A,next:T}),await this.updateManager.updateProperty(x,S,T),this.loadObject(x)})}),this.contentContainer.querySelectorAll("[data-logic-remove]").forEach(k=>{k.addEventListener("click",async j=>{var M;let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath,E=Number((M=L.dataset.index)!=null?M:-1);if(!x||!S||E<0)return;let C=window.getEditableObjectConfig,A=C==null?void 0:C(x);if(!A)return;let T=this.updateManager.getNestedProperty(A,S);if(!Array.isArray(T))return;let O=T.filter((R,z)=>z!==E);await this.updateManager.updateProperty(x,S,O),this.loadObject(x)})}),this.contentContainer.querySelectorAll("[data-logic-convert]").forEach(k=>{k.addEventListener("click",async j=>{var q,N;let L=j.target,x=L.dataset.objectId,S=L.dataset.propertyPath,E=Number((q=L.dataset.index)!=null?q:-1);if(!x||!S||E<0)return;let C=window.getEditableObjectConfig,A=C==null?void 0:C(x);if(!A)return;let T=this.updateManager.getNestedProperty(A,S);if(!Array.isArray(T))return;let O=T[E];if(typeof O!="string")return;let M=window,R=(N=M==null?void 0:M.__HANDLER_LOGIC_META)==null?void 0:N[O],z=this.getDefaultPropsForLogic(O,R),F=[...T];F[E]={id:O,props:z},await this.updateManager.updateProperty(x,S,F),this.loadObject(x)})});let m=(v=this.root)==null?void 0:v.querySelector("[data-inspector-advanced]");m==null||m.addEventListener("click",()=>{this.showAdvanced=!this.showAdvanced,this.selectedObjectId&&this.loadObject(this.selectedObjectId)});let b=(P=this.root)==null?void 0:P.querySelector("[data-convert-toggle]");b==null||b.addEventListener("click",()=>{var j;let k=(j=this.root)==null?void 0:j.querySelector("[data-convert-menu]");k==null||k.classList.toggle("hidden")});let y=(I=this.contentContainer)==null?void 0:I.querySelector("[data-inspector-add-component-btn]"),w=(_=this.contentContainer)==null?void 0:_.querySelector("[data-inspector-component-select]");y==null||y.addEventListener("click",async()=>{let k=w.value;k&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,k)})}getMotionDefaults(){var i,n,a,s;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"?(s=(a=t.motion)==null?void 0:a.defaults)!=null?s:{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(),s={...(l=n.motion)!=null?l:a},o={...(c=s.intro)!=null?c:{}};s.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",s.intro=o,await this.updateManager.updateProperty(e,"motion",s),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},s={...(l=a.intro)!=null?l:{}};a.enabled=!0,s.enabled=!0,a.intro=s,await this.updateManager.updateProperty(e,"motion",{...a,intro:{...s,enabled:!1}}),await this.updateManager.updateProperty(e,"motion",{...a,intro:{...s,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,s=a==null?void 0:a.schemas,o=null;s instanceof Map?o=s.get(t):s&&typeof s=="object"&&(o=s[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,s;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((s=(a=i.render)==null?void 0:a.asset)==null?void 0:s.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=`
1301
1301
  <div class="inspector-empty">
1302
1302
  <span class="inspector-empty-icon">\u26A0\uFE0F</span>
1303
1303
  <span class="inspector-empty-text">${e}</span>
@@ -1307,9 +1307,9 @@ ${f}
1307
1307
  <span class="inspector-empty-icon">\u{1F3AF}</span>
1308
1308
  <span class="inspector-empty-text">Select an object to inspect</span>
1309
1309
  </div>
1310
- `)}};function ca(o){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(o)})}function Ks(o){var n;let[e,t]=o.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 Xs(o){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=o})}async function Xi(o){var e,t;try{console.log("[ImageUtils] Fetching image data from URL:",o);let i=await fetch(o);if(!i.ok)return console.warn("[ImageUtils] Fetch failed with status:",i.status,o),null;let n=await i.blob();console.log("[ImageUtils] Blob received, size:",n.size,"type:",n.type);let a=await ca(n),s=await Xs(a),r=Ks(a);return console.log("[ImageUtils] Success resolution:",s==null?void 0:s.width,"x",s==null?void 0:s.height,"mime:",r.mimeType),{base64:r.base64,mimeType:r.mimeType,dataUrl:a,width:(e=s==null?void 0:s.width)!=null?e:0,height:(t=s==null?void 0:s.height)!=null?t:0}}catch(i){return console.error("[ImageUtils] Error fetching image data:",i),null}}async function Be(o){var e,t;try{let i=await ca(o),n=await Xs(i),a=Ks(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 da(o){return ca(o).then(e=>e).catch(()=>null)}function pa(o,e){var t;try{let[i,n]=o.split(","),a=i.match(/data:(.*?);base64/),s=(t=a==null?void 0:a[1])!=null?t:"image/png",r=atob(n),l=new Uint8Array(r.length);for(let c=0;c<r.length;c++)l[c]=r.charCodeAt(c);return new File([l],e,{type:s})}catch{return null}}async function ht(o,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=o}),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"),o;n.drawImage(t,0,0);let a=n.getImageData(0,0,i.width,i.height),s=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:s[p.offset],g:s[p.offset+1],b:s[p.offset+2]})),c=0;for(let p=0;p<s.length;p+=4){let u=s[p],g=s[p+1],h=s[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&&(s[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),o}}function ua(o,e){if(!o||!e)return"1:1";let t=o/e;return t>1.3?"16:9":t<.77?"9:16":"1:1"}function Me(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function ne(o){return typeof o=="string"?o:void 0}function Js(o){return o.toLowerCase().endsWith(".png")?o.slice(0,-4):o}function ol(o){var i,n,a;let e=(i=ne(o.id))!=null?i:ne(o.name);if(e)return e;let t=(n=ne(o.file))!=null?n:ne(o.asset);return t?Js((a=t.split("/").pop())!=null?a:t):void 0}function rl(o,e,t){var i,n,a;if(typeof e=="string")return{id:o,file:e,role:t};if(Me(e)){let s=(i=ne(e.file))!=null?i:ne(e.asset);return s?{id:(n=ne(e.id))!=null?n:o,file:s,role:(a=ne(e.role))!=null?a:t,dataUrl:ne(e.dataUrl),layout:e.layout}:null}return null}function ga(o,e){var t,i,n;if(!o)return[];if(Array.isArray(o)){let a=[];for(let s of o){if(typeof s=="string"){let r=Js((t=s.split("/").pop())!=null?t:s);a.push({id:r,file:s,role:e});continue}if(Me(s)){let r=ol(s),l=(i=ne(s.file))!=null?i:ne(s.asset);if(!r||!l)continue;a.push({id:r,file:l,role:(n=ne(s.role))!=null?n:e,dataUrl:ne(s.dataUrl),layout:s.layout})}}return a}if(Me(o)){let a=[];for(let[s,r]of Object.entries(o)){let l=rl(s,r,e);l&&a.push(l)}return a}return[]}function ll(o){var e,t;return(t=(e=ne(o.brand_name))!=null?e:ne(o.brandName))!=null?t:ne(o.name)}function cl(o){if(Me(o.brand_dna)&&Me(o.brand_dna.colors))return o.brand_dna;if(Me(o.colors)){let e={colors:o.colors};return typeof o.style=="string"&&(e.style=o.style),Me(o.fonts)&&(e.fonts=o.fonts),e}}function dl(o){var t;let e=new Map;for(let i of o){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 Zs(o,e={}){var s,r,l;let t=o.filter(Me),i=(r=(s=t.map(ll).find(Boolean))!=null?s:e.defaultBrandName)!=null?r:"Imported Brand",n=(l=t.map(cl).find(Boolean))!=null?l:{colors:{}},a=[];for(let c of t)"layers"in c&&a.push(...ga(c.layers,"visual element")),"assets"in c&&a.push(...ga(c.assets,"visual element")),Me(c.endgame)&&"assets"in c.endgame&&a.push(...ga(c.endgame.assets,"endgame"));return{version:"1.0",brand_name:i,brand_dna:n,assets:dl(a)}}var Qs=require("@google/genai");async function Ji(o,e,t=[],i={}){var n,a,s,r,l,c,d;try{if(!(o!=null&&o.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 Qs.GoogleGenAI({apiKey:o}),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=(s=(a=(n=h.candidates)==null?void 0:n[0])==null?void 0:a.content)==null?void 0:s.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),(r=p.message)!=null&&r.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 eo=require("@google/genai");async function ft(o,e,t=[],i={}){try{console.info("[GEMINI-REAL-SDK] Initializing GoogleGenAI...");let n=new eo.GoogleGenAI({apiKey:o}),a=[{text:e}];t.length>0&&t.forEach((r,l)=>{console.info(`[GEMINI-REAL-SDK] Adding image part ${l}`),a.push({inlineData:{mimeType:r.mimeType,data:r.base64}})}),console.info("[GEMINI-REAL-SDK] Calling generateContent with model: gemini-2.5-flash-image");let s=await n.models.generateContent({model:"gemini-2.5-flash-image",contents:a});if(console.info("[GEMINI-REAL-SDK] Received response from model"),!s.candidates||!s.candidates[0]||!s.candidates[0].content||!s.candidates[0].content.parts)throw new Error("Gemini 2.5 Flash Image returned invalid response structure.");for(let r of s.candidates[0].content.parts)if(r.text)console.log(r.text);else if(r.inlineData){let l=r.inlineData.data,c=r.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 to(o){let e=o.brandAssets.map(a=>{let s=`- ${a.id}: ${a.role}`;return a.layout&&(s+=` [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}]`),s}).join(`
1311
- `)||"None",t=o.brandDna?`Colors: ${JSON.stringify(o.brandDna.colors)}, Style: ${o.brandDna.style||"not specified"}`:"Not provided",i=o.gameObjects.map(a=>typeof a=="string"?`- id: ${a}`:`- id: ${a.id}${a.category?`, category: ${a.category}`:""}${a.type?`, type: ${a.type}`:""}`).join(`
1312
- `),n="";if(o.brandConfig){let a=o.brandConfig,s=[];a.splash&&s.push(`SPLASH: title="${a.splash.title||""}", subtitle="${a.splash.subtitle||""}", button="${a.splash.button_label||""}"`),a.endgame&&s.push(`ENDGAME: title="${a.endgame.title||""}", subtitle="${a.endgame.subtitle||""}", cta="${a.endgame.cta_label||""}"`),a.tutorial&&s.push(`TUTORIAL: text="${a.tutorial.label_text||""}", helper="${a.tutorial.helper_text||""}"`),s.length>0&&(n=`
1310
+ `)}};function da(r){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(r)})}function Xs(r){var n;let[e,t]=r.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 Js(r){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=r})}async function Ji(r){var e,t;try{console.log("[ImageUtils] Fetching image data from URL:",r);let i=await fetch(r);if(!i.ok)return console.warn("[ImageUtils] Fetch failed with status:",i.status,r),null;let n=await i.blob();console.log("[ImageUtils] Blob received, size:",n.size,"type:",n.type);let a=await da(n),s=await Js(a),o=Xs(a);return console.log("[ImageUtils] Success resolution:",s==null?void 0:s.width,"x",s==null?void 0:s.height,"mime:",o.mimeType),{base64:o.base64,mimeType:o.mimeType,dataUrl:a,width:(e=s==null?void 0:s.width)!=null?e:0,height:(t=s==null?void 0:s.height)!=null?t:0}}catch(i){return console.error("[ImageUtils] Error fetching image data:",i),null}}async function Ge(r){var e,t;try{let i=await da(r),n=await Js(i),a=Xs(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 pa(r){return da(r).then(e=>e).catch(()=>null)}function ua(r,e){var t;try{let[i,n]=r.split(","),a=i.match(/data:(.*?);base64/),s=(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:s})}catch{return null}}async function ft(r,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=r}),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"),r;n.drawImage(t,0,0);let a=n.getImageData(0,0,i.width,i.height),s=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:s[p.offset],g:s[p.offset+1],b:s[p.offset+2]})),c=0;for(let p=0;p<s.length;p+=4){let u=s[p],g=s[p+1],h=s[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&&(s[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),r}}function ga(r,e){if(!r||!e)return"1:1";let t=r/e;return t>1.3?"16:9":t<.77?"9:16":"1:1"}function je(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function se(r){return typeof r=="string"?r:void 0}function Zs(r){return r.toLowerCase().endsWith(".png")?r.slice(0,-4):r}function ol(r){var i,n,a;let e=(i=se(r.id))!=null?i:se(r.name);if(e)return e;let t=(n=se(r.file))!=null?n:se(r.asset);return t?Zs((a=t.split("/").pop())!=null?a:t):void 0}function ll(r,e,t){var i,n,a;if(typeof e=="string")return{id:r,file:e,role:t};if(je(e)){let s=(i=se(e.file))!=null?i:se(e.asset);return s?{id:(n=se(e.id))!=null?n:r,file:s,role:(a=se(e.role))!=null?a:t,dataUrl:se(e.dataUrl),layout:e.layout}:null}return null}function ha(r,e){var t,i,n;if(!r)return[];if(Array.isArray(r)){let a=[];for(let s of r){if(typeof s=="string"){let o=Zs((t=s.split("/").pop())!=null?t:s);a.push({id:o,file:s,role:e});continue}if(je(s)){let o=ol(s),l=(i=se(s.file))!=null?i:se(s.asset);if(!o||!l)continue;a.push({id:o,file:l,role:(n=se(s.role))!=null?n:e,dataUrl:se(s.dataUrl),layout:s.layout})}}return a}if(je(r)){let a=[];for(let[s,o]of Object.entries(r)){let l=ll(s,o,e);l&&a.push(l)}return a}return[]}function cl(r){var e,t;return(t=(e=se(r.brand_name))!=null?e:se(r.brandName))!=null?t:se(r.name)}function dl(r){if(je(r.brand_dna)&&je(r.brand_dna.colors))return r.brand_dna;if(je(r.colors)){let e={colors:r.colors};return typeof r.style=="string"&&(e.style=r.style),je(r.fonts)&&(e.fonts=r.fonts),e}}function pl(r){var t;let e=new Map;for(let i of r){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 Qs(r,e={}){var s,o,l;let t=r.filter(je),i=(o=(s=t.map(cl).find(Boolean))!=null?s:e.defaultBrandName)!=null?o:"Imported Brand",n=(l=t.map(dl).find(Boolean))!=null?l:{colors:{}},a=[];for(let c of t)"layers"in c&&a.push(...ha(c.layers,"visual element")),"assets"in c&&a.push(...ha(c.assets,"visual element")),je(c.endgame)&&"assets"in c.endgame&&a.push(...ha(c.endgame.assets,"endgame"));return{version:"1.0",brand_name:i,brand_dna:n,assets:pl(a)}}var er=require("@google/genai");async function Zi(r,e,t=[],i={}){var n,a,s,o,l,c,d;try{if(!(r!=null&&r.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 er.GoogleGenAI({apiKey:r}),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=(s=(a=(n=h.candidates)==null?void 0:n[0])==null?void 0:a.content)==null?void 0:s.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 tr=require("@google/genai");async function mt(r,e,t=[],i={}){try{console.info("[GEMINI-REAL-SDK] Initializing GoogleGenAI...");let n=new tr.GoogleGenAI({apiKey:r}),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 s=await n.models.generateContent({model:"gemini-2.5-flash-image",contents:a});if(console.info("[GEMINI-REAL-SDK] Received response from model"),!s.candidates||!s.candidates[0]||!s.candidates[0].content||!s.candidates[0].content.parts)throw new Error("Gemini 2.5 Flash Image returned invalid response structure.");for(let o of s.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 ir(r){let e=r.brandAssets.map(a=>{let s=`- ${a.id}: ${a.role}`;return a.layout&&(s+=` [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}]`),s}).join(`
1311
+ `)||"None",t=r.brandDna?`Colors: ${JSON.stringify(r.brandDna.colors)}, Style: ${r.brandDna.style||"not specified"}`:"Not provided",i=r.gameObjects.map(a=>typeof a=="string"?`- id: ${a}`:`- id: ${a.id}${a.category?`, category: ${a.category}`:""}${a.type?`, type: ${a.type}`:""}`).join(`
1312
+ `),n="";if(r.brandConfig){let a=r.brandConfig,s=[];a.splash&&s.push(`SPLASH: title="${a.splash.title||""}", subtitle="${a.splash.subtitle||""}", button="${a.splash.button_label||""}"`),a.endgame&&s.push(`ENDGAME: title="${a.endgame.title||""}", subtitle="${a.endgame.subtitle||""}", cta="${a.endgame.cta_label||""}"`),a.tutorial&&s.push(`TUTORIAL: text="${a.tutorial.label_text||""}", helper="${a.tutorial.helper_text||""}"`),s.length>0&&(n=`
1313
1313
  BRAND CONTENT:
1314
1314
  ${s.join(`
1315
1315
  `)}
@@ -1317,7 +1317,7 @@ ${s.join(`
1317
1317
  You are analyzing a brand's visual design for use in a playable ad game.
1318
1318
 
1319
1319
  GAME CONTEXT:
1320
- ${o.gamePrompt||"Simple game"}
1320
+ ${r.gamePrompt||"Simple game"}
1321
1321
 
1322
1322
  GAME OBJECTS (need assets):
1323
1323
  ${i}
@@ -1371,28 +1371,28 @@ OUTPUT ONLY VALID JSON (no markdown, no explanation):
1371
1371
  }
1372
1372
  ]
1373
1373
  }
1374
- `.trim()}function io(o){var n,a;let e=(n=o.brandDna)!=null&&n.colors?`Primary: ${o.brandDna.colors.primary}, Secondary: ${o.brandDna.colors.secondary||"N/A"}, Accent: ${o.brandDna.colors.accent||"N/A"}`:"Use provided reference colors",t=((a=o.brandDna)==null?void 0:a.style)||"modern gaming style",i=o.needsTransparency?"BACKGROUND: REQUIRED solid magenta #FF00FF (for transparency removal)":"BACKGROUND: Use brand colors naturally, fill the entire frame";return`
1375
- TASK: ${o.prompt}
1374
+ `.trim()}function nr(r){var n,a;let e=(n=r.brandDna)!=null&&n.colors?`Primary: ${r.brandDna.colors.primary}, Secondary: ${r.brandDna.colors.secondary||"N/A"}, Accent: ${r.brandDna.colors.accent||"N/A"}`:"Use provided reference colors",t=((a=r.brandDna)==null?void 0:a.style)||"modern gaming style",i=r.needsTransparency?"BACKGROUND: REQUIRED solid magenta #FF00FF (for transparency removal)":"BACKGROUND: Use brand colors naturally, fill the entire frame";return`
1375
+ TASK: ${r.prompt}
1376
1376
 
1377
1377
  BRAND STYLE:
1378
1378
  - Colors: ${e}
1379
1379
  - Style: ${t}
1380
1380
 
1381
1381
  CHANGE_STRENGTH: 8/10
1382
- REFERENCE: ${o.hasReference?"provided (use as style guide for colors and aesthetics)":"none"}
1382
+ REFERENCE: ${r.hasReference?"provided (use as style guide for colors and aesthetics)":"none"}
1383
1383
  ${i}
1384
1384
 
1385
1385
  OUTPUT CONSTRAINTS (MUST FOLLOW):
1386
1386
  - Do NOT add extra text unless specifically requested
1387
- - Preserve aspect ratio${o.aspectRatio?` (target: ${o.aspectRatio})`:""}
1387
+ - Preserve aspect ratio${r.aspectRatio?` (target: ${r.aspectRatio})`:""}
1388
1388
  - Keep padding under 5% of asset size
1389
1389
  - No drop shadows unless explicitly requested
1390
- - No gradients on the background (solid ${o.needsTransparency?"magenta":"colors"} only)
1390
+ - No gradients on the background (solid ${r.needsTransparency?"magenta":"colors"} only)
1391
1391
  - Center the subject in frame
1392
1392
 
1393
1393
  OUTPUT:
1394
- Generate the requested asset matching the brand style.${o.needsTransparency?" Background MUST be solid magenta (#FF00FF).":""}
1395
- `.trim()}function no(o){return o.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 ao(o,e){return!(o.includes("background")&&(o.includes("_1")||o.includes("splash")||o.includes("endgame")||o.includes("main"))||e==="text"||e==="effects"&&o.includes("particle"))}async function so(o){var s,r;let e=no(o.gameObjects),t={gamePrompt:o.gamePrompt,gameObjects:e,brandAssets:o.manifest.assets,brandDna:o.manifest.brand_dna,brandName:o.manifest.brand_name},i=to(t),n=[];if(o.flatDesignDataUrl)try{let l=oo(o.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 Ji(o.apiKey,i,n,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(s=l.message)!=null&&s.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."):(r=l.message)!=null&&r.includes("image")?new Error("Image processing failed. Please ensure your images are valid and not corrupted."):l}return pl(a,o.gameObjects)}function pl(o,e){try{let t=o,i=o.match(/```(?:json)?\s*([\s\S]*?)```/);if(i)t=i[1].trim();else{let a=o.match(/\{[\s\S]*\}/);a&&(t=a[0])}let n=JSON.parse(t);return n.mappings&&Array.isArray(n.mappings)?{mappingResult:n,rawResponse:o,parsed:!0}:{mappingResult:{mappings:e.map(a=>({game_object:a,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:o,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:o,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function ha(o,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 s=i[a];(n=t.onProgress)==null||n.call(t,a+1,i.length,s.game_object);try{let r=await ul(o,s);s.output_dataUrl=r,s.status="Generated \u2713"}catch(r){console.error(`[Pipeline] Failed to generate ${s.game_object}:`,r),s.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function ul(o,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&o.manifest){let r=o.manifest.assets.find(l=>l.id===e.reference_asset);if(r){let l=o.assetFiles.get(r.file);if(l){let c=await Be(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(o.flatDesignDataUrl){let r=oo(o.flatDesignDataUrl);r&&t.push(r)}let i=ao(e.game_object),n={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:o.manifest.brand_dna,needsTransparency:i},a=io(n);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${i})`);let s=await ft(o.apiKey,a,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return i&&await ht(s)||s}function oo(o){let[e,t]=o.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return t&&i?{base64:t,mimeType:i[1]}:null}async function ro(o,e){let t=o.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=[],o.assets=i;for(let n of i){let a=e.get(n.file);if(a){let s=await Be(a);s&&(n.dataUrl=s.dataUrl)}}}function lo(o){var t,i;let e=new Map;if(!o)return console.warn("[CanvaZip] No position data provided"),e;if(typeof o=="string")try{o=JSON.parse(o)}catch(n){return console.error("[CanvaZip] Failed to parse position data JSON:",n),e}if(o!=null&&o.layers&&Array.isArray(o.layers)){console.log(`[CanvaZip] Parsing ${o.layers.length} layers from position data`);for(let n of o.layers){let a=n.asset;if(!a||!n.layout){console.warn("[CanvaZip] Skipping layer without asset or layout:",n);continue}let s=n.layout,r={x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0},l=typeof s.scaleX=="number"?s.scaleX:1,c=typeof s.scaleY=="number"?s.scaleY:1,d=(l+c)/2;d>1&&(d=d/13.33);let p=typeof s.rotation=="number"?s.rotation:0;e.set(a,{position:r,scale:d,rotation:p}),console.log(`[CanvaZip] Parsed position for ${a}:`,{position:r,scale:d,rotation:p})}console.log(`[CanvaZip] Successfully parsed ${e.size} assets from position data`)}else console.warn("[CanvaZip] Position data does not have layers array:",o);if(e.size===0&&typeof o=="object"&&!Array.isArray(o)){for(let[n,a]of Object.entries(o))if(a&&typeof a=="object"&&"layout"in a){let s=a.layout,r={x:0,y:0},l=1,c=0;if(s.position&&typeof s.position=="object"?r={x:s.position.x||0,y:s.position.y||0}:(typeof s.x=="number"||typeof s.y=="number")&&(r={x:s.x||0,y:s.y||0}),typeof s.scale=="number")l=s.scale;else if(typeof s.scaleX=="number"||typeof s.scaleY=="number"){let d=(t=s.scaleX)!=null?t:1,p=(i=s.scaleY)!=null?i:1;l=(d+p)/2}typeof s.rotation=="number"&&(c=s.rotation),e.set(n,{position:r,scale:l,rotation:c})}}return e}function co(o,e){if(!o)return console.warn("[CanvaZip] No filename provided for matching"),null;if(e.size===0)return console.warn("[CanvaZip] Position map is empty, cannot match:",o),null;if(e.has(o))return console.log(`[CanvaZip] Exact match found for ${o}`),e.get(o);let t=o.replace(/\.png$/i,"").replace(/\.jpg$/i,"").replace(/\.jpeg$/i,"");if(e.has(t))return console.log(`[CanvaZip] Match found (without extension) for ${o} -> ${t}`),e.get(t);let i=t.toLowerCase();for(let[n,a]of e.entries()){let s=n.toLowerCase();if(s===i||s.includes(i)||i.includes(s))return console.log(`[CanvaZip] Partial match found for ${o} -> ${n}`),a}return console.warn(`[CanvaZip] No match found for ${o}. Available keys:`,Array.from(e.keys()).slice(0,5)),null}function gl(o){return o.replace(/^json\./,"").replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase())}function po(){let o=window.getEditableAssets;if(typeof o!="function")return console.warn("[CanvaZip] getEditableAssets not available"),[];let e=o();if(!(e!=null&&e.slots)||!Array.isArray(e.slots))return console.warn("[CanvaZip] No slots found in registry"),[];let t=[];for(let i of e.slots)i.assetType==="image"&&i.objectId&&t.push({id:i.objectId,name:i.displayName||gl(i.slotId||i.objectId),type:"sprite"});return t.sort((i,n)=>i.name.localeCompare(n.name))}var mt=require("pixi.js");ct();ri();Q();async function go(o,e,t){var i,n;console.log("[LIBRARY] applyAssetChange called with:",e,t);try{let a=Date.now(),r=`/${`raw/library/${e}/${t}`}?t=${a}`;console.log("[LIBRARY] Loading texture from:",r);let l=await mt.Assets.load(r);if(!l){console.error("[LIBRARY] Failed to load texture:",r);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)we[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 ho(o,e){var t,i,n;console.log("[LIBRARY] resetAsset called for:",e);try{let a=window.getEditableAssets,s=typeof a=="function"?a():null,r=(t=s==null?void 0:s.slots)==null?void 0:t.find(m=>m.category===e),l=r==null?void 0:r.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 mt.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)we[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 Zi(o,e,t,i){var n,a,s,r,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=mo(v),I=Date.now(),P=`/raw/library/${i}/${t}?t=${I}`;console.log("[LIBRARY] Loading texture from:",P);try{let x=await fetch(P,{method:"HEAD"});if(x.ok){let E=x.headers.get("content-type");console.log("[LIBRARY] File accessible, Content-Type:",E)}else{console.error("[LIBRARY] \u274C File not accessible:",P,"Status:",x.status);let E=await fetch(P),S=E.headers.get("content-type");if(console.error("[LIBRARY] Content-Type:",S,"Status:",E.status),!E.ok)throw new Error(`File not accessible: ${E.status} ${E.statusText}`)}}catch(x){console.error("[LIBRARY] \u274C Failed to verify file accessibility:",x)}let _;try{if(_=await mt.Assets.load(P),!_){console.error("[LIBRARY] \u274C Assets.load returned null/undefined for:",P);return}console.log("[LIBRARY] \u2705 Texture loaded successfully"),console.log("[LIBRARY] Texture dimensions:",_.width,"x",_.height)}catch(x){console.error("[LIBRARY] \u274C Assets.load failed for:",P),console.error("[LIBRARY] Error details:",x),console.error("[LIBRARY] Error message:",x instanceof Error?x.message:String(x)),console.error("[LIBRARY] Error stack:",x instanceof Error?x.stack:"No stack");try{let S=await(await fetch(P)).blob();console.log("[LIBRARY] Direct fetch successful, blob size:",S.size,"bytes, type:",S.type);let O=new Image,j=URL.createObjectURL(S);await new Promise((R,z)=>{O.onload=()=>{console.log("[LIBRARY] \u2705 Image decoded successfully via Image API, dimensions:",O.width,"x",O.height),URL.revokeObjectURL(j),R(null)},O.onerror=D=>{console.error("[LIBRARY] \u274C Image API also failed to decode:",D),URL.revokeObjectURL(j),z(D)},O.src=j}),console.log("[LIBRARY] \u26A0\uFE0F Image is valid via Image API but PixiJS Assets.load failed. This might be a PixiJS-specific issue.")}catch(E){console.error("[LIBRARY] \u274C Image verification also failed:",E)}throw x}we[v]=_,console.log("[LIBRARY] \u2705 Updated AssetTextures."+v);let T=window.CustomAssets;T!=null&&T[v]&&(T[v].texture=_,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+v));let M=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!M),M){let x=Array.from(((n=M.keys)==null?void 0:n.call(M))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",x);let E=M.get(v);if(console.log("[LIBRARY] gameObject for "+v+"?",!!E),E){let S=((a=E.getDisplayObject)==null?void 0:a.call(E))||E.pixiObject||E.pixi||E,O=(s=S==null?void 0:S.constructor)==null?void 0:s.name;if(console.log("[LIBRARY] displayObject:",S),console.log("[LIBRARY] displayObject type:",O),console.log("[LIBRARY] has texture?",!!(S!=null&&S.texture)),S!=null&&S.texture)S.texture=_,console.log("[LIBRARY] \u2705 Applied to display object:",v);else if(O==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:j}=await import("pixi.js"),R=S.parent,z=(l=(r=R==null?void 0:R.getChildIndex)==null?void 0:r.call(R,S))!=null?l:0,D={x:S.x,y:S.y},q={x:(d=(c=S.anchor)==null?void 0:c.x)!=null?d:.5,y:(u=(p=S.anchor)==null?void 0:p.y)!=null?u:.5},G={x:(h=(g=S.scale)==null?void 0:g.x)!=null?h:1,y:(m=(f=S.scale)==null?void 0:f.y)!=null?m:1},B=(b=S.alpha)!=null?b:1,F=(y=S.visible)!=null?y:!0,U=new j(_);U.anchor.set(q.x,q.y),U.position.set(D.x,D.y),U.scale.set(G.x,G.y),U.alpha=B,U.visible=F,R&&(R.removeChild(S),R.addChildAt(U,z),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),E.pixiObject&&(E.pixiObject=U),E.pixi&&(E.pixi=U),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if(S!=null&&S.children){let j=S.children.find(R=>R.texture);j?(j.texture=_,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let k=`raw/library/${i}/${t}`;bo(v,k,_,w),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:v,texture:_,assetPath:k}})),console.log("[LIBRARY] \u{1F4DD} Applying config override:",{objectId:v,path:"render.asset.path",value:k,persist:!0,emitEvent:!0});let A=hl(w);console.log("[LIBRARY] Objects using the same asset path:",{previousPath:w,count:A.length,objectIds:A}),oe({objectId:v,path:"render.asset.path",value:k},{persist:!0,emitEvent:!0});for(let x of A)x!==v&&(console.log(`[LIBRARY] \u{1F504} Also applying override to shared object: ${x}`),oe({objectId:x,path:"render.asset.path",value:k},{persist:!0,emitEvent:!0}));let C=window.__configOverrides||[],L=C.find(x=>x.objectId===v&&x.path==="render.asset.path");L?console.log("[LIBRARY] \u2705 Override confirmed in localStorage:",{objectId:L.objectId,path:L.path,value:L.value,totalOverrides:C.length,sharedObjectsUpdated:A.length-1}):console.error("[LIBRARY] \u274C Override NOT found in localStorage after save!"),console.log("[LIBRARY] \u2705 Staged config override for:",v,"path:",k)}catch(v){console.error("[LIBRARY] Error applying slot asset:",v)}}async function fo(o,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,s=mo(a),r=Date.now(),l=`/raw/${t}?t=${r}`;console.log("[LIBRARY] Loading default texture from:",l);let c=await mt.Assets.load(l);if(!c){console.error("[LIBRARY] Failed to load default texture:",l);return}we[a]=c,console.log("[LIBRARY] \u2705 Reset AssetTextures."+a);let d=window.CustomAssets;d!=null&&d[a]&&(d[a].texture=c,console.log("[LIBRARY] \u2705 Reset CustomAssets."+a+" to default"));let p=window.gameObjectManager;if(p){let u=p.get(a);if(u){let g=((n=u.getDisplayObject)==null?void 0:n.call(u))||u.pixiObject||u;g!=null&&g.texture&&(g.texture=c,console.log("[LIBRARY] \u2705 Reset display object:",a))}}bo(a,t,c,s),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:a,texture:c,assetPath:t}})),oe({objectId:a,path:"render.asset.path",value:t},{persist:!0,emitEvent:!0}),console.log("[LIBRARY] \u2705 Reset config override for:",a)}catch(a){console.error("[LIBRARY] Error resetting slot asset:",a)}}function mo(o){var e,t,i;try{let n=window.getEditableObjectConfig,a=typeof n=="function"?n(o):null;return(i=(t=(e=a==null?void 0:a.render)==null?void 0:e.asset)==null?void 0:t.path)!=null?i:null}catch{return null}}function hl(o){var t,i;if(!o)return[];let e=[];try{let n=window.getEditableObjectList,a=typeof n=="function"?n():[];if(!Array.isArray(a)||a.length===0){let r=window.__editableConfig;r!=null&&r.objects&&(r.objects instanceof Map?a.push(...Array.from(r.objects.keys())):typeof r.objects=="object"&&a.push(...Object.keys(r.objects)))}let s=window.getEditableObjectConfig;for(let r of a)try{let l=typeof s=="function"?s(r):null,c=(i=(t=l==null?void 0:l.render)==null?void 0:t.asset)==null?void 0:i.path,d=o.replace(/^\/+/,"").replace(/\\/g,"/");(c==null?void 0:c.replace(/^\/+/,"").replace(/\\/g,"/"))===d&&e.push(r)}catch(l){console.warn(`[LIBRARY] Failed to check asset path for object ${r}:`,l)}console.log(`[LIBRARY] Found ${e.length} objects using asset path: ${o}`,e)}catch(n){console.error("[LIBRARY] Error finding objects using asset path:",n)}return e}function bo(o,e,t,i){if(e){try{let n=`${o}:${e}`;ce.set(n,t)}catch{}if(i&&i!==e)try{let n=ce.store;n!=null&&n.delete&&n.delete(`${o}:${i}`)}catch{}uo(e,t),i&&i!==e&&uo(i,null)}}function uo(o,e){if(!o)return;let t=mt.Assets.cache;if(!t)return;let i=o.replace(/^\.?\//,""),n=[i,`/${i}`];for(let a of n)typeof t.remove=="function"?t.remove(a):typeof t.delete=="function"&&t.delete(a),e&&typeof t.set=="function"&&t.set(a,e)}var Qi=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`
1394
+ Generate the requested asset matching the brand style.${r.needsTransparency?" Background MUST be solid magenta (#FF00FF).":""}
1395
+ `.trim()}function ar(r){return r.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 sr(r,e){return!(r.includes("background")&&(r.includes("_1")||r.includes("splash")||r.includes("endgame")||r.includes("main"))||e==="text"||e==="effects"&&r.includes("particle"))}async function rr(r){var s,o;let e=ar(r.gameObjects),t={gamePrompt:r.gamePrompt,gameObjects:e,brandAssets:r.manifest.assets,brandDna:r.manifest.brand_dna,brandName:r.manifest.brand_name},i=ir(t),n=[];if(r.flatDesignDataUrl)try{let l=or(r.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 Zi(r.apiKey,i,n,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(s=l.message)!=null&&s.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 ul(a,r.gameObjects)}function ul(r,e){try{let t=r,i=r.match(/```(?:json)?\s*([\s\S]*?)```/);if(i)t=i[1].trim();else{let a=r.match(/\{[\s\S]*\}/);a&&(t=a[0])}let n=JSON.parse(t);return n.mappings&&Array.isArray(n.mappings)?{mappingResult:n,rawResponse:r,parsed:!0}:{mappingResult:{mappings:e.map(a=>({game_object:a,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:r,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:r,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function fa(r,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 s=i[a];(n=t.onProgress)==null||n.call(t,a+1,i.length,s.game_object);try{let o=await gl(r,s);s.output_dataUrl=o,s.status="Generated \u2713"}catch(o){console.error(`[Pipeline] Failed to generate ${s.game_object}:`,o),s.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function gl(r,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&r.manifest){let o=r.manifest.assets.find(l=>l.id===e.reference_asset);if(o){let l=r.assetFiles.get(o.file);if(l){let c=await Ge(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(r.flatDesignDataUrl){let o=or(r.flatDesignDataUrl);o&&t.push(o)}let i=sr(e.game_object),n={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:r.manifest.brand_dna,needsTransparency:i},a=nr(n);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${i})`);let s=await mt(r.apiKey,a,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return i&&await ft(s)||s}function or(r){let[e,t]=r.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return t&&i?{base64:t,mimeType:i[1]}:null}async function lr(r,e){let t=r.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=[],r.assets=i;for(let n of i){let a=e.get(n.file);if(a){let s=await Ge(a);s&&(n.dataUrl=s.dataUrl)}}}function cr(r){var t,i;let e=new Map;if(!r)return console.warn("[CanvaZip] No position data provided"),e;if(typeof r=="string")try{r=JSON.parse(r)}catch(n){return console.error("[CanvaZip] Failed to parse position data JSON:",n),e}if(r!=null&&r.layers&&Array.isArray(r.layers)){console.log(`[CanvaZip] Parsing ${r.layers.length} layers from position data`);for(let n of r.layers){let a=n.asset;if(!a||!n.layout){console.warn("[CanvaZip] Skipping layer without asset or layout:",n);continue}let s=n.layout,o={x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0},l=typeof s.scaleX=="number"?s.scaleX:1,c=typeof s.scaleY=="number"?s.scaleY:1,d=(l+c)/2;d>1&&(d=d/13.33);let p=typeof s.rotation=="number"?s.rotation:0;e.set(a,{position:o,scale:d,rotation:p}),console.log(`[CanvaZip] Parsed position for ${a}:`,{position:o,scale:d,rotation:p})}console.log(`[CanvaZip] Successfully parsed ${e.size} assets from position data`)}else console.warn("[CanvaZip] Position data does not have layers array:",r);if(e.size===0&&typeof r=="object"&&!Array.isArray(r)){for(let[n,a]of Object.entries(r))if(a&&typeof a=="object"&&"layout"in a){let s=a.layout,o={x:0,y:0},l=1,c=0;if(s.position&&typeof s.position=="object"?o={x:s.position.x||0,y:s.position.y||0}:(typeof s.x=="number"||typeof s.y=="number")&&(o={x:s.x||0,y:s.y||0}),typeof s.scale=="number")l=s.scale;else if(typeof s.scaleX=="number"||typeof s.scaleY=="number"){let d=(t=s.scaleX)!=null?t:1,p=(i=s.scaleY)!=null?i:1;l=(d+p)/2}typeof s.rotation=="number"&&(c=s.rotation),e.set(n,{position:o,scale:l,rotation:c})}}return e}function dr(r,e){if(!r)return console.warn("[CanvaZip] No filename provided for matching"),null;if(e.size===0)return console.warn("[CanvaZip] Position map is empty, cannot match:",r),null;if(e.has(r))return console.log(`[CanvaZip] Exact match found for ${r}`),e.get(r);let t=r.replace(/\.png$/i,"").replace(/\.jpg$/i,"").replace(/\.jpeg$/i,"");if(e.has(t))return console.log(`[CanvaZip] Match found (without extension) for ${r} -> ${t}`),e.get(t);let i=t.toLowerCase();for(let[n,a]of e.entries()){let s=n.toLowerCase();if(s===i||s.includes(i)||i.includes(s))return console.log(`[CanvaZip] Partial match found for ${r} -> ${n}`),a}return console.warn(`[CanvaZip] No match found for ${r}. Available keys:`,Array.from(e.keys()).slice(0,5)),null}function hl(r){return r.replace(/^json\./,"").replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase())}function pr(){let r=window.getEditableAssets;if(typeof r!="function")return console.warn("[CanvaZip] getEditableAssets not available"),[];let e=r();if(!(e!=null&&e.slots)||!Array.isArray(e.slots))return console.warn("[CanvaZip] No slots found in registry"),[];let t=[];for(let i of e.slots)i.assetType==="image"&&i.objectId&&t.push({id:i.objectId,name:i.displayName||hl(i.slotId||i.objectId),type:"sprite"});return t.sort((i,n)=>i.name.localeCompare(n.name))}var bt=require("pixi.js");dt();li();ne();async function gr(r,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 bt.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)xe[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 hr(r,e){var t,i,n;console.log("[LIBRARY] resetAsset called for:",e);try{let a=window.getEditableAssets,s=typeof a=="function"?a():null,o=(t=s==null?void 0:s.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 bt.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)xe[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)}}var Qi=new Map;async function en(r,e,t,i){let a=`${e.startsWith("json.")?e.replace("json.",""):e}:${t}`;if(Qi.has(a)){console.log(`[LIBRARY] \u23F3 Operation already in progress for ${a}, waiting...`);try{await Qi.get(a),console.log("[LIBRARY] \u2705 Previous operation completed, current apply should be redundant");return}catch(o){console.warn("[LIBRARY] Previous operation failed, proceeding with new apply:",o)}}let s=(async()=>{var o,l,c,d,p,u,g,h,f,m,b,y,w,v,P;console.log("[LIBRARY] applySlotAsset called:",{objectId:e,assetFilename:t,category:i});try{let I=e.startsWith("json.")?e.replace("json.",""):e;console.log("[LIBRARY] Asset key derived:",I,"(from objectId:",e+")");let k=(window.__configOverrides||[]).filter(N=>N.path==="render.asset.path"&&N.objectId!==I&&N.value&&N.value.includes(t));k.length>0&&(console.log("[LIBRARY] \u26A0\uFE0F WARNING: Other objects already using this asset:",{assetFilename:t,currentObject:I,otherObjects:k.map(N=>({objectId:N.objectId,assetPath:N.value}))}),console.log("[LIBRARY] This is OK - each object will have its own override entry"));let j=mr(I),L=Date.now(),x=`/raw/library/${i}/${t}?t=${L}`;console.log("[LIBRARY] Loading texture from:",x);try{let N=await fetch(x,{method:"HEAD"});if(N.ok){let H=N.headers.get("content-type");console.log("[LIBRARY] File accessible, Content-Type:",H)}else{console.error("[LIBRARY] \u274C File not accessible:",x,"Status:",N.status);let H=await fetch(x),$=H.headers.get("content-type");if(console.error("[LIBRARY] Content-Type:",$,"Status:",H.status),!H.ok)throw new Error(`File not accessible: ${H.status} ${H.statusText}`)}}catch(N){console.error("[LIBRARY] \u274C Failed to verify file accessibility:",N)}let S,E=3,C=0,A=null;for(;C<E&&!S;)try{C++,console.log(`[LIBRARY] Loading texture attempt ${C}/${E}:`,x);let N=`${x}${x.includes("?")?"&":"?"}retry=${C}`;if(S=await bt.Assets.load(N),!S)throw new Error("Assets.load returned null/undefined");console.log("[LIBRARY] \u2705 Texture loaded successfully"),console.log("[LIBRARY] Texture dimensions:",S.width,"x",S.height);break}catch(N){if(A=N,console.warn(`[LIBRARY] \u26A0\uFE0F Texture load attempt ${C} failed:`,N instanceof Error?N.message:String(N)),C<E){let H=Math.min(300*C,1e3);console.log(`[LIBRARY] Waiting ${H}ms before retry...`),await new Promise($=>setTimeout($,H))}}if(!S)try{console.error("[LIBRARY] \u274C Assets.load failed for:",x),console.error("[LIBRARY] Error details:",A),console.error("[LIBRARY] Error message:",A instanceof Error?A.message:String(A)),console.error("[LIBRARY] Error stack:",A instanceof Error?A.stack:"No stack");try{let H=await(await fetch(x)).blob();console.log("[LIBRARY] Direct fetch successful, blob size:",H.size,"bytes, type:",H.type);let $=new Image,U=URL.createObjectURL(H);await new Promise((Y,V)=>{$.onload=()=>{console.log("[LIBRARY] \u2705 Image decoded successfully via Image API, dimensions:",$.width,"x",$.height),URL.revokeObjectURL(U),Y(null)},$.onerror=G=>{console.error("[LIBRARY] \u274C Image API also failed to decode:",G),URL.revokeObjectURL(U),V(G)},$.src=U}),console.log("[LIBRARY] \u26A0\uFE0F Image is valid via Image API but PixiJS Assets.load failed. This might be a PixiJS-specific issue.")}catch(N){console.error("[LIBRARY] \u274C Image verification also failed:",N)}throw new Error(`Failed to load texture after ${E} attempts: ${A instanceof Error?A.message:String(A)}`)}catch(N){throw N}xe[I]=S,console.log("[LIBRARY] \u2705 Updated AssetTextures."+I);let T=window.CustomAssets;T!=null&&T[I]&&(T[I].texture=S,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+I));let O=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!O),O){let N=Array.from(((o=O.keys)==null?void 0:o.call(O))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",N);let H=O.get(I);if(console.log("[LIBRARY] gameObject for "+I+"?",!!H),H){let $=((l=H.getDisplayObject)==null?void 0:l.call(H))||H.pixiObject||H.pixi||H,U=(c=$==null?void 0:$.constructor)==null?void 0:c.name;if(console.log("[LIBRARY] displayObject:",$),console.log("[LIBRARY] displayObject type:",U),console.log("[LIBRARY] has texture?",!!($!=null&&$.texture)),$!=null&&$.texture)$.texture=S,console.log("[LIBRARY] \u2705 Applied to display object:",I);else if(U==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:Y}=await import("pixi.js"),V=$.parent,G=(p=(d=V==null?void 0:V.getChildIndex)==null?void 0:d.call(V,$))!=null?p:0,W={x:$.x,y:$.y},Z={x:(g=(u=$.anchor)==null?void 0:u.x)!=null?g:.5,y:(f=(h=$.anchor)==null?void 0:h.y)!=null?f:.5},ae={x:(b=(m=$.scale)==null?void 0:m.x)!=null?b:1,y:(w=(y=$.scale)==null?void 0:y.y)!=null?w:1},oe=(v=$.alpha)!=null?v:1,Re=(P=$.visible)!=null?P:!0,Q=new Y(S);Q.anchor.set(Z.x,Z.y),Q.position.set(W.x,W.y),Q.scale.set(ae.x,ae.y),Q.alpha=oe,Q.visible=Re,V&&(V.removeChild($),V.addChildAt(Q,G),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),H.pixiObject&&(H.pixiObject=Q),H.pixi&&(H.pixi=Q),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if($!=null&&$.children){let Y=$.children.find(V=>V.texture);Y?(Y.texture=S,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let M=`raw/library/${i}/${t}`;br(I,M,S,j),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:I,texture:S,assetPath:M}})),console.log("[LIBRARY] \u{1F4DD} Applying config override:",{objectId:I,path:"render.asset.path",value:M,persist:!0,emitEvent:!0}),le({objectId:I,path:"render.asset.path",value:M},{persist:!0,emitEvent:!0});let R=window.__configOverrides||[],z=R.find(N=>N.objectId===I&&N.path==="render.asset.path");z?console.log("[LIBRARY] \u2705 Override confirmed in localStorage:",{objectId:z.objectId,path:z.path,value:z.value,totalOverrides:R.length}):console.error("[LIBRARY] \u274C Override NOT found in localStorage after save!"),console.log("[LIBRARY] \u2705 Staged config override for:",I,"path:",M),await new Promise(N=>setTimeout(N,100));let q=(window.__configOverrides||[]).find(N=>N.objectId===I&&N.path==="render.asset.path");if(!q)throw new Error("Override not found in localStorage after save! This is a critical error.");if(q.value!==M)throw new Error(`Override value mismatch! Expected: ${M}, Got: ${q.value}`);console.log("[LIBRARY] \u2705 Override verified in localStorage")}catch(I){throw console.error("[LIBRARY] \u274C Error applying slot asset:",I),I}finally{Qi.delete(a)}})();Qi.set(a,s),await s}async function fr(r,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,s=mr(a),o=Date.now(),l=`/raw/${t}?t=${o}`;console.log("[LIBRARY] Loading default texture from:",l);let c=await bt.Assets.load(l);if(!c){console.error("[LIBRARY] Failed to load default texture:",l);return}xe[a]=c,console.log("[LIBRARY] \u2705 Reset AssetTextures."+a);let d=window.CustomAssets;d!=null&&d[a]&&(d[a].texture=c,console.log("[LIBRARY] \u2705 Reset CustomAssets."+a+" to default"));let p=window.gameObjectManager;if(p){let u=p.get(a);if(u){let g=((n=u.getDisplayObject)==null?void 0:n.call(u))||u.pixiObject||u;g!=null&&g.texture&&(g.texture=c,console.log("[LIBRARY] \u2705 Reset display object:",a))}}br(a,t,c,s),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:a,texture:c,assetPath:t}})),le({objectId:a,path:"render.asset.path",value:t},{persist:!0,emitEvent:!0}),console.log("[LIBRARY] \u2705 Reset config override for:",a)}catch(a){console.error("[LIBRARY] Error resetting slot asset:",a)}}function mr(r){var e,t,i;try{let n=window.getEditableObjectConfig,a=typeof n=="function"?n(r):null;return(i=(t=(e=a==null?void 0:a.render)==null?void 0:e.asset)==null?void 0:t.path)!=null?i:null}catch{return null}}function br(r,e,t,i){if(e){try{let n=`${r}:${e}`;pe.set(n,t)}catch{}if(i&&i!==e)try{let n=pe.store;n!=null&&n.delete&&n.delete(`${r}:${i}`)}catch{}ur(e,t),i&&i!==e&&ur(i,null)}}function ur(r,e){if(!r)return;let t=bt.Assets.cache;if(!t)return;let i=r.replace(/^\.?\//,""),n=[i,`/${i}`];for(let a of n)typeof t.remove=="function"?t.remove(a):typeof t.delete=="function"&&t.delete(a),e&&typeof t.set=="function"&&t.set(a,e)}var tn=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`
1396
1396
  <div class="canva-wizard-overlay" data-canva-wizard>
1397
1397
  <div class="canva-wizard-modal">
1398
1398
  <div class="canva-wizard-header">
@@ -1430,7 +1430,7 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1430
1430
  </div>
1431
1431
  </div>
1432
1432
  </div>
1433
- `}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":"",s=e.action==="replace"?this.renderReplaceDropdown(e,t):"",r=e.action==="add"?this.renderAddToSceneFields(e,t):"";return`
1433
+ `}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":"",s=e.action==="replace"?this.renderReplaceDropdown(e,t):"",o=e.action==="add"?this.renderAddToSceneFields(e,t):"";return`
1434
1434
  <div class="canva-asset-card ${a}" data-asset-index="${t}">
1435
1435
  <div class="canva-asset-preview">
1436
1436
  <img src="${e.dataUrl}" alt="${e.filename}" />
@@ -1467,7 +1467,7 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1467
1467
  \u23ED\uFE0F Do Nothing
1468
1468
  </button>
1469
1469
  </div>
1470
- ${r}
1470
+ ${o}
1471
1471
  ${s}
1472
1472
  </div>
1473
1473
  `}renderAddToSceneFields(e,t){return`
@@ -1498,8 +1498,8 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1498
1498
  ${this.replaceableObjects.map(i=>`<option value="${i.id}" ${e.targetObjectId===i.id?"selected":""}>${i.name}</option>`).join("")}
1499
1499
  </select>
1500
1500
  </div>
1501
- `}initialize(e,t,i,n){this.options=n,this.positionMap=lo(i),this.replaceableObjects=po(),this.assets=t.map(a=>{let s=co(a.filename,this.positionMap);return{filename:a.filename,dataUrl:a.dataUrl,category:this.inferCategory(a.filename),position:s==null?void 0:s.position,scale:s==null?void 0:s.scale,rotation:s==null?void 0:s.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 s=a.target,r=parseInt(s.getAttribute("data-asset-action")||"0"),l=s.getAttribute("data-action");this.handleAction(r,l)})}),this.root.querySelectorAll("[data-asset-category]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,r=parseInt(s.getAttribute("data-asset-category")||"0"),l=s.value;this.assets[r]&&(this.assets[r].category=l)})}),this.root.querySelectorAll("[data-asset-target]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,r=parseInt(s.getAttribute("data-asset-target")||"0"),l=s.value;this.assets[r]&&(this.assets[r].targetObjectId=l)})}),this.root.querySelectorAll("[data-asset-screen]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,r=parseInt(s.getAttribute("data-asset-screen")||"0"),l=s.value;this.assets[r]&&(this.assets[r].screen=l)})}),this.root.querySelectorAll("[data-asset-type]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,r=parseInt(s.getAttribute("data-asset-type")||"0"),l=s.value;this.assets[r]&&(this.assets[r].objectType=l)})}),this.root.addEventListener("click",n=>{n.target===this.root&&this.close()}))}handleAction(e,t){this.assets[e]&&(this.assets[e].action=t,t==="add"&&(this.assets[e].screen||(this.assets[e].screen="gameplay"),this.assets[e].objectType||(this.assets[e].objectType="sprite")),t==="replace"?this.updateAssetCard(e):(this.assets[e].targetObjectId=void 0,this.updateAssetCard(e)))}updateAssetCard(e){var i,n,a,s;if(!this.root)return;let t=this.root.querySelector(`[data-asset-index="${e}"]`);if(t&&this.assets[e]){let r=this.assets[e],l=this.renderAssetCard(r,e);t.outerHTML=l;let c=this.root.querySelector(`[data-asset-index="${e}"]`);c&&(c.querySelectorAll("[data-asset-action]").forEach(d=>{d.addEventListener("click",p=>{let u=p.target,g=parseInt(u.getAttribute("data-asset-action")||"0"),h=u.getAttribute("data-action");this.handleAction(g,h)})}),(i=c.querySelector("[data-asset-category]"))==null||i.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].category=u)}),(n=c.querySelector("[data-asset-target]"))==null||n.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].targetObjectId=u)}),(a=c.querySelector("[data-asset-screen]"))==null||a.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].screen=u)}),(s=c.querySelector("[data-asset-type]"))==null||s.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].objectType=u)}))}}async applyAll(){if(!this.options)return;for(let i of this.assets)i.action||(i.action="skip");this.processedCount=0,this.updateProgress();let e=[],t=[];for(let i=0;i<this.assets.length;i++){let n=this.assets[i];try{let a=await this.saveAssetToLibrary(n);n.libraryPath=a,n.action==="add"?e.push(n):n.action==="replace"&&n.targetObjectId&&t.push({asset:n,targetId:n.targetObjectId}),this.processedCount++,this.updateProgress()}catch(a){console.error(`[CanvaZip] Failed to save ${n.filename} to library:`,a)}}if(e.length>0)try{await this.batchAddToScene(e)}catch(i){console.error("[CanvaZip] Batch add to scene failed:",i)}if(t.length>0)for(let{asset:i,targetId:n}of t)try{await this.replaceObject(i,n)}catch(a){console.error(`[CanvaZip] Replace failed for ${n}:`,a)}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),this.options.onComplete&&this.options.onComplete(this.assets),this.close()}async batchAddToScene(e){var a;let t=e.map(s=>{let r=s.filename.replace(/\.(png|jpg|jpeg)$/i,"").replace(/[^a-zA-Z0-9._-]/g,"_").toLowerCase(),l=`json.${r}`,c={identity:{id:l,category:s.category||"environment"},transform:{position:s.position||{x:0,y:0},offset:{x:0,y:0},scale:.3,rotation:s.rotation||0,anchor:{x:.5,y:.5},position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0,asset:{type:"image",path:s.libraryPath}},instance_id:r,object_config:l};return{screenId:s.screen,instanceId:r,objectConfigId:l,layer:s.objectType==="ui-image"?"ui":"world",config:c}}),i=await fetch("/api/objects/batch-create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objects:t})}),n=await i.json().catch(()=>({}));if(!i.ok||(n==null?void 0:n.success)===!1){let s=((a=n==null?void 0:n.errors)==null?void 0:a.join(`
1502
- `))||(n==null?void 0:n.error)||"Batch create failed.";throw new Error(s)}try{let{trackObjectCreation:s}=await Promise.resolve().then(()=>(Q(),Ie));for(let r of t)s(r.instanceId,r.screenId,r.config)}catch(s){console.warn("[CanvaZip] Failed to track batch creation in history:",s)}console.log(`[CanvaZip] \u2705 Batch added ${e.length} objects to scene`)}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 syncScreens(){try{let e=window.__HANDLER_ACTIVE_SCREEN,t=await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})});if(!t.ok){let i=await t.json().catch(()=>({}));throw new Error((i==null?void 0:i.error)||"Failed to sync screens")}}catch(e){console.warn("[CanvaZip] Screen sync failed:",e)}}async replaceObject(e,t){let i=window.__debugContext;if(!i){console.warn("[CanvaZip] No debug context available for replace");return}try{await Zi(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 en=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.wizardProcessedAssets=new Set;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`
1501
+ `}initialize(e,t,i,n){this.options=n,this.positionMap=cr(i),this.replaceableObjects=pr(),this.assets=t.map(a=>{let s=dr(a.filename,this.positionMap);return{filename:a.filename,dataUrl:a.dataUrl,category:this.inferCategory(a.filename),position:s==null?void 0:s.position,scale:s==null?void 0:s.scale,rotation:s==null?void 0:s.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 s=a.target,o=parseInt(s.getAttribute("data-asset-action")||"0"),l=s.getAttribute("data-action");this.handleAction(o,l)})}),this.root.querySelectorAll("[data-asset-category]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-category")||"0"),l=s.value;this.assets[o]&&(this.assets[o].category=l)})}),this.root.querySelectorAll("[data-asset-target]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-target")||"0"),l=s.value;this.assets[o]&&(this.assets[o].targetObjectId=l)})}),this.root.querySelectorAll("[data-asset-screen]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-screen")||"0"),l=s.value;this.assets[o]&&(this.assets[o].screen=l)})}),this.root.querySelectorAll("[data-asset-type]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-type")||"0"),l=s.value;this.assets[o]&&(this.assets[o].objectType=l)})}),this.root.addEventListener("click",n=>{n.target===this.root&&this.close()}))}handleAction(e,t){this.assets[e]&&(this.assets[e].action=t,t==="add"&&(this.assets[e].screen||(this.assets[e].screen="gameplay"),this.assets[e].objectType||(this.assets[e].objectType="sprite")),t==="replace"?this.updateAssetCard(e):(this.assets[e].targetObjectId=void 0,this.updateAssetCard(e)))}updateAssetCard(e){var i,n,a,s;if(!this.root)return;let t=this.root.querySelector(`[data-asset-index="${e}"]`);if(t&&this.assets[e]){let o=this.assets[e],l=this.renderAssetCard(o,e);t.outerHTML=l;let c=this.root.querySelector(`[data-asset-index="${e}"]`);c&&(c.querySelectorAll("[data-asset-action]").forEach(d=>{d.addEventListener("click",p=>{let u=p.target,g=parseInt(u.getAttribute("data-asset-action")||"0"),h=u.getAttribute("data-action");this.handleAction(g,h)})}),(i=c.querySelector("[data-asset-category]"))==null||i.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].category=u)}),(n=c.querySelector("[data-asset-target]"))==null||n.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].targetObjectId=u)}),(a=c.querySelector("[data-asset-screen]"))==null||a.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].screen=u)}),(s=c.querySelector("[data-asset-type]"))==null||s.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].objectType=u)}))}}async applyAll(){if(!this.options)return;for(let i of this.assets)i.action||(i.action="skip");this.processedCount=0,this.updateProgress();let e=[],t=[];for(let i=0;i<this.assets.length;i++){let n=this.assets[i];try{let a=await this.saveAssetToLibrary(n);n.libraryPath=a,n.action==="add"?e.push(n):n.action==="replace"&&n.targetObjectId&&t.push({asset:n,targetId:n.targetObjectId}),this.processedCount++,this.updateProgress()}catch(a){console.error(`[CanvaZip] Failed to save ${n.filename} to library:`,a)}}if(e.length>0)try{await this.batchAddToScene(e)}catch(i){console.error("[CanvaZip] Batch add to scene failed:",i)}if(t.length>0)for(let{asset:i,targetId:n}of t)try{await this.replaceObject(i,n)}catch(a){console.error(`[CanvaZip] Replace failed for ${n}:`,a)}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),this.options.onComplete&&this.options.onComplete(this.assets),this.close()}async batchAddToScene(e){var a;let t=e.map(s=>{let o=s.filename.replace(/\.(png|jpg|jpeg)$/i,"").replace(/[^a-zA-Z0-9._-]/g,"_").toLowerCase(),l=`json.${o}`,c={identity:{id:l,category:s.category||"environment"},transform:{position:s.position||{x:0,y:0},offset:{x:0,y:0},scale:.3,rotation:s.rotation||0,anchor:{x:.5,y:.5},position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0,asset:{type:"image",path:s.libraryPath}},instance_id:o,object_config:l};return{screenId:s.screen,instanceId:o,objectConfigId:l,layer:s.objectType==="ui-image"?"ui":"world",config:c}}),i=await fetch("/api/objects/batch-create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objects:t})}),n=await i.json().catch(()=>({}));if(!i.ok||(n==null?void 0:n.success)===!1){let s=((a=n==null?void 0:n.errors)==null?void 0:a.join(`
1502
+ `))||(n==null?void 0:n.error)||"Batch create failed.";throw new Error(s)}try{let{trackObjectCreation:s}=await Promise.resolve().then(()=>(ne(),Pe));for(let o of t)s(o.instanceId,o.screenId,o.config)}catch(s){console.warn("[CanvaZip] Failed to track batch creation in history:",s)}console.log(`[CanvaZip] \u2705 Batch added ${e.length} objects to scene`)}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 syncScreens(){try{let e=window.__HANDLER_ACTIVE_SCREEN,t=await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})});if(!t.ok){let i=await t.json().catch(()=>({}));throw new Error((i==null?void 0:i.error)||"Failed to sync screens")}}catch(e){console.warn("[CanvaZip] Screen sync failed:",e)}}async replaceObject(e,t){let i=window.__debugContext;if(!i){console.warn("[CanvaZip] No debug context available for replace");return}try{await en(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 nn=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.wizardProcessedAssets=new Set;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`
1503
1503
  <div class="scene-panel brand-vision-panel panel-accent-violet" data-panel="brand-vision">
1504
1504
  <div class="scene-panel-header" data-panel-handle>
1505
1505
  <div class="panel-title">
@@ -1629,15 +1629,15 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1629
1629
  </div>
1630
1630
  <div class="panel-resize-handle" data-panel-resize></div>
1631
1631
  </div>
1632
- `}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,s,r,l,c,d,p,u,g,h,f;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let m="/dashboard";window.location.pathname!==m&&(window.location.href=m)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(m=>{m.addEventListener("click",()=>{let b=m.dataset.visionTab;this.switchTab(b)})}),(i=this.root.querySelector("[data-vision-upload-method]"))==null||i.addEventListener("change",m=>{let b=m.target.value;this.switchUploadMethod(b)}),(n=this.root.querySelector("[data-vision-upload-manifest]"))==null||n.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-manifest-input]"))==null||b.click()}),(a=this.root.querySelector("[data-vision-upload-batch-png]"))==null||a.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-batch-png-input]"))==null||b.click()}),(s=this.root.querySelector("[data-vision-batch-png-input]"))==null||s.addEventListener("change",m=>{this.handleBatchPNGUpload(m)}),(r=this.root.querySelector("[data-vision-upload-zip]"))==null||r.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-zip-input]"))==null||b.click()}),(l=this.root.querySelector("[data-vision-zip-input]"))==null||l.addEventListener("change",m=>{this.handleZipUpload(m)}),(c=this.root.querySelector("[data-vision-manifest-input]"))==null||c.addEventListener("change",m=>{this.handleManifestUpload(m)}),(d=this.root.querySelector("[data-vision-upload-assets]"))==null||d.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-assets-input]"))==null||b.click()}),(p=this.root.querySelector("[data-vision-assets-input]"))==null||p.addEventListener("change",m=>{this.handleAssetsUpload(m)}),(u=this.root.querySelector("[data-vision-upload-flat]"))==null||u.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-flat-input]"))==null||b.click()}),(g=this.root.querySelector("[data-vision-flat-input]"))==null||g.addEventListener("change",m=>{this.handleFlatDesignUpload(m)}),(h=this.root.querySelector("[data-vision-generate-all]"))==null||h.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",m=>{let b=m.target;if(!b)return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;v&&(b.closest("[data-mapping-apply-one]")&&this.applyOne(v),b.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(v),b.closest("[data-mapping-edit-one]")&&this.openEditorForOne(v),b.closest("[data-mapping-generate-one]")&&this.generateOne(v),b.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",m=>{let b=m.target;if(!b||!this.mappingResult)return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;if(!v)return;let w=this.mappingResult.mappings.find(I=>I.game_object===v);w&&(b.matches("[data-mapping-action]")&&(w.action=String(b.value||"KEEP"),w.status="Edited",this.renderMappings()),b.matches("[data-mapping-brand-asset]")&&(w.brand_asset=String(b.value||""),w.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",m=>{let b=m.target;if(!b||!this.mappingResult||!b.matches("[data-mapping-prompt]"))return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;if(!v)return;let w=this.mappingResult.mappings.find(I=>I.game_object===v);w&&(w.generation_prompt=String(b.value||""),w.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 handleBatchPNGUpload(e){var s;let t=e.target,i=Array.from(t.files||[]);if(i.length===0)return;let n=i.filter(r=>r.type.startsWith("image/"));if(n.length===0){this.setStatus("upload","\u26A0\uFE0F No image files selected");return}let a=(s=this.root)==null?void 0:s.querySelector("[data-vision-batch-png-status]");a&&(a.textContent=`Processing ${n.length} PNG${n.length>1?"s":""}...`);try{let r=window.__HANDLER_ACTIVE_SCREEN,l=r==="loading"||r==="start"||r==="gameplay"||r==="tutorial"||r==="endgame"?r:"gameplay",c=[];for(let g=0;g<n.length;g++){let h=n[g];try{let f=await this.fileToDataUrl(h);if(!f){c.push({success:!1,filename:h.name,error:"Failed to read file"});continue}let m=h.name.replace(/\.[^/.]+$/,""),b=this.inferCategoryFromFilename(m),y=m.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),v=`${y}_${Date.now()}${g>0?`_${g}`:""}`,w=`json.${v}`,I=`${y}.png`,_=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:b,filename:I,data:f,overwrite:!1})})).json();if(!_.success){c.push({success:!1,filename:h.name,error:_.error});continue}let T={identity:{id:w,category:b},transform:{anchor:"center",position:{x:0,y:0},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:_.path||`raw/library/${b}/${I}`}}},M=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:l,instanceId:v,objectConfigId:w,config:T,layer:b==="ui"?"ui":"world"})}),k=await M.json();M.ok&&k.success?c.push({success:!0,filename:h.name}):c.push({success:!1,filename:h.name,error:k.error})}catch(f){c.push({success:!1,filename:h.name,error:f instanceof Error?f.message:String(f)})}}let d=c.filter(g=>g.success).length,p=c.length-d;a&&(p===0?a.textContent=`\u2705 Added ${d} PNG${d>1?"s":""} to scene`:a.textContent=`\u26A0\uFE0F Added ${d}, failed ${p}`),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"));let u=window.refreshAssetLibrary;typeof u=="function"&&u(),t.value=""}catch(r){a&&(a.textContent=`\u274C Error: ${r instanceof Error?r.message:String(r)}`),console.error("[BrandVision] Batch PNG upload failed:",r)}}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}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;let t=null;if(typeof window!="undefined"&&window.JSZip)t=window.JSZip,console.log("[BrandVision] \u2705 Found window.JSZip");else try{let c=await import("jszip");t=c.default||c,console.log("[BrandVision] \u2705 Loaded JSZip via dynamic import")}catch(c){throw new Error(`JSZip is not properly imported. Make sure jszip is loaded globally (window.JSZip) or available as a module: ${(c==null?void 0:c.message)||"Unknown error"}`)}if(!t||typeof t.loadAsync!="function")throw new Error("JSZip is not properly imported - loadAsync method not found");let i=await t.loadAsync(e),n=[],a=[];i.forEach((c,d)=>{let p=c.toLowerCase();p.endsWith(".json")?n.push({name:c,content:null}):p.startsWith("assets/")&&p.endsWith(".png")&&a.push({name:c,file:d})});for(let c of n)try{let d=await((l=i.file(c.name))==null?void 0:l.async("text"));d&&(c.content=JSON.parse(d))}catch(d){console.warn(`Failed to parse ${c.name}:`,d)}let s=[];for(let c of a)try{let d=await c.file.async("uint8array"),p=new Blob([d],{type:"image/png"}),u=c.name.split("/").pop()||c.name;console.log(`Processing ${u}, uint8array length: ${d.length}, blob size: ${p.size}`);let g;try{g=await this.blobToDataUrl(p)}catch(h){console.warn(`FileReader failed for ${u}, using fallback:`,h),g=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(d)))}`}if(!g.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${u}:`,g.substring(0,100));continue}s.push({filename:u,dataUrl:g})}catch(d){console.warn(`Failed to extract ${c.name}:`,d)}let r=null;for(let c of n){let d=c.name.toLowerCase();if(d.includes("positionnormalizedpack")||d.includes("positionnormalized")){r=c.content,console.log(`[BrandVision] Found position data file: ${c.name}`,{hasContent:!!r,isString:typeof r=="string",isObject:typeof r=="object",hasLayers:r!=null&&r.layers?r.layers.length:0});break}}if(r||console.warn("[BrandVision] No positionnormalizedpack.json found in ZIP. Available JSON files:",n.map(c=>c.name)),s.length>0){await this.showCanvaZipWizard(s,r),this.setStatus("zip",`\u2705 Wizard completed - ${s.length} assets processed`);return}else{this.setStatus("zip","\u26A0\uFE0F No PNG files found in ZIP");return}}async showCanvaZipWizard(e,t){return new Promise(i=>{let n=e.filter(r=>!this.wizardProcessedAssets.has(r.filename));if(n.length===0){console.log("[BrandVision] All assets already processed by wizard"),i();return}let a=document.createElement("div");document.body.appendChild(a),new Qi().initialize(a,n,t,{onComplete:r=>{console.log("[BrandVision] Wizard completed, processed assets:",r),r.forEach(l=>{this.wizardProcessedAssets.add(l.filename)}),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 s=a.category||"misc";n[s]||(n[s]=[]),i.libraryAssets[s]||(i.libraryAssets[s]=[]),i.libraryAssets[s].some(l=>l.filename===a.filename)||(i.libraryAssets[s].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 ${s}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var s;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 l=await r.text(),c=JSON.parse(l);this.uploadedJsons.set(r.name,c),c.layers?n+=`\u2705 Layers: ${r.name}
1633
- `:c.brand_dna||c.colors?n+=`\u2705 Brand: ${r.name}
1634
- `:n+=`\u2705 Loaded: ${r.name}
1635
- `}catch{n+=`\u274C Error in ${r.name}
1636
- `}try{this.normalizedManifest=Zs(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let r=Array.isArray((s=this.normalizedManifest)==null?void 0:s.assets)?this.normalizedManifest.assets.length:0;n+=`
1637
- \u{1F4E6} Normalized manifest: ${r} assets`,n+=`
1638
- \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+=`
1632
+ `}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,s,o,l,c,d,p,u,g,h,f;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let m="/dashboard";window.location.pathname!==m&&(window.location.href=m)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(m=>{m.addEventListener("click",()=>{let b=m.dataset.visionTab;this.switchTab(b)})}),(i=this.root.querySelector("[data-vision-upload-method]"))==null||i.addEventListener("change",m=>{let b=m.target.value;this.switchUploadMethod(b)}),(n=this.root.querySelector("[data-vision-upload-manifest]"))==null||n.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-manifest-input]"))==null||b.click()}),(a=this.root.querySelector("[data-vision-upload-batch-png]"))==null||a.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-batch-png-input]"))==null||b.click()}),(s=this.root.querySelector("[data-vision-batch-png-input]"))==null||s.addEventListener("change",m=>{this.handleBatchPNGUpload(m)}),(o=this.root.querySelector("[data-vision-upload-zip]"))==null||o.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-zip-input]"))==null||b.click()}),(l=this.root.querySelector("[data-vision-zip-input]"))==null||l.addEventListener("change",m=>{this.handleZipUpload(m)}),(c=this.root.querySelector("[data-vision-manifest-input]"))==null||c.addEventListener("change",m=>{this.handleManifestUpload(m)}),(d=this.root.querySelector("[data-vision-upload-assets]"))==null||d.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-assets-input]"))==null||b.click()}),(p=this.root.querySelector("[data-vision-assets-input]"))==null||p.addEventListener("change",m=>{this.handleAssetsUpload(m)}),(u=this.root.querySelector("[data-vision-upload-flat]"))==null||u.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-flat-input]"))==null||b.click()}),(g=this.root.querySelector("[data-vision-flat-input]"))==null||g.addEventListener("change",m=>{this.handleFlatDesignUpload(m)}),(h=this.root.querySelector("[data-vision-generate-all]"))==null||h.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",m=>{let b=m.target;if(!b)return;let y=b.closest("[data-mapping-item]"),w=y==null?void 0:y.dataset.mappingItem;w&&(b.closest("[data-mapping-apply-one]")&&this.applyOne(w),b.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(w),b.closest("[data-mapping-edit-one]")&&this.openEditorForOne(w),b.closest("[data-mapping-generate-one]")&&this.generateOne(w),b.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",m=>{let b=m.target;if(!b||!this.mappingResult)return;let y=b.closest("[data-mapping-item]"),w=y==null?void 0:y.dataset.mappingItem;if(!w)return;let v=this.mappingResult.mappings.find(P=>P.game_object===w);v&&(b.matches("[data-mapping-action]")&&(v.action=String(b.value||"KEEP"),v.status="Edited",this.renderMappings()),b.matches("[data-mapping-brand-asset]")&&(v.brand_asset=String(b.value||""),v.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",m=>{let b=m.target;if(!b||!this.mappingResult||!b.matches("[data-mapping-prompt]"))return;let y=b.closest("[data-mapping-item]"),w=y==null?void 0:y.dataset.mappingItem;if(!w)return;let v=this.mappingResult.mappings.find(P=>P.game_object===w);v&&(v.generation_prompt=String(b.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 handleBatchPNGUpload(e){var s;let t=e.target,i=Array.from(t.files||[]);if(i.length===0)return;let n=i.filter(o=>o.type.startsWith("image/"));if(n.length===0){this.setStatus("upload","\u26A0\uFE0F No image files selected");return}let a=(s=this.root)==null?void 0:s.querySelector("[data-vision-batch-png-status]");a&&(a.textContent=`Processing ${n.length} PNG${n.length>1?"s":""}...`);try{let o=window.__HANDLER_ACTIVE_SCREEN,l=o==="loading"||o==="start"||o==="gameplay"||o==="tutorial"||o==="endgame"?o:"gameplay",c=[];for(let g=0;g<n.length;g++){let h=n[g];try{let f=await this.fileToDataUrl(h);if(!f){c.push({success:!1,filename:h.name,error:"Failed to read file"});continue}let m=h.name.replace(/\.[^/.]+$/,""),b=this.inferCategoryFromFilename(m),y=m.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),w=`${y}_${Date.now()}${g>0?`_${g}`:""}`,v=`json.${w}`,P=`${y}.png`,_=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:b,filename:P,data:f,overwrite:!1})})).json();if(!_.success){c.push({success:!1,filename:h.name,error:_.error});continue}let k={identity:{id:v,category:b},transform:{anchor:"center",position:{x:0,y:0},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:_.path||`raw/library/${b}/${P}`}}},j=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:l,instanceId:w,objectConfigId:v,config:k,layer:b==="ui"?"ui":"world"})}),L=await j.json();j.ok&&L.success?c.push({success:!0,filename:h.name}):c.push({success:!1,filename:h.name,error:L.error})}catch(f){c.push({success:!1,filename:h.name,error:f instanceof Error?f.message:String(f)})}}let d=c.filter(g=>g.success).length,p=c.length-d;a&&(p===0?a.textContent=`\u2705 Added ${d} PNG${d>1?"s":""} to scene`:a.textContent=`\u26A0\uFE0F Added ${d}, failed ${p}`),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"));let u=window.refreshAssetLibrary;typeof u=="function"&&u(),t.value=""}catch(o){a&&(a.textContent=`\u274C Error: ${o instanceof Error?o.message:String(o)}`),console.error("[BrandVision] Batch PNG upload failed:",o)}}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}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;let t=null;if(typeof window!="undefined"&&window.JSZip)t=window.JSZip,console.log("[BrandVision] \u2705 Found window.JSZip");else try{let c=await import("jszip");t=c.default||c,console.log("[BrandVision] \u2705 Loaded JSZip via dynamic import")}catch(c){throw new Error(`JSZip is not properly imported. Make sure jszip is loaded globally (window.JSZip) or available as a module: ${(c==null?void 0:c.message)||"Unknown error"}`)}if(!t||typeof t.loadAsync!="function")throw new Error("JSZip is not properly imported - loadAsync method not found");let i=await t.loadAsync(e),n=[],a=[];i.forEach((c,d)=>{let p=c.toLowerCase();p.endsWith(".json")?n.push({name:c,content:null}):p.startsWith("assets/")&&p.endsWith(".png")&&a.push({name:c,file:d})});for(let c of n)try{let d=await((l=i.file(c.name))==null?void 0:l.async("text"));d&&(c.content=JSON.parse(d))}catch(d){console.warn(`Failed to parse ${c.name}:`,d)}let s=[];for(let c of a)try{let d=await c.file.async("uint8array"),p=new Blob([d],{type:"image/png"}),u=c.name.split("/").pop()||c.name;console.log(`Processing ${u}, uint8array length: ${d.length}, blob size: ${p.size}`);let g;try{g=await this.blobToDataUrl(p)}catch(h){console.warn(`FileReader failed for ${u}, using fallback:`,h),g=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(d)))}`}if(!g.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${u}:`,g.substring(0,100));continue}s.push({filename:u,dataUrl:g})}catch(d){console.warn(`Failed to extract ${c.name}:`,d)}let o=null;for(let c of n){let d=c.name.toLowerCase();if(d.includes("positionnormalizedpack")||d.includes("positionnormalized")){o=c.content,console.log(`[BrandVision] Found position data file: ${c.name}`,{hasContent:!!o,isString:typeof o=="string",isObject:typeof o=="object",hasLayers:o!=null&&o.layers?o.layers.length:0});break}}if(o||console.warn("[BrandVision] No positionnormalizedpack.json found in ZIP. Available JSON files:",n.map(c=>c.name)),s.length>0){await this.showCanvaZipWizard(s,o),this.setStatus("zip",`\u2705 Wizard completed - ${s.length} assets processed`);return}else{this.setStatus("zip","\u26A0\uFE0F No PNG files found in ZIP");return}}async showCanvaZipWizard(e,t){return new Promise(i=>{let n=e.filter(o=>!this.wizardProcessedAssets.has(o.filename));if(n.length===0){console.log("[BrandVision] All assets already processed by wizard"),i();return}let a=document.createElement("div");document.body.appendChild(a),new tn().initialize(a,n,t,{onComplete:o=>{console.log("[BrandVision] Wizard completed, processed assets:",o),o.forEach(l=>{this.wizardProcessedAssets.add(l.filename)}),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 s=a.category||"misc";n[s]||(n[s]=[]),i.libraryAssets[s]||(i.libraryAssets[s]=[]),i.libraryAssets[s].some(l=>l.filename===a.filename)||(i.libraryAssets[s].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 ${s}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var s;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 o of Array.from(i))try{let l=await o.text(),c=JSON.parse(l);this.uploadedJsons.set(o.name,c),c.layers?n+=`\u2705 Layers: ${o.name}
1633
+ `:c.brand_dna||c.colors?n+=`\u2705 Brand: ${o.name}
1634
+ `:n+=`\u2705 Loaded: ${o.name}
1635
+ `}catch{n+=`\u274C Error in ${o.name}
1636
+ `}try{this.normalizedManifest=Qs(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let o=Array.isArray((s=this.normalizedManifest)==null?void 0:s.assets)?this.normalizedManifest.assets.length:0;n+=`
1637
+ \u{1F4E6} Normalized manifest: ${o} assets`,n+=`
1638
+ \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:o,brandName:this.normalizedManifest.brand_name})}catch(o){console.error("[BrandVision] Failed to normalize manifest:",o),this.normalizedManifest=null,n+=`
1639
1639
  \u274C Failed to normalize manifest`}t.value="";let a=n.trim();this.uploadedJsons.size>0?this.setStatus("manifest",`${a}
1640
- \u2705 JSONs ready - now upload PNGs to open wizard`):this.setStatus("manifest",a)}async handleAssetsUpload(e){console.log("[BrandVision] handleAssetsUpload called",e);let t=e.target,i=t.files;if(console.log("[BrandVision] Files object:",i),!i||i.length===0){console.log("[BrandVision] No files selected");return}console.log(`[BrandVision] handleAssetsUpload: ${i.length} files selected`);for(let r=0;r<i.length;r++)console.log(`[BrandVision] File ${r}: ${i[r].name}, type: ${i[r].type}, size: ${i[r].size}`);let n=[];for(let r of Array.from(i)){if(console.log(`[BrandVision] Processing file: ${r.name}, type: ${r.type}`),!r.type.startsWith("image/")){console.log(`[BrandVision] Skipping non-image file: ${r.name}`),this.assetFiles.set(r.name,r);continue}try{let l=await this.fileToDataUrl(r);l?(n.push({filename:r.name,dataUrl:l}),console.log(`[BrandVision] \u2705 Converted ${r.name} to data URL (length: ${l.length})`)):(console.error(`[BrandVision] Failed to convert ${r.name} to data URL`),this.assetFiles.set(r.name,r))}catch(l){console.error(`[BrandVision] Failed to process ${r.name}:`,l),this.assetFiles.set(r.name,r)}}console.log(`[BrandVision] Extracted ${n.length} image assets`);let a=this.uploadedJsons.size>0,s=n.length>0;if(console.log(`[BrandVision] Individual upload check: JSONs=${a}, Images=${s}`),a&&s){console.log("[BrandVision] Both JSONs and images present - showing wizard"),this.setStatus("assets",`Processing ${n.length} images...`);let r=null;console.log("[BrandVision] Checking uploaded JSONs for position data:",Array.from(this.uploadedJsons.keys()));for(let[l,c]of this.uploadedJsons.entries()){let d=l.toLowerCase();if(console.log(`[BrandVision] Checking JSON: ${l} (lowercase: ${d})`),d.includes("positionnormalizedpack")||d.includes("positionnormalized")){r=c,console.log("[BrandVision] \u2705 Found position data in:",l,{hasContent:!!r,isString:typeof r=="string",isObject:typeof r=="object",hasLayers:r!=null&&r.layers?r.layers.length:0,contentPreview:typeof r=="object"?JSON.stringify(r).substring(0,200):String(r).substring(0,200)});break}}r||console.warn("[BrandVision] \u26A0\uFE0F No position data found. Uploaded JSON files:",Array.from(this.uploadedJsons.keys())),console.log("[BrandVision] Opening wizard with assets:",n.map(l=>l.filename)),await this.showCanvaZipWizard(n,r),console.log("[BrandVision] Wizard completed successfully"),this.setStatus("assets",`\u2705 Wizard completed - ${n.length} assets processed`)}else console.log("[BrandVision] Waiting for both JSONs and images. Current state:",{jsons:this.uploadedJsons.size,images:n.length}),a?this.setStatus("assets",`Uploaded ${n.length} images. JSONs ready - wizard should open now.`):this.setStatus("assets","\u26A0\uFE0F Upload JSONs first, then PNGs to open wizard");t.value=""}async handleFlatDesignUpload(e){var a,s;let i=(a=e.target.files)==null?void 0:a[0];if(!i)return;let n=await Be(i);if(n){this.flatDesignDataUrl=n.dataUrl,this.setStatus("flat",`\u{1F3A8} ${i.name}`);let r=(s=this.root)==null?void 0:s.querySelector("[data-vision-flat-preview]");r&&(r.innerHTML=`<img src="${n.dataUrl}" style="max-width:100%;max-height:100px;border-radius:4px;">`)}}async runAnalysis(){var i,n,a,s,r,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 ro(t,this.assetFiles);let d={apiKey:e,manifest:t,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()},p=await so(d);this.mappingResult=p.mappingResult,this.analysisRawResponse=p.rawResponse,this.analysisParsedOk=p.parsed,this.analysisParseError=(s=p.parseError)!=null?s:null,this.renderMappings(),p.parsed?(this.setStatus("upload","Analysis complete"),this.setStatus("mapping",`${(c=(l=(r=this.mappingResult)==null?void 0:r.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 ha(a,this.mappingResult,{onProgress:(s,r,l)=>{this.setStatus("apply",`Generating ${s}/${r}: ${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 r;let e=(r=this.root)==null?void 0:r.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(""),s=n?`
1640
+ \u2705 JSONs ready - now upload PNGs to open wizard`):this.setStatus("manifest",a)}async handleAssetsUpload(e){console.log("[BrandVision] handleAssetsUpload called",e);let t=e.target,i=t.files;if(console.log("[BrandVision] Files object:",i),!i||i.length===0){console.log("[BrandVision] No files selected");return}console.log(`[BrandVision] handleAssetsUpload: ${i.length} files selected`);for(let o=0;o<i.length;o++)console.log(`[BrandVision] File ${o}: ${i[o].name}, type: ${i[o].type}, size: ${i[o].size}`);let n=[];for(let o of Array.from(i)){if(console.log(`[BrandVision] Processing file: ${o.name}, type: ${o.type}`),!o.type.startsWith("image/")){console.log(`[BrandVision] Skipping non-image file: ${o.name}`),this.assetFiles.set(o.name,o);continue}try{let l=await this.fileToDataUrl(o);l?(n.push({filename:o.name,dataUrl:l}),console.log(`[BrandVision] \u2705 Converted ${o.name} to data URL (length: ${l.length})`)):(console.error(`[BrandVision] Failed to convert ${o.name} to data URL`),this.assetFiles.set(o.name,o))}catch(l){console.error(`[BrandVision] Failed to process ${o.name}:`,l),this.assetFiles.set(o.name,o)}}console.log(`[BrandVision] Extracted ${n.length} image assets`);let a=this.uploadedJsons.size>0,s=n.length>0;if(console.log(`[BrandVision] Individual upload check: JSONs=${a}, Images=${s}`),a&&s){console.log("[BrandVision] Both JSONs and images present - showing wizard"),this.setStatus("assets",`Processing ${n.length} images...`);let o=null;console.log("[BrandVision] Checking uploaded JSONs for position data:",Array.from(this.uploadedJsons.keys()));for(let[l,c]of this.uploadedJsons.entries()){let d=l.toLowerCase();if(console.log(`[BrandVision] Checking JSON: ${l} (lowercase: ${d})`),d.includes("positionnormalizedpack")||d.includes("positionnormalized")){o=c,console.log("[BrandVision] \u2705 Found position data in:",l,{hasContent:!!o,isString:typeof o=="string",isObject:typeof o=="object",hasLayers:o!=null&&o.layers?o.layers.length:0,contentPreview:typeof o=="object"?JSON.stringify(o).substring(0,200):String(o).substring(0,200)});break}}o||console.warn("[BrandVision] \u26A0\uFE0F No position data found. Uploaded JSON files:",Array.from(this.uploadedJsons.keys())),console.log("[BrandVision] Opening wizard with assets:",n.map(l=>l.filename)),await this.showCanvaZipWizard(n,o),console.log("[BrandVision] Wizard completed successfully"),this.setStatus("assets",`\u2705 Wizard completed - ${n.length} assets processed`)}else console.log("[BrandVision] Waiting for both JSONs and images. Current state:",{jsons:this.uploadedJsons.size,images:n.length}),a?this.setStatus("assets",`Uploaded ${n.length} images. JSONs ready - wizard should open now.`):this.setStatus("assets","\u26A0\uFE0F Upload JSONs first, then PNGs to open wizard");t.value=""}async handleFlatDesignUpload(e){var a,s;let i=(a=e.target.files)==null?void 0:a[0];if(!i)return;let n=await Ge(i);if(n){this.flatDesignDataUrl=n.dataUrl,this.setStatus("flat",`\u{1F3A8} ${i.name}`);let o=(s=this.root)==null?void 0:s.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,s,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 lr(t,this.assetFiles);let d={apiKey:e,manifest:t,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()},p=await rr(d);this.mappingResult=p.mappingResult,this.analysisRawResponse=p.rawResponse,this.analysisParsedOk=p.parsed,this.analysisParseError=(s=p.parseError)!=null?s: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 fa(a,this.mappingResult,{onProgress:(s,o,l)=>{this.setStatus("apply",`Generating ${s}/${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(""),s=n?`
1641
1641
  <div class="vision-raw-block">
1642
1642
  <div class="inspector-text-sm" style="white-space: pre-wrap;">
1643
1643
  \u26A0\uFE0F AI response was not valid JSON (${this.analysisParseError||"unknown error"}).
@@ -1699,8 +1699,8 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1699
1699
  </div>
1700
1700
  </div>
1701
1701
  `}).join("")}
1702
- `}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 s=e.saveToLibrary?await this.saveToLibraryAndReturnPath(n,a.value):a.value;s&&(await this.stageEngineAssetOverride(n,s),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(s=>s.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(s=>s.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,s;if(!this.mappingResult||this.isGenerating)return;let t=this.mappingResult.mappings.find(r=>r.game_object===e);if(!t)return;if(t.action="GENERATE",!t.generation_prompt){t.status="Missing prompt",this.renderMappings();return}let i=(s=(a=(n=this.root)==null?void 0:n.querySelector("[data-vision-api-key]"))==null?void 0:a.value)==null?void 0:s.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 r={apiKey:i,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await ha(r,{mappings:[t]}),t.status=t.output_dataUrl?"Generated \u2713":t.status||"Done"}catch(r){console.error("[BrandVision] generateOne failed:",r),t.status="Failed \u2717"}finally{this.isGenerating=!1,this.renderMappings()}}async stageEngineAssetOverride(e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(Q(),Ie));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 s=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(!(s!=null&&s.success)||!(s!=null&&s.path))return console.error("[BrandVision] Save to library failed:",(s==null?void 0:s.error)||s),null;let r=window.addAssetToRegistry;typeof r=="function"&&r(i,n);let l=window.refreshAssetLibrary;return typeof l=="function"&&l(),String(s.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 s=n.slots.find(r=>r.slotId===e||r.currentAsset===e);if(s!=null&&s.category)return String(s.category)}let a=n==null?void 0:n.categories;if(Array.isArray(a)&&a.length>0){let s=e.toLowerCase(),r=l=>a.find(c=>c.toLowerCase().includes(l));return s.includes("bg")||s.includes("background")?r("background")||a[0]:(s.includes("cta")||s.includes("button")||s.includes("ui")||s.includes("logo"))&&r("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=r=>{let l=Math.max(300,n+(r.clientX-i));this.root.style.width=`${l}px`},s=()=>{window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",s)};window.addEventListener("pointermove",a),window.addEventListener("pointerup",s)})}refresh(){}};function yo(o,e={}){let{includeReference:t=!1,includeMagenta:i=!0,changeLevel:n=5}=e;return[`TASK: ${o}`,`CHANGE_STRENGTH: ${n}/10`,t?"REFERENCE: provided":"REFERENCE: none",i?"BACKGROUND: solid magenta #FF00FF (if possible)":""].filter(Boolean).join(`
1703
- `)}var fl=["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"],ml=["cta_hint","cta_label_end"],vo=[{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"}],bl=["brand.primary","brand.heading","brand.body","brand.warning"],tn=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`
1702
+ `}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 s=e.saveToLibrary?await this.saveToLibraryAndReturnPath(n,a.value):a.value;s&&(await this.stageEngineAssetOverride(n,s),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(s=>s.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(s=>s.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,s;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=(s=(a=(n=this.root)==null?void 0:n.querySelector("[data-vision-api-key]"))==null?void 0:a.value)==null?void 0:s.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 fa(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(()=>(ne(),Pe));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 s=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(!(s!=null&&s.success)||!(s!=null&&s.path))return console.error("[BrandVision] Save to library failed:",(s==null?void 0:s.error)||s),null;let o=window.addAssetToRegistry;typeof o=="function"&&o(i,n);let l=window.refreshAssetLibrary;return typeof l=="function"&&l(),String(s.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 s=n.slots.find(o=>o.slotId===e||o.currentAsset===e);if(s!=null&&s.category)return String(s.category)}let a=n==null?void 0:n.categories;if(Array.isArray(a)&&a.length>0){let s=e.toLowerCase(),o=l=>a.find(c=>c.toLowerCase().includes(l));return s.includes("bg")||s.includes("background")?o("background")||a[0]:(s.includes("cta")||s.includes("button")||s.includes("ui")||s.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`},s=()=>{window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",s)};window.addEventListener("pointermove",a),window.addEventListener("pointerup",s)})}refresh(){}};function yr(r,e={}){let{includeReference:t=!1,includeMagenta:i=!0,changeLevel:n=5}=e;return[`TASK: ${r}`,`CHANGE_STRENGTH: ${n}/10`,t?"REFERENCE: provided":"REFERENCE: none",i?"BACKGROUND: solid magenta #FF00FF (if possible)":""].filter(Boolean).join(`
1703
+ `)}var fl=["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"],ml=["cta_hint","cta_label_end"],vr=[{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"}],bl=["brand.primary","brand.heading","brand.body","brand.warning"],an=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`
1704
1704
  <div class="scene-panel customize-panel panel-accent-blue" data-panel="customize-settings">
1705
1705
  <div class="scene-panel-header" data-panel-handle>
1706
1706
  <div class="panel-title">
@@ -1758,17 +1758,17 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1758
1758
  </div>
1759
1759
  <div class="panel-resize-handle" data-panel-resize></div>
1760
1760
  </div>
1761
- `}initialize(e,t){var n,a,s,r,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=(s=this.root)==null?void 0:s.querySelector("[data-customize-fonts]"),this.textsContainer=(r=this.root)==null?void 0:r.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 s=t(a);s&&(s.ui||(s.ui={}),s.ui.renderMode=e?"png":"text",e&&(s.render||(s.render={}),s.render.asset||(s.render.asset={type:"image",path:""}),s.render.asset.type="image"),i(a,s))}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,s,r,l,c;let e=this.getEngineSnapshot();if(!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((r=(s=e.runtime)==null?void 0:s.ui)!=null?r:{}),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 s=document.createElement("span");s.className="customize-key",s.textContent=i;let r=document.createElement("input");r.type="text",r.value=n!=null?n:"",r.className="customize-input",r.dataset.assetKey=i,r.addEventListener("input",()=>{this.handleAssetValueChange(i,r)});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=`
1761
+ `}initialize(e,t){var n,a,s,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=(s=this.root)==null?void 0:s.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 s=t(a);s&&(s.ui||(s.ui={}),s.ui.renderMode=e?"png":"text",e&&(s.render||(s.render={}),s.render.asset||(s.render.asset={type:"image",path:""}),s.render.asset.type="image"),i(a,s))}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,s,o,l,c;let e=this.getEngineSnapshot();if(!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=(s=e.runtime)==null?void 0:s.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 s=document.createElement("span");s.className="customize-key",s.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=`
1762
1762
  <svg viewBox="0 0 24 24" aria-hidden="true">
1763
1763
  <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" />
1764
1764
  <circle cx="12" cy="12" r="3.2" />
1765
1765
  </svg>
1766
- `,c.addEventListener("click",()=>{this.previewAsset(i,r.value,r.dataset.assetType,p)});let d=document.createElement("button");d.type="button",d.className="customize-icon-btn",d.title="Upload asset",d.innerHTML=`
1766
+ `,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=`
1767
1767
  <svg viewBox="0 0 24 24" aria-hidden="true">
1768
1768
  <path d="M12 3l4 4h-3v6h-2V7H8l4-4z" />
1769
1769
  <path d="M5 14v4h14v-4h2v6H3v-6h2z" />
1770
1770
  </svg>
1771
- `;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,r,i)}),d.addEventListener("click",()=>p.click()),l.appendChild(c),l.appendChild(d),l.appendChild(p),a.appendChild(s),a.appendChild(r),a.appendChild(l),(u=this.assetsContainer)==null||u.appendChild(a)})}renderColors(e){this.colorsContainer&&(this.colorsContainer.innerHTML="",fl.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 s=document.createElement("input");s.type="color",s.value=i,s.dataset.colorKey=t;let r=document.createElement("input");r.type="text",r.value=i,r.className="customize-color-text",r.dataset.colorTextKey=t,s.addEventListener("input",()=>{r.value=s.value}),r.addEventListener("input",()=>{/^#([0-9a-fA-F]{6})$/.test(r.value)&&(s.value=r.value)}),n.appendChild(a),n.appendChild(s),n.appendChild(r),(d=this.colorsContainer)==null||d.appendChild(n)}))}renderFonts(e){this.fontsContainer&&(this.fontsContainer.innerHTML="",bl.forEach(t=>{var s,r;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=(s=e==null?void 0:e[t])!=null?s:t,a.className="customize-input",a.dataset.fontKey=t,i.appendChild(n),i.appendChild(a),(r=this.fontsContainer)==null||r.appendChild(i)}))}renderTexts(e){this.textsContainer&&(this.textsContainer.innerHTML="",ml.forEach(t=>{var s,r;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=(s=this.readUiValue(e,t))!=null?s:"",a.className="customize-input",a.dataset.textKey=t,i.appendChild(n),i.appendChild(a),(r=this.textsContainer)==null||r.appendChild(i)}),vo.forEach(({key:t,objectId:i})=>{var r,l;let n=document.createElement("div");n.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=t;let s=document.createElement("input");s.type="text",s.value=(r=this.getObjectTextValue(i))!=null?r:"",s.className="customize-input",s.dataset.objectTextKey=t,n.appendChild(a),n.appendChild(s),(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 r,l;let n=document.createElement("div");n.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=i.replace("_"," ");let s=document.createElement("input");s.type=i.includes("volume")?"number":"text",s.min="0",s.max="1",s.step="0.1",s.value=String((r=e==null?void 0:e[i])!=null?r:""),s.className="customize-input",s.dataset.audioKey=i,i.includes("file")&&(s.placeholder="audio file path"),n.appendChild(a),n.appendChild(s),(l=this.audioContainer)==null||l.appendChild(n)})}readUiValue(e,t){if(t.includes(".")){let n=t.split("."),a=e;for(let s of n){if(a==null)return null;a=a[s]}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("."),s=n;for(let r of a){if(s==null)return null;s=s[r]}return typeof s=="string"?s: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(r=>{let l=r;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(r=>{let l=r,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(r=>{let l=r,c=l.dataset.fontKey;c&&(n[c]=l.value)});let a={};this.root.querySelectorAll("[data-text-key]").forEach(r=>{let l=r,c=l.dataset.textKey;c&&(a[c]=l.value)});let s={};this.root.querySelectorAll("[data-audio-key]").forEach(r=>{let l=r,c=l.dataset.audioKey;if(c)if(c.includes("volume")){let d=parseFloat(l.value);s[c]=isNaN(d)?0:d}else s[c]=l.value}),this.root.querySelectorAll("[data-object-text-key]").forEach(r=>{let l=r,c=l.dataset.objectTextKey;if(!c)return;let d=vo.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:s}},{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 Xi(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,s;let t=(e==null?void 0:e.trim())||"";if(!t){let r=this.getSelectedAssetInput();t=(a=(n=r==null?void 0:r.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=(s=i==null?void 0:i.dataUrl)!=null?s: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 s=this.resolveAssetUrls(i);s[0]&&(a.src=s[0]);let r=document.createElement("span");r.className="ai-gallery-label",r.textContent=t,n.appendChild(a),n.appendChild(r),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 s,r;let i=t,n=i.dataset.assetKey,a=(r=(s=i.value)==null?void 0:s.trim())!=null?r:"";!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 r,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=`
1771
+ `;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(s),a.appendChild(o),a.appendChild(l),(u=this.assetsContainer)==null||u.appendChild(a)})}renderColors(e){this.colorsContainer&&(this.colorsContainer.innerHTML="",fl.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 s=document.createElement("input");s.type="color",s.value=i,s.dataset.colorKey=t;let o=document.createElement("input");o.type="text",o.value=i,o.className="customize-color-text",o.dataset.colorTextKey=t,s.addEventListener("input",()=>{o.value=s.value}),o.addEventListener("input",()=>{/^#([0-9a-fA-F]{6})$/.test(o.value)&&(s.value=o.value)}),n.appendChild(a),n.appendChild(s),n.appendChild(o),(d=this.colorsContainer)==null||d.appendChild(n)}))}renderFonts(e){this.fontsContainer&&(this.fontsContainer.innerHTML="",bl.forEach(t=>{var s,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=(s=e==null?void 0:e[t])!=null?s: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="",ml.forEach(t=>{var s,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=(s=this.readUiValue(e,t))!=null?s:"",a.className="customize-input",a.dataset.textKey=t,i.appendChild(n),i.appendChild(a),(o=this.textsContainer)==null||o.appendChild(i)}),vr.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 s=document.createElement("input");s.type="text",s.value=(o=this.getObjectTextValue(i))!=null?o:"",s.className="customize-input",s.dataset.objectTextKey=t,n.appendChild(a),n.appendChild(s),(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 s=document.createElement("input");s.type=i.includes("volume")?"number":"text",s.min="0",s.max="1",s.step="0.1",s.value=String((o=e==null?void 0:e[i])!=null?o:""),s.className="customize-input",s.dataset.audioKey=i,i.includes("file")&&(s.placeholder="audio file path"),n.appendChild(a),n.appendChild(s),(l=this.audioContainer)==null||l.appendChild(n)})}readUiValue(e,t){if(t.includes(".")){let n=t.split("."),a=e;for(let s of n){if(a==null)return null;a=a[s]}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("."),s=n;for(let o of a){if(s==null)return null;s=s[o]}return typeof s=="string"?s: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 s={};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);s[c]=isNaN(d)?0:d}else s[c]=l.value}),this.root.querySelectorAll("[data-object-text-key]").forEach(o=>{let l=o,c=l.dataset.objectTextKey;if(!c)return;let d=vr.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:s}},{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 Ji(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,s;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=(s=i==null?void 0:i.dataUrl)!=null?s: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 s=this.resolveAssetUrls(i);s[0]&&(a.src=s[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 s,o;let i=t,n=i.dataset.assetKey,a=(o=(s=i.value)==null?void 0:s.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=`
1772
1772
  <div class="ai-modal-card">
1773
1773
  <div class="ai-modal-header">
1774
1774
  <div>
@@ -1839,7 +1839,7 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1839
1839
  </div>
1840
1840
  </div>
1841
1841
  </div>
1842
- `;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]"),(r=this.aiRemoveBgToggle)==null||r.addEventListener("change",()=>{this.refreshAiOutputFromRaw()});let s=n.querySelector("[data-ai-ref-button]");s==null||s.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,I,P,_,T,M,k,A,C,L;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,s=n,r=Number((I=(w=this.aiStrengthInput)==null?void 0:w.value)!=null?I:"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())||((_=this.aiBaseValue)==null?void 0:_.trim())||"";this.setAiLoading(!0),this.setAiStatus(c?"Generating...":"Generating from scratch...");try{let x=null,E=null,S=(T=this.getSelectedAssetKey())!=null?T:"unknown",O=(M=this.aiUseOutputToggle)!=null&&M.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((k=this.aiUseOutputToggle)!=null&&k.checked&&this.aiOutputDataUrl){let B=pa(this.aiOutputDataUrl,"ai-output.png");if(B){let F=await Be(B);F&&(x={input:{base64:F.base64,mimeType:F.mimeType},dataUrl:F.dataUrl,width:F.width,height:F.height})}}!x&&c&&(x=await this.getImageDataFromAsset(c));let j=[];x&&j.push(x.input);let R=!1;if(this.aiReferenceFile){let B=await Be(this.aiReferenceFile);B?(E={input:{base64:B.base64,mimeType:B.mimeType},dataUrl:B.dataUrl,width:B.width,height:B.height},j.push(E.input),R=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let z=yo(i,{includeReference:R,includeMagenta:a,changeLevel:r}),D=(C=(A=this.aiReferenceFile)==null?void 0:A.name)!=null?C:"none";console.info("[AI] Final prompt:",z),console.info("[AI] Image sources:",{assetKey:S,base:O,reference:D});let q=x?ua(x.width,x.height):E?ua(E.width,E.height):"1:1";console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let G=await ft(e,z,j,{aspectRatio:q,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",G==null?void 0:G.length),this.aiRawOutputDataUrl=G,await this.refreshAiOutputFromRaw()}catch(x){console.error("[CustomizePanel] AI Generate Error:",x),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((L=this.aiStatusEl)==null?void 0:L.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var n,a,s,r;if(!this.aiRawOutputDataUrl)return;let e=(a=(n=this.aiRemoveBgToggle)==null?void 0:n.checked)!=null?a:!1,t=Number((r=(s=this.aiBgToleranceInput)==null?void 0:s.value)!=null?r:"30"),i=this.aiRawOutputDataUrl;if(e){let l=await ht(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||""),s=((n=this.aiContext)==null?void 0:n.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(a&&s)console.log("[CustomizePanel] Applying AI output directly to object:",a,s),this.applyObjectPropertyValue(a,s,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,s,r;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=((s=this.aiContext)==null?void 0:s.path)||this.inferPathFromAssetKey(this.aiTargetKey||""),f=this.getSelectedAssetInput();if(f&&(f.value=c.path,this.handleAssetValueChange((r=f.dataset.assetKey)!=null?r:"",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 s;let t=(s=this.aiContext)==null?void 0:s.objectId,i=e||this.aiTargetKey||"",n=window.getEditableAssets;if(typeof n=="function"){let r=n();if(r!=null&&r.slots){let l=r.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(s=>s.currentAsset===e||s.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 r;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}let e=this.getSelectedAssetInput(),t=(r=e==null?void 0:e.value)!=null?r:"",i=await this.getImageDimensions(t);if(!i){this.setAiStatus("Unable to read target dimensions.");return}let n=pa(this.aiOutputDataUrl,"ai-output.png");if(!n)return;let a=await this.showManualCropModal(n,i,t);if(!a)return;let s=await da(a);s&&this.setAiOutput(s)}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){var u,g,h,f,m;console.log("[CustomizePanel] Handling asset upload for:",i);let n=t.value,a=e;if(e.type.startsWith("image/")){let b=await this.getImageDimensions(n);if(b){let y=await this.showManualCropModal(e,b,n);if(!y)return;a=y}}let s=await da(a);if(!s){console.error("[CustomizePanel] Failed to convert file to data URL");return}let r=i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),l=((u=e.name.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/))==null?void 0:u[1])||"png",c=l==="jpg"?"jpeg":l,d=`${r}_uploaded_${Date.now()}.${c}`,p=this.inferCategoryFromAssetKey(i);console.log("[CustomizePanel] Saving uploaded file to library:",d,"category:",p);try{let y=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:p,filename:d,data:s,overwrite:!0})})).json();if(y.success){console.log("[CustomizePanel] \u2705 Uploaded file saved to library:",y.path),await new Promise(k=>setTimeout(k,100));let v=window.addAssetToRegistry;typeof v=="function"&&(v(p,d),console.log("[CustomizePanel] \u2705 Added to registry:",p,d));let w=window.getEditableAssets;if(typeof w=="function"){let k=w();k&&!k.categories&&(k.categories=[]),k!=null&&k.categories&&!k.categories.includes(p)&&(k.categories.push(p),console.log(`[CustomizePanel] Added category ${p} to registry`))}let I=!1,P=0,_=10;for(;!I&&P<_;){P++,console.log(`[CustomizePanel] Refresh attempt ${P}/${_}...`);try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&console.log("[CustomizePanel] \u2705 Registry rebuilt from disk")}catch(L){console.warn("[CustomizePanel] Setup-library not available:",L)}await new Promise(L=>setTimeout(L,300));let k=window.refreshAssetLibrary;typeof k=="function"&&(console.log("[CustomizePanel] Refreshing library panel..."),await k());let A=window.reRenderAssetLibrary;typeof A=="function"&&(console.log("[CustomizePanel] Re-rendering library panel..."),A());let C=window.getEditableAssets;if(typeof C=="function"){let L=C(),x=((g=L==null?void 0:L.libraryAssets)==null?void 0:g[p])||[];x.some(S=>(S==null?void 0:S.filename)===d)?(console.log("[CustomizePanel] \u2705 Asset found in registry!"),I=!0):(console.log(`[CustomizePanel] Asset not found yet, retrying... (found ${x.length} assets in ${p})`),await new Promise(S=>setTimeout(S,500)))}else P>=2&&(I=!0)}I||console.warn("[CustomizePanel] \u26A0\uFE0F Asset not found in registry after retries, proceeding anyway..."),t.value=y.path,this.handleAssetValueChange(i,t);let T=this.inferObjectIdFromAssetKey(i),M=this.inferPathFromAssetKey(i);if(T&&M){let k=!1,A=0,C=5;for(;!k&&A<C;){A++;try{console.log(`[CustomizePanel] Applying asset attempt ${A}/${C}...`);let x=window.applyAssetToSlot,E=/texture|image|sprite|asset\\.path/i.test(M)||/\\.(png|jpg|jpeg)$/i.test(String(y.path||""));if(typeof x=="function"&&E){let O=this.getFilenameFromPath(y.path);await x(T,O,p)}else this.applyObjectPropertyValue(T,M,y.path);await new Promise(O=>setTimeout(O,200));let S=window.getEditableObjectConfig;if(typeof S=="function"){let O=S(T),j=((f=(h=O==null?void 0:O.render)==null?void 0:h.asset)==null?void 0:f.path)||((m=O==null?void 0:O.ui)==null?void 0:m.image)||"";j===y.path||j.includes(d)?(console.log("[CustomizePanel] \u2705 Asset confirmed applied to object"),k=!0):(console.log(`[CustomizePanel] Asset not applied yet (attempt ${A}), retrying...`),await new Promise(R=>setTimeout(R,300)))}else k=!0}catch(x){console.error(`[CustomizePanel] Apply attempt ${A} failed:`,x),A<C&&await new Promise(E=>setTimeout(E,500))}}window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:T,action:"update",path:M}})),setTimeout(()=>{try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[CustomizePanel] Dispatched config:changed event")}catch(x){console.warn("[CustomizePanel] Failed to refresh textures:",x)}},300);let L=window.__highlightLibrarySlot;typeof L=="function"&&T&&setTimeout(()=>{L(T,p)},1e3),k?console.log("[CustomizePanel] \u2705 Upload complete and applied!"):console.warn("[CustomizePanel] \u26A0\uFE0F Upload succeeded but apply may have failed")}else console.log("[CustomizePanel] \u2705 Upload complete (no object context to apply)")}else console.error("[CustomizePanel] \u274C Upload save failed:",y.error),alert(`Failed to save uploaded file: ${y.error}`)}catch(b){console.error("[CustomizePanel] \u274C Upload error:",b),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 s=i||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=n!=null?n:null,this.openPreviewModal(e,t,a,s)}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=`
1842
+ `;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 s=n.querySelector("[data-ai-ref-button]");s==null||s.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,w;let b=(w=(y=this.aiStrengthInput)==null?void 0:y.value)!=null?w:"5";this.aiStrengthValue&&(this.aiStrengthValue.textContent=b)}),(d=this.aiBgToleranceInput)==null||d.addEventListener("input",()=>{var y,w;let b=(w=(y=this.aiBgToleranceInput)==null?void 0:y.value)!=null?w:"30";this.aiBgToleranceValue&&(this.aiBgToleranceValue.textContent=b),this.refreshAiOutputFromRaw()}),(p=this.aiReferenceInput)==null||p.addEventListener("change",()=>{var y,w,v;let b=(v=(w=(y=this.aiReferenceInput)==null?void 0:y.files)==null?void 0:w[0])!=null?v: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,w,v,P,I,_,k,j,L,x,S,E;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=(w=(y=this.aiRemoveBgToggle)==null?void 0:y.checked)!=null?w:!1,a=n,s=n,o=Number((P=(v=this.aiStrengthInput)==null?void 0:v.value)!=null?P:"5");if(!e){this.setAiStatus("Missing API key.");return}if(!i){this.setAiStatus("Add a prompt.");return}let l=this.getSelectedAssetInput(),c=((I=l==null?void 0:l.value)==null?void 0:I.trim())||((_=this.aiBaseValue)==null?void 0:_.trim())||"";this.setAiLoading(!0),this.setAiStatus(c?"Generating...":"Generating from scratch...");try{let C=null,A=null,T=(k=this.getSelectedAssetKey())!=null?k:"unknown",O=(j=this.aiUseOutputToggle)!=null&&j.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((L=this.aiUseOutputToggle)!=null&&L.checked&&this.aiOutputDataUrl){let H=ua(this.aiOutputDataUrl,"ai-output.png");if(H){let $=await Ge(H);$&&(C={input:{base64:$.base64,mimeType:$.mimeType},dataUrl:$.dataUrl,width:$.width,height:$.height})}}!C&&c&&(C=await this.getImageDataFromAsset(c));let M=[];C&&M.push(C.input);let R=!1;if(this.aiReferenceFile){let H=await Ge(this.aiReferenceFile);H?(A={input:{base64:H.base64,mimeType:H.mimeType},dataUrl:H.dataUrl,width:H.width,height:H.height},M.push(A.input),R=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let z=yr(i,{includeReference:R,includeMagenta:a,changeLevel:o}),F=(S=(x=this.aiReferenceFile)==null?void 0:x.name)!=null?S:"none";console.info("[AI] Final prompt:",z),console.info("[AI] Image sources:",{assetKey:T,base:O,reference:F});let q=C?ga(C.width,C.height):A?ga(A.width,A.height):"1:1";console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let N=await mt(e,z,M,{aspectRatio:q,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",N==null?void 0:N.length),this.aiRawOutputDataUrl=N,await this.refreshAiOutputFromRaw()}catch(C){console.error("[CustomizePanel] AI Generate Error:",C),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((E=this.aiStatusEl)==null?void 0:E.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var n,a,s,o;if(!this.aiRawOutputDataUrl)return;let e=(a=(n=this.aiRemoveBgToggle)==null?void 0:n.checked)!=null?a:!1,t=Number((o=(s=this.aiBgToleranceInput)==null?void 0:s.value)!=null?o:"30"),i=this.aiRawOutputDataUrl;if(e){let l=await ft(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||""),s=((n=this.aiContext)==null?void 0:n.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(a&&s)console.log("[CustomizePanel] Applying AI output directly to object:",a,s),this.applyObjectPropertyValue(a,s,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,s,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=((s=this.aiContext)==null?void 0:s.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 w=this.getFilenameFromPath(c.path);await b(g,w,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 s;let t=(s=this.aiContext)==null?void 0:s.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(s=>s.currentAsset===e||s.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=ua(this.aiOutputDataUrl,"ai-output.png");if(!n)return;let a=await this.showManualCropModal(n,i,t);if(!a)return;let s=await pa(a);s&&this.setAiOutput(s)}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){var u,g,h,f,m;console.log("[CustomizePanel] Handling asset upload for:",i);let n=t.value,a=e;if(e.type.startsWith("image/")){let b=await this.getImageDimensions(n);if(b){let y=await this.showManualCropModal(e,b,n);if(!y)return;a=y}}let s=await pa(a);if(!s){console.error("[CustomizePanel] Failed to convert file to data URL");return}let o=i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""),l=((u=e.name.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/))==null?void 0:u[1])||"png",c=l==="jpg"?"jpeg":l,d=`${o}_uploaded_${Date.now()}.${c}`,p=this.inferCategoryFromAssetKey(i);console.log("[CustomizePanel] Saving uploaded file to library:",d,"category:",p);try{let y=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:p,filename:d,data:s,overwrite:!0})})).json();if(y.success){console.log("[CustomizePanel] \u2705 Uploaded file saved to library:",y.path),await new Promise(L=>setTimeout(L,100));let w=window.addAssetToRegistry;typeof w=="function"&&(w(p,d),console.log("[CustomizePanel] \u2705 Added to registry:",p,d));let v=window.getEditableAssets;if(typeof v=="function"){let L=v();L&&!L.categories&&(L.categories=[]),L!=null&&L.categories&&!L.categories.includes(p)&&(L.categories.push(p),console.log(`[CustomizePanel] Added category ${p} to registry`))}let P=!1,I=0,_=10;for(;!P&&I<_;){I++,console.log(`[CustomizePanel] Refresh attempt ${I}/${_}...`);try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&console.log("[CustomizePanel] \u2705 Registry rebuilt from disk")}catch(E){console.warn("[CustomizePanel] Setup-library not available:",E)}await new Promise(E=>setTimeout(E,300));let L=window.refreshAssetLibrary;typeof L=="function"&&(console.log("[CustomizePanel] Refreshing library panel..."),await L());let x=window.reRenderAssetLibrary;typeof x=="function"&&(console.log("[CustomizePanel] Re-rendering library panel..."),x());let S=window.getEditableAssets;if(typeof S=="function"){let E=S(),C=((g=E==null?void 0:E.libraryAssets)==null?void 0:g[p])||[];C.some(T=>(T==null?void 0:T.filename)===d)?(console.log("[CustomizePanel] \u2705 Asset found in registry!"),P=!0):(console.log(`[CustomizePanel] Asset not found yet, retrying... (found ${C.length} assets in ${p})`),await new Promise(T=>setTimeout(T,500)))}else I>=2&&(P=!0)}P||console.warn("[CustomizePanel] \u26A0\uFE0F Asset not found in registry after retries, proceeding anyway..."),t.value=y.path,this.handleAssetValueChange(i,t);let k=this.inferObjectIdFromAssetKey(i),j=this.inferPathFromAssetKey(i);if(k&&j){let L=!1,x=0,S=5;for(;!L&&x<S;){x++;try{console.log(`[CustomizePanel] Applying asset attempt ${x}/${S}...`);let C=window.applyAssetToSlot,A=/texture|image|sprite|asset\\.path/i.test(j)||/\\.(png|jpg|jpeg)$/i.test(String(y.path||""));if(typeof C=="function"&&A){let O=this.getFilenameFromPath(y.path);await C(k,O,p)}else this.applyObjectPropertyValue(k,j,y.path);await new Promise(O=>setTimeout(O,200));let T=window.getEditableObjectConfig;if(typeof T=="function"){let O=T(k),M=((f=(h=O==null?void 0:O.render)==null?void 0:h.asset)==null?void 0:f.path)||((m=O==null?void 0:O.ui)==null?void 0:m.image)||"";M===y.path||M.includes(d)?(console.log("[CustomizePanel] \u2705 Asset confirmed applied to object"),L=!0):(console.log(`[CustomizePanel] Asset not applied yet (attempt ${x}), retrying...`),await new Promise(R=>setTimeout(R,300)))}else L=!0}catch(C){console.error(`[CustomizePanel] Apply attempt ${x} failed:`,C),x<S&&await new Promise(A=>setTimeout(A,500))}}window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:k,action:"update",path:j}})),setTimeout(()=>{try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[CustomizePanel] Dispatched config:changed event")}catch(C){console.warn("[CustomizePanel] Failed to refresh textures:",C)}},300);let E=window.__highlightLibrarySlot;typeof E=="function"&&k&&setTimeout(()=>{E(k,p)},1e3),L?console.log("[CustomizePanel] \u2705 Upload complete and applied!"):console.warn("[CustomizePanel] \u26A0\uFE0F Upload succeeded but apply may have failed")}else console.log("[CustomizePanel] \u2705 Upload complete (no object context to apply)")}else console.error("[CustomizePanel] \u274C Upload save failed:",y.error),alert(`Failed to save uploaded file: ${y.error}`)}catch(b){console.error("[CustomizePanel] \u274C Upload error:",b),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 s=i||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=n!=null?n:null,this.openPreviewModal(e,t,a,s)}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=`
1843
1843
  <div class="asset-preview-card">
1844
1844
  <div class="asset-preview-header">
1845
1845
  <div class="asset-preview-title">${e}</div>
@@ -1855,7 +1855,7 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1855
1855
  <img class="asset-preview-ai-image" alt="AI output preview">
1856
1856
  </div>
1857
1857
  </div>
1858
- `;let s=a.querySelector(".asset-preview-body"),r=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(r==null||r.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()}),s)if(n==="image"){let p=document.createElement("img");this.loadWithFallback(p,i),s.appendChild(p)}else if(n==="audio"){let p=document.createElement("audio");p.controls=!0,this.loadWithFallback(p,i),s.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."}),s.appendChild(p)}else{let p=document.createElement("a");p.href=i[0],p.target="_blank",p.rel="noreferrer",p.textContent="Open asset",s.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 s=n(e);if(!s)return;let r=JSON.parse(JSON.stringify(s)),l=t.split("."),c=r;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,r)}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 s=a.clientX,r=(g=(u=this.root)==null?void 0:u.getBoundingClientRect().width)!=null?g:0,l=260,c=620,d=h=>{let f=h.clientX-s,m=Math.min(c,Math.max(l,r+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),s=null;try{if(s=await this.loadImage(a),!(s!=null&&s.naturalWidth)||!(s!=null&&s.naturalHeight))return console.error("[CustomizePanel] Failed to load image for crop:",e.name),URL.revokeObjectURL(a),null;console.log("[CustomizePanel] Image loaded for crop:",s.naturalWidth,"x",s.naturalHeight)}catch(l){return console.error("[CustomizePanel] Error loading image:",l),URL.revokeObjectURL(a),null}let r=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=`
1858
+ `;let s=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()}),s)if(n==="image"){let p=document.createElement("img");this.loadWithFallback(p,i),s.appendChild(p)}else if(n==="audio"){let p=document.createElement("audio");p.controls=!0,this.loadWithFallback(p,i),s.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."}),s.appendChild(p)}else{let p=document.createElement("a");p.href=i[0],p.target="_blank",p.rel="noreferrer",p.textContent="Open asset",s.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 s=n(e);if(!s)return;let o=JSON.parse(JSON.stringify(s)),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 s=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-s,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),s=null;try{if(s=await this.loadImage(a),!(s!=null&&s.naturalWidth)||!(s!=null&&s.naturalHeight))return console.error("[CustomizePanel] Failed to load image for crop:",e.name),URL.revokeObjectURL(a),null;console.log("[CustomizePanel] Image loaded for crop:",s.naturalWidth,"x",s.naturalHeight)}catch(l){return console.error("[CustomizePanel] Error loading image:",l),URL.revokeObjectURL(a),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=`
1859
1859
  <div class="asset-crop-card" style="width:${d}px;">
1860
1860
  <div class="asset-crop-header">
1861
1861
  <div>
@@ -1885,7 +1885,7 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1885
1885
  <button class="asset-crop-apply" type="button">Apply Crop</button>
1886
1886
  </div>
1887
1887
  </div>
1888
- `;let y=c.querySelector(".asset-crop-canvas"),v=c.querySelector(".asset-crop-preview"),w=c.querySelector(".asset-crop-zoom"),I=c.querySelector(".asset-crop-zoom-value"),P=c.querySelector(".asset-crop-close"),_=c.querySelector(".asset-crop-cancel"),T=c.querySelector(".asset-crop-apply"),M=c.querySelector(".asset-crop-reset");if(!y||!v||!w||!I){l(null);return}let k=y.getContext("2d"),A=v.getContext("2d");if(!k||!A){l(null);return}let C=s.naturalWidth,L=s.naturalHeight,x=Math.max(y.width/C,y.height/L),E=1,S=0,O=0,j=!1,R=0,z=0,D=0,q=0,G=()=>{let H=x*E,ae=Math.max(0,(C*H-y.width)/2),te=Math.max(0,(L*H-y.height)/2);S=Math.min(ae,Math.max(-ae,S)),O=Math.min(te,Math.max(-te,O))},B=()=>{if(!s||!s.complete||s.naturalWidth===0||s.naturalHeight===0){console.warn("[CustomizePanel] Image not ready for drawing"),k.fillStyle="rgba(128, 128, 128, 0.3)",k.fillRect(0,0,y.width,y.height),k.fillStyle="rgba(255, 255, 255, 0.5)",k.font="14px sans-serif",k.textAlign="center",k.fillText("Loading image...",y.width/2,y.height/2);return}let H=x*E;k.clearRect(0,0,y.width,y.height);let ae=y.width/2-C*H/2+S,te=y.height/2-L*H/2+O;try{k.drawImage(s,ae,te,C*H,L*H)}catch(Re){console.error("[CustomizePanel] Error drawing image:",Re),k.fillStyle="rgba(255, 0, 0, 0.3)",k.fillRect(0,0,y.width,y.height),k.fillStyle="#ff0000",k.font="14px sans-serif",k.textAlign="center",k.fillText("Error drawing image",y.width/2,y.height/2)}if(A.clearRect(0,0,v.width,v.height),r!=null&&r.naturalWidth&&(r!=null&&r.naturalHeight)){let Re=Math.max(v.width/r.naturalWidth,v.height/r.naturalHeight),Cn=v.width/2-r.naturalWidth*Re/2,kt=v.height/2-r.naturalHeight*Re/2;A.drawImage(r,Cn,kt,r.naturalWidth*Re,r.naturalHeight*Re)}else A.fillStyle="rgba(255, 255, 255, 0.04)",A.fillRect(0,0,v.width,v.height),A.strokeStyle="rgba(255, 255, 255, 0.08)",A.strokeRect(4,4,v.width-8,v.height-8);let ie=v.width/y.width*(x*E),Oe=S*(v.width/y.width),ge=O*(v.height/y.height),Sn=v.width/2-C*ie/2+Oe,En=v.height/2-L*ie/2+ge;A.save(),A.globalAlpha=.7,A.drawImage(s,Sn,En,C*ie,L*ie),A.restore()},F=()=>{S=0,O=0,G(),B()};w.addEventListener("input",()=>{E=Number(w.value),I.textContent=`${E.toFixed(2)}\xD7`,G(),B()}),y.addEventListener("pointerdown",H=>{j=!0,R=H.clientX,z=H.clientY,D=S,q=O,y.setPointerCapture(H.pointerId)}),y.addEventListener("pointermove",H=>{j&&(S=D+(H.clientX-R),O=q+(H.clientY-z),G(),B())}),y.addEventListener("pointerup",H=>{j=!1,y.releasePointerCapture(H.pointerId)}),y.addEventListener("pointerleave",()=>{j=!1});let U=()=>{c.remove();try{URL.revokeObjectURL(a)}catch{}},Z=()=>{U(),l(null)},ee=async()=>{let H=document.createElement("canvas");H.width=t.width,H.height=t.height;let ae=H.getContext("2d");if(!ae){U(),l(null);return}let te=E,Oe=Math.max(H.width/C,H.height/L)*te,ge=H.width/y.width,Sn=S*ge,En=O*ge,Re=H.width/2-C*Oe/2+Sn,Cn=H.height/2-L*Oe/2+En;ae.drawImage(s,Re,Cn,C*Oe,L*Oe);let kt=await new Promise(ir=>{H.toBlob(nr=>ir(nr),e.type||"image/png")});if(U(),!kt){l(null);return}l(new File([kt],e.name,{type:kt.type}))};P==null||P.addEventListener("click",Z),_==null||_.addEventListener("click",Z),M==null||M.addEventListener("click",F),T==null||T.addEventListener("click",()=>{ee()}),c.addEventListener("click",H=>{H.target===c&&Z()}),document.body.appendChild(c),s.complete&&s.naturalWidth>0&&s.naturalHeight>0?F():(s.onload=()=>{console.log("[CustomizePanel] Image fully loaded, drawing crop modal"),F()},s.onerror=()=>{console.error("[CustomizePanel] Image failed to load"),U(),l(null)})})}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 nn=class{constructor(){this.root=null;this.options=null}render(){return`
1888
+ `;let y=c.querySelector(".asset-crop-canvas"),w=c.querySelector(".asset-crop-preview"),v=c.querySelector(".asset-crop-zoom"),P=c.querySelector(".asset-crop-zoom-value"),I=c.querySelector(".asset-crop-close"),_=c.querySelector(".asset-crop-cancel"),k=c.querySelector(".asset-crop-apply"),j=c.querySelector(".asset-crop-reset");if(!y||!w||!v||!P){l(null);return}let L=y.getContext("2d"),x=w.getContext("2d");if(!L||!x){l(null);return}let S=s.naturalWidth,E=s.naturalHeight,C=Math.max(y.width/S,y.height/E),A=1,T=0,O=0,M=!1,R=0,z=0,F=0,q=0,N=()=>{let G=C*A,W=Math.max(0,(S*G-y.width)/2),Z=Math.max(0,(E*G-y.height)/2);T=Math.min(W,Math.max(-W,T)),O=Math.min(Z,Math.max(-Z,O))},H=()=>{if(!s||!s.complete||s.naturalWidth===0||s.naturalHeight===0){console.warn("[CustomizePanel] Image not ready for drawing"),L.fillStyle="rgba(128, 128, 128, 0.3)",L.fillRect(0,0,y.width,y.height),L.fillStyle="rgba(255, 255, 255, 0.5)",L.font="14px sans-serif",L.textAlign="center",L.fillText("Loading image...",y.width/2,y.height/2);return}let G=C*A;L.clearRect(0,0,y.width,y.height);let W=y.width/2-S*G/2+T,Z=y.height/2-E*G/2+O;try{L.drawImage(s,W,Z,S*G,E*G)}catch(ze){console.error("[CustomizePanel] Error drawing image:",ze),L.fillStyle="rgba(255, 0, 0, 0.3)",L.fillRect(0,0,y.width,y.height),L.fillStyle="#ff0000",L.font="14px sans-serif",L.textAlign="center",L.fillText("Error drawing image",y.width/2,y.height/2)}if(x.clearRect(0,0,w.width,w.height),o!=null&&o.naturalWidth&&(o!=null&&o.naturalHeight)){let ze=Math.max(w.width/o.naturalWidth,w.height/o.naturalHeight),An=w.width/2-o.naturalWidth*ze/2,kt=w.height/2-o.naturalHeight*ze/2;x.drawImage(o,An,kt,o.naturalWidth*ze,o.naturalHeight*ze)}else x.fillStyle="rgba(255, 255, 255, 0.04)",x.fillRect(0,0,w.width,w.height),x.strokeStyle="rgba(255, 255, 255, 0.08)",x.strokeRect(4,4,w.width-8,w.height-8);let ae=w.width/y.width*(C*A),oe=T*(w.width/y.width),Re=O*(w.height/y.height),Q=w.width/2-S*ae/2+oe,Cn=w.height/2-E*ae/2+Re;x.save(),x.globalAlpha=.7,x.drawImage(s,Q,Cn,S*ae,E*ae),x.restore()},$=()=>{T=0,O=0,N(),H()};v.addEventListener("input",()=>{A=Number(v.value),P.textContent=`${A.toFixed(2)}\xD7`,N(),H()}),y.addEventListener("pointerdown",G=>{M=!0,R=G.clientX,z=G.clientY,F=T,q=O,y.setPointerCapture(G.pointerId)}),y.addEventListener("pointermove",G=>{M&&(T=F+(G.clientX-R),O=q+(G.clientY-z),N(),H())}),y.addEventListener("pointerup",G=>{M=!1,y.releasePointerCapture(G.pointerId)}),y.addEventListener("pointerleave",()=>{M=!1});let U=()=>{c.remove();try{URL.revokeObjectURL(a)}catch{}},Y=()=>{U(),l(null)},V=async()=>{let G=document.createElement("canvas");G.width=t.width,G.height=t.height;let W=G.getContext("2d");if(!W){U(),l(null);return}let Z=A,oe=Math.max(G.width/S,G.height/E)*Z,Re=G.width/y.width,Q=T*Re,Cn=O*Re,ze=G.width/2-S*oe/2+Q,An=G.height/2-E*oe/2+Cn;W.drawImage(s,ze,An,S*oe,E*oe);let kt=await new Promise(io=>{G.toBlob(no=>io(no),e.type||"image/png")});if(U(),!kt){l(null);return}l(new File([kt],e.name,{type:kt.type}))};I==null||I.addEventListener("click",Y),_==null||_.addEventListener("click",Y),j==null||j.addEventListener("click",$),k==null||k.addEventListener("click",()=>{V()}),c.addEventListener("click",G=>{G.target===c&&Y()}),document.body.appendChild(c),s.complete&&s.naturalWidth>0&&s.naturalHeight>0?$():(s.onload=()=>{console.log("[CustomizePanel] Image fully loaded, drawing crop modal"),$()},s.onerror=()=>{console.error("[CustomizePanel] Image failed to load"),U(),l(null)})})}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 sn=class{constructor(){this.root=null;this.options=null}render(){return`
1889
1889
  <div class="scene-panel loading-screen-panel panel-accent-purple" data-panel="loading-screen">
1890
1890
  <div class="scene-panel-header" data-panel-handle>
1891
1891
  <div class="panel-title">
@@ -1951,10 +1951,10 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1951
1951
  </div>
1952
1952
  </div>
1953
1953
  </div>
1954
- `}initialize(e,t){var y,v,w,I,P,_,T,M,k,A,C,L,x,E,S,O;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let n=(()=>{var R;let j=window.getEditableEngineConfig;if(typeof j=="function"){let z=j();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 j,R;(R=(j=this.options)==null?void 0:j.onUpdateLoading)==null||R.call(j,{type:a.value}),this.updateFieldVisibility(a.value)}));let s=(v=this.root)==null?void 0:v.querySelector("#loading-background-color");s&&(s.value=n.background_color||"#160a17",s.addEventListener("input",()=>{var j,R;(R=(j=this.options)==null?void 0:j.onUpdateLoading)==null||R.call(j,{background_color:s.value})}));let r=(w=this.root)==null?void 0:w.querySelector("#loading-overlay-alpha"),l=(I=this.root)==null?void 0:I.querySelector("#loading-overlay-alpha-value");r&&(r.value=String((P=n.overlay_alpha)!=null?P:1),l&&(l.textContent=Number(r.value).toFixed(2)),r.addEventListener("input",()=>{var R,z;let j=Number(r.value);l&&(l.textContent=j.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{overlay_alpha:j})}));let c=(_=this.root)==null?void 0:_.querySelector("#loading-text");c&&(c.value=n.text||"",c.addEventListener("input",()=>{var j,R;(R=(j=this.options)==null?void 0:j.onUpdateLoading)==null||R.call(j,{text:c.value})}));let d=(T=this.root)==null?void 0:T.querySelector("#loading-text-scale"),p=(M=this.root)==null?void 0:M.querySelector("#loading-text-scale-value");d&&(d.value=String((k=n.text_scale)!=null?k:.6),p&&(p.textContent=Number(d.value).toFixed(2)),d.addEventListener("input",()=>{var R,z;let j=Number(d.value);p&&(p.textContent=j.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{text_scale:j})}));let u=(A=this.root)==null?void 0:A.querySelector("#loading-enabled");u&&(u.checked=n.enabled!==!1,u.addEventListener("change",()=>{var j,R;(R=(j=this.options)==null?void 0:j.onUpdateLoading)==null||R.call(j,{enabled:u.checked})}));let g=(C=this.root)==null?void 0:C.querySelector("#loading-blur-enabled");g&&(g.checked=n.blur_enabled!==!1,g.addEventListener("change",()=>{var j,R;(R=(j=this.options)==null?void 0:j.onUpdateLoading)==null||R.call(j,{blur_enabled:g.checked})}));let h=(L=this.root)==null?void 0:L.querySelector("#loading-blur-strength"),f=(x=this.root)==null?void 0:x.querySelector("#loading-blur-strength-value");h&&(h.value=String((E=n.blur_strength)!=null?E:8),f&&(f.textContent=h.value),h.addEventListener("input",()=>{var j,R;f&&(f.textContent=h.value),(R=(j=this.options)==null?void 0:j.onUpdateLoading)==null||R.call(j,{blur_strength:Number(h.value)})}));let m=(S=this.root)==null?void 0:S.querySelector("#loading-show-btn"),b=(O=this.root)==null?void 0:O.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var j,R;(R=(j=this.options)==null?void 0:j.onShowLoadingScreen)==null||R.call(j)}),b==null||b.addEventListener("click",()=>{var j,R;(R=(j=this.options)==null?void 0:j.onHideLoadingScreen)==null||R.call(j)}),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 qt=require("pixi.js");var fa=require("pixi.js"),Ge=()=>window.debugConfig||{},wo=()=>window.resolveAnchorVec2||(o=>({x:.5,y:.5})),xo=()=>window.resolveScreenAnchorPoint||(()=>new fa.Point),So=()=>window.resolveScreenRatioPoint||(()=>new fa.Point);function Eo(o){an(o)&&(o.objectDebugRaf||(o.objectDebugRaf=window.requestAnimationFrame(()=>sn(o))))}function Co(o){o.objectDebugRaf&&(window.cancelAnimationFrame(o.objectDebugRaf),o.objectDebugRaf=null),Ut(o)}function an(o){return o.isDebugOpen}function sn(o){var a,s,r;if(!an(o)){o.objectDebugRaf=null;return}o.objectDebugRaf=window.requestAnimationFrame(()=>sn(o));let e=ma(o);if(!e){Gt(o,null),Ut(o);return}let t=ba(o,e);if(!t){Gt(o,null),Ut(o);return}let i=new qt.Point;(a=t.getGlobalPosition)==null||a.call(t,i);let n=ya(o,t);Gt(o,{instanceId:e,worldX:i.x,worldY:i.y,configX:(s=n==null?void 0:n.x)!=null?s:null,configY:(r=n==null?void 0:n.y)!=null?r:null}),o.highlightObject?Sa(o,t):Ca(o),o.highlightAnchor&&n?Ea(o,n):Aa(o)}function ma(o){var n;let e=o.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 ba(o,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 Vt(o){let e=o.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function ya(o,e){var s,r;let t=Vt(o);if(!t)return null;let i=(s=t.transform)!=null?s:{},n=va(o);if(!n)return null;if(i.position_ratio!=null)return So()(n.width,n.height,i.position_ratio);let a=(r=i.anchor)!=null?r:"bottom-center";return a==="bottom-center"&&i.anchor==null&&console.log("[DEBUG FALLBACK] objectVisuals transform.anchor \u2192 bottom-center"),xo()(n.width,n.height,a)}function va(o){var a;let e=(a=o.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 wa(o){let e=window.gameApp;return e!=null&&e.stage?(o.objectBoundsGfx&&o.objectBoundsGfx.parent!==e.stage&&(o.objectBoundsGfx.destroy(),o.objectBoundsGfx=null),o.objectBoundsGfx||(o.objectBoundsGfx=new qt.Graphics,o.objectBoundsGfx.zIndex=999999,e.stage.addChild(o.objectBoundsGfx)),o.objectBoundsGfx):null}function xa(o){let e=window.gameApp;return e!=null&&e.stage?(o.objectAnchorGfx&&o.objectAnchorGfx.parent!==e.stage&&(o.objectAnchorGfx.destroy(),o.objectAnchorGfx=null),o.objectAnchorGfx||(o.objectAnchorGfx=new qt.Graphics,o.objectAnchorGfx.zIndex=1e6,e.stage.addChild(o.objectAnchorGfx)),o.objectAnchorGfx):null}function Sa(o,e){var n;let t=wa(o);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 Ea(o,e){let t=xa(o);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 Ca(o){o.objectBoundsGfx&&o.objectBoundsGfx.clear()}function Aa(o){o.objectAnchorGfx&&o.objectAnchorGfx.clear()}function Ut(o){o.objectBoundsGfx&&(o.objectBoundsGfx.destroy(),o.objectBoundsGfx=null),o.objectAnchorGfx&&(o.objectAnchorGfx.destroy(),o.objectAnchorGfx=null)}function Gt(o,e){o.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function Ao(o,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,o)}function Lo(o,e,t){var s;let i=e.split("."),n=i.pop(),a=o;for(let r of i)a[r]=(s=a[r])!=null?s:{},a=a[r];a[n]=t}function La(o){var i,n,a,s,r;if(!o)return!1;if((i=o.transform)!=null&&i.offset)return!0;let e=((a=(n=o.identity)==null?void 0:n.category)!=null?a:"").toString().toLowerCase(),t=((r=(s=o.identity)==null?void 0:s.id)!=null?r:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function rn(o){let e=Ge();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 To(o){window.location.reload()}function ln(o){let e=JSON.stringify(Ge(),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 ko(o,e){var t,i,n;if(!(!o.configViewer||!o.container))try{let a=window.getEditableObjectConfig,s=typeof a=="function"?a(e):null;if(!s){let{loadObjectCentricConfig:r,loadObjectConfig:l}=await Promise.resolve().then(()=>(Ti(),Vs)),p=(((t=(await r("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),on(o,u),(i=o.configViewer)==null||i.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,s),on(o,s),(n=o.configViewer)==null||n.style.setProperty("display","block");return}catch(a){console.error("[DEBUG] Failed to load object config:",a)}}function on(o,e){var u,g,h,f,m,b,y,v,w,I;if(!o.container)return;let t=o.container.querySelector("#config-pos-x"),i=o.container.querySelector("#config-pos-y"),n=o.container.querySelector("#config-scale"),a=o.container.querySelector("#config-anchor-preset"),s=o.container.querySelector("#config-anchor-x"),r=o.container.querySelector("#config-anchor-y"),c=La(e)?(u=e.transform)==null?void 0:u.offset:(g=e.transform)==null?void 0:g.position;t&&(t.value=String((h=c==null?void 0:c.x)!=null?h:0)),i&&(i.value=String((f=c==null?void 0:c.y)!=null?f:0)),n&&(n.value=String((b=(m=e.transform)==null?void 0:m.scale)!=null?b:1));let d=(I=(w=(y=e.transform)==null?void 0:y.anchor)!=null?w:(v=e.render)==null?void 0:v.anchor)!=null?I:"center";if(a){typeof d=="string"?a.value=d:a.value="custom";let P=o.container.querySelectorAll(".anchor-custom-field"),_=a.value==="custom";P.forEach(T=>T.style.display=_?"block":"none")}let p=wo()(d);s&&(s.value=String(p.x)),r&&(r.value=String(p.y))}function Io(o){var l,c,d,p,u,g,h,f,m,b;let e=o.selectedObjectId;if(!e||!o.container)return;let t=(c=(l=o.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",i=(p=(d=o.container.querySelector("#config-pos-y"))==null?void 0:d.value)!=null?p:"0",n=(g=(u=o.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",a=(f=(h=o.container.querySelector("#config-anchor-x"))==null?void 0:h.value)!=null?f:"0.5",s=(b=(m=o.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",r=`${e}:
1954
+ `}initialize(e,t){var y,w,v,P,I,_,k,j,L,x,S,E,C,A,T,O;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let n=(()=>{var R;let M=window.getEditableEngineConfig;if(typeof M=="function"){let z=M();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 M,R;(R=(M=this.options)==null?void 0:M.onUpdateLoading)==null||R.call(M,{type:a.value}),this.updateFieldVisibility(a.value)}));let s=(w=this.root)==null?void 0:w.querySelector("#loading-background-color");s&&(s.value=n.background_color||"#160a17",s.addEventListener("input",()=>{var M,R;(R=(M=this.options)==null?void 0:M.onUpdateLoading)==null||R.call(M,{background_color:s.value})}));let o=(v=this.root)==null?void 0:v.querySelector("#loading-overlay-alpha"),l=(P=this.root)==null?void 0:P.querySelector("#loading-overlay-alpha-value");o&&(o.value=String((I=n.overlay_alpha)!=null?I:1),l&&(l.textContent=Number(o.value).toFixed(2)),o.addEventListener("input",()=>{var R,z;let M=Number(o.value);l&&(l.textContent=M.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{overlay_alpha:M})}));let c=(_=this.root)==null?void 0:_.querySelector("#loading-text");c&&(c.value=n.text||"",c.addEventListener("input",()=>{var M,R;(R=(M=this.options)==null?void 0:M.onUpdateLoading)==null||R.call(M,{text:c.value})}));let d=(k=this.root)==null?void 0:k.querySelector("#loading-text-scale"),p=(j=this.root)==null?void 0:j.querySelector("#loading-text-scale-value");d&&(d.value=String((L=n.text_scale)!=null?L:.6),p&&(p.textContent=Number(d.value).toFixed(2)),d.addEventListener("input",()=>{var R,z;let M=Number(d.value);p&&(p.textContent=M.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{text_scale:M})}));let u=(x=this.root)==null?void 0:x.querySelector("#loading-enabled");u&&(u.checked=n.enabled!==!1,u.addEventListener("change",()=>{var M,R;(R=(M=this.options)==null?void 0:M.onUpdateLoading)==null||R.call(M,{enabled:u.checked})}));let g=(S=this.root)==null?void 0:S.querySelector("#loading-blur-enabled");g&&(g.checked=n.blur_enabled!==!1,g.addEventListener("change",()=>{var M,R;(R=(M=this.options)==null?void 0:M.onUpdateLoading)==null||R.call(M,{blur_enabled:g.checked})}));let h=(E=this.root)==null?void 0:E.querySelector("#loading-blur-strength"),f=(C=this.root)==null?void 0:C.querySelector("#loading-blur-strength-value");h&&(h.value=String((A=n.blur_strength)!=null?A:8),f&&(f.textContent=h.value),h.addEventListener("input",()=>{var M,R;f&&(f.textContent=h.value),(R=(M=this.options)==null?void 0:M.onUpdateLoading)==null||R.call(M,{blur_strength:Number(h.value)})}));let m=(T=this.root)==null?void 0:T.querySelector("#loading-show-btn"),b=(O=this.root)==null?void 0:O.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var M,R;(R=(M=this.options)==null?void 0:M.onShowLoadingScreen)==null||R.call(M)}),b==null||b.addEventListener("click",()=>{var M,R;(R=(M=this.options)==null?void 0:M.onHideLoadingScreen)==null||R.call(M)}),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 Vt=require("pixi.js");var ma=require("pixi.js"),Ue=()=>window.debugConfig||{},wr=()=>window.resolveAnchorVec2||(r=>({x:.5,y:.5})),xr=()=>window.resolveScreenAnchorPoint||(()=>new ma.Point),Sr=()=>window.resolveScreenRatioPoint||(()=>new ma.Point);function Er(r){rn(r)&&(r.objectDebugRaf||(r.objectDebugRaf=window.requestAnimationFrame(()=>on(r))))}function Cr(r){r.objectDebugRaf&&(window.cancelAnimationFrame(r.objectDebugRaf),r.objectDebugRaf=null),qt(r)}function rn(r){return r.isDebugOpen}function on(r){var a,s,o;if(!rn(r)){r.objectDebugRaf=null;return}r.objectDebugRaf=window.requestAnimationFrame(()=>on(r));let e=ba(r);if(!e){Ut(r,null),qt(r);return}let t=ya(r,e);if(!t){Ut(r,null),qt(r);return}let i=new Vt.Point;(a=t.getGlobalPosition)==null||a.call(t,i);let n=va(r,t);Ut(r,{instanceId:e,worldX:i.x,worldY:i.y,configX:(s=n==null?void 0:n.x)!=null?s:null,configY:(o=n==null?void 0:n.y)!=null?o:null}),r.highlightObject?Ea(r,t):Aa(r),r.highlightAnchor&&n?Ca(r,n):La(r)}function ba(r){var n;let e=r.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 ya(r,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 Yt(r){let e=r.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function va(r,e){var s,o;let t=Yt(r);if(!t)return null;let i=(s=t.transform)!=null?s:{},n=wa(r);if(!n)return null;if(i.position_ratio!=null)return Sr()(n.width,n.height,i.position_ratio);let a=(o=i.anchor)!=null?o:"bottom-center";return a==="bottom-center"&&i.anchor==null&&console.log("[DEBUG FALLBACK] objectVisuals transform.anchor \u2192 bottom-center"),xr()(n.width,n.height,a)}function wa(r){var a;let e=(a=r.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 xa(r){let e=window.gameApp;return e!=null&&e.stage?(r.objectBoundsGfx&&r.objectBoundsGfx.parent!==e.stage&&(r.objectBoundsGfx.destroy(),r.objectBoundsGfx=null),r.objectBoundsGfx||(r.objectBoundsGfx=new Vt.Graphics,r.objectBoundsGfx.zIndex=999999,e.stage.addChild(r.objectBoundsGfx)),r.objectBoundsGfx):null}function Sa(r){let e=window.gameApp;return e!=null&&e.stage?(r.objectAnchorGfx&&r.objectAnchorGfx.parent!==e.stage&&(r.objectAnchorGfx.destroy(),r.objectAnchorGfx=null),r.objectAnchorGfx||(r.objectAnchorGfx=new Vt.Graphics,r.objectAnchorGfx.zIndex=1e6,e.stage.addChild(r.objectAnchorGfx)),r.objectAnchorGfx):null}function Ea(r,e){var n;let t=xa(r);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 Ca(r,e){let t=Sa(r);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 Aa(r){r.objectBoundsGfx&&r.objectBoundsGfx.clear()}function La(r){r.objectAnchorGfx&&r.objectAnchorGfx.clear()}function qt(r){r.objectBoundsGfx&&(r.objectBoundsGfx.destroy(),r.objectBoundsGfx=null),r.objectAnchorGfx&&(r.objectAnchorGfx.destroy(),r.objectAnchorGfx=null)}function Ut(r,e){r.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function Ar(r,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,r)}function Lr(r,e,t){var s;let i=e.split("."),n=i.pop(),a=r;for(let o of i)a[o]=(s=a[o])!=null?s:{},a=a[o];a[n]=t}function Ta(r){var i,n,a,s,o;if(!r)return!1;if((i=r.transform)!=null&&i.offset)return!0;let e=((a=(n=r.identity)==null?void 0:n.category)!=null?a:"").toString().toLowerCase(),t=((o=(s=r.identity)==null?void 0:s.id)!=null?o:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function cn(r){let e=Ue();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 Tr(r){window.location.reload()}function dn(r){let e=JSON.stringify(Ue(),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 Ir(r,e){var t,i,n;if(!(!r.configViewer||!r.container))try{let a=window.getEditableObjectConfig,s=typeof a=="function"?a(e):null;if(!s){let{loadObjectCentricConfig:o,loadObjectConfig:l}=await Promise.resolve().then(()=>(Ii(),Ys)),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),ln(r,u),(i=r.configViewer)==null||i.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,s),ln(r,s),(n=r.configViewer)==null||n.style.setProperty("display","block");return}catch(a){console.error("[DEBUG] Failed to load object config:",a)}}function ln(r,e){var u,g,h,f,m,b,y,w,v,P;if(!r.container)return;let t=r.container.querySelector("#config-pos-x"),i=r.container.querySelector("#config-pos-y"),n=r.container.querySelector("#config-scale"),a=r.container.querySelector("#config-anchor-preset"),s=r.container.querySelector("#config-anchor-x"),o=r.container.querySelector("#config-anchor-y"),c=Ta(e)?(u=e.transform)==null?void 0:u.offset:(g=e.transform)==null?void 0:g.position;t&&(t.value=String((h=c==null?void 0:c.x)!=null?h:0)),i&&(i.value=String((f=c==null?void 0:c.y)!=null?f:0)),n&&(n.value=String((b=(m=e.transform)==null?void 0:m.scale)!=null?b:1));let d=(P=(v=(y=e.transform)==null?void 0:y.anchor)!=null?v:(w=e.render)==null?void 0:w.anchor)!=null?P:"center";if(a){typeof d=="string"?a.value=d:a.value="custom";let I=r.container.querySelectorAll(".anchor-custom-field"),_=a.value==="custom";I.forEach(k=>k.style.display=_?"block":"none")}let p=wr()(d);s&&(s.value=String(p.x)),o&&(o.value=String(p.y))}function kr(r){var l,c,d,p,u,g,h,f,m,b;let e=r.selectedObjectId;if(!e||!r.container)return;let t=(c=(l=r.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",i=(p=(d=r.container.querySelector("#config-pos-y"))==null?void 0:d.value)!=null?p:"0",n=(g=(u=r.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",a=(f=(h=r.container.querySelector("#config-anchor-x"))==null?void 0:h.value)!=null?f:"0.5",s=(b=(m=r.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",o=`${e}:
1955
1955
  position: (${t}, ${i})
1956
1956
  scale: ${n}
1957
- anchor: (${a}, ${s})`;navigator.clipboard.writeText(r).then(()=>console.log("[DEBUG] Config values copied to clipboard")).catch(y=>console.error("[DEBUG] Failed to copy config values:",y))}async function Ta(o,e){var u,g,h,f,m,b,y,v,w,I,P,_;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!o.container)return;let t=o.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let i=Number((g=(u=o.container.querySelector("#config-pos-x"))==null?void 0:u.value)!=null?g:0),n=Number((f=(h=o.container.querySelector("#config-pos-y"))==null?void 0:h.value)!=null?f:0),a=Number((b=(m=o.container.querySelector("#config-scale"))==null?void 0:m.value)!=null?b:1),s=(v=(y=o.container.querySelector("#config-anchor-preset"))==null?void 0:y.value)!=null?v:"center",r=Number((I=(w=o.container.querySelector("#config-anchor-x"))==null?void 0:w.value)!=null?I:.5),l=Number((_=(P=o.container.querySelector("#config-anchor-y"))==null?void 0:P.value)!=null?_:.5),c=s==="custom"?{x:r,y:l}:s;console.log("[INSPECTOR] Applying config for:",t,{posX:i,posY:n,scale:a,anchor:c});let{applyConfigOverride:d}=await Promise.resolve().then(()=>(Q(),Ie));d({objectId:t,path:"transform.position",value:{x:i,y:n}},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.scale",value:a},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.anchor",value:c},{silent:e==null?void 0:e.silent});let p=Vt(o);La(p)&&d({objectId:t,path:"transform.offset",value:{x:i,y:n}},{silent:!0})}async function Po(o,e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(Q(),Ie));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)),s=(t==null?void 0:t.source)!=="auto"&&!a,r=window.__previewShell;s&&(r!=null&&r.refresh)&&r.refresh()}function Mo(o){o.selectedObjectId&&(o.objectAutoApplyTimer&&window.clearTimeout(o.objectAutoApplyTimer),o.objectAutoApplyTimer=window.setTimeout(()=>{o.objectAutoApplyTimer=null,Ta(o,{silent:!0})},150))}var yl=3e3;function tt(o,e,t){let i=t!=null?t:o.offsetParent;if(!i)return;e.style.cursor="move";let n=!1,a=0,s=0,r=0,l=0,c=0,d=0,p=g=>{if(!n)return;let h=i.getBoundingClientRect();o.style.left=`${g.clientX-h.left-c}px`,o.style.top=`${g.clientY-h.top-d}px`},u=()=>{n&&(n=!1,o.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=o.getBoundingClientRect(),m=i.getBoundingClientRect();console.log("[DRAG] Panel:",o.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}),o.style.left=`${b}px`,o.style.top=`${y}px`,o.style.right="auto",o.style.bottom="auto",o.style.zIndex=String(++yl),n=!0,o.classList.add("dragging"),window.addEventListener("pointermove",p),window.addEventListener("pointerup",u)})}function cn(o,e,t,i=280,n=200){e.style.cursor="nwse-resize";let a=0,s=0,r=0,l=0,c=!1,d=u=>{var y;if(!c)return;let g=u.clientX-r,h=u.clientY-l,f=Math.max(i,a+g),m=Math.max(n,s+h);o.style.width=`${f}px`,(y=o.closest(".preview-shell"))!=null&&y.classList.contains("layout-fixed")||(o.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=o.getBoundingClientRect();a=g.width,s=g.height,r=u.clientX,l=u.clientY,c=!0,window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)})}function ka(o,e){var f,m,b,y;let t=(b=(m=(f=o.container)==null?void 0:f.querySelector("#debug-overlay"))!=null?m:o.debugOverlay)!=null?b:e.offsetParent;if(!t||(y=o.container)!=null&&y.classList.contains("layout-fixed"))return;let i=t.getBoundingClientRect(),n=e.getBoundingClientRect(),a=12,s=Math.max(250,Math.floor(i.width-a*2)),r=Math.max(200,Math.floor(i.height-a*2));n.width>s&&(e.style.width=`${s}px`),n.height>r&&(e.style.height=`${r}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 bt(o){var i,n;if(!o.container)return;let e=o.container.querySelector("#debug-workbench");if(!e)return;if(ka(o,e),(i=o.container)!=null&&i.classList.contains("layout-fixed")){let a=localStorage.getItem("preview_workbench_state"),s={activeTab:o.activeTab};if(a)try{s={...JSON.parse(a),activeTab:o.activeTab}}catch{}localStorage.setItem("preview_workbench_state",JSON.stringify(s));return}let t={activeTab:o.activeTab,width:e.style.width,height:(n=o.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 dn(o){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(o.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var n,a;let i=(n=o.container)==null?void 0:n.querySelector("#debug-workbench");if(i){let s=(a=o.container)==null?void 0:a.classList.contains("layout-fixed");t.width&&(i.style.width=t.width),t.height&&!s?i.style.height=t.height:s&&(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"),ka(o,i)}})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function Ia(o,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",ka(o,e),bt(o))}function jo(o){var n,a,s;if(!o.container)return;let e=o.container,t=e.querySelector("#debug-toggle");t||console.warn("[PREVIEW] Debug toggle not found in DOM"),t==null||t.addEventListener("click",()=>{var r;console.log("[PREVIEW] Debug toggle clicked"),(r=o.toggleDebug)==null||r.call(o)}),(n=e.querySelector("#debug-close"))==null||n.addEventListener("click",()=>{var r;return(r=o.toggleDebug)==null?void 0:r.call(o,!1)}),(a=e.querySelector("#debug-reset"))==null||a.addEventListener("click",()=>rn(o)),(s=e.querySelector("#debug-export"))==null||s.addEventListener("click",()=>ln(o)),e.querySelectorAll(".workbench-tab").forEach(r=>{r.addEventListener("click",()=>{let l=r.dataset.tab;o.activeTab=l,Pa(o),bt(o)})}),ja(o,e),Ma(o,e)}function Pa(o){var n,a;if(!o.container)return;let e=o.container;e.querySelectorAll(".workbench-tab").forEach(s=>{let r=s.dataset.tab;s.classList.toggle("active",r===o.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(s=>{let r=s.dataset.tabPanel;s.classList.toggle("active",r===o.activeTab)}),o.activeTab==="library"&&o.libraryPanel&&((a=(n=o.libraryPanel).resetSearch)==null||a.call(n))}function Ma(o,e){fe(o,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),fe(o,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),fe(o,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),fe(o,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),fe(o,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),fe(o,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),fe(o,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),fe(o,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),fe(o,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=Ge();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),s=Ge();s.layout&&(s.layout.debug_rect_color=Number.isFinite(a)?a:16711680)})}function _o(o){if(!o.container||!o.debugOverlay)return;let e=o.container.querySelector("#debug-workbench"),t=o.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"),tt(e,t,o.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{bt(o),Ia(o,e)},10)}));let i=o.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"),tt(i,n,o.debugOverlay),n.addEventListener("pointerup",()=>{setTimeout(()=>{Ia(o,i)},10)})),i&&a&&cn(i,a);let s=o.container.querySelector('[data-panel="scene-tools-corner"]'),r=s==null?void 0:s.querySelector("[data-panel-handle]");s&&r&&tt(s,r,o.debugOverlay);let l=o.container.querySelector('[data-panel="nudge-panel"]'),c=l==null?void 0:l.querySelector("[data-panel-handle]");l&&c&&tt(l,c,o.debugOverlay),dn(o)}function ja(o,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 fe(o,e,t,i,n){let a=e.querySelector(`#${t}`),s=e.querySelector(n);if(!a||!s)return;let r=Ao(Ge(),i);typeof r=="number"&&(a.value=String(r),s.textContent=String(r)),a.addEventListener("input",()=>{let l=Number(a.value);s.textContent=String(l),Lo(Ge(),i,l)})}Q();var pn=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async forceResyncAfterApply(){var e;try{let t=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:t})})}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=He(),{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 s=localStorage.getItem("handler_last_applied"),r=s?new Date(parseInt(s)).toLocaleString():"Never",l=this.currentVersion?`Version: ${this.currentVersion} (Active)`:"Original",c=this.currentVersion?`Versioned (${this.currentVersion})`:"Global";return`
1957
+ anchor: (${a}, ${s})`;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 Ia(r,e){var u,g,h,f,m,b,y,w,v,P,I,_;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!r.container)return;let t=r.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let i=Number((g=(u=r.container.querySelector("#config-pos-x"))==null?void 0:u.value)!=null?g:0),n=Number((f=(h=r.container.querySelector("#config-pos-y"))==null?void 0:h.value)!=null?f:0),a=Number((b=(m=r.container.querySelector("#config-scale"))==null?void 0:m.value)!=null?b:1),s=(w=(y=r.container.querySelector("#config-anchor-preset"))==null?void 0:y.value)!=null?w:"center",o=Number((P=(v=r.container.querySelector("#config-anchor-x"))==null?void 0:v.value)!=null?P:.5),l=Number((_=(I=r.container.querySelector("#config-anchor-y"))==null?void 0:I.value)!=null?_:.5),c=s==="custom"?{x:o,y:l}:s;console.log("[INSPECTOR] Applying config for:",t,{posX:i,posY:n,scale:a,anchor:c});let{applyConfigOverride:d}=await Promise.resolve().then(()=>(ne(),Pe));d({objectId:t,path:"transform.position",value:{x:i,y:n}},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.scale",value:a},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.anchor",value:c},{silent:e==null?void 0:e.silent});let p=Yt(r);Ta(p)&&d({objectId:t,path:"transform.offset",value:{x:i,y:n}},{silent:!0})}async function Pr(r,e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(ne(),Pe));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)),s=(t==null?void 0:t.source)!=="auto"&&!a,o=window.__previewShell;s&&(o!=null&&o.refresh)&&o.refresh()}function Mr(r){r.selectedObjectId&&(r.objectAutoApplyTimer&&window.clearTimeout(r.objectAutoApplyTimer),r.objectAutoApplyTimer=window.setTimeout(()=>{r.objectAutoApplyTimer=null,Ia(r,{silent:!0})},150))}var yl=3e3;function it(r,e,t){let i=t!=null?t:r.offsetParent;if(!i)return;e.style.cursor="move";let n=!1,a=0,s=0,o=0,l=0,c=0,d=0,p=g=>{if(!n)return;let h=i.getBoundingClientRect();r.style.left=`${g.clientX-h.left-c}px`,r.style.top=`${g.clientY-h.top-d}px`},u=()=>{n&&(n=!1,r.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=r.getBoundingClientRect(),m=i.getBoundingClientRect();console.log("[DRAG] Panel:",r.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}),r.style.left=`${b}px`,r.style.top=`${y}px`,r.style.right="auto",r.style.bottom="auto",r.style.zIndex=String(++yl),n=!0,r.classList.add("dragging"),window.addEventListener("pointermove",p),window.addEventListener("pointerup",u)})}function pn(r,e,t,i=280,n=200){e.style.cursor="nwse-resize";let a=0,s=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,s+h);r.style.width=`${f}px`,(y=r.closest(".preview-shell"))!=null&&y.classList.contains("layout-fixed")||(r.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=r.getBoundingClientRect();a=g.width,s=g.height,o=u.clientX,l=u.clientY,c=!0,window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)})}function ka(r,e){var f,m,b,y;let t=(b=(m=(f=r.container)==null?void 0:f.querySelector("#debug-overlay"))!=null?m:r.debugOverlay)!=null?b:e.offsetParent;if(!t||(y=r.container)!=null&&y.classList.contains("layout-fixed"))return;let i=t.getBoundingClientRect(),n=e.getBoundingClientRect(),a=12,s=Math.max(250,Math.floor(i.width-a*2)),o=Math.max(200,Math.floor(i.height-a*2));n.width>s&&(e.style.width=`${s}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 yt(r){var i,n;if(!r.container)return;let e=r.container.querySelector("#debug-workbench");if(!e)return;if(ka(r,e),(i=r.container)!=null&&i.classList.contains("layout-fixed")){let a=localStorage.getItem("preview_workbench_state"),s={activeTab:r.activeTab};if(a)try{s={...JSON.parse(a),activeTab:r.activeTab}}catch{}localStorage.setItem("preview_workbench_state",JSON.stringify(s));return}let t={activeTab:r.activeTab,width:e.style.width,height:(n=r.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 un(r){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(r.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var n,a;let i=(n=r.container)==null?void 0:n.querySelector("#debug-workbench");if(i){let s=(a=r.container)==null?void 0:a.classList.contains("layout-fixed");t.width&&(i.style.width=t.width),t.height&&!s?i.style.height=t.height:s&&(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"),ka(r,i)}})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function Pa(r,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",ka(r,e),yt(r))}function jr(r){var n,a,s;if(!r.container)return;let e=r.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=r.toggleDebug)==null||o.call(r)}),(n=e.querySelector("#debug-close"))==null||n.addEventListener("click",()=>{var o;return(o=r.toggleDebug)==null?void 0:o.call(r,!1)}),(a=e.querySelector("#debug-reset"))==null||a.addEventListener("click",()=>cn(r)),(s=e.querySelector("#debug-export"))==null||s.addEventListener("click",()=>dn(r)),e.querySelectorAll(".workbench-tab").forEach(o=>{o.addEventListener("click",()=>{let l=o.dataset.tab;r.activeTab=l,Ma(r),yt(r)})}),_a(r,e),ja(r,e)}function Ma(r){var n,a;if(!r.container)return;let e=r.container;e.querySelectorAll(".workbench-tab").forEach(s=>{let o=s.dataset.tab;s.classList.toggle("active",o===r.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(s=>{let o=s.dataset.tabPanel;s.classList.toggle("active",o===r.activeTab)}),r.activeTab==="library"&&r.libraryPanel&&((a=(n=r.libraryPanel).resetSearch)==null||a.call(n))}function ja(r,e){me(r,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),me(r,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),me(r,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),me(r,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),me(r,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),me(r,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),me(r,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),me(r,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),me(r,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=Ue();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),s=Ue();s.layout&&(s.layout.debug_rect_color=Number.isFinite(a)?a:16711680)})}function _r(r){if(!r.container||!r.debugOverlay)return;let e=r.container.querySelector("#debug-workbench"),t=r.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"),it(e,t,r.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{yt(r),Pa(r,e)},10)}));let i=r.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"),it(i,n,r.debugOverlay),n.addEventListener("pointerup",()=>{setTimeout(()=>{Pa(r,i)},10)})),i&&a&&pn(i,a);let s=r.container.querySelector('[data-panel="scene-tools-corner"]'),o=s==null?void 0:s.querySelector("[data-panel-handle]");s&&o&&it(s,o,r.debugOverlay);let l=r.container.querySelector('[data-panel="nudge-panel"]'),c=l==null?void 0:l.querySelector("[data-panel-handle]");l&&c&&it(l,c,r.debugOverlay),un(r)}function _a(r,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 me(r,e,t,i,n){let a=e.querySelector(`#${t}`),s=e.querySelector(n);if(!a||!s)return;let o=Ar(Ue(),i);typeof o=="number"&&(a.value=String(o),s.textContent=String(o)),a.addEventListener("input",()=>{let l=Number(a.value);s.textContent=String(l),Lr(Ue(),i,l)})}ne();var gn=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async forceResyncAfterApply(){var e;try{let t=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:t})})}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=Fe(),{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 s=localStorage.getItem("handler_last_applied"),o=s?new Date(parseInt(s)).toLocaleString():"Never",l=this.currentVersion?`Version: ${this.currentVersion} (Active)`:"Original",c=this.currentVersion?`Versioned (${this.currentVersion})`:"Global";return`
1958
1958
  <div class="config-persistence-panel">
1959
1959
  <!-- Status Footer (Always Visible) -->
1960
1960
  <div class="persistence-status-footer">
@@ -1972,7 +1972,7 @@ Generate the requested asset matching the brand style.${o.needsTransparency?" Ba
1972
1972
  </div>
1973
1973
  <div class="status-footer-row">
1974
1974
  <span class="status-footer-label">Last Applied:</span>
1975
- <span class="status-footer-value">${r}</span>
1975
+ <span class="status-footer-value">${o}</span>
1976
1976
  </div>
1977
1977
  </div>
1978
1978
 
@@ -2118,17 +2118,17 @@ This will delete generated config JSON files in configs/objects that are not ref
2118
2118
 
2119
2119
  It will NOT touch library/base configs.
2120
2120
 
2121
- 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(!He().hasChanges){alert("No changes to save. Make some edits first.");return}if(confirm(`Save As New Version?
2121
+ 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(!Fe().hasChanges){alert("No changes to save. Make some edits first.");return}if(confirm(`Save As New Version?
2122
2122
 
2123
2123
  This will:
2124
2124
  \u2022 Create a new version snapshot
2125
2125
  \u2022 Include all current changes
2126
2126
  \u2022 Clear staged overrides after save
2127
- \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 xi(b),pe(),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||window.__handlerApplyCurrentInFlight)return;let u=this.currentVersion?`version "${this.currentVersion}"`:"Original configs";if(confirm(`Apply to Current Source?
2127
+ \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 Si(b),ge(),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||window.__handlerApplyCurrentInFlight)return;let u=this.currentVersion?`version "${this.currentVersion}"`:"Original configs";if(confirm(`Apply to Current Source?
2128
2128
 
2129
2129
  This will write all staged changes to ${u}.
2130
2130
 
2131
- After applying, staged overrides will be cleared.`))try{window.__handlerApplyCurrentInFlight=!0,i.textContent="\u23F3 Applying...",i.setAttribute("disabled","true");let h=Je(),f={};for(let[y,v]of Object.entries(h.objects)){let w=v,I=y;/^(json\.|ui\.|effects\.|engine\.)/.test(I)||(I=`json.${y}`),w&&typeof w=="object"&&(w.identity||(w.identity={}),w.identity.id=I),f[`objects/${I}.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")}pe();try{let y=window.__editableConfig;y&&(window.__editableConfigBaseline=X(y))}catch{}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")}finally{window.__handlerApplyCurrentInFlight=!1}});let n=this.container.querySelector("#apply-base-btn");n==null||n.addEventListener("click",async()=>{if(confirm(`\u26A0\uFE0F DANGER: APPLY TO BASE
2131
+ After applying, staged overrides will be cleared.`))try{window.__handlerApplyCurrentInFlight=!0,i.textContent="\u23F3 Applying...",i.setAttribute("disabled","true");let h=Ze(),f={};for(let[y,w]of Object.entries(h.objects)){let v=w,P=y;/^(json\.|ui\.|effects\.|engine\.)/.test(P)||(P=`json.${y}`),v&&typeof v=="object"&&(v.identity||(v.identity={}),v.identity.id=P),f[`objects/${P}.json`]=v}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,w]of Object.entries(h.scenes)){let v=y.startsWith("scene.")?y:`scene.${y}`;f[`scenes/${v}.json`]=w}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")}ge();try{let y=window.__editableConfig;y&&(window.__editableConfigBaseline=te(y))}catch{}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")}finally{window.__handlerApplyCurrentInFlight=!1}});let n=this.container.querySelector("#apply-base-btn");n==null||n.addEventListener("click",async()=>{if(confirm(`\u26A0\uFE0F DANGER: APPLY TO BASE
2132
2132
 
2133
2133
  This will DIRECTLY MODIFY base configuration files.
2134
2134
 
@@ -2138,25 +2138,25 @@ This is ONLY for active development.
2138
2138
 
2139
2139
  Make sure your project is under Git version control.
2140
2140
 
2141
- Continue?`))try{n.textContent="\u23F3 Writing to base...",n.setAttribute("disabled","true");let g=Je(),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")}pe(),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;zt(h||void 0,g)})});let r=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.")&&(pe(),$t(),this.refreshPanel())};r==null||r.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 Si()})}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=`
2141
+ Continue?`))try{n.textContent="\u23F3 Writing to base...",n.setAttribute("disabled","true");let g=Ze(),h={};for(let[m,b]of Object.entries(g.objects)){let y=b,w=m;/^(json\.|ui\.|effects\.|engine\.)/.test(w)||(w=`json.${m}`),y&&typeof y=="object"&&(y.identity||(y.identity={}),y.identity.id=w),h[`objects/${w}.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")}ge(),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;$t(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.")&&(ge(),Dt(),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?")&&Dt()});let p=this.container.querySelector("#reset-to-original-btn");p==null||p.addEventListener("click",async()=>{await Ei()})}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=`
2142
2142
  <div class="notify-icon">\u2705</div>
2143
2143
  <div class="notify-content">
2144
2144
  <strong>${i}</strong>
2145
2145
  <span>Project files updated.</span>
2146
2146
  </div>
2147
- `,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,s;let t=He();if(t.hasChanges){if(!confirm(`Switch to version "${e||"original"}"?
2147
+ `,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,s;let t=Fe();if(t.hasChanges){if(!confirm(`Switch to version "${e||"original"}"?
2148
2148
 
2149
2149
  You have ${t.overrideCount} staged changes that will be discarded.
2150
2150
 
2151
2151
  Options:
2152
2152
  OK = Discard staged overrides and switch
2153
- 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 r=await fetch("/api/switch-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({versionName:e||null})});if(!r.ok){let l=await r.json();throw new Error(l.error||"Failed to switch version")}pe(),localStorage.removeItem("handler_config_overrides"),localStorage.setItem("handler_preview_override_mode","false"),window.location.reload()}catch(r){alert(`\u274C Failed to switch version: ${r.message}`);let l=(s=this.container)==null?void 0:s.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
2153
+ 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")}ge(),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=(s=this.container)==null?void 0:s.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
2154
2154
 
2155
2155
  This will DIRECTLY MODIFY your base configuration files WITHOUT creating a snapshot.
2156
2156
 
2157
2157
  This cannot be undone unless you have git commits or backups.
2158
2158
 
2159
- Are you absolutely sure?`))try{let t=Je(),i={};for(let[a,s]of Object.entries(t.objects)){let r=s,l=a;/^(json\.|ui\.|effects\.|engine\.)/.test(l)||(l=`json.${a}`),r&&typeof r=="object"&&(r.identity||(r.identity={}),r.identity.id=l),i[`objects/${l}.json`]=r}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,s]of Object.entries(t.scenes)){let r=a.startsWith("scene.")?a:`scene.${a}`;i[`scenes/${r}.json`]=s}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")}pe(),this.showSuccessNotification(),this.refreshPanel()}catch(t){console.error("[ConfigPersistence] Direct apply failed:",t),alert(`\u274C Direct apply failed: ${t.message}`)}}};var Yt=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 _i;this.sceneToolsPanel=new Oi;this.nudgePanel=new Ri;this.inspectorPanel=new Ki;this.libraryPanel=new Bt;this.libraryPanelDocked=new Bt;this.brandVisionPanel=new en;this.customizeSettingsPanel=new tn;this.configPersistencePanel=new pn;this.loadingScreenPanel=new nn}applyAssetChange(e,t){return go(this,e,t)}resetAsset(e){return ho(this,e)}applySlotAsset(e,t,i){return Zi(this,e,t,i)}resetSlotAsset(e,t,i){return fo(this,e,t,i)}startObjectVisuals(){return Eo(this)}stopObjectVisuals(){return Co(this)}shouldRunObjectVisuals(){return an(this)}updateObjectVisuals(){return sn(this)}getSelectedInstanceId(){return ma(this)}getDisplayObjectById(e){return ba(this,e)}getSelectedObjectConfig(){return Vt(this)}getConfigAnchorWorldPoint(e){return ya(this,e)}getScreenSize(){return va(this)}ensureBoundsGfx(){return wa(this)}ensureAnchorGfx(){return xa(this)}drawBounds(e){return Sa(this,e)}drawAnchor(e){return Ea(this,e)}clearBounds(){return Ca(this)}clearAnchor(){return Aa(this)}clearObjectVisuals(){return Ut(this)}updateObjectInfo(e){return Gt(this,e)}resetDebugConfig(){return rn(this)}applyDebugConfig(){return To(this)}exportDebugConfig(){return ln(this)}loadObjectConfig(e){return ko(this,e)}fillConfigViewer(e){return on(this,e)}copyConfigValues(){return Io(this)}applyObjectConfig(e){return Ta(this,e)}applyCustomizeSettings(e,t){return Po(this,e,t)}scheduleObjectAutoApply(){return Mo(this)}setupDebugEventListeners(){return jo(this)}setupDebugInputListeners(e){return Ma(this,e)}setupPanelLayout(){return _o(this)}setupCollapsiblePanels(e){return ja(this,e)}setupRangeInput(e,t,i,n){return fe(this,e,t,i,n)}updateWorkbenchTabs(){return Pa(this)}saveWorkbenchState(){return bt(this)}loadWorkbenchState(){return dn(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 s=JSON.parse(a);s.activeTab&&(this.activeTab=s.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,s,r)=>this.applySlotAsset(a,s,r),onReset:(a,s,r)=>this.resetSlotAsset(a,s,r)});let t=e.querySelector("#dock-library-content");t&&(t.innerHTML=this.libraryPanelDocked.render(),this.libraryPanelDocked.initialize(t,{onApply:(a,s,r)=>this.applySlotAsset(a,s,r),onReset:(a,s,r)=>this.resetSlotAsset(a,s,r)})),this.inspectorPanel.initialize(e,{onPropertyChange:(a,s,r)=>{console.log("[Inspector] Property changed:",a,s,r)}}),this.brandVisionPanel.initialize(e,()=>{this.toggleDebug(!1);let a="/dashboard";window.location.pathname!==a&&(window.location.href=a)}),this.customizeSettingsPanel.initialize(e,{onApply:(a,s)=>this.applyCustomizeSettings(a,s)}),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,s)=>this.nudgeSelectedObject(a,s),onShowSplash:()=>{let a=window;typeof a.__previewShowSplash=="function"&&a.__previewShowSplash()},onUpdateSplash:a=>{let s=window;typeof s.applyEditableEngineConfig=="function"&&s.applyEditableEngineConfig({splash:a})}}),this.nudgePanel.initialize(e,{onNudge:async(a,s)=>{var u,g,h;if(!this.selectedObjectId)return;let r=this.getSelectedObjectConfig();if(!r)return;let l=(u=r.transform)==null?void 0:u.position,c=((g=l==null?void 0:l.x)!=null?g:0)+a,d=((h=l==null?void 0:l.y)!=null?h:0)+s,{applyConfigOverride:p}=await Promise.resolve().then(()=>(Q(),Ie));p({objectId:this.selectedObjectId,path:"transform.position",value:{x:c,y:d}},{silent:!0,emitEvent:!0}),window.dispatchEvent(new CustomEvent("inspector:refresh"))},onScale:async a=>{var d,p;if(!this.selectedObjectId)return;let s=this.getSelectedObjectConfig();if(!s)return;let r=(p=(d=s.transform)==null?void 0:d.scale)!=null?p:1,l=Math.max(.1,r+a),{applyConfigOverride:c}=await Promise.resolve().then(()=>(Q(),Ie));c({objectId:this.selectedObjectId,path:"transform.scale",value:l},{silent:!0,emitEvent:!0}),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 s=window;typeof s.applyEditableEngineConfig=="function"&&s.applyEditableEngineConfig({loading:a}),typeof s.__previewUpdateLoading=="function"?s.__previewUpdateLoading(a):console.warn("[DEBUG] __previewUpdateLoading not available")}}),window.__openAiEditor=(a,s,r,l)=>{this.customizeSettingsPanel.openAiEditor(a,s,r,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.__getSelectedObjectId=()=>this.selectedObjectId,window.addEventListener("config:changed",a=>{var s,r;((s=a.detail)==null?void 0:s.action)!=="remove"&&((r=a.detail)==null?void 0:r.action)!=="clear_object"&&this.highlightChangesTab()}),window.applyAssetToSlot=(a,s,r)=>this.applySlotAsset(a,s,r),window.refreshAssetLibrary=()=>Promise.all([this.libraryPanel.refresh(),this.libraryPanelDocked.refresh()]),window.reRenderAssetLibrary=()=>{this.libraryPanel.reRender(),this.libraryPanelDocked.reRender()},window.getEngineSplashConfig=()=>{var s;let a=window.getActiveConfig;if(typeof a=="function"){let r=a();return((s=r==null?void 0:r.engine)==null?void 0:s.splash)||null}return null},window.addAssetToRegistry=(a,s)=>{let r=window.getEditableAssets;if(typeof r=="function"){let l=r();if(l!=null&&l.libraryAssets&&(l.libraryAssets[a]||(l.libraryAssets[a]=[]),!l.libraryAssets[a].some(d=>d.filename===s))){let d=s.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");l.libraryAssets[a].unshift({filename:s,displayName:d}),console.log(`[DEBUG] Added ${s} to registry category ${a}`)}}},window.__highlightLibrarySlot=(a,s)=>{this.libraryPanel.highlightSlot(a,s),this.libraryPanelDocked.highlightSlot(a,s)}}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`
2159
+ Are you absolutely sure?`))try{let t=Ze(),i={};for(let[a,s]of Object.entries(t.objects)){let o=s,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,s]of Object.entries(t.scenes)){let o=a.startsWith("scene.")?a:`scene.${a}`;i[`scenes/${o}.json`]=s}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")}ge(),this.showSuccessNotification(),this.refreshPanel()}catch(t){console.error("[ConfigPersistence] Direct apply failed:",t),alert(`\u274C Direct apply failed: ${t.message}`)}}};var Wt=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 Oi;this.sceneToolsPanel=new Ri;this.nudgePanel=new zi;this.inspectorPanel=new Xi;this.libraryPanel=new Gt;this.libraryPanelDocked=new Gt;this.brandVisionPanel=new nn;this.customizeSettingsPanel=new an;this.configPersistencePanel=new gn;this.loadingScreenPanel=new sn}applyAssetChange(e,t){return gr(this,e,t)}resetAsset(e){return hr(this,e)}applySlotAsset(e,t,i){return en(this,e,t,i)}resetSlotAsset(e,t,i){return fr(this,e,t,i)}startObjectVisuals(){return Er(this)}stopObjectVisuals(){return Cr(this)}shouldRunObjectVisuals(){return rn(this)}updateObjectVisuals(){return on(this)}getSelectedInstanceId(){return ba(this)}getDisplayObjectById(e){return ya(this,e)}getSelectedObjectConfig(){return Yt(this)}getConfigAnchorWorldPoint(e){return va(this,e)}getScreenSize(){return wa(this)}ensureBoundsGfx(){return xa(this)}ensureAnchorGfx(){return Sa(this)}drawBounds(e){return Ea(this,e)}drawAnchor(e){return Ca(this,e)}clearBounds(){return Aa(this)}clearAnchor(){return La(this)}clearObjectVisuals(){return qt(this)}updateObjectInfo(e){return Ut(this,e)}resetDebugConfig(){return cn(this)}applyDebugConfig(){return Tr(this)}exportDebugConfig(){return dn(this)}loadObjectConfig(e){return Ir(this,e)}fillConfigViewer(e){return ln(this,e)}copyConfigValues(){return kr(this)}applyObjectConfig(e){return Ia(this,e)}applyCustomizeSettings(e,t){return Pr(this,e,t)}scheduleObjectAutoApply(){return Mr(this)}setupDebugEventListeners(){return jr(this)}setupDebugInputListeners(e){return ja(this,e)}setupPanelLayout(){return _r(this)}setupCollapsiblePanels(e){return _a(this,e)}setupRangeInput(e,t,i,n){return me(this,e,t,i,n)}updateWorkbenchTabs(){return Ma(this)}saveWorkbenchState(){return yt(this)}loadWorkbenchState(){return un(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 s=JSON.parse(a);s.activeTab&&(this.activeTab=s.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,s,o)=>this.applySlotAsset(a,s,o),onReset:(a,s,o)=>this.resetSlotAsset(a,s,o)});let t=e.querySelector("#dock-library-content");t&&(t.innerHTML=this.libraryPanelDocked.render(),this.libraryPanelDocked.initialize(t,{onApply:(a,s,o)=>this.applySlotAsset(a,s,o),onReset:(a,s,o)=>this.resetSlotAsset(a,s,o)})),this.inspectorPanel.initialize(e,{onPropertyChange:(a,s,o)=>{console.log("[Inspector] Property changed:",a,s,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,s)=>this.applyCustomizeSettings(a,s)}),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,s)=>this.nudgeSelectedObject(a,s),onShowSplash:()=>{let a=window;typeof a.__previewShowSplash=="function"&&a.__previewShowSplash()},onUpdateSplash:a=>{let s=window;typeof s.applyEditableEngineConfig=="function"&&s.applyEditableEngineConfig({splash:a})}}),this.nudgePanel.initialize(e,{onNudge:async(a,s)=>{var u,g,h;if(!this.selectedObjectId)return;let o=this.getSelectedObjectConfig();if(!o)return;let l=(u=o.transform)==null?void 0:u.position,c=((g=l==null?void 0:l.x)!=null?g:0)+a,d=((h=l==null?void 0:l.y)!=null?h:0)+s,{applyConfigOverride:p}=await Promise.resolve().then(()=>(ne(),Pe));p({objectId:this.selectedObjectId,path:"transform.position",value:{x:c,y:d}},{silent:!0,emitEvent:!0}),window.dispatchEvent(new CustomEvent("inspector:refresh"))},onScale:async a=>{var d,p;if(!this.selectedObjectId)return;let s=this.getSelectedObjectConfig();if(!s)return;let o=(p=(d=s.transform)==null?void 0:d.scale)!=null?p:1,l=Math.max(.1,o+a),{applyConfigOverride:c}=await Promise.resolve().then(()=>(ne(),Pe));c({objectId:this.selectedObjectId,path:"transform.scale",value:l},{silent:!0,emitEvent:!0}),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 s=window;typeof s.applyEditableEngineConfig=="function"&&s.applyEditableEngineConfig({loading:a}),typeof s.__previewUpdateLoading=="function"?s.__previewUpdateLoading(a):console.warn("[DEBUG] __previewUpdateLoading not available")}}),window.__openAiEditor=(a,s,o,l)=>{this.customizeSettingsPanel.openAiEditor(a,s,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.__getSelectedObjectId=()=>this.selectedObjectId,window.addEventListener("config:changed",a=>{var s,o;((s=a.detail)==null?void 0:s.action)!=="remove"&&((o=a.detail)==null?void 0:o.action)!=="clear_object"&&this.highlightChangesTab()}),window.applyAssetToSlot=(a,s,o)=>this.applySlotAsset(a,s,o),window.refreshAssetLibrary=()=>Promise.all([this.libraryPanel.refresh(),this.libraryPanelDocked.refresh()]),window.reRenderAssetLibrary=()=>{this.libraryPanel.reRender(),this.libraryPanelDocked.reRender()},window.getEngineSplashConfig=()=>{var s;let a=window.getActiveConfig;if(typeof a=="function"){let o=a();return((s=o==null?void 0:o.engine)==null?void 0:s.splash)||null}return null},window.addAssetToRegistry=(a,s)=>{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===s))){let d=s.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");l.libraryAssets[a].unshift({filename:s,displayName:d}),console.log(`[DEBUG] Added ${s} to registry category ${a}`)}}},window.__highlightLibrarySlot=(a,s)=>{this.libraryPanel.highlightSlot(a,s),this.libraryPanelDocked.highlightSlot(a,s)}}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`
2160
2160
  <div class="debug-overlay hidden" id="debug-overlay">
2161
2161
  <div class="debug-workbench" id="debug-workbench">
2162
2162
  <div class="workbench-header" id="workbench-handle">
@@ -2203,7 +2203,7 @@ Are you absolutely sure?`))try{let t=Je(),i={};for(let[a,s]of Object.entries(t.o
2203
2203
  ${this.sceneToolsPanel.render()}
2204
2204
  ${this.nudgePanel.render()}
2205
2205
  </div>
2206
- `}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 r,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((r=p.value)!=null?r: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 s=new xe;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 s.updateProperty(p,"transform.position",[m,b])}i.length===1&&this.selectedObjectId===i[0]&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}};function vl(o){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(o)})}function wl(o){var n;let[e,t]=o.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 xl(o){return`
2206
+ `}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 s=new Se;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 s.updateProperty(p,"transform.position",[m,b])}i.length===1&&this.selectedObjectId===i[0]&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}};function vl(r){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(r)})}function wl(r){var n;let[e,t]=r.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 xl(r){return`
2207
2207
  Analyze these screenshots of a brand or game and extract its "Brand DNA".
2208
2208
 
2209
2209
  Provide a concise summary (2-3 sentences) covering:
@@ -2217,12 +2217,12 @@ FORMAT:
2217
2217
  Summary: [Your summary here]
2218
2218
  Palette: [#RRGGBB, #RRGGBB, ...]
2219
2219
 
2220
- ${o?`
2220
+ ${r?`
2221
2221
  ADDITIONAL RULES/NOTES:
2222
- ${o}`:""}
2223
- `.trim()}function Oo(){let o=[],e="",t=null;return{async addSources(i){let n=[];for(let a of i){let s=await vl(a),r=wl(s),l={id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,name:a.name,base64:r.base64,mimeType:r.mimeType,dataUrl:s};o.push(l),n.push(l)}return n},getSources(){return o.slice()},async analyze(i,n,a){if(o.length===0)throw new Error("No screenshots to analyze.");let s=xl(n),r=o.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Ji(i,s,r,{model:a}),c=e,d=[],p=l.split(`
2222
+ ${r}`:""}
2223
+ `.trim()}function Or(){let r=[],e="",t=null;return{async addSources(i){let n=[];for(let a of i){let s=await vl(a),o=wl(s),l={id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,name:a.name,base64:o.base64,mimeType:o.mimeType,dataUrl:s};r.push(l),n.push(l)}return n},getSources(){return r.slice()},async analyze(i,n,a){if(r.length===0)throw new Error("No screenshots to analyze.");let s=xl(n),o=r.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Zi(i,s,o,{model:a}),c=e,d=[],p=l.split(`
2224
2224
  `);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(`
2225
- 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 it="handler_api_key_";var yt=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${it}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${it}${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=`${it}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${it}${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(it)){let n=i.substring(it.length),a=localStorage.getItem(i);if(a){let s=JSON.parse(a);e.push({service:n,label:s.label,created:s.created,lastUsed:s.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(it)&&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}}},_a=()=>yt.getKey("gemini"),Oa=(o,e)=>yt.setKey("gemini",o,e),Sl=()=>yt.hasKey("gemini");window.ApiKeyStorage=yt;window.getGeminiApiKey=_a;window.setGeminiApiKey=Oa;window.hasGeminiApiKey=Sl;var za=class{constructor(){this.modal=null;this.options=null;this.analyzer=Oo();this.currentPrompt="";this.isGenerating=!1;this.generatedImages=[];this.selectedImageIndex=-1;this.savedLibraryPaths=new Map;this.promptInput=null;this.generateBtn=null;this.saveLibraryBtn=null;this.loadingEl=null;this.galleryEl=null;this.previewEl=null;this.statusEl=null}open(e){this.options=e,this.currentPrompt=e.initialPrompt||"",this.generatedImages=[],this.selectedImageIndex=-1,this.isGenerating=!1,this.savedLibraryPaths.clear(),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=`
2225
+ 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 nt="handler_api_key_";var vt=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${nt}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${nt}${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=`${nt}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${nt}${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(nt)){let n=i.substring(nt.length),a=localStorage.getItem(i);if(a){let s=JSON.parse(a);e.push({service:n,label:s.label,created:s.created,lastUsed:s.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(nt)&&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}}},Oa=()=>vt.getKey("gemini"),Ra=(r,e)=>vt.setKey("gemini",r,e),Sl=()=>vt.hasKey("gemini");window.ApiKeyStorage=vt;window.getGeminiApiKey=Oa;window.setGeminiApiKey=Ra;window.hasGeminiApiKey=Sl;var $a=class{constructor(){this.modal=null;this.options=null;this.analyzer=Or();this.currentPrompt="";this.isGenerating=!1;this.generatedImages=[];this.selectedImageIndex=-1;this.savedLibraryPaths=new Map;this.promptInput=null;this.generateBtn=null;this.saveLibraryBtn=null;this.loadingEl=null;this.galleryEl=null;this.previewEl=null;this.statusEl=null}open(e){this.options=e,this.currentPrompt=e.initialPrompt||"",this.generatedImages=[],this.selectedImageIndex=-1,this.isGenerating=!1,this.savedLibraryPaths.clear(),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=`
2226
2226
  <style>
2227
2227
  .ai-gallery-item {
2228
2228
  position: relative;
@@ -2320,15 +2320,15 @@ Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0
2320
2320
  <button class="ai-btn primary" data-action="apply" disabled>Apply</button>
2321
2321
  </div>
2322
2322
  </div>
2323
- `,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.saveLibraryBtn=this.modal.querySelector('[data-action="save-library"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),this.statusEl=this.modal.querySelector("[data-status]"),(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 r;let a=n.target;switch(a.dataset.action||((r=a.closest("[data-action]"))==null?void 0:r.getAttribute("data-action"))){case"generate":this.generateImage();break;case"save-library":this.saveSelectedImageToLibrary();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 s=a.closest(".ai-gallery-item"),r=parseInt(s.dataset.index||"-1");r>=0&&this.selectImage(r)}}),this.updateGenerateButton(),this.setStatus("Ready. Generate an image to get started.")}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}
2323
+ `,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.saveLibraryBtn=this.modal.querySelector('[data-action="save-library"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),this.statusEl=this.modal.querySelector("[data-status]"),(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"save-library":this.saveSelectedImageToLibrary();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 s=a.closest(".ai-gallery-item"),o=parseInt(s.dataset.index||"-1");o>=0&&this.selectImage(o)}}),this.updateGenerateButton(),this.setStatus("Ready. Generate an image to get started.")}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}
2324
2324
 
2325
- 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 s=[];if(this.options.currentValue&&this.options.currentValue.startsWith("data:"))try{let c=await Xi(this.options.currentValue);c&&(s=[{base64:c.base64,mimeType:c.mimeType}])}catch(c){console.warn("[AiEditorModal] Failed to load current image:",c)}let r=await ft(a,this.currentPrompt,s,{aspectRatio:"1:1"}),l=await ht(r);this.generatedImages.push(l||r),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)=>{let n=this.savedLibraryPaths.has(i),a=n?this.savedLibraryPaths.get(i):null,s=a?a.split("/").pop():"";return`
2325
+ 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 s=[];if(this.options.currentValue&&this.options.currentValue.startsWith("data:"))try{let c=await Ji(this.options.currentValue);c&&(s=[{base64:c.base64,mimeType:c.mimeType}])}catch(c){console.warn("[AiEditorModal] Failed to load current image:",c)}let o=await mt(a,this.currentPrompt,s,{aspectRatio:"1:1"}),l=await ft(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)=>{let n=this.savedLibraryPaths.has(i),a=n?this.savedLibraryPaths.get(i):null,s=a?a.split("/").pop():"";return`
2326
2326
  <div class="ai-gallery-item ${i===this.selectedImageIndex?"active":""}" data-index="${i}">
2327
2327
  <img class="ai-gallery-thumb" src="${t}" alt="Generated ${i+1}" />
2328
2328
  <div class="ai-gallery-label">#${i+1}${n?" \u2713":""}</div>
2329
2329
  ${n?`<div class="ai-gallery-saved" title="Saved: ${s}">\u{1F4BE}</div>`:""}
2330
2330
  </div>
2331
- `}).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 i,n;let e=(i=this.modal)==null?void 0:i.querySelector('[data-action="apply"]'),t=(n=this.modal)==null?void 0:n.querySelector('[data-action="save-library"]');e&&(e.disabled=this.selectedImageIndex<0),t&&(t.disabled=this.selectedImageIndex<0)}setStatus(e,t=!1){this.statusEl&&(this.statusEl.textContent=e,this.statusEl.style.color=t?"#ff4444":"#888")}async saveSelectedImageToLibrary(){var r;if(this.selectedImageIndex<0){this.setStatus("No image selected.",!0);return}let e=this.generatedImages[this.selectedImageIndex];if(!e){this.setStatus("Invalid image data.",!0);return}if(this.savedLibraryPaths.has(this.selectedImageIndex)){let l=this.savedLibraryPaths.get(this.selectedImageIndex);this.setStatus(`Already saved: ${l}`);return}let t=e;if(!t.startsWith("data:image/")){this.setStatus("Invalid image format.",!0);return}t=t.trim().replace(/\s/g,"");let i=((r=this.options)==null?void 0:r.objectId)||"asset",a=`${i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_${Date.now()}.png`,s=this.inferCategoryFromObjectId(i);this.setStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:s,filename:a,data:t,overwrite:!0})})).json();if(c.success){console.log("[AiEditorModal] \u2705 Saved to library:",c.path),this.savedLibraryPaths.set(this.selectedImageIndex,c.path),this.setStatus(`\u2705 Saved: ${a}`);let d=window.addAssetToRegistry;typeof d=="function"&&d(s,a);let p=window.getEditableAssets;if(typeof p=="function"){let h=p();h&&!h.categories&&(h.categories=[]),h!=null&&h.categories&&!h.categories.includes(s)&&(h.categories.push(s),console.log(`[AiEditorModal] Added category ${s} to registry`))}await new Promise(h=>setTimeout(h,100));try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[AiEditorModal] \u2705 Registry rebuilt from disk"):console.warn("[AiEditorModal] Setup-library returned non-OK status")}catch(h){console.warn("[AiEditorModal] Setup-library not available:",h)}await new Promise(h=>setTimeout(h,200));let u=window.refreshAssetLibrary;typeof u=="function"&&(console.log("[AiEditorModal] Refreshing library panel..."),await u());let g=window.reRenderAssetLibrary;typeof g=="function"&&(console.log("[AiEditorModal] Re-rendering library panel..."),g()),setTimeout(()=>{try{let h=window.__screenManager;h&&typeof h.refreshTextures=="function"&&(console.log("[AiEditorModal] Refreshing game textures via screen manager..."),h.refreshTextures()),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[AiEditorModal] Dispatched config:changed event")}catch(h){console.warn("[AiEditorModal] Failed to refresh textures:",h)}},300),this.updateGallery()}else console.error("[AiEditorModal] \u274C Save failed:",c.error),this.setStatus(`Save failed: ${c.error}`,!0)}catch(l){console.error("[AiEditorModal] \u274C Save error:",l),this.setStatus("Save failed. Check console.",!0)}}inferCategoryFromObjectId(e){let t=e.toLowerCase();return t.includes("background")?"backgrounds":t.includes("character")?"characters":t.includes("key")?"collectedkeys":t.includes("draggable")?"draggables":t.includes("environment")||t.includes("env")||t.includes("hand")||t.includes("prop")||t.includes("item")?"environment":t.includes("machine")?"machines":t.includes("tutorial")?"tutorial":t.includes("ui")||t.includes("button")||t.includes("label")||t.includes("icon")||t.includes("logo")?"ui":t.includes("effect")||t.includes("confetti")||t.includes("particle")?"effects":"ui"}async applySelectedImage(){var i;if(this.selectedImageIndex<0||!((i=this.options)!=null&&i.onApply))return;let t=this.generatedImages[this.selectedImageIndex];this.savedLibraryPaths.has(this.selectedImageIndex)?(t=this.savedLibraryPaths.get(this.selectedImageIndex),this.setStatus("Applying saved image...")):(this.setStatus("Saving to library before applying..."),await this.saveSelectedImageToLibrary(),this.savedLibraryPaths.has(this.selectedImageIndex)?(t=this.savedLibraryPaths.get(this.selectedImageIndex),this.setStatus("\u2705 Saved and applying...")):this.setStatus("Failed to save. Applying data URL instead.",!0)),this.options.onApply(t),setTimeout(()=>{this.close()},500)}getApiKey(){let e=_a();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return Oa(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}},Ra=null;window.__openAiEditor=function(o,e,t,i){Ra||(Ra=new za),Ra.open({objectId:o,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(o,i.path,n);else{let s=window.getEditableObjectConfig,r=s==null?void 0:s(o);if(r){let l=i.path.split("."),c=r;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"))}})};ut();var $a=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=`
2331
+ `}).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 i,n;let e=(i=this.modal)==null?void 0:i.querySelector('[data-action="apply"]'),t=(n=this.modal)==null?void 0:n.querySelector('[data-action="save-library"]');e&&(e.disabled=this.selectedImageIndex<0),t&&(t.disabled=this.selectedImageIndex<0)}setStatus(e,t=!1){this.statusEl&&(this.statusEl.textContent=e,this.statusEl.style.color=t?"#ff4444":"#888")}async saveSelectedImageToLibrary(){var o;if(this.selectedImageIndex<0){this.setStatus("No image selected.",!0);return}let e=this.generatedImages[this.selectedImageIndex];if(!e){this.setStatus("Invalid image data.",!0);return}if(this.savedLibraryPaths.has(this.selectedImageIndex)){let l=this.savedLibraryPaths.get(this.selectedImageIndex);this.setStatus(`Already saved: ${l}`);return}let t=e;if(!t.startsWith("data:image/")){this.setStatus("Invalid image format.",!0);return}t=t.trim().replace(/\s/g,"");let i=((o=this.options)==null?void 0:o.objectId)||"asset",a=`${i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_${Date.now()}.png`,s=this.inferCategoryFromObjectId(i);this.setStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:s,filename:a,data:t,overwrite:!0})})).json();if(c.success){console.log("[AiEditorModal] \u2705 Saved to library:",c.path),this.savedLibraryPaths.set(this.selectedImageIndex,c.path),this.setStatus(`\u2705 Saved: ${a}`);let d=window.addAssetToRegistry;typeof d=="function"&&d(s,a);let p=window.getEditableAssets;if(typeof p=="function"){let h=p();h&&!h.categories&&(h.categories=[]),h!=null&&h.categories&&!h.categories.includes(s)&&(h.categories.push(s),console.log(`[AiEditorModal] Added category ${s} to registry`))}await new Promise(h=>setTimeout(h,100));try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[AiEditorModal] \u2705 Registry rebuilt from disk"):console.warn("[AiEditorModal] Setup-library returned non-OK status")}catch(h){console.warn("[AiEditorModal] Setup-library not available:",h)}await new Promise(h=>setTimeout(h,200));let u=window.refreshAssetLibrary;typeof u=="function"&&(console.log("[AiEditorModal] Refreshing library panel..."),await u());let g=window.reRenderAssetLibrary;typeof g=="function"&&(console.log("[AiEditorModal] Re-rendering library panel..."),g()),setTimeout(()=>{try{let h=window.__screenManager;h&&typeof h.refreshTextures=="function"&&(console.log("[AiEditorModal] Refreshing game textures via screen manager..."),h.refreshTextures()),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),console.log("[AiEditorModal] Dispatched config:changed event")}catch(h){console.warn("[AiEditorModal] Failed to refresh textures:",h)}},300),this.updateGallery()}else console.error("[AiEditorModal] \u274C Save failed:",c.error),this.setStatus(`Save failed: ${c.error}`,!0)}catch(l){console.error("[AiEditorModal] \u274C Save error:",l),this.setStatus("Save failed. Check console.",!0)}}inferCategoryFromObjectId(e){let t=e.toLowerCase();return t.includes("background")?"backgrounds":t.includes("character")?"characters":t.includes("key")?"collectedkeys":t.includes("draggable")?"draggables":t.includes("environment")||t.includes("env")||t.includes("hand")||t.includes("prop")||t.includes("item")?"environment":t.includes("machine")?"machines":t.includes("tutorial")?"tutorial":t.includes("ui")||t.includes("button")||t.includes("label")||t.includes("icon")||t.includes("logo")?"ui":t.includes("effect")||t.includes("confetti")||t.includes("particle")?"effects":"ui"}async applySelectedImage(){var i;if(this.selectedImageIndex<0||!((i=this.options)!=null&&i.onApply))return;let t=this.generatedImages[this.selectedImageIndex];this.savedLibraryPaths.has(this.selectedImageIndex)?(t=this.savedLibraryPaths.get(this.selectedImageIndex),this.setStatus("Applying saved image...")):(this.setStatus("Saving to library before applying..."),await this.saveSelectedImageToLibrary(),this.savedLibraryPaths.has(this.selectedImageIndex)?(t=this.savedLibraryPaths.get(this.selectedImageIndex),this.setStatus("\u2705 Saved and applying...")):this.setStatus("Failed to save. Applying data URL instead.",!0)),this.options.onApply(t),setTimeout(()=>{this.close()},500)}getApiKey(){let e=Oa();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return Ra(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}},za=null;window.__openAiEditor=function(r,e,t,i){za||(za=new $a),za.open({objectId:r,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(r,i.path,n);else{let s=window.getEditableObjectConfig,o=s==null?void 0:s(r);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"))}})};gt();var Da=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=`
2332
2332
  <div class="asset-preview-card">
2333
2333
  <div class="asset-preview-header">
2334
2334
  <div class="asset-preview-title">${n}</div>
@@ -2355,7 +2355,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2355
2355
  <source src="${n}" type="audio/wav">
2356
2356
  Your browser does not support the audio element.
2357
2357
  </audio>
2358
- `;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(()=>(ut(),Ht)).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(o){new $a().open(o)};la();Q();var $=require("pixi.js");Q();var un=class{constructor(e){this.app=null;this.camera=new $.Container;this.bgContainer=new $.Container;this.mainContainer=new $.Container;this.uiContainer=new $.Container;this.gizmoLayer=new $.Container;this.screenFrame=new $.Graphics;this.gameFrame=new $.Graphics;this.gridLayer=new $.Graphics;this.spawnPointLayer=new $.Container;this.objectMap=new Map;this.selectedId=null;this.selectedIds=new Set;this.dragMode=null;this.selectionBox=null;this.selectionBoxStart=null;this.isSelectionBoxActive=!1;this.dragStartPointer=null;this.dragStartPos=null;this.dragStartScale=1;this.dragStartRotation=0;this.dragStartAngle=0;this.dragStartDistance=1;this.dragAnchorLocal=null;this.dragStartValue=null;this.dragContainer=null;this.dragLastPointer=null;this.dragPointerOffset=null;this.dragSyncHoldUntil=0;this.dragLogged=!1;this.spawnPointDrag=null;this.lastGameFrameSize=null;this.cameraScale=1;this.isPanning=!1;this.panStart=null;this.panStartCamera=null;this.hasUserCamera=!1;this.resizeObserver=null;this.screenSyncRaf=null;this.gizmoOutline=new $.Graphics;this.anchorVisualizationLayer=new $.Graphics;this.moveHandle=new $.Graphics;this.scaleHandle=new $.Graphics;this.rotateHandle=new $.Graphics;this.isVisible=!0;this.applyQueued=!1;this.applyQueuedId=null;this.gridEnabled=!1;this.gridGap=50;this.gridAlpha=.25;this.snapToGrid=!1;this.alignmentGuidesEnabled=!0;this.alignmentGuideLayer=new $.Graphics;this.lastPickPoint=null;this.lastPickIds=[];this.lastPickIndex=0;this.lastPickTime=0;this.playModeEnabled=!0;this.playModeInitialized=!1;this.layoutScale=1;this.updateManager=new xe;this.backgroundCoverEnabled=!0;this.backgroundLocked=!0;this.dropZoneActive=!1;this.dropZoneOverlay=null;this.handleScreenChange=e=>{if(!(e!=null&&e.detail))return;let{width:t,height:i}=e.detail;!t||!i||(this.hasUserCamera=!1,this.updateLayout({width:t,height:i}),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid(),this.playModeEnabled?this.schedulePostScreenSync({width:t,height:i}):this.syncFromConfig())};this.handleAnchorChanged=e=>{let t=e==null?void 0:e.detail,i=t==null?void 0:t.objectId;if(!i)return;let n=t==null?void 0:t.previousAnchor,a=t==null?void 0:t.nextAnchor;this.adjustPositionForAnchorChange(i,n,a)};this.handleActiveScreenChanged=()=>{this.isVisible&&this.syncFromConfig()};this.handleConfigChanged=e=>{if(!this.isVisible)return;this.updateLayout(),this.updateGrid();let t=e==null?void 0:e.detail;if(!t){this.syncFromConfig();return}let i=t.path,n=t.objectId;if(i==="transform.anchor"&&n){let s=t.value,r=t.oldValue;r!=null&&this.adjustPositionForAnchorChange(n,r,s)}let a=t.objectIds;if(n){this.syncFromConfig([n]);return}if(Array.isArray(a)&&a.length>0){this.syncFromConfig(a);return}this.syncFromConfig()};this.handleSceneRefresh=()=>{this.isVisible&&this.syncFromConfig()};this.handleAssetUpdated=e=>{var l;let t=(l=e==null?void 0:e.detail)!=null?l:{},i=t.objectId,n=t.texture;if(!i||!n)return;let a=this.objectMap.get(i);if(!a)return;let s=a.displayObject;if(s!=null&&s.texture)s.texture=n;else if(s!=null&&s.children){let c=s.children.find(d=>d==null?void 0:d.texture);c&&(c.texture=n)}let r=this.getEditableObjectConfig(i);r&&(a.assetKey=this.getAssetKey(r))};this.handleLayoutApplied=e=>{var s;if(!this.isVisible)return;let t=(s=e==null?void 0:e.detail)!=null?s:{},i=Number(t.width),n=Number(t.height),a=Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:this.getScreen();this.updateLayout(a),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})};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.onStagePointerDown=e=>{if(!this.app||!this.isVisible)return;let t=this.getPointerButton(e);if(t===2){if(this.isGizmoTarget(e==null?void 0:e.target))return;let h=this.getEventGlobalPoint(e);if(!h)return;let f=new $.Point(h.x,h.y),m=this.getPickCandidates(f);if(m.length>0){let b=m[0];this.selectedIds.has(b)||(this.selectedIds.clear(),this.selectedIds.add(b),this.setSelected(b),this.updateGizmos()),this.showContextMenu(b,h.x,h.y)}return}if(t!==0||this.isGizmoTarget(e==null?void 0:e.target))return;let i=this.getEventGlobalPoint(e);if(!i)return;let n=new $.Point(i.x,i.y),a=this.getPickCandidates(n),r=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey;if(a.length===0){r||(this.setSelected(null),this.selectedIds.clear()),this.selectionBoxStart=n,this.isSelectionBoxActive=!0,this.lastPickIds=[],this.lastPickIndex=0,this.lastPickPoint=n,this.lastPickTime=performance.now();return}let l=performance.now(),c=this.areSameIds(a,this.lastPickIds),d=this.lastPickPoint&&this.distance(n,this.lastPickPoint)<=6,p=l-this.lastPickTime<1200,u=c&&d&&p?(this.lastPickIndex+1)%a.length:0,g=a[u];this.lastPickIds=a,this.lastPickIndex=u,this.lastPickPoint=n,this.lastPickTime=l,r?this.selectedIds.has(g)?(this.selectedIds.delete(g),this.selectedId===g&&(this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null)):(this.selectedIds.add(g),this.selectedId=g):(this.selectedIds.clear(),this.selectedIds.add(g),this.setSelected(g)),this.updateGizmos()};this.handleGridSettings=e=>{var a,s,r;let t=(a=e==null?void 0:e.detail)==null?void 0:a.enabled,i=(s=e==null?void 0:e.detail)==null?void 0:s.gap,n=(r=e==null?void 0:e.detail)==null?void 0:r.alpha;typeof t=="boolean"&&(this.gridEnabled=t),typeof i=="number"&&Number.isFinite(i)&&i>2&&(this.gridGap=i),typeof n=="number"&&Number.isFinite(n)&&n>=0&&n<=1&&(this.gridAlpha=n),this.updateGrid()};this.handleBackgroundCover=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(this.backgroundCoverEnabled=t,this.syncFromConfig(),this.updateGizmos())};this.handleBackgroundLock=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;if(typeof t=="boolean"&&(this.backgroundLocked=t,t&&this.selectedId)){let n=this.getEditableObjectConfig(this.selectedId),a=this.objectMap.get(this.selectedId);this.isBackgroundObject(this.selectedId,n,a==null?void 0:a.displayObject)&&this.setSelected(null)}};this.handlePlayModeChange=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(!this.playModeInitialized&&(this.playModeInitialized=!0,!t)||t&&this.applyPlayModeState(!0))};this.syncFromGameObjects=()=>{this.syncFromGameObjectsInternal()};this.onSpawnPointDragMove=e=>{if(!this.spawnPointDrag)return;let t=this.getPointerInContainer(e.clientX,e.clientY,this.mainContainer);if(!t)return;let i=t.x+this.spawnPointDrag.offset.x,n=t.y+this.spawnPointDrag.offset.y;this.updateLiveSpawnPoint(this.spawnPointDrag.objectId,this.spawnPointDrag.index,i,n)};this.onSpawnPointDragEnd=()=>{if(!this.spawnPointDrag)return;let{objectId:e,startPoints:t}=this.spawnPointDrag,i=this.getEditableObjectConfig(e),n=i?this.getSpawnPoints(i):null;i&&n&&(this.setNestedValue(i,"logic.props.spawnPoints",t),oe({objectId:e,path:"logic.props.spawnPoints",value:n},{persist:!0,emitEvent:!0,trackHistory:!0}),this.queueLiveApply(e)),this.spawnPointDrag=null,window.dispatchEvent(new CustomEvent("inspector:refresh")),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd)};this.onDragMove=e=>{var n;if(!this.dragMode||!this.selectedId||!this.dragContainer||!this.dragStartPointer||!this.dragStartPos)return;let t=this.objectMap.get(this.selectedId);if(!(t!=null&&t.displayObject))return;let i=this.getPointerInContainer(e.clientX,e.clientY,this.dragContainer);if(i){if(this.dragMode==="move"){let a=this.dragPointerOffset;if(!a)return;let s=i.x+a.x,r=i.y+a.y;if(this.snapToGrid){let d=this.snapToGridPosition(s,r);s=d.x,r=d.y}let l=s-this.dragStartPos.x,c=r-this.dragStartPos.y;if(t.displayObject.position.set(s,r),this.updateAlignmentGuides(this.selectedId,new $.Point(s,r)),this.updateLiveConfigPosition(s,r),this.selectedIds.size>1){let d=new Map;if(!this.multiDragStartPositions){this.multiDragStartPositions=new Map;for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);u!=null&&u.displayObject&&this.multiDragStartPositions.set(p,new $.Point(u.displayObject.position.x,u.displayObject.position.y))}}for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);if(!(u!=null&&u.displayObject))continue;let g=this.multiDragStartPositions.get(p);if(g){let h=g.x+l,f=g.y+c;if(this.snapToGrid){let m=this.snapToGridPosition(h,f);h=m.x,f=m.y}u.displayObject.position.set(h,f),this.updateLiveConfigPositionForObject(p,h,f)}}}this.dragLastPointer=new $.Point(i.x,i.y),this.dragLogged||(this.dragLogged=!0,console.log("[SceneEditor][DragMove]",{objectId:this.selectedId,selectedCount:this.selectedIds.size,pointer:{x:i.x,y:i.y},nextPos:{x:s,y:r}}))}if(this.dragMode==="scale"&&this.dragAnchorLocal){let s=Math.max(1,this.distance(i,this.dragAnchorLocal))/Math.max(1,this.dragStartDistance),r=Math.max(.01,this.dragStartScale*s);(n=t.displayObject.scale)!=null&&n.set?t.displayObject.scale.set(r,r):t.displayObject.scale&&(t.displayObject.scale.x=r,t.displayObject.scale.y=r),this.updateLiveConfigScale(r)}if(this.dragMode==="rotate"&&this.dragAnchorLocal){let a=Math.atan2(i.y-this.dragAnchorLocal.y,i.x-this.dragAnchorLocal.x),s=this.dragStartRotation+(a-this.dragStartAngle);t.displayObject.rotation=s,this.updateLiveConfigRotation(s)}this.updateGizmos()}};this.onDragEnd=()=>{if(this.dragMode){if(this.alignmentGuideLayer&&this.alignmentGuideLayer.clear(),this.selectedIds.size>0){let e=Array.from(this.selectedIds);window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectIds:e}})),this.dragSyncHoldUntil=performance.now()+200}this.dragMode=null,this.dragStartPointer=null,this.dragStartPos=null,this.dragAnchorLocal=null,this.dragStartValue=null,this.dragContainer=null,this.dragLastPointer=null,this.dragPointerOffset=null,this.multiDragStartPositions=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)),a=new $.Point(this.app.renderer.width/2,this.app.renderer.height/2),s=this.camera.toLocal(a);this.cameraScale=n,this.camera.scale.set(n);let r=this.camera.toGlobal(s);this.camera.position.set(this.camera.position.x+(a.x-r.x),this.camera.position.y+(a.y-r.y)),this.hasUserCamera=!0,this.updateGizmos(),this.updateGrid()};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){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.updateGrid()}if(this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(!t)return;let i=new $.Point(t.x,t.y);this.drawSelectionBox(this.selectionBoxStart,i)}};this.onPanEnd=e=>{if(this.isPanning&&(this.isPanning=!1,this.panStart=null,this.panStartCamera=null),this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(t){let i=new $.Point(t.x,t.y);this.finalizeSelectionBox(this.selectionBoxStart,i)}this.isSelectionBoxActive=!1,this.selectionBoxStart=null,this.selectionBox&&this.selectionBox.clear()}this.multiDragStartPositions=null};this.root=e.root,this.getScreen=e.getScreen}async mount(){this.app||(this.app=new $.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.bgContainer.sortableChildren=!0,this.mainContainer.sortableChildren=!0,this.uiContainer.sortableChildren=!0,this.spawnPointLayer.sortableChildren=!0,this.gizmoLayer.sortableChildren=!0,this.app.stage.addChild(this.camera),this.camera.addChild(this.screenFrame),this.camera.addChild(this.bgContainer),this.camera.addChild(this.mainContainer),this.camera.addChild(this.gridLayer),this.camera.addChild(this.uiContainer),this.camera.addChild(this.spawnPointLayer),this.camera.addChild(this.gameFrame),this.camera.addChild(this.gizmoLayer),this.screenFrame.zIndex=-1,this.screenFrame.eventMode="none",this.bgContainer.zIndex=-5e3,this.bgContainer.eventMode="none",this.mainContainer.zIndex=0,this.gridLayer.zIndex=2e4,this.gridLayer.eventMode="none",this.gridLayer.visible=!0,this.uiContainer.zIndex=5e4,this.spawnPointLayer.zIndex=8e4,this.spawnPointLayer.eventMode="passive",this.gameFrame.zIndex=85e3,this.gameFrame.eventMode="none",this.gizmoLayer.zIndex=1e5,this.gizmoLayer.addChild(this.gizmoOutline),this.gizmoLayer.addChild(this.anchorVisualizationLayer),this.gizmoLayer.addChild(this.moveHandle),this.gizmoLayer.addChild(this.scaleHandle),this.gizmoLayer.addChild(this.rotateHandle),this.selectionBox=new $.Graphics,this.selectionBox.zIndex=99999,this.selectionBox.eventMode="none",this.gizmoLayer.addChild(this.selectionBox),this.dropZoneOverlay=new $.Graphics,this.dropZoneOverlay.zIndex=99998,this.dropZoneOverlay.eventMode="none",this.gizmoLayer.addChild(this.dropZoneOverlay),this.alignmentGuideLayer=new $.Graphics,this.alignmentGuideLayer.zIndex=99997,this.alignmentGuideLayer.eventMode="none",this.gizmoLayer.addChild(this.alignmentGuideLayer),this.gizmoOutline.eventMode="none",this.anchorVisualizationLayer.eventMode="none",this.setupInteractions(),this.setupObservers(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.restoreScenePreferences(),this.refresh(),this.applyPlayModeState(!0),!this.isVisible&&this.app.ticker&&this.app.ticker.stop())}destroy(){var e;this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.screenSyncRaf&&(cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=null),window.removeEventListener("handler-preview:screen",this.handleScreenChange),window.removeEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.removeEventListener("config:changed",this.handleConfigChanged),window.removeEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.removeEventListener("handler:layout-applied",this.handleLayoutApplied),window.removeEventListener("preview:select",this.handlePreviewSelect),window.removeEventListener("scene-editor:grid",this.handleGridSettings),window.removeEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.removeEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.removeEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.removeEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.removeEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd),this.app&&((e=this.app.ticker)==null||e.remove(this.syncFromGameObjects),this.app.stage.off("pointerdown",this.onStagePointerDown),this.app.destroy(!0),this.app=null)}setVisible(e){this.isVisible=e,!(!this.app||!this.app.ticker)&&(e?(this.app.ticker.start(),this.refresh(),this.updateGrid()):this.app.ticker.stop())}refresh(){this.syncFromConfig()}setupObservers(){window.addEventListener("handler-preview:screen",this.handleScreenChange),window.addEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.addEventListener("config:changed",this.handleConfigChanged),window.addEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.addEventListener("handler:layout-applied",this.handleLayoutApplied),window.addEventListener("preview:select",this.handlePreviewSelect),window.addEventListener("scene-editor:grid",this.handleGridSettings),window.addEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.addEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.addEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.addEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.addEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),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.app.stage.on("pointerdown",this.onStagePointerDown),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)),this.applyEditControls(),this.setupKeyboardShortcuts(),this.setupDragAndDrop()}setupKeyboardShortcuts(){window.addEventListener("keydown",e=>{if(!this.isVisible)return;let i=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey,n=e.target;n.tagName==="INPUT"||n.tagName==="TEXTAREA"||n.isContentEditable||(i&&e.key==="a"?(e.preventDefault(),this.selectAll()):i&&e.key==="d"?(e.preventDefault(),this.duplicateSelected()):i&&e.key==="c"?(e.preventDefault(),this.copySelected()):i&&e.key==="v"?(e.preventDefault(),this.pasteObjects()):e.key==="Escape"?(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos()):(e.key==="Delete"||e.key==="Backspace")&&this.selectedIds.size>0?(e.preventDefault(),this.deleteSelectedObjects()):e.key==="g"||e.key==="G"?(e.preventDefault(),this.toggleGrid()):e.shiftKey&&(e.key==="g"||e.key==="G")&&(e.preventDefault(),this.toggleSnapToGrid()))})}async duplicateSelected(){if(this.selectedIds.size===0)return;let e=window.__HANDLER_ACTIVE_SCREEN,t=e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay",i=Array.from(this.selectedIds),n=[];for(let a of i)try{let s=`${a}_copy_${Date.now()}`,r=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:a,newInstanceId:s,shareConfig:!1,screenId:t})}),l=await r.json();r.ok&&l.success&&n.push(l.newObjectId)}catch(s){console.error(`[SceneEditor] Failed to duplicate ${a}:`,s)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")))}copySelected(){if(this.selectedIds.size===0)return;let e=[];for(let t of this.selectedIds){let i=this.getEditableObjectConfig(t);i&&e.push({id:t,config:i})}window.__sceneEditorClipboard={configs:e,timestamp:Date.now()},this.showToast(`\u{1F4CB} Copied ${e.length} object${e.length>1?"s":""}`,1500)}async pasteObjects(){var a,s;let e=window.__sceneEditorClipboard;if(!e||!e.configs||e.configs.length===0)return;let t=window.__HANDLER_ACTIVE_SCREEN,i=t==="loading"||t==="start"||t==="gameplay"||t==="tutorial"||t==="endgame"?t:"gameplay",n=[];for(let{id:r,config:l}of e.configs)try{let c=`${r}_paste_${Date.now()}_${Math.random().toString(36).substr(2,5)}`,d=`json.${c}`,p=JSON.parse(JSON.stringify(l));if(p.identity.id=d,p.instance_id=c,p.object_config=d,(a=p.transform)!=null&&a.position){let h=p.transform.position,f=Array.isArray(h)?h[0]:h.x||0,m=Array.isArray(h)?h[1]:h.y||0;Array.isArray(h)?p.transform.position=[f+20,m+20]:p.transform.position={x:f+20,y:m+20}}let u=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:p,layer:((s=p.identity)==null?void 0:s.category)==="ui"?"ui":"world"})}),g=await u.json();u.ok&&g.success&&n.push(c)}catch(c){console.error(`[SceneEditor] Failed to paste ${r}:`,c)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),this.showToast(`\u{1F4CB} Pasted ${n.length} object${n.length>1?"s":""}`,1500))}toggleGrid(){this.gridEnabled=!this.gridEnabled,this.updateGrid();try{window.localStorage.setItem(this.getSceneStorageKey("grid_enabled"),String(this.gridEnabled))}catch{}this.showToast(this.gridEnabled?"\u{1F4D0} Grid enabled":"\u{1F4D0} Grid disabled",1e3)}toggleSnapToGrid(){this.snapToGrid=!this.snapToGrid;try{window.localStorage.setItem(this.getSceneStorageKey("snap_to_grid"),String(this.snapToGrid))}catch{}this.showToast(this.snapToGrid?"\u{1F532} Snap to grid enabled":"\u{1F532} Snap to grid disabled",1e3)}snapToGridPosition(e,t){if(!this.snapToGrid)return{x:e,y:t};let i=this.gridGap;return{x:Math.round(e/i)*i,y:Math.round(t/i)*i}}updateAlignmentGuides(e,t){var d,p,u,g;if(!this.alignmentGuidesEnabled||!e||!this.alignmentGuideLayer){this.alignmentGuideLayer&&this.alignmentGuideLayer.clear();return}let i=this.objectMap.get(e);if(!(i!=null&&i.displayObject)){this.alignmentGuideLayer.clear();return}let n=(p=(d=i.displayObject).getBounds)==null?void 0:p.call(d);if(!n){this.alignmentGuideLayer.clear();return}this.alignmentGuideLayer.clear();let a=this.camera.toLocal(new $.Point(n.x,n.y)),s=this.camera.toLocal(new $.Point(n.x+n.width,n.y+n.height)),r=(a.x+s.x)/2,l=(a.y+s.y)/2,c=5;for(let[h,f]of this.objectMap.entries()){if(h===e||!(f!=null&&f.displayObject)||f.displayObject.visible===!1)continue;let m=(g=(u=f.displayObject).getBounds)==null?void 0:g.call(u);if(!m)continue;let b=this.camera.toLocal(new $.Point(m.x,m.y)),y=this.camera.toLocal(new $.Point(m.x+m.width,m.y+m.height)),v=(b.x+y.x)/2,w=(b.y+y.y)/2;if(Math.abs(r-v)<c){let L=Math.min(a.y,b.y),x=Math.max(s.y,y.y);this.alignmentGuideLayer.moveTo(v,L),this.alignmentGuideLayer.lineTo(v,x),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}if(Math.abs(l-w)<c){let L=Math.min(a.x,b.x),x=Math.max(s.x,y.x);this.alignmentGuideLayer.moveTo(L,w),this.alignmentGuideLayer.lineTo(x,w),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}let I=a.x,P=s.x,_=a.y,T=s.y,M=b.x,k=y.x,A=b.y,C=y.y;if(Math.abs(I-M)<c||Math.abs(I-k)<c||Math.abs(P-M)<c||Math.abs(P-k)<c){let L=Math.abs(I-M)<c?M:Math.abs(I-k)<c?k:Math.abs(P-M)<c?M:k,x=Math.min(_,A),E=Math.max(T,C);this.alignmentGuideLayer.moveTo(L,x),this.alignmentGuideLayer.lineTo(L,E),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}if(Math.abs(_-A)<c||Math.abs(_-C)<c||Math.abs(T-A)<c||Math.abs(T-C)<c){let L=Math.abs(_-A)<c?A:Math.abs(_-C)<c?C:Math.abs(T-A)<c?A:C,x=Math.min(I,M),E=Math.max(P,k);this.alignmentGuideLayer.moveTo(x,L),this.alignmentGuideLayer.lineTo(E,L),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}}}selectAll(){let e=Array.from(this.objectMap.keys()).filter(t=>{let i=this.getEditableObjectConfig(t),n=this.objectMap.get(t);return!(!(n!=null&&n.displayObject)||n.displayObject.visible===!1||this.backgroundLocked&&this.isBackgroundObject(t,i,n.displayObject))});this.selectedIds=new Set(e),e.length>0&&(this.selectedId=e[0],this.updateGizmos())}deleteSelectedObjects(){let e=Array.from(this.selectedIds);for(let t of e){let i=window.__deleteObjectRequest;typeof i=="function"&&i(t)}this.selectedIds.clear(),this.selectedId=null,this.updateGizmos()}handleResize(){this.app&&(this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid())}adjustPositionForAnchorChange(e,t,i){var k,A,C,L,x,E;if(t==null||i==null||t===i)return;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(k=n.transform)!=null?k:{};if(a.position_ratio!=null)return;let s=(A=this.getRuntimeScreenSize())!=null?A:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let r=this.objectMap.get(e);if(!(r!=null&&r.displayObject))return;let l=this.isBackgroundObject(e,n,r.displayObject),c=this.getRuntimeScale(),d=r.displayObject.position.x,p=r.displayObject.position.y,u=De(s.width,s.height,t),g=De(s.width,s.height,i),h=u.x,f=u.y,m=g.x,b=g.y;l||(h=(u.x-s.width/2)/c,f=(u.y-s.height/2)/c,m=(g.x-s.width/2)/c,b=(g.y-s.height/2)/c);let y={x:d-h,y:p-f},v={x:d-m,y:p-b},w=a.offset,I=Array.isArray(w)?Number((C=w[0])!=null?C:0):Number((L=w==null?void 0:w.x)!=null?L:0),P=Array.isArray(w)?Number((x=w[1])!=null?x:0):Number((E=w==null?void 0:w.y)!=null?E:0),_=v.x-I,T=v.y-P,M=this.buildPositionValue(a,{x:_,y:T});this.updateManager.updateProperty(e,"transform.position",M,{refreshInspector:!0})}getPickCandidates(e){var i;let t=[];for(let[n,a]of this.objectMap.entries()){let s=a.displayObject;if(!s||s.visible===!1||this.backgroundLocked&&this.isBackgroundObject(n,this.getEditableObjectConfig(n),s))continue;let r=(i=s.getBounds)==null?void 0:i.call(s);if(!r||r.width<=0||r.height<=0||e.x<r.x||e.x>r.x+r.width||e.y<r.y||e.y>r.y+r.height)continue;let l=s.parent,c=typeof(l==null?void 0:l.zIndex)=="number"?l.zIndex:0,d=typeof s.zIndex=="number"?s.zIndex:0,p=typeof(l==null?void 0:l.getChildIndex)=="function"?l.getChildIndex(s):0,u=c*1e6+d*1e3+p;t.push({id:n,order:u})}return t.sort((n,a)=>a.order-n.order),t.map(n=>n.id)}areSameIds(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i+=1)if(e[i]!==t[i])return!1;return!0}isGizmoTarget(e){return e&&this.spawnPointLayer.children.indexOf(e)!==-1?!0:e===this.moveHandle||e===this.scaleHandle||e===this.rotateHandle||e===this.gizmoOutline}restoreScenePreferences(){if(typeof window!="undefined"){try{let e=window.localStorage.getItem(this.getSceneStorageKey("grid_enabled")),t=window.localStorage.getItem(this.getSceneStorageKey("grid_gap")),i=window.localStorage.getItem(this.getSceneStorageKey("grid_alpha")),n=window.localStorage.getItem(this.getSceneStorageKey("snap_to_grid")),a=window.localStorage.getItem(this.getSceneStorageKey("background_cover")),s=window.localStorage.getItem(this.getSceneStorageKey("background_lock"));if(e!==null&&(this.gridEnabled=e==="true"),t!==null){let r=Number(t);Number.isFinite(r)&&r>2&&(this.gridGap=r)}if(i!==null){let r=Number(i);Number.isFinite(r)&&r>=0&&r<=1&&(this.gridAlpha=r)}n!==null&&(this.snapToGrid=n==="true"),a!==null&&(this.backgroundCoverEnabled=a==="true"),s!==null&&(this.backgroundLocked=s==="true")}catch{}this.updateGrid()}}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}applyPlayModeState(e){var t;this.playModeEnabled=e,(t=this.app)!=null&&t.ticker&&(this.app.ticker.remove(this.syncFromGameObjects),e&&this.app.ticker.add(this.syncFromGameObjects)),this.applyEditControls(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})}applyEditControls(){this.moveHandle.eventMode="static",this.scaleHandle.eventMode="static",this.rotateHandle.eventMode="static"}schedulePostScreenSync(e){this.screenSyncRaf&&cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=requestAnimationFrame(()=>{this.runPostScreenSync(e)})}async runPostScreenSync(e){this.screenSyncRaf=null,this.isVisible&&this.playModeEnabled&&(this.updateLayout(e),this.hasUserCamera||this.centerCamera(),await this.syncFromConfig(),this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid())}getRuntimeScreenSize(){var a,s,r,l,c,d,p;let e=window.gameApp;if(e!=null&&e.renderer){let u=e.renderer.screen,g=Number((a=u==null?void 0:u.width)!=null?a:0),h=Number((s=u==null?void 0:u.height)!=null?s:0);if(Number.isFinite(g)&&g>0&&Number.isFinite(h)&&h>0)return{width:g,height:h};let f=Number((r=e.renderer.resolution)!=null?r:1)||1,m=Number((l=e.renderer.width)!=null?l:0)/f,b=Number((c=e.renderer.height)!=null?c:0)/f;if(Number.isFinite(m)&&m>0&&Number.isFinite(b)&&b>0)return{width:m,height:b}}let t=document.querySelector(".game-container"),i=Number((d=t==null?void 0:t.dataset)==null?void 0:d.screenWidth),n=Number((p=t==null?void 0:t.dataset)==null?void 0:p.screenHeight);return Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:null}getRuntimeLayoutReference(){var a,s,r,l,c,d,p,u,g,h,f,m,b,y,v,w,I,P,_,T,M,k,A,C,L,x,E,S,O,j,R,z,D,q;let e=window.__screenManager;if(e){let G=["gameplay","start","tutorial","endgame","loading"];for(let B of G){let F=(a=e.get)==null?void 0:a.call(e,B);if(F!=null&&F.visible){let U=(s=F.getContentLayer)==null?void 0:s.call(F);if(U){let Z=(r=F.x)!=null?r:0,ee=(l=F.y)!=null?l:0,H=(c=U.x)!=null?c:0,ae=(d=U.y)!=null?d:0,te=(u=(p=U.scale)==null?void 0:p.x)!=null?u:1,ie=(h=(g=U.scale)==null?void 0:g.y)!=null?h:te;return console.log("[SceneEditor] getRuntimeLayoutReference: using visible screen contentLayer",{screenId:B,contentLayerScale:{x:te,y:ie},position:{x:Z+H,y:ee+ae}}),{scale:{x:te,y:ie},position:{x:Z+H,y:ee+ae},pivot:U.pivot?{x:U.pivot.x,y:U.pivot.y}:void 0}}}}for(let B of G){let F=(f=e.get)==null?void 0:f.call(e,B);if(F){if(!F.visible&&typeof F.updateLayout=="function"){let Z=window.gameApp;if((m=Z==null?void 0:Z.renderer)!=null&&m.screen){let ee=Z.renderer.screen.width,H=Z.renderer.screen.height;ee>0&&H>0&&F.updateLayout(ee,H)}}let U=(b=F.getContentLayer)==null?void 0:b.call(F);if(U){let Z=(y=F.x)!=null?y:0,ee=(v=F.y)!=null?v:0,H=(w=U.x)!=null?w:0,ae=(I=U.y)!=null?I:0,te=(_=(P=U.scale)==null?void 0:P.x)!=null?_:1,ie=(M=(T=U.scale)==null?void 0:T.y)!=null?M:te;return console.log("[SceneEditor] getRuntimeLayoutReference: using any screen contentLayer",{screenId:B,visible:F.visible,contentLayerScale:{x:te,y:ie},position:{x:Z+H,y:ee+ae}}),{scale:{x:te,y:ie},position:{x:Z+H,y:ee+ae},pivot:U.pivot?{x:U.pivot.x,y:U.pivot.y}:void 0}}}}}let t=window.__mainContainer;if(t){let G=(A=(k=t.scale)==null?void 0:k.x)!=null?A:1,B=(L=(C=t.scale)==null?void 0:C.y)!=null?L:G;return console.log("[SceneEditor] getRuntimeLayoutReference: using __mainContainer",{scale:{x:G,y:B},position:{x:(x=t.position)==null?void 0:x.x,y:(E=t.position)==null?void 0:E.y}}),t}let i=window.gameApp,n=(S=i==null?void 0:i.stage)!=null?S:null;if(n){let G=(j=(O=n.scale)==null?void 0:O.x)!=null?j:1,B=(z=(R=n.scale)==null?void 0:R.y)!=null?z:G;console.log("[SceneEditor] getRuntimeLayoutReference: using gameApp.stage (fallback)",{scale:{x:G,y:B},position:{x:(D=n.position)==null?void 0:D.x,y:(q=n.position)==null?void 0:q.y}})}else console.log("[SceneEditor] getRuntimeLayoutReference: no reference found");return n}getRuntimeScale(){var i,n;let e=this.getRuntimeLayoutReference(),t=Number((n=(i=e==null?void 0:e.scale)==null?void 0:i.x)!=null?n:1);return Number.isFinite(t)&&t>0?t:Number.isFinite(this.layoutScale)&&this.layoutScale>0?this.layoutScale:1}getRuntimeParentContainer(e){var c,d,p,u,g;let t=window.gameObjectManager;if(!(t!=null&&t.get))return null;let i=t.get(e),n=((c=i==null?void 0:i.getDisplayObject)==null?void 0:c.call(i))||(i==null?void 0:i.pixiObject)||i,a=n==null?void 0:n.parent;if(!a)return null;let s=window.__screenManager;if(s){let h=["gameplay","start","tutorial","endgame","loading"];for(let f of h){let m=(d=s.get)==null?void 0:d.call(s,f);if(!m)continue;let b=(u=(p=m.getBgLayer)==null?void 0:p.call(m))!=null?u:m.bgLayer;if(b&&(a===b||typeof b.contains=="function"&&b.contains(a)))return this.bgContainer}}let r=this.getRuntimeLayoutReference(),l=(g=window.gameApp)==null?void 0:g.stage;return r&&l&&r===l?this.mainContainer:r&&typeof r.contains=="function"&&r.contains(a)?this.mainContainer:a===r||a===l?this.mainContainer:this.uiContainer}applyRuntimeTransform(e){var s,r,l,c,d,p,u,g,h,f;if(!e)return console.log("[SceneEditor] applyRuntimeTransform: no reference"),!1;let t=1,i=1,n=Number((r=(s=e.position)==null?void 0:s.x)!=null?r:0),a=Number((c=(l=e.position)==null?void 0:l.y)!=null?c:0);if(!Number.isFinite(n)||!Number.isFinite(a))return console.log("[SceneEditor] applyRuntimeTransform: invalid position",{posX:n,posY:a}),!1;if(console.log("[SceneEditor] applyRuntimeTransform: applying (scale always 1)",{scale:{x:t,y:i},position:{x:n,y:a}}),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.position.set(n,a),this.uiContainer.position.set(n,a),e.pivot&&((d=this.mainContainer.pivot)!=null&&d.set)&&((p=this.uiContainer.pivot)!=null&&p.set)){let m=Number((g=(u=e.pivot)==null?void 0:u.x)!=null?g:0),b=Number((f=(h=e.pivot)==null?void 0:h.y)!=null?f:0);Number.isFinite(m)&&Number.isFinite(b)&&(this.mainContainer.pivot.set(m,b),this.uiContainer.pivot.set(m,b))}return typeof e.rotation=="number"&&(this.mainContainer.rotation=e.rotation,this.uiContainer.rotation=e.rotation),!0}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 s=this.getEditableObjectConfig(a);if(!s){this.removeObject(a);continue}await this.upsertObject(a,s)}this.updateGizmos(),this.updateSpawnPointHandles(),this.updateGameFrame(this.getScreen())}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),a=this.isUiConfig(e,t),s=this.playModeEnabled?this.getRuntimeParentContainer(e):null,l=this.isBackgroundObject(e,t)?this.bgContainer:a?this.uiContainer:this.mainContainer,c=s!=null?s:l;if(!n||n.assetKey!==i||n.isUi!==a){n&&this.removeObject(e);let p=await this.createDisplayObject(e,t);if(!p)return;c.addChild(p),this.objectMap.set(e,{id:e,displayObject:p,assetKey:i,isUi:a}),this.attachObjectInteraction(p,e)}let d=this.objectMap.get(e);d&&(d.displayObject.parent!==c&&c.addChild(d.displayObject),this.applyVisualConfig(d.displayObject,t),(!this.playModeEnabled||!s)&&this.applyTransformFromConfig(e,d.displayObject,t))}async createDisplayObject(e,t){var r,l,c,d,p,u,g,h,f,m,b,y,v,w,I;if((r=t==null?void 0:t.render)!=null&&r.asset)try{if(((c=(l=t==null?void 0:t.render)==null?void 0:l.asset)==null?void 0:c.type)!=="json"){let _=await ve.create(e,t,this.app);if(_ instanceof $.Container)return _}}catch(P){console.warn("[SceneEditor] ObjectFactory failed for",e,P)}let i=t==null?void 0:t.ui,n=(d=t==null?void 0:t.render)!=null?d:{},a=(i==null?void 0:i.text)||(i==null?void 0:i.kind)==="text";if(!!n.background_color){let P=this.getScreen(),_=(p=P==null?void 0:P.width)!=null?p:0,T=(u=P==null?void 0:P.height)!=null?u:0,M=new $.Graphics,k=this.parseColor(n.background_color,0),A=typeof n.background_alpha=="number"?n.background_alpha:1;_>0&&T>0&&M.rect(0,0,_,T).fill({color:k,alpha:A});let C=new $.Container;return C.addChild(M),C}if(a){let P=(h=(g=i==null?void 0:i.color)!=null?g:n==null?void 0:n.tint)!=null?h:"#ffffff",_=new $.TextStyle({fontFamily:"Arial, sans-serif",fontSize:(f=i==null?void 0:i.fontSize)!=null?f:16,fill:P,align:(m=i==null?void 0:i.align)!=null?m:"center",letterSpacing:(b=i==null?void 0:i.letterSpacing)!=null?b:0});return new $.Text({text:(y=i==null?void 0:i.text)!=null?y:"",style:_})}if((v=t==null?void 0:t.effects)!=null&&v.width||(w=t==null?void 0:t.effects)!=null&&w.height){let P=new $.Graphics,_=typeof t.effects.width=="number"?t.effects.width:100,T=typeof t.effects.height=="number"?t.effects.height:100,M=(I=t.effects.fill_color)!=null?I:"#ffffff",k=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,A=Number.parseInt(String(M).replace("#",""),16);return P.rect(0,0,_,T).fill({color:Number.isFinite(A)?A:16777215,alpha:k}),P}return new $.Container}attachObjectInteraction(e,t){if(e&&(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=new $.Rectangle(i.x,i.y,i.width,i.height))}}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}isUiConfig(e,t){var a,s;let i=(((a=t==null?void 0:t.identity)==null?void 0:a.category)||"").toString().toLowerCase(),n=(((s=t==null?void 0:t.identity)==null?void 0:s.id)||e||"").toString().toLowerCase();return i.includes("ui")||n.startsWith("ui")||n.includes("label")}isBackgroundObject(e,t,i){var s,r;if((i==null?void 0:i.parent)===this.bgContainer)return!0;let n=(((s=t==null?void 0:t.identity)==null?void 0:s.category)||"").toString().toLowerCase(),a=(((r=t==null?void 0:t.identity)==null?void 0:r.id)||e||"").toString().toLowerCase();return!!(n.includes("bg")||n.includes("background")||a.startsWith("background_")||a.includes("background"))}applyVisualConfig(e,t){var a,s,r;if(!e)return;let i=(a=t==null?void 0:t.render)!=null?a:{};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={x:.5,y:.5};if((s=e.anchor)!=null&&s.set)e.anchor.set(n.x,n.y);else if(e.pivot){let l=(r=e.getLocalBounds)==null?void 0:r.call(e);l&&e.pivot.set(l.width*n.x,l.height*n.y)}}applyTransformFromConfig(e,t,i){var _,T,M,k,A,C,L,x,E,S,O,j,R,z,D,q,G,B,F,U,Z;if(!t)return;let n=this.getScreen();if(!(n!=null&&n.width)||!(n!=null&&n.height))return;let a=(_=i==null?void 0:i.transform)!=null?_:{},s=this.getPositioningAnchor(e,a),r=a==null?void 0:a.position_ratio,l=a==null?void 0:a.position,c=a==null?void 0:a.offset,d=Array.isArray(l)?Number((T=l[0])!=null?T:0):Number((M=l==null?void 0:l.x)!=null?M:0),p=Array.isArray(l)?Number((k=l[1])!=null?k:0):Number((A=l==null?void 0:l.y)!=null?A:0),u=Array.isArray(c)?Number((C=c[0])!=null?C:0):Number((L=c==null?void 0:c.x)!=null?L:0),g=Array.isArray(c)?Number((x=c[1])!=null?x:0):Number((E=c==null?void 0:c.y)!=null?E:0),h=(Number.isFinite(d)?d:0)+(Number.isFinite(u)?u:0),f=(Number.isFinite(p)?p:0)+(Number.isFinite(g)?g:0);if(this.backgroundCoverEnabled&&this.isBackgroundObject(e,i,t)){let ee=Number((O=(S=t==null?void 0:t.texture)==null?void 0:S.width)!=null?O:0),H=Number((R=(j=t==null?void 0:t.texture)==null?void 0:j.height)!=null?R:0);if(!Number.isFinite(ee)||ee<=0||!Number.isFinite(H)||H<=0){let ge=(z=t==null?void 0:t.getLocalBounds)==null?void 0:z.call(t);ee=Number((D=ge==null?void 0:ge.width)!=null?D:0),H=Number((q=ge==null?void 0:ge.height)!=null?q:0)}if(!Number.isFinite(ee)||ee<=0||!Number.isFinite(H)||H<=0)return;(G=t.anchor)!=null&&G.set&&t.anchor.set(.5,.5),(B=t.position)!=null&&B.set?t.position.set(n.width/2,n.height/2):t.position&&(t.position.x=n.width/2,t.position.y=n.height/2);let ae=n.width/ee,te=n.height/H,ie=Math.max(ae,te);(F=t.scale)!=null&&F.set?t.scale.set(ie,ie):t.scale&&(t.scale.x=ie,t.scale.y=ie);let Oe=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(Oe);return}let m=r!=null?dt(n.width,n.height,r):De(n.width,n.height,s),b=this.getRuntimeScale(),y=(m.x-n.width/2)/b+h,v=(m.y-n.height/2)/b+f;(U=t.position)!=null&&U.set?t.position.set(y,v):t.position&&(t.position.x=y,t.position.y=v);let I=(typeof(a==null?void 0:a.scale)=="number"?a.scale:1)*this.getRuntimeScale();(Z=t.scale)!=null&&Z.set?t.scale.set(I,I):t.scale&&(t.scale.x=I,t.scale.y=I);let P=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(P)}getAnchorLocalPoint(e,t=this.mainContainer){var d;let i=(d=this.getRuntimeScreenSize())!=null?d:this.getScreen();if(!(i!=null&&i.width)||!(i!=null&&i.height))return null;let n="top-right",a=this.getPositioningAnchor(this.selectedId,e!=null?e:{}),s=(e==null?void 0:e.position_ratio)!=null?dt(i.width,i.height,e.position_ratio):De(i.width,i.height,a!=null?a:n);if(t===this.bgContainer)return new $.Point(s.x,s.y);let r=this.getRuntimeScale(),l=(s.x-i.width/2)/r,c=(s.y-i.height/2)/r;return new $.Point(l,c)}getPositioningAnchor(e,t){var i,n,a,s,r,l,c,d,p,u;if((t==null?void 0:t.anchor)!=null&&t.anchor!=="")return t.anchor;if(typeof window!="undefined"&&e){let g=window,h=g.__editableConfig,f=(n=(i=h==null?void 0:h.objects)==null?void 0:i.get)==null?void 0:n.call(i,e),m=(r=(a=f==null?void 0:f.transform)==null?void 0:a.anchor)!=null?r:(s=f==null?void 0:f.render)==null?void 0:s.anchor;if(m!=null&&m!=="")return m;let b=g.__editableConfigBaseline,y=(c=(l=b==null?void 0:b.objects)==null?void 0:l.get)==null?void 0:c.call(l,e),v=(u=(d=y==null?void 0:y.transform)==null?void 0:d.anchor)!=null?u:(p=y==null?void 0:y.render)==null?void 0:p.anchor;if(v!=null&&v!=="")return v}return"top-left"}getActiveScreenSize(e){var t,i;return this.playModeEnabled?(i=(t=this.getRuntimeScreenSize())!=null?t:e)!=null?i:this.getScreen():e!=null?e:this.getScreen()}updateLayout(e){var i,n,a,s,r,l,c,d,p;let t=this.getActiveScreenSize(e);if(!(!(t!=null&&t.width)||!(t!=null&&t.height))){if(console.log("[SceneEditor] updateLayout: called",{screen:{width:t.width,height:t.height},currentScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y}}),this.playModeEnabled){let u=this.getRuntimeLayoutReference();if(u){let g=Number((n=(i=u.position)==null?void 0:i.x)!=null?n:t.width/2),h=Number((s=(a=u.position)==null?void 0:a.y)!=null?s:t.height/2);this.mainContainer.position.set(g,h),this.uiContainer.position.set(g,h);let f=Number((l=(r=u.scale)==null?void 0:r.x)!=null?l:1);Number.isFinite(f)&&f>0&&(this.layoutScale=f)}this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1)}else this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.position.set(t.width/2,t.height/2),this.uiContainer.position.set(t.width/2,t.height/2),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.rotation=0,this.uiContainer.rotation=0,(c=this.mainContainer.pivot)!=null&&c.set&&this.mainContainer.pivot.set(0,0),(d=this.uiContainer.pivot)!=null&&d.set&&this.uiContainer.pivot.set(0,0);console.log("[SceneEditor] updateLayout: result",{finalScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y},position:{x:this.mainContainer.position.x,y:this.mainContainer.position.y}}),this.screenFrame.clear(),this.screenFrame.rect(0,0,t.width,t.height),this.screenFrame.stroke({width:2,color:2894892,alpha:.5}),this.updateGameFrame(t),(p=this.app)!=null&&p.stage&&(this.app.stage.hitArea=new $.Rectangle(0,0,this.app.renderer.width,this.app.renderer.height)),this.updateSpawnPointHandles()}}updateGrid(){if(!this.app)return;if(!this.gridEnabled){this.gridLayer.clear(),this.gridLayer.visible=!0;return}let e=Math.max(4,this.gridGap),t=this.app.renderer,i=this.camera.toLocal(new $.Point(0,0)),n=this.camera.toLocal(new $.Point(t.width,t.height)),a=Math.min(i.x,n.x),s=Math.max(i.x,n.x),r=Math.min(i.y,n.y),l=Math.max(i.y,n.y),c=400,d=Math.ceil((s-a)/e),p=Math.ceil((l-r)/e),u=e*Math.max(1,Math.ceil(d/c)),g=e*Math.max(1,Math.ceil(p/c)),h=Math.floor(a/u)*u,f=Math.floor(r/g)*g;this.gridLayer.clear(),this.gridLayer.visible=!0;for(let m=h;m<=s;m+=u)this.gridLayer.moveTo(m,r),this.gridLayer.lineTo(m,l);for(let m=f;m<=l;m+=g)this.gridLayer.moveTo(a,m),this.gridLayer.lineTo(s,m);this.gridLayer.stroke({width:1,color:16777215,alpha:this.gridAlpha})}updateGameFrame(e){let t=this.getActiveScreenSize(e);if(!(t!=null&&t.width)||!(t!=null&&t.height))return;let i=t.width,n=t.height,a=0,s=0;this.lastGameFrameSize&&this.lastGameFrameSize.width===t.width&&this.lastGameFrameSize.height===t.height||(this.lastGameFrameSize={width:t.width,height:t.height},this.gameFrame.clear(),this.gameFrame.rect(a,s,i,n),this.gameFrame.stroke({width:2,color:6333946,alpha:.35}))}syncFromGameObjectsInternal(){var i,n,a,s,r,l,c,d,p;if(!this.app||!this.isVisible)return;let e=window.gameObjectManager;if(!(e!=null&&e.get))return;let t=this.dragMode||this.selectedId&&performance.now()<this.dragSyncHoldUntil?this.selectedId:null;for(let[u,g]of this.objectMap.entries()){if(t&&u===t)continue;let h=e.get(u),f=((i=h==null?void 0:h.getDisplayObject)==null?void 0:i.call(h))||(h==null?void 0:h.pixiObject)||h;if(!f)continue;let m=(a=(n=g.displayObject)==null?void 0:n.parent)!=null?a:this.mainContainer,b=new $.Point;if(typeof f.getGlobalPosition=="function"){f.getGlobalPosition(b);let P=m.toLocal(b,this.camera);g.displayObject.position.set(P.x,P.y)}else if(f.worldTransform){b.set(f.worldTransform.tx,f.worldTransform.ty);let P=m.toLocal(b,this.camera);g.displayObject.position.set(P.x,P.y)}let y=this.getWorldScale(f);if(y){let P=Number((r=(s=m.scale)==null?void 0:s.x)!=null?r:1)||1,_=Number((c=(l=m.scale)==null?void 0:l.y)!=null?c:1)||1,T=y.x/P,M=y.y/_;(d=g.displayObject.scale)!=null&&d.set?g.displayObject.scale.set(T,M):g.displayObject.scale&&(g.displayObject.scale.x=T,g.displayObject.scale.y=M)}let v=this.getWorldRotation(f);if(typeof v=="number"){let P=m?m.rotation:0,_=v-P;g.displayObject.rotation=_;let T=this.getEditableObjectConfig(u);if(T){let M=(p=T.transform)!=null?p:{};T.transform||(T.transform=M);let k=this.toDegrees(_),A=typeof M.rotation=="number"?M.rotation:0;if(Math.abs(k-A)>.01){let C=Math.round(k*100)/100;M.rotation=C}}}let w=f.parent,I=typeof(w==null?void 0:w.getChildIndex)=="function"?w.getChildIndex(f):0;typeof f.zIndex=="number"?g.displayObject.zIndex=f.zIndex:Number.isFinite(I)&&(g.displayObject.zIndex=I)}this.updateGizmos()}getWorldScale(e){var a,s;let t=(s=e==null?void 0:e.worldTransform)!=null?s:(a=e==null?void 0:e.transform)==null?void 0:a.worldTransform;if(!t)return null;let i=Math.sqrt(t.a*t.a+t.b*t.b),n=Math.sqrt(t.c*t.c+t.d*t.d);return!Number.isFinite(i)||!Number.isFinite(n)?null:{x:i,y:n}}getWorldRotation(e){var i,n;let t=(n=e==null?void 0:e.worldTransform)!=null?n:(i=e==null?void 0:e.transform)==null?void 0:i.worldTransform;if(t){let a=Math.atan2(t.b,t.a);return Number.isFinite(a)?a:null}return typeof(e==null?void 0:e.rotation)=="number"?e.rotation:null}centerCamera(){if(!this.app)return;let e=this.getActiveScreenSize();if(!(e!=null&&e.width)||!(e!=null&&e.height))return;let t=this.app.renderer.width,i=this.app.renderer.height,n=Math.max(.01,Math.min(t/e.width,i/e.height));this.cameraScale=n,this.camera.scale.set(n),this.camera.position.set((t-e.width*n)/2,(i-e.height*n)/2)}updateGizmos(){var f,m,b,y,v,w;if(!this.selectedId&&this.selectedIds.size===0||!this.isVisible){this.clearGizmos();return}if(this.selectedIds.size>1){let I=1/0,P=1/0,_=-1/0,T=-1/0,M=!1;for(let k of this.selectedIds){let A=this.objectMap.get(k);if(!(A!=null&&A.displayObject))continue;let C=(m=(f=A.displayObject).getBounds)==null?void 0:m.call(f);if(!C||C.width<=0||C.height<=0)continue;let L=this.camera.toLocal(new $.Point(C.x,C.y)),x=this.camera.toLocal(new $.Point(C.x+C.width,C.y+C.height));I=Math.min(I,L.x,x.x),P=Math.min(P,L.y,x.y),_=Math.max(_,L.x,x.x),T=Math.max(T,L.y,x.y),M=!0}if(M){let k=_-I,A=T-P,C=I+k/2,L=P+A/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(I,P,k,A),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});for(let S of this.selectedIds){let O=this.objectMap.get(S);if(!(O!=null&&O.displayObject))continue;let j=(y=(b=O.displayObject).getBounds)==null?void 0:y.call(b);if(!j||j.width<=0||j.height<=0)continue;let R=this.camera.toLocal(new $.Point(j.x,j.y)),z=this.camera.toLocal(new $.Point(j.x+j.width,j.y+j.height)),D=z.x-R.x,q=z.y-R.y;this.gizmoOutline.rect(R.x,R.y,D,q),this.gizmoOutline.stroke({width:1,color:16752394,alpha:.5})}let x=7,E={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(C,L,x).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(E),this.moveHandle.cursor="move",this.scaleHandle.clear(),this.rotateHandle.clear()}else this.clearGizmos();return}if(!this.selectedId){this.clearGizmos();return}let e=this.objectMap.get(this.selectedId);if(!(e!=null&&e.displayObject)){this.clearGizmos();return}let t=(w=(v=e.displayObject).getBounds)==null?void 0:w.call(v);if(!t||t.width<=0||t.height<=0){this.clearGizmos();return}let i=this.camera.toLocal(new $.Point(t.x,t.y)),n=this.camera.toLocal(new $.Point(t.x+t.width,t.y+t.height)),a=n.x-i.x,s=n.y-i.y,r=i.x+a/2,l=i.y+s/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(i.x,i.y,a,s),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});let c=7,d={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(r,l,c).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(d),this.moveHandle.cursor="move";let p=i.x+a,u=i.y+s;this.scaleHandle.clear(),this.scaleHandle.rect(p-c,u-c,c*2,c*2).fill({color:3718648,alpha:.95}),this.scaleHandle.stroke(d),this.scaleHandle.cursor="nwse-resize";let g=r,h=i.y-c*2;this.rotateHandle.clear(),this.rotateHandle.circle(g,h,c).fill({color:16347926,alpha:.95}),this.rotateHandle.stroke(d),this.rotateHandle.cursor="crosshair"}clearGizmos(){this.gizmoOutline.clear(),this.moveHandle.clear(),this.scaleHandle.clear(),this.rotateHandle.clear()}updateSpawnPointHandles(){if(this.clearSpawnPointHandles(),!this.selectedId)return;let e=this.getEditableObjectConfig(this.selectedId);if(!e||!this.isSpawnerConfig(e))return;let t=this.getSpawnPoints(e);!t||t.length===0||t.forEach((i,n)=>{let a=new $.Graphics;a.circle(0,0,5).fill({color:16096779,alpha:.9}),a.circle(0,0,9).stroke({width:1,color:16096779,alpha:.45});let s=this.toCameraFromMain(i);a.position.set(s.x,s.y),a.cursor="move",a.eventMode="static",a.on("pointerdown",r=>this.startSpawnPointDrag(n,r)),this.spawnPointLayer.addChild(a)})}clearSpawnPointHandles(){this.spawnPointLayer.removeChildren().forEach(t=>{var i;(i=t.destroy)==null||i.call(t)})}isSpawnerConfig(e){var i,n;return((i=e==null?void 0:e.logic)==null?void 0:i.id)==="Spawner"?!0:String(((n=e==null?void 0:e.identity)==null?void 0:n.system_role)||"").toLowerCase().includes("spawner")}getSpawnPoints(e){var i,n;let t=(n=(i=e==null?void 0:e.logic)==null?void 0:i.props)==null?void 0:n.spawnPoints;return Array.isArray(t)?t.map(a=>{var s,r;return{x:Number((s=a==null?void 0:a.x)!=null?s:0),y:Number((r=a==null?void 0:a.y)!=null?r:0)}}):null}toCameraFromMain(e){let t=this.mainContainer.toGlobal(new $.Point(e.x,e.y)),i=new $.Point;return this.camera.toLocal(t,void 0,i),i}startSpawnPointDrag(e,t){var r,l;if(!this.selectedId)return;let i=this.getEditableObjectConfig(this.selectedId);if(!i)return;let n=this.getSpawnPoints(i);if(!n||!n[e])return;(r=t==null?void 0:t.stopPropagation)==null||r.call(t),(l=t==null?void 0:t.stopImmediatePropagation)==null||l.call(t);let a=this.getEventLocalPoint(t,this.mainContainer);if(!a)return;let s=n[e];this.spawnPointDrag={objectId:this.selectedId,index:e,offset:new $.Point(s.x-a.x,s.y-a.y),startPoints:n.map(c=>({x:c.x,y:c.y}))},window.addEventListener("pointermove",this.onSpawnPointDragMove),window.addEventListener("pointerup",this.onSpawnPointDragEnd)}updateLiveSpawnPoint(e,t,i,n){let a=this.getEditableObjectConfig(e);if(!a)return;let s=this.getSpawnPoints(a);if(!s||!s[t])return;let r=s.map((l,c)=>c===t?{x:i,y:n}:{x:l.x,y:l.y});this.setNestedValue(a,"logic.props.spawnPoints",r),this.queueLiveApply(e),this.updateSpawnPointHandles()}setSelected(e,t={}){if(!(this.selectedId===e&&this.selectedIds.size===1&&this.selectedIds.has(e||""))&&(this.selectedId=e,e?(this.selectedIds.clear(),this.selectedIds.add(e)):this.selectedIds.clear(),this.updateGizmos(),this.updateSpawnPointHandles(),!t.silent&&e)){let i=window.__previewSelectObject;typeof i=="function"&&i(e)}}startDrag(e,t){var d,p,u,g,h,f,m;if(!this.selectedId)return;let i=this.objectMap.get(this.selectedId);if(!(i!=null&&i.displayObject))return;let n=this.getEditableObjectConfig(this.selectedId);if(!n||this.backgroundLocked&&this.isBackgroundObject(this.selectedId,n,i.displayObject))return;let a=(d=n.transform)!=null?d:{},s=(p=i.displayObject.parent)!=null?p:this.mainContainer,r=this.getEventLocalPoint(t,s);if(!r)return;(u=t==null?void 0:t.stopPropagation)==null||u.call(t),(g=t==null?void 0:t.stopImmediatePropagation)==null||g.call(t);let l=this.getPositioningAnchor(this.selectedId,a);(a.anchor==null||a.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"transform.anchor",l),(((h=n==null?void 0:n.render)==null?void 0:h.anchor)==null||n.render.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"render.anchor",l),this.dragMode=e,this.dragContainer=s,this.dragStartPointer=new $.Point(r.x,r.y),this.dragStartPos=new $.Point(i.displayObject.position.x,i.displayObject.position.y),this.dragLastPointer=new $.Point(r.x,r.y),this.dragPointerOffset=new $.Point(i.displayObject.position.x-r.x,i.displayObject.position.y-r.y),this.dragLogged=!1;let c=(f=this.getRuntimeScreenSize())!=null?f:this.getScreen();console.log("[SceneEditor][DragStart]",{objectId:this.selectedId,mode:e,isBackground:this.isBackgroundObject(this.selectedId,n,i.displayObject),screen:c,runtimeScale:this.getRuntimeScale(),pointer:{x:r.x,y:r.y},objectPos:{x:i.displayObject.position.x,y:i.displayObject.position.y},container:s===this.bgContainer?"bg":s===this.uiContainer?"ui":"main"}),this.dragStartScale=typeof((m=i.displayObject.scale)==null?void 0:m.x)=="number"?i.displayObject.scale.x:1,this.dragStartRotation=typeof i.displayObject.rotation=="number"?i.displayObject.rotation:0,this.dragAnchorLocal=this.getAnchorLocalPoint(a,s),this.dragStartValue=this.getDragStartValue(e,a),this.dragAnchorLocal&&(this.dragStartAngle=Math.atan2(r.y-this.dragAnchorLocal.y,r.x-this.dragAnchorLocal.x),this.dragStartDistance=Math.max(1,this.distance(r,this.dragAnchorLocal))),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}updateLiveConfigPositionForObject(e,t,i){var I,P,_,T,M,k,A,C;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(I=n.transform)!=null?I:{};n.transform||(n.transform=a);let s=(P=this.getRuntimeScreenSize())!=null?P:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let r=this.objectMap.get(e),l=((_=r==null?void 0:r.displayObject)==null?void 0:_.parent)===this.bgContainer,c=this.getPositioningAnchor(e,a),d=(a==null?void 0:a.position_ratio)!=null?dt(s.width,s.height,a.position_ratio):De(s.width,s.height,c),p=d.x,u=d.y,g=t,h=i;if(!l){let L=this.getRuntimeScale();p=(d.x-s.width/2)/L,u=(d.y-s.height/2)/L,g=t/L,h=i/L}let f=g-p,m=h-u,b=(T=a.offset)!=null?T:{x:0,y:0},y=Array.isArray(b)?Number((M=b[0])!=null?M:0):Number((k=b==null?void 0:b.x)!=null?k:0),v=Array.isArray(b)?Number((A=b[1])!=null?A:0):Number((C=b==null?void 0:b.y)!=null?C:0),w=this.buildPositionValue(a,{x:f-y,y:m-v});this.updateManager.updateProperty(e,"transform.position",w,{refreshInspector:!0})}updateLiveConfigPosition(e,t){this.selectedId&&this.updateLiveConfigPositionForObject(this.selectedId,e,t)}updateLiveConfigScale(e){var a;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(a=t.transform)!=null?a:{};t.transform||(t.transform=i);let n=Math.round(e*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.scale",n,{refreshInspector:!0})}updateLiveConfigRotation(e){var s;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(s=t.transform)!=null?s:{};t.transform||(t.transform=i);let n=this.toDegrees(e),a=typeof i.rotation=="number"?i.rotation:0;if(Math.abs(n-a)>.01){let r=Math.round(n*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.rotation",r,{refreshInspector:!0})}}applyFinalOverride(e,t,i,n){let a=this.getEditableObjectConfig(e);a!=null&&a.transform&&this.setNestedValue(a.transform,t.replace("transform.",""),n),oe({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),window.dispatchEvent(new CustomEvent("inspector:refresh")))}))}setNestedValue(e,t,i){let n=t.split("."),a=e;for(let s=0;s<n.length-1;s+=1){let r=n[s];(!a[r]||typeof a[r]!="object")&&(a[r]={}),a=a[r]}a[n[n.length-1]]=i}buildPositionValue(e,t){let i=e==null?void 0:e.position,n=Math.round(t.x*100)/100,a=Math.round(t.y*100)/100;return Array.isArray(i)?[n,a]:{x:n,y:a}}toRadians(e){return e*Math.PI/180}toDegrees(e){return e*180/Math.PI}distance(e,t){let i=e.x-t.x,n=e.y-t.y;return Math.sqrt(i*i+n*n)}getPointerButton(e){var t,i,n;return typeof(e==null?void 0:e.button)=="number"?e.button:typeof((t=e==null?void 0:e.data)==null?void 0:t.button)=="number"?e.data.button:typeof((n=(i=e==null?void 0:e.data)==null?void 0:i.originalEvent)==null?void 0:n.button)=="number"?e.data.originalEvent.button:0}getEventGlobalPoint(e){var l,c;let t=(c=e==null?void 0:e.global)!=null?c:(l=e==null?void 0:e.data)==null?void 0:l.global;if(t)return new $.Point(t.x,t.y);if(!this.app)return null;let i=e==null?void 0:e.clientX,n=e==null?void 0:e.clientY;if(typeof i!="number"||typeof n!="number")return null;let a=this.app.canvas.getBoundingClientRect(),s=(i-a.left)*(this.app.renderer.width/a.width),r=(n-a.top)*(this.app.renderer.height/a.height);return new $.Point(s,r)}getEventLocalPoint(e,t=this.mainContainer){var a,s;if(!this.app)return null;if(typeof(e==null?void 0:e.getLocalPosition)=="function"){let r=e.getLocalPosition(t);return new $.Point(r.x,r.y)}let i=(s=e==null?void 0:e.global)!=null?s:(a=e==null?void 0:e.data)==null?void 0:a.global;if(!i)return null;let n=new $.Point;return t.toLocal(new $.Point(i.x,i.y),void 0,n),n}getPointerInContainer(e,t,i){if(!this.app)return null;let n=this.app.canvas.getBoundingClientRect(),a=(e-n.left)*(this.app.renderer.width/n.width),s=(t-n.top)*(this.app.renderer.height/n.height),r=new $.Point;return i.toLocal(new $.Point(a,s),void 0,r),r}parseColor(e,t){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let i=e.trim().replace("#",""),n=Number.parseInt(i,16);if(Number.isFinite(n))return n}return t}drawSelectionBox(e,t){if(!this.selectionBox)return;this.selectionBox.clear();let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),s=Math.max(e.y,t.y),r=n-i,l=s-a;this.selectionBox.rect(i,a,r,l),this.selectionBox.stroke({width:2,color:3900150,alpha:.8}),this.selectionBox.rect(i,a,r,l),this.selectionBox.fill({color:3900150,alpha:.1})}finalizeSelectionBox(e,t){var l;let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),s=Math.max(e.y,t.y),r=[];for(let[c,d]of this.objectMap.entries()){let p=d.displayObject;if(!p||p.visible===!1||this.backgroundLocked&&this.isBackgroundObject(c,this.getEditableObjectConfig(c),p))continue;let u=(l=p.getBounds)==null?void 0:l.call(p);if(!u||u.width<=0||u.height<=0)continue;let g=u.x+u.width/2,h=u.y+u.height/2;g>=i&&g<=n&&h>=a&&h<=s&&r.push(c)}r.length>0&&(this.selectedIds=new Set(r),this.selectedId=r[0],this.updateGizmos())}setupDragAndDrop(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),this.dropZoneActive||(this.dropZoneActive=!0,this.showDropZone())}),e.addEventListener("dragleave",t=>{e.contains(t.relatedTarget)||(this.dropZoneActive=!1,this.hideDropZone())}),e.addEventListener("drop",async t=>{var d;t.preventDefault(),t.stopPropagation(),this.dropZoneActive=!1,this.hideDropZone();let n=Array.from(((d=t.dataTransfer)==null?void 0:d.files)||[]).filter(p=>p.type.startsWith("image/"));if(n.length===0)return;let a=e.getBoundingClientRect(),s=t.clientX-a.left,r=t.clientY-a.top,l=new $.Point(s/a.width*this.app.renderer.width,r/a.height*this.app.renderer.height),c=this.camera.toLocal(l);await this.handleDroppedPNGs(n,c)})}showDropZone(){if(!this.dropZoneOverlay||!this.app)return;let e=this.camera.toLocal(new $.Point(0,0)),t=this.camera.toLocal(new $.Point(this.app.renderer.width,this.app.renderer.height)),i=t.x-e.x,n=t.y-e.y;this.dropZoneOverlay.clear(),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.fill({color:3900150,alpha:.1}),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.stroke({width:3,color:3900150,alpha:.6}),this.dropZoneOverlay.visible=!0}hideDropZone(){this.dropZoneOverlay&&(this.dropZoneOverlay.clear(),this.dropZoneOverlay.visible=!1)}async handleDroppedPNGs(e,t){let i=window.__HANDLER_ACTIVE_SCREEN,n=i==="loading"||i==="start"||i==="gameplay"||i==="tutorial"||i==="endgame"?i:"gameplay",a=this.showToast(`Processing ${e.length} PNG${e.length>1?"s":""}...`);try{for(let s=0;s<e.length;s++){let r=e[s];await this.processDroppedPNG(r,t,n,s)}this.hideToast(a),this.showToast(`\u2705 Added ${e.length} PNG${e.length>1?"s":""} to scene`,2e3),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))}catch(s){this.hideToast(a),this.showToast(`\u274C Error: ${s instanceof Error?s.message:String(s)}`,3e3),console.error("[SceneEditor] Failed to process dropped PNGs:",s)}}async processDroppedPNG(e,t,i,n){let a=await this.fileToDataUrl(e);if(!a)throw new Error(`Failed to read ${e.name}`);let s=e.name.replace(/\.[^/.]+$/,""),r=this.inferCategoryFromFilename(s),l=s.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),c=`${l}_${Date.now()}${n>0?`_${n}`:""}`,d=`json.${c}`,p=`${l}.png`,g=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:r,filename:p,data:a,overwrite:!1})})).json();if(!g.success)throw new Error(`Failed to save ${e.name} to library: ${g.error}`);let h=this.getScreen(),f=this.getRuntimeScale(),m=(t.x-h.width/2)/f,b=(t.y-h.height/2)/f,y={identity:{id:d,category:r},transform:{anchor:"center",position:{x:m,y:b},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:g.path||`raw/library/${r}/${p}`}}},v=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:y,layer:r==="ui"?"ui":"world"})}),w=await v.json();if(!v.ok||!w.success)throw new Error(`Failed to create object: ${w.error||"Unknown error"}`)}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}showToast(e,t=3e3){let i=document.createElement("div");return i.style.cssText=`
2358
+ `;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(()=>(gt(),Ft)).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(r){new Da().open(r)};ca();ne();var D=require("pixi.js");ne();var hn=class{constructor(e){this.app=null;this.camera=new D.Container;this.bgContainer=new D.Container;this.mainContainer=new D.Container;this.uiContainer=new D.Container;this.gizmoLayer=new D.Container;this.screenFrame=new D.Graphics;this.gameFrame=new D.Graphics;this.gridLayer=new D.Graphics;this.spawnPointLayer=new D.Container;this.objectMap=new Map;this.selectedId=null;this.selectedIds=new Set;this.dragMode=null;this.selectionBox=null;this.selectionBoxStart=null;this.isSelectionBoxActive=!1;this.dragStartPointer=null;this.dragStartPos=null;this.dragStartScale=1;this.dragStartRotation=0;this.dragStartAngle=0;this.dragStartDistance=1;this.dragAnchorLocal=null;this.dragStartValue=null;this.dragContainer=null;this.dragLastPointer=null;this.dragPointerOffset=null;this.dragSyncHoldUntil=0;this.dragLogged=!1;this.spawnPointDrag=null;this.lastGameFrameSize=null;this.cameraScale=1;this.isPanning=!1;this.panStart=null;this.panStartCamera=null;this.hasUserCamera=!1;this.resizeObserver=null;this.screenSyncRaf=null;this.gizmoOutline=new D.Graphics;this.anchorVisualizationLayer=new D.Graphics;this.moveHandle=new D.Graphics;this.scaleHandle=new D.Graphics;this.rotateHandle=new D.Graphics;this.isVisible=!0;this.applyQueued=!1;this.applyQueuedId=null;this.gridEnabled=!1;this.gridGap=50;this.gridAlpha=.25;this.snapToGrid=!1;this.alignmentGuidesEnabled=!0;this.alignmentGuideLayer=new D.Graphics;this.lastPickPoint=null;this.lastPickIds=[];this.lastPickIndex=0;this.lastPickTime=0;this.playModeEnabled=!0;this.playModeInitialized=!1;this.layoutScale=1;this.updateManager=new Se;this.backgroundCoverEnabled=!0;this.backgroundLocked=!0;this.backgroundCoverRetries=new Map;this.backgroundCoverRaf=null;this.dropZoneActive=!1;this.dropZoneOverlay=null;this.handleScreenChange=e=>{if(!(e!=null&&e.detail))return;let{width:t,height:i}=e.detail;!t||!i||(this.hasUserCamera=!1,this.updateLayout({width:t,height:i}),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid(),this.playModeEnabled?this.schedulePostScreenSync({width:t,height:i}):this.syncFromConfig())};this.handleAnchorChanged=e=>{let t=e==null?void 0:e.detail,i=t==null?void 0:t.objectId;if(!i)return;let n=t==null?void 0:t.previousAnchor,a=t==null?void 0:t.nextAnchor;this.adjustPositionForAnchorChange(i,n,a)};this.handleActiveScreenChanged=()=>{this.isVisible&&this.syncFromConfig()};this.handleConfigChanged=e=>{if(!this.isVisible)return;this.updateLayout(),this.updateGrid();let t=e==null?void 0:e.detail;if(!t){this.syncFromConfig();return}let i=t.path,n=t.objectId;if(i==="transform.anchor"&&n){let s=t.value,o=t.oldValue;o!=null&&this.adjustPositionForAnchorChange(n,o,s)}let a=t.objectIds;if(n){this.syncFromConfig([n]);return}if(Array.isArray(a)&&a.length>0){this.syncFromConfig(a);return}this.syncFromConfig()};this.handleSceneRefresh=()=>{this.isVisible&&this.syncFromConfig()};this.handleAssetUpdated=e=>{var l;let t=(l=e==null?void 0:e.detail)!=null?l:{},i=t.objectId,n=t.texture;if(!i||!n)return;let a=this.objectMap.get(i);if(!a)return;let s=a.displayObject;if(s!=null&&s.texture)s.texture=n;else if(s!=null&&s.children){let c=s.children.find(d=>d==null?void 0:d.texture);c&&(c.texture=n)}let o=this.getEditableObjectConfig(i);o&&(a.assetKey=this.getAssetKey(o))};this.handleLayoutApplied=e=>{var s;if(!this.isVisible)return;let t=(s=e==null?void 0:e.detail)!=null?s:{},i=Number(t.width),n=Number(t.height),a=Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:this.getScreen();this.updateLayout(a),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})};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.onStagePointerDown=e=>{if(!this.app||!this.isVisible)return;let t=this.getPointerButton(e);if(t===2){if(this.isGizmoTarget(e==null?void 0:e.target))return;let h=this.getEventGlobalPoint(e);if(!h)return;let f=new D.Point(h.x,h.y),m=this.getPickCandidates(f);if(m.length>0){let b=m[0];this.selectedIds.has(b)||(this.selectedIds.clear(),this.selectedIds.add(b),this.setSelected(b),this.updateGizmos()),this.showContextMenu(b,h.x,h.y)}return}if(t!==0||this.isGizmoTarget(e==null?void 0:e.target))return;let i=this.getEventGlobalPoint(e);if(!i)return;let n=new D.Point(i.x,i.y),a=this.getPickCandidates(n),o=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey;if(a.length===0){o||(this.setSelected(null),this.selectedIds.clear()),this.selectionBoxStart=n,this.isSelectionBoxActive=!0,this.lastPickIds=[],this.lastPickIndex=0,this.lastPickPoint=n,this.lastPickTime=performance.now();return}let l=performance.now(),c=this.areSameIds(a,this.lastPickIds),d=this.lastPickPoint&&this.distance(n,this.lastPickPoint)<=6,p=l-this.lastPickTime<1200,u=c&&d&&p?(this.lastPickIndex+1)%a.length:0,g=a[u];this.lastPickIds=a,this.lastPickIndex=u,this.lastPickPoint=n,this.lastPickTime=l,o?this.selectedIds.has(g)?(this.selectedIds.delete(g),this.selectedId===g&&(this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null)):(this.selectedIds.add(g),this.selectedId=g):(this.selectedIds.clear(),this.selectedIds.add(g),this.setSelected(g)),this.updateGizmos()};this.handleGridSettings=e=>{var a,s,o;let t=(a=e==null?void 0:e.detail)==null?void 0:a.enabled,i=(s=e==null?void 0:e.detail)==null?void 0:s.gap,n=(o=e==null?void 0:e.detail)==null?void 0:o.alpha;typeof t=="boolean"&&(this.gridEnabled=t),typeof i=="number"&&Number.isFinite(i)&&i>2&&(this.gridGap=i),typeof n=="number"&&Number.isFinite(n)&&n>=0&&n<=1&&(this.gridAlpha=n),this.updateGrid()};this.handleBackgroundCover=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(this.backgroundCoverEnabled=t,this.syncFromConfig(),this.updateGizmos())};this.handleBackgroundLock=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;if(typeof t=="boolean"&&(this.backgroundLocked=t,t&&this.selectedId)){let n=this.getEditableObjectConfig(this.selectedId),a=this.objectMap.get(this.selectedId);this.isBackgroundObject(this.selectedId,n,a==null?void 0:a.displayObject)&&this.setSelected(null)}};this.handlePlayModeChange=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(!this.playModeInitialized&&(this.playModeInitialized=!0,!t)||t&&this.applyPlayModeState(!0))};this.syncFromGameObjects=()=>{this.syncFromGameObjectsInternal()};this.onSpawnPointDragMove=e=>{if(!this.spawnPointDrag)return;let t=this.getPointerInContainer(e.clientX,e.clientY,this.mainContainer);if(!t)return;let i=t.x+this.spawnPointDrag.offset.x,n=t.y+this.spawnPointDrag.offset.y;this.updateLiveSpawnPoint(this.spawnPointDrag.objectId,this.spawnPointDrag.index,i,n)};this.onSpawnPointDragEnd=()=>{if(!this.spawnPointDrag)return;let{objectId:e,startPoints:t}=this.spawnPointDrag,i=this.getEditableObjectConfig(e),n=i?this.getSpawnPoints(i):null;i&&n&&(this.setNestedValue(i,"logic.props.spawnPoints",t),le({objectId:e,path:"logic.props.spawnPoints",value:n},{persist:!0,emitEvent:!0,trackHistory:!0}),this.queueLiveApply(e)),this.spawnPointDrag=null,window.dispatchEvent(new CustomEvent("inspector:refresh")),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd)};this.onDragMove=e=>{var n;if(!this.dragMode||!this.selectedId||!this.dragContainer||!this.dragStartPointer||!this.dragStartPos)return;let t=this.objectMap.get(this.selectedId);if(!(t!=null&&t.displayObject))return;let i=this.getPointerInContainer(e.clientX,e.clientY,this.dragContainer);if(i){if(this.dragMode==="move"){let a=this.dragPointerOffset;if(!a)return;let s=i.x+a.x,o=i.y+a.y;if(this.snapToGrid){let d=this.snapToGridPosition(s,o);s=d.x,o=d.y}let l=s-this.dragStartPos.x,c=o-this.dragStartPos.y;if(t.displayObject.position.set(s,o),this.updateAlignmentGuides(this.selectedId,new D.Point(s,o)),this.updateLiveConfigPosition(s,o),this.selectedIds.size>1){let d=new Map;if(!this.multiDragStartPositions){this.multiDragStartPositions=new Map;for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);u!=null&&u.displayObject&&this.multiDragStartPositions.set(p,new D.Point(u.displayObject.position.x,u.displayObject.position.y))}}for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);if(!(u!=null&&u.displayObject))continue;let g=this.multiDragStartPositions.get(p);if(g){let h=g.x+l,f=g.y+c;if(this.snapToGrid){let m=this.snapToGridPosition(h,f);h=m.x,f=m.y}u.displayObject.position.set(h,f),this.updateLiveConfigPositionForObject(p,h,f)}}}this.dragLastPointer=new D.Point(i.x,i.y),this.dragLogged||(this.dragLogged=!0,console.log("[SceneEditor][DragMove]",{objectId:this.selectedId,selectedCount:this.selectedIds.size,pointer:{x:i.x,y:i.y},nextPos:{x:s,y:o}}))}if(this.dragMode==="scale"&&this.dragAnchorLocal){let s=Math.max(1,this.distance(i,this.dragAnchorLocal))/Math.max(1,this.dragStartDistance),o=Math.max(.01,this.dragStartScale*s);(n=t.displayObject.scale)!=null&&n.set?t.displayObject.scale.set(o,o):t.displayObject.scale&&(t.displayObject.scale.x=o,t.displayObject.scale.y=o),this.updateLiveConfigScale(o)}if(this.dragMode==="rotate"&&this.dragAnchorLocal){let a=Math.atan2(i.y-this.dragAnchorLocal.y,i.x-this.dragAnchorLocal.x),s=this.dragStartRotation+(a-this.dragStartAngle);t.displayObject.rotation=s,this.updateLiveConfigRotation(s)}this.updateGizmos()}};this.onDragEnd=()=>{if(this.dragMode){if(this.alignmentGuideLayer&&this.alignmentGuideLayer.clear(),this.selectedIds.size>0){let e=Array.from(this.selectedIds);window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectIds:e}})),this.dragSyncHoldUntil=performance.now()+200}this.dragMode=null,this.dragStartPointer=null,this.dragStartPos=null,this.dragAnchorLocal=null,this.dragStartValue=null,this.dragContainer=null,this.dragLastPointer=null,this.dragPointerOffset=null,this.multiDragStartPositions=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)),a=new D.Point(this.app.renderer.width/2,this.app.renderer.height/2),s=this.camera.toLocal(a);this.cameraScale=n,this.camera.scale.set(n);let o=this.camera.toGlobal(s);this.camera.position.set(this.camera.position.x+(a.x-o.x),this.camera.position.y+(a.y-o.y)),this.hasUserCamera=!0,this.updateGizmos(),this.updateGrid()};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){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.updateGrid()}if(this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(!t)return;let i=new D.Point(t.x,t.y);this.drawSelectionBox(this.selectionBoxStart,i)}};this.onPanEnd=e=>{if(this.isPanning&&(this.isPanning=!1,this.panStart=null,this.panStartCamera=null),this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(t){let i=new D.Point(t.x,t.y);this.finalizeSelectionBox(this.selectionBoxStart,i)}this.isSelectionBoxActive=!1,this.selectionBoxStart=null,this.selectionBox&&this.selectionBox.clear()}this.multiDragStartPositions=null};this.root=e.root,this.getScreen=e.getScreen}async mount(){this.app||(this.app=new D.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.bgContainer.sortableChildren=!0,this.mainContainer.sortableChildren=!0,this.uiContainer.sortableChildren=!0,this.spawnPointLayer.sortableChildren=!0,this.gizmoLayer.sortableChildren=!0,this.app.stage.addChild(this.camera),this.camera.addChild(this.screenFrame),this.camera.addChild(this.bgContainer),this.camera.addChild(this.mainContainer),this.camera.addChild(this.gridLayer),this.camera.addChild(this.uiContainer),this.camera.addChild(this.spawnPointLayer),this.camera.addChild(this.gameFrame),this.camera.addChild(this.gizmoLayer),this.screenFrame.zIndex=-1,this.screenFrame.eventMode="none",this.bgContainer.zIndex=-5e3,this.bgContainer.eventMode="none",this.mainContainer.zIndex=0,this.gridLayer.zIndex=2e4,this.gridLayer.eventMode="none",this.gridLayer.visible=!0,this.uiContainer.zIndex=5e4,this.spawnPointLayer.zIndex=8e4,this.spawnPointLayer.eventMode="passive",this.gameFrame.zIndex=85e3,this.gameFrame.eventMode="none",this.gizmoLayer.zIndex=1e5,this.gizmoLayer.addChild(this.gizmoOutline),this.gizmoLayer.addChild(this.anchorVisualizationLayer),this.gizmoLayer.addChild(this.moveHandle),this.gizmoLayer.addChild(this.scaleHandle),this.gizmoLayer.addChild(this.rotateHandle),this.selectionBox=new D.Graphics,this.selectionBox.zIndex=99999,this.selectionBox.eventMode="none",this.gizmoLayer.addChild(this.selectionBox),this.dropZoneOverlay=new D.Graphics,this.dropZoneOverlay.zIndex=99998,this.dropZoneOverlay.eventMode="none",this.gizmoLayer.addChild(this.dropZoneOverlay),this.alignmentGuideLayer=new D.Graphics,this.alignmentGuideLayer.zIndex=99997,this.alignmentGuideLayer.eventMode="none",this.gizmoLayer.addChild(this.alignmentGuideLayer),this.gizmoOutline.eventMode="none",this.anchorVisualizationLayer.eventMode="none",this.setupInteractions(),this.setupObservers(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.restoreScenePreferences(),this.refresh(),this.applyPlayModeState(!0),!this.isVisible&&this.app.ticker&&this.app.ticker.stop())}destroy(){var e;this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.screenSyncRaf&&(cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=null),window.removeEventListener("handler-preview:screen",this.handleScreenChange),window.removeEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.removeEventListener("config:changed",this.handleConfigChanged),window.removeEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.removeEventListener("handler:layout-applied",this.handleLayoutApplied),window.removeEventListener("preview:select",this.handlePreviewSelect),window.removeEventListener("scene-editor:grid",this.handleGridSettings),window.removeEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.removeEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.removeEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.removeEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.removeEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd),this.app&&((e=this.app.ticker)==null||e.remove(this.syncFromGameObjects),this.app.stage.off("pointerdown",this.onStagePointerDown),this.app.destroy(!0),this.app=null)}setVisible(e){this.isVisible=e,!(!this.app||!this.app.ticker)&&(e?(this.app.ticker.start(),this.refresh(),this.updateGrid()):this.app.ticker.stop())}refresh(){this.syncFromConfig()}setupObservers(){window.addEventListener("handler-preview:screen",this.handleScreenChange),window.addEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.addEventListener("config:changed",this.handleConfigChanged),window.addEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.addEventListener("handler:layout-applied",this.handleLayoutApplied),window.addEventListener("preview:select",this.handlePreviewSelect),window.addEventListener("scene-editor:grid",this.handleGridSettings),window.addEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.addEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.addEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.addEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.addEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),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.app.stage.on("pointerdown",this.onStagePointerDown),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)),this.applyEditControls(),this.setupKeyboardShortcuts(),this.setupDragAndDrop()}setupKeyboardShortcuts(){window.addEventListener("keydown",e=>{if(!this.isVisible)return;let i=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey,n=e.target;n.tagName==="INPUT"||n.tagName==="TEXTAREA"||n.isContentEditable||(i&&e.key==="a"?(e.preventDefault(),this.selectAll()):i&&e.key==="d"?(e.preventDefault(),this.duplicateSelected()):i&&e.key==="c"?(e.preventDefault(),this.copySelected()):i&&e.key==="v"?(e.preventDefault(),this.pasteObjects()):e.key==="Escape"?(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos()):(e.key==="Delete"||e.key==="Backspace")&&this.selectedIds.size>0?(e.preventDefault(),this.deleteSelectedObjects()):e.key==="g"||e.key==="G"?(e.preventDefault(),this.toggleGrid()):e.shiftKey&&(e.key==="g"||e.key==="G")&&(e.preventDefault(),this.toggleSnapToGrid()))})}async duplicateSelected(){if(this.selectedIds.size===0)return;let e=window.__HANDLER_ACTIVE_SCREEN,t=e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay",i=Array.from(this.selectedIds),n=[];for(let a of i)try{let s=`${a}_copy_${Date.now()}`,o=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:a,newInstanceId:s,shareConfig:!1,screenId:t})}),l=await o.json();o.ok&&l.success&&n.push(l.newObjectId)}catch(s){console.error(`[SceneEditor] Failed to duplicate ${a}:`,s)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")))}copySelected(){if(this.selectedIds.size===0)return;let e=[];for(let t of this.selectedIds){let i=this.getEditableObjectConfig(t);i&&e.push({id:t,config:i})}window.__sceneEditorClipboard={configs:e,timestamp:Date.now()},this.showToast(`\u{1F4CB} Copied ${e.length} object${e.length>1?"s":""}`,1500)}async pasteObjects(){var a,s;let e=window.__sceneEditorClipboard;if(!e||!e.configs||e.configs.length===0)return;let t=window.__HANDLER_ACTIVE_SCREEN,i=t==="loading"||t==="start"||t==="gameplay"||t==="tutorial"||t==="endgame"?t:"gameplay",n=[];for(let{id:o,config:l}of e.configs)try{let c=`${o}_paste_${Date.now()}_${Math.random().toString(36).substr(2,5)}`,d=`json.${c}`,p=JSON.parse(JSON.stringify(l));if(p.identity.id=d,p.instance_id=c,p.object_config=d,(a=p.transform)!=null&&a.position){let h=p.transform.position,f=Array.isArray(h)?h[0]:h.x||0,m=Array.isArray(h)?h[1]:h.y||0;Array.isArray(h)?p.transform.position=[f+20,m+20]:p.transform.position={x:f+20,y:m+20}}let u=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:p,layer:((s=p.identity)==null?void 0:s.category)==="ui"?"ui":"world"})}),g=await u.json();u.ok&&g.success&&n.push(c)}catch(c){console.error(`[SceneEditor] Failed to paste ${o}:`,c)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),this.showToast(`\u{1F4CB} Pasted ${n.length} object${n.length>1?"s":""}`,1500))}toggleGrid(){this.gridEnabled=!this.gridEnabled,this.updateGrid();try{window.localStorage.setItem(this.getSceneStorageKey("grid_enabled"),String(this.gridEnabled))}catch{}this.showToast(this.gridEnabled?"\u{1F4D0} Grid enabled":"\u{1F4D0} Grid disabled",1e3)}toggleSnapToGrid(){this.snapToGrid=!this.snapToGrid;try{window.localStorage.setItem(this.getSceneStorageKey("snap_to_grid"),String(this.snapToGrid))}catch{}this.showToast(this.snapToGrid?"\u{1F532} Snap to grid enabled":"\u{1F532} Snap to grid disabled",1e3)}snapToGridPosition(e,t){if(!this.snapToGrid)return{x:e,y:t};let i=this.gridGap;return{x:Math.round(e/i)*i,y:Math.round(t/i)*i}}updateAlignmentGuides(e,t){var d,p,u,g;if(!this.alignmentGuidesEnabled||!e||!this.alignmentGuideLayer){this.alignmentGuideLayer&&this.alignmentGuideLayer.clear();return}let i=this.objectMap.get(e);if(!(i!=null&&i.displayObject)){this.alignmentGuideLayer.clear();return}let n=(p=(d=i.displayObject).getBounds)==null?void 0:p.call(d);if(!n){this.alignmentGuideLayer.clear();return}this.alignmentGuideLayer.clear();let a=this.camera.toLocal(new D.Point(n.x,n.y)),s=this.camera.toLocal(new D.Point(n.x+n.width,n.y+n.height)),o=(a.x+s.x)/2,l=(a.y+s.y)/2,c=5;for(let[h,f]of this.objectMap.entries()){if(h===e||!(f!=null&&f.displayObject)||f.displayObject.visible===!1)continue;let m=(g=(u=f.displayObject).getBounds)==null?void 0:g.call(u);if(!m)continue;let b=this.camera.toLocal(new D.Point(m.x,m.y)),y=this.camera.toLocal(new D.Point(m.x+m.width,m.y+m.height)),w=(b.x+y.x)/2,v=(b.y+y.y)/2;if(Math.abs(o-w)<c){let E=Math.min(a.y,b.y),C=Math.max(s.y,y.y);this.alignmentGuideLayer.moveTo(w,E),this.alignmentGuideLayer.lineTo(w,C),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}if(Math.abs(l-v)<c){let E=Math.min(a.x,b.x),C=Math.max(s.x,y.x);this.alignmentGuideLayer.moveTo(E,v),this.alignmentGuideLayer.lineTo(C,v),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}let P=a.x,I=s.x,_=a.y,k=s.y,j=b.x,L=y.x,x=b.y,S=y.y;if(Math.abs(P-j)<c||Math.abs(P-L)<c||Math.abs(I-j)<c||Math.abs(I-L)<c){let E=Math.abs(P-j)<c?j:Math.abs(P-L)<c?L:Math.abs(I-j)<c?j:L,C=Math.min(_,x),A=Math.max(k,S);this.alignmentGuideLayer.moveTo(E,C),this.alignmentGuideLayer.lineTo(E,A),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}if(Math.abs(_-x)<c||Math.abs(_-S)<c||Math.abs(k-x)<c||Math.abs(k-S)<c){let E=Math.abs(_-x)<c?x:Math.abs(_-S)<c?S:Math.abs(k-x)<c?x:S,C=Math.min(P,j),A=Math.max(I,L);this.alignmentGuideLayer.moveTo(C,E),this.alignmentGuideLayer.lineTo(A,E),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}}}selectAll(){let e=Array.from(this.objectMap.keys()).filter(t=>{let i=this.getEditableObjectConfig(t),n=this.objectMap.get(t);return!(!(n!=null&&n.displayObject)||n.displayObject.visible===!1||this.backgroundLocked&&this.isBackgroundObject(t,i,n.displayObject))});this.selectedIds=new Set(e),e.length>0&&(this.selectedId=e[0],this.updateGizmos())}deleteSelectedObjects(){let e=Array.from(this.selectedIds);for(let t of e){let i=window.__deleteObjectRequest;typeof i=="function"&&i(t)}this.selectedIds.clear(),this.selectedId=null,this.updateGizmos()}handleResize(){this.app&&(this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid())}adjustPositionForAnchorChange(e,t,i){var L,x,S,E,C,A;if(t==null||i==null||t===i)return;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(L=n.transform)!=null?L:{};if(a.position_ratio!=null)return;let s=(x=this.getRuntimeScreenSize())!=null?x:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let o=this.objectMap.get(e);if(!(o!=null&&o.displayObject))return;let l=this.isBackgroundObject(e,n,o.displayObject),c=this.getRuntimeScale(),d=o.displayObject.position.x,p=o.displayObject.position.y,u=Ne(s.width,s.height,t),g=Ne(s.width,s.height,i),h=u.x,f=u.y,m=g.x,b=g.y;l||(h=(u.x-s.width/2)/c,f=(u.y-s.height/2)/c,m=(g.x-s.width/2)/c,b=(g.y-s.height/2)/c);let y={x:d-h,y:p-f},w={x:d-m,y:p-b},v=a.offset,P=Array.isArray(v)?Number((S=v[0])!=null?S:0):Number((E=v==null?void 0:v.x)!=null?E:0),I=Array.isArray(v)?Number((C=v[1])!=null?C:0):Number((A=v==null?void 0:v.y)!=null?A:0),_=w.x-P,k=w.y-I,j=this.buildPositionValue(a,{x:_,y:k});this.updateManager.updateProperty(e,"transform.position",j,{refreshInspector:!0})}getPickCandidates(e){var i;let t=[];for(let[n,a]of this.objectMap.entries()){let s=a.displayObject;if(!s||s.visible===!1||this.backgroundLocked&&this.isBackgroundObject(n,this.getEditableObjectConfig(n),s))continue;let o=(i=s.getBounds)==null?void 0:i.call(s);if(!o||o.width<=0||o.height<=0||e.x<o.x||e.x>o.x+o.width||e.y<o.y||e.y>o.y+o.height)continue;let l=s.parent,c=typeof(l==null?void 0:l.zIndex)=="number"?l.zIndex:0,d=typeof s.zIndex=="number"?s.zIndex:0,p=typeof(l==null?void 0:l.getChildIndex)=="function"?l.getChildIndex(s):0,u=c*1e6+d*1e3+p;t.push({id:n,order:u})}return t.sort((n,a)=>a.order-n.order),t.map(n=>n.id)}areSameIds(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i+=1)if(e[i]!==t[i])return!1;return!0}isGizmoTarget(e){return e&&this.spawnPointLayer.children.indexOf(e)!==-1?!0:e===this.moveHandle||e===this.scaleHandle||e===this.rotateHandle||e===this.gizmoOutline}restoreScenePreferences(){if(typeof window!="undefined"){try{let e=window.localStorage.getItem(this.getSceneStorageKey("grid_enabled")),t=window.localStorage.getItem(this.getSceneStorageKey("grid_gap")),i=window.localStorage.getItem(this.getSceneStorageKey("grid_alpha")),n=window.localStorage.getItem(this.getSceneStorageKey("snap_to_grid")),a=window.localStorage.getItem(this.getSceneStorageKey("background_cover")),s=window.localStorage.getItem(this.getSceneStorageKey("background_lock"));if(e!==null&&(this.gridEnabled=e==="true"),t!==null){let o=Number(t);Number.isFinite(o)&&o>2&&(this.gridGap=o)}if(i!==null){let o=Number(i);Number.isFinite(o)&&o>=0&&o<=1&&(this.gridAlpha=o)}n!==null&&(this.snapToGrid=n==="true"),a!==null&&(this.backgroundCoverEnabled=a==="true"),s!==null&&(this.backgroundLocked=s==="true")}catch{}this.updateGrid()}}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}applyPlayModeState(e){var t;this.playModeEnabled=e,(t=this.app)!=null&&t.ticker&&(this.app.ticker.remove(this.syncFromGameObjects),e&&this.app.ticker.add(this.syncFromGameObjects)),this.applyEditControls(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})}applyEditControls(){this.moveHandle.eventMode="static",this.scaleHandle.eventMode="static",this.rotateHandle.eventMode="static"}schedulePostScreenSync(e){this.screenSyncRaf&&cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=requestAnimationFrame(()=>{this.runPostScreenSync(e)})}async runPostScreenSync(e){this.screenSyncRaf=null,this.isVisible&&this.playModeEnabled&&(this.updateLayout(e),this.hasUserCamera||this.centerCamera(),await this.syncFromConfig(),this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid())}getRuntimeScreenSize(){var a,s,o,l,c,d,p;let e=window.gameApp;if(e!=null&&e.renderer){let u=e.renderer.screen,g=Number((a=u==null?void 0:u.width)!=null?a:0),h=Number((s=u==null?void 0:u.height)!=null?s:0);if(Number.isFinite(g)&&g>0&&Number.isFinite(h)&&h>0)return{width:g,height:h};let f=Number((o=e.renderer.resolution)!=null?o:1)||1,m=Number((l=e.renderer.width)!=null?l:0)/f,b=Number((c=e.renderer.height)!=null?c:0)/f;if(Number.isFinite(m)&&m>0&&Number.isFinite(b)&&b>0)return{width:m,height:b}}let t=document.querySelector(".game-container"),i=Number((d=t==null?void 0:t.dataset)==null?void 0:d.screenWidth),n=Number((p=t==null?void 0:t.dataset)==null?void 0:p.screenHeight);return Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:null}getRuntimeLayoutReference(){var a,s,o,l,c,d,p,u,g,h,f,m,b,y,w,v,P,I,_,k,j,L,x,S,E,C,A,T,O,M,R,z,F,q;let e=window.__screenManager;if(e){let N=["gameplay","start","tutorial","endgame","loading"];for(let H of N){let $=(a=e.get)==null?void 0:a.call(e,H);if($!=null&&$.visible){let U=(s=$.getContentLayer)==null?void 0:s.call($);if(U){let Y=(o=$.x)!=null?o:0,V=(l=$.y)!=null?l:0,G=(c=U.x)!=null?c:0,W=(d=U.y)!=null?d:0,Z=(u=(p=U.scale)==null?void 0:p.x)!=null?u:1,ae=(h=(g=U.scale)==null?void 0:g.y)!=null?h:Z;return console.log("[SceneEditor] getRuntimeLayoutReference: using visible screen contentLayer",{screenId:H,contentLayerScale:{x:Z,y:ae},position:{x:Y+G,y:V+W}}),{scale:{x:Z,y:ae},position:{x:Y+G,y:V+W},pivot:U.pivot?{x:U.pivot.x,y:U.pivot.y}:void 0}}}}for(let H of N){let $=(f=e.get)==null?void 0:f.call(e,H);if($){if(!$.visible&&typeof $.updateLayout=="function"){let Y=window.gameApp;if((m=Y==null?void 0:Y.renderer)!=null&&m.screen){let V=Y.renderer.screen.width,G=Y.renderer.screen.height;V>0&&G>0&&$.updateLayout(V,G)}}let U=(b=$.getContentLayer)==null?void 0:b.call($);if(U){let Y=(y=$.x)!=null?y:0,V=(w=$.y)!=null?w:0,G=(v=U.x)!=null?v:0,W=(P=U.y)!=null?P:0,Z=(_=(I=U.scale)==null?void 0:I.x)!=null?_:1,ae=(j=(k=U.scale)==null?void 0:k.y)!=null?j:Z;return console.log("[SceneEditor] getRuntimeLayoutReference: using any screen contentLayer",{screenId:H,visible:$.visible,contentLayerScale:{x:Z,y:ae},position:{x:Y+G,y:V+W}}),{scale:{x:Z,y:ae},position:{x:Y+G,y:V+W},pivot:U.pivot?{x:U.pivot.x,y:U.pivot.y}:void 0}}}}}let t=window.__mainContainer;if(t){let N=(x=(L=t.scale)==null?void 0:L.x)!=null?x:1,H=(E=(S=t.scale)==null?void 0:S.y)!=null?E:N;return console.log("[SceneEditor] getRuntimeLayoutReference: using __mainContainer",{scale:{x:N,y:H},position:{x:(C=t.position)==null?void 0:C.x,y:(A=t.position)==null?void 0:A.y}}),t}let i=window.gameApp,n=(T=i==null?void 0:i.stage)!=null?T:null;if(n){let N=(M=(O=n.scale)==null?void 0:O.x)!=null?M:1,H=(z=(R=n.scale)==null?void 0:R.y)!=null?z:N;console.log("[SceneEditor] getRuntimeLayoutReference: using gameApp.stage (fallback)",{scale:{x:N,y:H},position:{x:(F=n.position)==null?void 0:F.x,y:(q=n.position)==null?void 0:q.y}})}else console.log("[SceneEditor] getRuntimeLayoutReference: no reference found");return n}getRuntimeScale(){var i,n;let e=this.getRuntimeLayoutReference(),t=Number((n=(i=e==null?void 0:e.scale)==null?void 0:i.x)!=null?n:1);return Number.isFinite(t)&&t>0?t:Number.isFinite(this.layoutScale)&&this.layoutScale>0?this.layoutScale:1}getRuntimeParentContainer(e){var c,d,p,u,g;let t=window.gameObjectManager;if(!(t!=null&&t.get))return null;let i=t.get(e),n=((c=i==null?void 0:i.getDisplayObject)==null?void 0:c.call(i))||(i==null?void 0:i.pixiObject)||i,a=n==null?void 0:n.parent;if(!a)return null;let s=window.__screenManager;if(s){let h=["gameplay","start","tutorial","endgame","loading"];for(let f of h){let m=(d=s.get)==null?void 0:d.call(s,f);if(!m)continue;let b=(u=(p=m.getBgLayer)==null?void 0:p.call(m))!=null?u:m.bgLayer;if(b&&(a===b||typeof b.contains=="function"&&b.contains(a)))return this.bgContainer}}let o=this.getRuntimeLayoutReference(),l=(g=window.gameApp)==null?void 0:g.stage;return o&&l&&o===l?this.mainContainer:o&&typeof o.contains=="function"&&o.contains(a)?this.mainContainer:a===o||a===l?this.mainContainer:this.uiContainer}applyRuntimeTransform(e){var s,o,l,c,d,p,u,g,h,f;if(!e)return console.log("[SceneEditor] applyRuntimeTransform: no reference"),!1;let t=1,i=1,n=Number((o=(s=e.position)==null?void 0:s.x)!=null?o:0),a=Number((c=(l=e.position)==null?void 0:l.y)!=null?c:0);if(!Number.isFinite(n)||!Number.isFinite(a))return console.log("[SceneEditor] applyRuntimeTransform: invalid position",{posX:n,posY:a}),!1;if(console.log("[SceneEditor] applyRuntimeTransform: applying (scale always 1)",{scale:{x:t,y:i},position:{x:n,y:a}}),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.position.set(n,a),this.uiContainer.position.set(n,a),e.pivot&&((d=this.mainContainer.pivot)!=null&&d.set)&&((p=this.uiContainer.pivot)!=null&&p.set)){let m=Number((g=(u=e.pivot)==null?void 0:u.x)!=null?g:0),b=Number((f=(h=e.pivot)==null?void 0:h.y)!=null?f:0);Number.isFinite(m)&&Number.isFinite(b)&&(this.mainContainer.pivot.set(m,b),this.uiContainer.pivot.set(m,b))}return typeof e.rotation=="number"&&(this.mainContainer.rotation=e.rotation,this.uiContainer.rotation=e.rotation),!0}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 s=this.getEditableObjectConfig(a);if(!s){this.removeObject(a);continue}await this.upsertObject(a,s)}this.updateGizmos(),this.updateSpawnPointHandles(),this.updateGameFrame(this.getScreen())}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),a=this.isUiConfig(e,t),s=this.playModeEnabled?this.getRuntimeParentContainer(e):null,l=this.isBackgroundObject(e,t)?this.bgContainer:a?this.uiContainer:this.mainContainer,c=s!=null?s:l;if(!n||n.assetKey!==i||n.isUi!==a){n&&this.removeObject(e);let p=await this.createDisplayObject(e,t);if(!p)return;c.addChild(p),this.objectMap.set(e,{id:e,displayObject:p,assetKey:i,isUi:a}),this.attachObjectInteraction(p,e)}let d=this.objectMap.get(e);d&&(d.displayObject.parent!==c&&c.addChild(d.displayObject),this.applyVisualConfig(d.displayObject,t),(!this.playModeEnabled||!s)&&this.applyTransformFromConfig(e,d.displayObject,t))}async createDisplayObject(e,t){var o,l,c,d,p,u,g,h,f,m,b,y,w,v,P;if((o=t==null?void 0:t.render)!=null&&o.asset)try{if(((c=(l=t==null?void 0:t.render)==null?void 0:l.asset)==null?void 0:c.type)!=="json"){let _=await we.create(e,t,this.app);if(_ instanceof D.Container)return _}}catch(I){console.warn("[SceneEditor] ObjectFactory failed for",e,I)}let i=t==null?void 0:t.ui,n=(d=t==null?void 0:t.render)!=null?d:{},a=(i==null?void 0:i.text)||(i==null?void 0:i.kind)==="text";if(!!n.background_color){let I=this.getScreen(),_=(p=I==null?void 0:I.width)!=null?p:0,k=(u=I==null?void 0:I.height)!=null?u:0,j=new D.Graphics,L=this.parseColor(n.background_color,0),x=typeof n.background_alpha=="number"?n.background_alpha:1;_>0&&k>0&&j.rect(0,0,_,k).fill({color:L,alpha:x});let S=new D.Container;return S.addChild(j),S}if(a){let I=(h=(g=i==null?void 0:i.color)!=null?g:n==null?void 0:n.tint)!=null?h:"#ffffff",_=new D.TextStyle({fontFamily:"Arial, sans-serif",fontSize:(f=i==null?void 0:i.fontSize)!=null?f:16,fill:I,align:(m=i==null?void 0:i.align)!=null?m:"center",letterSpacing:(b=i==null?void 0:i.letterSpacing)!=null?b:0});return new D.Text({text:(y=i==null?void 0:i.text)!=null?y:"",style:_})}if((w=t==null?void 0:t.effects)!=null&&w.width||(v=t==null?void 0:t.effects)!=null&&v.height){let I=new D.Graphics,_=typeof t.effects.width=="number"?t.effects.width:100,k=typeof t.effects.height=="number"?t.effects.height:100,j=(P=t.effects.fill_color)!=null?P:"#ffffff",L=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,x=Number.parseInt(String(j).replace("#",""),16);return I.rect(0,0,_,k).fill({color:Number.isFinite(x)?x:16777215,alpha:L}),I}return new D.Container}attachObjectInteraction(e,t){if(e&&(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=new D.Rectangle(i.x,i.y,i.width,i.height))}}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}isUiConfig(e,t){var a,s;let i=(((a=t==null?void 0:t.identity)==null?void 0:a.category)||"").toString().toLowerCase(),n=(((s=t==null?void 0:t.identity)==null?void 0:s.id)||e||"").toString().toLowerCase();return i.includes("ui")||n.startsWith("ui")||n.includes("label")}isBackgroundObject(e,t,i){var s,o;if((i==null?void 0:i.parent)===this.bgContainer)return!0;let n=(((s=t==null?void 0:t.identity)==null?void 0:s.category)||"").toString().toLowerCase(),a=(((o=t==null?void 0:t.identity)==null?void 0:o.id)||e||"").toString().toLowerCase();return!!(n.includes("bg")||n.includes("background")||a.startsWith("background_")||a.includes("background"))}queueBackgroundCoverRetry(e){var i;let t=(i=this.backgroundCoverRetries.get(e))!=null?i:0;t>=10||(this.backgroundCoverRetries.set(e,t+1),this.backgroundCoverRaf==null&&(this.backgroundCoverRaf=requestAnimationFrame(()=>{this.backgroundCoverRaf=null;let n=this.objectMap.get(e),a=this.getEditableObjectConfig(e);!(n!=null&&n.displayObject)||!a||this.applyTransformFromConfig(e,n.displayObject,a)})))}applyVisualConfig(e,t){var a,s,o;if(!e)return;let i=(a=t==null?void 0:t.render)!=null?a:{};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={x:.5,y:.5};if((s=e.anchor)!=null&&s.set)e.anchor.set(n.x,n.y);else if(e.pivot){let l=(o=e.getLocalBounds)==null?void 0:o.call(e);l&&e.pivot.set(l.width*n.x,l.height*n.y)}}applyTransformFromConfig(e,t,i){var _,k,j,L,x,S,E,C,A,T,O,M,R,z,F,q,N,H,$,U,Y,V;if(!t)return;let n=this.getScreen();if(!(n!=null&&n.width)||!(n!=null&&n.height))return;let a=(_=i==null?void 0:i.transform)!=null?_:{},s=this.getPositioningAnchor(e,a),o=a==null?void 0:a.position_ratio,l=a==null?void 0:a.position,c=a==null?void 0:a.offset,d=Array.isArray(l)?Number((k=l[0])!=null?k:0):Number((j=l==null?void 0:l.x)!=null?j:0),p=Array.isArray(l)?Number((L=l[1])!=null?L:0):Number((x=l==null?void 0:l.y)!=null?x:0),u=Array.isArray(c)?Number((S=c[0])!=null?S:0):Number((E=c==null?void 0:c.x)!=null?E:0),g=Array.isArray(c)?Number((C=c[1])!=null?C:0):Number((A=c==null?void 0:c.y)!=null?A:0),h=(Number.isFinite(d)?d:0)+(Number.isFinite(u)?u:0),f=(Number.isFinite(p)?p:0)+(Number.isFinite(g)?g:0);if(this.backgroundCoverEnabled&&this.isBackgroundObject(e,i,t)){let G=Number((O=(T=t==null?void 0:t.texture)==null?void 0:T.width)!=null?O:0),W=Number((R=(M=t==null?void 0:t.texture)==null?void 0:M.height)!=null?R:0);if(!Number.isFinite(G)||G<=0||!Number.isFinite(W)||W<=0){let Q=(z=t==null?void 0:t.getLocalBounds)==null?void 0:z.call(t);G=Number((F=Q==null?void 0:Q.width)!=null?F:0),W=Number((q=Q==null?void 0:Q.height)!=null?q:0)}if(!Number.isFinite(G)||G<=0||!Number.isFinite(W)||W<=0){this.queueBackgroundCoverRetry(e);return}(N=t.anchor)!=null&&N.set?t.anchor.set(.5,.5):(H=t.pivot)!=null&&H.set&&t.pivot.set(G*.5,W*.5),($=t.position)!=null&&$.set?t.position.set(n.width/2,n.height/2):t.position&&(t.position.x=n.width/2,t.position.y=n.height/2);let Z=n.width/G,ae=n.height/W,oe=Math.max(Z,ae);(U=t.scale)!=null&&U.set?t.scale.set(oe,oe):t.scale&&(t.scale.x=oe,t.scale.y=oe);let Re=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(Re);return}let m=o!=null?pt(n.width,n.height,o):Ne(n.width,n.height,s),b=this.getRuntimeScale(),y=(m.x-n.width/2)/b+h,w=(m.y-n.height/2)/b+f;(Y=t.position)!=null&&Y.set?t.position.set(y,w):t.position&&(t.position.x=y,t.position.y=w);let P=(typeof(a==null?void 0:a.scale)=="number"?a.scale:1)*this.getRuntimeScale();(V=t.scale)!=null&&V.set?t.scale.set(P,P):t.scale&&(t.scale.x=P,t.scale.y=P);let I=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(I)}getAnchorLocalPoint(e,t=this.mainContainer){var d;let i=(d=this.getRuntimeScreenSize())!=null?d:this.getScreen();if(!(i!=null&&i.width)||!(i!=null&&i.height))return null;let n="top-right",a=this.getPositioningAnchor(this.selectedId,e!=null?e:{}),s=(e==null?void 0:e.position_ratio)!=null?pt(i.width,i.height,e.position_ratio):Ne(i.width,i.height,a!=null?a:n);if(t===this.bgContainer)return new D.Point(s.x,s.y);let o=this.getRuntimeScale(),l=(s.x-i.width/2)/o,c=(s.y-i.height/2)/o;return new D.Point(l,c)}getPositioningAnchor(e,t){var i,n,a,s,o,l,c,d,p,u;if((t==null?void 0:t.anchor)!=null&&t.anchor!=="")return t.anchor;if(typeof window!="undefined"&&e){let g=window,h=g.__editableConfig,f=(n=(i=h==null?void 0:h.objects)==null?void 0:i.get)==null?void 0:n.call(i,e),m=(o=(a=f==null?void 0:f.transform)==null?void 0:a.anchor)!=null?o:(s=f==null?void 0:f.render)==null?void 0:s.anchor;if(m!=null&&m!=="")return m;let b=g.__editableConfigBaseline,y=(c=(l=b==null?void 0:b.objects)==null?void 0:l.get)==null?void 0:c.call(l,e),w=(u=(d=y==null?void 0:y.transform)==null?void 0:d.anchor)!=null?u:(p=y==null?void 0:y.render)==null?void 0:p.anchor;if(w!=null&&w!=="")return w}return"top-left"}getActiveScreenSize(e){var t,i;return this.playModeEnabled?(i=(t=this.getRuntimeScreenSize())!=null?t:e)!=null?i:this.getScreen():e!=null?e:this.getScreen()}updateLayout(e){var i,n,a,s,o,l,c,d,p;let t=this.getActiveScreenSize(e);if(!(!(t!=null&&t.width)||!(t!=null&&t.height))){if(console.log("[SceneEditor] updateLayout: called",{screen:{width:t.width,height:t.height},currentScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y}}),this.playModeEnabled){let u=this.getRuntimeLayoutReference();if(u){let g=Number((n=(i=u.position)==null?void 0:i.x)!=null?n:t.width/2),h=Number((s=(a=u.position)==null?void 0:a.y)!=null?s:t.height/2);this.mainContainer.position.set(g,h),this.uiContainer.position.set(g,h);let f=Number((l=(o=u.scale)==null?void 0:o.x)!=null?l:1);Number.isFinite(f)&&f>0&&(this.layoutScale=f)}this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1)}else this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.position.set(t.width/2,t.height/2),this.uiContainer.position.set(t.width/2,t.height/2),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.rotation=0,this.uiContainer.rotation=0,(c=this.mainContainer.pivot)!=null&&c.set&&this.mainContainer.pivot.set(0,0),(d=this.uiContainer.pivot)!=null&&d.set&&this.uiContainer.pivot.set(0,0);console.log("[SceneEditor] updateLayout: result",{finalScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y},position:{x:this.mainContainer.position.x,y:this.mainContainer.position.y}}),this.screenFrame.clear(),this.screenFrame.rect(0,0,t.width,t.height),this.screenFrame.stroke({width:2,color:2894892,alpha:.5}),this.updateGameFrame(t),(p=this.app)!=null&&p.stage&&(this.app.stage.hitArea=new D.Rectangle(0,0,this.app.renderer.width,this.app.renderer.height)),this.updateSpawnPointHandles()}}updateGrid(){if(!this.app)return;if(!this.gridEnabled){this.gridLayer.clear(),this.gridLayer.visible=!0;return}let e=Math.max(4,this.gridGap),t=this.app.renderer,i=this.camera.toLocal(new D.Point(0,0)),n=this.camera.toLocal(new D.Point(t.width,t.height)),a=Math.min(i.x,n.x),s=Math.max(i.x,n.x),o=Math.min(i.y,n.y),l=Math.max(i.y,n.y),c=400,d=Math.ceil((s-a)/e),p=Math.ceil((l-o)/e),u=e*Math.max(1,Math.ceil(d/c)),g=e*Math.max(1,Math.ceil(p/c)),h=Math.floor(a/u)*u,f=Math.floor(o/g)*g;this.gridLayer.clear(),this.gridLayer.visible=!0;for(let m=h;m<=s;m+=u)this.gridLayer.moveTo(m,o),this.gridLayer.lineTo(m,l);for(let m=f;m<=l;m+=g)this.gridLayer.moveTo(a,m),this.gridLayer.lineTo(s,m);this.gridLayer.stroke({width:1,color:16777215,alpha:this.gridAlpha})}updateGameFrame(e){let t=this.getActiveScreenSize(e);if(!(t!=null&&t.width)||!(t!=null&&t.height))return;let i=t.width,n=t.height,a=0,s=0;this.lastGameFrameSize&&this.lastGameFrameSize.width===t.width&&this.lastGameFrameSize.height===t.height||(this.lastGameFrameSize={width:t.width,height:t.height},this.gameFrame.clear(),this.gameFrame.rect(a,s,i,n),this.gameFrame.stroke({width:2,color:6333946,alpha:.35}))}syncFromGameObjectsInternal(){var i,n,a,s,o,l,c,d,p;if(!this.app||!this.isVisible)return;let e=window.gameObjectManager;if(!(e!=null&&e.get))return;let t=this.dragMode||this.selectedId&&performance.now()<this.dragSyncHoldUntil?this.selectedId:null;for(let[u,g]of this.objectMap.entries()){if(t&&u===t)continue;let h=e.get(u),f=((i=h==null?void 0:h.getDisplayObject)==null?void 0:i.call(h))||(h==null?void 0:h.pixiObject)||h;if(!f)continue;let m=(a=(n=g.displayObject)==null?void 0:n.parent)!=null?a:this.mainContainer,b=new D.Point;if(typeof f.getGlobalPosition=="function"){f.getGlobalPosition(b);let I=m.toLocal(b,this.camera);g.displayObject.position.set(I.x,I.y)}else if(f.worldTransform){b.set(f.worldTransform.tx,f.worldTransform.ty);let I=m.toLocal(b,this.camera);g.displayObject.position.set(I.x,I.y)}let y=this.getWorldScale(f);if(y){let I=Number((o=(s=m.scale)==null?void 0:s.x)!=null?o:1)||1,_=Number((c=(l=m.scale)==null?void 0:l.y)!=null?c:1)||1,k=y.x/I,j=y.y/_;(d=g.displayObject.scale)!=null&&d.set?g.displayObject.scale.set(k,j):g.displayObject.scale&&(g.displayObject.scale.x=k,g.displayObject.scale.y=j)}let w=this.getWorldRotation(f);if(typeof w=="number"){let I=m?m.rotation:0,_=w-I;g.displayObject.rotation=_;let k=this.getEditableObjectConfig(u);if(k){let j=(p=k.transform)!=null?p:{};k.transform||(k.transform=j);let L=this.toDegrees(_),x=typeof j.rotation=="number"?j.rotation:0;if(Math.abs(L-x)>.01){let S=Math.round(L*100)/100;j.rotation=S}}}let v=f.parent,P=typeof(v==null?void 0:v.getChildIndex)=="function"?v.getChildIndex(f):0;typeof f.zIndex=="number"?g.displayObject.zIndex=f.zIndex:Number.isFinite(P)&&(g.displayObject.zIndex=P)}this.updateGizmos()}getWorldScale(e){var a,s;let t=(s=e==null?void 0:e.worldTransform)!=null?s:(a=e==null?void 0:e.transform)==null?void 0:a.worldTransform;if(!t)return null;let i=Math.sqrt(t.a*t.a+t.b*t.b),n=Math.sqrt(t.c*t.c+t.d*t.d);return!Number.isFinite(i)||!Number.isFinite(n)?null:{x:i,y:n}}getWorldRotation(e){var i,n;let t=(n=e==null?void 0:e.worldTransform)!=null?n:(i=e==null?void 0:e.transform)==null?void 0:i.worldTransform;if(t){let a=Math.atan2(t.b,t.a);return Number.isFinite(a)?a:null}return typeof(e==null?void 0:e.rotation)=="number"?e.rotation:null}centerCamera(){if(!this.app)return;let e=this.getActiveScreenSize();if(!(e!=null&&e.width)||!(e!=null&&e.height))return;let t=this.app.renderer.width,i=this.app.renderer.height,n=Math.max(.01,Math.min(t/e.width,i/e.height));this.cameraScale=n,this.camera.scale.set(n),this.camera.position.set((t-e.width*n)/2,(i-e.height*n)/2)}updateGizmos(){var f,m,b,y,w,v;if(!this.selectedId&&this.selectedIds.size===0||!this.isVisible){this.clearGizmos();return}if(this.selectedIds.size>1){let P=1/0,I=1/0,_=-1/0,k=-1/0,j=!1;for(let L of this.selectedIds){let x=this.objectMap.get(L);if(!(x!=null&&x.displayObject))continue;let S=(m=(f=x.displayObject).getBounds)==null?void 0:m.call(f);if(!S||S.width<=0||S.height<=0)continue;let E=this.camera.toLocal(new D.Point(S.x,S.y)),C=this.camera.toLocal(new D.Point(S.x+S.width,S.y+S.height));P=Math.min(P,E.x,C.x),I=Math.min(I,E.y,C.y),_=Math.max(_,E.x,C.x),k=Math.max(k,E.y,C.y),j=!0}if(j){let L=_-P,x=k-I,S=P+L/2,E=I+x/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(P,I,L,x),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});for(let T of this.selectedIds){let O=this.objectMap.get(T);if(!(O!=null&&O.displayObject))continue;let M=(y=(b=O.displayObject).getBounds)==null?void 0:y.call(b);if(!M||M.width<=0||M.height<=0)continue;let R=this.camera.toLocal(new D.Point(M.x,M.y)),z=this.camera.toLocal(new D.Point(M.x+M.width,M.y+M.height)),F=z.x-R.x,q=z.y-R.y;this.gizmoOutline.rect(R.x,R.y,F,q),this.gizmoOutline.stroke({width:1,color:16752394,alpha:.5})}let C=7,A={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(S,E,C).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(A),this.moveHandle.cursor="move",this.scaleHandle.clear(),this.rotateHandle.clear()}else this.clearGizmos();return}if(!this.selectedId){this.clearGizmos();return}let e=this.objectMap.get(this.selectedId);if(!(e!=null&&e.displayObject)){this.clearGizmos();return}let t=(v=(w=e.displayObject).getBounds)==null?void 0:v.call(w);if(!t||t.width<=0||t.height<=0){this.clearGizmos();return}let i=this.camera.toLocal(new D.Point(t.x,t.y)),n=this.camera.toLocal(new D.Point(t.x+t.width,t.y+t.height)),a=n.x-i.x,s=n.y-i.y,o=i.x+a/2,l=i.y+s/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(i.x,i.y,a,s),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});let c=7,d={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(o,l,c).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(d),this.moveHandle.cursor="move";let p=i.x+a,u=i.y+s;this.scaleHandle.clear(),this.scaleHandle.rect(p-c,u-c,c*2,c*2).fill({color:3718648,alpha:.95}),this.scaleHandle.stroke(d),this.scaleHandle.cursor="nwse-resize";let g=o,h=i.y-c*2;this.rotateHandle.clear(),this.rotateHandle.circle(g,h,c).fill({color:16347926,alpha:.95}),this.rotateHandle.stroke(d),this.rotateHandle.cursor="crosshair"}clearGizmos(){this.gizmoOutline.clear(),this.moveHandle.clear(),this.scaleHandle.clear(),this.rotateHandle.clear()}updateSpawnPointHandles(){if(this.clearSpawnPointHandles(),!this.selectedId)return;let e=this.getEditableObjectConfig(this.selectedId);if(!e||!this.isSpawnerConfig(e))return;let t=this.getSpawnPoints(e);!t||t.length===0||t.forEach((i,n)=>{let a=new D.Graphics;a.circle(0,0,5).fill({color:16096779,alpha:.9}),a.circle(0,0,9).stroke({width:1,color:16096779,alpha:.45});let s=this.toCameraFromMain(i);a.position.set(s.x,s.y),a.cursor="move",a.eventMode="static",a.on("pointerdown",o=>this.startSpawnPointDrag(n,o)),this.spawnPointLayer.addChild(a)})}clearSpawnPointHandles(){this.spawnPointLayer.removeChildren().forEach(t=>{var i;(i=t.destroy)==null||i.call(t)})}isSpawnerConfig(e){var i,n;return((i=e==null?void 0:e.logic)==null?void 0:i.id)==="Spawner"?!0:String(((n=e==null?void 0:e.identity)==null?void 0:n.system_role)||"").toLowerCase().includes("spawner")}getSpawnPoints(e){var i,n;let t=(n=(i=e==null?void 0:e.logic)==null?void 0:i.props)==null?void 0:n.spawnPoints;return Array.isArray(t)?t.map(a=>{var s,o;return{x:Number((s=a==null?void 0:a.x)!=null?s:0),y:Number((o=a==null?void 0:a.y)!=null?o:0)}}):null}toCameraFromMain(e){let t=this.mainContainer.toGlobal(new D.Point(e.x,e.y)),i=new D.Point;return this.camera.toLocal(t,void 0,i),i}startSpawnPointDrag(e,t){var o,l;if(!this.selectedId)return;let i=this.getEditableObjectConfig(this.selectedId);if(!i)return;let n=this.getSpawnPoints(i);if(!n||!n[e])return;(o=t==null?void 0:t.stopPropagation)==null||o.call(t),(l=t==null?void 0:t.stopImmediatePropagation)==null||l.call(t);let a=this.getEventLocalPoint(t,this.mainContainer);if(!a)return;let s=n[e];this.spawnPointDrag={objectId:this.selectedId,index:e,offset:new D.Point(s.x-a.x,s.y-a.y),startPoints:n.map(c=>({x:c.x,y:c.y}))},window.addEventListener("pointermove",this.onSpawnPointDragMove),window.addEventListener("pointerup",this.onSpawnPointDragEnd)}updateLiveSpawnPoint(e,t,i,n){let a=this.getEditableObjectConfig(e);if(!a)return;let s=this.getSpawnPoints(a);if(!s||!s[t])return;let o=s.map((l,c)=>c===t?{x:i,y:n}:{x:l.x,y:l.y});this.setNestedValue(a,"logic.props.spawnPoints",o),this.queueLiveApply(e),this.updateSpawnPointHandles()}setSelected(e,t={}){if(!(this.selectedId===e&&this.selectedIds.size===1&&this.selectedIds.has(e||""))&&(this.selectedId=e,e?(this.selectedIds.clear(),this.selectedIds.add(e)):this.selectedIds.clear(),this.updateGizmos(),this.updateSpawnPointHandles(),!t.silent&&e)){let i=window.__previewSelectObject;typeof i=="function"&&i(e)}}startDrag(e,t){var d,p,u,g,h,f,m;if(!this.selectedId)return;let i=this.objectMap.get(this.selectedId);if(!(i!=null&&i.displayObject))return;let n=this.getEditableObjectConfig(this.selectedId);if(!n||this.backgroundLocked&&this.isBackgroundObject(this.selectedId,n,i.displayObject))return;let a=(d=n.transform)!=null?d:{},s=(p=i.displayObject.parent)!=null?p:this.mainContainer,o=this.getEventLocalPoint(t,s);if(!o)return;(u=t==null?void 0:t.stopPropagation)==null||u.call(t),(g=t==null?void 0:t.stopImmediatePropagation)==null||g.call(t);let l=this.getPositioningAnchor(this.selectedId,a);(a.anchor==null||a.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"transform.anchor",l),(((h=n==null?void 0:n.render)==null?void 0:h.anchor)==null||n.render.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"render.anchor",l),this.dragMode=e,this.dragContainer=s,this.dragStartPointer=new D.Point(o.x,o.y),this.dragStartPos=new D.Point(i.displayObject.position.x,i.displayObject.position.y),this.dragLastPointer=new D.Point(o.x,o.y),this.dragPointerOffset=new D.Point(i.displayObject.position.x-o.x,i.displayObject.position.y-o.y),this.dragLogged=!1;let c=(f=this.getRuntimeScreenSize())!=null?f:this.getScreen();console.log("[SceneEditor][DragStart]",{objectId:this.selectedId,mode:e,isBackground:this.isBackgroundObject(this.selectedId,n,i.displayObject),screen:c,runtimeScale:this.getRuntimeScale(),pointer:{x:o.x,y:o.y},objectPos:{x:i.displayObject.position.x,y:i.displayObject.position.y},container:s===this.bgContainer?"bg":s===this.uiContainer?"ui":"main"}),this.dragStartScale=typeof((m=i.displayObject.scale)==null?void 0:m.x)=="number"?i.displayObject.scale.x:1,this.dragStartRotation=typeof i.displayObject.rotation=="number"?i.displayObject.rotation:0,this.dragAnchorLocal=this.getAnchorLocalPoint(a,s),this.dragStartValue=this.getDragStartValue(e,a),this.dragAnchorLocal&&(this.dragStartAngle=Math.atan2(o.y-this.dragAnchorLocal.y,o.x-this.dragAnchorLocal.x),this.dragStartDistance=Math.max(1,this.distance(o,this.dragAnchorLocal))),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}updateLiveConfigPositionForObject(e,t,i){var P,I,_,k,j,L,x,S;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(P=n.transform)!=null?P:{};n.transform||(n.transform=a);let s=(I=this.getRuntimeScreenSize())!=null?I:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let o=this.objectMap.get(e),l=((_=o==null?void 0:o.displayObject)==null?void 0:_.parent)===this.bgContainer,c=this.getPositioningAnchor(e,a),d=(a==null?void 0:a.position_ratio)!=null?pt(s.width,s.height,a.position_ratio):Ne(s.width,s.height,c),p=d.x,u=d.y,g=t,h=i;if(!l){let E=this.getRuntimeScale();p=(d.x-s.width/2)/E,u=(d.y-s.height/2)/E,g=t/E,h=i/E}let f=g-p,m=h-u,b=(k=a.offset)!=null?k:{x:0,y:0},y=Array.isArray(b)?Number((j=b[0])!=null?j:0):Number((L=b==null?void 0:b.x)!=null?L:0),w=Array.isArray(b)?Number((x=b[1])!=null?x:0):Number((S=b==null?void 0:b.y)!=null?S:0),v=this.buildPositionValue(a,{x:f-y,y:m-w});this.updateManager.updateProperty(e,"transform.position",v,{refreshInspector:!0})}updateLiveConfigPosition(e,t){this.selectedId&&this.updateLiveConfigPositionForObject(this.selectedId,e,t)}updateLiveConfigScale(e){var a;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(a=t.transform)!=null?a:{};t.transform||(t.transform=i);let n=Math.round(e*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.scale",n,{refreshInspector:!0})}updateLiveConfigRotation(e){var s;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(s=t.transform)!=null?s:{};t.transform||(t.transform=i);let n=this.toDegrees(e),a=typeof i.rotation=="number"?i.rotation:0;if(Math.abs(n-a)>.01){let o=Math.round(n*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.rotation",o,{refreshInspector:!0})}}applyFinalOverride(e,t,i,n){let a=this.getEditableObjectConfig(e);a!=null&&a.transform&&this.setNestedValue(a.transform,t.replace("transform.",""),n),le({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),window.dispatchEvent(new CustomEvent("inspector:refresh")))}))}setNestedValue(e,t,i){let n=t.split("."),a=e;for(let s=0;s<n.length-1;s+=1){let o=n[s];(!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,n=Math.round(t.x*100)/100,a=Math.round(t.y*100)/100;return Array.isArray(i)?[n,a]:{x:n,y:a}}toRadians(e){return e*Math.PI/180}toDegrees(e){return e*180/Math.PI}distance(e,t){let i=e.x-t.x,n=e.y-t.y;return Math.sqrt(i*i+n*n)}getPointerButton(e){var t,i,n;return typeof(e==null?void 0:e.button)=="number"?e.button:typeof((t=e==null?void 0:e.data)==null?void 0:t.button)=="number"?e.data.button:typeof((n=(i=e==null?void 0:e.data)==null?void 0:i.originalEvent)==null?void 0:n.button)=="number"?e.data.originalEvent.button:0}getEventGlobalPoint(e){var l,c;let t=(c=e==null?void 0:e.global)!=null?c:(l=e==null?void 0:e.data)==null?void 0:l.global;if(t)return new D.Point(t.x,t.y);if(!this.app)return null;let i=e==null?void 0:e.clientX,n=e==null?void 0:e.clientY;if(typeof i!="number"||typeof n!="number")return null;let a=this.app.canvas.getBoundingClientRect(),s=(i-a.left)*(this.app.renderer.width/a.width),o=(n-a.top)*(this.app.renderer.height/a.height);return new D.Point(s,o)}getEventLocalPoint(e,t=this.mainContainer){var a,s;if(!this.app)return null;if(typeof(e==null?void 0:e.getLocalPosition)=="function"){let o=e.getLocalPosition(t);return new D.Point(o.x,o.y)}let i=(s=e==null?void 0:e.global)!=null?s:(a=e==null?void 0:e.data)==null?void 0:a.global;if(!i)return null;let n=new D.Point;return t.toLocal(new D.Point(i.x,i.y),void 0,n),n}getPointerInContainer(e,t,i){if(!this.app)return null;let n=this.app.canvas.getBoundingClientRect(),a=(e-n.left)*(this.app.renderer.width/n.width),s=(t-n.top)*(this.app.renderer.height/n.height),o=new D.Point;return i.toLocal(new D.Point(a,s),void 0,o),o}parseColor(e,t){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let i=e.trim().replace("#",""),n=Number.parseInt(i,16);if(Number.isFinite(n))return n}return t}drawSelectionBox(e,t){if(!this.selectionBox)return;this.selectionBox.clear();let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),s=Math.max(e.y,t.y),o=n-i,l=s-a;this.selectionBox.rect(i,a,o,l),this.selectionBox.stroke({width:2,color:3900150,alpha:.8}),this.selectionBox.rect(i,a,o,l),this.selectionBox.fill({color:3900150,alpha:.1})}finalizeSelectionBox(e,t){var l;let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),s=Math.max(e.y,t.y),o=[];for(let[c,d]of this.objectMap.entries()){let p=d.displayObject;if(!p||p.visible===!1||this.backgroundLocked&&this.isBackgroundObject(c,this.getEditableObjectConfig(c),p))continue;let u=(l=p.getBounds)==null?void 0:l.call(p);if(!u||u.width<=0||u.height<=0)continue;let g=u.x+u.width/2,h=u.y+u.height/2;g>=i&&g<=n&&h>=a&&h<=s&&o.push(c)}o.length>0&&(this.selectedIds=new Set(o),this.selectedId=o[0],this.updateGizmos())}setupDragAndDrop(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),this.dropZoneActive||(this.dropZoneActive=!0,this.showDropZone())}),e.addEventListener("dragleave",t=>{e.contains(t.relatedTarget)||(this.dropZoneActive=!1,this.hideDropZone())}),e.addEventListener("drop",async t=>{var d;t.preventDefault(),t.stopPropagation(),this.dropZoneActive=!1,this.hideDropZone();let n=Array.from(((d=t.dataTransfer)==null?void 0:d.files)||[]).filter(p=>p.type.startsWith("image/"));if(n.length===0)return;let a=e.getBoundingClientRect(),s=t.clientX-a.left,o=t.clientY-a.top,l=new D.Point(s/a.width*this.app.renderer.width,o/a.height*this.app.renderer.height),c=this.camera.toLocal(l);await this.handleDroppedPNGs(n,c)})}showDropZone(){if(!this.dropZoneOverlay||!this.app)return;let e=this.camera.toLocal(new D.Point(0,0)),t=this.camera.toLocal(new D.Point(this.app.renderer.width,this.app.renderer.height)),i=t.x-e.x,n=t.y-e.y;this.dropZoneOverlay.clear(),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.fill({color:3900150,alpha:.1}),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.stroke({width:3,color:3900150,alpha:.6}),this.dropZoneOverlay.visible=!0}hideDropZone(){this.dropZoneOverlay&&(this.dropZoneOverlay.clear(),this.dropZoneOverlay.visible=!1)}async handleDroppedPNGs(e,t){let i=window.__HANDLER_ACTIVE_SCREEN,n=i==="loading"||i==="start"||i==="gameplay"||i==="tutorial"||i==="endgame"?i:"gameplay",a=this.showToast(`Processing ${e.length} PNG${e.length>1?"s":""}...`);try{for(let s=0;s<e.length;s++){let o=e[s];await this.processDroppedPNG(o,t,n,s)}this.hideToast(a),this.showToast(`\u2705 Added ${e.length} PNG${e.length>1?"s":""} to scene`,2e3),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))}catch(s){this.hideToast(a),this.showToast(`\u274C Error: ${s instanceof Error?s.message:String(s)}`,3e3),console.error("[SceneEditor] Failed to process dropped PNGs:",s)}}async processDroppedPNG(e,t,i,n){let a=await this.fileToDataUrl(e);if(!a)throw new Error(`Failed to read ${e.name}`);let s=e.name.replace(/\.[^/.]+$/,""),o=this.inferCategoryFromFilename(s),l=s.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),c=`${l}_${Date.now()}${n>0?`_${n}`:""}`,d=`json.${c}`,p=`${l}.png`,g=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:p,data:a,overwrite:!1})})).json();if(!g.success)throw new Error(`Failed to save ${e.name} to library: ${g.error}`);let h=this.getScreen(),f=this.getRuntimeScale(),m=(t.x-h.width/2)/f,b=(t.y-h.height/2)/f,y={identity:{id:d,category:o},transform:{anchor:"center",position:{x:m,y:b},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:g.path||`raw/library/${o}/${p}`}}},w=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:y,layer:o==="ui"?"ui":"world"})}),v=await w.json();if(!w.ok||!v.success)throw new Error(`Failed to create object: ${v.error||"Unknown error"}`)}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}showToast(e,t=3e3){let i=document.createElement("div");return i.style.cssText=`
2359
2359
  position: fixed;
2360
2360
  top: 20px;
2361
2361
  right: 20px;
@@ -2368,7 +2368,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2368
2368
  font-family: system-ui, -apple-system, sans-serif;
2369
2369
  font-size: 14px;
2370
2370
  pointer-events: none;
2371
- `,i.textContent=e,document.body.appendChild(i),t>0&&setTimeout(()=>this.hideToast(i),t),i}hideToast(e){e&&e.parentNode&&e.parentNode.removeChild(e)}showContextMenu(e,t,i){let n=window.__HANDLER_ACTIVE_SCREEN,a=n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame"?n:"gameplay";new gt({objectId:e,screenId:a,onSelect:r=>{r?(this.selectedIds.clear(),this.selectedIds.add(r),this.setSelected(r),this.updateGizmos()):(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos())},onRefresh:()=>{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))},onClose:()=>{},onDeleteRequest:r=>{let l=window.__deleteObjectRequest;typeof l=="function"&&l(r)},onMoveRequest:(r,l)=>{let c=window.__moveObjectRequest;typeof c=="function"&&c(r,a,l)}}).open({x:t,y:i})}};var gn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[et("playable-portrait"),et("iphone-14"),et("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.hasForceSynced=!1;this.onWindowResize=e=>{if(this.ignoreNextWindowResize){this.ignoreNextWindowResize=!1;return}this.resizeListenersDisabled||!this.gameReady||(this.scheduleFit(),this.updateBottomDockHeight())};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=et(e.defaultDevice||ki.id),this.debugPanel=new Yt,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 i=window.localStorage.getItem(this.getSceneVisibilityStorageKey());this.sceneVisiblePreference=i===null?!0:i==="true"}catch{}let t="dark";try{let i=window.localStorage.getItem(this.getThemeStorageKey());(i==="light"||i==="dark")&&(t=i)}catch{}this.setTheme(t),this.sceneEditor=new un({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.updateBottomDockHeight(),this.isInitialized=!0,this.scheduleForceSync()}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()}scheduleForceSync(){this.hasForceSynced||(this.hasForceSynced=!0,window.setTimeout(()=>{let e=window.__HANDLER_ACTIVE_SCREEN;fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"})}).catch(i=>{console.warn("[PreviewShell] Force sync on refresh failed:",i)})},250))}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.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=et(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier: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");try{window.localStorage.setItem(this.getThemeStorageKey(),e)}catch{}let t=this.container.querySelector("#theme-select");t&&(t.value=e),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=null,s=l=>{let c=l.clientY-i,d=Math.max(100,Math.min(800,n-c));e.style.height=`${d}px`;let p=window.innerHeight;a=d/p*100;try{window.localStorage.setItem("preview_bottom_dock_height_percent",String(a))}catch{}let u=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:u})},r=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",r),e.classList.remove("resizing")};t.addEventListener("pointerdown",l=>{l.preventDefault(),i=l.clientY,n=e.offsetHeight,document.addEventListener("pointermove",s),document.addEventListener("pointerup",r),e.classList.add("resizing")})}updateBottomDockHeight(){let e=this.container.querySelector("#bottom-dock");if(!e||e.classList.contains("resizing"))return;try{let a=window.localStorage.getItem("preview_bottom_dock_height_percent");if(a){let s=Number(a);if(Number.isFinite(s)&&s>0){let r=window.innerHeight,l=Math.max(100,Math.min(800,s/100*r));e.style.height=`${l}px`;return}}}catch{}let t=e.offsetHeight,i=window.innerHeight,n=Math.min(800,i*.5);t>n&&(e.style.height=`${n}px`)}makeSidebarResizable(e,t,i){let n,a,s=()=>{let c=this.container.querySelector(".preview-main");if(!c)return 600;let p=c.getBoundingClientRect().width,u=i==="left"?this.container.querySelector(".debug-workbench"):this.container.querySelector(".scene-panel.scene-objects"),g=u?u.offsetWidth:i==="left"?350:300,f=p-g-200;return Math.max(200,f)},r=c=>{let d=i==="left"?c.clientX-n:n-c.clientX,p=s(),u=Math.max(200,Math.min(p,a+d));e.style.width=`${u}px`;let g=this.container.querySelector(".preview-main");if(g){let f=i==="left"?`${u}px`:g.style.gridTemplateColumns.split(" ")[0]||"300px",m=i==="right"?`${u}px`:g.style.gridTemplateColumns.split(" ")[2]||"350px",b=400;g.style.gridTemplateColumns=`${f} minmax(${b}px, 1fr) ${m}`}let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},l=()=>{document.removeEventListener("pointermove",r),document.removeEventListener("pointerup",l),e.classList.remove("resizing")};t.addEventListener("pointerdown",c=>{c.preventDefault(),n=c.clientX,a=e.offsetWidth,document.addEventListener("pointermove",r),document.addEventListener("pointerup",l),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"}`}getThemeStorageKey(){return`handler_preview_theme::${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&&tt(this.scenePane,e,i!=null?i:this.previewContainer),t&&cn(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 s=a.clientX,r=this.scenePane.offsetWidth,l=Math.max(260,Math.min(720,this.previewContainer.clientWidth*.6)),c=p=>{let u=p.clientX-s,g=Math.max(240,Math.min(l,r+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=`
2371
+ `,i.textContent=e,document.body.appendChild(i),t>0&&setTimeout(()=>this.hideToast(i),t),i}hideToast(e){e&&e.parentNode&&e.parentNode.removeChild(e)}showContextMenu(e,t,i){let n=window.__HANDLER_ACTIVE_SCREEN,a=n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame"?n:"gameplay";new ht({objectId:e,screenId:a,onSelect:o=>{o?(this.selectedIds.clear(),this.selectedIds.add(o),this.setSelected(o),this.updateGizmos()):(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos())},onRefresh:()=>{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))},onClose:()=>{},onDeleteRequest:o=>{let l=window.__deleteObjectRequest;typeof l=="function"&&l(o)},onMoveRequest:(o,l)=>{let c=window.__moveObjectRequest;typeof c=="function"&&c(o,a,l)}}).open({x:t,y:i})}};var fn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[tt("playable-portrait"),tt("iphone-14"),tt("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.hasForceSynced=!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=tt(e.defaultDevice||ki.id),this.debugPanel=new Wt,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 i=window.localStorage.getItem(this.getSceneVisibilityStorageKey());this.sceneVisiblePreference=i===null?!0:i==="true"}catch{}let t="dark";try{let i=window.localStorage.getItem(this.getThemeStorageKey());(i==="light"||i==="dark")&&(t=i)}catch{}this.setTheme(t),this.sceneEditor=new hn({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.isInitialized=!0,this.scheduleForceSync()}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()}scheduleForceSync(){this.hasForceSynced||(this.hasForceSynced=!0,window.setTimeout(()=>{let e=window.__HANDLER_ACTIVE_SCREEN;fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"})}).catch(i=>{console.warn("[PreviewShell] Force sync on refresh failed:",i)})},250))}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.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=tt(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier: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");try{window.localStorage.setItem(this.getThemeStorageKey(),e)}catch{}let t=this.container.querySelector("#theme-select");t&&(t.value=e),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.updatePanelPositions(),this.updateSceneVisibility(),window.dispatchEvent(new CustomEvent("inspector:refresh"))}makeSidebarResizable(e,t,i){let n,a,s=()=>{let c=this.container.querySelector(".preview-main");if(!c)return 600;let p=c.getBoundingClientRect().width,u=i==="left"?this.container.querySelector(".debug-workbench"):this.container.querySelector(".scene-panel.scene-objects"),g=u?u.offsetWidth:i==="left"?350:300,f=p-g-200;return Math.max(200,f)},o=c=>{let d=i==="left"?c.clientX-n:n-c.clientX,p=s(),u=Math.max(200,Math.min(p,a+d));e.style.width=`${u}px`;let g=this.container.querySelector(".preview-main");if(g){let f=i==="left"?`${u}px`:g.style.gridTemplateColumns.split(" ")[0]||"300px",m=i==="right"?`${u}px`:g.style.gridTemplateColumns.split(" ")[2]||"350px",b=400;g.style.gridTemplateColumns=`${f} minmax(${b}px, 1fr) ${m}`}let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},l=()=>{document.removeEventListener("pointermove",o),document.removeEventListener("pointerup",l),e.classList.remove("resizing")};t.addEventListener("pointerdown",c=>{c.preventDefault(),n=c.clientX,a=e.offsetWidth,document.addEventListener("pointermove",o),document.addEventListener("pointerup",l),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"}`}getThemeStorageKey(){return`handler_preview_theme::${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&&it(this.scenePane,e,i!=null?i:this.previewContainer),t&&pn(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 s=a.clientX,o=this.scenePane.offsetWidth,l=Math.max(260,Math.min(720,this.previewContainer.clientWidth*.6)),c=p=>{let u=p.clientX-s,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=`
2372
2372
  <div class="preview-toolbar">
2373
2373
  <div class="preview-toolbar-left">
2374
2374
  <span class="preview-logo">PREVIEWER</span>
@@ -2377,7 +2377,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2377
2377
  <div class="preview-toolbar-center">
2378
2378
  <div class="device-selector-wrapper">
2379
2379
  <select class="device-dropdown" id="device-select">
2380
- ${sa.map(i=>`
2380
+ ${ra.map(i=>`
2381
2381
  <optgroup label="${i.label}">
2382
2382
  ${i.devices.map(n=>`
2383
2383
  <option value="${n.id}" ${n.id===this.currentPreset.id?"selected":""}>
@@ -2540,6 +2540,8 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2540
2540
 
2541
2541
  ${((t=this.debugPanel)==null?void 0:t.getDebugOverlayHTML())||""}
2542
2542
 
2543
+ <!-- Bottom dock (Library and Console panels) - COMMENTED OUT -->
2544
+ <!--
2543
2545
  <div class="bottom-dock" id="bottom-dock">
2544
2546
  <div class="bottom-dock-resize-handle" id="bottom-dock-resize"></div>
2545
2547
  <div class="bottom-dock-header">
@@ -2558,9 +2560,10 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2558
2560
  </div>
2559
2561
  </div>
2560
2562
  </div>
2563
+ -->
2561
2564
 
2562
2565
  </div>
2563
- `,this.setupEventListeners(e),e}setupEventListeners(e){var P,_,T,M,k,A,C,L;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",x=>{if(this.viewMode==="compare")return;let E=x.target.value;this.setDevice(E)});let i=e.querySelector("#theme-select");i==null||i.addEventListener("change",x=>{let E=x.target.value;this.setTheme(E)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(x=>{x.addEventListener("click",()=>{let E=x.dataset.viewToggle;E&&this.setViewMode(E)})}),Array.from(e.querySelectorAll("[data-layout-toggle]")).forEach(x=>{x.addEventListener("click",()=>{let E=x.dataset.layoutToggle;E&&this.setLayoutMode(E)})});let s=e.querySelector("#scene-toggle");s==null||s.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!this.sceneVisiblePreference),this.updateSceneVisibility())});let r=e.querySelector("#scene-hide-btn");r==null||r.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!1),this.updateSceneVisibility())});let l=x=>{let E=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${x}::${E}`},c=e.querySelector("#scene-grid-btn"),d=e.querySelector("#scene-play-btn"),p=(x,E,S)=>{x&&(x.textContent=E?`${S} On`:`${S} Off`,x.setAttribute("aria-pressed",E?"true":"false"))},u=()=>{let x=window.localStorage.getItem(l("grid_gap")),E=Number(x!=null?x:50);return Number.isFinite(E)?E:50},g=x=>{try{window.localStorage.setItem(l("grid_enabled"),x?"true":"false")}catch{}p(c,x,"Grid");let E=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:x,gap:E}}))},h=x=>{try{window.localStorage.setItem(l("play_mode"),x?"true":"false")}catch{}p(d,x,"Play"),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:x}}))};try{let x=window.localStorage.getItem(l("grid_enabled"))==="true",E=!0;try{window.localStorage.setItem(l("play_mode"),"true")}catch{}if(p(c,x,"Grid"),p(d,E,"Play"),d&&(d.disabled=!0),c){let S=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:x,gap:S}}))}d&&window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:E}}))}catch{}c==null||c.addEventListener("click",()=>{let x=c.getAttribute("aria-pressed")==="true";g(!x)}),d==null||d.addEventListener("click",()=>{let x=d.getAttribute("aria-pressed")==="true";h(!x)}),(P=e.querySelector("#rotate-btn"))==null||P.addEventListener("click",()=>this.toggleRotation()),(_=e.querySelector("#zoom-in-btn"))==null||_.addEventListener("click",()=>this.adjustUserZoom(.1)),(T=e.querySelector("#zoom-out-btn"))==null||T.addEventListener("click",()=>this.adjustUserZoom(-.1)),(M=e.querySelector("#refresh-btn"))==null||M.addEventListener("click",()=>this.refresh());let f=e.querySelector("#bottom-dock"),m=e.querySelector("#bottom-dock-resize");f&&m&&this.makeBottomDockResizable(f,m);let b=Array.from(e.querySelectorAll(".bottom-dock-tab"));b.forEach(x=>{x.addEventListener("click",()=>{let E=x.dataset.dockTab;if(!E)return;b.forEach(O=>O.classList.remove("active")),x.classList.add("active"),Array.from(e.querySelectorAll(".bottom-dock-panel")).forEach(O=>{let j=O.dataset.dockPanel;O.classList.toggle("active",j===E)})})}),(k=e.querySelector("#console-clear"))==null||k.addEventListener("click",()=>this.clearConsole()),(A=e.querySelector("#corner-zoom-in-btn"))==null||A.addEventListener("click",()=>this.adjustUserZoom(.1)),(C=e.querySelector("#corner-zoom-out-btn"))==null||C.addEventListener("click",()=>this.adjustUserZoom(-.1)),(L=e.querySelector("#corner-grab-btn"))==null||L.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)});let y=e.querySelector(".scene-panel.scene-objects"),v=y==null?void 0:y.querySelector("[data-panel-resize-v]");y&&v&&this.makeSidebarResizable(y,v,"left");let w=e.querySelector(".debug-workbench"),I=w==null?void 0:w.querySelector("#workbench-resize-v");w&&I&&this.makeSidebarResizable(w,I,"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 s=n/t.width,r=a/t.height;if(this.autoScale=Math.max(.01,Math.min(s,r)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}(e==null?void 0:e.keepUserScaleMultiplier)!==void 0&&e.keepUserScaleMultiplier>0?this.userScaleMultiplier=e.keepUserScaleMultiplier: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(),vi();return}if(i&&(e.key==="z"&&n||e.key==="y"&&!n)){e.preventDefault(),wi();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=He().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.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier: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(s=>typeof s=="object"?this.safeStringify(s):String(s)).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 s=this.consoleMessages.filter(r=>r.type==="error").length;a.textContent=s>0?`${s}!`:"0",a.classList.toggle("has-errors",s>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]"),s=t.querySelector("[data-compare-ghost]"),r=t.querySelector("[data-compare-wrapper]"),l=t.querySelector("[data-compare-frame]"),c=t.querySelector("[data-compare-snapshot]"),d=t.querySelector("[data-compare-focus]");!a||!s||!r||!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:s,wrapper:r,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,s;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((r,l)=>{r.root.classList.toggle("is-active",l===e),r.ghost.classList.toggle("hidden",l===e),r.focus&&(r.focus.textContent=l===e?"Live":"Focus")}),this.applyPresetDimensions(),this.applyCompareDimensions(),this.fitToScreen({keepVisibleScale:i}),(s=(a=this.options).onDeviceChange)==null||s.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,s=n/e.preset.height,r=Math.max(.01,Math.min(a,s));e.wrapper.style.transform=`scale(${r})`})}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,s=t.canvas.height,r=Math.min(a/i.width,s/i.height),l=i.width*r,c=i.height*r,d=(a-l)/2,p=(s-c)/2;n.clearRect(0,0,a,s),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 Da(o={}){let e=new gn(o);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}Q();function Na(o){try{if(o&&typeof o.keys=="function")return Array.from(o.keys())}catch{}return[]}function Ro(o){var e;return o?((e=o.getDisplayObject)==null?void 0:e.call(o))||o.pixiObject||o:null}function El(o,e){if(!o||!(e!=null&&e.interaction))return;let t=e.interaction,i=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);o.eventMode=i?"static":"none",o.interactive=i,i&&(o.cursor=t.draggable?"move":"pointer")}function zo(o,e){var d,p,u;if(!o||!e)return;let t=e.transform||{};El(o,e);let i=t.position||{},n=t.offset||{},a=(typeof i.x=="number"?i.x:0)+(typeof n.x=="number"?n.x:0),s=(typeof i.y=="number"?i.y:0)+(typeof n.y=="number"?n.y:0),r=333,l=111;a+=r,s+=l,console.log("[DEBUG FALLBACK] tryApplyTransform (live-edit) position.set",a,s,"(raw + 333, +111)"),(d=o.position)!=null&&d.set?o.position.set(a,s):(typeof o.x=="number"&&(o.x=a),typeof o.y=="number"&&(o.y=s)),typeof t.scale=="number"&&((p=o.scale)!=null&&p.set?o.scale.set(t.scale):o.scale&&(o.scale.x=t.scale,o.scale.y=t.scale));let c=t.anchor;if(c&&((u=o.anchor)!=null&&u.set)){let g=null;typeof window!="undefined"&&window.resolveAnchorVec2?g=window.resolveAnchorVec2(c):typeof c=="object"&&c.x!==void 0&&c.y!==void 0?g=c:Array.isArray(c)&&c.length===2&&(g={x:c[0],y:c[1]}),g&&typeof g.x=="number"&&typeof g.y=="number"&&o.anchor.set(g.x,g.y)}}function $o(o){if(typeof window=="undefined")return;let e=o==null?void 0:o.objects,t=Na(e),i=a=>{var s;try{let r=window.__HANDLER_ACTIVE_SCREEN;if(!r||r==="all")return a;let l=window.__HANDLER_SCREEN_INDEX,c=(s=l==null?void 0:l.screenToInstances)==null?void 0:s[r];if(Array.isArray(c)&&c.length>0){let p=new Set(c);return a.filter(u=>p.has(u))}let d=l==null?void 0:l.instanceToScreen;return d?a.filter(p=>d[p]===r):a}catch{return a}};window.__editableObjectConfigs=e;let n=new Map;t.forEach(a=>n.set(a,[a])),window.__editableObjectInstances=n,window.refreshEditableConfigIndex=()=>$o(window.__editableConfig),window.getEditableObjectList=()=>{var a;return i(Na((a=window.__editableConfig)==null?void 0:a.objects))},window.getEditableObjectListAll=()=>{var a;return Na((a=window.__editableConfig)==null?void 0:a.objects)},window.getEditableObjectConfig=a=>{var p,u,g,h,f,m;let s=(h=(g=(u=(p=window.__editableConfig)==null?void 0:p.objects)==null?void 0:u.get)==null?void 0:g.call(u,a))!=null?h:null,r=window.__HANDLER_ACTIVE_SCREEN;if(!r||r==="all")return s;let l=window.__HANDLER_SCREEN_INDEX,c=(f=l==null?void 0:l.screenToInstances)==null?void 0:f[r];if(Array.isArray(c))return c.includes(a)?s:null;let d=(m=l==null?void 0:l.instanceToScreen)==null?void 0:m[a];return d&&d===r?s: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 s={...a.engine,objects:a.objects,scene:a.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(s.assets||{})),s}return a}}function Cl(){if(typeof window=="undefined")return;let o=t=>{let i=String(t||"").trim();return i?/^(data:|blob:|https?:)/.test(i)||i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`:""},e=async(t,i)=>{var a,s,r;let n=o(i);if(n)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),Promise.resolve().then(()=>(ct(),_s))]),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=(s=h==null?void 0:h.get)==null?void 0:s.call(h,t);if(f){let m=((r=f.getDisplayObject)==null?void 0:r.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=se();Array.isArray(i)&&i.length&&(window.__editableConfig=t,Ne(i,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let i=se();Array.isArray(i)&&i.length&&(window.__editableConfig=t,Ne(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,s]of Object.entries(t.runtime))n.push({path:`runtime.${a}`,value:s});if(t.assets)for(let[a,s]of Object.entries(t.assets))n.push({path:`assets.${a}`,value:s}),typeof s=="string"&&e(a,s);if(t.splash)for(let[a,s]of Object.entries(t.splash))n.push({path:`splash.${a}`,value:s});if(t.loading)for(let[a,s]of Object.entries(t.loading))n.push({path:`loading.${a}`,value:s});if(t.start)for(let[a,s]of Object.entries(t.start))n.push({path:`start.${a}`,value:s});n.length&&Ne(n,{silent:!0,persist:!0,emitEvent:!0})}}function hn(o){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:i}=o;t&&(t.onObjectRebuildRequired=async(a,s)=>{console.log(`[LIVE-EDIT] \u{1F3D7}\uFE0F Rebuilding object ${a} due to type change...`);let r=t.get(a),l=r==null?void 0:r.pixiObject,c=l==null?void 0:l.parent,d=c==null?void 0:c.children.indexOf(l);r?t.remove(a):l&&l.destroy();let p=window.gameApp,u=await ve.create(a,s,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"&&(Cl(),window.applyEditableObjectConfig=(a,s)=>{var r,l,c;console.log("[LIVE-EDIT] \u{1F504} applyEditableObjectConfig called for:",a);try{let d=window.__editableConfig;(r=d==null?void 0:d.objects)!=null&&r.set&&(d.objects.set(a,s),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(s);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=Ro(p);zo(u,s)}}catch(d){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",d)}});let n={async applyObjectConfig(a,s){var d,p;console.log("[BRIDGE] \u{1F504} applyObjectConfig called for:",a);let r=e();(d=r==null?void 0:r.objects)!=null&&d.set&&(r.objects.set(a,s),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(s);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=Ro(l);zo(u,s)}let c=[a];i==null||i(a,s,c)},rebuildIndexes(){let a=e();typeof window!="undefined"&&(window.__editableConfig=a,$o(a))}};return n.rebuildIndexes(),n}Q();var Ho=st(require("lottie-web"),1);Mn(In);typeof window!="undefined"&&!window.lottie&&(window.lottie=Ho.default);var vt=null,Al=async()=>{if(!vt){let o=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(o==null?void 0:o["handler.config"])||(o==null?void 0:o["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let i=atob(e.split(",")[1]);vt=JSON.parse(i)}else vt=JSON.parse(e);return vt}catch(i){console.warn("[CONFIG] Failed to parse inline handler.config.json:",i)}vt=await(await fetch("./handler.config.json")).json()}return vt},Ba,Xt,Fo,wt,Ha,Fa;function Ll(o){Ba=o.initGame,Xt=o.CustomAssets,Fo=o.updateScreenState,wt=o.globalResponsiveMultipliers,Ha=o.layout,Fa=o.clearResponsiveElements}var fn="web_embed",Kt="https://example.com",Do={profile_id:fn},Ue=null,Se=null,Wt={width:0,height:0},Tl=!0,kl=async()=>{var c,d,p,u;document.title="Handler Pixi Game";let o=await Al();Do={...o.ids||{},profile_id:fn},Kt=o.destination_url||((d=(c=o.export_profiles)==null?void 0:c[fn])==null?void 0:d.destination_url)||Kt,Ve.init({ids:Do,profile:fn,destinationUrl:Kt});let e=Ve.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),Se=Da({onDeviceChange:h=>{console.log(`[PREVIEW] Device switched to ${h.width}x${h.height}, restarting game...`),No()},onRefresh:No});let g=Se.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",h=>{var v,w,I,P,_,T,M,k,A,C,L,x,E;let f=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=h.detail;if(Wt.width=b,Wt.height=y,Fo(b,y),!(!f||!f.renderer)){m&&r(f,m);try{f.renderer.resize(b,y);let S=f.view;S&&(S.style.width="100%",S.style.height="100%",S.style.display="block")}catch(S){console.warn("[SCREEN] Error resizing renderer:",S);return}if(t&&m&&Ha)try{let S=(v=window.__mainContainer)!=null?v:f.stage,O=(M=(T=(P=window.__tutorialLabel)!=null?P:(I=(w=m.get("label_1"))==null?void 0:w.getDisplayObject)==null?void 0:I.call(w))!=null?T:(_=m.get("label_1"))==null?void 0:_.pixiObject)!=null?M:m.get("label_1"),j=m.get("background_1"),R=(L=(C=(A=window.__background)!=null?A:(k=j==null?void 0:j.getDisplayObject)==null?void 0:k.call(j))!=null?C:j==null?void 0:j.pixiObject)!=null?L:j;if(S){let z=S===f.stage;Ha({mainContainer:S,label:O,background:R,backgroundTexture:(R==null?void 0:R.texture)||null,app:f},t,0,Wt,m,{skipMainContainerTransform:z}),window.dispatchEvent(new CustomEvent("handler:layout-applied",{detail:{width:Wt.width,height:Wt.height,presetId:(E=(x=h.detail)==null?void 0:x.presetId)!=null?E:null}}))}}catch(S){console.warn("[SCREEN] Error in layout:",S)}}})}let t=await Pe("scene.main");window.__editableConfig=t,s(),window.__editableConfigBaseline||(window.__editableConfigBaseline=X(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 Pe("scene.main"));let i=await Ba(e,t,Kt,Se);Ue=i.app;let n=i.gameObjectManager;window.gameApp=Ue,window.gameObjectManager=n;try{window.__liveEditBridge=hn({getConfig:()=>window.__editableConfig,gameObjectManager:n,assets:Xt})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}Se&&Se.notifyGameLoaded();let a=window.__debugScale;a&&typeof a=="number"&&(wt.scale=a,console.log(`[DEBUG] Applied persisted debug scale: ${a}`)),r(Ue,n);async function s(){try{let g=async y=>{let v=y.startsWith("/")?y:`/${y}`,w=await fetch(v,{cache:"no-cache"});if(!w.ok)return null;let I=await w.text();try{return JSON.parse(I)}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 I=await g(w),P=I==null?void 0:I.elements;if(!Array.isArray(P))continue;let _=P.map(T=>T==null?void 0:T.instance_id).filter(T=>typeof T=="string");m[y]=_;for(let T of _)b[T]||(b[T]=y)}window.__HANDLER_APP_FLOW=h,window.__HANDLER_SCREEN_INDEX={screenToInstances:m,instanceToScreen:b},window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}}function r(g,h){if(Tl){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${wt.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let v=" ".repeat(y);b.children.forEach((w,I)=>{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,_=w.scale.y||1;w.__originalScale||(w.__originalScale={x:P,y:_},console.log(`${v}[RESPONSIVE] Stored original scale for child[${I}]: ${P.toFixed(3)}, ${_.toFixed(3)}`));let T=w.__originalScale.x*wt.scale,M=w.__originalScale.y*wt.scale;typeof w.scale.set=="function"?w.scale.set(T,M):(w.scale.x=T,w.scale.y=M),console.log(`${v}[RESPONSIVE] Child[${I}] 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[${I}] 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){wt.scale=g,console.log(`[RESPONSIVE] Updated global scale multiplier to: ${g.toFixed(3)}`);let h=window.gameApp,f=window.gameObjectManager;h&&f?(r(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,Ve.start()},No=async()=>{var e,t,i,n;console.log("[PREVIEW] Restarting game in 1 seconds...");let o=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(o){let a=((t=o.getDisplayObject)==null?void 0:t.call(o))||o;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(Se){Se.notifyGameDestroyed();try{Fa&&Fa()}catch(a){console.warn("Failed to clear responsive elements",a)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let a=Se.getGameContainer(),s=window.gameObjectManager;if(s&&typeof s.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),s.clear()),Ue){try{Ue.destroy(!0,{children:!0,texture:!1})}catch(r){console.warn("[PREVIEW] Destroy warning:",r)}Ue=null}window.gameApp=null,window.gameObjectManager=null,a&&(a.innerHTML="");try{typeof Xt.resetScene=="function"&&Xt.resetScene()}catch(r){console.warn("Asset reset failed",r)}setTimeout(()=>{Pe("scene.main").then(r=>{window.__editableConfig=r,window.__editableConfigBaseline||(window.__editableConfigBaseline=X(r)),Ba(a,r,Kt).then(l=>{Ue=l.app,window.gameApp=Ue,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=hn({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:Xt})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}Se&&Se.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{Ve.start()}catch{}})})},100)},1e3)}};Ti();Q();var Ee={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Bo=1.25,Go={fontFamily:"Inter, system-ui, sans-serif"};var mn=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=`
2566
+ `,this.setupEventListeners(e),e}setupEventListeners(e){var w,v,P,I,_,k,j;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",L=>{if(this.viewMode==="compare")return;let x=L.target.value;this.setDevice(x)});let i=e.querySelector("#theme-select");i==null||i.addEventListener("change",L=>{let x=L.target.value;this.setTheme(x)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(L=>{L.addEventListener("click",()=>{let x=L.dataset.viewToggle;x&&this.setViewMode(x)})}),Array.from(e.querySelectorAll("[data-layout-toggle]")).forEach(L=>{L.addEventListener("click",()=>{let x=L.dataset.layoutToggle;x&&this.setLayoutMode(x)})});let s=e.querySelector("#scene-toggle");s==null||s.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())});let l=L=>{let x=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${L}::${x}`},c=e.querySelector("#scene-grid-btn"),d=e.querySelector("#scene-play-btn"),p=(L,x,S)=>{L&&(L.textContent=x?`${S} On`:`${S} Off`,L.setAttribute("aria-pressed",x?"true":"false"))},u=()=>{let L=window.localStorage.getItem(l("grid_gap")),x=Number(L!=null?L:50);return Number.isFinite(x)?x:50},g=L=>{try{window.localStorage.setItem(l("grid_enabled"),L?"true":"false")}catch{}p(c,L,"Grid");let x=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:L,gap:x}}))},h=L=>{try{window.localStorage.setItem(l("play_mode"),L?"true":"false")}catch{}p(d,L,"Play"),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:L}}))};try{let L=window.localStorage.getItem(l("grid_enabled"))==="true",x=!0;try{window.localStorage.setItem(l("play_mode"),"true")}catch{}if(p(c,L,"Grid"),p(d,x,"Play"),d&&(d.disabled=!0),c){let S=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:L,gap:S}}))}d&&window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:x}}))}catch{}c==null||c.addEventListener("click",()=>{let L=c.getAttribute("aria-pressed")==="true";g(!L)}),d==null||d.addEventListener("click",()=>{let L=d.getAttribute("aria-pressed")==="true";h(!L)}),(w=e.querySelector("#rotate-btn"))==null||w.addEventListener("click",()=>this.toggleRotation()),(v=e.querySelector("#zoom-in-btn"))==null||v.addEventListener("click",()=>this.adjustUserZoom(.1)),(P=e.querySelector("#zoom-out-btn"))==null||P.addEventListener("click",()=>this.adjustUserZoom(-.1)),(I=e.querySelector("#refresh-btn"))==null||I.addEventListener("click",()=>this.refresh()),(_=e.querySelector("#corner-zoom-in-btn"))==null||_.addEventListener("click",()=>this.adjustUserZoom(.1)),(k=e.querySelector("#corner-zoom-out-btn"))==null||k.addEventListener("click",()=>this.adjustUserZoom(-.1)),(j=e.querySelector("#corner-grab-btn"))==null||j.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)});let f=e.querySelector(".scene-panel.scene-objects"),m=f==null?void 0:f.querySelector("[data-panel-resize-v]");f&&m&&this.makeSidebarResizable(f,m,"left");let b=e.querySelector(".debug-workbench"),y=b==null?void 0:b.querySelector("#workbench-resize-v");b&&y&&this.makeSidebarResizable(b,y,"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 s=n/t.width,o=a/t.height;if(this.autoScale=Math.max(.01,Math.min(s,o)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}(e==null?void 0:e.keepUserScaleMultiplier)!==void 0&&e.keepUserScaleMultiplier>0?this.userScaleMultiplier=e.keepUserScaleMultiplier: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(),wi();return}if(i&&(e.key==="z"&&n||e.key==="y"&&!n)){e.preventDefault(),xi();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=Fe().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.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier: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(s=>typeof s=="object"?this.safeStringify(s):String(s)).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 s=this.consoleMessages.filter(o=>o.type==="error").length;a.textContent=s>0?`${s}!`:"0",a.classList.toggle("has-errors",s>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;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]"),s=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||!s||!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:s,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,s;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}),(s=(a=this.options).onDeviceChange)==null||s.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,s=n/e.preset.height,o=Math.max(.01,Math.min(a,s));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,s=t.canvas.height,o=Math.min(a/i.width,s/i.height),l=i.width*o,c=i.height*o,d=(a-l)/2,p=(s-c)/2;n.clearRect(0,0,a,s),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 Na(r={}){let e=new fn(r);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}ne();function Ha(r){try{if(r&&typeof r.keys=="function")return Array.from(r.keys())}catch{}return[]}function Rr(r){var e;return r?((e=r.getDisplayObject)==null?void 0:e.call(r))||r.pixiObject||r:null}function El(r,e){if(!r||!(e!=null&&e.interaction))return;let t=e.interaction,i=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);r.eventMode=i?"static":"none",r.interactive=i,i&&(r.cursor=t.draggable?"move":"pointer")}function zr(r,e){var d,p,u;if(!r||!e)return;let t=e.transform||{};El(r,e);let i=t.position||{},n=t.offset||{},a=(typeof i.x=="number"?i.x:0)+(typeof n.x=="number"?n.x:0),s=(typeof i.y=="number"?i.y:0)+(typeof n.y=="number"?n.y:0),o=333,l=111;a+=o,s+=l,console.log("[DEBUG FALLBACK] tryApplyTransform (live-edit) position.set",a,s,"(raw + 333, +111)"),(d=r.position)!=null&&d.set?r.position.set(a,s):(typeof r.x=="number"&&(r.x=a),typeof r.y=="number"&&(r.y=s)),typeof t.scale=="number"&&((p=r.scale)!=null&&p.set?r.scale.set(t.scale):r.scale&&(r.scale.x=t.scale,r.scale.y=t.scale));let c=t.anchor;if(c&&((u=r.anchor)!=null&&u.set)){let g=null;typeof window!="undefined"&&window.resolveAnchorVec2?g=window.resolveAnchorVec2(c):typeof c=="object"&&c.x!==void 0&&c.y!==void 0?g=c:Array.isArray(c)&&c.length===2&&(g={x:c[0],y:c[1]}),g&&typeof g.x=="number"&&typeof g.y=="number"&&r.anchor.set(g.x,g.y)}}function $r(r){if(typeof window=="undefined")return;let e=r==null?void 0:r.objects,t=Ha(e),i=a=>{var s;try{let o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return a;let l=window.__HANDLER_SCREEN_INDEX,c=(s=l==null?void 0:l.screenToInstances)==null?void 0:s[o];if(Array.isArray(c)&&c.length>0){let p=new Set(c);return a.filter(u=>p.has(u))}let d=l==null?void 0:l.instanceToScreen;return d?a.filter(p=>d[p]===o):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(Ha((a=window.__editableConfig)==null?void 0:a.objects))},window.getEditableObjectListAll=()=>{var a;return Ha((a=window.__editableConfig)==null?void 0:a.objects)},window.getEditableObjectConfig=a=>{var p,u,g,h,f,m;let s=(h=(g=(u=(p=window.__editableConfig)==null?void 0:p.objects)==null?void 0:u.get)==null?void 0:g.call(u,a))!=null?h:null,o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return s;let l=window.__HANDLER_SCREEN_INDEX,c=(f=l==null?void 0:l.screenToInstances)==null?void 0:f[o];if(Array.isArray(c))return c.includes(a)?s:null;let d=(m=l==null?void 0:l.instanceToScreen)==null?void 0:m[a];return d&&d===o?s: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 s={...a.engine,objects:a.objects,scene:a.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(s.assets||{})),s}return a}}function Cl(){if(typeof window=="undefined")return;let r=t=>{let i=String(t||"").trim();return i?/^(data:|blob:|https?:)/.test(i)||i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`:""},e=async(t,i)=>{var a,s,o;let n=r(i);if(n)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),Promise.resolve().then(()=>(dt(),Os))]),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=(s=h==null?void 0:h.get)==null?void 0:s.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=re();Array.isArray(i)&&i.length&&(window.__editableConfig=t,He(i,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let i=re();Array.isArray(i)&&i.length&&(window.__editableConfig=t,He(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,s]of Object.entries(t.runtime))n.push({path:`runtime.${a}`,value:s});if(t.assets)for(let[a,s]of Object.entries(t.assets))n.push({path:`assets.${a}`,value:s}),typeof s=="string"&&e(a,s);if(t.splash)for(let[a,s]of Object.entries(t.splash))n.push({path:`splash.${a}`,value:s});if(t.loading)for(let[a,s]of Object.entries(t.loading))n.push({path:`loading.${a}`,value:s});if(t.start)for(let[a,s]of Object.entries(t.start))n.push({path:`start.${a}`,value:s});n.length&&He(n,{silent:!0,persist:!0,emitEvent:!0})}}function mn(r){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:i}=r;t&&(t.onObjectRebuildRequired=async(a,s)=>{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 we.create(a,s,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"&&(Cl(),window.applyEditableObjectConfig=(a,s)=>{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,s),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(s);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=Rr(p);zr(u,s)}}catch(d){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",d)}});let n={async applyObjectConfig(a,s){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,s),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(s);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=Rr(l);zr(u,s)}let c=[a];i==null||i(a,s,c)},rebuildIndexes(){let a=e();typeof window!="undefined"&&(window.__editableConfig=a,$r(a))}};return n.rebuildIndexes(),n}ne();var Hr=rt(require("lottie-web"),1);jn(Pn);typeof window!="undefined"&&!window.lottie&&(window.lottie=Hr.default);var wt=null,Al=async()=>{if(!wt){let r=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(r==null?void 0:r["handler.config"])||(r==null?void 0:r["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let i=atob(e.split(",")[1]);wt=JSON.parse(i)}else wt=JSON.parse(e);return wt}catch(i){console.warn("[CONFIG] Failed to parse inline handler.config.json:",i)}wt=await(await fetch("./handler.config.json")).json()}return wt},Ga,Jt,Fr,xt,Fa,Ba;function Ll(r){Ga=r.initGame,Jt=r.CustomAssets,Fr=r.updateScreenState,xt=r.globalResponsiveMultipliers,Fa=r.layout,Ba=r.clearResponsiveElements}var bn="web_embed",Xt="https://example.com",Dr={profile_id:bn},qe=null,Ee=null,Kt={width:0,height:0},Tl=!0,Il=async()=>{var c,d,p,u;document.title="Handler Pixi Game";let r=await Al();Dr={...r.ids||{},profile_id:bn},Xt=r.destination_url||((d=(c=r.export_profiles)==null?void 0:c[bn])==null?void 0:d.destination_url)||Xt,Ye.init({ids:Dr,profile:bn,destinationUrl:Xt});let e=Ye.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),Ee=Na({onDeviceChange:h=>{console.log(`[PREVIEW] Device switched to ${h.width}x${h.height}, restarting game...`),Nr()},onRefresh:Nr});let g=Ee.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",h=>{var w,v,P,I,_,k,j,L,x,S,E,C,A;let f=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=h.detail;if(Kt.width=b,Kt.height=y,Fr(b,y),!(!f||!f.renderer)){m&&o(f,m);try{f.renderer.resize(b,y);let T=f.view;T&&(T.style.width="100%",T.style.height="100%",T.style.display="block")}catch(T){console.warn("[SCREEN] Error resizing renderer:",T);return}if(t&&m&&Fa)try{let T=(w=window.__mainContainer)!=null?w:f.stage,O=(j=(k=(I=window.__tutorialLabel)!=null?I:(P=(v=m.get("label_1"))==null?void 0:v.getDisplayObject)==null?void 0:P.call(v))!=null?k:(_=m.get("label_1"))==null?void 0:_.pixiObject)!=null?j:m.get("label_1"),M=m.get("background_1"),R=(E=(S=(x=window.__background)!=null?x:(L=M==null?void 0:M.getDisplayObject)==null?void 0:L.call(M))!=null?S:M==null?void 0:M.pixiObject)!=null?E:M;if(T){let z=T===f.stage;Fa({mainContainer:T,label:O,background:R,backgroundTexture:(R==null?void 0:R.texture)||null,app:f},t,0,Kt,m,{skipMainContainerTransform:z}),window.dispatchEvent(new CustomEvent("handler:layout-applied",{detail:{width:Kt.width,height:Kt.height,presetId:(A=(C=h.detail)==null?void 0:C.presetId)!=null?A:null}}))}}catch(T){console.warn("[SCREEN] Error in layout:",T)}}})}let t=await Me("scene.main");window.__editableConfig=t,s(),window.__editableConfigBaseline||(window.__editableConfigBaseline=te(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 Me("scene.main"));let i=await Ga(e,t,Xt,Ee);qe=i.app;let n=i.gameObjectManager;window.gameApp=qe,window.gameObjectManager=n;try{window.__liveEditBridge=mn({getConfig:()=>window.__editableConfig,gameObjectManager:n,assets:Jt})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}Ee&&Ee.notifyGameLoaded();let a=window.__debugScale;a&&typeof a=="number"&&(xt.scale=a,console.log(`[DEBUG] Applied persisted debug scale: ${a}`)),o(qe,n);async function s(){try{let g=async y=>{let w=y.startsWith("/")?y:`/${y}`,v=await fetch(w,{cache:"no-cache"});if(!v.ok)return null;let P=await v.text();try{return JSON.parse(P)}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,w]of Object.entries(f)){let v=w==null?void 0:w.source;if(typeof v!="string")continue;let P=await g(v),I=P==null?void 0:P.elements;if(!Array.isArray(I))continue;let _=I.map(k=>k==null?void 0:k.instance_id).filter(k=>typeof k=="string");m[y]=_;for(let k of _)b[k]||(b[k]=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(Tl){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${xt.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let w=" ".repeat(y);b.children.forEach((v,P)=>{if(v&&v.zIndex===9999){console.log(`${w}[RESPONSIVE] Skipping debug border (zIndex 9999)`);return}if(v&&v.scale){let I=v.scale.x||1,_=v.scale.y||1;v.__originalScale||(v.__originalScale={x:I,y:_},console.log(`${w}[RESPONSIVE] Stored original scale for child[${P}]: ${I.toFixed(3)}, ${_.toFixed(3)}`));let k=v.__originalScale.x*xt.scale,j=v.__originalScale.y*xt.scale;typeof v.scale.set=="function"?v.scale.set(k,j):(v.scale.x=k,v.scale.y=j),console.log(`${w}[RESPONSIVE] Child[${P}] scale: ${I.toFixed(3)}\u2192${v.scale.x.toFixed(3)} (type: ${v.constructor.name})`),m(v,y+1)}else v&&console.log(`${w}[RESPONSIVE] Child[${P}] has no scale (type: ${v.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){xt.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,Ye.start()},Nr=async()=>{var e,t,i,n;console.log("[PREVIEW] Restarting game in 1 seconds...");let r=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(r){let a=((t=r.getDisplayObject)==null?void 0:t.call(r))||r;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(Ee){Ee.notifyGameDestroyed();try{Ba&&Ba()}catch(a){console.warn("Failed to clear responsive elements",a)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let a=Ee.getGameContainer(),s=window.gameObjectManager;if(s&&typeof s.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),s.clear()),qe){try{qe.destroy(!0,{children:!0,texture:!1})}catch(o){console.warn("[PREVIEW] Destroy warning:",o)}qe=null}window.gameApp=null,window.gameObjectManager=null,a&&(a.innerHTML="");try{typeof Jt.resetScene=="function"&&Jt.resetScene()}catch(o){console.warn("Asset reset failed",o)}setTimeout(()=>{Me("scene.main").then(o=>{window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=te(o)),Ga(a,o,Xt).then(l=>{qe=l.app,window.gameApp=qe,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=mn({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:Jt})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}Ee&&Ee.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{Ye.start()}catch{}})})},100)},1e3)}};Ii();ne();var Ce={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Br=1.25,Gr={fontFamily:"Inter, system-ui, sans-serif"};var yn=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=`
2564
2567
  position: fixed;
2565
2568
  inset: 0;
2566
2569
  display: flex;
@@ -2569,7 +2572,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2569
2572
  z-index: 50;
2570
2573
  user-select: none;
2571
2574
  overflow: hidden;
2572
- background-color: ${Ee.background};
2575
+ background-color: ${Ce.background};
2573
2576
  `;let t=document.createElement("div");t.style.cssText=`
2574
2577
  position: relative;
2575
2578
  width: 288px;
@@ -2599,13 +2602,13 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2599
2602
  font-size: 12px;
2600
2603
  font-weight: 900;
2601
2604
  letter-spacing: 0.15em;
2602
- color: ${Ee.ink};
2605
+ color: ${Ce.ink};
2603
2606
  `,s.innerHTML='LOADING<span class="loading-dots" style="animation: pulse 1.5s infinite;">..</span>',this.progressText=document.createElement("span"),this.progressText.style.cssText=`
2604
2607
  font-size: 10px;
2605
2608
  font-family: monospace;
2606
2609
  font-weight: bold;
2607
- color: ${Ee.primaryAccent};
2608
- `,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,a.appendChild(s),a.appendChild(this.progressText);let r=document.createElement("div");r.style.cssText=`
2610
+ color: ${Ce.primaryAccent};
2611
+ `,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,a.appendChild(s),a.appendChild(this.progressText);let o=document.createElement("div");o.style.cssText=`
2609
2612
  height: 4px;
2610
2613
  width: 100%;
2611
2614
  background-color: #E0DDD8;
@@ -2619,7 +2622,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2619
2622
  border-radius: 9999px;
2620
2623
  position: relative;
2621
2624
  width: ${this.currentProgress}%;
2622
- background-color: ${Ee.primaryAccent};
2625
+ background-color: ${Ce.primaryAccent};
2623
2626
  `;let l=document.createElement("div");l.style.cssText=`
2624
2627
  position: absolute;
2625
2628
  inset: 0;
@@ -2628,7 +2631,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2628
2631
  width: 50%;
2629
2632
  filter: blur(4px);
2630
2633
  animation: shimmer 2s infinite;
2631
- `,this.progressBar.appendChild(l),r.appendChild(this.progressBar);let c=document.createElement("div");c.style.cssText=`
2634
+ `,this.progressBar.appendChild(l),o.appendChild(this.progressBar);let c=document.createElement("div");c.style.cssText=`
2632
2635
  display: flex;
2633
2636
  justify-content: space-between;
2634
2637
  width: 100%;
@@ -2639,7 +2642,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2639
2642
  width: 1.5px;
2640
2643
  background-color: black;
2641
2644
  height: ${u%4===0?"6px":"2px"};
2642
- `,c.appendChild(g)}n.appendChild(a),n.appendChild(r),n.appendChild(c);let d=document.createElement("div");return d.id="handler-load-centered",d.style.cssText=`
2645
+ `,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=`
2643
2646
  position: absolute;
2644
2647
  top: 48px;
2645
2648
  width: 600px;
@@ -2658,7 +2661,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2658
2661
  font-size: 24px;
2659
2662
  letter-spacing: -0.05em;
2660
2663
  animation: handlerMove 2.5s linear infinite;
2661
- color: ${Ee.ink};
2664
+ color: ${Ce.ink};
2662
2665
  display: flex;
2663
2666
  align-items: center;
2664
2667
  justify-content: center;
@@ -2671,7 +2674,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2671
2674
  letter-spacing: 0.3em;
2672
2675
  opacity: 0.2;
2673
2676
  text-transform: uppercase;
2674
- color: ${Ee.ink};
2677
+ color: ${Ce.ink};
2675
2678
  `,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=`
2676
2679
  /* Box Loading Styles */
2677
2680
  .boxLoading {
@@ -2702,7 +2705,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2702
2705
  content: '';
2703
2706
  width: 50px;
2704
2707
  height: 50px;
2705
- background: ${Ee.primaryAccent};
2708
+ background: ${Ce.primaryAccent};
2706
2709
  animation: animate 0.5s linear infinite;
2707
2710
  position: absolute;
2708
2711
  top: 0;
@@ -2759,7 +2762,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2759
2762
  0%, 100% { opacity: 1; }
2760
2763
  50% { opacity: 0.3; }
2761
2764
  }
2762
- `,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 Ga=cs.version,Il=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"]);ls();var Xo={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"},Jo=Math.random().toString(36).slice(2),Et=null,xt={...Xo},Zo="web_embed",Ya={},Zt,Ua=!1,Jt=!1,ei=!1,Qo=!1,Ja=1,yn=0,xn=!1,je=!1,St="",Ct=Math.floor(window.innerWidth),At=Math.floor(window.innerHeight),Wa=Ct>At,_e=!1,Qt=!1,Uo=!1,qo=!1,qa=!1,vn=null,nt=null,Ka=!1,Xa=!1,bn=new Map;function er(){if(!nt)return null;let o=Date.now()-nt;return!Number.isFinite(o)||o<0?null:o}function Va(o){if(Ka)return;let e=er();e!==null&&(Ka=!0,N("session_time",{duration_ms:e,reason:o}))}function Vo(){if(Et)return Et;let o=document.createElement("div");return o.id="handler-root",o.setAttribute("data-handler-root","true"),document.body.appendChild(o),Et=o,o}function wn(o){switch(o){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return o}}function tr(o,e){return{event_name:o,ts:Date.now(),session_id:Jo,deployment_id:xt.deployment_id,variant_id:xt.variant_id,export_profile_id:xt.profile_id,instance_id:xt.instance_id||"default",env:Zo==="mraid"?"mraid":"web",attribution:Zt,payload:e}}function N(o,e){let t=wn(o),i=tr(t,e);Ln(i,!!Ya.analytics),si(t,i),t!==o&&si(o,i)}function ti(){vn&&(vn(Ct,At),vn=null)}function Lt(o){Ja=o,N("volume",o)}function Tt(o){o&&(Qo=!0),!ei&&(ei=!0,N("pause"),Lt(0))}function ii(o){!o&&Qo||ei&&(ei=!1,N("resume"),Lt(Ja))}function qe(o,e){Ct=Math.floor(o||window.innerWidth),At=Math.floor(e||window.innerHeight),Wa=Ct>At,N("resize",{width:Ct,height:At})}function Pl(){if(xs())try{let o=mraid.getMaxSize();qe(o.width,o.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?ii():Tt()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();qe(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();Lt(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&Lt(t>0?1:0)}),mraid.addEventListener("error",(t,i)=>{console.warn("mraid error:",t,"action:",i)}),xn=!0,mraid.isViewable()&&mraid.getState()!=="hidden")_e=!0,N("boot"),N("view"),N("ready"),je=!0,ti();else{let t=()=>{_e=!0,N("boot"),N("view"),N("ready"),je=!0,ti()};mraid.addEventListener("ready",t)}}catch(o){console.warn("MRAID hook skipped",o)}}function Ml(){if(Ss())try{let o=dapi.getScreenSize();qe(o.width,o.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?ii():Tt()}),dapi.addEventListener("adResized",t=>{let i=dapi.getScreenSize();qe(t.width||i.width,t.height||i.height)});let e=dapi.getAudioVolume();if(Lt(e?1:0),dapi.addEventListener("audioVolumeChange",t=>Lt(t?1:0)),xn=!0,dapi.isViewable())_e=!0,N("boot"),N("view"),N("ready"),je=!0,ti();else{let t=()=>{_e=!0,N("boot"),N("view"),N("ready"),je=!0,ti()};dapi.addEventListener("ready",t)}}catch(o){console.warn("DAPI hook skipped",o)}}function Yo(){let o=()=>{_e||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(_e=!0,N("boot"),N("view"),N("ready"),je=!0,ti(),Qt&&(Qt=!1,me.start()))};window.addEventListener("resize",()=>qe()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(ii(),o()):Tt()}),document.readyState==="complete"||document.readyState==="interactive"?o():window.addEventListener("load",o),xn=!0}function jl(){let o=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Uo=!0),!(Uo&&e instanceof MouseEvent)&&(yn+=1,Xa||(Xa=!0,N("first_interaction",{count:yn})),N("interaction",yn))};document.addEventListener("mousedown",o),document.addEventListener("touchstart",o)}function Wo(o){var i,n,a,s,r,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(o||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(lt())(a=(n=window.TJ_API)==null?void 0:n.click)==null||a.call(n);else if(Es())(r=(s=window.FbPlayableAd)==null?void 0:s.onCTAClick)==null||r.call(s);else if(Ts())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(Ls())try{(p=(d=window.smxTracking)==null?void 0:d.redirect)==null||p.call(d)}catch(f){console.warn("Smadex redirect failed",f)}else if(Cs()){let f=window.ExitApi;f&&typeof f.exit=="function"?f.exit(o||St||""):o&&window.open(o)}else rt()?(u=window.install)==null||u.call(window):As()?(g=window.openAppStore)==null||g.call(window):Tn()?(h=parent==null?void 0:parent.postMessage)==null||h.call(parent,"download","*"):o&&window.open(o)}function _l(){let o=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let i=new Image;i.src=t};if(o==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;re("view",()=>e(t.mraid_viewable)),re("start",()=>e(t.game_viewable)),re("engagement",()=>e(t.engagement));let i=()=>e(t.complete);re("complete",i),ai("engagement",n=>{var a;((a=n==null?void 0:n.payload)==null?void 0:a.count)>3&&i()}),re("cta_click",()=>e(t.click))}else if(o==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;re("view",()=>e(t.Ad_Load_Start)),re("start",()=>e(t.Ad_Viewable)),re("engagement",()=>e(t.First_Engagement)),re("complete",()=>e(t.Gameplay_Complete)),re("cta_click",()=>e(t.DSP_Click)),re("start",()=>{[5,10,15,20,25,30].forEach(i=>setTimeout(()=>e(t[`Spent_${i}_Seconds`]),i*1e3))})}}function Ol(){if(!lt())return;let o=window.TJ_API;o&&o.setPlayableAPI&&o.setPlayableAPI({skipAd:()=>{try{me.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function Ko(){var e,t,i;let o=window.TJ_API;(e=o==null?void 0:o.objectiveComplete)==null||e.call(o),(t=o==null?void 0:o.playableFinished)==null||t.call(o),(i=o==null?void 0:o.gameplayFinished)==null||i.call(o)}function Rl(){rt()&&(window.mintGameStart=()=>{ii(!0),qe()},window.mintGameClose=()=>{Tt(!0)})}function zl(){if(!kn())return;let o=window.NUC;!o||!o.trigger||(me.on("cta_click",()=>{var e,t;return(t=(e=o.trigger).convert)==null?void 0:t.call(e,St)}),me.on("complete",()=>{var e,t;return(t=(e=o.trigger).tryAgain)==null?void 0:t.call(e)}))}var me={init(o={},e){var t;if(Zo=o.profile||"web_embed",Ya=o.consent||{},xt={...Xo,...o.ids||{}},Et=o.rootEl||Et,Zt=void 0,ts((t=o.telemetry)!=null&&t.endpoint?o.telemetry:null),nt=null,Ka=!1,Xa=!1,bn.clear(),St=o.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(vn=e),N("init"),document.body.oncontextmenu=()=>!1,Vo(),Dl(Et),ks(),Pl(),Ml(),!xn){if(document.readyState==="complete")Yo();else if(!qo){qo=!0;let i=()=>{Yo(),window.removeEventListener("load",i),document.removeEventListener("DOMContentLoaded",i)};window.addEventListener("load",i),document.addEventListener("DOMContentLoaded",i)}}jl(),_l(),Ol(),Rl(),zl(),console.log(`%c @handler/playable-sdk %c v${Ga} `,"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;"),_e&&!je&&(N("boot"),N("view"),N("ready"),Qt&&(Qt=!1,me.start()),je=!0),je=_e},getRoot(){return Vo()},get version(){return Ga},get maxWidth(){return Ct},get maxHeight(){return At},get isLandscape(){return Wa},get isReady(){return je},get isStarted(){return Ua},get isPaused(){return ei},get isFinished(){return Jt},get volume(){return Ja},get interactions(){return yn},on(o,e){ai(wn(o),e)},off(o,e){An(wn(o),e)},start(){var o,e;if(!Ua){if(!_e){Qt=!0;return}if(Ua=!0,nt||(nt=Date.now()),N("start"),qe(),rt())Tt(),(o=window.gameReady)==null||o.call(window);else if(lt()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:Wa?"landscape":"portrait",buildID:Ga})}}},finish(){var o,e;Jt||(Jt=!0,N("complete"),Va("complete"),rt()?(o=window.gameEnd)==null||o.call(window):Tn()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):lt()&&Ko())},install(o){if(!Jt){Jt=!0,lt()?(Ko(),setTimeout(()=>me.install(o),300)):(N("complete"),setTimeout(()=>me.install(o),0));return}qa||(qa=!0,setTimeout(()=>qa=!1,500),N("cta_click"),N("conversion"),Va("cta"),Wo(o||St))},emit(o,e){let t=wn(o);if(!Il.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${o} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let i=tr(t,e);Ln(i,!!Ya.analytics),si(t,i)},gameStart(){me.start()},gameEnd(){me.finish()},ctaClick(o,e){N("cta_click",{url:o||St,manual:!0}),(e==null?void 0:e.open)!==!1&&Wo(o||St)},ctaShow(o){N("cta_show",o)},ctaDismiss(o){N("cta_dismiss",o)},getGameTimeMs(){return er()},endSession(o="manual"){Va(o)},setAttribution(o){Zt=o},abTest(o,e){if(!o)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($l(`${Jo}:${o}`))%e.length,i=e[t];return Zt={...Zt||{},experiment_id:o},xt.variant_id=i,N("ab_assign",{experiment_id:o,variant_id:i}),i},levelStart(o,e){nt||(nt=Date.now()),N("level_start",{level_id:o,...e})},levelComplete(o,e){N("level_complete",{level_id:o,...e})},levelFail(o,e){N("level_fail",{level_id:o,...e})},checkpoint(o,e){N("checkpoint",{checkpoint_id:o,...e})},reward(o,e){N("reward",{reward_id:o,...e})},tutorialStart(o,e){N("tutorial_start",{step_id:o,...e})},tutorialComplete(o,e){N("tutorial_complete",{step_id:o,...e})},tutorialSkip(o,e){N("tutorial_skip",{step_id:o,...e})},timerStart(o){o&&bn.set(o,Date.now())},timerEnd(o,e="custom",t){if(!o)return;let i=bn.get(o);if(!i)return;bn.delete(o);let n=Date.now()-i;if(!(!Number.isFinite(n)||n<0)){if(e==="custom"){N("engagement",{action:"timer",key:o,duration_ms:n,...t});return}N(e,{key:o,duration_ms:n,...t})}},fps(o,e){N("fps",{value:o,...e})},memory(o,e){N("memory",{bytes:o,...e})},assetLoadStart(o,e){N("asset_load_start",{asset_id:o,...e})},assetLoadComplete(o,e){N("asset_load_complete",{asset_id:o,...e})},reportError(o,e,t){N("error",{code:o,message:e,...t})},retry(){var o,e,t;if(rt())(o=window.gameRetry)==null||o.call(window);else if(kn()){let i=window.NUC;(t=(e=i==null?void 0:i.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}N("engagement",{action:"retry"})},pause(){Tt(!0)},resume(){ii(!0)},resize(o,e){qe(o,e)}},Ve=me;function $l(o){let e=2166136261;for(let t=0;t<o.length;t++)e^=o.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function Dl(o){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
2765
+ `,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 Ua=ds.version,kl=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"]);cs();var Xr={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"},Jr=Math.random().toString(36).slice(2),Ct=null,St={...Xr},Zr="web_embed",Wa={},Qt,qa=!1,Zt=!1,ti=!1,Qr=!1,Za=1,wn=0,En=!1,_e=!1,Et="",At=Math.floor(window.innerWidth),Lt=Math.floor(window.innerHeight),Ka=At>Lt,Oe=!1,ei=!1,Ur=!1,qr=!1,Va=!1,xn=null,at=null,Xa=!1,Ja=!1,vn=new Map;function eo(){if(!at)return null;let r=Date.now()-at;return!Number.isFinite(r)||r<0?null:r}function Ya(r){if(Xa)return;let e=eo();e!==null&&(Xa=!0,B("session_time",{duration_ms:e,reason:r}))}function Vr(){if(Ct)return Ct;let r=document.createElement("div");return r.id="handler-root",r.setAttribute("data-handler-root","true"),document.body.appendChild(r),Ct=r,r}function Sn(r){switch(r){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return r}}function to(r,e){return{event_name:r,ts:Date.now(),session_id:Jr,deployment_id:St.deployment_id,variant_id:St.variant_id,export_profile_id:St.profile_id,instance_id:St.instance_id||"default",env:Zr==="mraid"?"mraid":"web",attribution:Qt,payload:e}}function B(r,e){let t=Sn(r),i=to(t,e);Tn(i,!!Wa.analytics),ri(t,i),t!==r&&ri(r,i)}function ii(){xn&&(xn(At,Lt),xn=null)}function Tt(r){Za=r,B("volume",r)}function It(r){r&&(Qr=!0),!ti&&(ti=!0,B("pause"),Tt(0))}function ni(r){!r&&Qr||ti&&(ti=!1,B("resume"),Tt(Za))}function Ve(r,e){At=Math.floor(r||window.innerWidth),Lt=Math.floor(e||window.innerHeight),Ka=At>Lt,B("resize",{width:At,height:Lt})}function Pl(){if(Ss())try{let r=mraid.getMaxSize();Ve(r.width,r.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?ni():It()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();Ve(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();Tt(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&Tt(t>0?1:0)}),mraid.addEventListener("error",(t,i)=>{console.warn("mraid error:",t,"action:",i)}),En=!0,mraid.isViewable()&&mraid.getState()!=="hidden")Oe=!0,B("boot"),B("view"),B("ready"),_e=!0,ii();else{let t=()=>{Oe=!0,B("boot"),B("view"),B("ready"),_e=!0,ii()};mraid.addEventListener("ready",t)}}catch(r){console.warn("MRAID hook skipped",r)}}function Ml(){if(Es())try{let r=dapi.getScreenSize();Ve(r.width,r.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?ni():It()}),dapi.addEventListener("adResized",t=>{let i=dapi.getScreenSize();Ve(t.width||i.width,t.height||i.height)});let e=dapi.getAudioVolume();if(Tt(e?1:0),dapi.addEventListener("audioVolumeChange",t=>Tt(t?1:0)),En=!0,dapi.isViewable())Oe=!0,B("boot"),B("view"),B("ready"),_e=!0,ii();else{let t=()=>{Oe=!0,B("boot"),B("view"),B("ready"),_e=!0,ii()};dapi.addEventListener("ready",t)}}catch(r){console.warn("DAPI hook skipped",r)}}function Yr(){let r=()=>{Oe||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(Oe=!0,B("boot"),B("view"),B("ready"),_e=!0,ii(),ei&&(ei=!1,be.start()))};window.addEventListener("resize",()=>Ve()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(ni(),r()):It()}),document.readyState==="complete"||document.readyState==="interactive"?r():window.addEventListener("load",r),En=!0}function jl(){let r=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Ur=!0),!(Ur&&e instanceof MouseEvent)&&(wn+=1,Ja||(Ja=!0,B("first_interaction",{count:wn})),B("interaction",wn))};document.addEventListener("mousedown",r),document.addEventListener("touchstart",r)}function Wr(r){var i,n,a,s,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(r||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(ct())(a=(n=window.TJ_API)==null?void 0:n.click)==null||a.call(n);else if(Cs())(o=(s=window.FbPlayableAd)==null?void 0:s.onCTAClick)==null||o.call(s);else if(Is())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(Ts())try{(p=(d=window.smxTracking)==null?void 0:d.redirect)==null||p.call(d)}catch(f){console.warn("Smadex redirect failed",f)}else if(As()){let f=window.ExitApi;f&&typeof f.exit=="function"?f.exit(r||Et||""):r&&window.open(r)}else lt()?(u=window.install)==null||u.call(window):Ls()?(g=window.openAppStore)==null||g.call(window):In()?(h=parent==null?void 0:parent.postMessage)==null||h.call(parent,"download","*"):r&&window.open(r)}function _l(){let r=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let i=new Image;i.src=t};if(r==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;ce("view",()=>e(t.mraid_viewable)),ce("start",()=>e(t.game_viewable)),ce("engagement",()=>e(t.engagement));let i=()=>e(t.complete);ce("complete",i),si("engagement",n=>{var a;((a=n==null?void 0:n.payload)==null?void 0:a.count)>3&&i()}),ce("cta_click",()=>e(t.click))}else if(r==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;ce("view",()=>e(t.Ad_Load_Start)),ce("start",()=>e(t.Ad_Viewable)),ce("engagement",()=>e(t.First_Engagement)),ce("complete",()=>e(t.Gameplay_Complete)),ce("cta_click",()=>e(t.DSP_Click)),ce("start",()=>{[5,10,15,20,25,30].forEach(i=>setTimeout(()=>e(t[`Spent_${i}_Seconds`]),i*1e3))})}}function Ol(){if(!ct())return;let r=window.TJ_API;r&&r.setPlayableAPI&&r.setPlayableAPI({skipAd:()=>{try{be.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function Kr(){var e,t,i;let r=window.TJ_API;(e=r==null?void 0:r.objectiveComplete)==null||e.call(r),(t=r==null?void 0:r.playableFinished)==null||t.call(r),(i=r==null?void 0:r.gameplayFinished)==null||i.call(r)}function Rl(){lt()&&(window.mintGameStart=()=>{ni(!0),Ve()},window.mintGameClose=()=>{It(!0)})}function zl(){if(!kn())return;let r=window.NUC;!r||!r.trigger||(be.on("cta_click",()=>{var e,t;return(t=(e=r.trigger).convert)==null?void 0:t.call(e,Et)}),be.on("complete",()=>{var e,t;return(t=(e=r.trigger).tryAgain)==null?void 0:t.call(e)}))}var be={init(r={},e){var t;if(Zr=r.profile||"web_embed",Wa=r.consent||{},St={...Xr,...r.ids||{}},Ct=r.rootEl||Ct,Qt=void 0,is((t=r.telemetry)!=null&&t.endpoint?r.telemetry:null),at=null,Xa=!1,Ja=!1,vn.clear(),Et=r.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(xn=e),B("init"),document.body.oncontextmenu=()=>!1,Vr(),Dl(Ct),ks(),Pl(),Ml(),!En){if(document.readyState==="complete")Yr();else if(!qr){qr=!0;let i=()=>{Yr(),window.removeEventListener("load",i),document.removeEventListener("DOMContentLoaded",i)};window.addEventListener("load",i),document.addEventListener("DOMContentLoaded",i)}}jl(),_l(),Ol(),Rl(),zl(),console.log(`%c @handler/playable-sdk %c v${Ua} `,"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;"),Oe&&!_e&&(B("boot"),B("view"),B("ready"),ei&&(ei=!1,be.start()),_e=!0),_e=Oe},getRoot(){return Vr()},get version(){return Ua},get maxWidth(){return At},get maxHeight(){return Lt},get isLandscape(){return Ka},get isReady(){return _e},get isStarted(){return qa},get isPaused(){return ti},get isFinished(){return Zt},get volume(){return Za},get interactions(){return wn},on(r,e){si(Sn(r),e)},off(r,e){Ln(Sn(r),e)},start(){var r,e;if(!qa){if(!Oe){ei=!0;return}if(qa=!0,at||(at=Date.now()),B("start"),Ve(),lt())It(),(r=window.gameReady)==null||r.call(window);else if(ct()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:Ka?"landscape":"portrait",buildID:Ua})}}},finish(){var r,e;Zt||(Zt=!0,B("complete"),Ya("complete"),lt()?(r=window.gameEnd)==null||r.call(window):In()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):ct()&&Kr())},install(r){if(!Zt){Zt=!0,ct()?(Kr(),setTimeout(()=>be.install(r),300)):(B("complete"),setTimeout(()=>be.install(r),0));return}Va||(Va=!0,setTimeout(()=>Va=!1,500),B("cta_click"),B("conversion"),Ya("cta"),Wr(r||Et))},emit(r,e){let t=Sn(r);if(!kl.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${r} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let i=to(t,e);Tn(i,!!Wa.analytics),ri(t,i)},gameStart(){be.start()},gameEnd(){be.finish()},ctaClick(r,e){B("cta_click",{url:r||Et,manual:!0}),(e==null?void 0:e.open)!==!1&&Wr(r||Et)},ctaShow(r){B("cta_show",r)},ctaDismiss(r){B("cta_dismiss",r)},getGameTimeMs(){return eo()},endSession(r="manual"){Ya(r)},setAttribution(r){Qt=r},abTest(r,e){if(!r)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($l(`${Jr}:${r}`))%e.length,i=e[t];return Qt={...Qt||{},experiment_id:r},St.variant_id=i,B("ab_assign",{experiment_id:r,variant_id:i}),i},levelStart(r,e){at||(at=Date.now()),B("level_start",{level_id:r,...e})},levelComplete(r,e){B("level_complete",{level_id:r,...e})},levelFail(r,e){B("level_fail",{level_id:r,...e})},checkpoint(r,e){B("checkpoint",{checkpoint_id:r,...e})},reward(r,e){B("reward",{reward_id:r,...e})},tutorialStart(r,e){B("tutorial_start",{step_id:r,...e})},tutorialComplete(r,e){B("tutorial_complete",{step_id:r,...e})},tutorialSkip(r,e){B("tutorial_skip",{step_id:r,...e})},timerStart(r){r&&vn.set(r,Date.now())},timerEnd(r,e="custom",t){if(!r)return;let i=vn.get(r);if(!i)return;vn.delete(r);let n=Date.now()-i;if(!(!Number.isFinite(n)||n<0)){if(e==="custom"){B("engagement",{action:"timer",key:r,duration_ms:n,...t});return}B(e,{key:r,duration_ms:n,...t})}},fps(r,e){B("fps",{value:r,...e})},memory(r,e){B("memory",{bytes:r,...e})},assetLoadStart(r,e){B("asset_load_start",{asset_id:r,...e})},assetLoadComplete(r,e){B("asset_load_complete",{asset_id:r,...e})},reportError(r,e,t){B("error",{code:r,message:e,...t})},retry(){var r,e,t;if(lt())(r=window.gameRetry)==null||r.call(window);else if(kn()){let i=window.NUC;(t=(e=i==null?void 0:i.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}B("engagement",{action:"retry"})},pause(){It(!0)},resume(){ni(!0)},resize(r,e){Ve(r,e)}},Ye=be;function $l(r){let e=2166136261;for(let t=0;t<r.length;t++)e^=r.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function Dl(r){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
2763
2766
  (function(){
2764
2767
  var events = ['touchstart','touchend','mousedown','keydown'];
2765
2768
  function unlock(){
@@ -2775,4 +2778,4 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
2775
2778
  }
2776
2779
  events.forEach(function(e){ document.addEventListener(e, unlock, false); });
2777
2780
  })();
2778
- `,o.appendChild(e)}0&&(module.exports={COLORS,ConfigWatcher,DebugPanel,DefaultReloadStrategy,Handler,PlayableLoadingScreen,PreviewShell,STROKE_WIDTH,THEME,applyConfigOverride,applyConfigOverrides,applyConfigsToDisk,applyDefaults,baseLottie,bootstrap,clearConfigOverrides,clearConfigOverridesForObject,configOverrideManager,createPreviewShell,deepClone,defaultPreset,deviceGroups,devicePresets,diffConfigs,exportConfigsAsJSON,getConfigOverrides,getConfigStateSummary,getOverrideMode,getPresetById,getPresetsByCategory,loadAllObjectConfigs,loadComponentSchemas,loadEngineConfig,loadGamePromptConfig,loadObjectCentricConfig,loadObjectConfig,loadSceneConfig,redoLastConfigChange,rehydrateObject,removeConfigOverride,resetToApplied,resetToOriginal,setBootstrapDependencies,setOverrideMode,setupHotReload,setupLiveEditBridge,toLegacyFormat,trackObjectCreation,trackObjectDeletion,undoLastConfigChange,validateObjectConfig});
2781
+ `,r.appendChild(e)}0&&(module.exports={COLORS,ConfigWatcher,DebugPanel,DefaultReloadStrategy,Handler,PlayableLoadingScreen,PreviewShell,STROKE_WIDTH,THEME,applyConfigOverride,applyConfigOverrides,applyConfigsToDisk,applyDefaults,baseLottie,bootstrap,clearConfigOverrides,clearConfigOverridesForObject,configOverrideManager,createPreviewShell,deepClone,defaultPreset,deviceGroups,devicePresets,diffConfigs,exportConfigsAsJSON,getConfigOverrides,getConfigStateSummary,getOverrideMode,getPresetById,getPresetsByCategory,loadAllObjectConfigs,loadComponentSchemas,loadEngineConfig,loadGamePromptConfig,loadObjectCentricConfig,loadObjectConfig,loadSceneConfig,redoLastConfigChange,rehydrateObject,removeConfigOverride,resetToApplied,resetToOriginal,setBootstrapDependencies,setOverrideMode,setupHotReload,setupLiveEditBridge,toLegacyFormat,trackObjectCreation,trackObjectDeletion,undoLastConfigChange,validateObjectConfig});