handler-playable-sdk 1.0.89 → 1.0.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-M4LZRZ6U.js → chunk-HCWFDISI.js} +45 -23
- package/dist/cli/brand-dna.mjs +1 -1
- package/dist/cli/canva-import.mjs +1 -1
- package/dist/cli/cleanup-assets.mjs +1 -1
- package/dist/cli/fix-scales.mjs +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/screen-helper.mjs +1 -1
- package/dist/cli/setup-library.mjs +1 -1
- package/dist/cli/student-helper/add-logic.mjs +1 -1
- package/dist/cli/student-helper/add-object.mjs +1 -1
- package/dist/cli/student-helper/arg-parsing.mjs +1 -1
- package/dist/cli/student-helper/asset-registry.mjs +1 -1
- package/dist/cli/student-helper/bullet-system.mjs +1 -1
- package/dist/cli/student-helper/collectable-system.mjs +1 -1
- package/dist/cli/student-helper/constants.mjs +1 -1
- package/dist/cli/student-helper/drag-snap-couples.mjs +1 -1
- package/dist/cli/student-helper/endgame-screen.mjs +1 -1
- package/dist/cli/student-helper/fs-io.mjs +1 -1
- package/dist/cli/student-helper/logic-defaults.mjs +1 -1
- package/dist/cli/student-helper/print-help.mjs +1 -1
- package/dist/cli/student-helper/prompts.mjs +1 -1
- package/dist/cli/student-helper/scratch-card.mjs +1 -1
- package/dist/cli/student-helper/screen-utils.mjs +1 -1
- package/dist/cli/student-helper/snippets.mjs +1 -1
- package/dist/cli/student-helper/start-screen.mjs +1 -1
- package/dist/cli/student-helper/swerve-collect.mjs +1 -1
- package/dist/cli/student-helper/tap-destroy.mjs +1 -1
- package/dist/cli/student-helper/template-packs.mjs +1 -1
- package/dist/cli/student-helper.mjs +1 -1
- package/dist/cli/sync-screens.mjs +1 -1
- package/dist/cli/validate-assets.mjs +1 -1
- package/dist/cli/validate.mjs +1 -1
- package/dist/index.cjs +141 -119
- package/dist/index.css +9 -2
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/pixi/index.cjs +36 -16
- package/dist/pixi/index.css +9 -2
- package/dist/pixi/index.js +1 -1
- package/dist/three/index.cjs +44 -24
- package/dist/three/index.css +9 -2
- package/dist/three/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as Wt,c as en,d as Ae,e as tn}from"./chunk-I5OOVR5U.js";import{i as Jt}from"./chunk-GVZ2445E.js";import{c as Ue,d as Kt,e as Ze,g as Na,h as nn,j as Fa,k as Ba,n as an,o as Xt,p as st,q as Ga,r as sn,s as Ua}from"./chunk-EFRB44UC.js";import{a as $r}from"./chunk-JXBG6UFL.js";import{Application as nl}from"pixi.js";var qe={};function Zt(o,e,t=!1){qe[o]||(qe[o]=[]),qe[o].push({fn:e,once:t})}function rn(o,e){if(qe[o]){if(!e){delete qe[o];return}qe[o]=qe[o].filter(t=>t.fn!==e)}}function Qt(o,...e){let t=qe[o];if(t)for(let i of[...t])i.fn(...e),i.once&&rn(o,i.fn)}function fe(o,e){Zt(o,e,!0)}var ne=null,ve=[],rt=null;function Ya(o){ne=o,ve=[],rt!==null&&(clearTimeout(rt),rt=null)}function Wa(){var o,e,t;return{endpoint:(ne==null?void 0:ne.endpoint)||"",transport:(ne==null?void 0:ne.transport)||"beacon",batchSize:(o=ne==null?void 0:ne.batchSize)!=null?o:10,flushIntervalMs:(e=ne==null?void 0:ne.flushIntervalMs)!=null?e:300,maxQueue:(t=ne==null?void 0:ne.maxQueue)!=null?t:200,debug:!!(ne!=null&&ne.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 on(o,e){let t=Wa();if(e&&t.endpoint){if(ve.push(o),ve.length>t.maxQueue&&(ve=ve.slice(ve.length-t.maxQueue)),ve.length>=t.batchSize){Va();return}rt===null&&(rt=window.setTimeout(()=>{rt=null,Va()},t.flushIntervalMs))}}async function Va(){let o=Wa();if(!o.endpoint||ve.length===0)return;let e=ve.splice(0,o.batchSize);await qa(o.endpoint,{events:e},o.transport,o.debug),ve.length>0&&await qa(o.endpoint,{events:ve.splice(0,o.batchSize)},o.transport,o.debug)}function Ka(o){return Math.max(0,Math.min(1,o))}function Hr(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 Tt(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function Nr(o,e){let t=o==null?void 0:o[e];return typeof t=="number"?t:0}function Xa(o,e,t){try{o[e]=t}catch{}}function Fr(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 Ja(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 Za(o,e){let t=Fr(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 Qa(){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=Tt();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 m=g.durationMs>0?h/g.durationMs:1,f=Ka(m),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(m),b-1):0;if(g.repeat>0&&m>=1){let L=m-y;f=Ka(L)}let w=g.ease(f);g.yoyo&&y%2===1&&(w=1-w);for(let L of g.props)Xa(g.target,L.key,L.from+(L.to-L.from)*w);g.scaleFrom&&g.scaleTo&&Ja(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(m>=b){s(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var L;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+((L=u==null?void 0:u.delayMsOverride)!=null?L:0)),m=Hr(p.ease),f=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 M of Object.keys(p)){if(y.has(M))continue;let I=p[M];typeof I=="number"&&w.push({key:M,from:Nr(d,M),to:I})}let v=Za(d,p);return{target:d,startMs:Tt(),delayMs:h,durationMs:g,ease:m,props:w,scaleFrom:v.from,scaleTo:v.to,repeat:f,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=Tt())},resume:()=>{var m;if(!u.paused)return;let g=(m=u.pauseAtMs)!=null?m:Tt(),h=Tt()-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"&&Xa(d,g,h)}let u=Za(d,p);u.to&&Ja(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=[],m=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},f=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 f({kind:"to",target:y,vars:w,atMs:m(v)}),b},fromTo(y,w,v,L){return f({kind:"fromTo",target:y,vars:v,from:w,atMs:m(L)}),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 es(){if(typeof window=="undefined")return;let o=window;if(!o.gsap)try{o.gsap=Qa()}catch{}}var ts={name:"handler-playable-sdk",version:"1.0.89",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 be=0,Gr=be++,is=be++,ns=be++,as=be++,ss=be++,rs=be++,os=be++,ls=be++,cs=be++,ds=be++,ps=be++,us=be++,Q=Gr;function gs(){return Q===is}function hs(){return Q===ns}function ms(){return Q===as}function fs(){return Q===ss}function ot(){return Q===rs}function lt(){return Q===os}function bs(){return Q===ls}function ys(){return Q===cs}function vs(){return Q===ds}function ln(){return Q===ps}function cn(){return Q===us}function ws(){let o=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(o==="mraid")try{mraid.getState(),Q=is;return}catch{}else if(o==="dapi")try{dapi.isReady(),Q=ns;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(Q=as)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(Q=ss)}catch{}else if(e==="mintegral")window.gameReady&&(Q=rs);else if(e==="tapjoy")window.TJ_API&&(Q=os);else if(e==="tiktok")window.openAppStore&&(Q=ls);else if(e==="smadex")try{window.smxTracking&&(Q=cs)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(Q=ds)}catch{}else e==="vungle"?Q=ps:(o==="nucleo"||e==="nucleo")&&(Q=us)}import dn from"lottie-web";var xs=dn;typeof window!="undefined"&&(window.lottie=dn,window.__baseLottie=dn);function ae(o,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(o,e);return`${o/i}:${e/i}`}var Il=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:ae(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:ae(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:ae(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:ae(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:ae(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:ae(360,780)}],jl=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:ae(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:ae(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:ae(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:ae(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:ae(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:ae(412,915)}],_l=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:ae(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:ae(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:ae(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:ae(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:ae(800,1280)}],pn=[{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:ae(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:ae(768,1024),mraidScale:.7}];var Ss=[...pn],Es=[{category:"playable",label:"Playable Ad",devices:pn}],un=pn[0];function ct(o){return Ss.find(e=>e.id===o)||un}function Ol(o){return Ss.filter(e=>e.category===o)}var Le=class{async updateProperty(e,t,i,n={}){var l,c,d,p,u,g,h,m,f,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(Ue({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||((m=v==null?void 0:v.continuousRotate)==null?void 0:m.enabled)===!0||((f=v==null?void 0:v.orbit)==null?void 0:f.enabled)===!0)){let I=window.applyEditableObjectConfig;if(typeof I=="function"){let P=window.__editableConfig,j=(w=(y=(b=P==null?void 0:P.objects)==null?void 0:b.get)==null?void 0:y.call(b,e))!=null?w:s;await I(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 L=window.__editableConfig,M=(d=(c=(l=L==null?void 0:L.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:s;await v(e,M),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 gn(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()=>{let s=n.result,r=o.category||"misc",c=`${(o.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")||"new_asset"}_uploaded`;try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:r,filename:`${c}.png`,data:s,overwrite:!0})})).json();if(!(p!=null&&p.success)){alert(`Upload failed: ${(p==null?void 0:p.error)||"Unknown error"}`);return}let u=window.addAssetToRegistry;typeof u=="function"&&u(r,`${c}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch{}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),await o.onApply(p.path)}catch(d){console.error("[QuickActionsBar] Upload error:",d),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var ei=class{constructor(){this.updateManager=new Le}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");gn({objectId:e,category:a,onApply:async r=>{var g,h;let l=window.applyAssetToSlot,c=this.getFilenameFromPath(r),d=/render\.asset\.path/i.test(t)||/\.(png|jpg|jpeg|gif|webp)$/i.test(r);typeof l=="function"&&c&&d&&await l(e,c,a),await this.updateManager.updateProperty(e,t,r);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)},500),window.dispatchEvent(new CustomEvent("inspector:refresh"))}})}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 Ur=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],qr=["environment","ui","character","system","backgrounds"],Vr=["bg","world","ui"],Cs={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}}},ti=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=`
|
|
1
|
+
import{a as Wt,c as en,d as Ae,e as tn}from"./chunk-I5OOVR5U.js";import{i as Jt}from"./chunk-GVZ2445E.js";import{c as Ue,d as Kt,e as Ze,g as Na,h as nn,j as Fa,k as Ba,n as an,o as Xt,p as st,q as Ga,r as sn,s as Ua}from"./chunk-EFRB44UC.js";import{a as $r}from"./chunk-JXBG6UFL.js";import{Application as nl}from"pixi.js";var qe={};function Zt(o,e,t=!1){qe[o]||(qe[o]=[]),qe[o].push({fn:e,once:t})}function rn(o,e){if(qe[o]){if(!e){delete qe[o];return}qe[o]=qe[o].filter(t=>t.fn!==e)}}function Qt(o,...e){let t=qe[o];if(t)for(let i of[...t])i.fn(...e),i.once&&rn(o,i.fn)}function fe(o,e){Zt(o,e,!0)}var ne=null,ve=[],rt=null;function Ya(o){ne=o,ve=[],rt!==null&&(clearTimeout(rt),rt=null)}function Wa(){var o,e,t;return{endpoint:(ne==null?void 0:ne.endpoint)||"",transport:(ne==null?void 0:ne.transport)||"beacon",batchSize:(o=ne==null?void 0:ne.batchSize)!=null?o:10,flushIntervalMs:(e=ne==null?void 0:ne.flushIntervalMs)!=null?e:300,maxQueue:(t=ne==null?void 0:ne.maxQueue)!=null?t:200,debug:!!(ne!=null&&ne.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 on(o,e){let t=Wa();if(e&&t.endpoint){if(ve.push(o),ve.length>t.maxQueue&&(ve=ve.slice(ve.length-t.maxQueue)),ve.length>=t.batchSize){Va();return}rt===null&&(rt=window.setTimeout(()=>{rt=null,Va()},t.flushIntervalMs))}}async function Va(){let o=Wa();if(!o.endpoint||ve.length===0)return;let e=ve.splice(0,o.batchSize);await qa(o.endpoint,{events:e},o.transport,o.debug),ve.length>0&&await qa(o.endpoint,{events:ve.splice(0,o.batchSize)},o.transport,o.debug)}function Ka(o){return Math.max(0,Math.min(1,o))}function Hr(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 Tt(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function Nr(o,e){let t=o==null?void 0:o[e];return typeof t=="number"?t:0}function Xa(o,e,t){try{o[e]=t}catch{}}function Fr(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 Ja(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 Za(o,e){let t=Fr(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 Qa(){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=Tt();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 m=g.durationMs>0?h/g.durationMs:1,f=Ka(m),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(m),b-1):0;if(g.repeat>0&&m>=1){let L=m-y;f=Ka(L)}let w=g.ease(f);g.yoyo&&y%2===1&&(w=1-w);for(let L of g.props)Xa(g.target,L.key,L.from+(L.to-L.from)*w);g.scaleFrom&&g.scaleTo&&Ja(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(m>=b){s(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var L;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+((L=u==null?void 0:u.delayMsOverride)!=null?L:0)),m=Hr(p.ease),f=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 M of Object.keys(p)){if(y.has(M))continue;let I=p[M];typeof I=="number"&&w.push({key:M,from:Nr(d,M),to:I})}let v=Za(d,p);return{target:d,startMs:Tt(),delayMs:h,durationMs:g,ease:m,props:w,scaleFrom:v.from,scaleTo:v.to,repeat:f,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=Tt())},resume:()=>{var m;if(!u.paused)return;let g=(m=u.pauseAtMs)!=null?m:Tt(),h=Tt()-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"&&Xa(d,g,h)}let u=Za(d,p);u.to&&Ja(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=[],m=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},f=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 f({kind:"to",target:y,vars:w,atMs:m(v)}),b},fromTo(y,w,v,L){return f({kind:"fromTo",target:y,vars:v,from:w,atMs:m(L)}),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 es(){if(typeof window=="undefined")return;let o=window;if(!o.gsap)try{o.gsap=Qa()}catch{}}var ts={name:"handler-playable-sdk",version:"1.0.91",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 be=0,Gr=be++,is=be++,ns=be++,as=be++,ss=be++,rs=be++,os=be++,ls=be++,cs=be++,ds=be++,ps=be++,us=be++,Q=Gr;function gs(){return Q===is}function hs(){return Q===ns}function ms(){return Q===as}function fs(){return Q===ss}function ot(){return Q===rs}function lt(){return Q===os}function bs(){return Q===ls}function ys(){return Q===cs}function vs(){return Q===ds}function ln(){return Q===ps}function cn(){return Q===us}function ws(){let o=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(o==="mraid")try{mraid.getState(),Q=is;return}catch{}else if(o==="dapi")try{dapi.isReady(),Q=ns;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(Q=as)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(Q=ss)}catch{}else if(e==="mintegral")window.gameReady&&(Q=rs);else if(e==="tapjoy")window.TJ_API&&(Q=os);else if(e==="tiktok")window.openAppStore&&(Q=ls);else if(e==="smadex")try{window.smxTracking&&(Q=cs)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(Q=ds)}catch{}else e==="vungle"?Q=ps:(o==="nucleo"||e==="nucleo")&&(Q=us)}import dn from"lottie-web";var xs=dn;typeof window!="undefined"&&(window.lottie=dn,window.__baseLottie=dn);function ae(o,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(o,e);return`${o/i}:${e/i}`}var Il=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:ae(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:ae(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:ae(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:ae(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:ae(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:ae(360,780)}],jl=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:ae(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:ae(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:ae(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:ae(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:ae(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:ae(412,915)}],_l=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:ae(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:ae(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:ae(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:ae(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:ae(800,1280)}],pn=[{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:ae(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:ae(768,1024),mraidScale:.7}];var Ss=[...pn],Es=[{category:"playable",label:"Playable Ad",devices:pn}],un=pn[0];function ct(o){return Ss.find(e=>e.id===o)||un}function Ol(o){return Ss.filter(e=>e.category===o)}var Le=class{async updateProperty(e,t,i,n={}){var l,c,d,p,u,g,h,m,f,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(Ue({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||((m=v==null?void 0:v.continuousRotate)==null?void 0:m.enabled)===!0||((f=v==null?void 0:v.orbit)==null?void 0:f.enabled)===!0)){let I=window.applyEditableObjectConfig;if(typeof I=="function"){let P=window.__editableConfig,j=(w=(y=(b=P==null?void 0:P.objects)==null?void 0:b.get)==null?void 0:y.call(b,e))!=null?w:s;await I(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 L=window.__editableConfig,M=(d=(c=(l=L==null?void 0:L.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:s;await v(e,M),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 gn(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()=>{let s=n.result,r=o.category||"misc",c=`${(o.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")||"new_asset"}_uploaded`;try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:r,filename:`${c}.png`,data:s,overwrite:!0})})).json();if(!(p!=null&&p.success)){alert(`Upload failed: ${(p==null?void 0:p.error)||"Unknown error"}`);return}let u=window.addAssetToRegistry;typeof u=="function"&&u(r,`${c}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch{}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),await o.onApply(p.path)}catch(d){console.error("[QuickActionsBar] Upload error:",d),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var ei=class{constructor(){this.updateManager=new Le}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");gn({objectId:e,category:a,onApply:async r=>{var g,h;let l=window.applyAssetToSlot,c=this.getFilenameFromPath(r),d=/render\.asset\.path/i.test(t)||/\.(png|jpg|jpeg|gif|webp)$/i.test(r);typeof l=="function"&&c&&d&&await l(e,c,a),await this.updateManager.updateProperty(e,t,r);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)},500),window.dispatchEvent(new CustomEvent("inspector:refresh"))}})}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 Ur=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],qr=["environment","ui","character","system","backgrounds"],Vr=["bg","world","ui"],Cs={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}}},ti=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=`
|
|
2
2
|
<div class="wizard-card">
|
|
3
3
|
<div class="wizard-header">
|
|
4
4
|
<div class="wizard-title">
|
|
@@ -259,19 +259,21 @@ import{a as Wt,c as en,d as Ae,e as tn}from"./chunk-I5OOVR5U.js";import{i as Jt}
|
|
|
259
259
|
</div>
|
|
260
260
|
`});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(`
|
|
261
261
|
`)):(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(`
|
|
262
|
-
`))||(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 dt=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(){
|
|
262
|
+
`))||(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 dt=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=`
|
|
263
263
|
<div class="context-menu-item" data-action="add-logic">\u2699\uFE0F Add Logic</div>
|
|
264
264
|
<div class="context-menu-separator"></div>
|
|
265
|
-
<div class="context-menu-item
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
<div class="context-menu-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
265
|
+
<div class="context-menu-item-wrapper">
|
|
266
|
+
<div class="context-menu-item has-submenu" data-action="image-menu">
|
|
267
|
+
\u{1F5BC}\uFE0F Image
|
|
268
|
+
<span class="context-menu-arrow">\u25B6</span>
|
|
269
|
+
</div>
|
|
270
|
+
<div class="context-menu-submenu" data-submenu="image-menu">
|
|
271
|
+
<div class="context-menu-item" data-action="change-image">\u{1F504} Change Image</div>
|
|
272
|
+
<div class="context-menu-item" data-action="edit-image-crop">\u2702\uFE0F Edit Image (Crop/Move)</div>
|
|
273
|
+
<div class="context-menu-item" data-action="edit-image-ai">\u2728 Edit Image with AI</div>
|
|
274
|
+
<div class="context-menu-item" data-action="upload-image">\u{1F4E4} Upload Image</div>
|
|
275
|
+
<div class="context-menu-item" data-action="go-to-library">\u{1F4DA} Go to Library</div>
|
|
276
|
+
</div>
|
|
275
277
|
</div>
|
|
276
278
|
<div class="context-menu-separator"></div>
|
|
277
279
|
<div class="context-menu-item" data-action="duplicate">\u{1F4CB} Duplicate</div>
|
|
@@ -282,7 +284,7 @@ import{a as Wt,c as en,d as Ae,e as tn}from"./chunk-I5OOVR5U.js";import{i as Jt}
|
|
|
282
284
|
<div class="context-menu-item" data-action="inspect">\u{1F50D} Open in Inspector</div>
|
|
283
285
|
<div class="context-menu-separator"></div>
|
|
284
286
|
<div class="context-menu-item danger" data-action="delete">\u{1F5D1}\uFE0F Delete</div>
|
|
285
|
-
`,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"]');e&&t&&
|
|
287
|
+
`,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?
|
|
286
288
|
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(`
|
|
287
289
|
`))||(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(`
|
|
288
290
|
`))||(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(`
|
|
@@ -2124,7 +2126,22 @@ ADDITIONAL RULES/NOTES:
|
|
|
2124
2126
|
${o}`:""}
|
|
2125
2127
|
`.trim()}function pr(){let o=[],e="",t=null;return{async addSources(i){let n=[];for(let a of i){let s=await Mo(a),r=Io(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=jo(n),r=o.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Ti(i,s,r,{model:a}),c=e,d=[],p=l.split(`
|
|
2126
2128
|
`);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(`
|
|
2127
|
-
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 tt="handler_api_key_";var ht=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${tt}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${tt}${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=`${tt}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${tt}${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(tt)){let n=i.substring(tt.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(tt)&&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}}},Hn=()=>ht.getKey("gemini"),Nn=(o,e)=>ht.setKey("gemini",o,e),_o=()=>ht.hasKey("gemini");window.ApiKeyStorage=ht;window.getGeminiApiKey=Hn;window.setGeminiApiKey=Nn;window.hasGeminiApiKey=_o;var Bn=class{constructor(){this.modal=null;this.options=null;this.analyzer=pr();this.currentPrompt="";this.isGenerating=!1;this.generatedImages=[];this.selectedImageIndex=-1;this.promptInput=null;this.generateBtn=null;this.loadingEl=null;this.galleryEl=null;this.previewEl=null}open(e){this.options=e,this.currentPrompt=e.initialPrompt||"",this.generatedImages=[],this.selectedImageIndex=-1,this.isGenerating=!1,this.createModal(),document.body.appendChild(this.modal),setTimeout(()=>{var t,i;(t=this.promptInput)==null||t.focus(),(i=this.promptInput)==null||i.select()},100)}createModal(){var t;let e=document.createElement("div");e.className="ai-modal",e.innerHTML=`
|
|
2129
|
+
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 tt="handler_api_key_";var ht=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${tt}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${tt}${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=`${tt}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${tt}${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(tt)){let n=i.substring(tt.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(tt)&&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}}},Hn=()=>ht.getKey("gemini"),Nn=(o,e)=>ht.setKey("gemini",o,e),_o=()=>ht.hasKey("gemini");window.ApiKeyStorage=ht;window.getGeminiApiKey=Hn;window.setGeminiApiKey=Nn;window.hasGeminiApiKey=_o;var Bn=class{constructor(){this.modal=null;this.options=null;this.analyzer=pr();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=`
|
|
2130
|
+
<style>
|
|
2131
|
+
.ai-gallery-item {
|
|
2132
|
+
position: relative;
|
|
2133
|
+
}
|
|
2134
|
+
.ai-gallery-saved {
|
|
2135
|
+
position: absolute;
|
|
2136
|
+
top: 4px;
|
|
2137
|
+
right: 4px;
|
|
2138
|
+
font-size: 14px;
|
|
2139
|
+
background: rgba(0, 0, 0, 0.6);
|
|
2140
|
+
border-radius: 4px;
|
|
2141
|
+
padding: 2px 4px;
|
|
2142
|
+
pointer-events: none;
|
|
2143
|
+
}
|
|
2144
|
+
</style>
|
|
2128
2145
|
<div class="ai-modal-card">
|
|
2129
2146
|
<div class="ai-modal-header">
|
|
2130
2147
|
<div class="ai-modal-actions">
|
|
@@ -2196,21 +2213,26 @@ Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0
|
|
|
2196
2213
|
</div>
|
|
2197
2214
|
</div>
|
|
2198
2215
|
|
|
2216
|
+
<!-- STATUS MESSAGE -->
|
|
2217
|
+
<div class="ai-status" data-status style="padding: 8px 16px; font-size: 12px; color: #888; text-align: center;"></div>
|
|
2218
|
+
|
|
2199
2219
|
<!-- ACTION BUTTONS -->
|
|
2200
2220
|
<div class="ai-modal-actions">
|
|
2201
2221
|
<button class="ai-btn" data-action="cancel">Cancel</button>
|
|
2202
2222
|
<button class="ai-btn" data-action="generate" disabled>Generate</button>
|
|
2223
|
+
<button class="ai-btn success" data-action="save-library" disabled>\u{1F4BE} Save to Library</button>
|
|
2203
2224
|
<button class="ai-btn primary" data-action="apply" disabled>Apply</button>
|
|
2204
2225
|
</div>
|
|
2205
2226
|
</div>
|
|
2206
|
-
`,this.modal=e,this.attachEventListeners(),this.updatePromptFromDna()}attachEventListeners(){var i;if(!this.modal)return;this.promptInput=this.modal.querySelector(".ai-textarea"),this.generateBtn=this.modal.querySelector('[data-action="generate"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),(i=this.promptInput)==null||i.addEventListener("input",()=>{var n;this.currentPrompt=((n=this.promptInput)==null?void 0:n.value)||"",this.updateGenerateButton()});let e=this.modal.querySelector('[data-strength="creativity"]'),t=this.modal.querySelector(".ai-strength-value");e==null||e.addEventListener("input",()=>{t.textContent=e.value}),this.modal.addEventListener("click",n=>{var 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"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()}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}
|
|
2227
|
+
`,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}
|
|
2207
2228
|
|
|
2208
|
-
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 ki(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 ut(a,this.currentPrompt,s,{aspectRatio:"1:1"}),l=await pt(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)
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2229
|
+
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 ki(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 ut(a,this.currentPrompt,s,{aspectRatio:"1:1"}),l=await pt(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`
|
|
2230
|
+
<div class="ai-gallery-item ${i===this.selectedImageIndex?"active":""}" data-index="${i}">
|
|
2231
|
+
<img class="ai-gallery-thumb" src="${t}" alt="Generated ${i+1}" />
|
|
2232
|
+
<div class="ai-gallery-label">#${i+1}${n?" \u2713":""}</div>
|
|
2233
|
+
${n?`<div class="ai-gallery-saved" title="Saved: ${s}">\u{1F4BE}</div>`:""}
|
|
2234
|
+
</div>
|
|
2235
|
+
`}).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=Hn();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return Nn(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}},Fn=null;window.__openAiEditor=function(o,e,t,i){Fn||(Fn=new Bn),Fn.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"))}})};var Gn=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=`
|
|
2214
2236
|
<div class="asset-preview-card">
|
|
2215
2237
|
<div class="asset-preview-header">
|
|
2216
2238
|
<div class="asset-preview-title">${n}</div>
|
|
@@ -2237,7 +2259,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2237
2259
|
<source src="${n}" type="audio/wav">
|
|
2238
2260
|
Your browser does not support the audio element.
|
|
2239
2261
|
</audio>
|
|
2240
|
-
`;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&&import("./AssetEditorModal-N52QSFSY.js").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 Gn().open(o)};import{Application as Do,Container as $e,Graphics as de,Point as G,Rectangle as gr,Text as $o,TextStyle as Ho}from"pixi.js";import{Sprite as Oo,Container as ur}from"pixi.js";var Ro=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Un=Ro;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&&(Un=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Un}`))}}catch{}function zo(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 Te=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Un}`);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 m=new ur;return this.applyTransform(m,t==null?void 0:t.transform,t),m}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 en.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 Oo(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 ur)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let m=[n.path,`/assets/${n.path}`,`assets/${n.path}`,`../assets/${n.path}`],f=!1;for(let b of m)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),f=!0;break}}catch{continue}f||(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=zo(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 Gi=class{constructor(e){this.app=null;this.camera=new $e;this.bgContainer=new $e;this.mainContainer=new $e;this.uiContainer=new $e;this.gizmoLayer=new $e;this.screenFrame=new de;this.gameFrame=new de;this.gridLayer=new de;this.spawnPointLayer=new $e;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 de;this.anchorVisualizationLayer=new de;this.moveHandle=new de;this.scaleHandle=new de;this.rotateHandle=new de;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 de;this.lastPickPoint=null;this.lastPickIds=[];this.lastPickIndex=0;this.lastPickTime=0;this.playModeEnabled=!0;this.playModeInitialized=!1;this.layoutScale=1;this.updateManager=new Le;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 m=new G(h.x,h.y),f=this.getPickCandidates(m);if(f.length>0){let b=f[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 G(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),Ue({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 G(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 G(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,m=g.y+c;if(this.snapToGrid){let f=this.snapToGridPosition(h,m);h=f.x,m=f.y}u.displayObject.position.set(h,m),this.updateLiveConfigPositionForObject(p,h,m)}}}this.dragLastPointer=new G(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 G(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 G(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 G(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 Do,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 de,this.selectionBox.zIndex=99999,this.selectionBox.eventMode="none",this.gizmoLayer.addChild(this.selectionBox),this.dropZoneOverlay=new de,this.dropZoneOverlay.zIndex=99998,this.dropZoneOverlay.eventMode="none",this.gizmoLayer.addChild(this.dropZoneOverlay),this.alignmentGuideLayer=new de,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,m=Array.isArray(h)?h[0]:h.x||0,f=Array.isArray(h)?h[1]:h.y||0;Array.isArray(h)?p.transform.position=[m+20,f+20]:p.transform.position={x:m+20,y:f+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 G(n.x,n.y)),s=this.camera.toLocal(new G(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,m]of this.objectMap.entries()){if(h===e||!(m!=null&&m.displayObject)||m.displayObject.visible===!1)continue;let f=(g=(u=m.displayObject).getBounds)==null?void 0:g.call(u);if(!f)continue;let b=this.camera.toLocal(new G(f.x,f.y)),y=this.camera.toLocal(new G(f.x+f.width,f.y+f.height)),w=(b.x+y.x)/2,v=(b.y+y.y)/2;if(Math.abs(r-w)<c){let x=Math.min(a.y,b.y),E=Math.max(s.y,y.y);this.alignmentGuideLayer.moveTo(w,x),this.alignmentGuideLayer.lineTo(w,E),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}if(Math.abs(l-v)<c){let x=Math.min(a.x,b.x),E=Math.max(s.x,y.x);this.alignmentGuideLayer.moveTo(x,v),this.alignmentGuideLayer.lineTo(E,v),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}let L=a.x,M=s.x,I=a.y,P=s.y,j=b.x,_=y.x,T=b.y,S=y.y;if(Math.abs(L-j)<c||Math.abs(L-_)<c||Math.abs(M-j)<c||Math.abs(M-_)<c){let x=Math.abs(L-j)<c?j:Math.abs(L-_)<c?_:Math.abs(M-j)<c?j:_,E=Math.min(I,T),C=Math.max(P,S);this.alignmentGuideLayer.moveTo(x,E),this.alignmentGuideLayer.lineTo(x,C),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}if(Math.abs(I-T)<c||Math.abs(I-S)<c||Math.abs(P-T)<c||Math.abs(P-S)<c){let x=Math.abs(I-T)<c?T:Math.abs(I-S)<c?S:Math.abs(P-T)<c?T:S,E=Math.min(L,j),C=Math.max(M,_);this.alignmentGuideLayer.moveTo(E,x),this.alignmentGuideLayer.lineTo(C,x),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 _,T,S,x,E,C;if(t==null||i==null||t===i)return;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(_=n.transform)!=null?_:{};if(a.position_ratio!=null)return;let s=(T=this.getRuntimeScreenSize())!=null?T: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=we(s.width,s.height,t),g=we(s.width,s.height,i),h=u.x,m=u.y,f=g.x,b=g.y;l||(h=(u.x-s.width/2)/c,m=(u.y-s.height/2)/c,f=(g.x-s.width/2)/c,b=(g.y-s.height/2)/c);let y={x:d-h,y:p-m},w={x:d-f,y:p-b},v=a.offset,L=Array.isArray(v)?Number((S=v[0])!=null?S:0):Number((x=v==null?void 0:v.x)!=null?x:0),M=Array.isArray(v)?Number((E=v[1])!=null?E:0):Number((C=v==null?void 0:v.y)!=null?C:0),I=w.x-L,P=w.y-M,j=this.buildPositionValue(a,{x:I,y:P});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 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 m=Number((r=e.renderer.resolution)!=null?r:1)||1,f=Number((l=e.renderer.width)!=null?l:0)/m,b=Number((c=e.renderer.height)!=null?c:0)/m;if(Number.isFinite(f)&&f>0&&Number.isFinite(b)&&b>0)return{width:f,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,m,f,b,y,w,v,L,M,I,P,j,_,T,S,x,E,C,A,O,k,R,z,$,U;let e=window.__screenManager;if(e){let H=["gameplay","start","tutorial","endgame","loading"];for(let B of H){let D=(a=e.get)==null?void 0:a.call(e,B);if(D!=null&&D.visible){let q=(s=D.getContentLayer)==null?void 0:s.call(D);if(q){let Y=(r=D.x)!=null?r:0,W=(l=D.y)!=null?l:0,F=(c=q.x)!=null?c:0,te=(d=q.y)!=null?d:0,J=(u=(p=q.scale)==null?void 0:p.x)!=null?u:1,Z=(h=(g=q.scale)==null?void 0:g.y)!=null?h:J;return console.log("[SceneEditor] getRuntimeLayoutReference: using visible screen contentLayer",{screenId:B,contentLayerScale:{x:J,y:Z},position:{x:Y+F,y:W+te}}),{scale:{x:J,y:Z},position:{x:Y+F,y:W+te},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}for(let B of H){let D=(m=e.get)==null?void 0:m.call(e,B);if(D){if(!D.visible&&typeof D.updateLayout=="function"){let Y=window.gameApp;if((f=Y==null?void 0:Y.renderer)!=null&&f.screen){let W=Y.renderer.screen.width,F=Y.renderer.screen.height;W>0&&F>0&&D.updateLayout(W,F)}}let q=(b=D.getContentLayer)==null?void 0:b.call(D);if(q){let Y=(y=D.x)!=null?y:0,W=(w=D.y)!=null?w:0,F=(v=q.x)!=null?v:0,te=(L=q.y)!=null?L:0,J=(I=(M=q.scale)==null?void 0:M.x)!=null?I:1,Z=(j=(P=q.scale)==null?void 0:P.y)!=null?j:J;return console.log("[SceneEditor] getRuntimeLayoutReference: using any screen contentLayer",{screenId:B,visible:D.visible,contentLayerScale:{x:J,y:Z},position:{x:Y+F,y:W+te}}),{scale:{x:J,y:Z},position:{x:Y+F,y:W+te},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}}let t=window.__mainContainer;if(t){let H=(T=(_=t.scale)==null?void 0:_.x)!=null?T:1,B=(x=(S=t.scale)==null?void 0:S.y)!=null?x:H;return console.log("[SceneEditor] getRuntimeLayoutReference: using __mainContainer",{scale:{x:H,y:B},position:{x:(E=t.position)==null?void 0:E.x,y:(C=t.position)==null?void 0:C.y}}),t}let i=window.gameApp,n=(A=i==null?void 0:i.stage)!=null?A:null;if(n){let H=(k=(O=n.scale)==null?void 0:O.x)!=null?k:1,B=(z=(R=n.scale)==null?void 0:R.y)!=null?z:H;console.log("[SceneEditor] getRuntimeLayoutReference: using gameApp.stage (fallback)",{scale:{x:H,y:B},position:{x:($=n.position)==null?void 0:$.x,y:(U=n.position)==null?void 0:U.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 m of h){let f=(d=s.get)==null?void 0:d.call(s,m);if(!f)continue;let b=(u=(p=f.getBgLayer)==null?void 0:p.call(f))!=null?u:f.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,m;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 f=Number((g=(u=e.pivot)==null?void 0:u.x)!=null?g:0),b=Number((m=(h=e.pivot)==null?void 0:h.y)!=null?m:0);Number.isFinite(f)&&Number.isFinite(b)&&(this.mainContainer.pivot.set(f,b),this.uiContainer.pivot.set(f,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||this.applyTransformFromConfig(e,d.displayObject,t))}async createDisplayObject(e,t){var r,l,c,d,p,u,g,h,m,f,b,y,w,v,L;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 I=await Te.create(e,t,this.app);if(I instanceof $e)return I}}catch(M){console.warn("[SceneEditor] ObjectFactory failed for",e,M)}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 M=this.getScreen(),I=(p=M==null?void 0:M.width)!=null?p:0,P=(u=M==null?void 0:M.height)!=null?u:0,j=new de,_=this.parseColor(n.background_color,0),T=typeof n.background_alpha=="number"?n.background_alpha:1;I>0&&P>0&&j.rect(0,0,I,P).fill({color:_,alpha:T});let S=new $e;return S.addChild(j),S}if(a){let M=(h=(g=i==null?void 0:i.color)!=null?g:n==null?void 0:n.tint)!=null?h:"#ffffff",I=new Ho({fontFamily:"Arial, sans-serif",fontSize:(m=i==null?void 0:i.fontSize)!=null?m:16,fill:M,align:(f=i==null?void 0:i.align)!=null?f:"center",letterSpacing:(b=i==null?void 0:i.letterSpacing)!=null?b:0});return new $o({text:(y=i==null?void 0:i.text)!=null?y:"",style:I})}if((w=t==null?void 0:t.effects)!=null&&w.width||(v=t==null?void 0:t.effects)!=null&&v.height){let M=new de,I=typeof t.effects.width=="number"?t.effects.width:100,P=typeof t.effects.height=="number"?t.effects.height:100,j=(L=t.effects.fill_color)!=null?L:"#ffffff",_=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,T=Number.parseInt(String(j).replace("#",""),16);return M.rect(0,0,I,P).fill({color:Number.isFinite(T)?T:16777215,alpha:_}),M}return new $e}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 gr(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 I,P,j,_,T,S,x,E,C,A,O,k,R,z,$,U,H,B,D,q,Y;if(!t)return;let n=this.getScreen();if(!(n!=null&&n.width)||!(n!=null&&n.height))return;let a=(I=i==null?void 0:i.transform)!=null?I:{},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((P=l[0])!=null?P:0):Number((j=l==null?void 0:l.x)!=null?j:0),p=Array.isArray(l)?Number((_=l[1])!=null?_:0):Number((T=l==null?void 0:l.y)!=null?T:0),u=Array.isArray(c)?Number((S=c[0])!=null?S:0):Number((x=c==null?void 0:c.x)!=null?x:0),g=Array.isArray(c)?Number((E=c[1])!=null?E:0):Number((C=c==null?void 0:c.y)!=null?C:0),h=(Number.isFinite(d)?d:0)+(Number.isFinite(u)?u:0),m=(Number.isFinite(p)?p:0)+(Number.isFinite(g)?g:0);if(this.backgroundCoverEnabled&&this.isBackgroundObject(e,i,t)){let W=Number((O=(A=t==null?void 0:t.texture)==null?void 0:A.width)!=null?O:0),F=Number((R=(k=t==null?void 0:t.texture)==null?void 0:k.height)!=null?R:0);if(!Number.isFinite(W)||W<=0||!Number.isFinite(F)||F<=0){let re=(z=t==null?void 0:t.getLocalBounds)==null?void 0:z.call(t);W=Number(($=re==null?void 0:re.width)!=null?$:0),F=Number((U=re==null?void 0:re.height)!=null?U:0)}if(!Number.isFinite(W)||W<=0||!Number.isFinite(F)||F<=0)return;(H=t.anchor)!=null&&H.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 te=n.width/W,J=n.height/F,Z=Math.max(te,J);(D=t.scale)!=null&&D.set?t.scale.set(Z,Z):t.scale&&(t.scale.x=Z,t.scale.y=Z);let pe=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(pe);return}let f=r!=null?ze(n.width,n.height,r):we(n.width,n.height,s),b=this.getRuntimeScale(),y=(f.x-n.width/2)/b+h,w=(f.y-n.height/2)/b+m;(q=t.position)!=null&&q.set?t.position.set(y,w):t.position&&(t.position.x=y,t.position.y=w);let L=(typeof(a==null?void 0:a.scale)=="number"?a.scale:1)*this.getRuntimeScale();(Y=t.scale)!=null&&Y.set?t.scale.set(L,L):t.scale&&(t.scale.x=L,t.scale.y=L);let M=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(M)}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?ze(i.width,i.height,e.position_ratio):we(i.width,i.height,a!=null?a:n);if(t===this.bgContainer)return new G(s.x,s.y);let r=this.getRuntimeScale(),l=(s.x-i.width/2)/r,c=(s.y-i.height/2)/r;return new G(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,m=(n=(i=h==null?void 0:h.objects)==null?void 0:i.get)==null?void 0:n.call(i,e),f=(r=(a=m==null?void 0:m.transform)==null?void 0:a.anchor)!=null?r:(s=m==null?void 0:m.render)==null?void 0:s.anchor;if(f!=null&&f!=="")return f;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,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 m=Number((l=(r=u.scale)==null?void 0:r.x)!=null?l:1);Number.isFinite(m)&&m>0&&(this.layoutScale=m)}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 gr(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 G(0,0)),n=this.camera.toLocal(new G(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,m=Math.floor(r/g)*g;this.gridLayer.clear(),this.gridLayer.visible=!0;for(let f=h;f<=s;f+=u)this.gridLayer.moveTo(f,r),this.gridLayer.lineTo(f,l);for(let f=m;f<=l;f+=g)this.gridLayer.moveTo(a,f),this.gridLayer.lineTo(s,f);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),m=((i=h==null?void 0:h.getDisplayObject)==null?void 0:i.call(h))||(h==null?void 0:h.pixiObject)||h;if(!m)continue;let f=(a=(n=g.displayObject)==null?void 0:n.parent)!=null?a:this.mainContainer,b=new G;if(typeof m.getGlobalPosition=="function"){m.getGlobalPosition(b);let M=f.toLocal(b,this.camera);g.displayObject.position.set(M.x,M.y)}else if(m.worldTransform){b.set(m.worldTransform.tx,m.worldTransform.ty);let M=f.toLocal(b,this.camera);g.displayObject.position.set(M.x,M.y)}let y=this.getWorldScale(m);if(y){let M=Number((r=(s=f.scale)==null?void 0:s.x)!=null?r:1)||1,I=Number((c=(l=f.scale)==null?void 0:l.y)!=null?c:1)||1,P=y.x/M,j=y.y/I;(d=g.displayObject.scale)!=null&&d.set?g.displayObject.scale.set(P,j):g.displayObject.scale&&(g.displayObject.scale.x=P,g.displayObject.scale.y=j)}let w=this.getWorldRotation(m);if(typeof w=="number"){let M=f?f.rotation:0,I=w-M;g.displayObject.rotation=I;let P=this.getEditableObjectConfig(u);if(P){let j=(p=P.transform)!=null?p:{};P.transform||(P.transform=j);let _=this.toDegrees(I),T=typeof j.rotation=="number"?j.rotation:0;if(Math.abs(_-T)>.01){let S=Math.round(_*100)/100;j.rotation=S}}}let v=m.parent,L=typeof(v==null?void 0:v.getChildIndex)=="function"?v.getChildIndex(m):0;typeof m.zIndex=="number"?g.displayObject.zIndex=m.zIndex:Number.isFinite(L)&&(g.displayObject.zIndex=L)}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 m,f,b,y,w,v;if(!this.selectedId&&this.selectedIds.size===0||!this.isVisible){this.clearGizmos();return}if(this.selectedIds.size>1){let L=1/0,M=1/0,I=-1/0,P=-1/0,j=!1;for(let _ of this.selectedIds){let T=this.objectMap.get(_);if(!(T!=null&&T.displayObject))continue;let S=(f=(m=T.displayObject).getBounds)==null?void 0:f.call(m);if(!S||S.width<=0||S.height<=0)continue;let x=this.camera.toLocal(new G(S.x,S.y)),E=this.camera.toLocal(new G(S.x+S.width,S.y+S.height));L=Math.min(L,x.x,E.x),M=Math.min(M,x.y,E.y),I=Math.max(I,x.x,E.x),P=Math.max(P,x.y,E.y),j=!0}if(j){let _=I-L,T=P-M,S=L+_/2,x=M+T/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(L,M,_,T),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});for(let A of this.selectedIds){let O=this.objectMap.get(A);if(!(O!=null&&O.displayObject))continue;let k=(y=(b=O.displayObject).getBounds)==null?void 0:y.call(b);if(!k||k.width<=0||k.height<=0)continue;let R=this.camera.toLocal(new G(k.x,k.y)),z=this.camera.toLocal(new G(k.x+k.width,k.y+k.height)),$=z.x-R.x,U=z.y-R.y;this.gizmoOutline.rect(R.x,R.y,$,U),this.gizmoOutline.stroke({width:1,color:16752394,alpha:.5})}let E=7,C={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(S,x,E).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(C),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 G(t.x,t.y)),n=this.camera.toLocal(new G(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 de;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 G(e.x,e.y)),i=new G;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 G(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,m,f;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 G(r.x,r.y),this.dragStartPos=new G(i.displayObject.position.x,i.displayObject.position.y),this.dragLastPointer=new G(r.x,r.y),this.dragPointerOffset=new G(i.displayObject.position.x-r.x,i.displayObject.position.y-r.y),this.dragLogged=!1;let c=(m=this.getRuntimeScreenSize())!=null?m: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((f=i.displayObject.scale)==null?void 0:f.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 L,M,I,P,j,_,T,S;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(L=n.transform)!=null?L:{};n.transform||(n.transform=a);let s=(M=this.getRuntimeScreenSize())!=null?M:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let r=this.objectMap.get(e),l=((I=r==null?void 0:r.displayObject)==null?void 0:I.parent)===this.bgContainer,c=this.getPositioningAnchor(e,a),d=(a==null?void 0:a.position_ratio)!=null?ze(s.width,s.height,a.position_ratio):we(s.width,s.height,c),p=d.x,u=d.y,g=t,h=i;if(!l){let x=this.getRuntimeScale();p=(d.x-s.width/2)/x,u=(d.y-s.height/2)/x,g=t/x,h=i/x}let m=g-p,f=h-u,b=(P=a.offset)!=null?P:{x:0,y:0},y=Array.isArray(b)?Number((j=b[0])!=null?j:0):Number((_=b==null?void 0:b.x)!=null?_:0),w=Array.isArray(b)?Number((T=b[1])!=null?T:0):Number((S=b==null?void 0:b.y)!=null?S:0),v=this.buildPositionValue(a,{x:m-y,y:f-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 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),Ue({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 G(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 G(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 G(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 G;return t.toLocal(new G(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 G;return i.toLocal(new G(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 G(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 G(0,0)),t=this.camera.toLocal(new G(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(),m=this.getRuntimeScale(),f=(t.x-h.width/2)/m,b=(t.y-h.height/2)/m,y={identity:{id:d,category:r},transform:{anchor:"center",position:{x:f,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}`}}},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:r==="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=`
|
|
2262
|
+
`;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&&import("./AssetEditorModal-N52QSFSY.js").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 Gn().open(o)};import{Application as Do,Container as $e,Graphics as de,Point as G,Rectangle as gr,Text as $o,TextStyle as Ho}from"pixi.js";import{Sprite as Oo,Container as ur}from"pixi.js";var Ro=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Un=Ro;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&&(Un=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Un}`))}}catch{}function zo(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 Te=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Un}`);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 m=new ur;return this.applyTransform(m,t==null?void 0:t.transform,t),m}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 en.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 Oo(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 ur)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let m=[n.path,`/assets/${n.path}`,`assets/${n.path}`,`../assets/${n.path}`],f=!1;for(let b of m)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),f=!0;break}}catch{continue}f||(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=zo(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 Gi=class{constructor(e){this.app=null;this.camera=new $e;this.bgContainer=new $e;this.mainContainer=new $e;this.uiContainer=new $e;this.gizmoLayer=new $e;this.screenFrame=new de;this.gameFrame=new de;this.gridLayer=new de;this.spawnPointLayer=new $e;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 de;this.anchorVisualizationLayer=new de;this.moveHandle=new de;this.scaleHandle=new de;this.rotateHandle=new de;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 de;this.lastPickPoint=null;this.lastPickIds=[];this.lastPickIndex=0;this.lastPickTime=0;this.playModeEnabled=!0;this.playModeInitialized=!1;this.layoutScale=1;this.updateManager=new Le;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 m=new G(h.x,h.y),f=this.getPickCandidates(m);if(f.length>0){let b=f[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 G(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),Ue({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 G(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 G(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,m=g.y+c;if(this.snapToGrid){let f=this.snapToGridPosition(h,m);h=f.x,m=f.y}u.displayObject.position.set(h,m),this.updateLiveConfigPositionForObject(p,h,m)}}}this.dragLastPointer=new G(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 G(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 G(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 G(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 Do,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 de,this.selectionBox.zIndex=99999,this.selectionBox.eventMode="none",this.gizmoLayer.addChild(this.selectionBox),this.dropZoneOverlay=new de,this.dropZoneOverlay.zIndex=99998,this.dropZoneOverlay.eventMode="none",this.gizmoLayer.addChild(this.dropZoneOverlay),this.alignmentGuideLayer=new de,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,m=Array.isArray(h)?h[0]:h.x||0,f=Array.isArray(h)?h[1]:h.y||0;Array.isArray(h)?p.transform.position=[m+20,f+20]:p.transform.position={x:m+20,y:f+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 G(n.x,n.y)),s=this.camera.toLocal(new G(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,m]of this.objectMap.entries()){if(h===e||!(m!=null&&m.displayObject)||m.displayObject.visible===!1)continue;let f=(g=(u=m.displayObject).getBounds)==null?void 0:g.call(u);if(!f)continue;let b=this.camera.toLocal(new G(f.x,f.y)),y=this.camera.toLocal(new G(f.x+f.width,f.y+f.height)),w=(b.x+y.x)/2,v=(b.y+y.y)/2;if(Math.abs(r-w)<c){let x=Math.min(a.y,b.y),E=Math.max(s.y,y.y);this.alignmentGuideLayer.moveTo(w,x),this.alignmentGuideLayer.lineTo(w,E),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}if(Math.abs(l-v)<c){let x=Math.min(a.x,b.x),E=Math.max(s.x,y.x);this.alignmentGuideLayer.moveTo(x,v),this.alignmentGuideLayer.lineTo(E,v),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}let L=a.x,M=s.x,I=a.y,P=s.y,j=b.x,_=y.x,T=b.y,S=y.y;if(Math.abs(L-j)<c||Math.abs(L-_)<c||Math.abs(M-j)<c||Math.abs(M-_)<c){let x=Math.abs(L-j)<c?j:Math.abs(L-_)<c?_:Math.abs(M-j)<c?j:_,E=Math.min(I,T),C=Math.max(P,S);this.alignmentGuideLayer.moveTo(x,E),this.alignmentGuideLayer.lineTo(x,C),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}if(Math.abs(I-T)<c||Math.abs(I-S)<c||Math.abs(P-T)<c||Math.abs(P-S)<c){let x=Math.abs(I-T)<c?T:Math.abs(I-S)<c?S:Math.abs(P-T)<c?T:S,E=Math.min(L,j),C=Math.max(M,_);this.alignmentGuideLayer.moveTo(E,x),this.alignmentGuideLayer.lineTo(C,x),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 _,T,S,x,E,C;if(t==null||i==null||t===i)return;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(_=n.transform)!=null?_:{};if(a.position_ratio!=null)return;let s=(T=this.getRuntimeScreenSize())!=null?T: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=we(s.width,s.height,t),g=we(s.width,s.height,i),h=u.x,m=u.y,f=g.x,b=g.y;l||(h=(u.x-s.width/2)/c,m=(u.y-s.height/2)/c,f=(g.x-s.width/2)/c,b=(g.y-s.height/2)/c);let y={x:d-h,y:p-m},w={x:d-f,y:p-b},v=a.offset,L=Array.isArray(v)?Number((S=v[0])!=null?S:0):Number((x=v==null?void 0:v.x)!=null?x:0),M=Array.isArray(v)?Number((E=v[1])!=null?E:0):Number((C=v==null?void 0:v.y)!=null?C:0),I=w.x-L,P=w.y-M,j=this.buildPositionValue(a,{x:I,y:P});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 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 m=Number((r=e.renderer.resolution)!=null?r:1)||1,f=Number((l=e.renderer.width)!=null?l:0)/m,b=Number((c=e.renderer.height)!=null?c:0)/m;if(Number.isFinite(f)&&f>0&&Number.isFinite(b)&&b>0)return{width:f,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,m,f,b,y,w,v,L,M,I,P,j,_,T,S,x,E,C,A,O,k,R,z,$,U;let e=window.__screenManager;if(e){let H=["gameplay","start","tutorial","endgame","loading"];for(let B of H){let D=(a=e.get)==null?void 0:a.call(e,B);if(D!=null&&D.visible){let q=(s=D.getContentLayer)==null?void 0:s.call(D);if(q){let Y=(r=D.x)!=null?r:0,W=(l=D.y)!=null?l:0,F=(c=q.x)!=null?c:0,te=(d=q.y)!=null?d:0,J=(u=(p=q.scale)==null?void 0:p.x)!=null?u:1,Z=(h=(g=q.scale)==null?void 0:g.y)!=null?h:J;return console.log("[SceneEditor] getRuntimeLayoutReference: using visible screen contentLayer",{screenId:B,contentLayerScale:{x:J,y:Z},position:{x:Y+F,y:W+te}}),{scale:{x:J,y:Z},position:{x:Y+F,y:W+te},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}for(let B of H){let D=(m=e.get)==null?void 0:m.call(e,B);if(D){if(!D.visible&&typeof D.updateLayout=="function"){let Y=window.gameApp;if((f=Y==null?void 0:Y.renderer)!=null&&f.screen){let W=Y.renderer.screen.width,F=Y.renderer.screen.height;W>0&&F>0&&D.updateLayout(W,F)}}let q=(b=D.getContentLayer)==null?void 0:b.call(D);if(q){let Y=(y=D.x)!=null?y:0,W=(w=D.y)!=null?w:0,F=(v=q.x)!=null?v:0,te=(L=q.y)!=null?L:0,J=(I=(M=q.scale)==null?void 0:M.x)!=null?I:1,Z=(j=(P=q.scale)==null?void 0:P.y)!=null?j:J;return console.log("[SceneEditor] getRuntimeLayoutReference: using any screen contentLayer",{screenId:B,visible:D.visible,contentLayerScale:{x:J,y:Z},position:{x:Y+F,y:W+te}}),{scale:{x:J,y:Z},position:{x:Y+F,y:W+te},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}}let t=window.__mainContainer;if(t){let H=(T=(_=t.scale)==null?void 0:_.x)!=null?T:1,B=(x=(S=t.scale)==null?void 0:S.y)!=null?x:H;return console.log("[SceneEditor] getRuntimeLayoutReference: using __mainContainer",{scale:{x:H,y:B},position:{x:(E=t.position)==null?void 0:E.x,y:(C=t.position)==null?void 0:C.y}}),t}let i=window.gameApp,n=(A=i==null?void 0:i.stage)!=null?A:null;if(n){let H=(k=(O=n.scale)==null?void 0:O.x)!=null?k:1,B=(z=(R=n.scale)==null?void 0:R.y)!=null?z:H;console.log("[SceneEditor] getRuntimeLayoutReference: using gameApp.stage (fallback)",{scale:{x:H,y:B},position:{x:($=n.position)==null?void 0:$.x,y:(U=n.position)==null?void 0:U.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 m of h){let f=(d=s.get)==null?void 0:d.call(s,m);if(!f)continue;let b=(u=(p=f.getBgLayer)==null?void 0:p.call(f))!=null?u:f.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,m;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 f=Number((g=(u=e.pivot)==null?void 0:u.x)!=null?g:0),b=Number((m=(h=e.pivot)==null?void 0:h.y)!=null?m:0);Number.isFinite(f)&&Number.isFinite(b)&&(this.mainContainer.pivot.set(f,b),this.uiContainer.pivot.set(f,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,m,f,b,y,w,v,L;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 I=await Te.create(e,t,this.app);if(I instanceof $e)return I}}catch(M){console.warn("[SceneEditor] ObjectFactory failed for",e,M)}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 M=this.getScreen(),I=(p=M==null?void 0:M.width)!=null?p:0,P=(u=M==null?void 0:M.height)!=null?u:0,j=new de,_=this.parseColor(n.background_color,0),T=typeof n.background_alpha=="number"?n.background_alpha:1;I>0&&P>0&&j.rect(0,0,I,P).fill({color:_,alpha:T});let S=new $e;return S.addChild(j),S}if(a){let M=(h=(g=i==null?void 0:i.color)!=null?g:n==null?void 0:n.tint)!=null?h:"#ffffff",I=new Ho({fontFamily:"Arial, sans-serif",fontSize:(m=i==null?void 0:i.fontSize)!=null?m:16,fill:M,align:(f=i==null?void 0:i.align)!=null?f:"center",letterSpacing:(b=i==null?void 0:i.letterSpacing)!=null?b:0});return new $o({text:(y=i==null?void 0:i.text)!=null?y:"",style:I})}if((w=t==null?void 0:t.effects)!=null&&w.width||(v=t==null?void 0:t.effects)!=null&&v.height){let M=new de,I=typeof t.effects.width=="number"?t.effects.width:100,P=typeof t.effects.height=="number"?t.effects.height:100,j=(L=t.effects.fill_color)!=null?L:"#ffffff",_=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,T=Number.parseInt(String(j).replace("#",""),16);return M.rect(0,0,I,P).fill({color:Number.isFinite(T)?T:16777215,alpha:_}),M}return new $e}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 gr(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 I,P,j,_,T,S,x,E,C,A,O,k,R,z,$,U,H,B,D,q,Y;if(!t)return;let n=this.getScreen();if(!(n!=null&&n.width)||!(n!=null&&n.height))return;let a=(I=i==null?void 0:i.transform)!=null?I:{},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((P=l[0])!=null?P:0):Number((j=l==null?void 0:l.x)!=null?j:0),p=Array.isArray(l)?Number((_=l[1])!=null?_:0):Number((T=l==null?void 0:l.y)!=null?T:0),u=Array.isArray(c)?Number((S=c[0])!=null?S:0):Number((x=c==null?void 0:c.x)!=null?x:0),g=Array.isArray(c)?Number((E=c[1])!=null?E:0):Number((C=c==null?void 0:c.y)!=null?C:0),h=(Number.isFinite(d)?d:0)+(Number.isFinite(u)?u:0),m=(Number.isFinite(p)?p:0)+(Number.isFinite(g)?g:0);if(this.backgroundCoverEnabled&&this.isBackgroundObject(e,i,t)){let W=Number((O=(A=t==null?void 0:t.texture)==null?void 0:A.width)!=null?O:0),F=Number((R=(k=t==null?void 0:t.texture)==null?void 0:k.height)!=null?R:0);if(!Number.isFinite(W)||W<=0||!Number.isFinite(F)||F<=0){let re=(z=t==null?void 0:t.getLocalBounds)==null?void 0:z.call(t);W=Number(($=re==null?void 0:re.width)!=null?$:0),F=Number((U=re==null?void 0:re.height)!=null?U:0)}if(!Number.isFinite(W)||W<=0||!Number.isFinite(F)||F<=0)return;(H=t.anchor)!=null&&H.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 te=n.width/W,J=n.height/F,Z=Math.max(te,J);(D=t.scale)!=null&&D.set?t.scale.set(Z,Z):t.scale&&(t.scale.x=Z,t.scale.y=Z);let pe=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(pe);return}let f=r!=null?ze(n.width,n.height,r):we(n.width,n.height,s),b=this.getRuntimeScale(),y=(f.x-n.width/2)/b+h,w=(f.y-n.height/2)/b+m;(q=t.position)!=null&&q.set?t.position.set(y,w):t.position&&(t.position.x=y,t.position.y=w);let L=(typeof(a==null?void 0:a.scale)=="number"?a.scale:1)*this.getRuntimeScale();(Y=t.scale)!=null&&Y.set?t.scale.set(L,L):t.scale&&(t.scale.x=L,t.scale.y=L);let M=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(M)}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?ze(i.width,i.height,e.position_ratio):we(i.width,i.height,a!=null?a:n);if(t===this.bgContainer)return new G(s.x,s.y);let r=this.getRuntimeScale(),l=(s.x-i.width/2)/r,c=(s.y-i.height/2)/r;return new G(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,m=(n=(i=h==null?void 0:h.objects)==null?void 0:i.get)==null?void 0:n.call(i,e),f=(r=(a=m==null?void 0:m.transform)==null?void 0:a.anchor)!=null?r:(s=m==null?void 0:m.render)==null?void 0:s.anchor;if(f!=null&&f!=="")return f;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,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 m=Number((l=(r=u.scale)==null?void 0:r.x)!=null?l:1);Number.isFinite(m)&&m>0&&(this.layoutScale=m)}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 gr(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 G(0,0)),n=this.camera.toLocal(new G(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,m=Math.floor(r/g)*g;this.gridLayer.clear(),this.gridLayer.visible=!0;for(let f=h;f<=s;f+=u)this.gridLayer.moveTo(f,r),this.gridLayer.lineTo(f,l);for(let f=m;f<=l;f+=g)this.gridLayer.moveTo(a,f),this.gridLayer.lineTo(s,f);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),m=((i=h==null?void 0:h.getDisplayObject)==null?void 0:i.call(h))||(h==null?void 0:h.pixiObject)||h;if(!m)continue;let f=(a=(n=g.displayObject)==null?void 0:n.parent)!=null?a:this.mainContainer,b=new G;if(typeof m.getGlobalPosition=="function"){m.getGlobalPosition(b);let M=f.toLocal(b,this.camera);g.displayObject.position.set(M.x,M.y)}else if(m.worldTransform){b.set(m.worldTransform.tx,m.worldTransform.ty);let M=f.toLocal(b,this.camera);g.displayObject.position.set(M.x,M.y)}let y=this.getWorldScale(m);if(y){let M=Number((r=(s=f.scale)==null?void 0:s.x)!=null?r:1)||1,I=Number((c=(l=f.scale)==null?void 0:l.y)!=null?c:1)||1,P=y.x/M,j=y.y/I;(d=g.displayObject.scale)!=null&&d.set?g.displayObject.scale.set(P,j):g.displayObject.scale&&(g.displayObject.scale.x=P,g.displayObject.scale.y=j)}let w=this.getWorldRotation(m);if(typeof w=="number"){let M=f?f.rotation:0,I=w-M;g.displayObject.rotation=I;let P=this.getEditableObjectConfig(u);if(P){let j=(p=P.transform)!=null?p:{};P.transform||(P.transform=j);let _=this.toDegrees(I),T=typeof j.rotation=="number"?j.rotation:0;if(Math.abs(_-T)>.01){let S=Math.round(_*100)/100;j.rotation=S}}}let v=m.parent,L=typeof(v==null?void 0:v.getChildIndex)=="function"?v.getChildIndex(m):0;typeof m.zIndex=="number"?g.displayObject.zIndex=m.zIndex:Number.isFinite(L)&&(g.displayObject.zIndex=L)}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 m,f,b,y,w,v;if(!this.selectedId&&this.selectedIds.size===0||!this.isVisible){this.clearGizmos();return}if(this.selectedIds.size>1){let L=1/0,M=1/0,I=-1/0,P=-1/0,j=!1;for(let _ of this.selectedIds){let T=this.objectMap.get(_);if(!(T!=null&&T.displayObject))continue;let S=(f=(m=T.displayObject).getBounds)==null?void 0:f.call(m);if(!S||S.width<=0||S.height<=0)continue;let x=this.camera.toLocal(new G(S.x,S.y)),E=this.camera.toLocal(new G(S.x+S.width,S.y+S.height));L=Math.min(L,x.x,E.x),M=Math.min(M,x.y,E.y),I=Math.max(I,x.x,E.x),P=Math.max(P,x.y,E.y),j=!0}if(j){let _=I-L,T=P-M,S=L+_/2,x=M+T/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(L,M,_,T),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});for(let A of this.selectedIds){let O=this.objectMap.get(A);if(!(O!=null&&O.displayObject))continue;let k=(y=(b=O.displayObject).getBounds)==null?void 0:y.call(b);if(!k||k.width<=0||k.height<=0)continue;let R=this.camera.toLocal(new G(k.x,k.y)),z=this.camera.toLocal(new G(k.x+k.width,k.y+k.height)),$=z.x-R.x,U=z.y-R.y;this.gizmoOutline.rect(R.x,R.y,$,U),this.gizmoOutline.stroke({width:1,color:16752394,alpha:.5})}let E=7,C={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(S,x,E).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(C),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 G(t.x,t.y)),n=this.camera.toLocal(new G(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 de;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 G(e.x,e.y)),i=new G;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 G(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,m,f;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 G(r.x,r.y),this.dragStartPos=new G(i.displayObject.position.x,i.displayObject.position.y),this.dragLastPointer=new G(r.x,r.y),this.dragPointerOffset=new G(i.displayObject.position.x-r.x,i.displayObject.position.y-r.y),this.dragLogged=!1;let c=(m=this.getRuntimeScreenSize())!=null?m: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((f=i.displayObject.scale)==null?void 0:f.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 L,M,I,P,j,_,T,S;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(L=n.transform)!=null?L:{};n.transform||(n.transform=a);let s=(M=this.getRuntimeScreenSize())!=null?M:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let r=this.objectMap.get(e),l=((I=r==null?void 0:r.displayObject)==null?void 0:I.parent)===this.bgContainer,c=this.getPositioningAnchor(e,a),d=(a==null?void 0:a.position_ratio)!=null?ze(s.width,s.height,a.position_ratio):we(s.width,s.height,c),p=d.x,u=d.y,g=t,h=i;if(!l){let x=this.getRuntimeScale();p=(d.x-s.width/2)/x,u=(d.y-s.height/2)/x,g=t/x,h=i/x}let m=g-p,f=h-u,b=(P=a.offset)!=null?P:{x:0,y:0},y=Array.isArray(b)?Number((j=b[0])!=null?j:0):Number((_=b==null?void 0:b.x)!=null?_:0),w=Array.isArray(b)?Number((T=b[1])!=null?T:0):Number((S=b==null?void 0:b.y)!=null?S:0),v=this.buildPositionValue(a,{x:m-y,y:f-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 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),Ue({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 G(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 G(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 G(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 G;return t.toLocal(new G(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 G;return i.toLocal(new G(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 G(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 G(0,0)),t=this.camera.toLocal(new G(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(),m=this.getRuntimeScale(),f=(t.x-h.width/2)/m,b=(t.y-h.height/2)/m,y={identity:{id:d,category:r},transform:{anchor:"center",position:{x:f,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}`}}},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:r==="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=`
|
|
2241
2263
|
position: fixed;
|
|
2242
2264
|
top: 20px;
|
|
2243
2265
|
right: 20px;
|
|
@@ -2250,7 +2272,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2250
2272
|
font-family: system-ui, -apple-system, sans-serif;
|
|
2251
2273
|
font-size: 14px;
|
|
2252
2274
|
pointer-events: none;
|
|
2253
|
-
`,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 dt({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 qn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[ct("playable-portrait"),ct("iphone-14"),ct("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=ct(e.defaultDevice||un.id),this.debugPanel=new Bi,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 Gi({root:this.sceneRoot,getScreen:()=>this.getScreen()}),this.sceneEditor.mount(),this.applyDeviceFrameStyles(),this.setupCompareViewports(),this.setupConsoleInterceptor(),this.setupObserversAndListeners(),this.setupFrameDragging(),this.setupSpaceKeyListener(),this.setupShortcutListeners(),this.setupUnsavedChangesIndicator(),this.setupScenePaneInteractions(),this.updateSceneVisibility(),this.setDevice(this.currentPreset.id,{suppressCallback:!0}),this.updateDockState(),this.isInitialized=!0,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=ct(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=r=>{let l=r.clientY-i,c=Math.max(100,Math.min(800,n-l));e.style.height=`${c}px`;let d=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:d})},s=()=>{document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",s),e.classList.remove("resizing")};t.addEventListener("pointerdown",r=>{r.preventDefault(),i=r.clientY,n=e.offsetHeight,document.addEventListener("pointermove",a),document.addEventListener("pointerup",s),e.classList.add("resizing")})}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,m=p-g-200;return Math.max(200,m)},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 m=i==="left"?`${u}px`:g.style.gridTemplateColumns.split(" ")[0]||"300px",f=i==="right"?`${u}px`:g.style.gridTemplateColumns.split(" ")[2]||"350px",b=400;g.style.gridTemplateColumns=`${m} minmax(${b}px, 1fr) ${f}`}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&&et(this.scenePane,e,i!=null?i:this.previewContainer),t&&Hi(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=`
|
|
2275
|
+
`,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 dt({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 qn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[ct("playable-portrait"),ct("iphone-14"),ct("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=ct(e.defaultDevice||un.id),this.debugPanel=new Bi,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 Gi({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=ct(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,m=p-g-200;return Math.max(200,m)},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 m=i==="left"?`${u}px`:g.style.gridTemplateColumns.split(" ")[0]||"300px",f=i==="right"?`${u}px`:g.style.gridTemplateColumns.split(" ")[2]||"350px",b=400;g.style.gridTemplateColumns=`${m} minmax(${b}px, 1fr) ${f}`}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&&et(this.scenePane,e,i!=null?i:this.previewContainer),t&&Hi(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=`
|
|
2254
2276
|
<div class="preview-toolbar">
|
|
2255
2277
|
<div class="preview-toolbar-left">
|
|
2256
2278
|
<span class="preview-logo">PREVIEWER</span>
|