handler-playable-sdk 0.3.34 → 0.3.35
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/AssetEditorModal-FTOKF3XD.js +1 -0
- package/dist/AssetTextures-HOSCQNZW.js +1 -0
- package/dist/{ConfigOverride-C26KK6X2.js → ConfigOverride-RARXNEZC.js} +1 -1
- package/dist/chunk-OZZRT3XI.js +1626 -0
- package/dist/chunk-ZFQCFKYD.js +1 -0
- 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.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/{config-44AFSRES.js → config-4IWHAC43.js} +1 -1
- package/dist/index.cjs +290 -367
- package/dist/index.css +310 -0
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1 -1
- package/dist/pixi/index.cjs +35 -36
- package/dist/pixi/index.css +310 -0
- package/dist/pixi/index.js +1 -1
- package/dist/three/index.cjs +76 -77
- package/dist/three/index.css +310 -0
- package/dist/three/index.js +1 -1
- package/package.json +2 -1
- package/dist/AssetEditorModal-DBAGQINC.js +0 -1
- package/dist/AssetTextures-CWUQXU5Q.js +0 -1
- package/dist/chunk-PHSE57CN.js +0 -1703
- package/dist/chunk-Q7FPWOA3.js +0 -1
|
@@ -0,0 +1,1626 @@
|
|
|
1
|
+
import{c as Pi,d as ce,e as _i}from"./chunk-I5OOVR5U.js";import{i as It}from"./chunk-LV4HGC5G.js";import{c as lt,d as Rt,e as Mi,g as aa,h as Ri,j as Ii,k as ra,l as sa,m as Oi,n as ji,o as oa}from"./chunk-ZLL42OOV.js";import{a as Xr,b as Jr,c as Zr,d as Qr}from"./chunk-ZFQCFKYD.js";var Na={};Zr(Na,{makePanelDraggable:()=>Ui,makePanelResizable:()=>Gi});function Ui(a,e,t){let i=t!=null?t:a.offsetParent;if(!i)return;e.style.cursor="move";let n=0,r=0,s=0,o=0,l=!1,c=d=>{if(!l)return;let u=d.clientX-n,g=d.clientY-r;a.style.left=`${s+u}px`,a.style.top=`${o+g}px`},p=()=>{l&&(l=!1,window.removeEventListener("pointermove",c),window.removeEventListener("pointerup",p))};e.addEventListener("pointerdown",d=>{if(d.button!==0)return;let u=d.target;if(u!=null&&u.closest("button, input, select, textarea"))return;d.preventDefault();let g=a.getBoundingClientRect(),f=i.getBoundingClientRect();s=Math.max(0,g.left-f.left),o=Math.max(0,g.top-f.top);let h=g.width,m=g.height,b=f.width,y=f.height;s=Math.min(s,b-h),o=Math.min(o,y-m),n=d.clientX,r=d.clientY,a.style.left=`${s}px`,a.style.top=`${o}px`,a.style.right="auto",a.style.bottom="auto",a.style.zIndex=String(++rs);let v=a.getBoundingClientRect();(v.left<0||v.top<0||v.right>window.innerWidth||v.bottom>window.innerHeight)&&(a.style.left="16px",a.style.top="72px",a.style.right="auto",a.style.bottom="auto"),l=!0,window.addEventListener("pointermove",c),window.addEventListener("pointerup",p)})}function Gi(a,e,t){e.style.cursor="nwse-resize";let i=0,n=0,r=0,s=0,o=!1,l=p=>{if(!o)return;let d=p.clientX-r,u=p.clientY-s,g=Math.max(100,i+d),f=Math.max(100,n+u);a.style.width=`${g}px`,a.style.height=`${f}px`,t==null||t(g,f)},c=()=>{o&&(o=!1,window.removeEventListener("pointermove",l),window.removeEventListener("pointerup",c))};e.addEventListener("pointerdown",p=>{if(p.button!==0)return;p.preventDefault(),p.stopPropagation();let d=a.getBoundingClientRect();i=d.width,n=d.height,r=p.clientX,s=p.clientY,o=!0,window.addEventListener("pointermove",l),window.addEventListener("pointerup",c)})}var rs,qi=Jr(()=>{"use strict";rs=3e3});import{Application as Gs}from"pixi.js";var Ce={};function Ot(a,e,t=!1){Ce[a]||(Ce[a]=[]),Ce[a].push({fn:e,once:t})}function Di(a,e){if(Ce[a]){if(!e){delete Ce[a];return}Ce[a]=Ce[a].filter(t=>t.fn!==e)}}function jt(a,...e){let t=Ce[a];if(t)for(let i of[...t])i.fn(...e),i.once&&Di(a,i.fn)}function ee(a,e){Ot(a,e,!0)}var G=null,ae=[],Ne=null;function da(a){G=a,ae=[],Ne!==null&&(clearTimeout(Ne),Ne=null)}function pa(){var a,e,t;return{endpoint:(G==null?void 0:G.endpoint)||"",transport:(G==null?void 0:G.transport)||"beacon",batchSize:(a=G==null?void 0:G.batchSize)!=null?a:10,flushIntervalMs:(e=G==null?void 0:G.flushIntervalMs)!=null?e:300,maxQueue:(t=G==null?void 0:G.maxQueue)!=null?t:200,debug:!!(G!=null&&G.debug)}}async function la(a,e,t,i){let n=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let r=navigator.sendBeacon(a,new Blob([n],{type:"application/json"}));i&&console.log("[handler.telemetry] beacon",r,e);return}catch(r){i&&console.warn("[handler.telemetry] beacon failed, fallback to fetch",r)}try{await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}),i&&console.log("[handler.telemetry] fetch",e)}catch(r){i&&console.warn("[handler.telemetry] fetch failed",r)}}function zi(a,e){let t=pa();if(e&&t.endpoint){if(ae.push(a),ae.length>t.maxQueue&&(ae=ae.slice(ae.length-t.maxQueue)),ae.length>=t.batchSize){ca();return}Ne===null&&(Ne=window.setTimeout(()=>{Ne=null,ca()},t.flushIntervalMs))}}async function ca(){let a=pa();if(!a.endpoint||ae.length===0)return;let e=ae.splice(0,a.batchSize);await la(a.endpoint,{events:e},a.transport,a.debug),ae.length>0&&await la(a.endpoint,{events:ae.splice(0,a.batchSize)},a.transport,a.debug)}function ua(a){return Math.max(0,Math.min(1,a))}function es(a){let e=String(a!=null?a:"power2.out");if(e==="linear")return t=>t;if(e==="sine.inOut")return t=>.5-Math.cos(Math.PI*t)/2;if(e==="power2.out"||e==="easeOutQuad")return t=>1-(1-t)*(1-t);if(e.startsWith("back.out")){let t=e.match(/back\.out\(([\d.]+)\)/),i=t?Number(t[1]):1.8;return n=>1+(i+1)*Math.pow(n-1,3)+i*Math.pow(n-1,2)}return t=>1-(1-t)*(1-t)}function ct(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function ts(a,e){let t=a==null?void 0:a[e];return typeof t=="number"?t:0}function ga(a,e,t){try{a[e]=t}catch{}}function is(a){let e=a==null?void 0:a.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 ha(a,e){let t=a==null?void 0:a.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 fa(a,e){let t=is(a);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 ma(){let a=new Set,e=new WeakMap,t=null,i=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,o(),a.size>0&&i()})},n=p=>{var u;a.add(p);let d=(u=e.get(p.target))!=null?u:new Set;d.add(p),e.set(p.target,d),i()},r=p=>{a.delete(p);let d=e.get(p.target);d&&(d.delete(p),d.size===0&&e.delete(p.target))},s=p=>{p.killed||(p.killed=!0,r(p))},o=()=>{var d,u;let p=ct();for(let g of Array.from(a)){if(g.killed||g.paused)continue;let f=p-g.startMs-g.delayMs;if(f<0)continue;let h=g.durationMs>0?f/g.durationMs:1,m=ua(h),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(h),b-1):0;if(g.repeat>0&&h>=1){let w=h-y;m=ua(w)}let v=g.ease(m);g.yoyo&&y%2===1&&(v=1-v);for(let w of g.props)ga(g.target,w.key,w.from+(w.to-w.from)*v);g.scaleFrom&&g.scaleTo&&ha(g.target,{x:g.scaleFrom.x+(g.scaleTo.x-g.scaleFrom.x)*v,y:g.scaleFrom.y+(g.scaleTo.y-g.scaleFrom.y)*v});try{(d=g.onUpdate)==null||d.call(g)}catch{}if(h>=b){s(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(p,d,u)=>{var w;let g=Math.max(0,(typeof d.duration=="number"?d.duration:.5)*1e3),f=Math.max(0,(typeof d.delay=="number"?d.delay:0)*1e3+((w=u==null?void 0:u.delayMsOverride)!=null?w:0)),h=es(d.ease),m=typeof d.repeat=="number"?Math.max(0,d.repeat|0):0,b=d.yoyo===!0,y=new Set(["duration","delay","ease","repeat","yoyo","onUpdate","onComplete","scale","scaleX","scaleY"]),v=[];for(let C of Object.keys(d)){if(y.has(C))continue;let k=d[C];typeof k=="number"&&v.push({key:C,from:ts(p,C),to:k})}let x=fa(p,d);return{target:p,startMs:ct(),delayMs:f,durationMs:g,ease:h,props:v,scaleFrom:x.from,scaleTo:x.to,repeat:m,yoyo:b,onUpdate:typeof d.onUpdate=="function"?d.onUpdate:void 0,onComplete:typeof d.onComplete=="function"?d.onComplete:void 0,killed:!1,paused:!1,pauseAtMs:null}},c={to(p,d){let u=l(p,d);return n(u),{kill:()=>s(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=ct())},resume:()=>{var h;if(!u.paused)return;let g=(h=u.pauseAtMs)!=null?h:ct(),f=ct()-g;u.startMs+=f,u.paused=!1,u.pauseAtMs=null},isActive:()=>!u.killed&&!u.paused}},fromTo(p,d,u){return c.set(p,d),c.to(p,u)},set(p,d){if(!p||!d)return;for(let g of Object.keys(d)){let f=d[g];g==="scale"||g==="scaleX"||g==="scaleY"||typeof f=="number"&&ga(p,g,f)}let u=fa(p,d);u.to&&ha(p,u.to)},killTweensOf(p){let d=e.get(p);if(d)for(let u of Array.from(d))s(u)},timeline(p={}){let d=[],u=0,g=!1,f=[],h=y=>{if(typeof y=="number")return Math.max(0,y*1e3);let v=typeof y=="string"?y.trim():"";return v.startsWith("+=")?u+Math.max(0,Number(v.slice(2))*1e3||0):v?Math.max(0,Number(v)*1e3||0):u},m=y=>{d.push(y);let v=Math.max(0,(typeof y.vars.duration=="number"?y.vars.duration:.5)*1e3);u=Math.max(u,y.atMs+v)},b={to(y,v,x){return m({kind:"to",target:y,vars:v,atMs:h(x)}),b},fromTo(y,v,x,w){return m({kind:"fromTo",target:y,vars:x,from:v,atMs:h(w)}),b},play(){var y,v;if(g)return b;g=!0,f=[];for(let x of d)x.kind==="fromTo"&&c.set(x.target,(y=x.from)!=null?y:{}),f.push(c.to(x.target,{...x.vars,delay:x.atMs/1e3+((v=x.vars.delay)!=null?v:0)}));return b},pause(){for(let y of f)y.pause();return b},kill(){for(let y of f)y.kill();f=[],g=!1}};return p.paused||b.play(),b}};return c}function ba(){if(typeof window=="undefined")return;let a=window;if(!a.gsap)try{a.gsap=ma()}catch{}}var ya={name:"handler-playable-sdk",version:"0.3.35",type:"module",description:"Handler Playable SDK v0.1 with contract-aligned surface (root sandbox, canonical event envelope).",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./pixi":{types:"./dist/pixi/index.d.ts",import:"./dist/pixi/index.js",require:"./dist/pixi/index.cjs"},"./pixi/index.css":{import:"./dist/pixi/index.css",require:"./dist/pixi/index.css"},"./three":{types:"./dist/three/index.d.ts",import:"./dist/three/index.js",require:"./dist/three/index.cjs"},"./cli":{types:"./dist/cli/index.d.ts",import:"./dist/cli/index.js",require:"./dist/cli/index.cjs"}},bin:{"handler-student-helper":"./bin/student-helper.mjs","handler-validate":"./bin/validate.mjs","handler-sync-screens":"./bin/sync-screens.mjs","handler-brand-dna":"./bin/brand-dna.mjs","handler-setup-library":"./bin/setup-library.mjs","handler-screen-helper":"./bin/screen-helper.mjs"},scripts:{prebuild:"python3 src/preview/build-css.py",build:"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --minify --external lottie-web && npm run create-mjs-symlinks && npm run postbuild-cli && npm run obfuscate && npm run postbuild",postbuild:"python3 src/preview/copy-css-to-dist.py","postbuild-cli":"cp src/cli/*.mjs dist/cli/ && chmod +x dist/cli/*.mjs && chmod +x bin/*.mjs","create-mjs-symlinks":"cd dist && ln -sf index.js index.mjs && cd pixi && ln -sf index.js index.mjs && cd ../three && ln -sf index.js index.mjs","build:dev":"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --external lottie-web && npm run create-mjs-symlinks && npm run postbuild-cli",obfuscate:"javascript-obfuscator dist/pixi/index.js --output dist/pixi/index.js --config obfuscator.config.json && javascript-obfuscator dist/three/index.js --output dist/three/index.js --config obfuscator.config.json && javascript-obfuscator dist/cli/index.js --output dist/cli/index.js --config obfuscator.config.json && npm run obfuscate-cli","obfuscate-cli":'for file in dist/cli/*.mjs; do javascript-obfuscator "$file" --output "$file" --config obfuscator.config.json; done',lint:"eslint 'src/**/*.{ts,tsx}'",typecheck:"tsc --noEmit",prepublishOnly:"npm run build","publish:update":"node scripts/publish-and-update.cjs patch","publish:update:minor":"node scripts/publish-and-update.cjs minor","publish:update:major":"node scripts/publish-and-update.cjs major"},author:"Handler",license:"MIT",publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/HandlerAIGames/handler-playable-sdk.git"},files:["dist","bin","LICENSE","README.md"],peerDependencies:{"lottie-web":"^5.0.0","pixi.js":"^8.0.0",three:"^0.182.0"},peerDependenciesMeta:{"pixi.js":{optional:!0},three:{optional:!0},"lottie-web":{optional:!0}},devDependencies:{"@types/three":"^0.182.0",eslint:"^9.39.2","javascript-obfuscator":"^5.1.0","pixi.js":"8.8.1",three:"^0.182.0","ts-node":"^10.9.2",tsup:"^8.4.0",typescript:"^5.7.2","typescript-eslint":"^8.53.0"},dependencies:{"@google/genai":"^1.35.0","@google/generative-ai":"^0.24.1",jszip:"^3.10.1",sharp:"^0.34.5"}};var te=0,as=te++,va=te++,xa=te++,wa=te++,Ea=te++,Aa=te++,Sa=te++,Ca=te++,La=te++,Ta=te++,ka=te++,Pa=te++,N=as;function _a(){return N===va}function Ma(){return N===xa}function Ra(){return N===wa}function Ia(){return N===Ea}function Fe(){return N===Aa}function Ue(){return N===Sa}function Oa(){return N===Ca}function ja(){return N===La}function Da(){return N===Ta}function Hi(){return N===ka}function $i(){return N===Pa}function za(){let a=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(a==="mraid")try{mraid.getState(),N=va;return}catch{}else if(a==="dapi")try{dapi.isReady(),N=xa;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(N=wa)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(N=Ea)}catch{}else if(e==="mintegral")window.gameReady&&(N=Aa);else if(e==="tapjoy")window.TJ_API&&(N=Sa);else if(e==="tiktok")window.openAppStore&&(N=Ca);else if(e==="smadex")try{window.smxTracking&&(N=La)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(N=Ta)}catch{}else e==="vungle"?N=ka:(a==="nucleo"||e==="nucleo")&&(N=Pa)}import Bi from"lottie-web";var Ha=Bi;typeof window!="undefined"&&(window.lottie=Bi,window.__baseLottie=Bi);function q(a,e){let t=(n,r)=>r===0?n:t(r,n%r),i=t(a,e);return`${a/i}:${e/i}`}var Bo=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:q(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:q(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:q(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:q(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:q(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:q(360,780)}],No=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:q(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:q(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:q(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:q(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:q(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:q(412,915)}],Fo=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:q(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:q(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:q(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:q(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:q(800,1280)}],Ni=[{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:q(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:q(768,1024),mraidScale:.7}];var $a=[...Ni],Ba=[{category:"playable",label:"Playable Ad",devices:Ni}],Fi=Ni[0];function Ge(a){return $a.find(e=>e.id===a)||Fi}function Uo(a){return $a.filter(e=>e.category===a)}var Dt=class{constructor(){this.root=null;this.listContainer=null;this.searchInput=null;this.selectedId=null;this.options=null;this.retryTimer=null;this.screenFilter="all"}getScreenFilterStorageKey(){return`handler_preview_screen_filter::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}render(){return`
|
|
2
|
+
<div class="scene-panel scene-objects panel-accent-teal" data-panel="scene-objects" style="left:16px; top:72px;">
|
|
3
|
+
<div class="scene-panel-header" data-panel-handle>
|
|
4
|
+
<div class="panel-title">
|
|
5
|
+
<span class="panel-pill">Hierarchy</span>
|
|
6
|
+
<span class="panel-title-text">Scene Objects</span>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="scene-panel-actions">
|
|
9
|
+
<button class="scene-panel-toggle" type="button" data-panel-toggle>\u25BE</button>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="scene-breadcrumbs" data-breadcrumbs style="display: none;">
|
|
13
|
+
<span class="breadcrumb-item" data-breadcrumb-screen>\u2014</span>
|
|
14
|
+
<span class="breadcrumb-separator">\u203A</span>
|
|
15
|
+
<span class="breadcrumb-item" data-breadcrumb-object>\u2014</span>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="scene-panel-body">
|
|
18
|
+
<div class="scene-panel-search">
|
|
19
|
+
<input type="text" id="scene-object-search" placeholder="Search ids, tags, UI">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="scene-panel-filters">
|
|
22
|
+
<select id="scene-screen-filter" class="scene-screen-filter" title="Filter by screen">
|
|
23
|
+
<option value="all">All Screens</option>
|
|
24
|
+
<option value="loading">Loading</option>
|
|
25
|
+
<option value="start">Start</option>
|
|
26
|
+
<option value="gameplay">Gameplay</option>
|
|
27
|
+
<option value="tutorial">Tutorial</option>
|
|
28
|
+
<option value="endgame">Endgame</option>
|
|
29
|
+
</select>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="scene-object-list" data-object-list></div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
`}initialize(e,t){var n,r,s,o,l;this.options=t,this.root=e.querySelector('[data-panel="scene-objects"]'),this.listContainer=(n=this.root)==null?void 0:n.querySelector("[data-object-list]"),this.searchInput=(r=this.root)==null?void 0:r.querySelector("#scene-object-search"),(s=this.searchInput)==null||s.addEventListener("input",()=>this.refreshObjects());let i=(o=this.root)==null?void 0:o.querySelector("#scene-screen-filter");if(i){try{let c=window.localStorage.getItem(this.getScreenFilterStorageKey());c&&(this.screenFilter=c)}catch{}i.value=this.screenFilter;try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}i.addEventListener("change",()=>{let c=i.value||"all";this.screenFilter=c;try{window.localStorage.setItem(this.getScreenFilterStorageKey(),this.screenFilter)}catch{}try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}this.refreshObjects()})}(l=this.root)==null||l.addEventListener("click",c=>{let p=c.target;if(!p)return;let d=p.closest("[data-object-id]");if(!d)return;let u=d.dataset.objectId;u&&this.select(u)}),window.addEventListener("handler:screen-index-loaded",()=>this.refreshObjects())}setSelected(e){var s,o,l,c,p;if(this.selectedId=e,!this.listContainer)return;Array.from(this.listContainer.querySelectorAll("[data-object-id]")).forEach(d=>{d.classList.toggle("selected",d.dataset.objectId===e)});let i=(s=this.root)==null?void 0:s.querySelector("[data-breadcrumbs]"),n=(o=this.root)==null?void 0:o.querySelector("[data-breadcrumb-screen]"),r=(l=this.root)==null?void 0:l.querySelector("[data-breadcrumb-object]");if(i&&n&&r)if(e){let d=window.getEditableObjectConfig,u=typeof d=="function"?d(e):null;if(!u){let b=window.__editableObjectConfigs;b&&typeof b.get=="function"&&(u=(c=b.get(e))!=null?c:null)}let g=this.inferScreen(e,u),f={loading:"Loading",start:"Start",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},h=(((p=u==null?void 0:u.identity)==null?void 0:p.id)||e).toString(),m=this.formatDisplayName(h);n.textContent=f[g]||g,r.textContent=m,i.style.display="flex"}else i.style.display="none"}refreshObjects(){var p;if(!this.listContainer)return;let e=window.getEditableObjectList,t=window.getEditableObjectConfig,i=window.refreshEditableConfigIndex;if(typeof i=="function"&&i(),typeof e!="function"){this.scheduleRetry();return}let n=e();if(!Array.isArray(n)||n.length===0){let d=window.__editableObjectConfigs;d&&typeof d.keys=="function"&&(n=Array.from(d.keys()))}if(!Array.isArray(n)||n.length===0){this.scheduleRetry();return}let r=(((p=this.searchInput)==null?void 0:p.value)||"").trim().toLowerCase(),s=["loading","start","gameplay","tutorial","endgame"],o=Object.fromEntries(s.map(d=>[d,[]])),l=Object.fromEntries(s.map(d=>[d,[]]));n.forEach(d=>{var O,j,T,E;let u=typeof t=="function"?t(d):null;if(!u){let S=window.__editableObjectConfigs;S&&typeof S.get=="function"&&(u=(O=S.get(d))!=null?O:null)}let g=(((j=u==null?void 0:u.identity)==null?void 0:j.category)||"scene").toString(),f=(((T=u==null?void 0:u.identity)==null?void 0:T.id)||d).toString(),h=g.toLowerCase(),m=f.toLowerCase(),b=h.includes("ui")||m.startsWith("ui")||m.includes("label"),y=this.formatDisplayName(f||d),v=((E=u==null?void 0:u.render)==null?void 0:E.visible)===!1||(u==null?void 0:u.enabled)===!1,x=this.getObjectType(u),w={id:d,label:y,category:g,isUi:b,isUnused:v,objectType:x},C=this.inferScreen(w.id,u);if(this.screenFilter!=="all"&&C!==this.screenFilter||!(!r||w.id.toLowerCase().includes(r)||w.label.toLowerCase().includes(r)))return;(w.isUnused?l:o)[C].push(w)});let c={loading:"Loading Screen",start:"Start Screen",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"};this.listContainer.innerHTML=`
|
|
35
|
+
${s.map(d=>this.renderGroup(c[d],[...o[d],...l[d]])).join("")}
|
|
36
|
+
`,this.setSelected(this.selectedId)}formatDisplayName(e){let t=e.replace(/^json\./,"").replace(/^ui\./,"").replace(/_\d+$/,"").replace(/\./g," ").replace(/_/g," ");return t=t.split(" ").map(i=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join(" "),t}inferScreen(e,t){var o,l;let i=window.__HANDLER_SCREEN_INDEX,n=(o=i==null?void 0:i.instanceToScreen)==null?void 0:o[e];if(n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame")return n;let r=(((l=t==null?void 0:t.identity)==null?void 0:l.id)||"").toString(),s=`${e} ${r}`.toLowerCase();return s.includes("loading")?"loading":s.includes("start")?"start":s.includes("tutorial")?"tutorial":s.includes("endgame")||s.includes("end_card")||s.includes("endcard")?"endgame":"gameplay"}getObjectType(e){var t,i,n,r,s,o,l,c,p;return e?(t=e.ui)!=null&&t.text?"text":(r=(n=(i=e.render)==null?void 0:i.asset)==null?void 0:n.path)!=null&&r.endsWith(".json")?"animation":((o=(s=e.render)==null?void 0:s.asset)==null?void 0:o.type)==="image"||(l=e.render)!=null&&l.texture?"sprite":(p=(c=e.gameplay)==null?void 0:c.tuning)!=null&&p.panel_width?"graphics":"container":"container"}renderGroup(e,t){if(!t.length)return"";let i=window.getEditableObjectConfig,n=t.map(r=>{var p,d;let s=typeof i=="function"?i(r.id):null;if(!s){let u=window.__editableObjectConfigs;u&&typeof u.get=="function"&&(s=(p=u.get(r.id))!=null?p:null)}let o=this.getTypeIconByType(r.objectType),l=this.getAssetPreview(s),c=(d=s==null?void 0:s.ui)!=null&&d.text?`"${s.ui.text.substring(0,12)}${s.ui.text.length>12?"...":""}"`:"";return`
|
|
37
|
+
<button class="scene-object-item ${r.isUnused?"unused":""}" data-object-id="${r.id}">
|
|
38
|
+
<span class="scene-object-label">${r.label}</span>
|
|
39
|
+
${c?`<span class="scene-object-text-preview">${c}</span>`:""}
|
|
40
|
+
<span class="scene-object-badge ${r.isUi?"ui":"scene"}">${r.category}</span>
|
|
41
|
+
</button>
|
|
42
|
+
`}).join("");return`
|
|
43
|
+
<div class="scene-object-group">
|
|
44
|
+
<div class="scene-object-group-title">${e} <span class="scene-object-count">${t.length}</span></div>
|
|
45
|
+
<div class="scene-object-group-items">
|
|
46
|
+
${n}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
`}getTypeIconByType(e){return{text:"\u{1F4DD}",sprite:"\u{1F5BC}\uFE0F",graphics:"\u2B1C",container:"\u{1F4E6}",animation:"\u{1F3AC}"}[e]||"\u{1F4E6}"}getTypeIcon(e){var i,n,r,s,o,l;if(!e)return"\u{1F4E6}";if((i=e.render)!=null&&i.texture){let c=e.render.texture;return c.includes("button")?"\u{1F518}":c.includes("key")?"\u{1F511}":"\u{1F5BC}\uFE0F"}if((n=e.ui)!=null&&n.text)return"\u{1F4DD}";if(((r=e.identity)==null?void 0:r.category)==="ui")return"\u{1F3A8}";if(e.effects||(o=(s=e.identity)==null?void 0:s.id)!=null&&o.includes("effect"))return"\u2728";if(e.audio)return"\u{1F50A}";let t=((l=e.identity)==null?void 0:l.id)||"";return t.includes("background")?"\u{1F5BC}\uFE0F":t.includes("character")?"\u{1F464}":t.includes("key")?"\u{1F511}":t.includes("draggable")?"\u{1F3AF}":t.includes("machine")?"\u2699\uFE0F":t.includes("tutorial")||t.includes("hand")?"\u{1F446}":"\u{1F4E6}"}getAssetPreview(e){var i;if(!e)return null;let t=(i=e.render)==null?void 0:i.texture;return t&&(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg"))?t.startsWith("library/")||t.startsWith("/raw/")?`/raw/${t.replace(/^\/raw\//,"")}`:`/raw/${t}`:null}getColorIndicator(e){var i,n,r,s;if(!e)return"";let t=((i=e.render)==null?void 0:i.background_color)||((r=(n=e.gameplay)==null?void 0:n.tuning)==null?void 0:r.panel_bg_color)||((s=e.ui)==null?void 0:s.backgroundColor);return t?`<span class="scene-object-color-dot" style="background-color: ${t}" title="${t}"></span>`:""}getMetadata(e){var i,n,r,s;if(!e)return"";let t=[];return((i=e.render)==null?void 0:i.visible)===!1&&t.push("hidden"),((n=e.render)==null?void 0:n.z_index)!==void 0&&t.push(`z:${e.render.z_index}`),((r=e.interaction)!=null&&r.clickable||(s=e.ui)!=null&&s.button)&&t.push("clickable"),t.length>0?t.join(" \u2022 "):""}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refreshObjects()},400))}select(e){var t;this.selectedId=e,this.setSelected(e),(t=this.options)==null||t.onSelect(e)}};var zt=class{constructor(){this.root=null;this.options=null;this.isCollapsed=!1}render(){return`
|
|
50
|
+
<div class="scene-tools-corner-panel ${this.isCollapsed?"collapsed":""}" data-panel="scene-tools-corner">
|
|
51
|
+
<div class="scene-tools-header" data-tools-header data-panel-handle>
|
|
52
|
+
<span class="scene-tools-title">Scene Tools</span>
|
|
53
|
+
<div class="scene-tools-header-actions">
|
|
54
|
+
<div class="scene-tools-status-icons" data-status-icons>
|
|
55
|
+
<span class="status-icon" data-status="bounds" title="Highlight Bounds">
|
|
56
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
57
|
+
<rect x="3" y="3" width="18" height="18" rx="2"></rect>
|
|
58
|
+
</svg>
|
|
59
|
+
</span>
|
|
60
|
+
<span class="status-icon" data-status="anchor" title="Highlight Anchor">
|
|
61
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
62
|
+
<circle cx="12" cy="12" r="3"></circle>
|
|
63
|
+
<path d="M12 3v6M12 15v6M3 12h6M15 12h6"></path>
|
|
64
|
+
</svg>
|
|
65
|
+
</span>
|
|
66
|
+
<span class="status-icon" data-status="nudge" title="Arrow Nudging">
|
|
67
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
68
|
+
<path d="M5 9l7-7 7 7M5 15l7 7 7-7"></path>
|
|
69
|
+
</svg>
|
|
70
|
+
</span>
|
|
71
|
+
</div>
|
|
72
|
+
<button class="scene-tools-collapse-btn" data-tools-collapse type="button" title="Collapse/Expand Panel">
|
|
73
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
74
|
+
<polyline points="18 15 12 9 6 15"></polyline>
|
|
75
|
+
</svg>
|
|
76
|
+
</button>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="scene-tools-body" data-tools-body>
|
|
80
|
+
<div class="debug-field checkbox-field">
|
|
81
|
+
<input type="checkbox" id="debug-highlight-object">
|
|
82
|
+
<label for="debug-highlight-object" title="Show bounding boxes around all objects">Highlight bounds</label>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="debug-field checkbox-field">
|
|
85
|
+
<input type="checkbox" id="debug-highlight-anchor">
|
|
86
|
+
<label for="debug-highlight-anchor" title="Show anchor points for all objects">Highlight config anchor</label>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="debug-field checkbox-field">
|
|
89
|
+
<input type="checkbox" id="debug-nudge-enabled">
|
|
90
|
+
<label for="debug-nudge-enabled" title="Enable keyboard arrow keys to nudge selected object">Enable arrow nudging</label>
|
|
91
|
+
</div>
|
|
92
|
+
<div id="debug-nudge-controls" class="debug-nudge hidden">
|
|
93
|
+
<div class="debug-field">
|
|
94
|
+
<label for="debug-nudge-step" title="Number of pixels to move per nudge">Nudge step (px)</label>
|
|
95
|
+
<input type="number" id="debug-nudge-step" step="1" value="10" title="Pixels per nudge">
|
|
96
|
+
</div>
|
|
97
|
+
<div class="debug-arrow-pad">
|
|
98
|
+
<button class="debug-arrow-btn" data-nudge="up" title="Nudge Up">\u2191</button>
|
|
99
|
+
<button class="debug-arrow-btn" data-nudge="left" title="Nudge Left">\u2190</button>
|
|
100
|
+
<button class="debug-arrow-btn" data-nudge="down" title="Nudge Down">\u2193</button>
|
|
101
|
+
<button class="debug-arrow-btn" data-nudge="right" title="Nudge Right">\u2192</button>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
`}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="scene-tools-corner"]'),!this.root)return;let i=localStorage.getItem("scene-tools-collapsed");i!==null&&(this.isCollapsed=i==="true",this.root.classList.toggle("collapsed",this.isCollapsed));let n=this.root.querySelector("[data-panel-handle]");if(n){let{makePanelDraggable:u}=(qi(),Qr(Na));u(this.root,n)}let r=this.root.querySelector("[data-tools-collapse]");r==null||r.addEventListener("click",()=>{var u;this.isCollapsed=!this.isCollapsed,(u=this.root)==null||u.classList.toggle("collapsed",this.isCollapsed),localStorage.setItem("scene-tools-collapsed",String(this.isCollapsed))});let s=(u,g)=>{var h;let f=(h=this.root)==null?void 0:h.querySelector(`[data-status="${u}"]`);f&&f.classList.toggle("active",g)},o=this.root.querySelector("#debug-highlight-object");o==null||o.addEventListener("change",()=>{var u;(u=this.options)==null||u.onHighlightObject(!!o.checked),s("bounds",o.checked)});let l=this.root.querySelector("#debug-highlight-anchor");l==null||l.addEventListener("change",()=>{var u;(u=this.options)==null||u.onHighlightAnchor(!!l.checked),s("anchor",l.checked)});let c=this.root.querySelector("#debug-nudge-enabled"),p=this.root.querySelector("#debug-nudge-controls");if(c&&p){let u=()=>{var f;let g=c.checked;p.classList.toggle("hidden",!g),s("nudge",g),g&&this.isCollapsed&&(this.isCollapsed=!1,(f=this.root)==null||f.classList.remove("collapsed"),localStorage.setItem("scene-tools-collapsed","false"))};c.addEventListener("change",u),u()}Array.from(this.root.querySelectorAll(".debug-arrow-btn")||[]).forEach(u=>{u.addEventListener("click",()=>{var f,h,m,b;switch(u.dataset.nudge){case"up":(f=this.options)==null||f.onNudge(0,-1);break;case"down":(h=this.options)==null||h.onNudge(0,1);break;case"left":(m=this.options)==null||m.onNudge(-1,0);break;case"right":(b=this.options)==null||b.onNudge(1,0);break;default:break}})})}getNudgeStep(){var i,n;let e=(i=this.root)==null?void 0:i.querySelector("#debug-nudge-step"),t=Number((n=e==null?void 0:e.value)!=null?n:10);return Number.isFinite(t)?t:10}updateInfo(e){}};var Ht=class{constructor(){this.root=null;this.slotsContainer=null;this.options=null;this.registry=null;this.expandedSlot=null}mergeRegistries(e,t){let i=e||{},n=t||{},r={slots:Array.isArray(n.slots)?[...n.slots]:[],libraryAssets:typeof n.libraryAssets=="object"&&n.libraryAssets?{...n.libraryAssets}:{},categories:Array.isArray(n.categories)?[...n.categories]:[]},s=Array.isArray(i.slots)?i.slots:[];if(s.length>0&&r.slots.length>0)for(let c of r.slots){let p=s.find(d=>(d==null?void 0:d.slotId)&&d.slotId===(c==null?void 0:c.slotId));p!=null&&p.currentAsset&&p.currentAsset!==(c==null?void 0:c.currentAsset)&&(c.currentAsset=p.currentAsset)}let o=i.libraryAssets||{};for(let[c,p]of Object.entries(o)){if(!Array.isArray(p))continue;r.libraryAssets[c]||(r.libraryAssets[c]=[]);let d=new Set((r.libraryAssets[c]||[]).map(u=>u==null?void 0:u.filename));for(let u of p){let g=u==null?void 0:u.filename;!g||d.has(g)||(r.libraryAssets[c].unshift(u),d.add(g))}}let l=new Set(r.categories||[]);for(let c of i.categories||[])typeof c=="string"&&l.add(c);return r.categories=Array.from(l),r}render(){return`
|
|
107
|
+
<div class="scene-panel library-panel panel-accent-purple" data-panel="library">
|
|
108
|
+
<div class="scene-panel-header" data-panel-handle>
|
|
109
|
+
<div class="panel-title">
|
|
110
|
+
<span class="panel-pill">\u{1F3A8}</span>
|
|
111
|
+
<span class="panel-title-text">Asset Library</span>
|
|
112
|
+
</div>
|
|
113
|
+
<div class="scene-panel-actions">
|
|
114
|
+
<button class="debug-btn debug-btn-sm" type="button" data-refresh-library title="Force Refresh Library">\u{1F504} Refresh</button>
|
|
115
|
+
<button class="debug-btn debug-btn-sm success" type="button" data-create-ai>\u2728 Create with AI</button>
|
|
116
|
+
<button class="scene-panel-toggle" type="button" data-panel-toggle>\u25BE</button>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="scene-panel-body">
|
|
120
|
+
<div class="library-subtitle">Click slot to expand, select asset to apply, or use AI to edit/create</div>
|
|
121
|
+
<div class="library-slots" data-library-slots></div>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="panel-resize-handle" data-panel-resize></div>
|
|
124
|
+
</div>
|
|
125
|
+
`}initialize(e,t){var r,s,o;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(r=this.root)==null?void 0:r.querySelector("[data-library-slots]");let i=(s=this.root)==null?void 0:s.querySelector("[data-create-ai]");i==null||i.addEventListener("click",()=>{this.handleCreateWithAI()});let n=(o=this.root)==null?void 0:o.querySelector("[data-refresh-library]");n==null||n.addEventListener("click",()=>{n.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>n.classList.remove("pulse-anim"),500)}),this.loadAssetRegistry()}reRender(){console.log("[LIBRARY] Re-rendering slots..."),this.loadAssetRegistry()}async refresh(){console.log("[LIBRARY] Force refreshing asset registry...");try{let e=window.getEditableAssets,t=typeof e=="function"?e():null,i=await fetch(`/raw/assetRegistry.json?t=${Date.now()}`);if(i.ok){let n=await i.json(),r=this.mergeRegistries(t,n);window.getEditableAssets=()=>r,console.log("[LIBRARY] \u2705 Registry re-fetched successfully")}}catch(e){console.warn("[LIBRARY] Failed to re-fetch registry:",e)}this.loadAssetRegistry()}loadAssetRegistry(e=0){let t=window.getEditableAssets;if(typeof t=="function"){let i=t();if(i!=null&&i.slots&&Array.isArray(i.slots)&&i.slots.length>0){this.registry=i,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.renderSlots();return}}e<15?(console.log(`[LIBRARY] Waiting for asset registry... (attempt ${e+1}/15)`),setTimeout(()=>this.loadAssetRegistry(e+1),200)):(console.warn("[LIBRARY] Failed to load asset registry"),this.slotsContainer&&(this.slotsContainer.innerHTML='<div class="library-info">No editable assets available</div>'))}renderSlots(){if(!this.slotsContainer||!this.registry)return;let e={};for(let i of this.registry.slots)e[i.category]||(e[i.category]=[]),e[i.category].push(i);let t=Date.now();this.slotsContainer.innerHTML="";for(let i of this.registry.categories){let n=e[i]||[];if(n.length===0)continue;let r=document.createElement("div");r.className="library-category";let s=document.createElement("div");s.className="library-category-header",s.textContent=this.formatCategoryName(i),r.appendChild(s);let o=document.createElement("div");o.className="library-category-slots";for(let l of n){let c=this.createSlotElement(l,t);o.appendChild(c)}r.appendChild(o),this.slotsContainer.appendChild(r)}}createSlotElement(e,t){let i=this.expandedSlot===e.slotId,n=document.createElement("div");n.className=`library-slot ${i?"expanded":""}`,n.dataset.slotId=e.slotId;let r=document.createElement("div");r.className="slot-header";let s=document.createElement("div");s.className="slot-current";let o=document.createElement("img");o.src=`/raw/${e.currentAsset}?t=${t}`,o.alt=e.displayName,o.className="slot-thumbnail",o.onerror=()=>{o.style.display="none"},s.appendChild(o),r.appendChild(s);let l=document.createElement("div");l.className="slot-info";let c=document.createElement("div");c.className="slot-name",c.textContent=e.displayName;let p=document.createElement("div");p.className="slot-asset",p.textContent=e.currentAsset,l.appendChild(c),l.appendChild(p),r.appendChild(l);let d=document.createElement("div");d.className="slot-actions";let u=document.createElement("button");u.className="slot-ai-edit",u.title="Edit with AI",u.textContent="\u2728 AI",u.addEventListener("click",async h=>{h.stopPropagation(),await this.handleAIEdit(e)}),d.appendChild(u);let g=document.createElement("button");g.className="slot-reset",g.title="Reset to default",g.textContent="\u21BA",g.addEventListener("click",async h=>{h.stopPropagation(),await this.handleReset(e)}),d.appendChild(g);let f=document.createElement("span");if(f.className="slot-expand-icon",f.textContent=i?"\u25BC":"\u25B6",d.appendChild(f),r.appendChild(d),r.addEventListener("click",()=>{this.expandedSlot=this.expandedSlot===e.slotId?null:e.slotId,this.renderSlots()}),n.appendChild(r),i){let h=this.createLibraryElement(e,t);n.appendChild(h)}return n}createLibraryElement(e,t){var r;let i=document.createElement("div");i.className="slot-library";let n=((r=this.registry)==null?void 0:r.libraryAssets[e.libraryFolder])||[];return this.fetchFolderAssets(e.libraryFolder,t).then(s=>{let o=new Map;for(let c of n)o.set(c.filename,c);for(let c of s)o.has(c.filename)||o.set(c.filename,c);let l=Array.from(o.values());if(l.length===0){i.innerHTML='<div class="library-empty">No alternative assets</div>';return}i.innerHTML="";for(let c of l){let p=document.createElement("div");p.className="library-item";let d=document.createElement("img");d.src=`/raw/library/${e.libraryFolder}/${c.filename}?t=${t}`,d.alt=c.displayName,d.className="library-thumbnail",d.onerror=()=>{d.style.opacity="0.3"},p.appendChild(d);let u=document.createElement("div");u.className="library-label",u.textContent=c.displayName,p.appendChild(u),p.addEventListener("click",async()=>{await this.handleApply(e,c.filename)}),i.appendChild(p)}}),i.innerHTML='<div class="library-loading">Loading assets...</div>',i}async fetchFolderAssets(e,t){try{let i=await fetch(`/raw/library/${e}/?t=${t}`);if(!i.ok)return[];let n=await i.text(),r=[],s=/href="([^"]+\.(png|jpg|jpeg))"/gi,o;for(;(o=s.exec(n))!==null;){let l=o[1];if(!l.startsWith("/")&&!l.startsWith("..")){let c=l.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");r.push({filename:l,displayName:c})}}return r}catch{return console.log("[LIBRARY] Could not fetch folder listing, using registry only"),[]}}async handleApply(e,t){var i;console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{await((i=this.options)==null?void 0:i.onApply(e.objectId,t,e.category)),e.currentAsset=t,this.renderSlots()}catch(n){console.error("[LIBRARY] Failed to apply asset:",n)}}async handleReset(e){var t;console.log("[LIBRARY] Resetting slot:",e.slotId,"to default:",e.defaultAsset);try{await((t=this.options)==null?void 0:t.onReset(e.objectId,e.defaultAsset,e.category)),e.currentAsset=e.defaultAsset,this.renderSlots()}catch(i){console.error("[LIBRARY] Failed to reset slot:",i)}}formatCategoryName(e){return e.replace(/_/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}async handleAIEdit(e){console.log("[Library] Opening AI Edit for slot:",e);let t=window.__openAiEditor;if(typeof t=="function"){let i=e.slotId||e.objectId,n="render.texture";e.category==="ui"&&(n="ui.image"),e.category==="audio"&&(n="audio.src"),t(i,`Edit ${e.displayName} with AI`,e.currentAsset,{objectId:e.objectId,path:n})}else console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded.")}handleCreateWithAI(){console.log("[Library] Opening AI Create modal");let e=window.__openAiEditor;typeof e=="function"?e("new_asset","Create new asset with AI"):(console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded."))}highlightSlot(e,t){if(!this.registry||!this.slotsContainer)return;let i=e.startsWith("json.")?e.replace("json.",""):e,n=this.registry.slots.find(r=>(r.objectId===i||r.slotId===i)&&(!t||r.category===t));n?(console.log("[LIBRARY] Highlighting slot:",n.slotId),this.expandedSlot=n.slotId,this.renderSlots(),setTimeout(()=>{var s;let r=(s=this.slotsContainer)==null?void 0:s.querySelector(`[data-slot-id="${n.slotId}"]`);r&&(r.scrollIntoView({behavior:"smooth",block:"center"}),r.classList.add("highlight-pulse"),setTimeout(()=>r.classList.remove("highlight-pulse"),3e3))},100)):console.warn("[LIBRARY] No slot found for highlight:",e,t)}};var $t=class{detectType(e,t,i){let n=e.toLowerCase();return n==="logic_id"||n==="logicid"?"select":typeof t=="string"&&t.match(/\.(png|jpg|jpeg|gif|webp)$/i)?"image":n.includes("color")||n.includes("tint")?"color":typeof t=="boolean"?"boolean":typeof t=="number"?"number":Array.isArray(t)?"array":typeof t=="object"&&t!==null?"object":"text"}isHexColor(e){return/^#[0-9a-fA-F]{6}$/i.test(e)}isImagePath(e){return/\.(png|jpg|jpeg|gif|svg)$/i.test(e)}};var Bt=class{render(e,t,i,n){let r=i&&i.trim(),s=r?`/raw/${i}`:"";return`
|
|
126
|
+
<div class="inspector-property inspector-property-image">
|
|
127
|
+
<div class="property-header">
|
|
128
|
+
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
129
|
+
<div class="property-badges">
|
|
130
|
+
<span class="property-badge" title="Image Asset">IMG</span>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<div class="inspector-image-container">
|
|
135
|
+
${r?`
|
|
136
|
+
<div class="inspector-image-preview">
|
|
137
|
+
<img src="${s}" alt="${t}" onclick="window.open('${s}', '_blank')" />
|
|
138
|
+
<div class="preview-overlay">
|
|
139
|
+
<span class="preview-resolution" id="res-${e}-${t}">- x -</span>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
`:`
|
|
143
|
+
<div class="inspector-image-placeholder">
|
|
144
|
+
<span>No Image Selected</span>
|
|
145
|
+
</div>
|
|
146
|
+
`}
|
|
147
|
+
|
|
148
|
+
<div class="inspector-image-details">
|
|
149
|
+
<div class="path-group">
|
|
150
|
+
<input type="text"
|
|
151
|
+
class="inspector-input inspector-input-path"
|
|
152
|
+
value="${i||""}"
|
|
153
|
+
data-property-path="${n}"
|
|
154
|
+
data-object-id="${e}"
|
|
155
|
+
placeholder="path/to/asset.png" />
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
<div class="inspector-image-actions">
|
|
159
|
+
<button class="inspector-btn inspector-btn-sm primary" data-action="library" data-path="${n}" data-object="${e}">
|
|
160
|
+
\u{1F4DA} Show in Library
|
|
161
|
+
</button>
|
|
162
|
+
<button class="inspector-btn inspector-btn-sm" data-action="ai-edit" data-path="${n}" data-object="${e}">
|
|
163
|
+
\u2728 AI Edit
|
|
164
|
+
</button>
|
|
165
|
+
<button class="inspector-btn inspector-btn-sm" data-action="upload" data-path="${n}" data-object="${e}">
|
|
166
|
+
\u{1F4E4}
|
|
167
|
+
</button>
|
|
168
|
+
<button class="inspector-btn inspector-btn-sm" data-action="reset" data-path="${n}" data-object="${e}">
|
|
169
|
+
\u21BA
|
|
170
|
+
</button>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Nt=class{render(e,t,i,n){let r=i||"#000000";return`
|
|
176
|
+
<div class="inspector-property inspector-property-color">
|
|
177
|
+
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
178
|
+
<div class="inspector-color-group">
|
|
179
|
+
<input type="color"
|
|
180
|
+
class="inspector-color-picker"
|
|
181
|
+
value="${r}"
|
|
182
|
+
data-property-path="${n}"
|
|
183
|
+
data-object-id="${e}" />
|
|
184
|
+
<input type="text"
|
|
185
|
+
class="inspector-input inspector-color-text"
|
|
186
|
+
value="${r}"
|
|
187
|
+
data-property-path="${n}"
|
|
188
|
+
data-object-id="${e}" />
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ft=class{render(e,t,i,n){return`
|
|
192
|
+
<div class="inspector-property inspector-property-number">
|
|
193
|
+
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
194
|
+
<input type="number"
|
|
195
|
+
class="inspector-input"
|
|
196
|
+
value="${i}"
|
|
197
|
+
data-property-path="${n}"
|
|
198
|
+
data-object-id="${e}"
|
|
199
|
+
step="any" />
|
|
200
|
+
</div>
|
|
201
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ut=class{render(e,t,i,n){let r=String(i||"");return`
|
|
202
|
+
<div class="inspector-property inspector-property-text">
|
|
203
|
+
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
204
|
+
<div class="inspector-input-group">
|
|
205
|
+
<input type="text"
|
|
206
|
+
class="inspector-input"
|
|
207
|
+
value="${r}"
|
|
208
|
+
data-property-path="${n}"
|
|
209
|
+
data-object-id="${e}" />
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Gt=class{render(e,t,i,n){return`
|
|
213
|
+
<div class="inspector-property inspector-property-boolean">
|
|
214
|
+
<label class="inspector-property-label">
|
|
215
|
+
<input type="checkbox"
|
|
216
|
+
class="inspector-checkbox"
|
|
217
|
+
${i?"checked":""}
|
|
218
|
+
data-property-path="${n}"
|
|
219
|
+
data-object-id="${e}" />
|
|
220
|
+
<span>${this.formatLabel(t)}</span>
|
|
221
|
+
</label>
|
|
222
|
+
</div>
|
|
223
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var qt=class{render(e,t,i,n){if(!Array.isArray(i)||i.length===0)return`
|
|
224
|
+
<div class="inspector-property inspector-property-array">
|
|
225
|
+
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
226
|
+
<div class="inspector-array-empty">Empty array</div>
|
|
227
|
+
</div>
|
|
228
|
+
`;let r=i.map((s,o)=>typeof s=="string"?`<div class="inspector-array-item">\u2022 ${s}</div>`:typeof s=="object"?`<div class="inspector-array-item">\u2022 ${JSON.stringify(s)}</div>`:`<div class="inspector-array-item">\u2022 ${String(s)}</div>`).join("");return`
|
|
229
|
+
<div class="inspector-property inspector-property-array">
|
|
230
|
+
<label class="inspector-property-label">${this.formatLabel(t)} (${i.length} items)</label>
|
|
231
|
+
<div class="inspector-array-list">
|
|
232
|
+
${r}
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Vt=class{constructor(e){this.registry=e}render(e,t,i,n){if(t==="logic"&&i&&typeof i=="object")return this.renderLogic(e,t,i,n);let r=[];for(let o in i){let l=i[o],c=`${n}.${o}`,p=this.registry.renderProperty(e,o,l,c);p&&r.push(p)}return r.length===0?"":r.length<=4&&r.every(o=>o.includes("inspector-property"))?`
|
|
236
|
+
<div class="inspector-subsection">
|
|
237
|
+
<div class="inspector-subsection-title">${this.formatLabel(t)}</div>
|
|
238
|
+
<div class="inspector-subsection-content">
|
|
239
|
+
${r.join("")}
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
`:`
|
|
243
|
+
<div class="inspector-property inspector-property-object">
|
|
244
|
+
<div class="inspector-object-header">${this.formatLabel(t)}</div>
|
|
245
|
+
<div class="inspector-object-body">
|
|
246
|
+
${r.join("")}
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
`}renderLogic(e,t,i,n){let r=[],s=typeof(i==null?void 0:i.id)=="string"?i.id:"",o={zone:["bottom-left","bottom-right","top-left","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"]},l=(()=>{let p=window,d=Array.isArray(p==null?void 0:p.__HANDLER_LOGIC_OPTIONS)?p.__HANDLER_LOGIC_OPTIONS:[],g=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...d].map(f=>String(f)).filter(f=>f.trim().length>0);return Array.from(new Set(g)).sort((f,h)=>f.localeCompare(h))})(),c=s&&!l.includes(s)?[s,...l]:l;r.push(`
|
|
250
|
+
<div class="inspector-property inspector-property-text">
|
|
251
|
+
<label class="inspector-property-label">Id</label>
|
|
252
|
+
<div class="inspector-input-group">
|
|
253
|
+
<select class="inspector-component-select inspector-input"
|
|
254
|
+
data-property-path="${n}.id"
|
|
255
|
+
data-object-id="${e}"
|
|
256
|
+
data-logic-id-selector="true">
|
|
257
|
+
<option value="" ${s?"":"selected"}>None</option>
|
|
258
|
+
${c.map(p=>`<option value="${p}" ${p===s?"selected":""}>${p}</option>`).join("")}
|
|
259
|
+
</select>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
`);for(let p in i){if(p==="id")continue;let d=i[p],u=`${n}.${p}`;if(p==="props"&&d&&typeof d=="object"){let f=[];for(let h in d){let m=d[h],b=`${u}.${h}`,y=o[h];if((h==="targetId"||h==="inputId")&&typeof m=="string"){let v=(()=>{try{let C=window,k=C==null?void 0:C.__editableConfig;if(!(k!=null&&k.objects))return[];let P=[];if(k.objects instanceof Map)for(let O of k.objects.keys())P.push(O);else typeof k.objects=="object"&&P.push(...Object.keys(k.objects));return P.sort()}catch{return[]}})(),x=m||"",w=x&&!v.includes(x)?[x,...v]:v;f.push(`
|
|
263
|
+
<div class="inspector-property inspector-property-text">
|
|
264
|
+
<label class="inspector-property-label">${this.formatLabel(h)}</label>
|
|
265
|
+
<div class="inspector-input-group">
|
|
266
|
+
<select class="inspector-component-select inspector-input"
|
|
267
|
+
data-property-path="${b}"
|
|
268
|
+
data-object-id="${e}">
|
|
269
|
+
<option value="" ${x?"":"selected"}>None</option>
|
|
270
|
+
${w.map(C=>`<option value="${C}" ${C===x?"selected":""}>${C}</option>`).join("")}
|
|
271
|
+
</select>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
`);continue}if(Array.isArray(y)&&y.length)f.push(`
|
|
275
|
+
<div class="inspector-property inspector-property-text">
|
|
276
|
+
<label class="inspector-property-label">${this.formatLabel(h)}</label>
|
|
277
|
+
<div class="inspector-input-group">
|
|
278
|
+
<select class="inspector-component-select inspector-input"
|
|
279
|
+
data-property-path="${b}"
|
|
280
|
+
data-object-id="${e}">
|
|
281
|
+
${y.map(v=>`<option value="${String(v)}" ${String(v)===String(m)?"selected":""}>${String(v)}</option>`).join("")}
|
|
282
|
+
</select>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
`);else{let v=this.registry.renderProperty(e,h,m,b);v&&f.push(v)}}f.length&&r.push(`
|
|
286
|
+
<div class="inspector-property inspector-property-object">
|
|
287
|
+
<div class="inspector-object-header">Props</div>
|
|
288
|
+
<div class="inspector-object-body">
|
|
289
|
+
${f.join("")}
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
`);continue}let g=this.registry.renderProperty(e,p,d,u);g&&r.push(g)}return r.length===0?"":`
|
|
293
|
+
<div class="inspector-property inspector-property-object">
|
|
294
|
+
<div class="inspector-object-header">${this.formatLabel(t)}</div>
|
|
295
|
+
<div class="inspector-object-body">
|
|
296
|
+
${r.join("")}
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Yt=class{render(e,t,i,n,r){let s=i==null?"":String(i),o=Array.from(new Set(r.map(c=>String(c)))),l=s&&!o.includes(s)?[s,...o]:o;return`
|
|
300
|
+
<div class="inspector-property inspector-property-text">
|
|
301
|
+
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
302
|
+
<div class="inspector-input-group">
|
|
303
|
+
<select class="inspector-component-select inspector-input"
|
|
304
|
+
data-property-path="${n}"
|
|
305
|
+
data-object-id="${e}">
|
|
306
|
+
${l.map(c=>`<option value="${c}" ${c===s?"selected":""}>${c}</option>`).join("")}
|
|
307
|
+
</select>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Wt=class{constructor(){this.typeDetector=new $t,this.imageRenderer=new Bt,this.colorRenderer=new Nt,this.numberRenderer=new Ft,this.textRenderer=new Ut,this.booleanRenderer=new Gt,this.arrayRenderer=new qt,this.objectRenderer=new Vt(this),this.selectRenderer=new Yt}getObjectIds(){try{let e=window,t=e==null?void 0:e.__editableConfig;if(!(t!=null&&t.objects))return[];let i=[];if(t.objects instanceof Map)for(let n of t.objects.keys())i.push(n);else typeof t.objects=="object"&&i.push(...Object.keys(t.objects));return i.sort()}catch{return[]}}getEnumOptionsFromSchemas(e){var t;try{let i=window,n=i==null?void 0:i.__editableConfig,r=n==null?void 0:n.schemas;if(!r)return null;let s=String(e||"").split(".").filter(Boolean);if(s.length<2)return null;let o=s[0],l=s.slice(1).join("."),c=r instanceof Map?r.get(o):r==null?void 0:r[o];if(!c)return null;let p=(t=c==null?void 0:c.types)==null?void 0:t[l];if(typeof p!="string"||!p.startsWith("enum:"))return null;let u=p.slice(5).split("|").map(g=>g.trim()).filter(Boolean);return u.length?u:null}catch{return null}}getLogicOptions(){try{let e=window,t=Array.isArray(e==null?void 0:e.__HANDLER_LOGIC_OPTIONS)?e.__HANDLER_LOGIC_OPTIONS:[],n=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...t].map(r=>String(r)).filter(r=>r.trim().length>0);return Array.from(new Set(n)).sort((r,s)=>r.localeCompare(s))}catch{return[]}}renderProperty(e,t,i,n){let r=t.toLowerCase(),s=r==="logic"||r==="logic_id"||r==="logicid",o=r==="id"&&n.toLowerCase().includes("logic");if((s||o)&&typeof i=="string"){let u=this.getLogicOptions();return this.selectRenderer.render(e,t,i,n,u)}let c={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"]}[t];if(c&&n.includes("logic.props"))return this.selectRenderer.render(e,t,i,n,c);if((t==="targetId"||t==="inputId")&&typeof i=="string"){let u=this.getObjectIds();return this.selectRenderer.render(e,t,i,n,["",...u])}let p=this.getEnumOptionsFromSchemas(n);if(p)return this.selectRenderer.render(e,t,i,n,p);switch(this.typeDetector.detectType(t,i)){case"image":return this.imageRenderer.render(e,t,i,n);case"color":return this.colorRenderer.render(e,t,i,n);case"number":return this.numberRenderer.render(e,t,i,n);case"boolean":return this.booleanRenderer.render(e,t,i,n);case"array":return this.arrayRenderer.render(e,t,i,n);case"object":return this.objectRenderer.render(e,t,i,n);case"select":return this.selectRenderer.render(e,t,i,n,[]);default:return this.textRenderer.render(e,t,i,n)}}getTypeDetector(){return this.typeDetector}};var qe=class{async updateProperty(e,t,i,n={}){var l,c,p;console.log("[PropertyUpdateManager] Updating:",e,t,i);let r=window.getEditableObjectConfig;if(typeof r!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let s=r(e);if(!s){console.error("[PropertyUpdateManager] Config not found for:",e);return}lt({objectId:e,path:t,value:i},{persist:!0});let o=window.applyEditableObjectConfig;if(typeof o=="function"){let d=window.__editableConfig,u=(p=(c=(l=d==null?void 0:d.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?p:s;await o(e,u),console.log("[PropertyUpdateManager] Applied config successfully")}else console.warn("[PropertyUpdateManager] applyEditableObjectConfig not available");this.triggerRefresh(e),n.refreshInspector&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}getNestedProperty(e,t){let i=t.split("."),n=e;for(let r of i)if(n&&typeof n=="object"&&r in n)n=n[r];else return;return n}triggerRefresh(e){let t=window.__refreshHierarchy;typeof t=="function"&&t(),window.dispatchEvent(new CustomEvent("inspector:property-updated",{detail:{objectId:e}}))}};var Kt=class{constructor(){this.updateManager=new qe}async handleAction(e,t,i){console.log("[QuickActionsBar] Action:",e,t,i);let n=window.getEditableObjectConfig;if(typeof n!="function")return;let r=n(t);if(!r)return;let s=this.updateManager.getNestedProperty(r,i);if(e==="ai-convert"||e==="upload"||e==="library"){let o=i==="ui.text"||i==="render.asset.path",l=i==="render.asset.path";o&&(await this.prepareForImageConversion(t,r),e==="ai-convert"&&i!=="render.asset.path"&&(i="render.asset.path"))}switch(e){case"library":this.openLibrary(t,i,s);break;case"ai-edit":this.openAIEditor(t,i,s);break;case"upload":this.openUpload(t,i);break;case"reset":await this.resetToDefault(t,i);break;case"ai-convert":this.handleAiConvert(t,i,s);break;default:console.warn("[QuickActionsBar] Unknown action:",e)}}async prepareForImageConversion(e,t){var i,n;if(console.log("[QuickActionsBar] Preparing for image conversion:",e),t.render||(t.render={alpha:1,visible:!0}),(t.render.alpha===0||t.render.alpha===void 0)&&(t.render.alpha=1,await this.updateManager.updateProperty(e,"render.alpha",1)),(t.render.visible===!1||t.render.visible===void 0)&&(t.render.visible=!0,await this.updateManager.updateProperty(e,"render.visible",!0)),t.render.asset||(t.render.asset={type:"image",path:""}),t.render.asset.type!=="image"&&(t.render.asset.type="image",await this.updateManager.updateProperty(e,"render.asset",{type:"image",path:t.render.asset.path||""})),t.ui&&t.ui.renderMode!=="png"){await this.updateManager.updateProperty(e,"ui.renderMode","png",{refreshInspector:!0}),await this.updateManager.updateProperty(e,"render.tint","#ffffff");let s=((n=(i=t.transform)==null?void 0:i.scale)!=null?n:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",s),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",s)}this.ensureSlotInRegistry(e,t)}ensureSlotInRegistry(e,t){var o,l,c;let i=window.getEditableAssets;if(typeof i!="function")return;let n=i();if(!n||!n.slots)return;let r=e.startsWith("json.")?e.replace("json.",""):e;if(!n.slots.some(p=>p.objectId===r||p.slotId===r)){let p=((o=t.identity)==null?void 0:o.category)||"ui";console.log("[QuickActionsBar] Adding new slot to registry for converted object:",r),n.slots.push({slotId:r,displayName:r.replace(/_/g," "),objectId:r,category:p,currentAsset:((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.path)||"",defaultAsset:"",libraryFolder:p,assetType:"image"}),n.categories&&!n.categories.includes(p)&&n.categories.push(p),n.libraryAssets&&!n.libraryAssets[p]&&(n.libraryAssets[p]=[]);let d=window.reRenderAssetLibrary;typeof d=="function"&&d()}}openLibrary(e,t,i){var r;let n=window.__debugContext;if(n){if(n.activeTab!=="library"){n.activeTab="library";let s=window.__updateWorkbenchTabs;typeof s=="function"&&s()}if(n.libraryPanel){let s=window.getEditableObjectConfig,o=s==null?void 0:s(e),l=(r=o==null?void 0:o.identity)==null?void 0:r.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 r=t.split(".").pop()||t;n(r,`Edit ${r} for ${e}`,i,{objectId:e,path:t})}else console.warn("[QuickActionsBar] AI Editor not available")}openUpload(e,t){let i=document.createElement("input");i.type="file",i.accept="image/*",i.onchange=async n=>{var o;let r=(o=n.target.files)==null?void 0:o[0];if(!r)return;console.log("[QuickActionsBar] Preparing upload for:",r.name);let s=new FileReader;s.onload=async()=>{var c,p,d;let l=s.result;try{let u=window.getEditableObjectConfig,g=u==null?void 0:u(e),f=((c=g==null?void 0:g.identity)==null?void 0:c.category)||(t.split(".")[0]==="render"?"environment":"ui"),m=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:f,filename:r.name,data:l,overwrite:!0})})).json();if(m.success){console.log("[QuickActionsBar] \u2705 Uploaded and saved:",m.path),this.updateManager.updateProperty(e,t,m.path);let b=window.__debugContext;(d=(p=b==null?void 0:b.options)==null?void 0:p.onPropertyChange)==null||d.call(p,e,t,m.path);let y=window.addAssetToRegistry;typeof y=="function"&&y(f,r.name);let v=window.reRenderAssetLibrary;typeof v=="function"&&v(),window.dispatchEvent(new CustomEvent("inspector:refresh"))}else console.error("[QuickActionsBar] \u274C Upload failed:",m.error),alert(`Upload failed: ${m.error}`)}catch(u){console.error("[QuickActionsBar] \u274C Upload error:",u),alert("Upload failed. Check console.")}},s.readAsDataURL(r)},i.click()}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],r=i.slice(1),s=window.__editableConfig;if(!(s!=null&&s.schemas))return;let o=null;if(s.schemas instanceof Map?o=s.schemas.get(n):typeof s.schemas=="object"&&(o=s.schemas[n]),!(o!=null&&o.defaults))return;let l=o.defaults;for(let c of r)if(l&&typeof l=="object")l=l[c];else return;return l}handleAiConvert(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let s=`A single, high-quality, high-detail game UI icon/asset representing "${String(i||e.replace(/_/g," ").replace("json.",""))}". Modern stylized 3D rendered style, vibrant colors, soft lighting, isolated on solid magenta background, highly polished professional game art.`,o="render.asset.path";console.log("[QuickActionsBar] AI Convert for:",e,"from:",t,"to:",o),n(e,s,"",{objectId:e,path:o});let l=window.__debugContext;if(l){l.activeTab="ai";let c=window.__updateWorkbenchTabs;typeof c=="function"&&c()}}else console.warn("[QuickActionsBar] AI Editor not available")}};function ss(a,e){let t;return function(...n){let r=()=>{clearTimeout(t),a(...n)};clearTimeout(t),t=setTimeout(r,e)}}var Xt=class{constructor(){this.root=null;this.contentContainer=null;this.selectedObjectId=null;this.options=null;this.showAdvanced=!1;this.rendererRegistry=new Wt,this.updateManager=new qe,this.quickActions=new Kt,window.addEventListener("inspector:refresh",()=>{this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),window.addEventListener("config:changed",()=>{})}render(){return`
|
|
311
|
+
<div class="scene-panel inspector-panel panel-accent-violet" data-panel="inspector" style="right:16px; top:72px;">
|
|
312
|
+
<div class="scene-panel-header" data-panel-handle>
|
|
313
|
+
<div class="panel-title">
|
|
314
|
+
<span class="panel-pill">Inspector</span>
|
|
315
|
+
<span class="panel-title-text">Properties</span>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="scene-panel-actions">
|
|
318
|
+
<button class="debug-btn debug-btn-sm ${this.showAdvanced?"primary":""}" type="button" data-inspector-advanced title="Show Advanced Properties">\u2699\uFE0F</button>
|
|
319
|
+
<button class="scene-panel-toggle" type="button" data-panel-toggle>\u25BE</button>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
<div class="scene-panel-body">
|
|
323
|
+
<div class="inspector-content" data-inspector-content>
|
|
324
|
+
<div class="inspector-empty">
|
|
325
|
+
<span class="inspector-empty-icon">\u{1F3AF}</span>
|
|
326
|
+
<span class="inspector-empty-text">Select an object to inspect</span>
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
`}initialize(e,t){var i;this.options=t,this.root=e.querySelector('[data-panel="inspector"]'),this.contentContainer=(i=this.root)==null?void 0:i.querySelector("[data-inspector-content]")}loadObject(e){this.selectedObjectId=e;let t=window.getEditableObjectConfig;if(typeof t!="function"){this.showError("Config system not ready");return}let i=t(e);if(!i){this.showError("Object not found");return}this.renderProperties(e,i)}renderProperties(e,t){if(!this.contentContainer)return;let i=[],n=t.identity||{},r=n.id||e,s=n.category||"unknown";i.push(`
|
|
332
|
+
<div class="inspector-header">
|
|
333
|
+
<div class="inspector-header-info">
|
|
334
|
+
<div class="inspector-object-name">${r}</div>
|
|
335
|
+
<div class="inspector-object-category">${s}</div>
|
|
336
|
+
</div>
|
|
337
|
+
${this.renderConversionButtons(e,t)}
|
|
338
|
+
</div>
|
|
339
|
+
`);let o=["ui","transform","render","gameplay","interaction","audio","effects","physics","motion","identity"];for(let l of o){let c=t[l];if(c){if(!this.showAdvanced&&!this.isSectionMeaningful(l,c,t))continue;i.push(this.renderSection(e,l,c,l))}}for(let l in t)if(!o.includes(l)&&typeof t[l]=="object"&&t[l]!==null){if(!this.showAdvanced&&!this.isSectionMeaningful(l,t[l],t))continue;i.push(this.renderSection(e,l,t[l],l))}this.contentContainer.innerHTML=i.join("")+this.renderFooter(t),this.attachEventListeners()}renderConversionButtons(e,t){var o,l,c,p;let i=!!t.ui,n=((o=t.ui)==null?void 0:o.renderMode)==="png"||((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.type)==="image";if(!(i||e.includes("ui_endgame")||e.includes("splash")||e.includes("button")||e.includes("label"))||n)return"";let s=(p=t.ui)!=null&&p.text?"ui.text":"render.asset.path";return`
|
|
340
|
+
<div class="inspector-quick-actions">
|
|
341
|
+
<button class="debug-btn debug-btn-sm success ai-simple-btn" type="button" data-convert-toggle>
|
|
342
|
+
\u2728 Convert to PNG
|
|
343
|
+
</button>
|
|
344
|
+
<div class="inspector-convert-menu hidden" data-convert-menu>
|
|
345
|
+
<button class="debug-btn debug-btn-sm" data-action="library" data-path="render.asset.path" data-object="${e}">\u{1F3A8} Library</button>
|
|
346
|
+
<button class="debug-btn debug-btn-sm" data-action="ai-convert" data-path="${s}" data-object="${e}">\u2728 AI</button>
|
|
347
|
+
<button class="debug-btn debug-btn-sm" data-action="upload" data-path="render.asset.path" data-object="${e}">\u{1F4E4} Upload</button>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
`}renderFooter(e){let t=["motion","effects","ui","audio","physics","interaction","gameplay","visibility"],i=Object.keys(e),n=t.filter(r=>!i.includes(r));return n.length===0?"":`
|
|
351
|
+
<div class="inspector-footer">
|
|
352
|
+
<div class="inspector-add-component">
|
|
353
|
+
<select class="inspector-component-select" data-inspector-component-select>
|
|
354
|
+
<option value="" disabled selected>Add Component...</option>
|
|
355
|
+
${n.map(r=>`<option value="${r}">${this.formatLabel(r)}</option>`).join("")}
|
|
356
|
+
</select>
|
|
357
|
+
<button class="debug-btn debug-btn-sm primary" data-inspector-add-component-btn>Add</button>
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
360
|
+
`}renderSection(e,t,i,n){let r=[],s=["kind","renderMode","position_ratio","position_mode","responsive","slot_id","asset_type"];for(let o in i){if(!this.showAdvanced&&s.includes(o))continue;let l=i[o],c=`${n}.${o}`,p=this.rendererRegistry.renderProperty(e,o,l,c);p&&r.push(p)}return r.length===0?"":`
|
|
361
|
+
<div class="inspector-section" data-section="${t}">
|
|
362
|
+
<div class="inspector-section-header" data-section-toggle="${t}">
|
|
363
|
+
<span class="inspector-section-arrow">\u25BC</span>
|
|
364
|
+
<span class="inspector-section-icon">${this.getSectionIcon(t)}</span>
|
|
365
|
+
<span class="inspector-section-title">${this.formatLabel(t)}</span>
|
|
366
|
+
</div>
|
|
367
|
+
<div class="inspector-section-body" data-section-body="${t}">
|
|
368
|
+
${r.join("")}
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
`}attachEventListeners(){var c,p,d,u;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=ss((g,f,h)=>{var m,b;this.updateManager.updateProperty(g,f,h),(b=(m=this.options)==null?void 0:m.onPropertyChange)==null||b.call(m,g,f,h)},300);e.forEach(g=>{let f=m=>{var x,w;let b=m.target,y=b.dataset.propertyPath,v=b.dataset.objectId;if(y&&v){let C=b.value;if(b.type==="checkbox")C=b.checked;else if(b.type==="number"&&(C=parseFloat(b.value),isNaN(C)))return;b.type==="text"||b.type==="range"||b.tagName==="TEXTAREA"?t(v,y,C):(this.updateManager.updateProperty(v,y,C),(w=(x=this.options)==null?void 0:x.onPropertyChange)==null||w.call(x,v,y,C))}},h=g.dataset.propertyPath;h==="logic.id"||h!=null&&h.endsWith(".logic.id")?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",h),g.addEventListener("change",async m=>{var O;let b=m.target,y=b.dataset.propertyPath,v=b.dataset.objectId,x=b.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",x),!y||!v)return;await this.updateManager.updateProperty(v,y,x),console.log("[Inspector v1.0.0] Logic ID updated");let w=window,C=(O=w==null?void 0:w.__HANDLER_LOGIC_META)==null?void 0:O[x],k=this.getDefaultPropsForLogic(x,C);console.log("[Inspector v1.0.0] New logic default props:",k);let P=y.replace(".id",".props");await this.updateManager.updateProperty(v,P,k),console.log("[Inspector v1.0.0] Logic props updated to:",k),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(v)})):(g.addEventListener("change",f),(g.tagName==="INPUT"||g.tagName==="TEXTAREA")&&g.addEventListener("input",f))}),this.contentContainer.querySelectorAll("[data-action]").forEach(g=>{g.addEventListener("click",f=>{let h=f.target,m=h.dataset.action,b=h.dataset.path,y=h.dataset.object;m&&b&&y&&this.quickActions.handleAction(m,y,b)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(g=>{g.addEventListener("click",f=>{var b,y;let h=f.target,m=h.dataset.sectionToggle||((b=h.closest("[data-section-toggle]"))==null?void 0:b.getAttribute("data-section-toggle"));if(m){let v=(y=this.contentContainer)==null?void 0:y.querySelector(`[data-section="${m}"]`);v==null||v.classList.toggle("collapsed")}})});let r=(c=this.root)==null?void 0:c.querySelector("[data-inspector-advanced]");r==null||r.addEventListener("click",()=>{this.showAdvanced=!this.showAdvanced,this.selectedObjectId&&this.loadObject(this.selectedObjectId)});let s=(p=this.root)==null?void 0:p.querySelector("[data-convert-toggle]");s==null||s.addEventListener("click",()=>{var f;let g=(f=this.root)==null?void 0:f.querySelector("[data-convert-menu]");g==null||g.classList.toggle("hidden")});let o=(d=this.contentContainer)==null?void 0:d.querySelector("[data-inspector-add-component-btn]"),l=(u=this.contentContainer)==null?void 0:u.querySelector("[data-inspector-component-select]");o==null||o.addEventListener("click",async()=>{let g=l.value;g&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,g)})}async addComponent(e,t){console.log("[InspectorPanel] Adding component:",t,"to:",e);let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n){console.error("[InspectorPanel] Failed to get config for:",e);return}let r=window.__editableConfig,s=r==null?void 0:r.schemas,o=null;s instanceof Map?o=s.get(t):s&&typeof s=="object"&&(o=s[t]),o||console.warn("[InspectorPanel] Schema not found for component:",t);let l=(o==null?void 0:o.defaults)||{enabled:!0};n[t]={...l},await this.updateManager.updateProperty(e,t,n[t]),this.loadObject(e),console.log("[InspectorPanel] Component added successfully")}isSectionMeaningful(e,t,i){var r,s;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((s=(r=i.render)==null?void 0:r.asset)==null?void 0:s.type)==="image")return!1;if(e==="interaction")return t.clickable===!0||t.draggable===!0;if(t.enabled===!0||t.active===!0||t.visible===!0)return!0;if(e==="ui")return!!(t.text||t.font||t.fontSize);let n=Object.keys(t);return n.length===0||n.length===1&&n[0]==="enabled"&&t.enabled===!1?!1:["audio","effects","physics","motion","gameplay"].includes(e)?t.enabled===!0:!0}showError(e){this.contentContainer&&(this.contentContainer.innerHTML=`
|
|
372
|
+
<div class="inspector-empty">
|
|
373
|
+
<span class="inspector-empty-icon">\u26A0\uFE0F</span>
|
|
374
|
+
<span class="inspector-empty-text">${e}</span>
|
|
375
|
+
</div>
|
|
376
|
+
`)}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}getDefaultPropsForLogic(e,t){return{DragToWin:{targetDrags:3},DragSnap:{targetId:"",snapRadius:100,snapDuration:.5,returnOnMiss:!0,returnDuration:.3,ease:"power2.out"},SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},JoystickMove:{speed:200,zone:"bottom-center",offsetX:0,offsetY:-50,inputId:""}}[e]||{}}getSectionIcon(e){return{identity:"\u{1F194}",transform:"\u{1F4D0}",render:"\u{1F3A8}",ui:"\u{1F4AC}",gameplay:"\u{1F3AE}",interaction:"\u{1F446}",audio:"\u{1F50A}",effects:"\u2728",motion:"\u{1F3AC}"}[e]||"\u{1F4E6}"}clear(){this.selectedObjectId=null,this.contentContainer&&(this.contentContainer.innerHTML=`
|
|
377
|
+
<div class="inspector-empty">
|
|
378
|
+
<span class="inspector-empty-icon">\u{1F3AF}</span>
|
|
379
|
+
<span class="inspector-empty-text">Select an object to inspect</span>
|
|
380
|
+
</div>
|
|
381
|
+
`)}};import ms from"jszip";function Vi(a){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(a)})}function Fa(a){var n;let[e,t]=a.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(n=i==null?void 0:i[1])!=null?n:"image/png"}}async function Ua(a){return await new Promise(e=>{let t=new Image;t.onload=()=>e({width:t.naturalWidth||t.width,height:t.naturalHeight||t.height}),t.onerror=()=>e(null),t.src=a})}async function Jt(a){var e,t;try{console.log("[ImageUtils] Fetching image data from URL:",a);let i=await fetch(a);if(!i.ok)return console.warn("[ImageUtils] Fetch failed with status:",i.status,a),null;let n=await i.blob();console.log("[ImageUtils] Blob received, size:",n.size,"type:",n.type);let r=await Vi(n),s=await Ua(r),o=Fa(r);return console.log("[ImageUtils] Success resolution:",s==null?void 0:s.width,"x",s==null?void 0:s.height,"mime:",o.mimeType),{base64:o.base64,mimeType:o.mimeType,dataUrl:r,width:(e=s==null?void 0:s.width)!=null?e:0,height:(t=s==null?void 0:s.height)!=null?t:0}}catch(i){return console.error("[ImageUtils] Error fetching image data:",i),null}}async function Le(a){var e,t;try{let i=await Vi(a),n=await Ua(i),r=Fa(i);return{base64:r.base64,mimeType:r.mimeType,dataUrl:i,width:(e=n==null?void 0:n.width)!=null?e:0,height:(t=n==null?void 0:n.height)!=null?t:0}}catch{return null}}function Ga(a){return Vi(a).then(e=>e).catch(()=>null)}function Yi(a,e){var t;try{let[i,n]=a.split(","),r=i.match(/data:(.*?);base64/),s=(t=r==null?void 0:r[1])!=null?t:"image/png",o=atob(n),l=new Uint8Array(o.length);for(let c=0;c<o.length;c++)l[c]=o.charCodeAt(c);return new File([l],e,{type:s})}catch{return null}}async function Ve(a,e=30){try{console.log("[ImageUtils] Removing background color...");let t=await new Promise((d,u)=>{let g=new Image;g.onload=()=>d(g),g.onerror=()=>u(new Error("Failed to load image")),g.src=a}),i=document.createElement("canvas");i.width=t.width,i.height=t.height;let n=i.getContext("2d");if(!n)return console.error("[ImageUtils] Failed to get canvas context"),a;n.drawImage(t,0,0);let r=n.getImageData(0,0,i.width,i.height),s=r.data,l=[{name:"top-left",offset:0},{name:"top-right",offset:(i.width-1)*4},{name:"bottom-left",offset:(i.height-1)*i.width*4},{name:"bottom-right",offset:((i.height-1)*i.width+(i.width-1))*4}].map(d=>({r:s[d.offset],g:s[d.offset+1],b:s[d.offset+2]})),c=0;for(let d=0;d<s.length;d+=4){let u=s[d],g=s[d+1],f=s[d+2],h=!1;for(let m of l)if(Math.sqrt(Math.pow(u-m.r,2)+Math.pow(g-m.g,2)+Math.pow(f-m.b,2))<e){h=!0;break}h&&(s[d+3]=0,c++)}return console.log(`[ImageUtils] Removed background from ${c} pixels (4-corner sampling, tolerance: ${e})`),n.putImageData(r,0,0),i.toDataURL("image/png")}catch(t){return console.error("[ImageUtils] Error removing background:",t),a}}function qa(a,e){if(!a||!e)return"1:1";let t=a/e;return t>1.3?"16:9":t<.77?"9:16":"1:1"}function me(a){return typeof a=="object"&&a!==null&&!Array.isArray(a)}function W(a){return typeof a=="string"?a:void 0}function Va(a){return a.toLowerCase().endsWith(".png")?a.slice(0,-4):a}function os(a){var i,n,r;let e=(i=W(a.id))!=null?i:W(a.name);if(e)return e;let t=(n=W(a.file))!=null?n:W(a.asset);return t?Va((r=t.split("/").pop())!=null?r:t):void 0}function ls(a,e,t){var i,n,r;if(typeof e=="string")return{id:a,file:e,role:t};if(me(e)){let s=(i=W(e.file))!=null?i:W(e.asset);return s?{id:(n=W(e.id))!=null?n:a,file:s,role:(r=W(e.role))!=null?r:t,dataUrl:W(e.dataUrl),layout:e.layout}:null}return null}function Wi(a,e){var t,i,n;if(!a)return[];if(Array.isArray(a)){let r=[];for(let s of a){if(typeof s=="string"){let o=Va((t=s.split("/").pop())!=null?t:s);r.push({id:o,file:s,role:e});continue}if(me(s)){let o=os(s),l=(i=W(s.file))!=null?i:W(s.asset);if(!o||!l)continue;r.push({id:o,file:l,role:(n=W(s.role))!=null?n:e,dataUrl:W(s.dataUrl),layout:s.layout})}}return r}if(me(a)){let r=[];for(let[s,o]of Object.entries(a)){let l=ls(s,o,e);l&&r.push(l)}return r}return[]}function cs(a){var e,t;return(t=(e=W(a.brand_name))!=null?e:W(a.brandName))!=null?t:W(a.name)}function ds(a){if(me(a.brand_dna)&&me(a.brand_dna.colors))return a.brand_dna;if(me(a.colors)){let e={colors:a.colors};return typeof a.style=="string"&&(e.style=a.style),me(a.fonts)&&(e.fonts=a.fonts),e}}function ps(a){var t;let e=new Map;for(let i of a){let n=e.get(i.id);if(!n){e.set(i.id,i);continue}e.set(i.id,{...n,...i,file:i.file||n.file,role:i.role||n.role,dataUrl:i.dataUrl||n.dataUrl,layout:(t=i.layout)!=null?t:n.layout})}return Array.from(e.values())}function Ki(a,e={}){var s,o,l;let t=a.filter(me),i=(o=(s=t.map(cs).find(Boolean))!=null?s:e.defaultBrandName)!=null?o:"Imported Brand",n=(l=t.map(ds).find(Boolean))!=null?l:{colors:{}},r=[];for(let c of t)"layers"in c&&r.push(...Wi(c.layers,"visual element")),"assets"in c&&r.push(...Wi(c.assets,"visual element")),me(c.endgame)&&"assets"in c.endgame&&r.push(...Wi(c.endgame.assets,"endgame"));return{version:"1.0",brand_name:i,brand_dna:n,assets:ps(r)}}import{GoogleGenAI as us}from"@google/genai";async function Zt(a,e,t=[],i={}){var n,r,s,o,l,c,p;try{if(!(a!=null&&a.trim()))throw new Error("Gemini API key is required");if(!(e!=null&&e.trim()))throw new Error("Prompt is required");for(let b=0;b<t.length;b++){let y=t[b];if(!y.base64||!y.mimeType)throw new Error(`Image ${b+1} is missing required data`);if(y.base64.length<1e3&&console.warn(`Image ${b+1} data appears very small, may be corrupted`),!y.mimeType.startsWith("image/"))throw new Error(`Image ${b+1} has invalid MIME type: ${y.mimeType}`)}let d=new us({apiKey:a}),u="gemini-2.5-flash",g=[e];t.length>0&&t.forEach((b,y)=>{g.push({inlineData:{data:b.base64,mimeType:b.mimeType}}),console.log(`[Gemini] Added image ${y+1}: ${b.mimeType}, size: ${Math.round(b.base64.length/1024)}KB`)}),console.log(`[Gemini] Making request with ${t.length} images and prompt length: ${e.length}`);let f=await d.models.generateContent({model:u,contents:g}),h="",m=(s=(r=(n=f.candidates)==null?void 0:n[0])==null?void 0:r.content)==null?void 0:s.parts;if(m)for(let b of m)b.text&&(h+=b.text);if(!h.trim())throw new Error("Empty response from Gemini API");return console.log(`[Gemini] Response received, length: ${h.length}`),h}catch(d){throw console.error("[Gemini] API error:",d),(o=d.message)!=null&&o.includes("Unable to process input image")?new Error("Unable to process the uploaded image. Please ensure it's a valid PNG, JPG, or JPEG file under 10MB and not corrupted."):(l=d.message)!=null&&l.includes("API_KEY_INVALID")?new Error("Invalid Gemini API key. Please check your API key configuration."):(c=d.message)!=null&&c.includes("QUOTA_EXCEEDED")?new Error("Gemini API quota exceeded. Please try again later or check your billing."):(p=d.message)!=null&&p.includes("SAFETY")?new Error("Content was flagged by Gemini safety filters. Please try with different images."):d}}import{GoogleGenAI as gs}from"@google/genai";async function Ye(a,e,t=[],i={}){try{console.info("[GEMINI-REAL-SDK] Initializing GoogleGenAI...");let n=new gs({apiKey:a}),r=[{text:e}];t.length>0&&t.forEach((o,l)=>{console.info(`[GEMINI-REAL-SDK] Adding image part ${l}`),r.push({inlineData:{mimeType:o.mimeType,data:o.base64}})}),console.info("[GEMINI-REAL-SDK] Calling generateContent with model: gemini-2.5-flash-image");let s=await n.models.generateContent({model:"gemini-2.5-flash-image",contents:r});if(console.info("[GEMINI-REAL-SDK] Received response from model"),!s.candidates||!s.candidates[0]||!s.candidates[0].content||!s.candidates[0].content.parts)throw new Error("Gemini 2.5 Flash Image returned invalid response structure.");for(let o of s.candidates[0].content.parts)if(o.text)console.log(o.text);else if(o.inlineData){let l=o.inlineData.data,c=o.inlineData.mimeType||"image/png";return console.info("[GEMINI-REAL-SDK] Found inline image data in response"),`data:${c};base64,${l}`}throw new Error("Gemini 2.5 Flash Image returned no image data.")}catch(n){throw console.error("[GEMINI-REAL-SDK] Error in generateImageWithGemini25Flash:",JSON.stringify(n,Object.getOwnPropertyNames(n),2)),n}}function Ya(a){let e=a.brandAssets.map(r=>{let s=`- ${r.id}: ${r.role}`;return r.layout&&(s+=` [pos: ${r.layout.x.toFixed(0)},${r.layout.y.toFixed(0)}, size: ${r.layout.w.toFixed(0)}x${r.layout.h.toFixed(0)}, z: ${r.layout.z}, opacity: ${r.layout.opacity}]`),s}).join(`
|
|
382
|
+
`)||"None",t=a.brandDna?`Colors: ${JSON.stringify(a.brandDna.colors)}, Style: ${a.brandDna.style||"not specified"}`:"Not provided",i=a.gameObjects.map(r=>typeof r=="string"?`- id: ${r}`:`- id: ${r.id}${r.category?`, category: ${r.category}`:""}${r.type?`, type: ${r.type}`:""}`).join(`
|
|
383
|
+
`),n="";if(a.brandConfig){let r=a.brandConfig,s=[];r.splash&&s.push(`SPLASH: title="${r.splash.title||""}", subtitle="${r.splash.subtitle||""}", button="${r.splash.button_label||""}"`),r.endgame&&s.push(`ENDGAME: title="${r.endgame.title||""}", subtitle="${r.endgame.subtitle||""}", cta="${r.endgame.cta_label||""}"`),r.tutorial&&s.push(`TUTORIAL: text="${r.tutorial.label_text||""}", helper="${r.tutorial.helper_text||""}"`),s.length>0&&(n=`
|
|
384
|
+
BRAND CONTENT:
|
|
385
|
+
${s.join(`
|
|
386
|
+
`)}
|
|
387
|
+
`)}return`
|
|
388
|
+
You are analyzing a brand's visual design for use in a playable ad game.
|
|
389
|
+
|
|
390
|
+
GAME CONTEXT:
|
|
391
|
+
${a.gamePrompt||"Simple game"}
|
|
392
|
+
|
|
393
|
+
GAME OBJECTS (need assets):
|
|
394
|
+
${i}
|
|
395
|
+
|
|
396
|
+
BRAND ASSETS PROVIDED:
|
|
397
|
+
${e}
|
|
398
|
+
|
|
399
|
+
BRAND DNA:
|
|
400
|
+
${t}
|
|
401
|
+
${n}
|
|
402
|
+
VISUAL REFERENCE: [See attached flat design image]
|
|
403
|
+
|
|
404
|
+
TASK:
|
|
405
|
+
1. Match brand assets to game objects where semantically appropriate
|
|
406
|
+
2. For unmatched game objects that need visuals, mark as GENERATE with a detailed prompt
|
|
407
|
+
3. For non-visual objects (text, effects, particles), mark as KEEP
|
|
408
|
+
|
|
409
|
+
RULES (IMPORTANT):
|
|
410
|
+
- Backgrounds should map to background objects
|
|
411
|
+
- Logos should map to logo/brand objects
|
|
412
|
+
- CTA/buttons should map to button objects
|
|
413
|
+
- Characters/elements may map to game elements
|
|
414
|
+
- Generate prompts should be detailed and include: subject, style, colors
|
|
415
|
+
- For EVERY decision, you MUST include:
|
|
416
|
+
- "confidence": number between 0.0 and 1.0
|
|
417
|
+
- "reason": short explanation of why this action was chosen
|
|
418
|
+
|
|
419
|
+
OUTPUT ONLY VALID JSON (no markdown, no explanation):
|
|
420
|
+
{
|
|
421
|
+
"mappings": [
|
|
422
|
+
{
|
|
423
|
+
"game_object": "object_id",
|
|
424
|
+
"action": "APPLY",
|
|
425
|
+
"brand_asset": "asset_id",
|
|
426
|
+
"confidence": 0.95,
|
|
427
|
+
"reason": "Logo asset matches brand logo object"
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"game_object": "object_id",
|
|
431
|
+
"action": "GENERATE",
|
|
432
|
+
"generation_prompt": "Create a...",
|
|
433
|
+
"reference_asset": "logo",
|
|
434
|
+
"confidence": 0.72,
|
|
435
|
+
"reason": "CTA requires brand color and typography"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
"game_object": "object_id",
|
|
439
|
+
"action": "KEEP",
|
|
440
|
+
"confidence": 0.9,
|
|
441
|
+
"reason": "Effect/particle object, no visual replacement needed"
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
}
|
|
445
|
+
`.trim()}function Wa(a){var n,r;let e=(n=a.brandDna)!=null&&n.colors?`Primary: ${a.brandDna.colors.primary}, Secondary: ${a.brandDna.colors.secondary||"N/A"}, Accent: ${a.brandDna.colors.accent||"N/A"}`:"Use provided reference colors",t=((r=a.brandDna)==null?void 0:r.style)||"modern gaming style",i=a.needsTransparency?"BACKGROUND: REQUIRED solid magenta #FF00FF (for transparency removal)":"BACKGROUND: Use brand colors naturally, fill the entire frame";return`
|
|
446
|
+
TASK: ${a.prompt}
|
|
447
|
+
|
|
448
|
+
BRAND STYLE:
|
|
449
|
+
- Colors: ${e}
|
|
450
|
+
- Style: ${t}
|
|
451
|
+
|
|
452
|
+
CHANGE_STRENGTH: 8/10
|
|
453
|
+
REFERENCE: ${a.hasReference?"provided (use as style guide for colors and aesthetics)":"none"}
|
|
454
|
+
${i}
|
|
455
|
+
|
|
456
|
+
OUTPUT CONSTRAINTS (MUST FOLLOW):
|
|
457
|
+
- Do NOT add extra text unless specifically requested
|
|
458
|
+
- Preserve aspect ratio${a.aspectRatio?` (target: ${a.aspectRatio})`:""}
|
|
459
|
+
- Keep padding under 5% of asset size
|
|
460
|
+
- No drop shadows unless explicitly requested
|
|
461
|
+
- No gradients on the background (solid ${a.needsTransparency?"magenta":"colors"} only)
|
|
462
|
+
- Center the subject in frame
|
|
463
|
+
|
|
464
|
+
OUTPUT:
|
|
465
|
+
Generate the requested asset matching the brand style.${a.needsTransparency?" Background MUST be solid magenta (#FF00FF).":""}
|
|
466
|
+
`.trim()}function Ka(a){return a.map(e=>{if(typeof e=="string"){let t=e,i,n;return t.includes("background")?(i="background",n="background"):t.includes("button")||t.includes("cta")?(i="ui",n="button"):t.includes("logo")?(i="ui",n="logo"):t.includes("title")||t.includes("subtitle")||t.includes("text")?(i="text",n="text"):t.includes("effect")||t.includes("confetti")||t.includes("particle")?(i="effects",n="effect"):t.includes("ui.")||t.includes("splash")||t.includes("endgame")?(i="ui",n="image"):(i="environment",n="interactive"),{id:t,category:i,type:n}}return e})}function Xa(a,e){return!(a.includes("background")&&(a.includes("_1")||a.includes("splash")||a.includes("endgame")||a.includes("main"))||e==="text"||e==="effects"&&a.includes("particle"))}async function Ja(a){var s,o;let e=Ka(a.gameObjects),t={gamePrompt:a.gamePrompt,gameObjects:e,brandAssets:a.manifest.assets,brandDna:a.manifest.brand_dna,brandName:a.manifest.brand_name},i=Ya(t),n=[];if(a.flatDesignDataUrl)try{let l=Za(a.flatDesignDataUrl);l&&l.base64&&l.mimeType?l.base64.length<100?console.warn("[Pipeline] Flat design data URL appears invalid (too short)"):(n.push(l),console.log("[Pipeline] Added flat design to analysis, size:",l.base64.length)):console.warn("[Pipeline] Failed to parse flat design data URL")}catch(l){console.warn("[Pipeline] Error processing flat design:",l)}console.log("[Pipeline] Running analysis chain with",n.length,"images...");let r;try{r=await Zt(a.apiKey,i,n,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(s=l.message)!=null&&s.includes("Unable to process input image")?new Error("Gemini API unable to process the uploaded images. Please try with different images or ensure they are valid PNG/JPG files under 10MB."):(o=l.message)!=null&&o.includes("image")?new Error("Image processing failed. Please ensure your images are valid and not corrupted."):l}return hs(r,a.gameObjects)}function hs(a,e){try{let t=a,i=a.match(/```(?:json)?\s*([\s\S]*?)```/);if(i)t=i[1].trim();else{let r=a.match(/\{[\s\S]*\}/);r&&(t=r[0])}let n=JSON.parse(t);return n.mappings&&Array.isArray(n.mappings)?{mappingResult:n,rawResponse:a,parsed:!0}:{mappingResult:{mappings:e.map(r=>({game_object:r,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:a,parsed:!1,parseError:"Missing mappings[] array"}}catch(t){return{mappingResult:{mappings:e.map(i=>({game_object:i,action:"KEEP",status:"Analysis response was not valid JSON"}))},rawResponse:a,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function Xi(a,e,t={}){var n;let i=e.mappings.filter(r=>r.action==="GENERATE");if(i.length===0){console.log("[Pipeline] No assets to generate");return}console.log(`[Pipeline] Generating ${i.length} assets...`);for(let r=0;r<i.length;r++){let s=i[r];(n=t.onProgress)==null||n.call(t,r+1,i.length,s.game_object);try{let o=await fs(a,s);s.output_dataUrl=o,s.status="Generated \u2713"}catch(o){console.error(`[Pipeline] Failed to generate ${s.game_object}:`,o),s.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function fs(a,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&a.manifest){let o=a.manifest.assets.find(l=>l.id===e.reference_asset);if(o){let l=a.assetFiles.get(o.file);if(l){let c=await Le(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(a.flatDesignDataUrl){let o=Za(a.flatDesignDataUrl);o&&t.push(o)}let i=Xa(e.game_object),n={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:a.manifest.brand_dna,needsTransparency:i},r=Wa(n);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${i})`);let s=await Ye(a.apiKey,r,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return i&&await Ve(s)||s}function Za(a){let[e,t]=a.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return t&&i?{base64:t,mimeType:i[1]}:null}async function Qa(a,e){let t=a.assets,i=[];Array.isArray(t)?i=t:t&&typeof t=="object"?i=Object.entries(t).map(([n,r])=>({id:n,file:String(r),role:"visual element"})):i=[],a.assets=i;for(let n of i){let r=e.get(n.file);if(r){let s=await Le(r);s&&(n.dataUrl=s.dataUrl)}}}var Qt=class{constructor(){this.root=null;this.currentTab="upload";this.uploadMethod="individual";this.uploadedJsons=new Map;this.normalizedManifest=null;this.flatDesignDataUrl=null;this.assetFiles=new Map;this.zipFile=null;this.mappingResult=null;this.analysisRawResponse=null;this.analysisParsedOk=null;this.analysisParseError=null;this.isAnalyzing=!1;this.isGenerating=!1}get manifest(){return this.normalizedManifest}render(){return`
|
|
467
|
+
<div class="scene-panel brand-vision-panel panel-accent-violet" data-panel="brand-vision">
|
|
468
|
+
<div class="scene-panel-header" data-panel-handle>
|
|
469
|
+
<div class="panel-title">
|
|
470
|
+
<span class="panel-pill">\u{1F3A8}</span>
|
|
471
|
+
<span class="panel-title-text">Brand Vision Mapper</span>
|
|
472
|
+
</div>
|
|
473
|
+
<div class="scene-panel-actions">
|
|
474
|
+
<button class="scene-panel-close" type="button" data-panel-close title="Close and return to dashboard">\u2715</button>
|
|
475
|
+
<button class="scene-panel-toggle" type="button" data-panel-toggle>\u25BE</button>
|
|
476
|
+
</div>
|
|
477
|
+
</div>
|
|
478
|
+
<div class="scene-panel-body">
|
|
479
|
+
<!-- TABS -->
|
|
480
|
+
<div class="ai-tabs">
|
|
481
|
+
<button class="ai-tab-btn active" data-vision-tab="upload">\u{1F4E4} Upload</button>
|
|
482
|
+
<button class="ai-tab-btn" data-vision-tab="mapping">\u{1F3AF} Mapping</button>
|
|
483
|
+
<button class="ai-tab-btn" data-vision-tab="apply">\u2705 Apply</button>
|
|
484
|
+
</div>
|
|
485
|
+
|
|
486
|
+
<!-- UPLOAD TAB -->
|
|
487
|
+
<div class="ai-tab-content active" data-vision-content="upload">
|
|
488
|
+
<div class="panel-section">
|
|
489
|
+
<div class="panel-section-title">1. API Key</div>
|
|
490
|
+
<input class="inspector-input" type="password" data-vision-api-key placeholder="Gemini API Key" value="">
|
|
491
|
+
</div>
|
|
492
|
+
|
|
493
|
+
<div class="panel-section">
|
|
494
|
+
<div class="panel-section-title">2. Upload Method</div>
|
|
495
|
+
<div class="inspector-row">
|
|
496
|
+
<select class="inspector-input" data-vision-upload-method style="flex:1;">
|
|
497
|
+
<option value="individual">Individual Files</option>
|
|
498
|
+
<option value="zip">ZIP Package</option>
|
|
499
|
+
</select>
|
|
500
|
+
</div>
|
|
501
|
+
</div>
|
|
502
|
+
|
|
503
|
+
<!-- INDIVIDUAL FILES UPLOAD -->
|
|
504
|
+
<div class="vision-upload-section active" data-vision-upload-section="individual">
|
|
505
|
+
<div class="panel-section">
|
|
506
|
+
<div class="panel-section-title">Brand Configs (JSON)</div>
|
|
507
|
+
<div class="inspector-row">
|
|
508
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-vision-upload-manifest>\u{1F4C4} Upload JSONs</button>
|
|
509
|
+
<input class="hidden" type="file" accept=".json" multiple data-vision-manifest-input>
|
|
510
|
+
<div class="inspector-text-sm" data-vision-manifest-status style="white-space: pre-wrap;">None</div>
|
|
511
|
+
</div>
|
|
512
|
+
</div>
|
|
513
|
+
|
|
514
|
+
<div class="panel-section">
|
|
515
|
+
<div class="panel-section-title">Asset Files (PNG)</div>
|
|
516
|
+
<div class="inspector-row">
|
|
517
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-vision-upload-assets>\u{1F4F7} Upload PNGs</button>
|
|
518
|
+
<input class="hidden" type="file" accept="image/*" multiple data-vision-assets-input>
|
|
519
|
+
<span class="inspector-text-sm" data-vision-assets-status>None</span>
|
|
520
|
+
</div>
|
|
521
|
+
</div>
|
|
522
|
+
|
|
523
|
+
<div class="panel-section">
|
|
524
|
+
<div class="panel-section-title">Flat Design (Style Reference)</div>
|
|
525
|
+
<div class="inspector-row">
|
|
526
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-vision-upload-flat>\u{1F3A8} Upload Flat Design</button>
|
|
527
|
+
<input class="hidden" type="file" accept="image/*" data-vision-flat-input>
|
|
528
|
+
<span class="inspector-text-sm" data-vision-flat-status>None</span>
|
|
529
|
+
</div>
|
|
530
|
+
<div class="vision-flat-preview" data-vision-flat-preview></div>
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
|
|
534
|
+
<!-- ZIP PACKAGE UPLOAD -->
|
|
535
|
+
<div class="vision-upload-section" data-vision-upload-section="zip">
|
|
536
|
+
<div class="panel-section">
|
|
537
|
+
<div class="panel-section-title">ZIP Package</div>
|
|
538
|
+
<div class="inspector-row">
|
|
539
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-vision-upload-zip>\u{1F4E6} Upload ZIP</button>
|
|
540
|
+
<input class="hidden" type="file" accept=".zip" data-vision-zip-input>
|
|
541
|
+
<span class="inspector-text-sm" data-vision-zip-status>None</span>
|
|
542
|
+
</div>
|
|
543
|
+
<div class="inspector-text-sm" style="margin-top: 8px; color: #888;">
|
|
544
|
+
ZIP should contain: assets/ folder with PNGs, brandDna.json, positionnormalizedpack.json
|
|
545
|
+
</div>
|
|
546
|
+
</div>
|
|
547
|
+
</div>
|
|
548
|
+
|
|
549
|
+
<div class="panel-section">
|
|
550
|
+
<div class="inspector-row">
|
|
551
|
+
<button class="inspector-btn primary" type="button" data-vision-analyze>\u{1F50D} Analyze & Map</button>
|
|
552
|
+
<span class="inspector-status" data-vision-upload-status>Ready</span>
|
|
553
|
+
</div>
|
|
554
|
+
</div>
|
|
555
|
+
</div>
|
|
556
|
+
|
|
557
|
+
<!-- MAPPING TAB -->
|
|
558
|
+
<div class="ai-tab-content" data-vision-content="mapping">
|
|
559
|
+
<div class="panel-section">
|
|
560
|
+
<div class="panel-section-title">Mapping Plan</div>
|
|
561
|
+
<div class="inspector-status" data-vision-mapping-status>Run analysis first</div>
|
|
562
|
+
<div class="vision-mapping-list" data-vision-mappings></div>
|
|
563
|
+
</div>
|
|
564
|
+
</div>
|
|
565
|
+
|
|
566
|
+
<!-- APPLY TAB -->
|
|
567
|
+
<div class="ai-tab-content" data-vision-content="apply">
|
|
568
|
+
<div class="panel-section">
|
|
569
|
+
<div class="panel-section-title">Generation & Apply</div>
|
|
570
|
+
<div class="inspector-row">
|
|
571
|
+
<button class="inspector-btn" type="button" data-vision-generate-all>\u{1F916} Generate Missing</button>
|
|
572
|
+
<button class="inspector-btn primary" type="button" data-vision-apply-all>\u2705 Apply All</button>
|
|
573
|
+
</div>
|
|
574
|
+
<div class="inspector-status" data-vision-apply-status>Ready</div>
|
|
575
|
+
<div class="vision-progress-list" data-vision-progress></div>
|
|
576
|
+
</div>
|
|
577
|
+
</div>
|
|
578
|
+
|
|
579
|
+
</div>
|
|
580
|
+
<div class="panel-resize-handle" data-panel-resize></div>
|
|
581
|
+
</div>
|
|
582
|
+
`}initialize(e,t){this.root=e.querySelector('[data-panel="brand-vision"]'),this.onClose=t,this.root&&(this.attachEventListeners(),this.setupResizeHandle())}attachEventListeners(){var t,i,n,r,s,o,l,c,p,d,u,g,f;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let h="/dashboard";window.location.pathname!==h&&(window.location.href=h)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(h=>{h.addEventListener("click",()=>{let m=h.dataset.visionTab;this.switchTab(m)})}),(i=this.root.querySelector("[data-vision-upload-method]"))==null||i.addEventListener("change",h=>{let m=h.target.value;this.switchUploadMethod(m)}),(n=this.root.querySelector("[data-vision-upload-manifest]"))==null||n.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-manifest-input]"))==null||m.click()}),(r=this.root.querySelector("[data-vision-upload-zip]"))==null||r.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-zip-input]"))==null||m.click()}),(s=this.root.querySelector("[data-vision-zip-input]"))==null||s.addEventListener("change",h=>{this.handleZipUpload(h)}),(o=this.root.querySelector("[data-vision-manifest-input]"))==null||o.addEventListener("change",h=>{this.handleManifestUpload(h)}),(l=this.root.querySelector("[data-vision-upload-assets]"))==null||l.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-assets-input]"))==null||m.click()}),(c=this.root.querySelector("[data-vision-assets-input]"))==null||c.addEventListener("change",h=>{this.handleAssetsUpload(h)}),(p=this.root.querySelector("[data-vision-upload-flat]"))==null||p.addEventListener("click",()=>{var h,m;(m=(h=this.root)==null?void 0:h.querySelector("[data-vision-flat-input]"))==null||m.click()}),(d=this.root.querySelector("[data-vision-flat-input]"))==null||d.addEventListener("change",h=>{this.handleFlatDesignUpload(h)}),(u=this.root.querySelector("[data-vision-analyze]"))==null||u.addEventListener("click",()=>{this.runAnalysis()}),(g=this.root.querySelector("[data-vision-generate-all]"))==null||g.addEventListener("click",()=>{this.generateAllMissing()}),(f=this.root.querySelector("[data-vision-apply-all]"))==null||f.addEventListener("click",()=>{this.applyAll()});let e=this.root.querySelector("[data-vision-mappings]");e==null||e.addEventListener("click",h=>{let m=h.target;if(!m)return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;y&&(m.closest("[data-mapping-apply-one]")&&this.applyOne(y),m.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(y),m.closest("[data-mapping-edit-one]")&&this.openEditorForOne(y),m.closest("[data-mapping-generate-one]")&&this.generateOne(y),m.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",h=>{let m=h.target;if(!m||!this.mappingResult)return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;if(!y)return;let v=this.mappingResult.mappings.find(x=>x.game_object===y);v&&(m.matches("[data-mapping-action]")&&(v.action=String(m.value||"KEEP"),v.status="Edited",this.renderMappings()),m.matches("[data-mapping-brand-asset]")&&(v.brand_asset=String(m.value||""),v.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",h=>{let m=h.target;if(!m||!this.mappingResult||!m.matches("[data-mapping-prompt]"))return;let b=m.closest("[data-mapping-item]"),y=b==null?void 0:b.dataset.mappingItem;if(!y)return;let v=this.mappingResult.mappings.find(x=>x.game_object===y);v&&(v.generation_prompt=String(m.value||""),v.status="Edited")})}switchTab(e){var t,i;this.root&&(this.currentTab=e,this.root.querySelectorAll("[data-vision-tab]").forEach(n=>n.classList.remove("active")),this.root.querySelectorAll("[data-vision-content]").forEach(n=>n.classList.remove("active")),(t=this.root.querySelector(`[data-vision-tab="${e}"]`))==null||t.classList.add("active"),(i=this.root.querySelector(`[data-vision-content="${e}"]`))==null||i.classList.add("active"))}switchUploadMethod(e){var t;this.root&&(this.uploadMethod=e,this.root.querySelectorAll("[data-vision-upload-section]").forEach(i=>{i.classList.remove("active")}),(t=this.root.querySelector(`[data-vision-upload-section="${e}"]`))==null||t.classList.add("active"))}async handleZipUpload(e){var n;let i=(n=e.target.files)==null?void 0:n[0];if(i){this.zipFile=i,this.setStatus("zip",`Selected: ${i.name} (${(i.size/1024/1024).toFixed(2)} MB)`);try{await this.processZipFile(i)}catch(r){console.error("[BrandVision] ZIP processing failed:",r),this.setStatus("zip",`Error: ${r instanceof Error?r.message:"Unknown error"}`)}}}async processZipFile(e){var s,o;let t=await ms.loadAsync(e),i=[],n=[];t.forEach((l,c)=>{let p=l.toLowerCase();p.endsWith(".json")?i.push({name:l,content:null}):p.startsWith("assets/")&&p.endsWith(".png")&&n.push({name:l,file:c})});for(let l of i)try{let c=await((s=t.file(l.name))==null?void 0:s.async("text"));c&&(l.content=JSON.parse(c))}catch(c){console.warn(`Failed to parse ${l.name}:`,c)}let r=new Map;for(let l of n)try{let c=await l.file.async("uint8array"),p=new Blob([c],{type:"image/png"}),d=l.name.split("/").pop()||l.name;console.log(`Processing ${d}, uint8array length: ${c.length}, blob size: ${p.size}`);let u;try{u=await this.blobToDataUrl(p)}catch(m){console.warn(`FileReader failed for ${d}, using fallback:`,m),u=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(c)))}`}if(console.log(`Data URL length: ${u.length}, starts with: ${u.substring(0,50)}...`),!u.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${d}:`,u.substring(0,100));continue}let g=this.inferAssetCategory(d.replace(".png",""));console.log(`Saving ${d} to category: ${g}`);let h=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:g,filename:d,data:u,overwrite:!0})})).json();if(console.log(`Save result for ${d}:`,h),h.success){console.log(`\u2705 Saved PNG to library: ${d} (${g}) at ${h.path}`);let m=new File([p],d,{type:"image/png"});r.set(d,m)}else console.warn(`\u274C Failed to save ${d}:`,h.error)}catch(c){console.warn(`Failed to extract ${l.name}:`,c)}this.uploadedJsons.clear(),i.forEach(({name:l,content:c})=>{c&&this.uploadedJsons.set(l,c)}),this.assetFiles=r;try{this.normalizedManifest=Ki(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let l=[];for(let[p,d]of r){let u=await this.fileToDataUrl(d);l.push({id:p.replace(".png",""),filename:p,dataUrl:u,category:this.inferAssetCategory(p.replace(".png",""))})}this.normalizedManifest&&(this.normalizedManifest.assets=l);let c=l.length;this.setStatus("zip",`\u2705 Processed: ${i.length} JSONs, ${c} PNGs
|
|
583
|
+
\u{1F3F7}\uFE0F Brand: ${((o=this.normalizedManifest)==null?void 0:o.brand_name)||"Imported Brand"}`),this.addAssetsToRegistry(l),this.refreshLibrary()}catch(l){console.error("[BrandVision] Failed to normalize ZIP manifest:",l),this.normalizedManifest=null,this.setStatus("zip","\u274C Failed to normalize manifest")}}async fileToDataUrl(e){return new Promise((t,i)=>{let n=new FileReader;n.onload=()=>t(n.result),n.onerror=i,n.readAsDataURL(e)})}async blobToDataUrl(e){return new Promise((t,i)=>{let n=new FileReader;n.onload=()=>{let r=n.result;console.log("FileReader result type:",typeof r,"length:",r.length),console.log("Data URL prefix:",r.substring(0,30)),t(r)},n.onerror=r=>{console.error("FileReader error:",r),i(r)},n.readAsDataURL(e)})}inferAssetCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"misc"}addAssetsToRegistry(e){let t=window.getEditableAssets;if(typeof t!="function")return;let i=t();if(!(i!=null&&i.libraryAssets))return;let n={};for(let r of e){let s=r.category||"misc";n[s]||(n[s]=[]),i.libraryAssets[s]||(i.libraryAssets[s]=[]),i.libraryAssets[s].some(l=>l.filename===r.filename)||(i.libraryAssets[s].unshift({filename:r.filename,displayName:r.id.replace(/_/g," ").replace(/\b\w/g,l=>l.toUpperCase())}),console.log(`[BrandVision] Added ${r.filename} to registry category ${s}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var r;let t=e.target,i=t.files;if(!i||i.length===0)return;this.uploadedJsons.clear(),this.normalizedManifest=null,this.mappingResult=null;let n="";for(let s of Array.from(i))try{let o=await s.text(),l=JSON.parse(o);this.uploadedJsons.set(s.name,l),l.layers?n+=`\u2705 Layers: ${s.name}
|
|
584
|
+
`:l.brand_dna||l.colors?n+=`\u2705 Brand: ${s.name}
|
|
585
|
+
`:n+=`\u2705 Loaded: ${s.name}
|
|
586
|
+
`}catch{n+=`\u274C Error in ${s.name}
|
|
587
|
+
`}try{this.normalizedManifest=Ki(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let s=Array.isArray((r=this.normalizedManifest)==null?void 0:r.assets)?this.normalizedManifest.assets.length:0;n+=`
|
|
588
|
+
\u{1F4E6} Normalized manifest: ${s} assets`,n+=`
|
|
589
|
+
\u{1F3F7}\uFE0F Brand: ${this.normalizedManifest.brand_name||"Imported Brand"}`,console.info("[BrandVision] Normalized manifest",{jsonFiles:Array.from(this.uploadedJsons.keys()),assetsType:typeof this.normalizedManifest.assets,assetsCount:s,brandName:this.normalizedManifest.brand_name})}catch(s){console.error("[BrandVision] Failed to normalize manifest:",s),this.normalizedManifest=null,n+=`
|
|
590
|
+
\u274C Failed to normalize manifest`}t.value="",this.setStatus("manifest",n.trim())}async handleAssetsUpload(e){let i=e.target.files;if(!(!i||i.length===0)){for(let n of Array.from(i))this.assetFiles.set(n.name,n);this.setStatus("assets",`${this.assetFiles.size} files loaded`)}}async handleFlatDesignUpload(e){var r,s;let i=(r=e.target.files)==null?void 0:r[0];if(!i)return;let n=await Le(i);if(n){this.flatDesignDataUrl=n.dataUrl,this.setStatus("flat",i.name);let o=(s=this.root)==null?void 0:s.querySelector("[data-vision-flat-preview]");o&&(o.innerHTML=`<img src="${n.dataUrl}" style="max-width:100%;max-height:100px;border-radius:4px;">`)}}async runAnalysis(){var i,n,r,s,o,l,c;if(this.isAnalyzing)return;let e=(r=(n=(i=this.root)==null?void 0:i.querySelector("[data-vision-api-key]"))==null?void 0:n.value)==null?void 0:r.trim();if(!e){this.setStatus("upload","Missing API key");return}let t=this.manifest;if(!t){this.setStatus("upload","Upload manifest first");return}Array.isArray(t.assets)||console.warn("[BrandVision] Manifest assets not array at analysis time; continuing with normalization fallback.",{assets:t.assets}),this.isAnalyzing=!0,this.setStatus("upload","Analyzing...");try{await Qa(t,this.assetFiles);let p={apiKey:e,manifest:t,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()},d=await Ja(p);this.mappingResult=d.mappingResult,this.analysisRawResponse=d.rawResponse,this.analysisParsedOk=d.parsed,this.analysisParseError=(s=d.parseError)!=null?s:null,this.renderMappings(),d.parsed?(this.setStatus("upload","Analysis complete"),this.setStatus("mapping",`${(c=(l=(o=this.mappingResult)==null?void 0:o.mappings)==null?void 0:l.length)!=null?c:0} objects mapped`)):(this.setStatus("upload","Analysis response was not JSON"),this.setStatus("mapping",`Parse failed: ${d.parseError||"Unknown error"}`)),this.switchTab("mapping")}catch(p){console.error("[BrandVision] Analysis failed:",p),this.setStatus("upload","Analysis failed")}finally{this.isAnalyzing=!1}}async generateAllMissing(){var t,i,n;if(this.isGenerating||!this.mappingResult||!this.manifest)return;let e=(n=(i=(t=this.root)==null?void 0:t.querySelector("[data-vision-api-key]"))==null?void 0:i.value)==null?void 0:n.trim();if(!e){this.setStatus("apply","Missing API key");return}this.isGenerating=!0;try{let r={apiKey:e,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await Xi(r,this.mappingResult,{onProgress:(s,o,l)=>{this.setStatus("apply",`Generating ${s}/${o}: ${l}`),this.renderMappings()}}),this.setStatus("apply","Generation complete"),this.renderMappings()}catch(r){console.error("[BrandVision] Generation failed:",r),this.setStatus("apply","Generation failed")}finally{this.isGenerating=!1}}renderMappings(){var o;let e=(o=this.root)==null?void 0:o.querySelector("[data-vision-mappings]");if(!e||!this.mappingResult)return;let t=this.manifest,i=this.getEngineAssets(),n=!!this.analysisRawResponse&&this.analysisParsedOk===!1,r=((t==null?void 0:t.assets)||[]).map(l=>`<option value="${l.id}">${l.id}</option>`).join(""),s=n?`
|
|
591
|
+
<div class="vision-raw-block">
|
|
592
|
+
<div class="inspector-text-sm" style="white-space: pre-wrap;">
|
|
593
|
+
\u26A0\uFE0F AI response was not valid JSON (${this.analysisParseError||"unknown error"}).
|
|
594
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-mapping-copy-raw style="margin-left:8px;">Copy raw</button>
|
|
595
|
+
</div>
|
|
596
|
+
<textarea class="inspector-input vision-raw-textarea" readonly>${this.analysisRawResponse||""}</textarea>
|
|
597
|
+
</div>
|
|
598
|
+
`:"";e.innerHTML=`
|
|
599
|
+
${s}
|
|
600
|
+
${this.mappingResult.mappings.map(l=>{var b;let c=i[l.game_object]||"",p=l.brand_asset||"",d=(b=t==null?void 0:t.assets)==null?void 0:b.find(y=>y.id===p),u=(d==null?void 0:d.dataUrl)||"",g=l.output_dataUrl||"",f=l.action==="GENERATE"?g:l.action==="APPLY"?u:"",h=!!f,m=`
|
|
601
|
+
<select class="inspector-input" data-mapping-brand-asset style="flex:1; padding:6px 8px;">
|
|
602
|
+
<option value="">Select brand asset\u2026</option>
|
|
603
|
+
${r.replace(`value="${p}"`,`value="${p}" selected`)}
|
|
604
|
+
</select>
|
|
605
|
+
`;return`
|
|
606
|
+
<div class="vision-mapping-item" data-mapping-item="${l.game_object}">
|
|
607
|
+
<div class="vision-mapping-header">
|
|
608
|
+
<span class="vision-mapping-object">${l.game_object}</span>
|
|
609
|
+
<select class="inspector-input vision-mapping-select" data-mapping-action>
|
|
610
|
+
<option value="APPLY" ${l.action==="APPLY"?"selected":""}>APPLY</option>
|
|
611
|
+
<option value="GENERATE" ${l.action==="GENERATE"?"selected":""}>GENERATE</option>
|
|
612
|
+
<option value="KEEP" ${l.action==="KEEP"?"selected":""}>KEEP</option>
|
|
613
|
+
</select>
|
|
614
|
+
</div>
|
|
615
|
+
|
|
616
|
+
${l.action==="APPLY"?`
|
|
617
|
+
<div class="inspector-row" style="margin-top:8px;">
|
|
618
|
+
${m}
|
|
619
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-mapping-edit-one>Edit/Crop\u2026</button>
|
|
620
|
+
</div>
|
|
621
|
+
`:""}
|
|
622
|
+
|
|
623
|
+
${l.action==="GENERATE"?`
|
|
624
|
+
<div style="margin-top:8px;">
|
|
625
|
+
<div class="inspector-text-sm" style="opacity:0.9;">Prompt</div>
|
|
626
|
+
<textarea class="inspector-input vision-mapping-prompt" data-mapping-prompt>${l.generation_prompt||""}</textarea>
|
|
627
|
+
<div class="inspector-row" style="margin-top:8px;">
|
|
628
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-mapping-generate-one>Generate</button>
|
|
629
|
+
<button class="inspector-btn inspector-btn-sm" type="button" data-mapping-edit-one>Edit/Crop\u2026</button>
|
|
630
|
+
</div>
|
|
631
|
+
</div>
|
|
632
|
+
`:""}
|
|
633
|
+
|
|
634
|
+
<div class="vision-mapping-row">
|
|
635
|
+
<div class="vision-mapping-current">
|
|
636
|
+
<div class="inspector-text-sm" style="opacity:0.8;">Current</div>
|
|
637
|
+
<div class="inspector-text-sm" style="white-space: pre-wrap; word-break: break-all;">${c||"(empty)"}</div>
|
|
638
|
+
</div>
|
|
639
|
+
<div class="vision-mapping-preview">
|
|
640
|
+
<div class="inspector-text-sm" style="opacity:0.8;">Preview</div>
|
|
641
|
+
${h?`<img src="${f}">`:'<div class="inspector-text-sm" style="opacity:0.6;">None</div>'}
|
|
642
|
+
</div>
|
|
643
|
+
</div>
|
|
644
|
+
|
|
645
|
+
<div class="vision-mapping-actions">
|
|
646
|
+
<button class="inspector-btn inspector-btn-sm primary" type="button" data-mapping-apply-one>Stage Override</button>
|
|
647
|
+
<button class="inspector-btn inspector-btn-sm success" type="button" data-mapping-save-one>Save to Library + Apply</button>
|
|
648
|
+
<span class="inspector-status vision-mapping-status">${l.status||"Ready"}</span>
|
|
649
|
+
</div>
|
|
650
|
+
</div>
|
|
651
|
+
`}).join("")}
|
|
652
|
+
`}async applyAll(){let e=await this.stageOverridesFromMappings({saveToLibrary:!1});this.setStatus("apply",e>0?`Staged ${e} asset overrides`:"No assets to stage")}getEngineAssets(){let e=window.getEditableEngineConfig;if(typeof e!="function")return{};let t=e();return t!=null&&t.assets&&typeof t.assets=="object"?t.assets:{}}getPreviewValueForMapping(e){if(!this.mappingResult||!this.manifest)return{value:null,source:"none"};let t=this.mappingResult.mappings.find(i=>i.game_object===e);if(!t)return{value:null,source:"none"};if(t.action==="GENERATE"&&t.output_dataUrl)return{value:t.output_dataUrl,source:"generated"};if(t.action==="APPLY"&&t.brand_asset){let i=this.manifest.assets.find(n=>n.id===t.brand_asset);if(i!=null&&i.dataUrl)return{value:i.dataUrl,source:"brand"}}return{value:null,source:"none"}}async stageOverridesFromMappings(e){if(!this.mappingResult)return 0;let t=0;for(let i of this.mappingResult.mappings){if(i.action==="KEEP"||i.action==="APPLY"&&!i.brand_asset||i.action==="GENERATE"&&!i.output_dataUrl)continue;let n=i.game_object,r=this.getPreviewValueForMapping(n);if(!r.value)continue;let s=e.saveToLibrary?await this.saveToLibraryAndReturnPath(n,r.value):r.value;s&&(await this.stageEngineAssetOverride(n,s),i.status=e.saveToLibrary?"Saved + staged \u2713":"Staged \u2713",t++)}return this.renderMappings(),t}async applyOne(e){var n;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to apply for ${e}`);return}await this.stageEngineAssetOverride(e,t.value);let i=(n=this.mappingResult)==null?void 0:n.mappings.find(r=>r.game_object===e);i&&(i.status="Staged \u2713"),this.renderMappings(),this.setStatus("apply",`Staged override for ${e}`)}async saveAndApplyOne(e){var r;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to save for ${e}`);return}let i=await this.saveToLibraryAndReturnPath(e,t.value);if(!i){this.setStatus("apply",`Save failed for ${e}`);return}await this.stageEngineAssetOverride(e,i);let n=(r=this.mappingResult)==null?void 0:r.mappings.find(s=>s.game_object===e);n&&(n.status="Saved + staged \u2713"),this.renderMappings(),this.setStatus("apply",`Saved + staged ${e}`)}openEditorForOne(e){if(!this.mappingResult)return;let t=this.mappingResult.mappings.find(s=>s.game_object===e);if(!t)return;let i=this.getPreviewValueForMapping(e),n=window.__openAiEditor;if(typeof n!="function"){this.setStatus("apply","AI editor not available");return}let r=t.action==="GENERATE"?t.generation_prompt:void 0;n(e,r,i.value||void 0,{path:`assets.${e}`})}async generateOne(e){var n,r,s;if(!this.mappingResult||this.isGenerating)return;let t=this.mappingResult.mappings.find(o=>o.game_object===e);if(!t)return;if(t.action="GENERATE",!t.generation_prompt){t.status="Missing prompt",this.renderMappings();return}let i=(s=(r=(n=this.root)==null?void 0:n.querySelector("[data-vision-api-key]"))==null?void 0:r.value)==null?void 0:s.trim();if(!i||!this.manifest){this.setStatus("apply","Missing API key or manifest");return}this.isGenerating=!0,t.status="Generating\u2026",this.renderMappings();try{let o={apiKey:i,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await Xi(o,{mappings:[t]}),t.status=t.output_dataUrl?"Generated \u2713":t.status||"Done"}catch(o){console.error("[BrandVision] generateOne failed:",o),t.status="Failed \u2717"}finally{this.isGenerating=!1,this.renderMappings()}}async stageEngineAssetOverride(e,t){let{applyConfigOverride:i}=await import("./ConfigOverride-RARXNEZC.js");i({path:`assets.${e}`,value:t},{silent:!0});let n=window.applyEditableEngineConfig;typeof n=="function"&&n({assets:{[e]:t}})}async saveToLibraryAndReturnPath(e,t){if(!/^(data:|blob:)/.test(t))return t;let i=this.inferCategoryFromAssetKey(e),n=`${e.replace(/[^a-zA-Z0-9_-]/g,"_")}_vision_${Date.now()}.png`;try{let s=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:i,filename:n,data:t,overwrite:!0})})).json();if(!(s!=null&&s.success)||!(s!=null&&s.path))return console.error("[BrandVision] Save to library failed:",(s==null?void 0:s.error)||s),null;let o=window.addAssetToRegistry;typeof o=="function"&&o(i,n);let l=window.refreshAssetLibrary;return typeof l=="function"&&l(),String(s.path)}catch(r){return console.error("[BrandVision] Save to library error:",r),null}}inferCategoryFromAssetKey(e){let t=window.getEditableAssets;if(typeof t=="function"){let n=t();if(n!=null&&n.slots&&Array.isArray(n.slots)){let s=n.slots.find(o=>o.slotId===e||o.currentAsset===e);if(s!=null&&s.category)return String(s.category)}let r=n==null?void 0:n.categories;if(Array.isArray(r)&&r.length>0){let s=e.toLowerCase(),o=l=>r.find(c=>c.toLowerCase().includes(l));return s.includes("bg")||s.includes("background")?o("background")||r[0]:(s.includes("cta")||s.includes("button")||s.includes("ui")||s.includes("logo"))&&o("ui")||r[0]}}let i=e.toLowerCase();return i.includes("bg")||i.includes("background")?"backgrounds":i.includes("cta")||i.includes("button")||i.includes("ui")||i.includes("logo")?"ui":"misc"}async copyRawAnalysis(){if(this.analysisRawResponse)try{await navigator.clipboard.writeText(this.analysisRawResponse),this.setStatus("mapping","Copied raw analysis to clipboard")}catch{this.setStatus("mapping","Clipboard not available")}}setStatus(e,t){var r;let i={manifest:"[data-vision-manifest-status]",assets:"[data-vision-assets-status]",flat:"[data-vision-flat-status]",zip:"[data-vision-zip-status]",upload:"[data-vision-upload-status]",mapping:"[data-vision-mapping-status]",apply:"[data-vision-apply-status]"},n=(r=this.root)==null?void 0:r.querySelector(i[e]);n&&(n.textContent=t)}getGameObjects(){let e=window.getEditableObjectList;return typeof e=="function"?e():[]}async getGamePrompt(){try{let e=await fetch("./configs/engine/game.prompt.json");if(e.ok)return(await e.json()).game_prompt||""}catch{}return""}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");e&&e.addEventListener("pointerdown",t=>{let i=t.clientX,n=this.root.getBoundingClientRect().width,r=o=>{let l=Math.max(300,n+(o.clientX-i));this.root.style.width=`${l}px`},s=()=>{window.removeEventListener("pointermove",r),window.removeEventListener("pointerup",s)};window.addEventListener("pointermove",r),window.addEventListener("pointerup",s)})}refresh(){}};function er(a,e={}){let{includeReference:t=!1,includeMagenta:i=!0,changeLevel:n=5}=e;return[`TASK: ${a}`,`CHANGE_STRENGTH: ${n}/10`,t?"REFERENCE: provided":"REFERENCE: none",i?"BACKGROUND: solid magenta #FF00FF (if possible)":""].filter(Boolean).join(`
|
|
653
|
+
`)}var bs=["background_color","text_color","cta_background","cta_text","warning_text_color","endgame_title_color","endgame_subtitle_color","endgame_cta_text_color","endgame_cta_hint_color","endgame_footer_color"],ys=["cta_hint","cta_label_end"],tr=[{key:"warning_text",objectId:"label.warning",property:"ui.text"},{key:"endgame_title",objectId:"ui.endgame.title",property:"ui.text"},{key:"endgame_subtitle",objectId:"ui.endgame.subtitle",property:"ui.text"},{key:"endgame_cta_text",objectId:"ui.endgame.cta",property:"ui.text"},{key:"endgame_cta_hint_text",objectId:"ui.endgame.cta.hint",property:"ui.text"},{key:"endgame_footer_text",objectId:"ui.endgame.footer",property:"ui.text"}],vs=["brand.primary","brand.heading","brand.body","brand.warning"],ei=class{constructor(){this.root=null;this.assetsContainer=null;this.colorsContainer=null;this.fontsContainer=null;this.textsContainer=null;this.audioContainer=null;this.options=null;this.previewModal=null;this.autoApplyTimer=null;this.activePreviewKey=null;this.activePreviewValue=null;this.activePreviewFileInput=null;this.retryTimer=null;this.aiModal=null;this.aiTargetKey=null;this.aiKeyInput=null;this.aiPromptInput=null;this.aiStrengthInput=null;this.aiStrengthValue=null;this.aiModelSelect=null;this.aiModalSubtitle=null;this.aiGalleryToggle=null;this.aiGalleryEl=null;this.aiGalleryGrid=null;this.aiReferenceInput=null;this.aiReferenceName=null;this.aiReferenceFile=null;this.aiRemoveBgToggle=null;this.aiUseOutputToggle=null;this.aiGenerateBtn=null;this.aiApplyBtn=null;this.aiSaveLibraryBtn=null;this.aiCropBtn=null;this.aiDownloadBtn=null;this.aiPreviewImg=null;this.aiStatusEl=null;this.aiOutputDataUrl=null;this.aiBaseDataUrl=null;this.aiBaseValue=null;this.aiOutputKey=null;this.aiContext=null;this.aiBgToleranceInput=null;this.aiBgToleranceValue=null;this.aiRawOutputDataUrl=null;this.aiLoadingEl=null}render(){return`
|
|
654
|
+
<div class="scene-panel customize-panel panel-accent-blue" data-panel="customize-settings">
|
|
655
|
+
<div class="scene-panel-header" data-panel-handle>
|
|
656
|
+
<div class="panel-title">
|
|
657
|
+
<span class="panel-pill">Brand</span>
|
|
658
|
+
<span class="panel-title-text">Customize Settings</span>
|
|
659
|
+
</div>
|
|
660
|
+
<div class="scene-panel-actions">
|
|
661
|
+
<button class="scene-panel-toggle" type="button" data-panel-toggle>\u25BE</button>
|
|
662
|
+
</div>
|
|
663
|
+
</div>
|
|
664
|
+
<div class="scene-panel-body">
|
|
665
|
+
<div class="panel-section">
|
|
666
|
+
<div class="panel-section-title">Assets</div>
|
|
667
|
+
<div class="customize-list" data-customize-assets></div>
|
|
668
|
+
</div>
|
|
669
|
+
<div class="panel-section">
|
|
670
|
+
<div class="panel-section-title">UI Colors</div>
|
|
671
|
+
<div class="customize-grid" data-customize-colors></div>
|
|
672
|
+
</div>
|
|
673
|
+
<div class="panel-section">
|
|
674
|
+
<div class="panel-section-title">Fonts</div>
|
|
675
|
+
<div class="customize-grid" data-customize-fonts></div>
|
|
676
|
+
<div class="customize-help">Font IDs only (ex: brand.primary). Mapping is applied later.</div>
|
|
677
|
+
</div>
|
|
678
|
+
<div class="panel-section">
|
|
679
|
+
<div class="panel-section-title">Texts</div>
|
|
680
|
+
<div class="customize-list" data-customize-texts></div>
|
|
681
|
+
</div>
|
|
682
|
+
<div class="panel-section">
|
|
683
|
+
<div class="panel-section-title">Audio</div>
|
|
684
|
+
<div class="customize-list" data-customize-audio></div>
|
|
685
|
+
</div>
|
|
686
|
+
<div class="panel-section">
|
|
687
|
+
<div class="panel-section-title">Render Modes</div>
|
|
688
|
+
<div class="customize-list" data-customize-render-modes>
|
|
689
|
+
<div class="customize-row">
|
|
690
|
+
<label class="customize-toggle-label">
|
|
691
|
+
<input type="checkbox" data-render-mode="endgame-png" />
|
|
692
|
+
<span>EndGame PNG Mode</span>
|
|
693
|
+
</label>
|
|
694
|
+
<div class="customize-help">Convert all EndGame elements to PNG images</div>
|
|
695
|
+
</div>
|
|
696
|
+
<div class="customize-row">
|
|
697
|
+
<label class="customize-toggle-label">
|
|
698
|
+
<input type="checkbox" data-render-mode="splash-png" />
|
|
699
|
+
<span>Splash PNG Mode</span>
|
|
700
|
+
</label>
|
|
701
|
+
<div class="customize-help">Use a single full-screen PNG for splash</div>
|
|
702
|
+
</div>
|
|
703
|
+
</div>
|
|
704
|
+
</div>
|
|
705
|
+
<div class="debug-btn-group">
|
|
706
|
+
<button class="debug-btn primary" data-customize-apply>Apply & Restart</button>
|
|
707
|
+
</div>
|
|
708
|
+
</div>
|
|
709
|
+
<div class="panel-resize-handle" data-panel-resize></div>
|
|
710
|
+
</div>
|
|
711
|
+
`}initialize(e,t){var n,r,s,o,l,c;this.options=t,this.root=e.querySelector('[data-panel="customize-settings"]'),this.assetsContainer=(n=this.root)==null?void 0:n.querySelector("[data-customize-assets]"),this.colorsContainer=(r=this.root)==null?void 0:r.querySelector("[data-customize-colors]"),this.fontsContainer=(s=this.root)==null?void 0:s.querySelector("[data-customize-fonts]"),this.textsContainer=(o=this.root)==null?void 0:o.querySelector("[data-customize-texts]"),this.audioContainer=(l=this.root)==null?void 0:l.querySelector("[data-customize-audio]");let i=(c=this.root)==null?void 0:c.querySelector("[data-customize-apply]");i==null||i.addEventListener("click",()=>this.handleApply()),this.setupRenderModeHandlers(),this.setupResizeHandle(),this.refresh()}setupRenderModeHandlers(){var i,n;let e=(i=this.root)==null?void 0:i.querySelector('[data-render-mode="endgame-png"]'),t=(n=this.root)==null?void 0:n.querySelector('[data-render-mode="splash-png"]');e==null||e.addEventListener("change",()=>{this.applyEndgamePngMode(e.checked)}),t==null||t.addEventListener("change",()=>{this.applySplashPngMode(t.checked)})}applyEndgamePngMode(e){let t=window.getEditableObjectConfig,i=window.applyEditableObjectConfig;if(typeof t!="function"||typeof i!="function")return;let n=["ui_endgame_title_1","ui_endgame_subtitle_1","ui_endgame_logo_1","ui_endgame_cta_1"];for(let r of n){let s=t(r);s&&(s.ui||(s.ui={}),s.ui.renderMode=e?"png":"text",e&&(s.render||(s.render={}),s.render.asset||(s.render.asset={type:"image",path:""}),s.render.asset.type="image"),i(r,s))}console.log("[CustomizePanel] EndGame PNG mode:",e?"enabled":"disabled")}applySplashPngMode(e){let t=window.applyEditableEngineConfig;typeof t=="function"&&(t({splash:{type:e?"image":"text",image_path:e?"library/splash/splash.png":""}}),console.log("[CustomizePanel] Splash PNG mode:",e?"enabled":"disabled"))}openAiEditor(e,t,i,n){this.openAiModal(e,i,n),t&&this.aiPromptInput&&(this.aiPromptInput.value=t,this.setAiStatus("Prompt loaded."))}refresh(){var t,i,n,r,s,o,l,c;let e=this.getEngineSnapshot();if(console.log("[CustomizePanel] Refreshing with snapshot:",!!e),!e){this.scheduleRetry();return}console.log("[CustomizePanel] Snapshot assets count:",Object.keys(e.assets||{}).length),this.renderAssets(e.assets),this.renderColors((i=(t=e.runtime)==null?void 0:t.theme)!=null?i:{}),this.renderFonts((r=(n=e.runtime)==null?void 0:n.fonts)!=null?r:{}),this.renderTexts((o=(s=e.runtime)==null?void 0:s.ui)!=null?o:{}),this.renderAudio((c=(l=e.runtime)==null?void 0:l.audio)!=null?c:{})}getEngineSnapshot(){let e=window.getEditableEngineConfig;return typeof e!="function"?null:e()}renderAssets(e){if(!this.assetsContainer)return;this.assetsContainer.innerHTML="";let t=Object.entries(e!=null?e:{});if(!t.length){this.assetsContainer.innerHTML='<div class="customize-empty">No assets found.</div>',this.scheduleRetry();return}this.clearRetry(),t.forEach(([i,n])=>{var u;let r=document.createElement("div");r.className="customize-row";let s=document.createElement("span");s.className="customize-key",s.textContent=i;let o=document.createElement("input");o.type="text",o.value=n!=null?n:"",o.className="customize-input",o.dataset.assetKey=i,o.addEventListener("input",()=>{this.handleAssetValueChange(i,o)});let l=document.createElement("div");l.className="customize-actions";let c=document.createElement("button");c.type="button",c.className="customize-icon-btn",c.title="Preview asset",c.innerHTML=`
|
|
712
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
713
|
+
<path d="M12 5c5.2 0 9.2 3.7 10 6.8-.8 3.1-4.8 6.8-10 6.8S2.8 14.9 2 11.8C2.8 8.7 6.8 5 12 5z" />
|
|
714
|
+
<circle cx="12" cy="12" r="3.2" />
|
|
715
|
+
</svg>
|
|
716
|
+
`,c.addEventListener("click",()=>{this.previewAsset(i,o.value,o.dataset.assetType,d)});let p=document.createElement("button");p.type="button",p.className="customize-icon-btn",p.title="Upload asset",p.innerHTML=`
|
|
717
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
718
|
+
<path d="M12 3l4 4h-3v6h-2V7H8l4-4z" />
|
|
719
|
+
<path d="M5 14v4h14v-4h2v6H3v-6h2z" />
|
|
720
|
+
</svg>
|
|
721
|
+
`;let d=document.createElement("input");d.type="file",d.accept="image/*,audio/*,application/json",d.className="customize-file",d.addEventListener("change",()=>{var f;let g=(f=d.files)==null?void 0:f[0];g&&this.handleAssetUpload(g,o,i)}),p.addEventListener("click",()=>d.click()),l.appendChild(c),l.appendChild(p),l.appendChild(d),r.appendChild(s),r.appendChild(o),r.appendChild(l),(u=this.assetsContainer)==null||u.appendChild(r)})}renderColors(e){this.colorsContainer&&(this.colorsContainer.innerHTML="",bs.forEach(t=>{var l,c,p;let i=(l=e==null?void 0:e[t])!=null?l:"#ffffff";if(t.includes("_text_color")||t.includes("_color")){let u={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[t];u&&(i=(c=this.getObjectPropertyValue(u.objectId,u.property))!=null?c:"#ffffff")}let n=document.createElement("label");n.className="customize-color-field";let r=document.createElement("span");r.textContent=t.replace(/_/g," ");let s=document.createElement("input");s.type="color",s.value=i,s.dataset.colorKey=t;let o=document.createElement("input");o.type="text",o.value=i,o.className="customize-color-text",o.dataset.colorTextKey=t,s.addEventListener("input",()=>{o.value=s.value}),o.addEventListener("input",()=>{/^#([0-9a-fA-F]{6})$/.test(o.value)&&(s.value=o.value)}),n.appendChild(r),n.appendChild(s),n.appendChild(o),(p=this.colorsContainer)==null||p.appendChild(n)}))}renderFonts(e){this.fontsContainer&&(this.fontsContainer.innerHTML="",vs.forEach(t=>{var s,o;let i=document.createElement("div");i.className="customize-row";let n=document.createElement("span");n.className="customize-key",n.textContent=t;let r=document.createElement("input");r.type="text",r.value=(s=e==null?void 0:e[t])!=null?s:t,r.className="customize-input",r.dataset.fontKey=t,i.appendChild(n),i.appendChild(r),(o=this.fontsContainer)==null||o.appendChild(i)}))}renderTexts(e){this.textsContainer&&(this.textsContainer.innerHTML="",ys.forEach(t=>{var s,o;let i=document.createElement("div");i.className="customize-row";let n=document.createElement("span");n.className="customize-key",n.textContent=t;let r=document.createElement("input");r.type="text",r.value=(s=this.readUiValue(e,t))!=null?s:"",r.className="customize-input",r.dataset.textKey=t,i.appendChild(n),i.appendChild(r),(o=this.textsContainer)==null||o.appendChild(i)}),tr.forEach(({key:t,objectId:i})=>{var o,l;let n=document.createElement("div");n.className="customize-row";let r=document.createElement("span");r.className="customize-key",r.textContent=t;let s=document.createElement("input");s.type="text",s.value=(o=this.getObjectTextValue(i))!=null?o:"",s.className="customize-input",s.dataset.objectTextKey=t,n.appendChild(r),n.appendChild(s),(l=this.textsContainer)==null||l.appendChild(n)}))}renderAudio(e){if(!this.audioContainer)return;this.audioContainer.innerHTML="",["background_file","background_volume","click_file","click_volume","success_file","success_volume","complete_file","complete_volume"].forEach(i=>{var o,l;let n=document.createElement("div");n.className="customize-row";let r=document.createElement("span");r.className="customize-key",r.textContent=i.replace("_"," ");let s=document.createElement("input");s.type=i.includes("volume")?"number":"text",s.min="0",s.max="1",s.step="0.1",s.value=String((o=e==null?void 0:e[i])!=null?o:""),s.className="customize-input",s.dataset.audioKey=i,i.includes("file")&&(s.placeholder="audio file path"),n.appendChild(r),n.appendChild(s),(l=this.audioContainer)==null||l.appendChild(n)})}readUiValue(e,t){if(t.includes(".")){let n=t.split("."),r=e;for(let s of n){if(r==null)return null;r=r[s]}return typeof r=="string"?r:null}let i=e==null?void 0:e[t];return typeof i=="string"?i:null}getObjectTextValue(e){var n,r;let t=window.getEditableObjectConfig;if(typeof t!="function")return null;let i=t(e);return(r=(n=i==null?void 0:i.ui)==null?void 0:n.text)!=null?r:null}getObjectPropertyValue(e,t){let i=window.getEditableObjectConfig;if(typeof i!="function")return null;let n=i(e);if(!n)return null;let r=t.split("."),s=n;for(let o of r){if(s==null)return null;s=s[o]}return typeof s=="string"?s:null}handleApply(){this.handleApplyWithSource("manual")}handleApplyWithSource(e){if(console.log(`[CustomizePanel] handleApplyWithSource called with source: ${e}`),!this.root||!this.options)return;let t={};this.root.querySelectorAll("[data-asset-key]").forEach(o=>{let l=o;l.dataset.assetKey&&(t[l.dataset.assetKey]=l.value)}),console.log("[CustomizePanel] Assets being applied:",Object.keys(t).length,"total"),console.log("[CustomizePanel] Asset values:",t);let i={};this.root.querySelectorAll("[data-color-text-key]").forEach(o=>{let l=o,c=l.dataset.colorTextKey;c&&(c.includes("_text_color")||c.includes("_color")?this.applyTextColorToObject(c,l.value):i[c]=l.value)});let n={};this.root.querySelectorAll("[data-font-key]").forEach(o=>{let l=o,c=l.dataset.fontKey;c&&(n[c]=l.value)});let r={};this.root.querySelectorAll("[data-text-key]").forEach(o=>{let l=o,c=l.dataset.textKey;c&&(r[c]=l.value)});let s={};this.root.querySelectorAll("[data-audio-key]").forEach(o=>{let l=o,c=l.dataset.audioKey;if(c)if(c.includes("volume")){let p=parseFloat(l.value);s[c]=isNaN(p)?0:p}else s[c]=l.value}),this.root.querySelectorAll("[data-object-text-key]").forEach(o=>{let l=o,c=l.dataset.objectTextKey;if(!c)return;let p=tr.find(d=>d.key===c);p&&this.applyObjectPropertyValue(p.objectId,p.property,l.value)}),console.log("[CustomizePanel] Calling onApply callback to restart game with source:",e),this.options.onApply({assets:t,runtime:{theme:i,ui:r,fonts:n,audio:s}},{source:e})}setupAiPanel(){}setAiStatus(e){this.aiStatusEl&&(this.aiStatusEl.textContent=e)}getSelectedAssetKey(){return this.aiTargetKey}getSelectedAssetInput(){let e=this.getSelectedAssetKey();return!this.root||!e?null:this.root.querySelector(`input[data-asset-key="${e}"]`)}async getImageDataFromAsset(e){let t=this.resolveAssetUrls(e);console.log("[CustomizePanel] Resolving asset urls for AI:",e,t);for(let i of t)try{let n=await Jt(i);if(n)return console.log("[CustomizePanel] Successfully fetched image data for AI"),{input:{base64:n.base64,mimeType:n.mimeType},dataUrl:n.dataUrl,width:n.width,height:n.height}}catch(n){console.warn("[CustomizePanel] Failed to fetch image data from:",i,n)}return console.error("[CustomizePanel] Could not load image data for AI from any URL"),null}async updateAiBasePreview(e){var n,r,s;let t=(e==null?void 0:e.trim())||"";if(!t){let o=this.getSelectedAssetInput();t=(r=(n=o==null?void 0:o.value)==null?void 0:n.trim())!=null?r:""}if(console.log("[CustomizePanel] updateAiBasePreview using value:",t),!t){this.aiBaseDataUrl=null,this.updateAiPreview();return}let i=await this.getImageDataFromAsset(t);this.aiBaseDataUrl=(s=i==null?void 0:i.dataUrl)!=null?s:null,this.updateAiPreview()}updateAiPreview(){if(!this.aiPreviewImg)return;let e=this.aiOutputDataUrl||this.aiBaseDataUrl||"";if(!e){this.aiPreviewImg.removeAttribute("src");return}this.aiPreviewImg.src=e}updateAiModalPreview(e,t){if(!e)return;let i=t!=null?t:this.activePreviewKey;if(!i||!this.aiOutputDataUrl||this.aiOutputKey!==i){e.classList.add("hidden");return}let n=e.querySelector(".asset-preview-ai-image");n&&(n.src=this.aiOutputDataUrl),e.classList.remove("hidden")}setAiLoading(e){this.aiLoadingEl&&this.aiLoadingEl.classList.toggle("active",e),this.aiGenerateBtn&&(this.aiGenerateBtn.disabled=e)}toggleAiGallery(){if(!this.aiGalleryEl||!this.aiGalleryToggle)return;let e=this.aiGalleryEl.classList.toggle("hidden");this.aiGalleryToggle.textContent=e?"Gallery":"Hide Gallery",e||this.renderAiGallery()}renderAiGallery(){if(!this.aiGalleryGrid)return;let e=this.getAiGalleryEntries();if(!e.length){this.aiGalleryGrid.innerHTML='<div class="ai-gallery-empty">No image assets found.</div>';return}this.aiGalleryGrid.innerHTML="",e.forEach(({key:t,value:i})=>{var l;let n=document.createElement("button");n.type="button",n.className="ai-gallery-item",t===this.aiTargetKey&&n.classList.add("active");let r=document.createElement("img");r.className="ai-gallery-thumb",r.alt=t;let s=this.resolveAssetUrls(i);s[0]&&(r.src=s[0]);let o=document.createElement("span");o.className="ai-gallery-label",o.textContent=t,n.appendChild(r),n.appendChild(o),n.addEventListener("click",()=>this.selectAiGalleryAsset(t)),(l=this.aiGalleryGrid)==null||l.appendChild(n)})}getAiGalleryEntries(){if(!this.root)return[];let e=[];return this.root.querySelectorAll("[data-asset-key]").forEach(t=>{var s,o;let i=t,n=i.dataset.assetKey,r=(o=(s=i.value)==null?void 0:s.trim())!=null?o:"";!n||!r||this.isAiGalleryImage(r)&&e.push({key:n,value:r})}),e}isAiGalleryImage(e){let t=e.trim();if(!t)return!1;if(/^(data:image|blob:)/.test(t))return!0;let i=t.split("?")[0].toLowerCase();return![".mp3",".wav",".ogg",".json"].some(n=>i.endsWith(n))}selectAiGalleryAsset(e){this.aiTargetKey!==e&&(this.aiTargetKey=e,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null,this.aiReferenceInput&&(this.aiReferenceInput.value=""),this.aiReferenceName&&(this.aiReferenceName.textContent="Optional"),this.aiModalSubtitle&&(this.aiModalSubtitle.textContent=e),this.setAiOutputButtonsEnabled(!1),this.updateAiBasePreview(),this.updateAiPreview(),this.renderAiGallery())}openAiModal(e,t,i){var o,l,c,p,d,u,g,f,h,m;this.closeAiModal(),this.aiTargetKey=e,this.aiBaseValue=t||null,this.aiContext=i||null,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null;let n=document.createElement("div");n.className="ai-modal",n.innerHTML=`
|
|
722
|
+
<div class="ai-modal-card">
|
|
723
|
+
<div class="ai-modal-header">
|
|
724
|
+
<div>
|
|
725
|
+
<div class="ai-modal-title">AI Image Edit</div>
|
|
726
|
+
<div class="ai-modal-subtitle">${e}</div>
|
|
727
|
+
</div>
|
|
728
|
+
<div class="ai-modal-actions">
|
|
729
|
+
<button class="ai-modal-gallery" type="button" data-ai-gallery-toggle>Gallery</button>
|
|
730
|
+
<button class="ai-modal-close" type="button">Close</button>
|
|
731
|
+
</div>
|
|
732
|
+
</div>
|
|
733
|
+
<div class="ai-panel">
|
|
734
|
+
<label class="ai-label">API Key</label>
|
|
735
|
+
<input type="password" class="ai-input" data-ai-key placeholder="Paste Gemini API key">
|
|
736
|
+
|
|
737
|
+
<label class="ai-label">Model</label>
|
|
738
|
+
<select class="ai-select" data-ai-model>
|
|
739
|
+
<option value="gemini-2.5-flash-image">Gemini 2.5 Flash (fast)</option>
|
|
740
|
+
<option value="gemini-3-pro-image-preview">Gemini 3 Pro (preview)</option>
|
|
741
|
+
</select>
|
|
742
|
+
|
|
743
|
+
<label class="ai-label">Prompt</label>
|
|
744
|
+
<textarea class="ai-textarea" data-ai-prompt placeholder="Describe the change"></textarea>
|
|
745
|
+
|
|
746
|
+
<div class="ai-row ai-strength">
|
|
747
|
+
<span class="ai-label">Change strength</span>
|
|
748
|
+
<input type="range" min="1" max="10" value="5" data-ai-strength>
|
|
749
|
+
<span class="ai-strength-value" data-ai-strength-value>5</span>
|
|
750
|
+
</div>
|
|
751
|
+
|
|
752
|
+
<div class="ai-gallery hidden" data-ai-gallery>
|
|
753
|
+
<div class="ai-gallery-grid" data-ai-gallery-grid></div>
|
|
754
|
+
</div>
|
|
755
|
+
|
|
756
|
+
<div class="ai-row">
|
|
757
|
+
<button class="ai-btn" type="button" data-ai-ref-button>Reference Image</button>
|
|
758
|
+
<input class="ai-file" type="file" accept="image/*" data-ai-ref-input>
|
|
759
|
+
<span class="ai-file-name" data-ai-ref-name>Optional</span>
|
|
760
|
+
</div>
|
|
761
|
+
|
|
762
|
+
<div class="ai-row ai-toggles">
|
|
763
|
+
<label><input type="checkbox" data-ai-remove-bg checked> Remove BG</label>
|
|
764
|
+
<label><input type="checkbox" data-ai-use-output> Use output as input</label>
|
|
765
|
+
</div>
|
|
766
|
+
|
|
767
|
+
<div class="ai-row ai-strength">
|
|
768
|
+
<span class="ai-label">BG removal sensitivity</span>
|
|
769
|
+
<input type="range" min="0" max="255" value="30" data-ai-bg-tolerance>
|
|
770
|
+
<span class="ai-strength-value" data-ai-bg-tolerance-value>30</span>
|
|
771
|
+
</div>
|
|
772
|
+
|
|
773
|
+
<div class="ai-row ai-actions">
|
|
774
|
+
<button class="debug-btn primary" type="button" data-ai-generate>Generate</button>
|
|
775
|
+
<button class="debug-btn" type="button" data-ai-apply disabled>Apply Output</button>
|
|
776
|
+
<button class="debug-btn success" type="button" data-ai-save-library disabled>\u{1F4BE} Save to Library</button>
|
|
777
|
+
<button class="debug-btn" type="button" data-ai-crop disabled>Crop Output</button>
|
|
778
|
+
<button class="debug-btn" type="button" data-ai-download disabled>Download</button>
|
|
779
|
+
</div>
|
|
780
|
+
|
|
781
|
+
<div class="ai-status" data-ai-status>Idle</div>
|
|
782
|
+
<div class="ai-loading" data-ai-loading>
|
|
783
|
+
<div class="ai-loading-ring"></div>
|
|
784
|
+
<div class="ai-loading-bar"></div>
|
|
785
|
+
<div class="ai-loading-text">Generating\u2026</div>
|
|
786
|
+
</div>
|
|
787
|
+
<div class="ai-preview">
|
|
788
|
+
<img data-ai-preview alt="AI output preview">
|
|
789
|
+
</div>
|
|
790
|
+
</div>
|
|
791
|
+
</div>
|
|
792
|
+
`;let r=n.querySelector(".ai-modal-close");r==null||r.addEventListener("click",()=>this.closeAiModal()),n.addEventListener("click",b=>{b.target===n&&this.closeAiModal()}),this.aiModal=n,this.aiKeyInput=n.querySelector("[data-ai-key]"),this.aiModelSelect=n.querySelector("[data-ai-model]"),this.aiPromptInput=n.querySelector("[data-ai-prompt]"),this.aiStrengthInput=n.querySelector("[data-ai-strength]"),this.aiStrengthValue=n.querySelector("[data-ai-strength-value]"),this.aiModalSubtitle=n.querySelector(".ai-modal-subtitle"),this.aiGalleryToggle=n.querySelector("[data-ai-gallery-toggle]"),this.aiGalleryEl=n.querySelector("[data-ai-gallery]"),this.aiGalleryGrid=n.querySelector("[data-ai-gallery-grid]"),this.aiReferenceInput=n.querySelector("[data-ai-ref-input]"),this.aiReferenceName=n.querySelector("[data-ai-ref-name]"),this.aiRemoveBgToggle=n.querySelector("[data-ai-remove-bg]"),this.aiUseOutputToggle=n.querySelector("[data-ai-use-output]"),this.aiGenerateBtn=n.querySelector("[data-ai-generate]"),this.aiApplyBtn=n.querySelector("[data-ai-apply]"),this.aiSaveLibraryBtn=n.querySelector("[data-ai-save-library]"),this.aiCropBtn=n.querySelector("[data-ai-crop]"),this.aiDownloadBtn=n.querySelector("[data-ai-download]"),this.aiPreviewImg=n.querySelector("[data-ai-preview]"),this.aiStatusEl=n.querySelector("[data-ai-status]"),this.aiLoadingEl=n.querySelector("[data-ai-loading]"),this.aiBgToleranceInput=n.querySelector("[data-ai-bg-tolerance]"),this.aiBgToleranceValue=n.querySelector("[data-ai-bg-tolerance-value]"),(o=this.aiRemoveBgToggle)==null||o.addEventListener("change",()=>{this.refreshAiOutputFromRaw()});let s=n.querySelector("[data-ai-ref-button]");s==null||s.addEventListener("click",()=>{var b;return(b=this.aiReferenceInput)==null?void 0:b.click()}),(l=this.aiGalleryToggle)==null||l.addEventListener("click",()=>this.toggleAiGallery()),(c=this.aiStrengthInput)==null||c.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiStrengthInput)==null?void 0:y.value)!=null?v:"5";this.aiStrengthValue&&(this.aiStrengthValue.textContent=b)}),(p=this.aiBgToleranceInput)==null||p.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiBgToleranceInput)==null?void 0:y.value)!=null?v:"30";this.aiBgToleranceValue&&(this.aiBgToleranceValue.textContent=b),this.refreshAiOutputFromRaw()}),(d=this.aiReferenceInput)==null||d.addEventListener("change",()=>{var y,v,x;let b=(x=(v=(y=this.aiReferenceInput)==null?void 0:y.files)==null?void 0:v[0])!=null?x:null;this.aiReferenceFile=b,this.aiReferenceName&&(this.aiReferenceName.textContent=b?`${b.name} (loaded)`:"Optional"),b&&this.setAiStatus(`Reference attached: ${b.name}`)}),(u=this.aiGenerateBtn)==null||u.addEventListener("click",()=>{this.handleAiGenerate()}),(g=this.aiApplyBtn)==null||g.addEventListener("click",()=>this.handleAiApply()),(f=this.aiSaveLibraryBtn)==null||f.addEventListener("click",()=>{this.handleAiSaveToLibrary()}),(h=this.aiCropBtn)==null||h.addEventListener("click",()=>{this.handleAiCrop()}),(m=this.aiDownloadBtn)==null||m.addEventListener("click",()=>this.handleAiDownload()),document.body.appendChild(n),this.setAiOutputButtonsEnabled(!1),this.setAiStatus("Ready."),this.updateAiBasePreview(t),this.updateAiPreview(),this.renderAiGallery()}closeAiModal(){this.aiModal&&(this.aiModal.remove(),this.aiModal=null),this.aiTargetKey=null,this.aiBaseValue=null,this.aiContext=null,this.aiKeyInput=null,this.aiModelSelect=null,this.aiPromptInput=null,this.aiStrengthInput=null,this.aiStrengthValue=null,this.aiModalSubtitle=null,this.aiGalleryToggle=null,this.aiGalleryEl=null,this.aiGalleryGrid=null,this.aiReferenceInput=null,this.aiReferenceName=null,this.aiReferenceFile=null,this.aiRemoveBgToggle=null,this.aiUseOutputToggle=null,this.aiGenerateBtn=null,this.aiApplyBtn=null,this.aiCropBtn=null,this.aiDownloadBtn=null,this.aiPreviewImg=null,this.aiStatusEl=null,this.aiLoadingEl=null,this.aiBgToleranceInput=null,this.aiBgToleranceValue=null}async handleAiGenerate(){var p,d,u,g,f,h,m,b,y,v,x,w,C,k,P,O,j,T,E,S;if(console.log("[CustomizePanel] handleAiGenerate clicked"),!this.aiGenerateBtn)return;let e=(u=(d=(p=this.aiKeyInput)==null?void 0:p.value)==null?void 0:d.trim())!=null?u:"",t=(f=(g=this.aiModelSelect)==null?void 0:g.value)!=null?f:"gemini-2.5-flash-image",i=(b=(m=(h=this.aiPromptInput)==null?void 0:h.value)==null?void 0:m.trim())!=null?b:"",n=(v=(y=this.aiRemoveBgToggle)==null?void 0:y.checked)!=null?v:!1,r=n,s=n,o=Number((w=(x=this.aiStrengthInput)==null?void 0:x.value)!=null?w:"5");if(!e){this.setAiStatus("Missing API key.");return}if(!i){this.setAiStatus("Add a prompt.");return}let l=this.getSelectedAssetInput(),c=((C=l==null?void 0:l.value)==null?void 0:C.trim())||((k=this.aiBaseValue)==null?void 0:k.trim())||"";if(!c&&!this.aiOutputDataUrl){this.setAiStatus("Select an asset first.");return}this.setAiLoading(!0),this.setAiStatus("Generating...");try{let A=null,M=(P=this.getSelectedAssetKey())!=null?P:"unknown",_=(O=this.aiUseOutputToggle)!=null&&O.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((j=this.aiUseOutputToggle)!=null&&j.checked&&this.aiOutputDataUrl){let V=Yi(this.aiOutputDataUrl,"ai-output.png");if(V){let Y=await Le(V);Y&&(A={input:{base64:Y.base64,mimeType:Y.mimeType},dataUrl:Y.dataUrl,width:Y.width,height:Y.height})}}if(A||(A=await this.getImageDataFromAsset(c)),!A){this.setAiStatus("Unable to load the base image.");return}let D=[A.input],L=!1;if(this.aiReferenceFile){let V=await Le(this.aiReferenceFile);V?(D.push({base64:V.base64,mimeType:V.mimeType}),L=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let R=er(i,{includeReference:L,includeMagenta:r,changeLevel:o}),$=(E=(T=this.aiReferenceFile)==null?void 0:T.name)!=null?E:"none";console.info("[AI] Final prompt:",R),console.info("[AI] Image sources:",{assetKey:M,base:_,reference:$});let Q=qa(A.width,A.height);console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let B=await Ye(e,R,D,{aspectRatio:Q,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",B==null?void 0:B.length),this.aiRawOutputDataUrl=B,await this.refreshAiOutputFromRaw()}catch(A){console.error("[CustomizePanel] AI Generate Error:",A),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((S=this.aiStatusEl)==null?void 0:S.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var n,r,s,o;if(!this.aiRawOutputDataUrl)return;let e=(r=(n=this.aiRemoveBgToggle)==null?void 0:n.checked)!=null?r:!1,t=Number((o=(s=this.aiBgToleranceInput)==null?void 0:s.value)!=null?o:"30"),i=this.aiRawOutputDataUrl;if(e){let l=await Ve(this.aiRawOutputDataUrl,t);l&&(i=l)}this.setAiOutput(i),this.setAiStatus("Ready.")}setAiOutput(e){var i,n;this.aiOutputDataUrl=e,this.aiOutputKey=this.getSelectedAssetKey(),this.updateAiPreview(),this.setAiOutputButtonsEnabled(!0);let t=(i=this.previewModal)==null?void 0:i.querySelector("[data-asset-ai-preview]");this.updateAiModalPreview(t,(n=this.activePreviewKey)!=null?n:void 0)}setAiOutputButtonsEnabled(e){this.aiApplyBtn&&(this.aiApplyBtn.disabled=!e),this.aiSaveLibraryBtn&&(this.aiSaveLibraryBtn.disabled=!e),this.aiCropBtn&&(this.aiCropBtn.disabled=!e),this.aiDownloadBtn&&(this.aiDownloadBtn.disabled=!e)}handleAiApply(){var t,i,n;let e=this.getSelectedAssetInput();if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(e)console.log("[CustomizePanel] Applying AI output to brand asset:",e.dataset.assetKey),e.value=this.aiOutputDataUrl,this.handleAssetValueChange((t=e.dataset.assetKey)!=null?t:"",e),this.setAiStatus("Applied. Restarting game...");else{let r=((i=this.aiContext)==null?void 0:i.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),s=((n=this.aiContext)==null?void 0:n.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(r&&s)console.log("[CustomizePanel] Applying AI output directly to object:",r,s),this.applyObjectPropertyValue(r,s,this.aiOutputDataUrl),this.setAiStatus("Applied directly. Restarting game..."),window.dispatchEvent(new CustomEvent("inspector:refresh"));else{this.setAiStatus("No target input found to apply.");return}}setTimeout(()=>{this.closeAiModal()},500)}async handleAiSaveToLibrary(){var r,s,o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(!this.getSelectedAssetKey()){this.setAiStatus("No asset selected.");return}let i=`${(this.aiTargetKey||"asset").replace(/[^a-zA-Z0-9_-]/g,"_")}_ai_${Date.now()}`,n=this.inferCategoryFromAssetKey(this.aiTargetKey||"");this.setAiStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:n,filename:`${i}.png`,data:this.aiOutputDataUrl,overwrite:!0})})).json();if(c.success){console.log("[CustomizePanel] \u2705 Saved to library:",c.path),this.setAiStatus(`Saved as ${i}. Applying...`);let p=window.addAssetToRegistry;typeof p=="function"&&(console.log("[CustomizePanel] Logic: Adding to registry category:",n),p(n,`${i}.png`));let d=window.refreshAssetLibrary;typeof d=="function"&&(console.log("[CustomizePanel] Logic: Refreshing library panel"),d());let u=((r=this.aiContext)==null?void 0:r.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),g=((s=this.aiContext)==null?void 0:s.path)||this.inferPathFromAssetKey(this.aiTargetKey||""),f=this.getSelectedAssetInput();if(f&&(f.value=c.path,this.handleAssetValueChange((o=f.dataset.assetKey)!=null?o:"",f)),u&&g){console.log("[CustomizePanel] Saved and applying directly to object:",u,g);let h=window.applyAssetToSlot,m=/texture|image|sprite|asset\\.path/i.test(g)||/\\.(png|jpg|jpeg)$/i.test(String(c.path||""));if(typeof h=="function"&&m){let b=this.getFilenameFromPath(c.path);h(u,b,n)}else this.applyObjectPropertyValue(u,g,c.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}setTimeout(()=>{this.closeAiModal()},1e3)}else console.error("[CustomizePanel] \u274C Save failed:",c.error),this.setAiStatus(`Save failed: ${c.error}`)}catch(l){console.error("[CustomizePanel] \u274C Save error:",l),this.setAiStatus("Save failed. Check console.")}}inferCategoryFromAssetKey(e){var s;let t=(s=this.aiContext)==null?void 0:s.objectId,i=e||this.aiTargetKey||"",n=window.getEditableAssets;if(typeof n=="function"){let o=n();if(o!=null&&o.slots){let l=o.slots.find(c=>t&&c.objectId===t||c.currentAsset===i||c.slotId===i||c.currentAsset&&c.currentAsset.includes(i)||i.includes(c.slotId));if(l){let c=l.libraryFolder||l.category;if(c)return c}}}let r=i.toLowerCase();return r.includes("background")?"backgrounds":r.includes("character")?"characters":r.includes("key")?"collectedkeys":r.includes("draggable")?"draggables":r.includes("environment")||r.includes("env")||r.includes("hand")||r.includes("prop")||r.includes("item")||r.includes("decor")||r.includes("object")?"environment":r.includes("machine")?"machines":r.includes("tutorial")?"tutorial":r.includes("ui")||r.includes("button")||r.includes("label")||r.includes("icon")||r.includes("logo")||r.includes("cta")||r.includes("menu")||r.includes("overlay")?"ui":r.includes("effect")||r.includes("confetti")||r.includes("particle")?"effects":"ui"}inferObjectIdFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(r=>r.currentAsset===e||r.slotId===e);return(n==null?void 0:n.objectId)||null}inferPathFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(s=>s.currentAsset===e||s.slotId===e);if(!n)return null;let r=n.category;return r==="render"||r==="backgrounds"||r==="characters"?"render.texture":r==="ui"?"ui.image":r==="audio"?"audio.src":"render.texture"}getFilenameFromPath(e){if(!e)return"";let t=e.split("/");return t[t.length-1]}async handleAiCrop(){var o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}let e=this.getSelectedAssetInput(),t=(o=e==null?void 0:e.value)!=null?o:"",i=await this.getImageDimensions(t);if(!i){this.setAiStatus("Unable to read target dimensions.");return}let n=Yi(this.aiOutputDataUrl,"ai-output.png");if(!n)return;let r=await this.showManualCropModal(n,i,t);if(!r)return;let s=await Ga(r);s&&this.setAiOutput(s)}handleAiDownload(){var i;if(!this.aiOutputDataUrl)return;let e=(i=this.getSelectedAssetKey())!=null?i:"ai-image",t=document.createElement("a");t.href=this.aiOutputDataUrl,t.download=`${e}-ai.png`,t.click()}handleAssetValueChange(e,t){this.previewModal&&this.closePreviewModal(),this.scheduleAutoApply(),this.updatePreviewIfOpen(e,t.value,t.dataset.assetType)}async handleAssetUpload(e,t,i){let n=t.value,r=e;if(e.type.startsWith("image/")){let l=await this.getImageDimensions(n);if(l){let c=await this.showManualCropModal(e,l,n);if(!c)return;r=c}}let s=URL.createObjectURL(r),o=t.dataset.objectUrl;if(o)try{URL.revokeObjectURL(o)}catch{}t.dataset.objectUrl=s,t.dataset.assetType=r.type,t.value=s,this.handleAssetValueChange(i,t)}scheduleAutoApply(){this.options&&(this.autoApplyTimer&&window.clearTimeout(this.autoApplyTimer),console.log("[CustomizePanel] Scheduling auto-apply in 250ms"),this.autoApplyTimer=window.setTimeout(()=>{this.autoApplyTimer=null,console.log("[CustomizePanel] Executing auto-apply now"),this.handleApplyWithSource("auto")},250))}previewAsset(e,t,i,n){if(!t)return;let r=this.resolveAssetUrls(t);if(r.length===0)return;let s=i||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=n!=null?n:null,this.openPreviewModal(e,t,r,s)}resolveAssetUrls(e){let t=e.trim();if(!t)return[];if(console.log("[CustomizePanel] Resolving asset urls for:",t),/^(blob:|data:|https?:|\/)/.test(t))return console.log("[CustomizePanel] Path is absolute or data/blob, using as is"),[t];let i=t.replace(/^\.?\//,""),n=[];return i.startsWith("raw/")?n=[`/${i}`,`/assets/${i}`]:i.startsWith("assets/")?n=[`/${i}`]:n=[`/raw/${i}`,`/assets/raw/${i}`,`/assets/${i}`,`/${i}`],console.log("[CustomizePanel] Resolved to possible paths:",n),n}guessMimeType(e){let t=e.toLowerCase();return t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".gif")||t.endsWith(".webp")||t.endsWith(".svg")?"image":t.endsWith(".mp3")||t.endsWith(".wav")||t.endsWith(".ogg")?"audio":t.endsWith(".json")?"json":"file"}openPreviewModal(e,t,i,n){this.closePreviewModal(!0);let r=document.createElement("div");r.className="asset-preview-modal",r.innerHTML=`
|
|
793
|
+
<div class="asset-preview-card">
|
|
794
|
+
<div class="asset-preview-header">
|
|
795
|
+
<div class="asset-preview-title">${e}</div>
|
|
796
|
+
<div class="asset-preview-actions">
|
|
797
|
+
<button class="asset-preview-change" type="button">Change</button>
|
|
798
|
+
<button class="asset-preview-ai" type="button">AI Edit</button>
|
|
799
|
+
<button class="asset-preview-close" type="button">Close</button>
|
|
800
|
+
</div>
|
|
801
|
+
</div>
|
|
802
|
+
<div class="asset-preview-body"></div>
|
|
803
|
+
<div class="asset-preview-ai-output hidden" data-asset-ai-preview>
|
|
804
|
+
<div class="asset-preview-ai-label">AI Output</div>
|
|
805
|
+
<img class="asset-preview-ai-image" alt="AI output preview">
|
|
806
|
+
</div>
|
|
807
|
+
</div>
|
|
808
|
+
`;let s=r.querySelector(".asset-preview-body"),o=r.querySelector(".asset-preview-close"),l=r.querySelector(".asset-preview-change"),c=r.querySelector(".asset-preview-ai"),p=r.querySelector("[data-asset-ai-preview]");if(o==null||o.addEventListener("click",()=>this.closePreviewModal()),c==null||c.addEventListener("click",()=>{console.log("[CustomizePanel] AI Edit clicked for:",e),this.openAiModal(e,t)}),l==null||l.addEventListener("click",()=>{console.log("[CustomizePanel] Change clicked for:",e),this.activePreviewFileInput&&this.activePreviewFileInput.click()}),r.addEventListener("click",d=>{d.target===r&&this.closePreviewModal()}),s)if(n==="image"){let d=document.createElement("img");this.loadWithFallback(d,i),s.appendChild(d)}else if(n==="audio"){let d=document.createElement("audio");d.controls=!0,this.loadWithFallback(d,i),s.appendChild(d)}else if(n==="json"){let d=document.createElement("pre");this.fetchWithFallback(i).then(u=>{d.textContent=u!=null?u:"Unable to load JSON."}),s.appendChild(d)}else{let d=document.createElement("a");d.href=i[0],d.target="_blank",d.rel="noreferrer",d.textContent="Open asset",s.appendChild(d)}document.body.appendChild(r),this.previewModal=r,this.updateAiModalPreview(p,e)}loadWithFallback(e,t){if(t.length===0)return;let i=0,n=()=>{i>=t.length||(e.src=t[i],i+=1)};e.addEventListener("error",n),n()}async fetchWithFallback(e){for(let t of e)try{let i=await fetch(t);if(!i.ok)continue;return await i.text()}catch{}return null}applyObjectPropertyValue(e,t,i){let n=window.getEditableObjectConfig,r=window.applyEditableObjectConfig;if(typeof n!="function"||typeof r!="function")return;let s=n(e);if(!s)return;let o=JSON.parse(JSON.stringify(s)),l=t.split("."),c=o;for(let p=0;p<l.length-1;p++){let d=l[p];c[d]=c[d]||{},c=c[d]}c[l[l.length-1]]=i,r(e,o)}applyTextColorToObject(e,t){let n={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[e];n&&this.applyObjectPropertyValue(n.objectId,n.property,t)}closePreviewModal(e){this.previewModal&&(this.previewModal.remove(),this.previewModal=null),e||(this.activePreviewKey=null,this.activePreviewValue=null,this.activePreviewFileInput=null)}updatePreviewIfOpen(e,t,i){var r;if(!this.previewModal||this.activePreviewKey!==e)return;let n=t!=null?t:"";this.activePreviewValue!==n&&this.previewAsset(e,n,i,(r=this.activePreviewFileInput)!=null?r:void 0)}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refresh()},350))}clearRetry(){this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=null)}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");if(!e)return;let t=window.localStorage.getItem("customizePanelWidth"),i=t?Number(t):NaN;Number.isFinite(i)&&i>0&&(this.root.style.width=`${i}px`);let n=r=>{var u,g;r.preventDefault();let s=r.clientX,o=(g=(u=this.root)==null?void 0:u.getBoundingClientRect().width)!=null?g:0,l=260,c=620,p=f=>{let h=f.clientX-s,m=Math.min(c,Math.max(l,o+h));this.root&&(this.root.style.width=`${m}px`)},d=()=>{var h,m;window.removeEventListener("pointermove",p),window.removeEventListener("pointerup",d);let f=(m=(h=this.root)==null?void 0:h.getBoundingClientRect().width)!=null?m:0;f>0&&window.localStorage.setItem("customizePanelWidth",String(Math.round(f)))};window.addEventListener("pointermove",p),window.addEventListener("pointerup",d)};e.addEventListener("pointerdown",n)}async getImageDimensions(e){let t=this.resolveAssetUrls(e);if(t.length===0)return null;for(let i of t){let n=await this.loadImage(i);if(n!=null&&n.naturalWidth&&(n!=null&&n.naturalHeight))return{width:n.naturalWidth,height:n.naturalHeight}}return null}async loadImage(e){return await new Promise(t=>{let i=new Image;i.onload=()=>t(i),i.onerror=()=>t(null),i.src=e})}async showManualCropModal(e,t,i){let n=t.width/t.height,r=URL.createObjectURL(e),s=await this.loadImage(r);try{URL.revokeObjectURL(r)}catch{}if(!(s!=null&&s.naturalWidth)||!(s!=null&&s.naturalHeight))return null;let o=await this.loadImageForValue(i);return await new Promise(l=>{let c=document.createElement("div");c.className="asset-crop-modal";let p=Math.min(860,window.innerWidth-60),f=Math.max(220,Math.floor((p-32-16)/2)),h=Math.min(520,window.innerHeight-240),m=f,b=m/n;b>h&&(b=h,m=b*n),c.innerHTML=`
|
|
809
|
+
<div class="asset-crop-card" style="width:${p}px;">
|
|
810
|
+
<div class="asset-crop-header">
|
|
811
|
+
<div>
|
|
812
|
+
<div class="asset-crop-title">Crop to match current asset</div>
|
|
813
|
+
<div class="asset-crop-subtitle">${t.width}\xD7${t.height}px \u2022 ${n.toFixed(3)} ratio</div>
|
|
814
|
+
</div>
|
|
815
|
+
<button class="asset-crop-close" type="button">Close</button>
|
|
816
|
+
</div>
|
|
817
|
+
<div class="asset-crop-body">
|
|
818
|
+
<div class="asset-crop-column">
|
|
819
|
+
<div class="asset-crop-label">Crop</div>
|
|
820
|
+
<canvas class="asset-crop-canvas" width="${Math.round(m)}" height="${Math.round(b)}"></canvas>
|
|
821
|
+
</div>
|
|
822
|
+
<div class="asset-crop-column">
|
|
823
|
+
<div class="asset-crop-label">Compare</div>
|
|
824
|
+
<canvas class="asset-crop-preview" width="${Math.round(m)}" height="${Math.round(b)}"></canvas>
|
|
825
|
+
</div>
|
|
826
|
+
</div>
|
|
827
|
+
<div class="asset-crop-controls">
|
|
828
|
+
<label>Zoom</label>
|
|
829
|
+
<input class="asset-crop-zoom" type="range" min="0.5" max="3" step="0.01" value="1">
|
|
830
|
+
<span class="asset-crop-zoom-value">1.00\xD7</span>
|
|
831
|
+
<button class="asset-crop-reset" type="button">Center</button>
|
|
832
|
+
</div>
|
|
833
|
+
<div class="asset-crop-actions">
|
|
834
|
+
<button class="asset-crop-cancel" type="button">Cancel</button>
|
|
835
|
+
<button class="asset-crop-apply" type="button">Apply Crop</button>
|
|
836
|
+
</div>
|
|
837
|
+
</div>
|
|
838
|
+
`;let y=c.querySelector(".asset-crop-canvas"),v=c.querySelector(".asset-crop-preview"),x=c.querySelector(".asset-crop-zoom"),w=c.querySelector(".asset-crop-zoom-value"),C=c.querySelector(".asset-crop-close"),k=c.querySelector(".asset-crop-cancel"),P=c.querySelector(".asset-crop-apply"),O=c.querySelector(".asset-crop-reset");if(!y||!v||!x||!w){l(null);return}let j=y.getContext("2d"),T=v.getContext("2d");if(!j||!T){l(null);return}let E=s.naturalWidth,S=s.naturalHeight,A=Math.max(y.width/E,y.height/S),M=1,_=0,D=0,L=!1,R=0,$=0,Q=0,B=0,V=()=>{let z=A*M,oe=Math.max(0,(E*z-y.width)/2),ge=Math.max(0,(S*z-y.height)/2);_=Math.min(oe,Math.max(-oe,_)),D=Math.min(ge,Math.max(-ge,D))},Y=()=>{let z=A*M;j.clearRect(0,0,y.width,y.height);let oe=y.width/2-E*z/2+_,ge=y.height/2-S*z/2+D;if(j.drawImage(s,oe,ge,E*z,S*z),T.clearRect(0,0,v.width,v.height),o!=null&&o.naturalWidth&&(o!=null&&o.naturalHeight)){let fe=Math.max(v.width/o.naturalWidth,v.height/o.naturalHeight),Be=v.width/2-o.naturalWidth*fe/2,Se=v.height/2-o.naturalHeight*fe/2;T.drawImage(o,Be,Se,o.naturalWidth*fe,o.naturalHeight*fe)}else T.fillStyle="rgba(255, 255, 255, 0.04)",T.fillRect(0,0,v.width,v.height),T.strokeStyle="rgba(255, 255, 255, 0.08)",T.strokeRect(4,4,v.width-8,v.height-8);let Ae=v.width/y.width*(A*M),he=_*(v.width/y.width),Me=D*(v.height/y.height),He=v.width/2-E*Ae/2+he,$e=v.height/2-S*Ae/2+Me;T.save(),T.globalAlpha=.7,T.drawImage(s,He,$e,E*Ae,S*Ae),T.restore()},J=()=>{_=0,D=0,V(),Y()};x.addEventListener("input",()=>{M=Number(x.value),w.textContent=`${M.toFixed(2)}\xD7`,V(),Y()}),y.addEventListener("pointerdown",z=>{L=!0,R=z.clientX,$=z.clientY,Q=_,B=D,y.setPointerCapture(z.pointerId)}),y.addEventListener("pointermove",z=>{L&&(_=Q+(z.clientX-R),D=B+(z.clientY-$),V(),Y())}),y.addEventListener("pointerup",z=>{L=!1,y.releasePointerCapture(z.pointerId)}),y.addEventListener("pointerleave",()=>{L=!1});let Ee=()=>{c.remove()},ze=()=>{Ee(),l(null)},Tt=async()=>{let z=document.createElement("canvas");z.width=t.width,z.height=t.height;let oe=z.getContext("2d");if(!oe){Ee(),l(null);return}let ge=M,he=Math.max(z.width/E,z.height/S)*ge,Me=z.width/y.width,He=_*Me,$e=D*Me,fe=z.width/2-E*he/2+He,Be=z.height/2-S*he/2+$e;oe.drawImage(s,fe,Be,E*he,S*he);let Se=await new Promise(kt=>{z.toBlob(Pt=>kt(Pt),e.type||"image/png")});if(Ee(),!Se){l(null);return}l(new File([Se],e.name,{type:Se.type}))};C==null||C.addEventListener("click",ze),k==null||k.addEventListener("click",ze),O==null||O.addEventListener("click",J),P==null||P.addEventListener("click",()=>{Tt()}),c.addEventListener("click",z=>{z.target===c&&ze()}),document.body.appendChild(c),J()})}async loadImageForValue(e){let t=this.resolveAssetUrls(e);if(!t.length)return null;for(let i of t){let n=await this.loadImage(i);if(n)return n}return null}};var ti=class{constructor(){this.root=null;this.options=null}render(){return`
|
|
839
|
+
<div class="scene-panel loading-screen-panel panel-accent-purple" data-panel="loading-screen">
|
|
840
|
+
<div class="scene-panel-header" data-panel-handle>
|
|
841
|
+
<div class="panel-title">
|
|
842
|
+
<span class="panel-pill">Loading</span>
|
|
843
|
+
<span class="panel-title-text">Loading Screen</span>
|
|
844
|
+
</div>
|
|
845
|
+
<button class="scene-panel-toggle" type="button" data-panel-toggle>\u25BE</button>
|
|
846
|
+
</div>
|
|
847
|
+
<div class="scene-panel-body">
|
|
848
|
+
<div class="debug-section">
|
|
849
|
+
<div class="debug-section-title">Display Mode</div>
|
|
850
|
+
<div class="debug-field">
|
|
851
|
+
<label>Type</label>
|
|
852
|
+
<select id="loading-screen-type">
|
|
853
|
+
<option value="color">Solid Color</option>
|
|
854
|
+
<option value="image">PNG Image</option>
|
|
855
|
+
</select>
|
|
856
|
+
</div>
|
|
857
|
+
<div class="debug-field" id="loading-color-field">
|
|
858
|
+
<label>Background Color</label>
|
|
859
|
+
<input type="color" id="loading-background-color" value="#160a17">
|
|
860
|
+
</div>
|
|
861
|
+
<div class="debug-field" id="loading-alpha-field">
|
|
862
|
+
<label>Overlay Alpha</label>
|
|
863
|
+
<input type="range" id="loading-overlay-alpha" min="0" max="1" step="0.05" value="1">
|
|
864
|
+
<span class="debug-value-display" id="loading-overlay-alpha-value">1.00</span>
|
|
865
|
+
</div>
|
|
866
|
+
</div>
|
|
867
|
+
|
|
868
|
+
<div class="debug-section">
|
|
869
|
+
<div class="debug-section-title">Loading Text</div>
|
|
870
|
+
<div class="debug-field">
|
|
871
|
+
<label>Text</label>
|
|
872
|
+
<input type="text" id="loading-text" placeholder="Loading...">
|
|
873
|
+
</div>
|
|
874
|
+
<div class="debug-field">
|
|
875
|
+
<label>Text Scale</label>
|
|
876
|
+
<input type="range" id="loading-text-scale" min="0.2" max="1.5" step="0.05" value="0.6">
|
|
877
|
+
<span class="debug-value-display" id="loading-text-scale-value">0.60</span>
|
|
878
|
+
</div>
|
|
879
|
+
</div>
|
|
880
|
+
|
|
881
|
+
<div class="debug-section">
|
|
882
|
+
<div class="debug-section-title">Settings</div>
|
|
883
|
+
<div class="debug-field checkbox-field">
|
|
884
|
+
<input type="checkbox" id="loading-enabled" checked>
|
|
885
|
+
<label>Enabled</label>
|
|
886
|
+
</div>
|
|
887
|
+
<div class="debug-field checkbox-field">
|
|
888
|
+
<input type="checkbox" id="loading-blur-enabled" checked>
|
|
889
|
+
<label>Enable Blur</label>
|
|
890
|
+
</div>
|
|
891
|
+
<div class="debug-field">
|
|
892
|
+
<label>Blur Strength</label>
|
|
893
|
+
<input type="range" id="loading-blur-strength" min="0" max="20" step="1" value="8">
|
|
894
|
+
<span class="debug-value-display" id="loading-blur-strength-value">8</span>
|
|
895
|
+
</div>
|
|
896
|
+
</div>
|
|
897
|
+
|
|
898
|
+
<div class="debug-btn-group">
|
|
899
|
+
<button class="debug-btn" id="loading-show-btn">Show Loading Screen</button>
|
|
900
|
+
<button class="debug-btn" id="loading-hide-btn">Hide</button>
|
|
901
|
+
</div>
|
|
902
|
+
</div>
|
|
903
|
+
</div>
|
|
904
|
+
`}initialize(e,t){var y,v,x,w,C,k,P,O,j,T,E,S,A,M,_,D;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let n=(()=>{var R;let L=window.getEditableEngineConfig;if(typeof L=="function"){let $=L();return(R=$==null?void 0:$.loading)!=null?R:{}}return{}})(),r=(y=this.root)==null?void 0:y.querySelector("#loading-screen-type");r&&(r.value=n.type==="image"?"image":"color",r.addEventListener("change",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{type:r.value}),this.updateFieldVisibility(r.value)}));let s=(v=this.root)==null?void 0:v.querySelector("#loading-background-color");s&&(s.value=n.background_color||"#160a17",s.addEventListener("input",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{background_color:s.value})}));let o=(x=this.root)==null?void 0:x.querySelector("#loading-overlay-alpha"),l=(w=this.root)==null?void 0:w.querySelector("#loading-overlay-alpha-value");o&&(o.value=String((C=n.overlay_alpha)!=null?C:1),l&&(l.textContent=Number(o.value).toFixed(2)),o.addEventListener("input",()=>{var R,$;let L=Number(o.value);l&&(l.textContent=L.toFixed(2)),($=(R=this.options)==null?void 0:R.onUpdateLoading)==null||$.call(R,{overlay_alpha:L})}));let c=(k=this.root)==null?void 0:k.querySelector("#loading-text");c&&(c.value=n.text||"",c.addEventListener("input",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{text:c.value})}));let p=(P=this.root)==null?void 0:P.querySelector("#loading-text-scale"),d=(O=this.root)==null?void 0:O.querySelector("#loading-text-scale-value");p&&(p.value=String((j=n.text_scale)!=null?j:.6),d&&(d.textContent=Number(p.value).toFixed(2)),p.addEventListener("input",()=>{var R,$;let L=Number(p.value);d&&(d.textContent=L.toFixed(2)),($=(R=this.options)==null?void 0:R.onUpdateLoading)==null||$.call(R,{text_scale:L})}));let u=(T=this.root)==null?void 0:T.querySelector("#loading-enabled");u&&(u.checked=n.enabled!==!1,u.addEventListener("change",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{enabled:u.checked})}));let g=(E=this.root)==null?void 0:E.querySelector("#loading-blur-enabled");g&&(g.checked=n.blur_enabled!==!1,g.addEventListener("change",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{blur_enabled:g.checked})}));let f=(S=this.root)==null?void 0:S.querySelector("#loading-blur-strength"),h=(A=this.root)==null?void 0:A.querySelector("#loading-blur-strength-value");f&&(f.value=String((M=n.blur_strength)!=null?M:8),h&&(h.textContent=f.value),f.addEventListener("input",()=>{var L,R;h&&(h.textContent=f.value),(R=(L=this.options)==null?void 0:L.onUpdateLoading)==null||R.call(L,{blur_strength:Number(f.value)})}));let m=(_=this.root)==null?void 0:_.querySelector("#loading-show-btn"),b=(D=this.root)==null?void 0:D.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onShowLoadingScreen)==null||R.call(L)}),b==null||b.addEventListener("click",()=>{var L,R;(R=(L=this.options)==null?void 0:L.onHideLoadingScreen)==null||R.call(L)}),this.updateFieldVisibility(n.type==="image"?"image":"color")}updateFieldVisibility(e){var n,r;let t=(n=this.root)==null?void 0:n.querySelector("#loading-color-field"),i=(r=this.root)==null?void 0:r.querySelector("#loading-alpha-field");e==="image"?(t&&(t.style.display="none"),i&&(i.style.display="none")):(t&&(t.style.display=""),i&&(i.style.display=""))}refresh(){}};import{Assets as ii}from"pixi.js";async function ir(a,e,t){var i,n;console.log("[LIBRARY] applyAssetChange called with:",e,t);try{let r=Date.now(),o=`/${`raw/library/${e}/${t}`}?t=${r}`;console.log("[LIBRARY] Loading texture from:",o);let l=await ii.load(o);if(!l){console.error("[LIBRARY] Failed to load texture:",o);return}let c=window.CustomAssets,p=Object.keys(c||{}).filter(u=>{let g=e.replace(/s$/,"");return u.startsWith(g)||u.includes(g)});for(let u of p)ce[u]=l,console.log("[LIBRARY] \u2705 Updated AssetTextures."+u),(i=c[u])!=null&&i.texture&&(c[u].texture=l,console.log("[LIBRARY] \u2705 Updated CustomAssets."+u+".texture"));let d=window.gameObjectManager;if(d)for(let u of p){let g=d.get(u);if(g){let f=((n=g.getDisplayObject)==null?void 0:n.call(g))||g.pixiObject||g;f!=null&&f.texture&&(f.texture=l,console.log("[LIBRARY] \u2705 Applied to display object:",u))}}}catch(r){console.error("[LIBRARY] Error applying asset change:",r)}}async function nr(a,e){var t,i,n;console.log("[LIBRARY] resetAsset called for:",e);try{let r=window.getEditableAssets,s=typeof r=="function"?r():null,o=(t=s==null?void 0:s.slots)==null?void 0:t.find(m=>m.category===e),l=o==null?void 0:o.defaultAsset;if(!l){console.warn("[LIBRARY] Could not find default asset for:",e);return}let c=Date.now(),p=`/raw/${l}?t=${c}`;console.log("[LIBRARY] Loading default texture from:",p);let d=await ii.load(p);if(!d){console.error("[LIBRARY] Failed to load default texture:",p);return}let u=window.CustomAssets,g=e.replace(/s$/,""),f=Object.keys(u||{}).filter(m=>m.startsWith(g)||m.includes(g));for(let m of f)ce[m]=d,console.log("[LIBRARY] \u2705 Reset AssetTextures."+m),(i=u[m])!=null&&i.texture&&(u[m].texture=d,console.log("[LIBRARY] \u2705 Reset CustomAssets."+m+" to default"));let h=window.gameObjectManager;if(h)for(let m of f){let b=h.get(m);if(b){let y=((n=b.getDisplayObject)==null?void 0:n.call(b))||b.pixiObject||b;y!=null&&y.texture&&(y.texture=d,console.log("[LIBRARY] \u2705 Reset display object:",m))}}}catch(r){console.error("[LIBRARY] Error resetting asset:",r)}}async function ar(a,e,t,i){var n,r,s,o,l,c,p,d,u,g,f,h,m,b,y;console.log("[LIBRARY] applySlotAsset:",{objectId:e,assetFilename:t,category:i});try{let v=e.startsWith("json.")?e.replace("json.",""):e;console.log("[LIBRARY] Asset key:",v);let x=Date.now(),w=`/raw/library/${i}/${t}?t=${x}`;console.log("[LIBRARY] Loading texture from:",w);let C=await ii.load(w);if(!C){console.error("[LIBRARY] Failed to load texture:",w);return}console.log("[LIBRARY] \u2705 Texture loaded"),ce[v]=C,console.log("[LIBRARY] \u2705 Updated AssetTextures."+v);let k=window.CustomAssets;k!=null&&k[v]&&(k[v].texture=C,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+v));let P=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!P),P){let j=Array.from(((n=P.keys)==null?void 0:n.call(P))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",j);let T=P.get(v);if(console.log("[LIBRARY] gameObject for "+v+"?",!!T),T){let E=((r=T.getDisplayObject)==null?void 0:r.call(T))||T.pixiObject||T.pixi||T,S=(s=E==null?void 0:E.constructor)==null?void 0:s.name;if(console.log("[LIBRARY] displayObject:",E),console.log("[LIBRARY] displayObject type:",S),console.log("[LIBRARY] has texture?",!!(E!=null&&E.texture)),E!=null&&E.texture)E.texture=C,console.log("[LIBRARY] \u2705 Applied to display object:",v);else if(S==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:A}=await import("pixi.js"),M=E.parent,_=(l=(o=M==null?void 0:M.getChildIndex)==null?void 0:o.call(M,E))!=null?l:0,D={x:E.x,y:E.y},L={x:(p=(c=E.anchor)==null?void 0:c.x)!=null?p:.5,y:(u=(d=E.anchor)==null?void 0:d.y)!=null?u:.5},R={x:(f=(g=E.scale)==null?void 0:g.x)!=null?f:1,y:(m=(h=E.scale)==null?void 0:h.y)!=null?m:1},$=(b=E.alpha)!=null?b:1,Q=(y=E.visible)!=null?y:!0,B=new A(C);B.anchor.set(L.x,L.y),B.position.set(D.x,D.y),B.scale.set(R.x,R.y),B.alpha=$,B.visible=Q,M&&(M.removeChild(E),M.addChildAt(B,_),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),T.pixiObject&&(T.pixiObject=B),T.pixi&&(T.pixi=B),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if(E!=null&&E.children){let A=E.children.find(M=>M.texture);A?(A.texture=C,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let O=`raw/library/${i}/${t}`;lt({objectId:v,path:"render.asset.path",value:O}),console.log("[LIBRARY] \u2705 Staged config override for:",v,"path:",O)}catch(v){console.error("[LIBRARY] Error applying slot asset:",v)}}async function rr(a,e,t,i){var n;console.log("[LIBRARY] resetSlotAsset:",{objectId:e,defaultAsset:t,category:i});try{let r=e.startsWith("json.")?e.replace("json.",""):e,s=Date.now(),o=`/raw/${t}?t=${s}`;console.log("[LIBRARY] Loading default texture from:",o);let l=await ii.load(o);if(!l){console.error("[LIBRARY] Failed to load default texture:",o);return}ce[r]=l,console.log("[LIBRARY] \u2705 Reset AssetTextures."+r);let c=window.CustomAssets;c!=null&&c[r]&&(c[r].texture=l,console.log("[LIBRARY] \u2705 Reset CustomAssets."+r+" to default"));let p=window.gameObjectManager;if(p){let d=p.get(r);if(d){let u=((n=d.getDisplayObject)==null?void 0:n.call(d))||d.pixiObject||d;u!=null&&u.texture&&(u.texture=l,console.log("[LIBRARY] \u2705 Reset display object:",r))}}lt({objectId:r,path:"render.asset.path",value:t}),console.log("[LIBRARY] \u2705 Reset config override for:",r)}catch(r){console.error("[LIBRARY] Error resetting slot asset:",r)}}import{Graphics as dr,Point as xs}from"pixi.js";import{Point as sr}from"pixi.js";var Te=()=>window.debugConfig||{},or=()=>window.resolveAnchorVec2||(a=>({x:.5,y:.5})),lr=()=>window.resolveScreenAnchorPoint||(()=>new sr),cr=()=>window.resolveScreenRatioPoint||(()=>new sr);function pr(a){ni(a)&&(a.objectDebugRaf||(a.objectDebugRaf=window.requestAnimationFrame(()=>ai(a))))}function ur(a){a.objectDebugRaf&&(window.cancelAnimationFrame(a.objectDebugRaf),a.objectDebugRaf=null),pt(a)}function ni(a){return a.isDebugOpen}function ai(a){var r,s,o;if(!ni(a)){a.objectDebugRaf=null;return}a.objectDebugRaf=window.requestAnimationFrame(()=>ai(a));let e=Ji(a);if(!e){dt(a,null),pt(a);return}let t=Zi(a,e);if(!t){dt(a,null),pt(a);return}let i=new xs;(r=t.getGlobalPosition)==null||r.call(t,i);let n=Qi(a,t);dt(a,{instanceId:e,worldX:i.x,worldY:i.y,configX:(s=n==null?void 0:n.x)!=null?s:null,configY:(o=n==null?void 0:n.y)!=null?o:null}),a.highlightObject?an(a,t):sn(a),a.highlightAnchor&&n?rn(a,n):on(a)}function Ji(a){var n;let e=a.selectedObjectId;if(!e)return null;let t=window.__editableObjectInstances,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return Array.isArray(i)&&i.length>0?i[0]:e}function Zi(a,e){var n,r;let t=window.gameObjectManager,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return i?((r=i.getDisplayObject)==null?void 0:r.call(i))||i.pixiObject||i:null}function ut(a){let e=a.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function Qi(a,e){var s,o;let t=ut(a);if(!t)return null;let i=(s=t.transform)!=null?s:{},n=en(a);if(!n)return null;if(i.position_ratio!=null)return cr()(n.width,n.height,i.position_ratio);let r=(o=i.anchor)!=null?o:"center";return lr()(n.width,n.height,r)}function en(a){var r;let e=(r=a.container)==null?void 0:r.querySelector(".game-container"),t=Number(e==null?void 0:e.dataset.screenWidth),i=Number(e==null?void 0:e.dataset.screenHeight);if(Number.isFinite(t)&&t>0&&Number.isFinite(i)&&i>0)return{width:t,height:i};let n=window.gameApp;return n!=null&&n.renderer?{width:n.renderer.width,height:n.renderer.height}:null}function tn(a){let e=window.gameApp;return e!=null&&e.stage?(a.objectBoundsGfx&&a.objectBoundsGfx.parent!==e.stage&&(a.objectBoundsGfx.destroy(),a.objectBoundsGfx=null),a.objectBoundsGfx||(a.objectBoundsGfx=new dr,a.objectBoundsGfx.zIndex=999999,e.stage.addChild(a.objectBoundsGfx)),a.objectBoundsGfx):null}function nn(a){let e=window.gameApp;return e!=null&&e.stage?(a.objectAnchorGfx&&a.objectAnchorGfx.parent!==e.stage&&(a.objectAnchorGfx.destroy(),a.objectAnchorGfx=null),a.objectAnchorGfx||(a.objectAnchorGfx=new dr,a.objectAnchorGfx.zIndex=1e6,e.stage.addChild(a.objectAnchorGfx)),a.objectAnchorGfx):null}function an(a,e){var n;let t=tn(a);if(!t)return;let i=(n=e.getBounds)==null?void 0:n.call(e);i&&(t.clear(),t.rect(i.x,i.y,i.width,i.height).stroke({width:2,color:16726832,alpha:.9}))}function rn(a,e){let t=nn(a);if(!t)return;let i=6;t.clear(),t.moveTo(e.x-i,e.y),t.lineTo(e.x+i,e.y),t.moveTo(e.x,e.y-i),t.lineTo(e.x,e.y+i),t.stroke({width:2,color:3066993,alpha:.9})}function sn(a){a.objectBoundsGfx&&a.objectBoundsGfx.clear()}function on(a){a.objectAnchorGfx&&a.objectAnchorGfx.clear()}function pt(a){a.objectBoundsGfx&&(a.objectBoundsGfx.destroy(),a.objectBoundsGfx=null),a.objectAnchorGfx&&(a.objectAnchorGfx.destroy(),a.objectAnchorGfx=null)}function dt(a,e){a.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function gr(a,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,a)}function hr(a,e,t){var s;let i=e.split("."),n=i.pop(),r=a;for(let o of i)r[o]=(s=r[o])!=null?s:{},r=r[o];r[n]=t}function ln(a){var i,n,r,s,o;if(!a)return!1;if((i=a.transform)!=null&&i.offset)return!0;let e=((r=(n=a.identity)==null?void 0:n.category)!=null?r:"").toString().toLowerCase(),t=((o=(s=a.identity)==null?void 0:s.id)!=null?o:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function si(a){let e=Te();e.layout&&(e.layout.scale_multiplier=1,e.layout.position_offset={x:0,y:0},e.layout.debug_rect_visible=!0,e.layout.debug_rect_color=16711680,e.layout.debug_rect_thickness=4),e.engine&&(e.engine.scale=1,e.engine.background_scale=1.05,e.engine.label_pulse_speed=3,e.engine.label_pulse_intensity=.03),e.physics&&(e.physics.rope_length=420),window.location.reload()}function fr(a){window.location.reload()}function oi(a){let e=JSON.stringify(Te(),null,2);navigator.clipboard.writeText(e).then(()=>{alert("Debug config copied to clipboard!")}).catch(()=>{console.log(e),alert("Config logged to console (clipboard not available)")})}async function mr(a,e){var t,i,n;if(!(!a.configViewer||!a.container))try{let r=window.getEditableObjectConfig,s=typeof r=="function"?r(e):null;if(!s){let{loadObjectCentricConfig:o,loadObjectConfig:l}=await import("./config-4IWHAC43.js"),d=(((t=(await o("scene.main")).scene)==null?void 0:t.objects)||[]).find(g=>g.object_config===e||g.instance_id===e);if(!d)return;let u=await l(d.object_config);console.log("[PREVIEW] Loaded object config (fallback)",e,u),ri(a,u),(i=a.configViewer)==null||i.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,s),ri(a,s),(n=a.configViewer)==null||n.style.setProperty("display","block");return}catch(r){console.error("[DEBUG] Failed to load object config:",r)}}function ri(a,e){var d,u,g,f,h,m,b,y,v,x;if(!a.container)return;let t=a.container.querySelector("#config-pos-x"),i=a.container.querySelector("#config-pos-y"),n=a.container.querySelector("#config-scale"),r=a.container.querySelector("#config-anchor-x"),s=a.container.querySelector("#config-anchor-y"),l=ln(e)?(d=e.transform)==null?void 0:d.offset:(u=e.transform)==null?void 0:u.position;t&&(t.value=String((g=l==null?void 0:l.x)!=null?g:0)),i&&(i.value=String((f=l==null?void 0:l.y)!=null?f:0)),n&&(n.value=String((m=(h=e.transform)==null?void 0:h.scale)!=null?m:1));let c=(x=(v=(b=e.transform)==null?void 0:b.anchor)!=null?v:(y=e.render)==null?void 0:y.anchor)!=null?x:{x:.5,y:.5},p=or()(c);r&&(r.value=String(p.x)),s&&(s.value=String(p.y))}function br(a){var l,c,p,d,u,g,f,h,m,b;let e=a.selectedObjectId;if(!e||!a.container)return;let t=(c=(l=a.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",i=(d=(p=a.container.querySelector("#config-pos-y"))==null?void 0:p.value)!=null?d:"0",n=(g=(u=a.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",r=(h=(f=a.container.querySelector("#config-anchor-x"))==null?void 0:f.value)!=null?h:"0.5",s=(b=(m=a.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",o=`${e}:
|
|
905
|
+
position: (${t}, ${i})
|
|
906
|
+
scale: ${n}
|
|
907
|
+
anchor: (${r}, ${s})`;navigator.clipboard.writeText(o).then(()=>console.log("[DEBUG] Config values copied to clipboard")).catch(y=>console.error("[DEBUG] Failed to copy config values:",y))}async function cn(a,e){var d,u,g,f,h,m,b,y,v,x,w;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!a.container)return;let t=a.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let i=Number((u=(d=a.container.querySelector("#config-pos-x"))==null?void 0:d.value)!=null?u:0),n=Number((f=(g=a.container.querySelector("#config-pos-y"))==null?void 0:g.value)!=null?f:0),r=Number((m=(h=a.container.querySelector("#config-scale"))==null?void 0:h.value)!=null?m:1),s=Number((y=(b=a.container.querySelector("#config-anchor-x"))==null?void 0:b.value)!=null?y:.5),o=Number((x=(v=a.container.querySelector("#config-anchor-y"))==null?void 0:v.value)!=null?x:.5);console.log("[INSPECTOR] Applying config for:",t,{posX:i,posY:n,scale:r,anchorX:s,anchorY:o});let{applyConfigOverride:l}=await import("./ConfigOverride-RARXNEZC.js");l({objectId:t,path:"transform.position",value:{x:i,y:n}},{silent:e==null?void 0:e.silent}),l({objectId:t,path:"transform.scale",value:r},{silent:e==null?void 0:e.silent}),l({objectId:t,path:"transform.anchor",value:{x:s,y:o}},{silent:e==null?void 0:e.silent});let c=ut(a);ln(c)&&l({objectId:t,path:"transform.offset",value:{x:i,y:n}},{silent:!0}),console.log("[INSPECTOR] Calling applyEditableObjectConfig...");let p=window.applyEditableObjectConfig;if(typeof p=="function"){let C=(w=window.getEditableObjectConfig)==null?void 0:w.call(window,t);C?(console.log("[INSPECTOR] \u2705 Calling applyEditableObjectConfig for:",t),p(t,C)):console.warn("[INSPECTOR] \u26A0\uFE0F No config found for:",t)}else console.warn("[INSPECTOR] \u26A0\uFE0F applyEditableObjectConfig not available")}async function yr(a,e,t){let{applyConfigOverride:i}=await import("./ConfigOverride-RARXNEZC.js");Object.entries(e.assets).forEach(([l,c])=>{i({path:`assets.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.theme).forEach(([l,c])=>{i({path:`runtime.theme.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.ui).forEach(([l,c])=>{i({path:`runtime.ui.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.fonts).forEach(([l,c])=>{i({path:`runtime.fonts.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.audio).forEach(([l,c])=>{i({path:`runtime.audio.${l}`,value:c},{silent:!0})});let n=window.applyEditableEngineConfig;if(typeof n=="function"){let l={theme:e.runtime.theme,fonts:e.runtime.fonts,audio:e.runtime.audio},c={};Object.entries(e.runtime.ui).forEach(([p,d])=>{var u;if(p)if(p.includes(".")){let g=p.split("."),f=c;for(let h=0;h<g.length-1;h++){let m=g[h];f[m]=(u=f[m])!=null?u:{},f=f[m]}f[g[g.length-1]]=d}else c[p]=d}),l.ui=c,n({runtime:l,assets:e.assets})}let r=Object.values(e.assets).some(l=>/^(blob:|data:)/.test(l)),s=(t==null?void 0:t.source)!=="auto"&&!r,o=window.__previewShell;s&&(o!=null&&o.refresh)&&o.refresh()}function vr(a){a.selectedObjectId&&(a.objectAutoApplyTimer&&window.clearTimeout(a.objectAutoApplyTimer),a.objectAutoApplyTimer=window.setTimeout(()=>{a.objectAutoApplyTimer=null,cn(a,{silent:!0})},150))}qi();function dn(a,e){var h,m,b;let t=(b=(m=(h=a.container)==null?void 0:h.querySelector("#debug-overlay"))!=null?m:a.debugOverlay)!=null?b:e.offsetParent;if(!t)return;let i=t.getBoundingClientRect(),n=e.getBoundingClientRect(),r=12,s=Math.max(250,Math.floor(i.width-r*2)),o=Math.max(200,Math.floor(i.height-r*2));n.width>s&&(e.style.width=`${s}px`),n.height>o&&(e.style.height=`${o}px`);let l=e.getBoundingClientRect(),c=l.left-i.left,p=l.top-i.top,d=Math.max(r,i.width-l.width-r),u=Math.max(r,i.height-l.height-r),g=Math.min(Math.max(c,r),d),f=Math.min(Math.max(p,r),u);e.style.left=`${Math.round(g)}px`,e.style.top=`${Math.round(f)}px`,e.style.right="auto",e.style.bottom="auto"}function Ie(a){if(!a.container)return;let e=a.container.querySelector("#debug-workbench");if(!e)return;dn(a,e);let t={activeTab:a.activeTab,width:e.style.width,height:e.style.height,left:e.style.left,top:e.style.top};localStorage.setItem("preview_workbench_state",JSON.stringify(t))}function li(a){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(a.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var n;let i=(n=a.container)==null?void 0:n.querySelector("#debug-workbench");i&&(t.width&&(i.style.width=t.width),t.height&&(i.style.height=t.height),t.left&&(i.style.left=t.left,i.style.right="auto"),t.top&&(i.style.top=t.top,i.style.bottom="auto"),dn(a,i))})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function xr(a,e){let t=e.getBoundingClientRect();(t.left<0||t.top<0||t.right>window.innerWidth||t.bottom>window.innerHeight)&&(console.warn("[Workbench] Workbench positioned outside viewport, repositioning..."),e.style.left="16px",e.style.top="72px",e.style.right="auto",e.style.bottom="auto",dn(a,e),Ie(a))}function wr(a){var n,r,s;if(!a.container)return;let e=a.container,t=e.querySelector("#debug-toggle");t||console.warn("[PREVIEW] Debug toggle not found in DOM"),t==null||t.addEventListener("click",()=>{var o;console.log("[PREVIEW] Debug toggle clicked"),(o=a.toggleDebug)==null||o.call(a)}),(n=e.querySelector("#debug-close"))==null||n.addEventListener("click",()=>{var o;return(o=a.toggleDebug)==null?void 0:o.call(a,!1)}),(r=e.querySelector("#debug-reset"))==null||r.addEventListener("click",()=>si(a)),(s=e.querySelector("#debug-export"))==null||s.addEventListener("click",()=>oi(a)),e.querySelectorAll(".workbench-tab").forEach(o=>{o.addEventListener("click",()=>{let l=o.dataset.tab;a.activeTab=l,pn(a),Ie(a)})}),gn(a,e),un(a,e)}function pn(a){if(!a.container)return;let e=a.container;e.querySelectorAll(".workbench-tab").forEach(n=>{let r=n.dataset.tab;n.classList.toggle("active",r===a.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(n=>{let r=n.dataset.tabPanel;n.classList.toggle("active",r===a.activeTab)})}function un(a,e){re(a,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),re(a,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),re(a,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),re(a,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),re(a,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),re(a,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),re(a,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),re(a,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),re(a,e,"debug-rope-length","physics.rope_length","#debug-rope-length-value");let t=e.querySelector("#debug-rect-visible");t==null||t.addEventListener("change",()=>{let n=Te();n.layout&&(n.layout.debug_rect_visible=!!t.checked)});let i=e.querySelector("#debug-rect-color");i==null||i.addEventListener("input",()=>{let n=i.value.replace("#",""),r=parseInt(n,16),s=Te();s.layout&&(s.layout.debug_rect_color=Number.isFinite(r)?r:16711680)})}function Er(a){if(!a.container||!a.debugOverlay)return;let e=a.container.querySelector("#debug-workbench"),t=a.container.querySelector("#workbench-handle"),i=a.container.querySelector("#workbench-resize");e&&t&&(!e.style.left&&!e.style.right&&!e.style.top&&!e.style.bottom&&(e.style.right="16px",e.style.top="72px"),Ui(e,t,a.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{Ie(a),xr(a,e)},10)})),e&&i&&Gi(e,i,()=>Ie(a)),li(a)}function gn(a,e){Array.from(e.querySelectorAll("[data-panel-toggle]")).forEach(i=>{i.addEventListener("click",()=>{let n=i.closest(".scene-panel");n&&n.classList.toggle("collapsed")})})}function re(a,e,t,i,n){let r=e.querySelector(`#${t}`),s=e.querySelector(n);if(!r||!s)return;let o=gr(Te(),i);typeof o=="number"&&(r.value=String(o),s.textContent=String(o)),r.addEventListener("input",()=>{let l=Number(r.value);s.textContent=String(l),hr(Te(),i,l)})}var ci=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async initialize(e){this.container=e,this.isDevelopmentMode=typeof window!="undefined"&&document.querySelector('script[type="module"][src*="/@vite/"]')!==null,await this.loadVersionsList(),window.addEventListener("config:changed",()=>{this.refreshPanel()}),this.refreshPanel()}render(){let e=sa(),{hasChanges:t,overrideCount:i,overrides:n}=e,r={};for(let l of n){let c=l.objectId||"Engine";r[c]||(r[c]=[]),r[c].push(l)}let s=localStorage.getItem("handler_last_applied"),o=s?new Date(parseInt(s)).toLocaleString():"Never";return`
|
|
908
|
+
<div class="config-persistence-panel">
|
|
909
|
+
<div class="persistence-status-bar ${t?"has-changes":"no-changes"}">
|
|
910
|
+
${t?`
|
|
911
|
+
<div class="status-box">
|
|
912
|
+
<span class="status-badge">UNAPPLIED</span>
|
|
913
|
+
<span class="status-text">${i} staging changes</span>
|
|
914
|
+
</div>
|
|
915
|
+
<div class="status-action-hint">Review below before applying to project</div>
|
|
916
|
+
`:`
|
|
917
|
+
<div class="status-box">
|
|
918
|
+
<span class="status-badge success">READY</span>
|
|
919
|
+
<span class="status-text">Configuration in sync with disk</span>
|
|
920
|
+
</div>
|
|
921
|
+
`}
|
|
922
|
+
</div>
|
|
923
|
+
|
|
924
|
+
<div class="persistence-main-actions">
|
|
925
|
+
<button
|
|
926
|
+
id="apply-to-project-btn"
|
|
927
|
+
class="persistence-btn primary-action"
|
|
928
|
+
${t?"":"disabled"}
|
|
929
|
+
title="Saves all staged changes to the actual configuration files on disk."
|
|
930
|
+
>
|
|
931
|
+
\u{1F4BE} APPLY ALL CHANGES TO PROJECT
|
|
932
|
+
</button>
|
|
933
|
+
</div>
|
|
934
|
+
|
|
935
|
+
<div class="version-management-section">
|
|
936
|
+
<div class="version-header">
|
|
937
|
+
<span class="version-label">\u{1F4E6} Version Management</span>
|
|
938
|
+
</div>
|
|
939
|
+
<div class="version-controls">
|
|
940
|
+
<div class="version-current">
|
|
941
|
+
<label>Current Version:</label>
|
|
942
|
+
<select id="version-selector" class="version-dropdown">
|
|
943
|
+
<option value="">original (pristine)</option>
|
|
944
|
+
${this.availableVersions.map(l=>`
|
|
945
|
+
<option value="${l.name}" ${l.name===this.currentVersion?"selected":""}>
|
|
946
|
+
${l.name} (${new Date(l.lastApplied).toLocaleDateString()})
|
|
947
|
+
</option>
|
|
948
|
+
`).join("")}
|
|
949
|
+
</select>
|
|
950
|
+
</div>
|
|
951
|
+
<button id="create-version-btn" class="persistence-btn" ${t?"":"disabled"}>
|
|
952
|
+
\u{1F4DD} Create New Version
|
|
953
|
+
</button>
|
|
954
|
+
</div>
|
|
955
|
+
</div>
|
|
956
|
+
|
|
957
|
+
${this.isDevelopmentMode&&t?`
|
|
958
|
+
<div class="dev-only-section">
|
|
959
|
+
<div class="dev-warning">
|
|
960
|
+
\u26A0\uFE0F Developer Mode Only
|
|
961
|
+
</div>
|
|
962
|
+
<button id="direct-apply-btn" class="persistence-btn danger-action">
|
|
963
|
+
\u{1F527} APPLY DIRECTLY (No Snapshot)
|
|
964
|
+
</button>
|
|
965
|
+
<p class="dev-hint">
|
|
966
|
+
This will directly modify base configs without creating a version snapshot.
|
|
967
|
+
Use with caution!
|
|
968
|
+
</p>
|
|
969
|
+
</div>
|
|
970
|
+
`:""}
|
|
971
|
+
|
|
972
|
+
${t?`
|
|
973
|
+
<div class="staging-area">
|
|
974
|
+
<div class="staging-header">
|
|
975
|
+
<span>Staging Area (Pending Review)</span>
|
|
976
|
+
<button class="staging-clear-all" id="clear-all-overrides">Discard All</button>
|
|
977
|
+
</div>
|
|
978
|
+
<div class="staging-list">
|
|
979
|
+
${Object.entries(r).map(([l,c])=>`
|
|
980
|
+
<div class="staging-group">
|
|
981
|
+
<div class="staging-group-title">
|
|
982
|
+
<span class="group-icon">${l==="Engine"?"\u2699\uFE0F":"\u{1F4E6}"}</span>
|
|
983
|
+
<span class="group-id">${l}</span>
|
|
984
|
+
</div>
|
|
985
|
+
<div class="staging-items">
|
|
986
|
+
${c.map(p=>`
|
|
987
|
+
<div class="staging-item">
|
|
988
|
+
<div class="item-path">${p.path}</div>
|
|
989
|
+
<div class="item-value" title="${JSON.stringify(p.value)}">
|
|
990
|
+
${this.formatValue(p.value)}
|
|
991
|
+
</div>
|
|
992
|
+
<button class="item-remove" data-remove-path="${p.path}" data-remove-id="${p.objectId||""}" title="Discard this change">\xD7</button>
|
|
993
|
+
</div>
|
|
994
|
+
`).join("")}
|
|
995
|
+
</div>
|
|
996
|
+
</div>
|
|
997
|
+
`).join("")}
|
|
998
|
+
</div>
|
|
999
|
+
</div>
|
|
1000
|
+
`:`
|
|
1001
|
+
<div class="persistence-empty-state">
|
|
1002
|
+
<div class="empty-icon">\u{1F4C2}</div>
|
|
1003
|
+
<p>No pending changes to review.</p>
|
|
1004
|
+
<p class="empty-hint">Modify properties in the Inspector or change assets in the Library to see them here.</p>
|
|
1005
|
+
</div>
|
|
1006
|
+
`}
|
|
1007
|
+
|
|
1008
|
+
<div class="persistence-footer">
|
|
1009
|
+
<div class="footer-row">
|
|
1010
|
+
<span class="footer-label">Last Applied:</span>
|
|
1011
|
+
<span class="footer-value">${o}</span>
|
|
1012
|
+
</div>
|
|
1013
|
+
<div class="footer-secondary-actions">
|
|
1014
|
+
<button id="reset-to-applied-btn" class="footer-btn" ${t?"":"disabled"}>Reload State</button>
|
|
1015
|
+
<button id="reset-to-original-btn" class="footer-btn danger">Factory Reset (Pristine)</button>
|
|
1016
|
+
</div>
|
|
1017
|
+
</div>
|
|
1018
|
+
|
|
1019
|
+
<div class="persistence-info">
|
|
1020
|
+
<p><strong>Apply to Project</strong> writes the current preview state to your local .json files in /configs/ folder. This state will be used for the dashboard build.</p>
|
|
1021
|
+
</div>
|
|
1022
|
+
</div>
|
|
1023
|
+
`}formatValue(e){return e===null?"null":typeof e=="string"?e.length>25?e.substring(0,22)+"...":e:typeof e=="object"?"{...}":String(e)}setupEventListeners(){if(!this.container)return;let e=this.container.querySelector("#apply-to-project-btn");e==null||e.addEventListener("click",async()=>{var p;if(!(e.getAttribute("disabled")!==null||!confirm("This will permanently update your project configuration files on disk. Are you sure?")))try{let d=localStorage.getItem("handler_last_version_name")||"",g=((p=prompt("Version name for this Apply (e.g. v1, ab_red_cta, 2026-01-17a):",d))!=null?p:"").trim();if(!g){alert("Version name is required to Apply. (No changes were written.)");return}localStorage.setItem("handler_last_version_name",g),e.textContent="\u23F3 Writing to disk...",e.setAttribute("disabled","true"),await Oi(g),this.showSuccessNotification(),this.refreshPanel()}catch(d){console.error("[ConfigPersistence] Apply failed:",d),alert(`\u274C Apply failed: ${d.message}`),e.textContent="\u{1F4BE} APPLY ALL CHANGES TO PROJECT",e.removeAttribute("disabled")}}),this.container.querySelectorAll(".item-remove").forEach(c=>{c.addEventListener("click",()=>{let p=c.dataset.removePath,d=c.dataset.removeId;aa(d||void 0,p)})});let i=this.container.querySelector("#clear-all-overrides");i==null||i.addEventListener("click",()=>{confirm("Discard all staged changes?")&&ji()});let n=this.container.querySelector("#reset-to-applied-btn");n==null||n.addEventListener("click",()=>{confirm("Discard changes and reload last applied state?")&&ji()});let r=this.container.querySelector("#reset-to-original-btn");r==null||r.addEventListener("click",async()=>{await oa()});let s=this.container.querySelector("#version-selector");s==null||s.addEventListener("change",async c=>{let d=c.target.value;await this.switchVersion(d)});let o=this.container.querySelector("#create-version-btn");o==null||o.addEventListener("click",async()=>{var p;if(!(o.getAttribute("disabled")!==null||!confirm("This will create a new version snapshot and save your changes. Continue?")))try{let d=localStorage.getItem("handler_last_version_name")||"",g=((p=prompt("Version name (e.g. v1, test_2024):",d))!=null?p:"").trim();if(!g){alert("Version name is required. (No changes were written.)");return}localStorage.setItem("handler_last_version_name",g),o.textContent="\u23F3 Creating version...",o.setAttribute("disabled","true"),await Oi(g),this.showSuccessNotification(),await this.loadVersionsList(),this.refreshPanel()}catch(d){console.error("[ConfigPersistence] Create version failed:",d),alert(`\u274C Failed to create version: ${d.message}`),o.textContent="\u{1F4DD} Create New Version",o.removeAttribute("disabled")}});let l=this.container.querySelector("#direct-apply-btn");l==null||l.addEventListener("click",async()=>{await this.directApply()})}showSuccessNotification(){let e=document.createElement("div");e.className="persistence-notification success",e.innerHTML=`
|
|
1024
|
+
<div class="notify-icon">\u2705</div>
|
|
1025
|
+
<div class="notify-content">
|
|
1026
|
+
<strong>Changes Applied!</strong>
|
|
1027
|
+
<span>Project files updated.</span>
|
|
1028
|
+
</div>
|
|
1029
|
+
`,document.body.appendChild(e),setTimeout(()=>{e.classList.add("out"),setTimeout(()=>e.remove(),500)},3e3)}refreshPanel(){if(!this.container)return;let e=this.container.querySelector(".config-persistence-panel");e?e.outerHTML=this.render():this.container.innerHTML=this.render(),this.setupEventListeners()}async loadVersionsList(){try{let e=await fetch("/api/versions");if(!e.ok)throw new Error("Failed to fetch versions");let t=await e.json();this.availableVersions=t.versions||[],this.currentVersion=t.current||null}catch(e){console.error("[ConfigPersistence] Failed to load versions:",e),this.availableVersions=[],this.currentVersion=null}}async switchVersion(e){if(confirm(`Switch to version "${e||"original"}"?
|
|
1030
|
+
|
|
1031
|
+
All unsaved changes in the current version will be lost.`))try{let i=await fetch("/api/switch-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({versionName:e||null})});if(!i.ok){let n=await i.json();throw new Error(n.error||"Failed to switch version")}Mi(),window.location.reload()}catch(i){alert(`\u274C Failed to switch version: ${i.message}`)}}async directApply(){if(!this.isDevelopmentMode){alert("Direct Apply is only available in development mode.");return}if(confirm(`\u26A0\uFE0F WARNING: Direct Apply
|
|
1032
|
+
|
|
1033
|
+
This will DIRECTLY MODIFY your base configuration files WITHOUT creating a snapshot.
|
|
1034
|
+
|
|
1035
|
+
This cannot be undone unless you have git commits or backups.
|
|
1036
|
+
|
|
1037
|
+
Are you absolutely sure?`))try{let t=ra(),i={};for(let[r,s]of Object.entries(t.objects)){let o=s,l=r;/^(json\.|ui\.|effects\.|engine\.)/.test(l)||(l=`json.${r}`),o&&typeof o=="object"&&(o.identity||(o.identity={}),o.identity.id=l),i[`objects/${l}.json`]=o}t.engine&&(t.engine.runtime&&(i["engine/engine.runtime.json"]=t.engine.runtime),t.engine.assets&&(i["engine/engine.assets.json"]=t.engine.assets),t.engine.splash&&(i["engine/engine.splash.json"]=t.engine.splash),t.engine.loading&&(i["engine/engine.loading.json"]=t.engine.loading),t.engine.start&&(i["engine/engine.start.json"]=t.engine.start),t.engine.tutorial&&(i["engine/engine.tutorial.json"]=t.engine.tutorial),t.engine.endgame&&(i["engine/engine.endgame.json"]=t.engine.endgame),!t.engine.runtime&&!t.engine.assets&&(i["engine/engine.json"]=t.engine));for(let[r,s]of Object.entries(t.scenes)){let o=r.startsWith("scene.")?r:`scene.${r}`;i[`scenes/${o}.json`]=s}let n=await fetch("/api/apply-direct",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:i,assets:{}})});if(!n.ok){let r=await n.json();throw new Error(r.error||"Direct apply failed")}Mi(),this.showSuccessNotification(),this.refreshPanel()}catch(t){console.error("[ConfigPersistence] Direct apply failed:",t),alert(`\u274C Direct apply failed: ${t.message}`)}}};var di=class{constructor(){this.debugOverlay=null;this.isDebugOpen=!1;this.selectedObjectId=null;this.configViewer=null;this.container=null;this.objectAutoApplyTimer=null;this.objectDebugRaf=null;this.objectBoundsGfx=null;this.objectAnchorGfx=null;this.highlightObject=!1;this.highlightAnchor=!1;this.activeTab="hierarchy";this.sceneObjectsPanel=new Dt;this.sceneToolsPanel=new zt;this.inspectorPanel=new Xt;this.libraryPanel=new Ht;this.brandVisionPanel=new Qt;this.customizeSettingsPanel=new ei;this.configPersistencePanel=new ci;this.loadingScreenPanel=new ti}applyAssetChange(e,t){return ir(this,e,t)}resetAsset(e){return nr(this,e)}applySlotAsset(e,t,i){return ar(this,e,t,i)}resetSlotAsset(e,t,i){return rr(this,e,t,i)}startObjectVisuals(){return pr(this)}stopObjectVisuals(){return ur(this)}shouldRunObjectVisuals(){return ni(this)}updateObjectVisuals(){return ai(this)}getSelectedInstanceId(){return Ji(this)}getDisplayObjectById(e){return Zi(this,e)}getSelectedObjectConfig(){return ut(this)}getConfigAnchorWorldPoint(e){return Qi(this,e)}getScreenSize(){return en(this)}ensureBoundsGfx(){return tn(this)}ensureAnchorGfx(){return nn(this)}drawBounds(e){return an(this,e)}drawAnchor(e){return rn(this,e)}clearBounds(){return sn(this)}clearAnchor(){return on(this)}clearObjectVisuals(){return pt(this)}updateObjectInfo(e){return dt(this,e)}resetDebugConfig(){return si(this)}applyDebugConfig(){return fr(this)}exportDebugConfig(){return oi(this)}loadObjectConfig(e){return mr(this,e)}fillConfigViewer(e){return ri(this,e)}copyConfigValues(){return br(this)}applyObjectConfig(e){return cn(this,e)}applyCustomizeSettings(e,t){return yr(this,e,t)}scheduleObjectAutoApply(){return vr(this)}setupDebugEventListeners(){return wr(this)}setupDebugInputListeners(e){return un(this,e)}setupPanelLayout(){return Er(this)}setupCollapsiblePanels(e){return gn(this,e)}setupRangeInput(e,t,i,n){return re(this,e,t,i,n)}updateWorkbenchTabs(){return pn(this)}saveWorkbenchState(){return Ie(this)}loadWorkbenchState(){return li(this)}initialize(e){var t;this.container=e,this.debugOverlay=e.querySelector(".debug-overlay"),this.configViewer=e.querySelector("#config-viewer");try{let i=localStorage.getItem("preview_workbench_state");if(i){let n=JSON.parse(i);n.activeTab&&(this.activeTab=n.activeTab)}}catch(i){console.warn("[PREVIEW] Failed to load workbench tab state",i)}this.sceneObjectsPanel.initialize(e,{onSelect:i=>this.handleObjectSelect(i)}),this.libraryPanel.initialize(e,{onApply:(i,n,r)=>this.applySlotAsset(i,n,r),onReset:(i,n,r)=>this.resetSlotAsset(i,n,r)}),this.inspectorPanel.initialize(e,{onPropertyChange:(i,n,r)=>{console.log("[Inspector] Property changed:",i,n,r)}}),this.brandVisionPanel.initialize(e,()=>{this.toggleDebug(!1);let i="/dashboard";window.location.pathname!==i&&(window.location.href=i)}),this.customizeSettingsPanel.initialize(e,{onApply:(i,n)=>this.applyCustomizeSettings(i,n)}),this.sceneToolsPanel.initialize(e,{onHighlightObject:i=>{this.highlightObject=i,i?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onHighlightAnchor:i=>{this.highlightAnchor=i,i?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onNudge:(i,n)=>this.nudgeSelectedObject(i,n),onShowSplash:()=>{let i=window;typeof i.__previewShowSplash=="function"&&i.__previewShowSplash()},onUpdateSplash:i=>{let n=window;typeof n.applyEditableEngineConfig=="function"&&n.applyEditableEngineConfig({splash:i})}}),this.configPersistencePanel.initialize(e),this.loadingScreenPanel.initialize(e,{onShowLoadingScreen:()=>{let i=window;typeof i.__previewShowLoading=="function"?i.__previewShowLoading():console.warn("[DEBUG] __previewShowLoading not available")},onHideLoadingScreen:()=>{let i=window;typeof i.__previewHideLoading=="function"?i.__previewHideLoading():console.warn("[DEBUG] __previewHideLoading not available")},onUpdateLoading:i=>{let n=window;typeof n.applyEditableEngineConfig=="function"&&n.applyEditableEngineConfig({loading:i}),typeof n.__previewUpdateLoading=="function"?n.__previewUpdateLoading(i):console.warn("[DEBUG] __previewUpdateLoading not available")}}),window.__openAiEditor=(i,n,r,s)=>{this.customizeSettingsPanel.openAiEditor(i,n,r,s)},this.setupPanelLayout(),this.updateWorkbenchTabs(),window.__debugContext=this,window.__updateWorkbenchTabs=()=>this.updateWorkbenchTabs(),this.isDebugOpen=!0,(t=this.debugOverlay)==null||t.classList.remove("hidden"),this.updateDebugBadge(),this.sceneObjectsPanel.refreshObjects(),window.__previewSelectObject=i=>this.selectObject(i),window.addEventListener("config:changed",i=>{var n,r;((n=i.detail)==null?void 0:n.action)!=="remove"&&((r=i.detail)==null?void 0:r.action)!=="clear_object"&&this.highlightChangesTab()}),window.applyAssetToSlot=(i,n,r)=>this.applySlotAsset(i,n,r),window.refreshAssetLibrary=()=>this.libraryPanel.refresh(),window.reRenderAssetLibrary=()=>this.libraryPanel.reRender(),window.getEngineSplashConfig=()=>{var n;let i=window.getActiveConfig;if(typeof i=="function"){let r=i();return((n=r==null?void 0:r.engine)==null?void 0:n.splash)||null}return null},window.addAssetToRegistry=(i,n)=>{let r=window.getEditableAssets;if(typeof r=="function"){let s=r();if(s!=null&&s.libraryAssets&&(s.libraryAssets[i]||(s.libraryAssets[i]=[]),!s.libraryAssets[i].some(l=>l.filename===n))){let l=n.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");s.libraryAssets[i].unshift({filename:n,displayName:l}),console.log(`[DEBUG] Added ${n} to registry category ${i}`)}}}}selectObject(e){this.handleObjectSelect(e),this.activeTab!=="inspector"&&(this.activeTab="inspector",this.updateWorkbenchTabs())}highlightChangesTab(){var t;let e=(t=this.container)==null?void 0:t.querySelector('[data-tab="changes"]');e&&e.classList.add("has-pending-changes")}getDebugOverlayHTML(){return`
|
|
1038
|
+
<div class="debug-overlay hidden" id="debug-overlay">
|
|
1039
|
+
<div class="debug-workbench" id="debug-workbench">
|
|
1040
|
+
<div class="workbench-header" id="workbench-handle">
|
|
1041
|
+
<div class="panel-title">
|
|
1042
|
+
<span class="panel-pill">Workbench</span>
|
|
1043
|
+
<span class="panel-title-text">Debug Console</span>
|
|
1044
|
+
</div>
|
|
1045
|
+
<div class="scene-panel-actions">
|
|
1046
|
+
<button class="scene-panel-action" type="button" id="debug-close">Close</button>
|
|
1047
|
+
</div>
|
|
1048
|
+
</div>
|
|
1049
|
+
<div class="workbench-tabs">
|
|
1050
|
+
<button class="workbench-tab ${this.activeTab==="inspector"?"active":""}" data-tab="inspector">Inspector</button>
|
|
1051
|
+
<button class="workbench-tab ${this.activeTab==="library"?"active":""}" data-tab="library">Library</button>
|
|
1052
|
+
<button class="workbench-tab ${this.activeTab==="ai"?"active":""}" data-tab="ai">\u2728 AI Suite</button>
|
|
1053
|
+
<button class="workbench-tab ${this.activeTab==="loading"?"active":""}" data-tab="loading">\u23F3 Loading</button>
|
|
1054
|
+
<button class="workbench-tab ${this.activeTab==="changes"?"active":""}" data-tab="changes">\u{1F4BE} Changes</button>
|
|
1055
|
+
</div>
|
|
1056
|
+
<div class="workbench-content">
|
|
1057
|
+
<div class="workbench-tab-panel ${this.activeTab==="inspector"?"active":""}" data-tab-panel="inspector">
|
|
1058
|
+
${this.inspectorPanel.render()}
|
|
1059
|
+
</div>
|
|
1060
|
+
<div class="workbench-tab-panel ${this.activeTab==="library"?"active":""}" data-tab-panel="library">
|
|
1061
|
+
${this.libraryPanel.render()}
|
|
1062
|
+
</div>
|
|
1063
|
+
<div class="workbench-tab-panel ${this.activeTab==="ai"?"active":""}" data-tab-panel="ai">
|
|
1064
|
+
${this.brandVisionPanel.render()}
|
|
1065
|
+
${this.customizeSettingsPanel.render()}
|
|
1066
|
+
</div>
|
|
1067
|
+
<div class="workbench-tab-panel ${this.activeTab==="loading"?"active":""}" data-tab-panel="loading">
|
|
1068
|
+
${this.loadingScreenPanel.render()}
|
|
1069
|
+
</div>
|
|
1070
|
+
<div class="workbench-tab-panel ${this.activeTab==="changes"?"active":""}" data-tab-panel="changes">
|
|
1071
|
+
${this.configPersistencePanel.render()}
|
|
1072
|
+
</div>
|
|
1073
|
+
</div>
|
|
1074
|
+
<div class="workbench-resize-handle" id="workbench-resize"></div>
|
|
1075
|
+
</div>
|
|
1076
|
+
|
|
1077
|
+
<!-- Standalone Hierarchy Panel -->
|
|
1078
|
+
${this.sceneObjectsPanel.render()}
|
|
1079
|
+
|
|
1080
|
+
<!-- Standalone Scene Tools Corner Panel -->
|
|
1081
|
+
${this.sceneToolsPanel.render()}
|
|
1082
|
+
</div>
|
|
1083
|
+
`}refresh(){this.isDebugOpen&&(this.sceneObjectsPanel.refreshObjects(),this.libraryPanel.refresh(),this.brandVisionPanel.refresh(),this.selectedObjectId&&this.handleObjectSelect(this.selectedObjectId))}toggleDebug(e){var t;this.isDebugOpen=e!=null?e:!this.isDebugOpen,(t=this.debugOverlay)==null||t.classList.toggle("hidden",!this.isDebugOpen),this.updateDebugBadge(),this.isDebugOpen?this.refresh():this.stopObjectVisuals()}updateDebugBadge(){if(!this.container)return;let e=this.container.querySelector("#debug-badge");e&&e.classList.toggle("active",this.isDebugOpen)}handleObjectSelect(e){this.selectedObjectId=e,this.sceneObjectsPanel.setSelected(e),this.inspectorPanel.loadObject(e),this.loadObjectConfig(e),this.startObjectVisuals()}nudgeSelectedObject(e,t){var d,u,g,f,h,m,b,y,v;if(!this.container||!this.selectedObjectId)return;let n=this.sceneToolsPanel.getNudgeStep(),r=this.container.querySelector("#config-pos-x"),s=this.container.querySelector("#config-pos-y"),o=Number((d=r==null?void 0:r.value)!=null?d:0),l=Number((u=s==null?void 0:s.value)!=null?u:0);if(!Number.isFinite(o)||!Number.isFinite(l)){let x=this.getSelectedObjectConfig();o=(h=(f=(g=x==null?void 0:x.transform)==null?void 0:g.position)==null?void 0:f.x)!=null?h:0,l=(y=(b=(m=x==null?void 0:x.transform)==null?void 0:m.position)==null?void 0:b.y)!=null?y:0}let c=o+e*n,p=l+t*n;r&&(r.value=String(c)),s&&(s.value=String(p)),(v=this.configViewer)==null||v.style.setProperty("display","block"),this.scheduleObjectAutoApply()}};function ws(a){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(a)})}function Es(a){var n;let[e,t]=a.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(n=i==null?void 0:i[1])!=null?n:"image/png"}}function As(a){return`
|
|
1084
|
+
Analyze these screenshots of a brand or game and extract its "Brand DNA".
|
|
1085
|
+
|
|
1086
|
+
Provide a concise summary (2-3 sentences) covering:
|
|
1087
|
+
1. Primary and secondary brand colors.
|
|
1088
|
+
2. The overall aesthetic "vibe" (e.g., minimalist, neon, glossy, retro, corporate).
|
|
1089
|
+
3. Common UI patterns (e.g., rounded buttons, flat icons).
|
|
1090
|
+
|
|
1091
|
+
Then, list the exact hex color codes (#RRGGBB) found in the screenshots.
|
|
1092
|
+
|
|
1093
|
+
FORMAT:
|
|
1094
|
+
Summary: [Your summary here]
|
|
1095
|
+
Palette: [#RRGGBB, #RRGGBB, ...]
|
|
1096
|
+
|
|
1097
|
+
${a?`
|
|
1098
|
+
ADDITIONAL RULES/NOTES:
|
|
1099
|
+
${a}`:""}
|
|
1100
|
+
`.trim()}function Ar(){let a=[],e="",t=null;return{async addSources(i){let n=[];for(let r of i){let s=await ws(r),o=Es(s),l={id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,name:r.name,base64:o.base64,mimeType:o.mimeType,dataUrl:s};a.push(l),n.push(l)}return n},getSources(){return a.slice()},async analyze(i,n,r){if(a.length===0)throw new Error("No screenshots to analyze.");let s=As(n),o=a.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Zt(i,s,o,{model:r}),c=e,p=[],d=l.split(`
|
|
1101
|
+
`);for(let u of d)if(u.toLowerCase().startsWith("summary:"))c=u.slice(8).trim();else if(u.toLowerCase().includes("palette:")){let g=u.match(/#[0-9A-Fa-f]{6}/g);g&&g.forEach(f=>{p.includes(f.toUpperCase())||p.push(f.toUpperCase())})}return(!c||c===e)&&(c=l.split(`
|
|
1102
|
+
Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:p.slice(0,10)},t},setSummary(i){e=i,t&&(t={...t,summary:i})},getResult(){return t}}}var Oe="handler_api_key_";var We=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},r=`${Oe}${e}`;localStorage.setItem(r,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${Oe}${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=`${Oe}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${Oe}${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(Oe)){let n=i.substring(Oe.length),r=localStorage.getItem(i);if(r){let s=JSON.parse(r);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(Oe)&&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=()=>We.getKey("gemini"),fn=(a,e)=>We.setKey("gemini",a,e),Ss=()=>We.hasKey("gemini");window.ApiKeyStorage=We;window.getGeminiApiKey=hn;window.setGeminiApiKey=fn;window.hasGeminiApiKey=Ss;var bn=class{constructor(){this.modal=null;this.options=null;this.analyzer=Ar();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=`
|
|
1103
|
+
<div class="ai-modal-card">
|
|
1104
|
+
<div class="ai-modal-header">
|
|
1105
|
+
<div class="ai-modal-actions">
|
|
1106
|
+
<button class="ai-modal-gallery" type="button" data-action="gallery">
|
|
1107
|
+
\u{1F5BC}\uFE0F Gallery
|
|
1108
|
+
</button>
|
|
1109
|
+
</div>
|
|
1110
|
+
<div>
|
|
1111
|
+
<div class="ai-modal-title">AI Image Editor</div>
|
|
1112
|
+
<div class="ai-modal-subtitle">${((t=this.options)==null?void 0:t.objectId)||"Unknown Object"}</div>
|
|
1113
|
+
</div>
|
|
1114
|
+
<button class="ai-modal-close" type="button" data-action="close">\xD7</button>
|
|
1115
|
+
</div>
|
|
1116
|
+
|
|
1117
|
+
<div class="ai-modal-body">
|
|
1118
|
+
<!-- PROMPT INPUT -->
|
|
1119
|
+
<div class="ai-section">
|
|
1120
|
+
<label class="ai-label">Prompt</label>
|
|
1121
|
+
<textarea
|
|
1122
|
+
class="ai-textarea"
|
|
1123
|
+
placeholder="Describe the image you want to generate..."
|
|
1124
|
+
rows="3"
|
|
1125
|
+
>${this.currentPrompt}</textarea>
|
|
1126
|
+
</div>
|
|
1127
|
+
|
|
1128
|
+
<!-- STRENGTH CONTROLS -->
|
|
1129
|
+
<div class="ai-section">
|
|
1130
|
+
<div class="ai-row ai-strength">
|
|
1131
|
+
<label class="ai-label">Creativity</label>
|
|
1132
|
+
<input
|
|
1133
|
+
type="range"
|
|
1134
|
+
class="ai-input"
|
|
1135
|
+
min="0.1"
|
|
1136
|
+
max="1.0"
|
|
1137
|
+
step="0.1"
|
|
1138
|
+
value="0.8"
|
|
1139
|
+
data-strength="creativity"
|
|
1140
|
+
/>
|
|
1141
|
+
<span class="ai-strength-value">0.8</span>
|
|
1142
|
+
</div>
|
|
1143
|
+
</div>
|
|
1144
|
+
|
|
1145
|
+
<!-- BRAND DNA -->
|
|
1146
|
+
<div class="ai-section">
|
|
1147
|
+
<div class="ai-row">
|
|
1148
|
+
<input type="checkbox" id="ai-use-dna" checked />
|
|
1149
|
+
<label for="ai-use-dna" class="ai-label">Apply Brand DNA</label>
|
|
1150
|
+
</div>
|
|
1151
|
+
</div>
|
|
1152
|
+
|
|
1153
|
+
<!-- PREVIEW AREA -->
|
|
1154
|
+
<div class="ai-section">
|
|
1155
|
+
<div class="ai-preview" data-preview>
|
|
1156
|
+
<div class="ai-preview-placeholder">
|
|
1157
|
+
Generated images will appear here
|
|
1158
|
+
</div>
|
|
1159
|
+
</div>
|
|
1160
|
+
</div>
|
|
1161
|
+
|
|
1162
|
+
<!-- LOADING INDICATOR -->
|
|
1163
|
+
<div class="ai-loading hidden" data-loading>
|
|
1164
|
+
<div class="ai-loading-ring"></div>
|
|
1165
|
+
<div class="ai-loading-text">Generating image...</div>
|
|
1166
|
+
</div>
|
|
1167
|
+
|
|
1168
|
+
<!-- GALLERY (hidden by default) -->
|
|
1169
|
+
<div class="ai-gallery hidden" data-gallery>
|
|
1170
|
+
<div class="ai-gallery-grid" data-gallery-grid></div>
|
|
1171
|
+
</div>
|
|
1172
|
+
</div>
|
|
1173
|
+
|
|
1174
|
+
<!-- ACTION BUTTONS -->
|
|
1175
|
+
<div class="ai-modal-actions">
|
|
1176
|
+
<button class="ai-btn" data-action="cancel">Cancel</button>
|
|
1177
|
+
<button class="ai-btn" data-action="generate" disabled>Generate</button>
|
|
1178
|
+
<button class="ai-btn primary" data-action="apply" disabled>Apply</button>
|
|
1179
|
+
</div>
|
|
1180
|
+
</div>
|
|
1181
|
+
`,this.modal=e,this.attachEventListeners(),this.updatePromptFromDna()}attachEventListeners(){var i;if(!this.modal)return;this.promptInput=this.modal.querySelector(".ai-textarea"),this.generateBtn=this.modal.querySelector('[data-action="generate"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),(i=this.promptInput)==null||i.addEventListener("input",()=>{var n;this.currentPrompt=((n=this.promptInput)==null?void 0:n.value)||"",this.updateGenerateButton()});let e=this.modal.querySelector('[data-strength="creativity"]'),t=this.modal.querySelector(".ai-strength-value");e==null||e.addEventListener("input",()=>{t.textContent=e.value}),this.modal.addEventListener("click",n=>{var o;let r=n.target;switch(r.dataset.action||((o=r.closest("[data-action]"))==null?void 0:o.getAttribute("data-action"))){case"generate":this.generateImage();break;case"apply":this.applySelectedImage();break;case"gallery":this.toggleGallery();break;case"close":case"cancel":this.close();break}}),this.modal.addEventListener("click",n=>{let r=n.target;if(r.classList.contains("ai-gallery-item")||r.closest(".ai-gallery-item")){let s=r.closest(".ai-gallery-item"),o=parseInt(s.dataset.index||"-1");o>=0&&this.selectImage(o)}}),this.modal.addEventListener("click",n=>{n.target===this.modal&&this.close()}),this.updateGenerateButton()}updateGenerateButton(){if(!this.generateBtn)return;let e=this.currentPrompt.trim().length>0;this.generateBtn.disabled=!e||this.isGenerating}async updatePromptFromDna(){var t;let e=(t=this.modal)==null?void 0:t.querySelector("#ai-use-dna");if(e!=null&&e.checked)try{let i=this.analyzer.getResult();if(i!=null&&i.summary&&this.promptInput){let n=`${this.currentPrompt}
|
|
1182
|
+
|
|
1183
|
+
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 r=this.getApiKey();if(!r){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 Jt(this.options.currentValue);c&&(s=[{base64:c.base64,mimeType:c.mimeType}])}catch(c){console.warn("[AiEditorModal] Failed to load current image:",c)}let o=await Ye(r,this.currentPrompt,s,{aspectRatio:"1:1"}),l=await Ve(o);this.generatedImages.push(l||o),this.selectedImageIndex=this.generatedImages.length-1,this.updateGallery(),this.updatePreview(),this.updateApplyButton()}catch(r){console.error("[AiEditorModal] Generation failed:",r),alert(`Generation failed: ${r instanceof Error?r.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)=>`
|
|
1184
|
+
<div class="ai-gallery-item ${i===this.selectedImageIndex?"active":""}" data-index="${i}">
|
|
1185
|
+
<img class="ai-gallery-thumb" src="${t}" alt="Generated ${i+1}" />
|
|
1186
|
+
<div class="ai-gallery-label">#${i+1}</div>
|
|
1187
|
+
</div>
|
|
1188
|
+
`).join(""))}updatePreview(){if(!this.previewEl||this.selectedImageIndex<0)return;let e=this.generatedImages[this.selectedImageIndex];this.previewEl.innerHTML=`<img src="${e}" alt="Selected image" />`}selectImage(e){e<0||e>=this.generatedImages.length||(this.selectedImageIndex=e,this.updateGallery(),this.updatePreview(),this.updateApplyButton())}toggleGallery(){this.galleryEl&&this.galleryEl.classList.toggle("hidden")}updateApplyButton(){var t;let e=(t=this.modal)==null?void 0:t.querySelector('[data-action="apply"]');e&&(e.disabled=this.selectedImageIndex<0)}applySelectedImage(){var t;if(this.selectedImageIndex<0||!((t=this.options)!=null&&t.onApply))return;let e=this.generatedImages[this.selectedImageIndex];this.options.onApply(e),this.close()}getApiKey(){let e=hn();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return fn(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}},mn=null;window.__openAiEditor=function(a,e,t,i){mn||(mn=new bn),mn.open({objectId:a,initialPrompt:e,currentValue:t,path:i==null?void 0:i.path,onApply:n=>{if(i!=null&&i.path){let r=window.updateManager;if(r)r.updateProperty(a,i.path,n);else{let s=window.getEditableObjectConfig,o=s==null?void 0:s(a);if(o){let l=i.path.split("."),c=o;for(let p=0;p<l.length-1;p++)c[l[p]]||(c[l[p]]={}),c=c[l[p]];c[l[l.length-1]]=n}}}window.dispatchEvent(new CustomEvent("inspector:refresh"))}})};var yn=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",r=document.createElement("div");r.className="asset-preview-modal",r.innerHTML=`
|
|
1189
|
+
<div class="asset-preview-card">
|
|
1190
|
+
<div class="asset-preview-header">
|
|
1191
|
+
<div class="asset-preview-title">${n}</div>
|
|
1192
|
+
<button class="asset-preview-close" data-action="close">\xD7</button>
|
|
1193
|
+
</div>
|
|
1194
|
+
|
|
1195
|
+
<div class="asset-preview-meta">
|
|
1196
|
+
<div>Type: ${t.toUpperCase()}</div>
|
|
1197
|
+
<div>Path: ${e||"None"}</div>
|
|
1198
|
+
</div>
|
|
1199
|
+
|
|
1200
|
+
<div class="asset-preview-body">
|
|
1201
|
+
${this.renderAssetContent(e,t)}
|
|
1202
|
+
</div>
|
|
1203
|
+
|
|
1204
|
+
<div class="asset-preview-actions">
|
|
1205
|
+
<button class="asset-preview-change" data-action="change">Change Asset</button>
|
|
1206
|
+
${t==="image"?'<button class="asset-preview-ai" data-action="edit">\u2728 AI Edit</button>':""}
|
|
1207
|
+
</div>
|
|
1208
|
+
</div>
|
|
1209
|
+
`,this.modal=r,this.attachEventListeners()}renderAssetContent(e,t){if(!e)return'<div class="asset-preview-placeholder">No asset selected</div>';switch(t){case"image":return`<img src="${this.resolveAssetUrl(e)}" alt="Asset preview" style="max-width: 100%; max-height: 400px; object-fit: contain;" />`;case"audio":let n=this.resolveAssetUrl(e);return`
|
|
1210
|
+
<audio controls style="width: 100%;">
|
|
1211
|
+
<source src="${n}" type="audio/mpeg">
|
|
1212
|
+
<source src="${n}" type="audio/wav">
|
|
1213
|
+
Your browser does not support the audio element.
|
|
1214
|
+
</audio>
|
|
1215
|
+
`;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-FTOKF3XD.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(a){new yn().open(a)};var vn=class{constructor(){this.modal=null;this.canvas=null;this.ctx=null;this.image=null;this.options=null;this.cropX=0;this.cropY=0;this.cropWidth=100;this.cropHeight=100;this.scale=1;this.panX=0;this.panY=0;this.isDragging=!1;this.dragStartX=0;this.dragStartY=0;this.lastPanX=0;this.lastPanY=0}open(e){this.options=e,this.createModal(),this.loadImage(),document.body.appendChild(this.modal)}createModal(){let e=document.createElement("div");e.className="asset-crop-modal",e.innerHTML=`
|
|
1216
|
+
<div class="asset-crop-card">
|
|
1217
|
+
<div class="asset-crop-header">
|
|
1218
|
+
<div>
|
|
1219
|
+
<div class="asset-crop-title">Crop Image</div>
|
|
1220
|
+
<div class="asset-crop-subtitle">Drag to reposition, scroll to zoom</div>
|
|
1221
|
+
</div>
|
|
1222
|
+
<button class="asset-crop-close" data-action="close">\xD7</button>
|
|
1223
|
+
</div>
|
|
1224
|
+
|
|
1225
|
+
<div class="asset-crop-body">
|
|
1226
|
+
<div class="asset-crop-column">
|
|
1227
|
+
<div class="asset-crop-canvas-container">
|
|
1228
|
+
<canvas class="asset-crop-canvas"></canvas>
|
|
1229
|
+
</div>
|
|
1230
|
+
|
|
1231
|
+
<div class="asset-crop-controls">
|
|
1232
|
+
<div class="asset-crop-zoom">
|
|
1233
|
+
<label class="asset-crop-label">Zoom</label>
|
|
1234
|
+
<input type="range" min="0.1" max="3" step="0.1" value="1" class="asset-crop-zoom-slider" />
|
|
1235
|
+
<span class="asset-crop-zoom-value">1.0x</span>
|
|
1236
|
+
</div>
|
|
1237
|
+
|
|
1238
|
+
<div class="asset-crop-aspect">
|
|
1239
|
+
<label class="asset-crop-label">Aspect Ratio</label>
|
|
1240
|
+
<select class="asset-crop-aspect-select">
|
|
1241
|
+
<option value="free">Free</option>
|
|
1242
|
+
<option value="1:1">Square (1:1)</option>
|
|
1243
|
+
<option value="4:3">Standard (4:3)</option>
|
|
1244
|
+
<option value="16:9">Widescreen (16:9)</option>
|
|
1245
|
+
<option value="3:2">Photo (3:2)</option>
|
|
1246
|
+
</select>
|
|
1247
|
+
</div>
|
|
1248
|
+
|
|
1249
|
+
<button class="asset-crop-reset" data-action="reset">Reset</button>
|
|
1250
|
+
</div>
|
|
1251
|
+
</div>
|
|
1252
|
+
|
|
1253
|
+
<div class="asset-crop-column">
|
|
1254
|
+
<div class="asset-crop-preview">
|
|
1255
|
+
<div class="asset-crop-preview-label">Preview</div>
|
|
1256
|
+
<canvas class="asset-crop-preview-canvas"></canvas>
|
|
1257
|
+
</div>
|
|
1258
|
+
</div>
|
|
1259
|
+
</div>
|
|
1260
|
+
|
|
1261
|
+
<div class="asset-crop-actions">
|
|
1262
|
+
<button class="asset-crop-apply" data-action="cancel">Cancel</button>
|
|
1263
|
+
<button class="asset-crop-apply primary" data-action="apply">Apply Crop</button>
|
|
1264
|
+
</div>
|
|
1265
|
+
</div>
|
|
1266
|
+
`,this.modal=e,this.attachEventListeners(),this.initializeCanvas()}initializeCanvas(){this.modal&&(this.canvas=this.modal.querySelector(".asset-crop-canvas"),this.canvas&&(this.ctx=this.canvas.getContext("2d"),this.canvas.width=400,this.canvas.height=300))}loadImage(){this.options&&(this.image=new Image,this.image.crossOrigin="anonymous",this.image.onload=()=>{this.initializeCrop(),this.render()},this.image.src=this.options.imageSrc)}initializeCrop(){var i;if(!this.image||!this.canvas)return;let e=this.image.width/this.image.height,t=this.canvas.width/this.canvas.height;e>t?(this.cropHeight=this.image.height,this.cropWidth=this.cropHeight*t,this.cropX=(this.image.width-this.cropWidth)/2,this.cropY=0):(this.cropWidth=this.image.width,this.cropHeight=this.cropWidth/t,this.cropX=0,this.cropY=(this.image.height-this.cropHeight)/2),(i=this.options)!=null&&i.aspectRatio&&this.applyAspectRatio(this.options.aspectRatio),this.fitToCanvas()}applyAspectRatio(e){if(!this.image)return;let t=this.image.width/this.image.height,i=this.cropX+this.cropWidth/2,n=this.cropY+this.cropHeight/2;e>t?(this.cropWidth=Math.min(this.image.width,this.cropHeight*e),this.cropHeight=this.cropWidth/e):(this.cropHeight=Math.min(this.image.height,this.cropWidth/e),this.cropWidth=this.cropHeight*e),this.cropX=Math.max(0,Math.min(this.image.width-this.cropWidth,i-this.cropWidth/2)),this.cropY=Math.max(0,Math.min(this.image.height-this.cropHeight,n-this.cropHeight/2))}fitToCanvas(){if(!this.image||!this.canvas)return;let e=this.canvas.width/this.cropWidth,t=this.canvas.height/this.cropHeight;this.scale=Math.min(e,t)*.9,this.panX=(this.canvas.width-this.cropWidth*this.scale)/2,this.panY=(this.canvas.height-this.cropHeight*this.scale)/2}render(){!this.ctx||!this.image||!this.canvas||(this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(this.panX,this.panY),this.ctx.scale(this.scale,this.scale),this.ctx.drawImage(this.image,-this.cropX,-this.cropY,this.image.width,this.image.height),this.ctx.restore(),this.drawCropOverlay(),this.updatePreview())}drawCropOverlay(){if(!this.ctx||!this.canvas)return;let e=this.panX,t=this.panY,i=this.cropWidth*this.scale,n=this.cropHeight*this.scale;this.ctx.fillStyle="rgba(0, 0, 0, 0.5)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.clearRect(e,t,i,n),this.ctx.strokeStyle="#ffffff",this.ctx.lineWidth=2,this.ctx.strokeRect(e,t,i,n),this.ctx.fillStyle="#ffffff";let r=8;[[e,t],[e+i-r,t],[e,t+n-r],[e+i-r,t+n-r]].forEach(([o,l])=>{var c;(c=this.ctx)==null||c.fillRect(o,l,r,r)})}updatePreview(){if(!this.modal||!this.image)return;let e=this.modal.querySelector(".asset-crop-preview-canvas");if(!e)return;let t=e.getContext("2d");if(!t)return;let i=150;e.width=i,e.height=i;let n=i/this.cropWidth,r=i/this.cropHeight,s=Math.min(n,r),o=this.cropWidth*s,l=this.cropHeight*s,c=(i-o)/2,p=(i-l)/2;t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,p,o,l)}attachEventListeners(){if(!this.modal||!this.canvas)return;this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("wheel",this.handleWheel.bind(this)),this.canvas.addEventListener("touchstart",this.handleTouchStart.bind(this)),this.canvas.addEventListener("touchmove",this.handleTouchMove.bind(this)),this.canvas.addEventListener("touchend",this.handleTouchEnd.bind(this));let e=this.modal.querySelector(".asset-crop-zoom-slider");e==null||e.addEventListener("input",i=>{let n=parseFloat(i.target.value);this.setZoom(n)});let t=this.modal.querySelector(".asset-crop-aspect-select");t==null||t.addEventListener("change",i=>{let n=i.target.value;this.setAspectRatio(n)}),this.modal.addEventListener("click",i=>{switch(i.target.dataset.action){case"reset":this.reset();break;case"apply":this.applyCrop();break;case"cancel":case"close":this.close();break}}),this.modal.addEventListener("click",i=>{i.target===this.modal&&this.close()})}handleMouseDown(e){this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY,this.lastPanX=this.panX,this.lastPanY=this.panY,this.canvas.style.cursor="grabbing"}handleMouseMove(e){if(!this.isDragging)return;let t=e.clientX-this.dragStartX,i=e.clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleMouseUp(){this.isDragging=!1,this.canvas.style.cursor="grab"}handleWheel(e){e.preventDefault();let t=e.deltaY>0?.9:1.1;this.setZoom(this.scale*t)}handleTouchStart(e){e.touches.length===1&&(this.isDragging=!0,this.dragStartX=e.touches[0].clientX,this.dragStartY=e.touches[0].clientY,this.lastPanX=this.panX,this.lastPanY=this.panY)}handleTouchMove(e){if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0].clientX-this.dragStartX,i=e.touches[0].clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleTouchEnd(){this.isDragging=!1}setZoom(e){this.scale=Math.max(.1,Math.min(3,e)),this.updateZoomUI(),this.constrainPan(),this.render()}setAspectRatio(e){let t;switch(e){case"1:1":t=1;break;case"4:3":t=4/3;break;case"16:9":t=16/9;break;case"3:2":t=3/2;break;default:t=void 0}t&&this.applyAspectRatio(t),this.fitToCanvas(),this.render()}updateZoomUI(){if(!this.modal)return;let e=this.modal.querySelector(".asset-crop-zoom-value"),t=this.modal.querySelector(".asset-crop-zoom-slider");e&&(e.textContent=`${this.scale.toFixed(1)}x`),t&&(t.value=this.scale.toString())}constrainPan(){if(!this.canvas)return;let e=this.cropWidth*this.scale,t=this.cropHeight*this.scale;this.panX=Math.max(this.canvas.width-e,Math.min(0,this.panX)),this.panY=Math.max(this.canvas.height-t,Math.min(0,this.panY))}reset(){this.initializeCrop(),this.render()}applyCrop(){var n;if(!this.image||!((n=this.options)!=null&&n.onCrop))return;let e=document.createElement("canvas"),t=e.getContext("2d");if(!t)return;e.width=this.cropWidth,e.height=this.cropHeight,t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,0,0,this.cropWidth,this.cropHeight);let i=e.toDataURL("image/png");this.options.onCrop(i),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal);let e=this.options;this.modal=null,this.canvas=null,this.ctx=null,this.image=null,this.options=null,e!=null&&e.onCancel&&e.onCancel()}};window.openAssetCrop=function(a){new vn().open(a)};var xn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.comparePresets=[Ge("playable-portrait"),Ge("iphone-14"),Ge("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.hasInitialFit=!1;this.isMounted=!1;this.isInitialized=!1;this.gameReady=!1;this.resizeListenersDisabled=!1;this.compareSnapshotTimer=null;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=Ge(e.defaultDevice||Fi.id),this.debugPanel=new di,this.container=this.createShell(),this.previewContainer=this.mustQuery(".preview-container"),this.singleStage=this.mustQuery('[data-preview-stage="single"]'),this.compareStage=this.mustQuery('[data-preview-stage="compare"]'),this.frameDragger=this.mustQuery(".frame-dragger"),this.frameWrapper=this.mustQuery(".frame-wrapper"),this.deviceFrame=this.mustQuery(".device-frame"),this.gameContainer=this.mustQuery(".game-container"),this.lastSinglePresetId=this.currentPreset.id,this.consolePanel=this.container.querySelector(".console-panel"),this.debugPanel.initialize(this.container),this.debugPanel.setupDebugEventListeners(),this.applyDeviceFrameStyles(),this.setupCompareViewports(),this.setupConsoleInterceptor(),this.setupObserversAndListeners(),this.setupFrameDragging(),this.setupSpaceKeyListener(),this.setDevice(this.currentPreset.id,{suppressCallback:!0}),this.isInitialized=!0}mount(e=document.body){e.innerHTML="",e.appendChild(this.container),this.isMounted=!0,this.scheduleFit()}destroy(){if(this.disableResizeListeners(),this.resizeObserver){try{this.resizeObserver.disconnect()}catch{}this.resizeObserver=null}window.removeEventListener("resize",this.onWindowResize),this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null),this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null),this.gameReady=!1}getGameContainer(){return this.gameContainer}getScreen(){let e=this.getEffectivePreset();return{width:e.width,height:e.height}}getEffectivePreset(){var e;return this.isLandscape?{...this.currentPreset,width:this.currentPreset.height,height:this.currentPreset.width,ratio:((e=this.currentPreset.ratio)==null?void 0:e.split(":").reverse().join(":"))||this.currentPreset.ratio}:this.currentPreset}notifyGameLoaded(){this.gameReady=!0,this.enableResizeListeners(),this.scheduleFit(),this.debugPanel.refresh()}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,r;let i=this.autoScale*this.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=Ge(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepVisibleScale:i}),t.suppressCallback||(r=(n=this.options).onDeviceChange)==null||r.call(n,this.getEffectivePreset()),this.emitScreenChange()}createShell(){var t;let e=document.createElement("div");return e.className="preview-shell",e.innerHTML=`
|
|
1267
|
+
<div class="preview-toolbar">
|
|
1268
|
+
<div class="preview-toolbar-left">
|
|
1269
|
+
<span class="preview-logo">PREVIEWER</span>
|
|
1270
|
+
</div>
|
|
1271
|
+
|
|
1272
|
+
<div class="preview-toolbar-center">
|
|
1273
|
+
<div class="device-selector-wrapper">
|
|
1274
|
+
<select class="device-dropdown" id="device-select">
|
|
1275
|
+
${Ba.map(i=>`
|
|
1276
|
+
<optgroup label="${i.label}">
|
|
1277
|
+
${i.devices.map(n=>`
|
|
1278
|
+
<option value="${n.id}" ${n.id===this.currentPreset.id?"selected":""}>
|
|
1279
|
+
${n.label} (${n.width}\xD7${n.height})
|
|
1280
|
+
</option>
|
|
1281
|
+
`).join("")}
|
|
1282
|
+
</optgroup>
|
|
1283
|
+
`).join("")}
|
|
1284
|
+
</select>
|
|
1285
|
+
</div>
|
|
1286
|
+
|
|
1287
|
+
<div class="view-toggle" role="group" aria-label="Preview mode">
|
|
1288
|
+
<button class="view-toggle-btn active" data-view-toggle="single" type="button">Single</button>
|
|
1289
|
+
<button class="view-toggle-btn" data-view-toggle="compare" type="button">Compare 3</button>
|
|
1290
|
+
</div>
|
|
1291
|
+
|
|
1292
|
+
<button class="preview-btn icon-btn" id="rotate-btn" title="Rotate">
|
|
1293
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1294
|
+
<path d="M21 12a9 9 0 11-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/>
|
|
1295
|
+
<path d="M21 3v5h-5"/>
|
|
1296
|
+
</svg>
|
|
1297
|
+
</button>
|
|
1298
|
+
|
|
1299
|
+
<div class="toolbar-divider"></div>
|
|
1300
|
+
|
|
1301
|
+
<button class="preview-btn icon-btn" id="zoom-out-btn" title="Zoom Out">
|
|
1302
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1303
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
1304
|
+
</svg>
|
|
1305
|
+
</button>
|
|
1306
|
+
|
|
1307
|
+
<span class="zoom-label" id="zoom-label">100%</span>
|
|
1308
|
+
|
|
1309
|
+
<button class="preview-btn icon-btn" id="zoom-in-btn" title="Zoom In">
|
|
1310
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1311
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
1312
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
1313
|
+
</svg>
|
|
1314
|
+
</button>
|
|
1315
|
+
</div>
|
|
1316
|
+
|
|
1317
|
+
<div class="preview-toolbar-right">
|
|
1318
|
+
<button class="preview-btn" id="refresh-btn">Restart</button>
|
|
1319
|
+
<button class="preview-btn debug-toggle" id="debug-toggle">
|
|
1320
|
+
Scene Edit Panel <span class="debug-toggle-badge" id="debug-badge"></span>
|
|
1321
|
+
</button>
|
|
1322
|
+
<button class="preview-btn console-toggle" id="console-toggle">
|
|
1323
|
+
Console <span class="console-badge" id="console-badge">0</span>
|
|
1324
|
+
</button>
|
|
1325
|
+
</div>
|
|
1326
|
+
</div>
|
|
1327
|
+
|
|
1328
|
+
<div class="preview-main">
|
|
1329
|
+
<div class="preview-container">
|
|
1330
|
+
<div class="preview-stage" data-preview-stage="single">
|
|
1331
|
+
<div class="frame-dragger">
|
|
1332
|
+
<div class="frame-wrapper">
|
|
1333
|
+
<div class="device-frame">
|
|
1334
|
+
<div class="game-container"></div>
|
|
1335
|
+
</div>
|
|
1336
|
+
</div>
|
|
1337
|
+
</div>
|
|
1338
|
+
</div>
|
|
1339
|
+
|
|
1340
|
+
<div class="preview-stage hidden" data-preview-stage="compare">
|
|
1341
|
+
<div class="compare-grid" data-compare-grid>
|
|
1342
|
+
${this.comparePresets.map(i=>`
|
|
1343
|
+
<div class="compare-viewport" data-viewport="${i.id}">
|
|
1344
|
+
<div class="compare-header">
|
|
1345
|
+
<div class="compare-title">
|
|
1346
|
+
<span class="compare-title-text">${i.label}</span>
|
|
1347
|
+
<span class="compare-meta">${i.ratio} | ${i.width}x${i.height}</span>
|
|
1348
|
+
</div>
|
|
1349
|
+
<button class="compare-focus" data-compare-focus type="button">Focus</button>
|
|
1350
|
+
</div>
|
|
1351
|
+
<div class="compare-body">
|
|
1352
|
+
<div class="compare-slot" data-compare-slot></div>
|
|
1353
|
+
<div class="compare-ghost" data-compare-ghost>
|
|
1354
|
+
<div class="frame-wrapper" data-compare-wrapper>
|
|
1355
|
+
<div class="device-frame" data-compare-frame>
|
|
1356
|
+
<canvas class="snapshot-canvas" data-compare-snapshot></canvas>
|
|
1357
|
+
</div>
|
|
1358
|
+
</div>
|
|
1359
|
+
</div>
|
|
1360
|
+
<div class="compare-overlay" data-compare-overlay>Click to focus</div>
|
|
1361
|
+
</div>
|
|
1362
|
+
</div>
|
|
1363
|
+
`).join("")}
|
|
1364
|
+
</div>
|
|
1365
|
+
</div>
|
|
1366
|
+
</div>
|
|
1367
|
+
|
|
1368
|
+
<!-- Corner Controls -->
|
|
1369
|
+
<div class="preview-corner-controls">
|
|
1370
|
+
<button class="corner-control-btn" id="corner-grab-btn" title="Hold Space to drag preview">
|
|
1371
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1372
|
+
<path d="M9 11V6a2 2 0 0 1 4 0v5M9 11a2 2 0 1 0-4 0v5a6 6 0 0 0 12 0v-3a2 2 0 1 0-4 0M9 11h4"/>
|
|
1373
|
+
</svg>
|
|
1374
|
+
</button>
|
|
1375
|
+
<button class="corner-control-btn" id="corner-zoom-out-btn" title="Zoom Out">
|
|
1376
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1377
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
1378
|
+
</svg>
|
|
1379
|
+
</button>
|
|
1380
|
+
<button class="corner-control-btn" id="corner-zoom-in-btn" title="Zoom In">
|
|
1381
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1382
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
1383
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
1384
|
+
</svg>
|
|
1385
|
+
</button>
|
|
1386
|
+
</div>
|
|
1387
|
+
|
|
1388
|
+
${((t=this.debugPanel)==null?void 0:t.getDebugOverlayHTML())||""}
|
|
1389
|
+
|
|
1390
|
+
<div class="console-panel closed">
|
|
1391
|
+
<div class="console-header">
|
|
1392
|
+
<span class="console-title">Debug Console</span>
|
|
1393
|
+
<div class="console-actions">
|
|
1394
|
+
<button class="console-action-btn" id="console-clear">Clear</button>
|
|
1395
|
+
<button class="console-action-btn" id="console-close">Close</button>
|
|
1396
|
+
</div>
|
|
1397
|
+
</div>
|
|
1398
|
+
<div class="console-messages" id="console-messages"></div>
|
|
1399
|
+
</div>
|
|
1400
|
+
</div>
|
|
1401
|
+
`,this.setupEventListeners(e),e}setupEventListeners(e){var n,r,s,o,l,c,p,d,u,g;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",f=>{if(this.viewMode==="compare")return;let h=f.target.value;this.setDevice(h)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(f=>{f.addEventListener("click",()=>{let h=f.dataset.viewToggle;h&&this.setViewMode(h)})}),(n=e.querySelector("#rotate-btn"))==null||n.addEventListener("click",()=>this.toggleRotation()),(r=e.querySelector("#zoom-in-btn"))==null||r.addEventListener("click",()=>this.adjustUserZoom(.1)),(s=e.querySelector("#zoom-out-btn"))==null||s.addEventListener("click",()=>this.adjustUserZoom(-.1)),(o=e.querySelector("#refresh-btn"))==null||o.addEventListener("click",()=>this.refresh()),(l=e.querySelector("#console-toggle"))==null||l.addEventListener("click",()=>this.toggleConsole()),(c=e.querySelector("#console-close"))==null||c.addEventListener("click",()=>this.toggleConsole(!1)),(p=e.querySelector("#console-clear"))==null||p.addEventListener("click",()=>this.clearConsole()),(d=e.querySelector("#corner-zoom-in-btn"))==null||d.addEventListener("click",()=>this.adjustUserZoom(.1)),(u=e.querySelector("#corner-zoom-out-btn"))==null||u.addEventListener("click",()=>this.adjustUserZoom(-.1)),(g=e.querySelector("#corner-grab-btn"))==null||g.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)})}applyDeviceFrameStyles(){Object.assign(this.frameDragger.style,{display:"flex",justifyContent:"center",alignItems:"center",transform:"translate(0px, 0px)",touchAction:"none"}),Object.assign(this.frameWrapper.style,{display:"flex",justifyContent:"center",alignItems:"center",transformOrigin:"center center",transition:"transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)",boxShadow:"0 20px 50px rgba(0,0,0,0.5)",borderRadius:"0px",willChange:"transform"}),Object.assign(this.deviceFrame.style,{overflow:"hidden",position:"relative",borderRadius:"0px"}),Object.assign(this.gameContainer.style,{position:"relative",overflow:"hidden",minWidth:"0px",minHeight:"0px"})}setupObserversAndListeners(){this.resizeObserver=new ResizeObserver(()=>{this.resizeListenersDisabled||!this.gameReady||this.scheduleFit()}),this.resizeObserver.observe(this.previewContainer),window.addEventListener("resize",this.onWindowResize,{passive:!0})}scheduleFit(){this.rafFitHandle&&cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=requestAnimationFrame(()=>{this.rafFitHandle=null,this.fitToScreen()})}applyPresetDimensions(){let e=this.getEffectivePreset(),t=`${e.width}px`,i=`${e.height}px`;this.deviceFrame.style.width=t,this.deviceFrame.style.height=i,this.gameContainer.style.width=t,this.gameContainer.style.height=i,this.gameContainer.style.maxWidth=t,this.gameContainer.style.maxHeight=i,this.gameContainer.style.minWidth=t,this.gameContainer.style.minHeight=i,this.gameContainer.dataset.screenWidth=String(e.width),this.gameContainer.dataset.screenHeight=String(e.height),this.container.style.setProperty("--preview-screen-width",String(e.width)),this.container.style.setProperty("--preview-screen-height",String(e.height))}fitToScreen(e){if(!this.previewContainer)return;let t=this.getEffectivePreset(),i=this.getFitBounds(),n=Math.max(0,i.width),r=Math.max(0,i.height);if(n<=0||r<=0)return;this.applyPresetDimensions(),this.viewMode==="compare"&&this.applyCompareDimensions();let s=n/t.width,o=r/t.height;if(this.autoScale=Math.max(.01,Math.min(s,o)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}e!=null&&e.keepVisibleScale&&e.keepVisibleScale>0&&(this.userScaleMultiplier=e.keepVisibleScale/this.autoScale),this.applyTransform(),this.viewMode==="compare"&&this.fitCompareGhosts(),this.emitScreenChange()}applyTransform(){let e=this.autoScale*this.userScaleMultiplier;this.frameWrapper.style.transform=`scale(${e})`;let t=this.container.querySelector("#zoom-label");t&&(t.textContent=`${Math.round(e*100)}%`)}applyFrameDrag(){this.frameDragger.style.transform=`translate(${this.frameDragOffsetX}px, ${this.frameDragOffsetY}px)`}setupFrameDragging(){this.frameDragger.addEventListener("pointerdown",e=>{let t=!this.gameContainer.contains(e.target);!this.isSpaceKeyPressed&&!t||e.button===0&&(e.preventDefault(),this.frameDragActive=!0,this.frameDragStartX=e.clientX,this.frameDragStartY=e.clientY,this.frameDragOriginX=this.frameDragOffsetX,this.frameDragOriginY=this.frameDragOffsetY,window.addEventListener("pointermove",this.onFrameDragMove),window.addEventListener("pointerup",this.onFrameDragEnd))})}setupSpaceKeyListener(){window.addEventListener("keydown",e=>{e.code==="Space"&&!this.isInputFocused()&&(this.isSpaceKeyPressed||(this.isSpaceKeyPressed=!0,this.updateDragCursor(),e.preventDefault()))}),window.addEventListener("keyup",e=>{e.code==="Space"&&(this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd())}),window.addEventListener("blur",()=>{this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd()})}isInputFocused(){let e=document.activeElement;if(!e)return!1;let t=e.tagName.toLowerCase();return t==="input"||t==="textarea"||t==="select"||e.isContentEditable}updateDragCursor(){this.isSpaceKeyPressed?(this.frameDragger.style.cursor="grab",this.frameDragActive&&(this.frameDragger.style.cursor="grabbing")):this.frameDragger.style.cursor=""}adjustUserZoom(e){this.userScaleMultiplier=Math.max(.1,Math.min(6,this.userScaleMultiplier+e)),this.applyTransform(),this.emitScreenChange()}toggleRotation(){var t,i;if(this.viewMode==="compare")return;let e=this.autoScale*this.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepVisibleScale:e}),(i=(t=this.options).onDeviceChange)==null||i.call(t,this.getEffectivePreset()),this.emitScreenChange()}emitScreenChange(){if(!this.gameReady)return;let e=this.getEffectivePreset(),t={width:e.width,height:e.height,dpr:Math.max(1,Math.floor(window.devicePixelRatio||1)),presetId:e.id,isLandscape:this.isLandscape};if(window.dispatchEvent(new CustomEvent("handler-preview:screen",{detail:t})),this.viewMode==="compare"&&this.refreshCompareSnapshots(),this.isInitialized&&this.isMounted&&this.gameReady){let i=window.gameApp;if(!(i!=null&&i.renderer))return;this.ignoreNextWindowResize=!0,window.dispatchEvent(new Event("resize"))}}safeStringify(e){var i;let t=new WeakSet;try{return JSON.stringify(e,(n,r)=>{if(typeof r=="object"&&r!==null){if(t.has(r))return"[Circular]";t.add(r)}return r},2)}catch{try{if(e&&((i=e.constructor)!=null&&i.name))return`[object ${e.constructor.name}]`}catch{}return String(e)}}setupConsoleInterceptor(){let e=console.log.bind(console),t=console.warn.bind(console),i=console.error.bind(console),n=console.info.bind(console),r=(s,...o)=>{let l=o.map(p=>typeof p=="object"?this.safeStringify(p):String(p)).join(" ");this.consoleMessages.push({type:s,message:l,timestamp:new Date}),this.appendConsoleMessage(this.consoleMessages[this.consoleMessages.length-1]);let c=this.container.querySelector("#console-badge");if(c){let p=this.consoleMessages.filter(d=>d.type==="error").length;c.textContent=p>0?`${p}!`:"0",c.classList.toggle("has-errors",p>0)}};console.log=(...s)=>{e(...s),r("log",...s)},console.warn=(...s)=>{t(...s),r("warn",...s)},console.error=(...s)=>{i(...s),r("error",...s)},console.info=(...s)=>{n(...s),r("info",...s)}}appendConsoleMessage(e){let t=this.container.querySelector("#console-messages");if(!t)return;let i=document.createElement("div");i.className=`console-msg type-${e.type}`;let n=e.timestamp.toLocaleTimeString();i.innerHTML=`<span class="time">${this.escapeHtml(n)}</span> <pre>${this.escapeHtml(e.message)}</pre>`,t.appendChild(i),t.scrollTop=t.scrollHeight}escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}toggleConsole(e){var t;this.isConsoleOpen=e!=null?e:!this.isConsoleOpen,(t=this.consolePanel)==null||t.classList.toggle("closed",!this.isConsoleOpen)}clearConsole(){this.consoleMessages=[];let e=this.container.querySelector("#console-messages");e&&(e.innerHTML="");let t=this.container.querySelector("#console-badge");t&&(t.textContent="0")}setupCompareViewports(){Array.from(this.container.querySelectorAll("[data-viewport]")).forEach(t=>{let i=t.dataset.viewport;if(!i)return;let n=this.comparePresets.find(d=>d.id===i);if(!n)return;let r=t.querySelector("[data-compare-slot]"),s=t.querySelector("[data-compare-ghost]"),o=t.querySelector("[data-compare-wrapper]"),l=t.querySelector("[data-compare-frame]"),c=t.querySelector("[data-compare-snapshot]"),p=t.querySelector("[data-compare-focus]");!r||!s||!o||!l||(t.addEventListener("click",d=>{let u=d.target;if(u!=null&&u.closest("[data-compare-focus]")){d.preventDefault(),this.activateCompareViewport(i);return}t.classList.contains("is-active")||this.activateCompareViewport(i)}),this.compareViewports.set(i,{preset:n,root:t,slot:r,ghost:s,wrapper:o,frame:l,canvas:c,focus:p}))})}setViewMode(e){if(this.viewMode===e)return;this.viewMode=e,this.container.classList.toggle("compare-mode",e==="compare"),this.singleStage.classList.toggle("hidden",e!=="single"),this.compareStage.classList.toggle("hidden",e!=="compare");let t=this.container.querySelector("#device-select");t&&(t.disabled=e==="compare");let i=this.container.querySelector("#rotate-btn");if(i&&(i.disabled=e==="compare"),this.updateViewToggleUI(),e==="compare"){this.lastSinglePresetId=this.currentPreset.id,this.activateCompareViewport(this.activeCompareId),this.refreshCompareSnapshots(),this.startCompareSnapshots();return}this.stopCompareSnapshots(),this.singleStage.appendChild(this.frameDragger),this.setDevice(this.lastSinglePresetId,{suppressCallback:!0}),this.fitToScreen()}updateViewToggleUI(){Array.from(this.container.querySelectorAll("[data-view-toggle]")).forEach(t=>{t.classList.toggle("active",t.dataset.viewToggle===this.viewMode)})}activateCompareViewport(e){var r,s;let t=this.compareViewports.get(e);if(!t)return;let i=this.autoScale*this.userScaleMultiplier,n=this.activeCompareId;n&&n!==e&&this.captureCompareSnapshot(n),this.activeCompareId=e,this.currentPreset=t.preset,this.isLandscape=!1,t.slot.appendChild(this.frameDragger),this.frameDragOffsetX=0,this.frameDragOffsetY=0,this.applyFrameDrag(),this.compareViewports.forEach((o,l)=>{o.root.classList.toggle("is-active",l===e),o.ghost.classList.toggle("hidden",l===e),o.focus&&(o.focus.textContent=l===e?"Live":"Focus")}),this.applyPresetDimensions(),this.applyCompareDimensions(),this.fitToScreen({keepVisibleScale:i}),(s=(r=this.options).onDeviceChange)==null||s.call(r,this.getEffectivePreset())}applyCompareDimensions(){this.compareViewports.forEach(e=>{let t=e.preset,i=`${t.width}px`,n=`${t.height}px`;e.frame.style.width=i,e.frame.style.height=n,e.canvas&&(e.canvas.width=t.width,e.canvas.height=t.height)})}fitCompareGhosts(){this.compareViewports.forEach(e=>{let t=e.root.querySelector(".compare-body");if(!t)return;let i=Math.max(0,t.clientWidth-24),n=Math.max(0,t.clientHeight-24);if(i<=0||n<=0)return;let r=i/e.preset.width,s=n/e.preset.height,o=Math.max(.01,Math.min(r,s));e.wrapper.style.transform=`scale(${o})`})}captureCompareSnapshot(e){let t=this.compareViewports.get(e);if(!(t!=null&&t.canvas))return;let i=this.gameContainer.querySelector("canvas");if(!i)return;let n=t.canvas.getContext("2d");if(!n)return;let r=t.canvas.width,s=t.canvas.height,o=Math.min(r/i.width,s/i.height),l=i.width*o,c=i.height*o,p=(r-l)/2,d=(s-c)/2;n.clearRect(0,0,r,s),n.drawImage(i,p,d,l,c)}refreshCompareSnapshots(){this.compareViewports.forEach((e,t)=>{t!==this.activeCompareId&&this.captureCompareSnapshot(t)})}startCompareSnapshots(){this.compareSnapshotTimer||(this.compareSnapshotTimer=window.setInterval(()=>{this.viewMode==="compare"&&this.refreshCompareSnapshots()},500))}stopCompareSnapshots(){this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null)}getFitBounds(){if(this.viewMode!=="compare")return{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40};let e=this.compareViewports.get(this.activeCompareId),t=e==null?void 0:e.root.querySelector(".compare-body");return t?{width:t.clientWidth-24,height:t.clientHeight-24}:{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40}}mustQuery(e){let t=this.container.querySelector(e);if(!t)throw new Error(`PreviewShell missing element: ${e}`);return t}};function Sr(a={}){let e=new xn(a);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}import{Sprite as Cs,Container as Cr}from"pixi.js";var Ls=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",wn=Ls;if(typeof window!="undefined")try{let a=new XMLHttpRequest;if(a.open("GET","./build-settings.json",!1),a.send(),a.status===200&&a.responseText){let e=JSON.parse(a.responseText);e!=null&&e.buildMode&&(wn=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${wn}`))}}catch{}var ke=class{static async create(e,t,i){var l,c,p,d,u,g,f;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${wn}`);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 h=new Cr;return this.applyTransform(h,t==null?void 0:t.transform,t),h}let r=(c=t==null?void 0:t.identity)==null?void 0:c.id;console.log(`[ObjectFactory] Calling AssetLoader.load() for: ${e}, configId: ${r}, type: ${n.type}, path: ${n.path}`);let s=await Pi.load(e,n,i,r);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(p=s==null?void 0:s.constructor)==null?void 0:p.name}`);let o;if(n.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",s,"for object:",e),o=new Cs(s),console.log("[ObjectFactory] Created object:",o,"type:",(d=o==null?void 0:o.constructor)==null?void 0:d.name),this.applyTransform(o,t==null?void 0:t.transform,t);else if(n.type==="json")if(console.log("[ObjectFactory] JSON asset for",e,"rawAsset type:",(u=s==null?void 0:s.constructor)==null?void 0:u.name,s),s&&(((g=s.constructor)==null?void 0:g.name)==="Container"||s instanceof Cr)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let h=[n.path,`/assets/${n.path}`,`assets/${n.path}`,`../assets/${n.path}`],m=!1;for(let b of h)try{let y=await fetch(b);if(y.ok){o=await y.json(),console.log("[ObjectFactory] Reloaded JSON directly from:",b,"type:",(f=o==null?void 0:o.constructor)==null?void 0:f.name),m=!0;break}}catch{continue}m||(console.error("[ObjectFactory] Failed to reload JSON from any path"),o=s)}else o=s;else o=s,o&&typeof o=="object"&&("x"in o||"position"in o)&&this.applyTransform(o,t==null?void 0:t.transform,t);return o}static applyTransform(e,t,i){var n,r,s,o,l;if(!(!t||!e)){if(t.position&&("x"in e&&"y"in e?(e.x=(n=t.position.x)!=null?n:0,e.y=(r=t.position.y)!=null?r:0):"position"in e&&e.position&&e.position.set((s=t.position.x)!=null?s:0,(o=t.position.y)!=null?o:0)),t.scale!==void 0){let c=(l=i==null?void 0:i.identity)==null?void 0:l.category,p=c==="ui"||c==="environment"?.2:1,d=t.scale*p;"scale"in e&&e.scale&&(typeof e.scale=="object"&&"set"in e.scale?e.scale.set(d):e.scale=d)}t.rotation!==void 0&&"rotation"in e&&(e.rotation=t.rotation),t.anchor&&"anchor"in e&&e.anchor&&Array.isArray(t.anchor)&&("set"in e.anchor?e.anchor.set(t.anchor[0],t.anchor[1]):(e.anchor.x=t.anchor[0],e.anchor.y=t.anchor[1]))}}};function En(a){try{if(a&&typeof a.keys=="function")return Array.from(a.keys())}catch{}return[]}function Lr(a){var e;return a?((e=a.getDisplayObject)==null?void 0:e.call(a))||a.pixiObject||a:null}function Ts(a,e){if(!a||!(e!=null&&e.interaction))return;let t=e.interaction,i=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);a.eventMode=i?"static":"none",a.interactive=i,i&&(a.cursor=t.draggable?"move":"pointer")}function Tr(a,e){var l,c,p,d,u;if(!a||!e)return;let t=e.transform||{};Ts(a,e);let i=t.position||{},n=t.offset||{},r=(typeof i.x=="number"?i.x:0)+(typeof n.x=="number"?n.x:0),s=(typeof i.y=="number"?i.y:0)+(typeof n.y=="number"?n.y:0);(l=a.position)!=null&&l.set?a.position.set(r,s):(typeof a.x=="number"&&(a.x=r),typeof a.y=="number"&&(a.y=s)),typeof t.scale=="number"&&((c=a.scale)!=null&&c.set?a.scale.set(t.scale):a.scale&&(a.scale.x=t.scale,a.scale.y=t.scale));let o=(d=t.anchor)!=null?d:(p=e.render)==null?void 0:p.anchor;o&&((u=a.anchor)!=null&&u.set)&&typeof o.x=="number"&&typeof o.y=="number"&&a.anchor.set(o.x,o.y)}function kr(a){if(typeof window=="undefined")return;let e=a==null?void 0:a.objects,t=En(e),i=r=>{try{let s=window.__HANDLER_ACTIVE_SCREEN;if(!s||s==="all")return r;let o=window.__HANDLER_SCREEN_INDEX,l=o==null?void 0:o.instanceToScreen;return l?r.filter(c=>l[c]===s):r}catch{return r}};window.__editableObjectConfigs=e;let n=new Map;t.forEach(r=>n.set(r,[r])),window.__editableObjectInstances=n,window.refreshEditableConfigIndex=()=>kr(window.__editableConfig),window.getEditableObjectList=()=>{var r;return i(En((r=window.__editableConfig)==null?void 0:r.objects))},window.getEditableObjectListAll=()=>{var r;return En((r=window.__editableConfig)==null?void 0:r.objects)},window.getEditableObjectConfig=r=>{var p,d,u,g,f;let s=(g=(u=(d=(p=window.__editableConfig)==null?void 0:p.objects)==null?void 0:d.get)==null?void 0:u.call(d,r))!=null?g:null,o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return s;let l=window.__HANDLER_SCREEN_INDEX,c=(f=l==null?void 0:l.instanceToScreen)==null?void 0:f[r];return c&&c===o?s:null},window.getEditableEngineConfig=()=>{let r=window.__editableConfig;if(console.log("[BRIDGE] getEditableEngineConfig called, cfg present:",!!r),!r)return null;if(r.engine&&r.objects instanceof Map){console.log("[BRIDGE] Detected ObjectCentricConfig, flattening...");let s={...r.engine,objects:r.objects,scene:r.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(s.assets||{})),s}return r}}function ks(){if(typeof window=="undefined")return;let a=t=>{let i=String(t||"").trim();return i?/^(data:|blob:|https?:)/.test(i)||i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`:""},e=async(t,i)=>{var r,s,o;let n=a(i);if(n)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),import("./AssetTextures-HOSCQNZW.js")]),p=Date.now(),d=/^(data:|blob:)/.test(n)?n:n+(n.includes("?")?`&t=${p}`:`?t=${p}`),u=await l.load(d);if(!u)return;c[t]=u;let g=window.CustomAssets;(r=g==null?void 0:g[t])!=null&&r.texture&&(g[t].texture=u);let f=window.gameObjectManager,h=(s=f==null?void 0:f.get)==null?void 0:s.call(f,t);if(h){let m=((o=h.getDisplayObject)==null?void 0:o.call(h))||h.pixiObject||h.pixi||h;if(m!=null&&m.texture)m.texture=u;else if(m!=null&&m.children){let b=m.children.find(y=>y==null?void 0:y.texture);b!=null&&b.texture&&(b.texture=u)}}}catch(l){console.warn("[LIVE-EDIT] Failed to reload Pixi texture for",t,l)}};window.applyLiveEditOverrides=t=>{try{let i=Ri();Array.isArray(i)&&i.length&&(window.__editableConfig=t,Rt(i,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let i=Ri();Array.isArray(i)&&i.length&&(window.__editableConfig=t,Rt(i,{silent:!0,persist:!1}))}catch{}},window.applyEditableEngineConfig=t=>{let i=window.__editableConfig;if(!(i!=null&&i.engine))return;let n=[];if(t.runtime)for(let[r,s]of Object.entries(t.runtime))n.push({path:`runtime.${r}`,value:s});if(t.assets)for(let[r,s]of Object.entries(t.assets))n.push({path:`assets.${r}`,value:s}),typeof s=="string"&&e(r,s);if(t.splash)for(let[r,s]of Object.entries(t.splash))n.push({path:`splash.${r}`,value:s});if(t.loading)for(let[r,s]of Object.entries(t.loading))n.push({path:`loading.${r}`,value:s});if(t.start)for(let[r,s]of Object.entries(t.start))n.push({path:`start.${r}`,value:s});n.length&&Rt(n,{silent:!0,persist:!0,emitEvent:!0})}}function An(a){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:i}=a;t&&(t.onObjectRebuildRequired=async(r,s)=>{console.log(`[LIVE-EDIT] \u{1F3D7}\uFE0F Rebuilding object ${r} due to type change...`);let o=t.get(r),l=o==null?void 0:o.pixiObject,c=l==null?void 0:l.parent,p=c==null?void 0:c.children.indexOf(l);o?t.remove(r):l&&l.destroy();let d=window.gameApp,u=await ke.create(r,s,d);c&&(p!==void 0&&p!==-1?c.addChildAt(u,p):c.addChild(u));let g=t.create(r,u);return console.log(`[LIVE-EDIT] \u2705 Rebuild complete for ${r}`),g}),typeof window!="undefined"&&(ks(),window.applyEditableObjectConfig=(r,s)=>{var o,l,c;console.log("[LIVE-EDIT] \u{1F504} applyEditableObjectConfig called for:",r);try{let p=window.__editableConfig;(o=p==null?void 0:p.objects)!=null&&o.set&&(p.objects.set(r,s),console.log("[LIVE-EDIT] \u2705 Updated config in __editableConfig"));let d=(l=t==null?void 0:t.get)==null?void 0:l.call(t,r);if(console.log("[LIVE-EDIT] gameObject found?",!!d),d&&(console.log("[LIVE-EDIT] gameObject type:",(c=d.constructor)==null?void 0:c.name),console.log("[LIVE-EDIT] has updateConfig?",typeof d.updateConfig=="function"),console.log("[LIVE-EDIT] has onConfigUpdate?",typeof d.onConfigUpdate=="function")),d&&typeof d.updateConfig=="function")console.log("[LIVE-EDIT] \u2705 Calling updateConfig()"),d.updateConfig(s);else if(d&&typeof d.onConfigUpdate=="function")console.log("[LIVE-EDIT] \u2705 Calling onConfigUpdate()"),d.onConfigUpdate();else{console.log("[LIVE-EDIT] \u26A0\uFE0F No updateConfig or onConfigUpdate, applying transform directly");let u=Lr(d);Tr(u,s)}}catch(p){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",p)}});let n={async applyObjectConfig(r,s){var p,d;console.log("[BRIDGE] \u{1F504} applyObjectConfig called for:",r);let o=e();(p=o==null?void 0:o.objects)!=null&&p.set&&(o.objects.set(r,s),console.log("[BRIDGE] \u2705 Updated config"));let l=(d=t==null?void 0:t.get)==null?void 0:d.call(t,r);if(console.log("[BRIDGE] gameObject found?",!!l),l&&(console.log("[BRIDGE] has updateConfig?",typeof l.updateConfig=="function"),console.log("[BRIDGE] has onConfigUpdate?",typeof l.onConfigUpdate=="function")),l&&typeof l.updateConfig=="function")console.log("[BRIDGE] \u2705 Calling updateConfig()"),l.updateConfig(s);else if(l&&typeof l.onConfigUpdate=="function")console.log("[BRIDGE] \u2705 Calling onConfigUpdate()"),l.onConfigUpdate();else{console.log("[BRIDGE] \u26A0\uFE0F Applying transform directly");let u=Lr(l);Tr(u,s)}let c=[r];i==null||i(r,s,c)},rebuildIndexes(){let r=e();typeof window!="undefined"&&(window.__editableConfig=r,kr(r))}};return n.rebuildIndexes(),n}import Ps from"lottie-web";Tn(Ha);typeof window!="undefined"&&!window.lottie&&(window.lottie=Ps);var Ke=null,_s=async()=>{if(!Ke){let a=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(a==null?void 0:a["handler.config"])||(a==null?void 0:a["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let i=atob(e.split(",")[1]);Ke=JSON.parse(i)}else Ke=JSON.parse(e);return Ke}catch(i){console.warn("[CONFIG] Failed to parse inline handler.config.json:",i)}Ke=await(await fetch("./handler.config.json")).json()}return Ke},kn,ht,Mr,Xe,Cn,Ln;function ud(a){kn=a.initGame,ht=a.CustomAssets,Mr=a.updateScreenState,Xe=a.globalResponsiveMultipliers,Cn=a.layout,Ln=a.clearResponsiveElements}var pi="web_embed",gt="https://example.com",Pr={profile_id:pi},Pe=null,de=null,Sn={width:0,height:0},Ms=!0,gd=async()=>{var c,p,d,u;document.title="Handler Pixi Game";let a=await _s();Pr={...a.ids||{},profile_id:pi},gt=a.destination_url||((p=(c=a.export_profiles)==null?void 0:c[pi])==null?void 0:p.destination_url)||gt,be.init({ids:Pr,profile:pi,destinationUrl:gt});let e=be.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),de=Sr({onDeviceChange:f=>{console.log(`[PREVIEW] Device switched to ${f.width}x${f.height}, restarting game...`),_r()},onRefresh:_r});let g=de.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",f=>{var v,x,w,C,k,P,O,j,T,E,S;let h=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=f.detail;if(Sn.width=b,Sn.height=y,Mr(b,y),!(!h||!h.renderer)){m&&o(h,m);try{h.renderer.resize(b,y);let A=h.view;A&&(A.style.width="100%",A.style.height="100%",A.style.display="block")}catch(A){console.warn("[SCREEN] Error resizing renderer:",A);return}if(t&&m&&Cn)try{let A=(v=window.__mainContainer)!=null?v:h.stage,M=(O=(P=(C=window.__tutorialLabel)!=null?C:(w=(x=m.get("label_1"))==null?void 0:x.getDisplayObject)==null?void 0:w.call(x))!=null?P:(k=m.get("label_1"))==null?void 0:k.pixiObject)!=null?O:m.get("label_1"),_=m.get("background_1"),D=(S=(E=(T=window.__background)!=null?T:(j=_==null?void 0:_.getDisplayObject)==null?void 0:j.call(_))!=null?E:_==null?void 0:_.pixiObject)!=null?S:_;if(A){let L=A===h.stage;Cn({mainContainer:A,label:M,background:D,backgroundTexture:(D==null?void 0:D.texture)||null,app:h},t,0,Sn,m,{skipMainContainerTransform:L})}}catch(A){console.warn("[SCREEN] Error in layout:",A)}}})}let t=await It("scene.main");window.__editableConfig=t,s(),window.__editableConfigBaseline||(window.__editableConfigBaseline=Ii(t),console.log("[BOOTSTRAP] Frozen config baseline for persistence")),(u=(d=t.engine.runtime)==null?void 0:d.layout)!=null&&u.design_width_portrait||(console.warn("[BOOTSTRAP] Config layout missing, retrying..."),await new Promise(g=>setTimeout(g,100)),t=await It("scene.main"));let i=await kn(e,t,gt,de);Pe=i.app;let n=i.gameObjectManager;window.gameApp=Pe,window.gameObjectManager=n;try{window.__liveEditBridge=An({getConfig:()=>window.__editableConfig,gameObjectManager:n,assets:ht})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}de&&de.notifyGameLoaded();let r=window.__debugScale;r&&typeof r=="number"&&(Xe.scale=r,console.log(`[DEBUG] Applied persisted debug scale: ${r}`)),o(Pe,n);async function s(){try{let g=async y=>{let v=y.startsWith("/")?y:`/${y}`,x=await fetch(v,{cache:"no-cache"});if(!x.ok)return null;let w=await x.text();try{return JSON.parse(w)}catch{return null}},f=await g("configs/flow/app.flow.json");if(!f||typeof f!="object")return;let h=f.screens;if(!h||typeof h!="object")return;let m={},b={};for(let[y,v]of Object.entries(h)){let x=v==null?void 0:v.source;if(typeof x!="string")continue;let w=await g(x),C=w==null?void 0:w.elements;if(!Array.isArray(C))continue;let k=C.map(P=>P==null?void 0:P.instance_id).filter(P=>typeof P=="string");m[y]=k;for(let P of k)b[P]||(b[P]=y)}window.__HANDLER_APP_FLOW=f,window.__HANDLER_SCREEN_INDEX={screenToInstances:m,instanceToScreen:b},window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}}function o(g,f){if(Ms){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${Xe.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let v=" ".repeat(y);b.children.forEach((x,w)=>{if(x&&x.zIndex===9999){console.log(`${v}[RESPONSIVE] Skipping debug border (zIndex 9999)`);return}if(x&&x.scale){let C=x.scale.x||1,k=x.scale.y||1;x.__originalScale||(x.__originalScale={x:C,y:k},console.log(`${v}[RESPONSIVE] Stored original scale for child[${w}]: ${C.toFixed(3)}, ${k.toFixed(3)}`));let P=x.__originalScale.x*Xe.scale,O=x.__originalScale.y*Xe.scale;typeof x.scale.set=="function"?x.scale.set(P,O):(x.scale.x=P,x.scale.y=O),console.log(`${v}[RESPONSIVE] Child[${w}] scale: ${C.toFixed(3)}\u2192${x.scale.x.toFixed(3)} (type: ${x.constructor.name})`),m(x,y+1)}else x&&console.log(`${v}[RESPONSIVE] Child[${w}] has no scale (type: ${x.constructor.name})`)})};var h=m;console.log("[RESPONSIVE] Applying scale to PIXI stage children"),m(g.stage)}else console.warn("[RESPONSIVE] No app.stage found!");console.log("[REDDEBUG] Debug border left unscaled (fixed boundaries)"),console.log("[RESPONSIVE] ===== GLOBAL RESPONSIVE SCALING COMPLETE =====")}function l(g){if(g!==void 0){Xe.scale=g,console.log(`[RESPONSIVE] Updated global scale multiplier to: ${g.toFixed(3)}`);let f=window.gameApp,h=window.gameObjectManager;f&&h?(o(f,h),f.renderer&&(f.renderer.render(f.stage),console.log("[RESPONSIVE] Forced PIXI renderer update"))):console.warn(`[RESPONSIVE] No gameApp (${!!f}) or gameObjectManager (${!!h}) found in window for live update`)}}window.updateGlobalResponsiveMultipliers=l,be.start()},_r=async()=>{var e,t,i,n;console.log("[PREVIEW] Restarting game in 1 seconds...");let a=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(a){let r=((t=a.getDisplayObject)==null?void 0:t.call(a))||a;r&&r.scale&&console.log(`[CHARACTER] Before restart - Current scale - x: ${((i=r.scale.x)!=null?i:1).toFixed(3)}, y: ${((n=r.scale.y)!=null?n:1).toFixed(3)}`)}if(de){de.notifyGameDestroyed();try{Ln&&Ln()}catch(r){console.warn("Failed to clear responsive elements",r)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let r=de.getGameContainer(),s=window.gameObjectManager;if(s&&typeof s.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),s.clear()),Pe){try{Pe.destroy(!0,{children:!0,texture:!1})}catch(o){console.warn("[PREVIEW] Destroy warning:",o)}Pe=null}window.gameApp=null,window.gameObjectManager=null,r&&(r.innerHTML="");try{typeof ht.resetScene=="function"&&ht.resetScene()}catch(o){console.warn("Asset reset failed",o)}setTimeout(()=>{It("scene.main").then(o=>{window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Ii(o)),kn(r,o,gt).then(l=>{Pe=l.app,window.gameApp=Pe,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=An({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:ht})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}de&&de.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{be.start()}catch{}})})},100)},1e3)}};var ye={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Rs=1.25,Is={fontFamily:"Inter, system-ui, sans-serif"};var Pn=class{constructor(e={}){this.currentProgress=0;var t;this.currentProgress=(t=e.progress)!=null?t:0,this.container=this.createContainer()}createContainer(){let e=document.createElement("div");e.className="handler-loading-screen",e.style.cssText=`
|
|
1402
|
+
position: fixed;
|
|
1403
|
+
inset: 0;
|
|
1404
|
+
display: flex;
|
|
1405
|
+
align-items: center;
|
|
1406
|
+
justify-content: center;
|
|
1407
|
+
z-index: 50;
|
|
1408
|
+
user-select: none;
|
|
1409
|
+
overflow: hidden;
|
|
1410
|
+
background-color: ${ye.background};
|
|
1411
|
+
`;let t=document.createElement("div");t.style.cssText=`
|
|
1412
|
+
position: relative;
|
|
1413
|
+
width: 288px;
|
|
1414
|
+
display: flex;
|
|
1415
|
+
flex-direction: column;
|
|
1416
|
+
align-items: center;
|
|
1417
|
+
`;let i=document.createElement("div");i.style.cssText=`
|
|
1418
|
+
position: absolute;
|
|
1419
|
+
top: -96px;
|
|
1420
|
+
width: 96px;
|
|
1421
|
+
height: 96px;
|
|
1422
|
+
opacity: 0.9;
|
|
1423
|
+
transform: scale(0.9);
|
|
1424
|
+
`,i.innerHTML='<div class="boxLoading"></div>',t.appendChild(i);let n=document.createElement("div");n.style.cssText=`
|
|
1425
|
+
width: 100%;
|
|
1426
|
+
position: relative;
|
|
1427
|
+
display: flex;
|
|
1428
|
+
flex-direction: column;
|
|
1429
|
+
align-items: center;
|
|
1430
|
+
`;let r=document.createElement("div");r.style.cssText=`
|
|
1431
|
+
width: 100%;
|
|
1432
|
+
display: flex;
|
|
1433
|
+
justify-content: space-between;
|
|
1434
|
+
align-items: flex-end;
|
|
1435
|
+
margin-bottom: 8px;
|
|
1436
|
+
`;let s=document.createElement("span");s.style.cssText=`
|
|
1437
|
+
font-size: 12px;
|
|
1438
|
+
font-weight: 900;
|
|
1439
|
+
letter-spacing: 0.15em;
|
|
1440
|
+
color: ${ye.ink};
|
|
1441
|
+
`,s.innerHTML='LOADING<span class="loading-dots" style="animation: pulse 1.5s infinite;">..</span>',this.progressText=document.createElement("span"),this.progressText.style.cssText=`
|
|
1442
|
+
font-size: 10px;
|
|
1443
|
+
font-family: monospace;
|
|
1444
|
+
font-weight: bold;
|
|
1445
|
+
color: ${ye.primaryAccent};
|
|
1446
|
+
`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,r.appendChild(s),r.appendChild(this.progressText);let o=document.createElement("div");o.style.cssText=`
|
|
1447
|
+
height: 4px;
|
|
1448
|
+
width: 100%;
|
|
1449
|
+
background-color: #E0DDD8;
|
|
1450
|
+
position: relative;
|
|
1451
|
+
border-radius: 9999px;
|
|
1452
|
+
overflow: hidden;
|
|
1453
|
+
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
|
|
1454
|
+
`,this.progressBar=document.createElement("div"),this.progressBar.style.cssText=`
|
|
1455
|
+
height: 100%;
|
|
1456
|
+
transition: width 0.5s ease-out;
|
|
1457
|
+
border-radius: 9999px;
|
|
1458
|
+
position: relative;
|
|
1459
|
+
width: ${this.currentProgress}%;
|
|
1460
|
+
background-color: ${ye.primaryAccent};
|
|
1461
|
+
`;let l=document.createElement("div");l.style.cssText=`
|
|
1462
|
+
position: absolute;
|
|
1463
|
+
inset: 0;
|
|
1464
|
+
opacity: 0.2;
|
|
1465
|
+
background-color: white;
|
|
1466
|
+
width: 50%;
|
|
1467
|
+
filter: blur(4px);
|
|
1468
|
+
animation: shimmer 2s infinite;
|
|
1469
|
+
`,this.progressBar.appendChild(l),o.appendChild(this.progressBar);let c=document.createElement("div");c.style.cssText=`
|
|
1470
|
+
display: flex;
|
|
1471
|
+
justify-content: space-between;
|
|
1472
|
+
width: 100%;
|
|
1473
|
+
margin-top: 8px;
|
|
1474
|
+
padding: 0 4px;
|
|
1475
|
+
opacity: 0.4;
|
|
1476
|
+
`;for(let u=0;u<9;u++){let g=document.createElement("div");g.style.cssText=`
|
|
1477
|
+
width: 1.5px;
|
|
1478
|
+
background-color: black;
|
|
1479
|
+
height: ${u%4===0?"6px":"2px"};
|
|
1480
|
+
`,c.appendChild(g)}n.appendChild(r),n.appendChild(o),n.appendChild(c);let p=document.createElement("div");return p.id="handler-load-centered",p.style.cssText=`
|
|
1481
|
+
position: absolute;
|
|
1482
|
+
top: 48px;
|
|
1483
|
+
width: 600px;
|
|
1484
|
+
height: 160px;
|
|
1485
|
+
pointer-events: none;
|
|
1486
|
+
left: 50%;
|
|
1487
|
+
transform: translateX(-50%);
|
|
1488
|
+
overflow: visible;
|
|
1489
|
+
`,"HANDLER".split("").forEach((u,g)=>{let f=document.createElement("div");f.textContent=u,f.style.cssText=`
|
|
1490
|
+
position: absolute;
|
|
1491
|
+
width: 28px;
|
|
1492
|
+
height: 40px;
|
|
1493
|
+
opacity: 0;
|
|
1494
|
+
font-family: 'Inter', sans-serif;
|
|
1495
|
+
font-weight: 800;
|
|
1496
|
+
font-size: 24px;
|
|
1497
|
+
letter-spacing: -0.05em;
|
|
1498
|
+
animation: handlerMove 2.5s linear infinite;
|
|
1499
|
+
color: ${ye.ink};
|
|
1500
|
+
display: flex;
|
|
1501
|
+
align-items: center;
|
|
1502
|
+
justify-content: center;
|
|
1503
|
+
animation-delay: ${[1.05,.875,.7,.525,.35,.175,0][g]}s;
|
|
1504
|
+
`,p.appendChild(f)}),t.appendChild(n),t.appendChild(p),this.authSeq=document.createElement("div"),this.authSeq.style.cssText=`
|
|
1505
|
+
position: absolute;
|
|
1506
|
+
bottom: 48px;
|
|
1507
|
+
font-size: 8px;
|
|
1508
|
+
font-family: monospace;
|
|
1509
|
+
letter-spacing: 0.3em;
|
|
1510
|
+
opacity: 0.2;
|
|
1511
|
+
text-transform: uppercase;
|
|
1512
|
+
color: ${ye.ink};
|
|
1513
|
+
`,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`,e.appendChild(t),e.appendChild(this.authSeq),this.injectStyles(),e}injectStyles(){if(document.getElementById("handler-loading-screen-styles"))return;let e=document.createElement("style");e.id="handler-loading-screen-styles",e.textContent=`
|
|
1514
|
+
/* Box Loading Styles */
|
|
1515
|
+
.boxLoading {
|
|
1516
|
+
width: 50px;
|
|
1517
|
+
height: 50px;
|
|
1518
|
+
margin: auto;
|
|
1519
|
+
position: absolute;
|
|
1520
|
+
left: 0;
|
|
1521
|
+
right: 0;
|
|
1522
|
+
top: 0;
|
|
1523
|
+
bottom: 0;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
.boxLoading:before {
|
|
1527
|
+
content: '';
|
|
1528
|
+
width: 50px;
|
|
1529
|
+
height: 5px;
|
|
1530
|
+
background: #000;
|
|
1531
|
+
opacity: 0.15;
|
|
1532
|
+
position: absolute;
|
|
1533
|
+
top: 59px;
|
|
1534
|
+
left: 0;
|
|
1535
|
+
border-radius: 50%;
|
|
1536
|
+
animation: shadow 0.5s linear infinite;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
.boxLoading:after {
|
|
1540
|
+
content: '';
|
|
1541
|
+
width: 50px;
|
|
1542
|
+
height: 50px;
|
|
1543
|
+
background: ${ye.primaryAccent};
|
|
1544
|
+
animation: animate 0.5s linear infinite;
|
|
1545
|
+
position: absolute;
|
|
1546
|
+
top: 0;
|
|
1547
|
+
left: 0;
|
|
1548
|
+
border-radius: 2px;
|
|
1549
|
+
box-shadow: 0 4px 12px rgba(227, 138, 90, 0.2);
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
@keyframes animate {
|
|
1553
|
+
17% { border-bottom-right-radius: 2px; }
|
|
1554
|
+
25% { transform: translateY(9px) rotate(22.5deg); }
|
|
1555
|
+
50% {
|
|
1556
|
+
transform: translateY(18px) scale(1, 0.9) rotate(45deg);
|
|
1557
|
+
border-bottom-right-radius: 32px;
|
|
1558
|
+
}
|
|
1559
|
+
75% { transform: translateY(9px) rotate(67.5deg); }
|
|
1560
|
+
100% { transform: translateY(0) rotate(90deg); }
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
@keyframes shadow {
|
|
1564
|
+
0%, 100% { transform: scale(1, 1); }
|
|
1565
|
+
50% { transform: scale(1.3, 1); opacity: 0.25; }
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
@keyframes shimmer {
|
|
1569
|
+
0% { transform: translateX(-100%); }
|
|
1570
|
+
100% { transform: translateX(200%); }
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
@keyframes handlerMove {
|
|
1574
|
+
0% {
|
|
1575
|
+
left: 0;
|
|
1576
|
+
opacity: 0;
|
|
1577
|
+
transform: scale(0.9);
|
|
1578
|
+
}
|
|
1579
|
+
35% {
|
|
1580
|
+
left: 40%;
|
|
1581
|
+
opacity: 1;
|
|
1582
|
+
transform: scale(1);
|
|
1583
|
+
}
|
|
1584
|
+
65% {
|
|
1585
|
+
left: 60%;
|
|
1586
|
+
opacity: 1;
|
|
1587
|
+
transform: scale(1);
|
|
1588
|
+
}
|
|
1589
|
+
100% {
|
|
1590
|
+
left: 100%;
|
|
1591
|
+
opacity: 0;
|
|
1592
|
+
transform: scale(0.9);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
@keyframes pulse {
|
|
1597
|
+
0%, 100% { opacity: 1; }
|
|
1598
|
+
50% { opacity: 0.3; }
|
|
1599
|
+
}
|
|
1600
|
+
`,document.head.appendChild(e)}setProgress(e){this.currentProgress=Math.max(0,Math.min(100,e)),this.progressBar.style.width=`${this.currentProgress}%`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`}mount(e=document.body){e.appendChild(this.container)}unmount(){this.container.parentElement&&this.container.parentElement.removeChild(this.container)}getElement(){return this.container}};var _n=ya.version,Os=new Set(["init","boot","view","ready","start","pause","resume","complete","error","engagement","first_interaction","retry","cta_show","cta_click","cta_dismiss","clickout","conversion","session_time","level_time","load_time","level_start","level_complete","level_fail","checkpoint","reward","tutorial_start","tutorial_complete","tutorial_skip","ab_assign","fps","memory","asset_load_start","asset_load_complete"]);ba();var Hr={mechanic_id:"TODO_mechanic_id",variant_id:"TODO_variant_id",deployment_id:"TODO_deployment_id",export_id:"TODO_export_id",profile_id:"TODO_profile_id",instance_id:"default"},$r=Math.random().toString(36).slice(2),Qe=null,Je={...Hr},Br="web_embed",On={},mt,Mn=!1,ft=!1,yt=!1,Nr=!1,Hn=1,gi=0,mi=!1,ve=!1,Ze="",et=Math.floor(window.innerWidth),tt=Math.floor(window.innerHeight),jn=et>tt,xe=!1,bt=!1,Rr=!1,Ir=!1,Rn=!1,hi=null,je=null,Dn=!1,zn=!1,ui=new Map;function Fr(){if(!je)return null;let a=Date.now()-je;return!Number.isFinite(a)||a<0?null:a}function In(a){if(Dn)return;let e=Fr();e!==null&&(Dn=!0,I("session_time",{duration_ms:e,reason:a}))}function Or(){if(Qe)return Qe;let a=document.createElement("div");return a.id="handler-root",a.setAttribute("data-handler-root","true"),document.body.appendChild(a),Qe=a,a}function fi(a){switch(a){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return a}}function Ur(a,e){return{event_name:a,ts:Date.now(),session_id:$r,deployment_id:Je.deployment_id,variant_id:Je.variant_id,export_profile_id:Je.profile_id,instance_id:Je.instance_id||"default",env:Br==="mraid"?"mraid":"web",attribution:mt,payload:e}}function I(a,e){let t=fi(a),i=Ur(t,e);zi(i,!!On.analytics),jt(t,i),t!==a&&jt(a,i)}function vt(){hi&&(hi(et,tt),hi=null)}function it(a){Hn=a,I("volume",a)}function nt(a){a&&(Nr=!0),!yt&&(yt=!0,I("pause"),it(0))}function xt(a){!a&&Nr||yt&&(yt=!1,I("resume"),it(Hn))}function _e(a,e){et=Math.floor(a||window.innerWidth),tt=Math.floor(e||window.innerHeight),jn=et>tt,I("resize",{width:et,height:tt})}function js(){if(_a())try{let a=mraid.getMaxSize();_e(a.width,a.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?xt():nt()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();_e(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();it(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&it(t>0?1:0)}),mraid.addEventListener("error",(t,i)=>{console.warn("mraid error:",t,"action:",i)}),mi=!0,mraid.isViewable()&&mraid.getState()!=="hidden")xe=!0,I("boot"),I("view"),I("ready"),ve=!0,vt();else{let t=()=>{xe=!0,I("boot"),I("view"),I("ready"),ve=!0,vt()};mraid.addEventListener("ready",t)}}catch(a){console.warn("MRAID hook skipped",a)}}function Ds(){if(Ma())try{let a=dapi.getScreenSize();_e(a.width,a.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?xt():nt()}),dapi.addEventListener("adResized",t=>{let i=dapi.getScreenSize();_e(t.width||i.width,t.height||i.height)});let e=dapi.getAudioVolume();if(it(e?1:0),dapi.addEventListener("audioVolumeChange",t=>it(t?1:0)),mi=!0,dapi.isViewable())xe=!0,I("boot"),I("view"),I("ready"),ve=!0,vt();else{let t=()=>{xe=!0,I("boot"),I("view"),I("ready"),ve=!0,vt()};dapi.addEventListener("ready",t)}}catch(a){console.warn("DAPI hook skipped",a)}}function jr(){let a=()=>{xe||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(xe=!0,I("boot"),I("view"),I("ready"),ve=!0,vt(),bt&&(bt=!1,pe.start()))};window.addEventListener("resize",()=>_e()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(xt(),a()):nt()}),document.readyState==="complete"||document.readyState==="interactive"?a():window.addEventListener("load",a),mi=!0}function zs(){let a=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Rr=!0),!(Rr&&e instanceof MouseEvent)&&(gi+=1,zn||(zn=!0,I("first_interaction",{count:gi})),I("interaction",gi))};document.addEventListener("mousedown",a),document.addEventListener("touchstart",a)}function Dr(a){var i,n,r,s,o,l,c,p,d,u,g,f;let e=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none";if((typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed")==="google")try{(i=window.ExitApi)==null||i.exit();return}catch{}if(e==="mraid"&&typeof mraid!="undefined")mraid.open(a||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(Ue())(r=(n=window.TJ_API)==null?void 0:n.click)==null||r.call(n);else if(Ra())(o=(s=window.FbPlayableAd)==null?void 0:s.onCTAClick)==null||o.call(s);else if(Da())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(ja())try{(d=(p=window.smxTracking)==null?void 0:p.redirect)==null||d.call(p)}catch(h){console.warn("Smadex redirect failed",h)}else if(Ia()){let h=window.ExitApi;h&&typeof h.exit=="function"?h.exit(a||Ze||""):a&&window.open(a)}else Fe()?(u=window.install)==null||u.call(window):Oa()?(g=window.openAppStore)==null||g.call(window):Hi()?(f=parent==null?void 0:parent.postMessage)==null||f.call(parent,"download","*"):a&&window.open(a)}function Hs(){let a=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let i=new Image;i.src=t};if(a==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;ee("view",()=>e(t.mraid_viewable)),ee("start",()=>e(t.game_viewable)),ee("engagement",()=>e(t.engagement));let i=()=>e(t.complete);ee("complete",i),Ot("engagement",n=>{var r;((r=n==null?void 0:n.payload)==null?void 0:r.count)>3&&i()}),ee("cta_click",()=>e(t.click))}else if(a==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;ee("view",()=>e(t.Ad_Load_Start)),ee("start",()=>e(t.Ad_Viewable)),ee("engagement",()=>e(t.First_Engagement)),ee("complete",()=>e(t.Gameplay_Complete)),ee("cta_click",()=>e(t.DSP_Click)),ee("start",()=>{[5,10,15,20,25,30].forEach(i=>setTimeout(()=>e(t[`Spent_${i}_Seconds`]),i*1e3))})}}function $s(){if(!Ue())return;let a=window.TJ_API;a&&a.setPlayableAPI&&a.setPlayableAPI({skipAd:()=>{try{pe.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function zr(){var e,t,i;let a=window.TJ_API;(e=a==null?void 0:a.objectiveComplete)==null||e.call(a),(t=a==null?void 0:a.playableFinished)==null||t.call(a),(i=a==null?void 0:a.gameplayFinished)==null||i.call(a)}function Bs(){Fe()&&(window.mintGameStart=()=>{xt(!0),_e()},window.mintGameClose=()=>{nt(!0)})}function Ns(){if(!$i())return;let a=window.NUC;!a||!a.trigger||(pe.on("cta_click",()=>{var e,t;return(t=(e=a.trigger).convert)==null?void 0:t.call(e,Ze)}),pe.on("complete",()=>{var e,t;return(t=(e=a.trigger).tryAgain)==null?void 0:t.call(e)}))}var pe={init(a={},e){var t;if(Br=a.profile||"web_embed",On=a.consent||{},Je={...Hr,...a.ids||{}},Qe=a.rootEl||Qe,mt=void 0,da((t=a.telemetry)!=null&&t.endpoint?a.telemetry:null),je=null,Dn=!1,zn=!1,ui.clear(),Ze=a.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(hi=e),I("init"),document.body.oncontextmenu=()=>!1,Or(),Us(Qe),za(),js(),Ds(),!mi){if(document.readyState==="complete")jr();else if(!Ir){Ir=!0;let i=()=>{jr(),window.removeEventListener("load",i),document.removeEventListener("DOMContentLoaded",i)};window.addEventListener("load",i),document.addEventListener("DOMContentLoaded",i)}}zs(),Hs(),$s(),Bs(),Ns(),console.log(`%c @handler/playable-sdk %c v${_n} `,"background: #007acc; color: #fff; font-size: 14px; padding: 4px 8px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;","background: #e1e4e8; color: #333; font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"),xe&&!ve&&(I("boot"),I("view"),I("ready"),bt&&(bt=!1,pe.start()),ve=!0),ve=xe},getRoot(){return Or()},get version(){return _n},get maxWidth(){return et},get maxHeight(){return tt},get isLandscape(){return jn},get isReady(){return ve},get isStarted(){return Mn},get isPaused(){return yt},get isFinished(){return ft},get volume(){return Hn},get interactions(){return gi},on(a,e){Ot(fi(a),e)},off(a,e){Di(fi(a),e)},start(){var a,e;if(!Mn){if(!xe){bt=!0;return}if(Mn=!0,je||(je=Date.now()),I("start"),_e(),Fe())nt(),(a=window.gameReady)==null||a.call(window);else if(Ue()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:jn?"landscape":"portrait",buildID:_n})}}},finish(){var a,e;ft||(ft=!0,I("complete"),In("complete"),Fe()?(a=window.gameEnd)==null||a.call(window):Hi()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):Ue()&&zr())},install(a){if(!ft){ft=!0,Ue()?(zr(),setTimeout(()=>pe.install(a),300)):(I("complete"),setTimeout(()=>pe.install(a),0));return}Rn||(Rn=!0,setTimeout(()=>Rn=!1,500),I("cta_click"),I("conversion"),In("cta"),Dr(a||Ze))},emit(a,e){let t=fi(a);if(!Os.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${a} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let i=Ur(t,e);zi(i,!!On.analytics),jt(t,i)},gameStart(){pe.start()},gameEnd(){pe.finish()},ctaClick(a,e){I("cta_click",{url:a||Ze,manual:!0}),(e==null?void 0:e.open)!==!1&&Dr(a||Ze)},ctaShow(a){I("cta_show",a)},ctaDismiss(a){I("cta_dismiss",a)},getGameTimeMs(){return Fr()},endSession(a="manual"){In(a)},setAttribution(a){mt=a},abTest(a,e){if(!a)throw new Error("abTest requires experimentId");if(!Array.isArray(e)||e.length<2)throw new Error("abTest requires at least 2 variants");let t=Math.abs(Fs(`${$r}:${a}`))%e.length,i=e[t];return mt={...mt||{},experiment_id:a},Je.variant_id=i,I("ab_assign",{experiment_id:a,variant_id:i}),i},levelStart(a,e){je||(je=Date.now()),I("level_start",{level_id:a,...e})},levelComplete(a,e){I("level_complete",{level_id:a,...e})},levelFail(a,e){I("level_fail",{level_id:a,...e})},checkpoint(a,e){I("checkpoint",{checkpoint_id:a,...e})},reward(a,e){I("reward",{reward_id:a,...e})},tutorialStart(a,e){I("tutorial_start",{step_id:a,...e})},tutorialComplete(a,e){I("tutorial_complete",{step_id:a,...e})},tutorialSkip(a,e){I("tutorial_skip",{step_id:a,...e})},timerStart(a){a&&ui.set(a,Date.now())},timerEnd(a,e="custom",t){if(!a)return;let i=ui.get(a);if(!i)return;ui.delete(a);let n=Date.now()-i;if(!(!Number.isFinite(n)||n<0)){if(e==="custom"){I("engagement",{action:"timer",key:a,duration_ms:n,...t});return}I(e,{key:a,duration_ms:n,...t})}},fps(a,e){I("fps",{value:a,...e})},memory(a,e){I("memory",{bytes:a,...e})},assetLoadStart(a,e){I("asset_load_start",{asset_id:a,...e})},assetLoadComplete(a,e){I("asset_load_complete",{asset_id:a,...e})},reportError(a,e,t){I("error",{code:a,message:e,...t})},retry(){var a,e,t;if(Fe())(a=window.gameRetry)==null||a.call(window);else if($i()){let i=window.NUC;(t=(e=i==null?void 0:i.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}I("engagement",{action:"retry"})},pause(){nt(!0)},resume(){xt(!0)},resize(a,e){_e(a,e)}},be=pe;function Fs(a){let e=2166136261;for(let t=0;t<a.length;t++)e^=a.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function Us(a){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
|
|
1601
|
+
(function(){
|
|
1602
|
+
var events = ['touchstart','touchend','mousedown','keydown'];
|
|
1603
|
+
function unlock(){
|
|
1604
|
+
if(window.AudioContext && AudioContext.prototype.resume){
|
|
1605
|
+
if(!window.__handler_audio_ctx){
|
|
1606
|
+
window.__handler_audio_ctx = new AudioContext();
|
|
1607
|
+
}
|
|
1608
|
+
if(window.__handler_audio_ctx.state === 'suspended'){
|
|
1609
|
+
window.__handler_audio_ctx.resume();
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
events.forEach(function(e){ document.removeEventListener(e, unlock); });
|
|
1613
|
+
}
|
|
1614
|
+
events.forEach(function(e){ document.addEventListener(e, unlock, false); });
|
|
1615
|
+
})();
|
|
1616
|
+
`,a.appendChild(e)}async function $n(a,e={}){let t=new Gs;await t.init({resizeTo:a,autoDensity:!0,resolution:window.devicePixelRatio||1,antialias:!0,backgroundAlpha:0});let i=s=>{var d,u,g,f;if(!t.renderer)return;let o=(d=s==null?void 0:s.width)!=null?d:a.clientWidth,l=(u=s==null?void 0:s.height)!=null?u:a.clientHeight,c=o&&o>0?o:(g=window.innerWidth)!=null?g:320,p=l&&l>0?l:(f=window.innerHeight)!=null?f:480;t.renderer.resize(c,p)};a.appendChild(t.canvas),a.style.position="relative",a.style.display="flex",a.style.flexDirection="column",a.style.alignItems="stretch",a.style.width="100%",a.style.height="100dvh",a.style.minHeight="100vh",a.style.maxWidth="100%",a.style.maxHeight="100%",a.style.boxSizing="border-box",a.style.overflow="hidden",e.background&&(a.style.background=e.background),i();let n=document.createElement("div");return n.setAttribute("style",["position:absolute","inset:0","display:flex","flex-direction:column","align-items:center","justify-content:flex-start","gap:12px","pointer-events:none","font-family:Arial,sans-serif","padding:20px 16px","padding-bottom:clamp(24px, 6vh, 96px)","box-sizing:border-box","z-index:2"].join(";")),a.appendChild(n),be.on("pause",()=>{t.ticker.stop(),document.querySelectorAll("audio").forEach(o=>o.pause())}),be.on("resume",()=>{t.ticker.start(),document.querySelectorAll("audio").forEach(o=>{o.currentTime>0&&!o.ended&&o.play().catch(()=>{})})}),be.on("resize",({payload:s})=>{i({width:s==null?void 0:s.width,height:s==null?void 0:s.height})}),window.addEventListener("resize",()=>i()),requestAnimationFrame(()=>i()),new ResizeObserver(s=>{let o=s[0];if(o&&o.contentRect.width>0&&o.contentRect.height>0){let l=Math.round(o.contentRect.width),c=Math.round(o.contentRect.height);if(i({width:l,height:c}),typeof window!="undefined"&&window.gameApp&&window.gameObjectManager){let p={width:l,height:c,dpr:Math.max(1,Math.floor(window.devicePixelRatio||1)),presetId:"auto-resize",isLandscape:l>c};window.dispatchEvent(new CustomEvent("handler-preview:screen",{detail:p}))}}}).observe(a),{app:t,stage:t.stage,overlay:n,applySize:i}}import{BlurFilter as Bn,Ticker as at,ColorMatrixFilter as qs}from"pixi.js";var bi=class{constructor(e){var n,r;let t=e==null?void 0:e.position,i=e==null?void 0:e.offset;this._basePosition={x:typeof(t==null?void 0:t.x)=="number"?t.x:0,y:typeof(t==null?void 0:t.y)=="number"?t.y:0},this._offset={x:typeof(i==null?void 0:i.x)=="number"?i.x:0,y:typeof(i==null?void 0:i.y)=="number"?i.y:0},this.position={x:this._basePosition.x+this._offset.x,y:this._basePosition.y+this._offset.y},this.scale=(n=e==null?void 0:e.scale)!=null?n:1,this.rotation=(r=e==null?void 0:e.rotation)!=null?r:0}update(e){let t=e.position,i=e.offset;t!==void 0&&(this._basePosition={x:typeof(t==null?void 0:t.x)=="number"?t.x:0,y:typeof(t==null?void 0:t.y)=="number"?t.y:0}),i!==void 0&&(this._offset={x:typeof(i==null?void 0:i.x)=="number"?i.x:0,y:typeof(i==null?void 0:i.y)=="number"?i.y:0}),(t!==void 0||i!==void 0)&&(this.position={x:this._basePosition.x+this._offset.x,y:this._basePosition.y+this._offset.y}),e.scale!==void 0&&(this.scale=e.scale),e.rotation!==void 0&&(this.rotation=e.rotation)}syncToPixi(e){e&&(e.position.set(this.position.x,this.position.y),e.scale.set(this.scale),e.rotation=this.rotation)}},yi=class{constructor(e){var t,i,n,r;this.z_index=(t=e==null?void 0:e.z_index)!=null?t:0,this.alpha=(i=e==null?void 0:e.alpha)!=null?i:1,this.visible=(n=e==null?void 0:e.visible)!=null?n:!0,this.tint=(r=e==null?void 0:e.tint)!=null?r:null}update(e){e.z_index!==void 0&&(this.z_index=e.z_index),e.alpha!==void 0&&(this.alpha=e.alpha),e.visible!==void 0&&(this.visible=e.visible),e.tint!==void 0&&(this.tint=e.tint)}syncToPixi(e,t){if(!e)return;if(e.zIndex=this.z_index,t!=null&&t.startsWith("ui_endgame_")||(e.alpha=this.alpha),e.visible=this.visible,this.tint!==null&&"tint"in e&&(e.tint=this.tint),t&&"texture"in e)try{let{AssetTextures:n}=Xr("handler-playable-sdk/pixi");if(n&&n[t]){let r=n[t];r&&(e.texture=r)}}catch{}}},vi=class{constructor(e,t,i,n){this._tickerCleanup=null;this.onRebuildRequired=null;this.instanceId=e,this.objectConfig=t,this.pixiObject=i,this._config=n,this.transform=new bi(n.transform),this.renderer=new yi(n.render),this.sync()}sync(){this.transform.syncToPixi(this.pixiObject),this.renderer.syncToPixi(this.pixiObject,this.instanceId),this.applyAnchor(),this.applyEffectsScale(),this.applyEffects(),this.syncTextProperties(),(!this._initialized||this._shouldReplayIntro)&&(this.applyIntro(),this._initialized=!0,this._shouldReplayIntro=!1),this.applyMotion()}syncTextProperties(){var t;if(!this.pixiObject||!("text"in this.pixiObject))return;let e=(t=this._config)==null?void 0:t.ui;e&&(e.text!==void 0&&this.pixiObject.text!==e.text&&(this.pixiObject.text=e.text),this.pixiObject.style&&(e.fontSize!==void 0&&(this.pixiObject.style.fontSize=e.fontSize),e.color!==void 0&&(this.pixiObject.style.fill=e.color),e.align!==void 0&&(this.pixiObject.style.align=e.align)))}destroy(){this._tickerCleanup&&(this._tickerCleanup(),this._tickerCleanup=null),this._introTicker&&(at.shared.remove(this._introTicker),this._introTicker=null),this.pixiObject&&this.pixiObject.parent&&this.pixiObject.parent.removeChild(this.pixiObject)}updateConfig(e){var l,c,p,d,u,g,f,h,m,b,y;let t=(c=(l=this._config)==null?void 0:l.motion)==null?void 0:c.intro,i=(p=e==null?void 0:e.motion)==null?void 0:p.intro;i!=null&&i.enabled&&JSON.stringify(t)!==JSON.stringify(i)&&(this._shouldReplayIntro=!0);let n=(g=(u=(d=this._config)==null?void 0:d.render)==null?void 0:u.asset)==null?void 0:g.type,r=(h=(f=e==null?void 0:e.render)==null?void 0:f.asset)==null?void 0:h.type,s=(b=(m=this._config)==null?void 0:m.ui)==null?void 0:b.renderMode,o=(y=e==null?void 0:e.ui)==null?void 0:y.renderMode;if((n!==r||s!==o)&&(console.log(`[GameObject] Rebuild required for ${this.instanceId}: type changed from ${n}/${s} to ${r}/${o}`),this.onRebuildRequired)){this.onRebuildRequired(this,e);return}this._config=e,e.transform&&this.transform.update(e.transform),e.render&&this.renderer.update(e.render),this.sync()}applyAnchor(){var n,r,s,o;if(!this.pixiObject||!("anchor"in this.pixiObject)||!this.pixiObject.anchor)return;let e=(r=(n=this._config)==null?void 0:n.render)==null?void 0:r.anchor,t=(o=(s=this._config)==null?void 0:s.transform)==null?void 0:o.anchor,i=e&&typeof e=="object"?e:t&&typeof t=="object"?t:null;i&&typeof i.x=="number"&&typeof i.y=="number"&&this.pixiObject.anchor.set(i.x,i.y)}applyEffectsScale(){var r,s,o;if(!((r=this.pixiObject)!=null&&r.scale))return;let e=(s=this._config)==null?void 0:s.effects,t=typeof(e==null?void 0:e.scale_x)=="number"?e.scale_x:1,i=typeof(e==null?void 0:e.scale_y)=="number"?e.scale_y:1;if(t===1&&i===1)return;let n=(o=this.transform.scale)!=null?o:1;typeof this.pixiObject.scale.set=="function"?this.pixiObject.scale.set(n*t,n*i):(this.pixiObject.scale.x=n*t,this.pixiObject.scale.y=n*i)}applyEffects(){var i,n,r,s,o,l,c,p,d;if(!this.pixiObject)return;let e=(i=this._config)==null?void 0:i.effects;if(!e||e.enabled===!1){this.pixiObject.filters=null;return}let t=[];if((n=e.blur)!=null&&n.enabled){let u=new Bn;u.blur=(r=e.blur.strength)!=null?r:4,t.push(u)}if((s=e.shadow)!=null&&s.enabled){let u=e.shadow,g=new Bn;g.blur=(o=u.blur)!=null?o:4,g.blendMode="multiply",t.push(g),(u.offsetX!==0||u.offsetY!==0)&&console.warn("[Effects] Drop shadow offset requires pixi-filters. Install: npm install pixi-filters")}if((l=e.glow)!=null&&l.enabled){let u=e.glow,g=new Bn;if(g.blur=(c=u.blur)!=null?c:8,t.push(g),u.color){let f=new qs,h=typeof u.color=="string"?parseInt(u.color.replace("#",""),16):u.color;f.tint(h),t.push(f)}}(p=e.stroke)!=null&&p.enabled&&console.warn("[Effects] Stroke/outline effect requires pixi-filters. Install: npm install pixi-filters"),(d=e.distortion)!=null&&d.enabled&&console.warn("[Effects] Distortion effect requires pixi-filters or a displacement map. Install: npm install pixi-filters"),this.pixiObject.filters=t.length>0?t:null}applyIntro(){var p,d,u,g,f,h,m;let e=(p=this._config)==null?void 0:p.motion;if(!e||!((d=e.intro)!=null&&d.enabled)||!this.pixiObject)return;let t=e.intro,i=(t.duration||0)/1e3,n=(t.delay||0)/1e3,r=this.transform.position.y,s=this.transform.scale*(((g=(u=this._config)==null?void 0:u.effects)==null?void 0:g.scale_x)||1),o=this.transform.scale*(((h=(f=this._config)==null?void 0:f.effects)==null?void 0:h.scale_y)||1);if(this.pixiObject.alpha=(m=t.startAlpha)!=null?m:0,t.startScale!==void 0&&this.pixiObject.scale.set(s*t.startScale,o*t.startScale),t.startYOffset!==void 0&&(this.pixiObject.y=r+(t.startYOffset||0)),this._introTicker&&at.shared.remove(this._introTicker),i<=0&&n<=0){this.pixiObject.alpha=this.renderer.alpha,this.pixiObject.y=this.transform.position.y,this.pixiObject.scale.set(s,o);return}let l=0,c=b=>{var O,j,T,E,S,A;if(l+=b.deltaTime/60,l<n)return;let y=i>0?Math.min(1,(l-n)/i):1,v=1-Math.pow(1-y,3),x=this.renderer.alpha,w=this.transform.scale*(((j=(O=this._config)==null?void 0:O.effects)==null?void 0:j.scale_x)||1),C=this.transform.scale*(((E=(T=this._config)==null?void 0:T.effects)==null?void 0:E.scale_y)||1),k=this.transform.position.y,P=this.transform.position.x;if(this.pixiObject.alpha=((S=t.startAlpha)!=null?S:0)+(x-((A=t.startAlpha)!=null?A:0))*v,t.startScale!==void 0){let M=t.startScale+(1-t.startScale)*v;this.pixiObject.scale.set(w*M,C*M)}t.startYOffset!==void 0&&(this.pixiObject.y=k+t.startYOffset+(k-(k+t.startYOffset))*v),y>=1&&(at.shared.remove(c),this._introTicker=null,this.pixiObject.alpha=x,this.pixiObject.x=P,this.pixiObject.y=k,this.pixiObject.scale.set(w,C))};this._introTicker=c,at.shared.add(c)}applyMotion(){var n,r,s;let e=(n=this._config)==null?void 0:n.motion,t=e&&e.enabled!==!1,i=JSON.stringify(e);if(!(this._lastMotionStr===i&&this._tickerCleanup)){if(this._lastMotionStr=i,!t){this._tickerCleanup&&(this._tickerCleanup(),this._tickerCleanup=null);return}if(this._tickerCleanup&&this._tickerCleanup(),(r=e.pulse)!=null&&r.enabled||(s=e.swing)!=null&&s.enabled){let o=0,l=c=>{var h,m,b,y,v,x,w,C,k,P,O;o+=c.deltaTime*.05;let p=this.transform.scale,d=p*(((m=(h=this._config)==null?void 0:h.effects)==null?void 0:m.scale_x)||1),u=p*(((y=(b=this._config)==null?void 0:b.effects)==null?void 0:y.scale_y)||1),g=this.transform.position.x,f=this.transform.position.y;if((v=e.pulse)!=null&&v.enabled){let j=(x=e.pulse.intensity)!=null?x:.1,T=(w=e.pulse.speed)!=null?w:1,S=1+Math.sin(o*T)*j;(C=this.pixiObject.scale)!=null&&C.set?this.pixiObject.scale.set(d*S,u*S):this.pixiObject.scale&&(this.pixiObject.scale.x=d*S,this.pixiObject.scale.y=u*S)}if((k=e.swing)!=null&&k.enabled){let j=(P=e.swing.amplitude)!=null?P:10,T=(O=e.swing.speed)!=null?O:1,E=Math.sin(o*T)*j;e.swing.axis==="vertical"?this.pixiObject.y=f+E:e.swing.axis==="both"?(this.pixiObject.x=g+E,this.pixiObject.y=f+E):this.pixiObject.x=g+E}};at.shared.add(l),this._tickerCleanup=()=>{var c,p,d,u,g;if(at.shared.remove(l),this.pixiObject){let f=this.transform.scale*(((p=(c=this._config)==null?void 0:c.effects)==null?void 0:p.scale_x)||1),h=this.transform.scale*(((u=(d=this._config)==null?void 0:d.effects)==null?void 0:u.scale_y)||1);this.pixiObject.x=this.transform.position.x,this.pixiObject.y=this.transform.position.y,(g=this.pixiObject.scale)!=null&&g.set?this.pixiObject.scale.set(f,h):this.pixiObject.scale&&(this.pixiObject.scale.x=f,this.pixiObject.scale.y=h)}}}}}getComponent(e){return this._config[e]}getPosition(){return{...this.transform.position}}setPosition(e,t){this.transform.position={x:e,y:t},this.transform.syncToPixi(this.pixiObject)}getAlpha(){return this.renderer.alpha}setAlpha(e){this.renderer.alpha=e,this.renderer.syncToPixi(this.pixiObject)}getVisible(){return this.renderer.visible}setVisible(e){this.renderer.visible=e,this.renderer.syncToPixi(this.pixiObject)}},wt=class{constructor(e){this.objects=new Map;this.onObjectRebuildRequired=null;this.config=e}create(e,t){let i=this.config.objects.get(e);if(!i)throw new Error(`Object config not found: ${e}`);let n=new vi(e,i.object_config||e,t,i);return this.objects.set(e,n),n.onRebuildRequired=async(r,s)=>{if(this.onObjectRebuildRequired){console.log(`[GameObjectManager] Triggering rebuild for ${e}`);let o=await this.onObjectRebuildRequired(e,s);o&&this.objects.get(e)===o&&console.log(`[GameObjectManager] \u2705 Rebuilt ${e} successfully`)}else console.warn(`[GameObjectManager] Rebuild required for ${e} but no factory provided`),r.updateConfig(s)},n}get(e){return this.objects.get(e)}updateConfig(e){this.config=e;for(let[t,i]of this.objects.entries()){let n=e.objects.get(t);n&&i.updateConfig(n)}}getAll(){return Array.from(this.objects.values())}remove(e){let t=this.objects.get(e);t&&t.destroy(),this.objects.delete(e)}clear(){for(let e of this.objects.values())e.destroy();this.objects.clear()}};var xi={"brand.primary":{family:"Arial, sans-serif",weight:"400"},"brand.warning":{family:"Arial Black, Arial, sans-serif",weight:"900"},"brand.heading":{family:"Arial Black, Arial, sans-serif",weight:"800"},"brand.body":{family:"Arial, sans-serif",weight:"400"}};function Vs(a){let e=xi[a];return e?e.family:(console.warn(`Font ID "${a}" not found in registry, using fallback`),"Arial, sans-serif")}function Ys(a){var t;let e=xi[a];return e&&(t=e.weight)!=null?t:"400"}function Ws(a,e){xi[a]=e}function Ks(){return Object.keys(xi)}var rt=null;function Xs(){return console.log("[LottieOverlay] getLottie called, lottieLib cached?",!!rt),console.log("[LottieOverlay] window.lottie exists?",typeof window!="undefined"&&!!window.lottie),rt||(typeof window!="undefined"&&window.lottie?(rt=window.lottie,console.log("[LottieOverlay] \u2705 Found window.lottie, cached it")):(console.warn("[LottieOverlay] \u274C lottie-web is not available globally. Make sure it is loaded before using Lottie animations."),console.log("[LottieOverlay] window keys:",typeof window!="undefined"?Object.keys(window).filter(a=>a.toLowerCase().includes("lottie")):"no window"),rt=null)),rt}function Js(a){return!a||a.startsWith("http://")||a.startsWith("https://")||a.startsWith("/")?a:`/${a.replace(/^\.\//,"")}`}function Zs(a){try{let e=new XMLHttpRequest;return e.open("GET",Js(a),!1),e.send(null),e.status<200||e.status>=300||!e.responseText?null:JSON.parse(e.responseText)}catch{return null}}function Gr(a){return!a||typeof a!="object"||!Array.isArray(a.layers)?null:(Array.isArray(a.assets)||(a.assets=[]),Array.isArray(a.chars)||(a.chars=[]),a)}function Tn(a){rt=a}function Qs(a,e,t,i){var C,k,P,O,j,T,E,S,A,M,_,D,L,R,$,Q,B,V,Y;let n=t.objects.get(a);if(!n)return console.warn(`[LottieOverlay] Object config not found: ${a}`),null;let r=((C=n.effects)==null?void 0:C.lottie)||{},s=n.transform||{},o=n.render||{};if(r.enabled===!1||o.visible===!1)return null;let l=i==null?void 0:i[a],c=Gr(l);if(!c){let J=(P=(k=n.render)==null?void 0:k.asset)==null?void 0:P.path;if(typeof J=="string"&&J.toLowerCase().endsWith(".json")){let Ee=Zs(J);if(c=Gr(Ee),c)try{i[a]=c}catch{}}}if(!c){let J=l&&typeof l=="object"?Object.prototype.toString.call(l):typeof l;return console.warn(`[LottieOverlay] Lottie JSON invalid for: ${a}`,{kind:J}),null}let p=Xs();if(!p)return console.warn(`[LottieOverlay] lottie-web is not available. Cannot play animation: ${a}`),null;let d=(O=r.width)!=null?O:300,u=(j=r.height)!=null?j:300,g=(T=s.scale)!=null?T:1,f=((S=(E=s.position)==null?void 0:E.x)!=null?S:0)+((M=(A=s.offset)==null?void 0:A.x)!=null?M:0),h=((D=(_=s.position)==null?void 0:_.y)!=null?D:0)+((R=(L=s.offset)==null?void 0:L.y)!=null?R:0),m=($=s.rotation)!=null?$:0,b=(Q=o.z_index)!=null?Q:100,y=(B=o.alpha)!=null?B:1,v=document.createElement("div");v.style.cssText=`
|
|
1617
|
+
position: absolute;
|
|
1618
|
+
top: calc(50% + ${h}px);
|
|
1619
|
+
left: calc(50% + ${f}px);
|
|
1620
|
+
transform: translate(-50%, -50%) scale(${g}) rotate(${m}deg);
|
|
1621
|
+
width: ${d}px;
|
|
1622
|
+
height: ${u}px;
|
|
1623
|
+
pointer-events: none;
|
|
1624
|
+
z-index: ${b};
|
|
1625
|
+
opacity: ${y};
|
|
1626
|
+
`,e.appendChild(v);let x;try{x=p.loadAnimation({container:v,renderer:r.renderer||"svg",loop:(V=r.loop)!=null?V:!1,autoplay:(Y=r.autoplay)!=null?Y:!0,animationData:c})}catch(J){return v.parentNode&&v.parentNode.removeChild(v),console.warn(`[LottieOverlay] Failed to start animation: ${a}`,J),null}r.speed!==void 0&&x.setSpeed(r.speed);let w=()=>{x.destroy(),v.parentNode&&v.parentNode.removeChild(v)};return r.loop||x.addEventListener("complete",w),{animation:x,cleanup:w}}var Nn=class{constructor(e,t,i){this.systems=[];this.totalTime=0;this.context=null;this.root=e,this.config=t,this.destinationUrl=i}async createApp(e){if(this.context)return{app:this.app,gameObjectManager:this.gameObjectManager};let{app:t,stage:i}=await $n(this.root,{background:e.background_color,text:e.text_color,primary:e.cta_background,cta_text:e.cta_text});this.app=t,this.stage=i,this.gameObjectManager=new wt(this.config),this.stage.eventMode="passive",this.stage.interactive=!1,this.stage.interactiveChildren=!0,this.stage.sortableChildren=!0,this.context={app:this.app,stage:this.stage,config:this.config,gameObjectManager:this.gameObjectManager,destinationUrl:this.destinationUrl,root:this.root,engine:this};for(let n of this.systems)n.setContext(this.context);return{app:this.app,gameObjectManager:this.gameObjectManager}}async initSystems(){if(!this.context)throw new Error("[GameEngine] createApp() must be called before initSystems()");for(let e of this.systems)e.init&&await e.init()}async init(e){return await this.createApp(e),await this.initSystems(),{app:this.app,gameObjectManager:this.gameObjectManager}}registerSystems(e){this.systems.push(...e)}async start(){for(let e of this.systems)e.onStart&&await e.onStart();this.app.ticker.add(this.update.bind(this)),window.addEventListener("handler-preview:screen",e=>{let{width:t,height:i}=e.detail;this.resize(t,i)})}update(e){let t=e.deltaTime/60;this.totalTime+=t;for(let i of this.systems)i.update&&i.update(t,this.totalTime)}resize(e,t){for(let i of this.systems)i.onResize&&i.onResize(e,t)}updateConfig(e){this.config=e;for(let t of this.systems)t.context.config=e,t.onConfigUpdate&&t.onConfigUpdate(e)}destroy(){for(let e of this.systems)e.onDestroy&&e.onDestroy();this.app.ticker.remove(this.update.bind(this)),this.app.destroy(!0,{children:!0,texture:!1})}getApp(){return this.app}getGameObjectManager(){return this.gameObjectManager}getTotalTime(){return this.totalTime}getSystem(e){let t=this.systems.find(i=>i instanceof e);if(!t)throw new Error(`System ${e.name} not found!`);return t}};var Et=class{setContext(e){this.context=e}};var At=class{constructor(){this.config=null}init(e){this.config=e}get(e){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return this.config.objects.get(e)}getAllIds(){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return Array.from(this.config.objects.keys())}has(e){return this.config?this.config.objects.has(e):!1}};import*as qr from"pixi.js";var eo=qr;typeof window!="undefined"&&(window.__basePixi=qr);import{Sprite as to,Text as io,TextStyle as no,Texture as Vr}from"pixi.js";var Yr=a=>a*Math.PI/180;function ao(a,e){var s,o,l,c,p;let t=e.ui;if(!(t!=null&&t.text))return null;let i="#ffffff";(s=e.render)!=null&&s.tint&&(i=e.render.tint);let n=new no({fontFamily:(o=t.font)!=null?o:"Arial",fontSize:(l=t.fontSize)!=null?l:16,fill:i,align:(c=t.align)!=null?c:"center",letterSpacing:(p=t.letterSpacing)!=null?p:0}),r=new io({text:t.text,style:n});return r.label=a,r}function ro(a){var p,d,u,g,f,h,m,b,y,v;let{stage:e,mainContainer:t,activeConfig:i,gameObjectManager:n,allowList:r,denyList:s}=a,o={},l={},c={};t.sortableChildren=!0;for(let[x,w]of i.objects.entries()){if(s!=null&&s.has(x)||r&&!r.has(x)||(w==null?void 0:w.enabled)===!1)continue;let C=(d=(p=w==null?void 0:w.render)==null?void 0:p.asset)==null?void 0:d.path,k=(g=(u=w==null?void 0:w.render)==null?void 0:u.asset)==null?void 0:g.type,P=!!(C&&k==="image"),O=!!((f=w==null?void 0:w.ui)!=null&&f.text),j=O?(h=w==null?void 0:w.ui)==null?void 0:h.renderMode:void 0,T;if(j==="png"&&P?T="png":j==="text"&&O?T="text":P?T="png":O?T="text":T="skip",T!=="skip"){if(T==="text"){let E=ao(x,w);if(!E)continue;let S=w.render;E.alpha=typeof(S==null?void 0:S.alpha)=="number"?S.alpha:1,E.visible=(S==null?void 0:S.visible)!==!1,E.zIndex=typeof(S==null?void 0:S.z_index)=="number"?S.z_index:0,S!=null&&S.anchor&&typeof S.anchor.x=="number"&&typeof S.anchor.y=="number"?E.anchor.set(S.anchor.x,S.anchor.y):E.anchor.set(.5,.5);let A=w.transform,M=(A==null?void 0:A.position)||(A==null?void 0:A.offset);M&&E.position.set((m=M.x)!=null?m:0,(b=M.y)!=null?b:0);let _=typeof(A==null?void 0:A.scale)=="number"?A.scale:1;E.scale.set(_,_);let D=typeof(A==null?void 0:A.rotation)=="number"?A.rotation:0;E.rotation=Yr(D),E.parent||t.addChild(E);try{n.create(x,E)}catch{}o[x]=E,c[x]=E}else if(T==="png"){let E=ce[x]||(typeof Vr!="undefined"?Vr.EMPTY:void 0),S=new to(E);S.label=x;let A=w.render;S.alpha=typeof(A==null?void 0:A.alpha)=="number"?A.alpha:1,S.visible=(A==null?void 0:A.visible)!==!1,S.zIndex=typeof(A==null?void 0:A.z_index)=="number"?A.z_index:0,A!=null&&A.anchor&&typeof A.anchor.x=="number"&&typeof A.anchor.y=="number"&&S.anchor.set(A.anchor.x,A.anchor.y);let M=w.transform,_=(M==null?void 0:M.position)||(M==null?void 0:M.offset);_&&S.position.set((y=_.x)!=null?y:0,(v=_.y)!=null?v:0);let D=typeof(M==null?void 0:M.scale)=="number"?M.scale:1;S.scale.set(D,D);let L=typeof(M==null?void 0:M.rotation)=="number"?M.rotation:0;S.rotation=Yr(L),S.parent||t.addChild(S);try{n.create(x,S)}catch{}o[x]=S,l[x]=S}}}return t.parent||e.addChild(t),{objects:o,sprites:l,texts:c}}var Fn=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new At}init(e,t){this.registry.init(e),this.app=t}updateConfig(e){this.registry.init(e),this.instanceCache.clear(),this.readyPromise=null}async ready(){this.readyPromise&&await this.readyPromise;let t=this.registry.getAllIds().filter(n=>!this.instanceCache.has(n));if(t.length===0)return;let i=async n=>{n.length&&(console.log("[Assets] Loading objects:",n),await Promise.all(n.map(async r=>{var o;let s=this.registry.get(r);if(!s){console.warn("[Assets] No config found for object:",r);return}try{let l=await ke.create(r,s,this.app);this.instanceCache.set(r,l),console.log("[Assets] Loaded object:",r,(o=l==null?void 0:l.constructor)==null?void 0:o.name)}catch(l){console.error("[Assets] Failed to load object:",r,l)}})))};return this.readyPromise=(async()=>{await i(t);let n=this.registry.getAllIds().filter(r=>!this.instanceCache.has(r));n.length>0&&(console.warn("[Assets] Retrying missing assets:",n),await i(n)),console.log("[Assets] Ready. Cached objects:",Array.from(this.instanceCache.keys()))})(),this.readyPromise}resetScene(){this.instanceCache.clear(),this.readyPromise=null}async reloadObject(e){let t=this.registry.get(e);if(t){let i=await ke.create(e,t,this.app);this.instanceCache.set(e,i)}}get(e){return this.instanceCache.get(e)}},Wr=new Fn,so=new Proxy(Wr,{get(a,e){if(e in a&&typeof a[e]=="function")return a[e].bind(a);if(a.get(e))return a.get(e)}});function oo(a,e){Wr.init(a,e)}var Un=class extends Et{async init(){_i(this.context.config,this.context.app),await ce.ready(),console.log("[AssetSystem] All assets preloaded and ready")}async onStart(){}onConfigUpdate(){console.log("[AssetSystem] Config updated - systems will refresh textures")}};import{Graphics as lo,Point as co}from"pixi.js";var we={width:400,height:600,designWidth:400,scaleFactor:1},Ei={scale:1,position:1},Ai=[];function po(a,e,t,i,n,r,s){Ai.push({element:a,originalScale:r,positionHelper:e,heightPercent:n}),e(a,t,i,n,r,s,!1)}function uo(){Ai.forEach(({element:a,originalScale:e,positionHelper:t,heightPercent:i})=>{let n=e*we.scaleFactor;t(a,we.width,we.height,i,n,!0,!1)})}function go(){Ai.length=0,console.log("[LAYOUT] Cleared all responsive elements")}function Gn(a,e){console.log(`[SCREEN] updateScreenState called: ${a}x${e}`),we.width=a,we.height=e,we.scaleFactor=Math.min(a/we.designWidth,1.15),Ei.scale=we.scaleFactor,Ei.position=1,console.log(`[SCREEN] Global multipliers - scale: ${Ei.scale.toFixed(3)}`),uo()}var F={layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}};function ho(a,e,t){let i=F[a];i&&i[e]!==void 0&&(i[e]=t,console.log(`Updated ${a}.${e} = ${t}`))}function fo(){return F}var mo={center:{x:.5,y:.5},"center-center":{x:.5,y:.5},middle:{x:.5,y:.5},"middle-center":{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},"left-center":{x:0,y:.5},"right-center":{x:1,y:.5},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};function wi(a,e){return typeof a=="number"&&Number.isFinite(a)?a:e}function Si(a,e={x:.5,y:.5}){var t;if(Array.isArray(a))return{x:wi(a[0],e.x),y:wi(a[1],e.y)};if(a&&typeof a=="object"){let i=a;return{x:wi(i.x,e.x),y:wi(i.y,e.y)}}if(typeof a=="string"){let i=a.trim().toLowerCase();return(t=mo[i])!=null?t:e}return e}function Ct(a,e,t,i={}){var g,f,h,m,b,y;let n=Si(t),r=(g=i.inset)!=null?g:{},s=(f=i.padding)!=null?f:{x:0,y:0},o=((h=r.left)!=null?h:0)+s.x,l=((m=r.right)!=null?m:0)+s.x,c=((b=r.top)!=null?b:0)+s.y,p=((y=r.bottom)!=null?y:0)+s.y,d=Math.max(0,a-o-l),u=Math.max(0,e-c-p);return{x:o+d*n.x,y:c+u*n.y}}function Lt(a,e,t,i={}){var h,m,b,y,v,x;let n=(h=i.inset)!=null?h:{},r=(m=i.padding)!=null?m:{x:0,y:0},s=((b=n.left)!=null?b:0)+r.x,o=((y=n.right)!=null?y:0)+r.x,l=((v=n.top)!=null?v:0)+r.y,c=((x=n.bottom)!=null?x:0)+r.y,p=Math.max(0,a-s-o),d=Math.max(0,e-l-c),u=Si(t,{x:.5,y:.5}),g=Math.min(Math.max(u.x,0),1),f=Math.min(Math.max(u.y,0),1);return{x:s+p*g,y:l+d*f}}function qn(a,e,t,i={}){var p,d,u;if(!a)return;let n=i.positionRatio?Lt(e,t,i.positionRatio,{inset:i.inset,padding:i.screenPadding}):Ct(e,t,i.anchor,{inset:i.inset,padding:i.screenPadding}),r=(p=i.offset)!=null?p:{x:0,y:0},s=n.x+r.x,o=n.y+r.y;a.anchor&&i.renderAnchor&&a.anchor.set(i.renderAnchor.x,i.renderAnchor.y),se(a,s,o);let l=(d=i.scale)!=null?d:1,c=(u=i.scaleMultiplier)!=null?u:1;(i.scale!==void 0||i.scaleMultiplier!==void 0)&&ue(a,l*c)}if(typeof window!="undefined"){let a=window.innerWidth,e=window.innerHeight,t=()=>{let i=window.innerWidth,n=window.innerHeight;(i!==a||n!==e)&&(a=i,e=n,Gn(i,n))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),Gn(window.innerWidth,window.innerHeight),window.updateDebugConfig=ho,window.getDebugConfig=fo,window.copyConfig=To,window.applyConfig=St,window.applyConfigForRatio=ko,window.positionAtBottom=Kr,window.positionAtTop=vo,window.positionAtCenter=xo,window.positionAtLeft=wo,window.positionAtRight=Eo,window.positionAtBottomLeft=Ao,window.positionAtBottomRight=So,window.positionAtTopLeft=Co,window.positionAtTopRight=Lo,window.applyPositionContract=yo,console.log("\u{1F3AE} Debug Config Functions Available:"),console.log("\u2022 updateDebugConfig(category, key, value)"),console.log("\u2022 getDebugConfig()"),console.log("\u2022 copyConfig(presetName)"),console.log("\u2022 applyConfig(config)"),console.log("\u2022 applyConfigForRatio(width, height)"),console.log("\u{1F4CD} Positioning Helpers Available (with scale):"),console.log("\u2022 positionAtBottom(element, w, h, percent, scale)"),console.log("\u2022 positionAtTop(element, w, h, percent, scale)"),console.log("\u2022 positionAtCenter(element, w, h, offsetX, offsetY, scale)"),console.log("\u2022 positionAtLeft/Right(element, w, h, percent, scale)"),console.log("\u2022 Corner positions: BottomLeft/Right, TopLeft/Right (all with scale)"),console.log("\u2022 applyPositionContract(element, w, h, contract)"),console.log("Example: positionAtCenter(mySprite, 400, 600, 0, -50, 1.2)")}function Ci(a,e,t=0){return a*e+t}function Li(a,e,t=0){return a*(1-e)+t}function Ti(a,e,t=0){return a*e+t}function ki(a,e,t=0){return a*(1-e)+t}function ie(a,e=0){return a/2+e}function bo(a,e){return a*e}function yo(a,e,t,i){var s,o,l,c,p,d,u,g,f,h,m,b,y,v,x,w,C,k,P,O;let n=0,r=0;switch(i.type){case"top":n=ie(e,(o=(s=i.offset)==null?void 0:s.x)!=null?o:0),r=Ci(t,i.percent,(c=(l=i.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":n=ie(e,(d=(p=i.offset)==null?void 0:p.x)!=null?d:0),r=Li(t,i.percent,(g=(u=i.offset)==null?void 0:u.y)!=null?g:0);break;case"left":n=Ti(e,i.percent,(h=(f=i.offset)==null?void 0:f.x)!=null?h:0),r=ie(t,(b=(m=i.offset)==null?void 0:m.y)!=null?b:0);break;case"right":n=ki(e,i.percent,(v=(y=i.offset)==null?void 0:y.x)!=null?v:0),r=ie(t,(w=(x=i.offset)==null?void 0:x.y)!=null?w:0);break;case"center":n=ie(e,(k=(C=i.offset)==null?void 0:C.x)!=null?k:0),r=ie(t,(O=(P=i.offset)==null?void 0:P.y)!=null?O:0);break}a.position?a.position.set(n,r):(a.x=n,a.y=r),i.scale!==void 0&&i.scale!==1&&a.scale&&(typeof a.scale.set=="function"?a.scale.set(i.scale,i.scale):(a.scale.x=i.scale,a.scale.y=i.scale))}function Kr(a,e,t,i=.2,n=1,r=!0,s=!1){let o=bo(t,i),l=Li(t,i/2);se(a,ie(e),l);let c=r?n*we.scaleFactor:n;ue(a,c),s&&!Ai.find(p=>p.element===a)&&po(a,Kr,e,t,i,n,r)}function vo(a,e,t,i=.1,n=1){se(a,ie(e),Ci(t,i)),ue(a,n)}function xo(a,e,t,i=0,n=0,r=1){se(a,ie(e,i),ie(t,n)),ue(a,r)}function wo(a,e,t,i=.1,n=1){se(a,Ti(e,i),ie(t)),ue(a,n)}function Eo(a,e,t,i=.1,n=1){se(a,ki(e,i),ie(t)),ue(a,n)}function Ao(a,e,t,i=.05,n=.05,r=1){se(a,Ti(e,n),Li(t,i)),ue(a,r)}function So(a,e,t,i=.05,n=.05,r=1){se(a,ki(e,n),Li(t,i)),ue(a,r)}function Co(a,e,t,i=.05,n=.05,r=1){se(a,Ti(e,n),Ci(t,i)),ue(a,r)}function Lo(a,e,t,i=.05,n=.05,r=1){se(a,ki(e,n),Ci(t,i)),ue(a,r)}function se(a,e,t){a&&a.position?typeof a.position.set=="function"?a.position.set(e,t):(a.position.x=e,a.position.y=t):a&&(a.x=e,a.y=t)}function ue(a,e){e!==1&&a&&a.scale&&(typeof a.scale.set=="function"?a.scale.set(e,e):a.scale.x!==void 0&&a.scale.y!==void 0&&(a.scale.x=e,a.scale.y=e))}var De={default:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}},wide:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.9,screen_scale_y:1.1},engine:{scale:1,background_scale:1.1,background_offset_y:0,background_alpha:.95,label_pulse_speed:3,label_pulse_intensity:.03}},square:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.85,screen_scale_y:.85},engine:{scale:1,background_scale:1,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}},tall:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1.1,screen_scale_y:.9},engine:{scale:1,background_scale:.95,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}}};function To(a){return a&&De[a]?JSON.parse(JSON.stringify(De[a])):JSON.parse(JSON.stringify(F))}function St(a){Object.keys(a).forEach(e=>{let t=e;F[t]&&a[t]&&Object.assign(F[t],a[t])}),console.log("Config applied:",a)}function ko(a,e){let t=a/e;t>1.6?(St(De.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(St(De.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(St(De.square),console.log("Applied SQUARE config for ratio:",t)):(St(De.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let a=window;a.configPresets=De,a.resolveAnchorVec2=a.resolveAnchorVec2||Si,a.resolveScreenAnchorPoint=a.resolveScreenAnchorPoint||Ct,a.resolveScreenRatioPoint=a.resolveScreenRatioPoint||Lt}var Z=null;function Po(a,e,t,i,n,r={}){var D,L,R,$,Q,B,V,Y,J,Ee,ze,Tt,z,oe,ge,Ae,he,Me,He,$e,fe,Be,Se,kt,Pt,Vn,Yn,Wn,Kn,Xn,Jn,Zn,Qn,ea,ta,ia,na;let s=(D=r.enableDebugLogs)!=null?D:!1;s&&(console.log("\u{1F3AF} [LAYOUT_DEBUGS] ===== STARTING LAYOUT CALCULATION ====="),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Screen dimensions:",{width:i.width,height:i.height}),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Time:",t),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Options:",r));let{mainContainer:o,label:l,background:c,backgroundTexture:p,app:d}=a;if(!d||!d.renderer){s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] \u274C No app or renderer, skipping layout");return}s&&(console.log("\u{1F3AF} [LAYOUT_DEBUGS] App renderer dimensions:",{width:d.renderer.width,height:d.renderer.height}),console.log("\u{1F3AF} [LAYOUT_DEBUGS] App screen dimensions:",{width:d.screen.width,height:d.screen.height}));let u=i.width,g=i.height;s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] Base dimensions:",{baseWidth:u,baseHeight:g});let f=u*F.layout.screen_scale_x,h=g*F.layout.screen_scale_y,m=u/2,b=e.engine.runtime||{},y=b.layout||{};s&&(console.log("\u{1F3AF} [LAYOUT_DEBUGS] Debug config:",{screen_scale_x:F.layout.screen_scale_x,screen_scale_y:F.layout.screen_scale_y}),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Calculated dimensions:",{width:f,height:h,midX:m}),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Engine runtime:",b),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Layout config:",y));let v=y.design_width_portrait||400,x=f/v;x=Math.min(x,1.15);let w=x*((L=F.engine.scale)!=null?L:1),C=(R=r.skipMainContainerTransform)!=null?R:!1;!C&&o&&o.scale&&(typeof o.scale.set=="function"?o.scale.set(w):(o.scale.x=w,o.scale.y=w));let k=($=y.main_container_anchor)!=null?$:"center",P=(Q=y.main_container_position_ratio)!=null?Q:{x:.5,y:.5},O=(B=y.main_container_offset)!=null?B:{x:0,y:0},j=y.main_container_position_ratio?Lt(u,g,P):Ct(u,g,k),T=j.x+O.x+F.layout.position_offset.x,E=j.y+O.y+F.layout.position_offset.y;if(!C&&o&&o.position&&(typeof o.position.set=="function"?o.position.set(T,E):(o.position.x=T,o.position.y=E)),n&&(o!=null&&o.toLocal))for(let[K,X]of e.objects.entries()){let U=X==null?void 0:X.transform;if(!U||((V=U.position_mode)!=null?V:"static")!=="static")continue;let H=(Y=n.get)==null?void 0:Y.call(n,K),le=((J=H==null?void 0:H.getDisplayObject)==null?void 0:J.call(H))||(H==null?void 0:H.pixiObject)||H;if(!le||le.parent!==o)continue;let st=U.position_ratio!=null?Lt(u,g,U.position_ratio):Ct(u,g,(Ee=U.anchor)!=null?Ee:"center"),_t=o.toLocal(new co(st.x,st.y)),Mt=(ze=U.position)!=null?ze:{x:0,y:0},ot=_t.x+Mt.x,Re=_t.y+Mt.y;typeof(H==null?void 0:H.setPosition)=="function"?H.setPosition(ot,Re):(se(le,ot,Re),(Tt=H==null?void 0:H.transform)!=null&&Tt.position&&(H.transform.position.x=ot,H.transform.position.y=Re))}let S=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,M=((S==null?void 0:S.buildMode)||(typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"dev"))==="dev";if(F.layout.debug_rect_visible&&M){(!Z||Z.parent!==d.stage)&&(Z==null||Z.destroy(),Z=new lo,Z.zIndex=9999,d.stage.addChild(Z)),Z.clear();let K=F.layout.debug_rect_scale_x,X=F.layout.debug_rect_scale_y,U=(u-4)*K,ne=(g-4)*X,H=(u-U)/2,le=(g-ne)/2;s&&(console.log("\u{1F3AF} [LAYOUT_DEBUGS] ===== DEBUG RECT POSITIONING ====="),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Debug rect calculations:",{baseWidth:u,baseHeight:g,rectW:U,rectH:ne,offsetX:H,offsetY:le}),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Debug rect final position:",{x:2+H,y:2+le,width:U,height:ne})),Z.rect(2+H,2+le,U,ne).stroke({width:F.layout.debug_rect_thickness,color:F.layout.debug_rect_color})}else Z&&(Z.destroy(),Z=null);let _=((z=a.label)==null?void 0:z.config)||e.objects.get("label_1")||e.objects.get("ui_tutorial_1");if(l&&l.position&&_){let K=(oe=_==null?void 0:_.render)==null?void 0:oe.anchor,X=(Ae=(ge=_==null?void 0:_.transform)==null?void 0:ge.anchor)!=null?Ae:"center",U=(he=_==null?void 0:_.transform)==null?void 0:he.position_ratio,ne=((Me=_==null?void 0:_.transform)==null?void 0:Me.offset)||{x:0,y:0};qn(l,u,g,{anchor:X,positionRatio:U,offset:{x:ne.x*w,y:ne.y*w},renderAnchor:K})}if(l&&l.alpha>0){let K=1+Math.sin(t*F.engine.label_pulse_speed)*F.engine.label_pulse_intensity,X=($e=(He=_==null?void 0:_.transform)==null?void 0:He.scale)!=null?$e:1,U=K*w*X;l.scale&&(typeof l.scale.set=="function"?l.scale.set(U):(l.scale.x=U,l.scale.y=U))}if(s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] ===== BACKGROUND POSITIONING ====="),c){s&&(console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background object exists:",!!c),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background type:",(fe=c.constructor)==null?void 0:fe.name)),c.alpha=((Se=(Be=b.background)==null?void 0:Be.alpha)!=null?Se:.98)*F.engine.background_alpha,s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background alpha set to:",c.alpha);let K=e.objects.get("background_1");s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background config:",K);let X=(K==null?void 0:K.transform)||{};s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background transform:",X);let U=X.offset||{x:0,y:0},ne=((Pt=(kt=b.background)==null?void 0:kt.offset_y)!=null?Pt:0)+F.engine.background_offset_y,H=(Yn=(Vn=K==null?void 0:K.render)==null?void 0:Vn.anchor)!=null?Yn:{x:.5,y:.5},le=(Wn=X.anchor)!=null?Wn:"center",st=X.position_ratio;if(s&&console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background positioning params:",{bgOffset:U,bgRuntimeOffsetY:ne,bgRenderAnchor:H,bgScreenAnchor:le,bgPositionRatio:st,baseWidth:u,baseHeight:g,finalScale:w}),qn(c,u,g,{anchor:le,positionRatio:st,offset:{x:U.x*w,y:U.y*w+ne},renderAnchor:H}),s&&(console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background position after applyScreenAnchor:",{x:c.x,y:c.y,scaleX:(Kn=c.scale)==null?void 0:Kn.x,scaleY:(Xn=c.scale)==null?void 0:Xn.y,anchorX:(Jn=c.anchor)==null?void 0:Jn.x,anchorY:(Zn=c.anchor)==null?void 0:Zn.y,pivotX:(Qn=c.pivot)==null?void 0:Qn.x,pivotY:(ea=c.pivot)==null?void 0:ea.y,width:c.width,height:c.height}),console.log("\u{1F3AF} [LAYOUT_DEBUGS] Background texture dimensions:",{textureWidth:p==null?void 0:p.width,textureHeight:p==null?void 0:p.height})),p){let _t=Math.max(f/p.width,h/p.height),Mt=(ia=(ta=b.background)==null?void 0:ta.scale_multiplier)!=null?ia:1.05,ot=(na=X.scale)!=null?na:1,Re=_t*Mt*F.engine.background_scale*ot;c.scale&&(typeof c.scale.set=="function"?c.scale.set(Re):(c.scale.x=Re,c.scale.y=Re))}else c&&typeof c.clear=="function"&&(c.clear(),c.rect(-f/2,-h/2,f,h).fill({color:1444375}))}}function _o(a){var o,l,c;let{setState:e,updateLabelAlpha:t,updateHandAlpha:i,config:n,states:r}=a,s=((l=(o=n.engine)==null?void 0:o.runtime)==null?void 0:l.timeline)||{};e(r.showHook),setTimeout(()=>{t(1),i(1),e(r.waitInput),console.log("[GAME] \u23F3 Game ready for user input - tutorial shown")},(c=s.tutorial_delay_ms)!=null?c:1500)}export{Ha as a,$n as b,bi as c,yi as d,vi as e,wt as f,Vs as g,Ys as h,Ws as i,Ks as j,Tn as k,Qs as l,ke as m,Nn as n,Et as o,At as p,eo as q,ro as r,so as s,oo as t,Un as u,Ei as v,go as w,Gn as x,Si as y,Ct as z,Lt as A,qn as B,Po as C,_o as D,$a as E,Ba as F,Fi as G,Ge as H,Uo as I,di as J,xn as K,Sr as L,An as M,ud as N,gd as O,ye as P,Rs as Q,Is as R,Pn as S,pe as T,be as U};
|