@mirage-engine/core 0.3.1 → 0.3.3
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/CHANGELOG.md +13 -0
- package/dist/mirage-engine.js +658 -633
- package/dist/mirage-engine.umd.js +15 -15
- package/dist/src/renderer/Renderer.d.ts +4 -0
- package/dist/src/store/TextureLifecycleManager.d.ts +2 -2
- package/dist/src/types/config.d.ts +9 -0
- package/package.json +3 -3
- package/src/core/Syncer.ts +3 -0
- package/src/renderer/Renderer.ts +61 -28
- package/src/store/TextureLifecycleManager.ts +26 -18
- package/src/types/config.ts +9 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
(function(y,
|
|
2
|
-
`),
|
|
1
|
+
(function(y,S){typeof exports=="object"&&typeof module!="undefined"?S(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],S):(y=typeof globalThis!="undefined"?globalThis:y||self,S(y.MirageEngine={},y.THREE))})(this,function(y,S){"use strict";var ct=Object.defineProperty,lt=Object.defineProperties;var ht=Object.getOwnPropertyDescriptors;var Xe=Object.getOwnPropertySymbols;var dt=Object.prototype.hasOwnProperty,ut=Object.prototype.propertyIsEnumerable;var Ce=(y,S,M)=>S in y?ct(y,S,{enumerable:!0,configurable:!0,writable:!0,value:M}):y[S]=M,J=(y,S)=>{for(var M in S||(S={}))dt.call(S,M)&&Ce(y,M,S[M]);if(Xe)for(var M of Xe(S))ut.call(S,M)&&Ce(y,M,S[M]);return y},Se=(y,S)=>lt(y,ht(S));var g=(y,S,M)=>(Ce(y,typeof S!="symbol"?S+"":S,M),M);var Ye=(y,S,M)=>new Promise((b,te)=>{var P=D=>{try{A(M.next(D))}catch(B){te(B)}},re=D=>{try{A(M.throw(D))}catch(B){te(B)}},A=D=>D.done?b(D.value):Promise.resolve(D.value).then(P,re);A((M=M.apply(y,S)).next())});function M(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const b=M(S),te={INCLUDE_TREE:"include-tree",EXCLUDE_TREE:"exclude-tree",INCLUDE_SELF:"include-self",EXCLUDE_SELF:"exclude-self",END:"end"},P={NAME:"data-mirage-dom",KEY:"mirageDom",VALUES:{HIDE:"hide"}},re={TRAVELER:"traveler",NATIVE:"native",CAPTURE_1:"1",CAPTURE_2:"2",CAPTURE_3:"3",CAPTURE_4:"4",CAPTURE_5:"5"},A={NAME:"data-mirage-travel",KEY:"mirageTravel",VALUES:re,MAX_LAYERS:Object.keys(re).length-1},D={NAME:"data-mirage-filter",KEY:"mirageFilter",VALUES:te},B={NAME:"data-mirage-select",KEY:"mirageSelect",VALUES:te},Re={NAME:"data-mirage-shader",KEY:"mirageShader"},Ne={NAME:"data-mirage-sandwich",KEY:"mirageSandwich",VALUES:{FRONT:"front"}},ie=0,K=1,Q=2,Le=4,fe=8,ge=16;function ze(s){const e=s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);return e?{r:parseInt(e[1])/255,g:parseInt(e[2])/255,b:parseInt(e[3])/255}:{r:1,g:1,b:1}}function Me(s){const e={};if(s.opacity&&(e.opacity=parseFloat(s.opacity)),s.backgroundColor&&s.backgroundColor!=="rgba(0, 0, 0, 0)"){const t=ze(s.backgroundColor);e.backgroundColor=[t.r,t.g,t.b]}if(s.backgroundImage?e.backgroundImage=s.backgroundImage:s.background&&(e.backgroundImage=s.background),s.borderRadius&&(e.borderRadius=parseFloat(s.borderRadius)),s.width&&(e.width=parseFloat(s.width)),s.height&&(e.height=parseFloat(s.height)),s.transform&&s.transform!=="none"){const t=new DOMMatrix(s.transform);e.x=t.m41,e.y=t.m42,e.z=t.m43}return e}class De{constructor(e,t){g(this,"target");g(this,"observer");g(this,"pendingDeletions",new Set);g(this,"pendingStyles",new Map);g(this,"isDomDirty",!1);g(this,"isRunning",!1);g(this,"pendingMask",ie);g(this,"mutationTimer",null);g(this,"cssTimer",null);g(this,"resizeConfig");g(this,"resizeTimer",null);g(this,"isResizing",!1);g(this,"lastScrollX",0);g(this,"lastScrollY",0);g(this,"scrollTimer",null);g(this,"onBeforeRender",new Set);g(this,"onLayoutChange",new Set);g(this,"onStyleChange",new Set);g(this,"onScrollChange",new Set);g(this,"onRender",new Set);g(this,"onTransitionFinished",e=>{this.target.contains(e.target)&&this.mutationTimer===null&&(this.cssTimer&&clearTimeout(this.cssTimer),this.pendingStyles.size==0&&(this.pendingMask|=K|Q,this.cssTimer=window.setTimeout(()=>{this.isDomDirty=!0,this.cssTimer=null},50)))});g(this,"onWindowResize",()=>{if(!this.resizeConfig.enabled){this.isDomDirty=!0;return}this.isResizing||(this.isResizing=!0,this.resizeConfig.onStart&&this.resizeConfig.onStart()),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.isDomDirty=!0,this.resizeConfig.onEnd&&this.resizeConfig.onEnd(),this.isResizing=!1,this.resizeTimer=null},this.resizeConfig.delay)});g(this,"renderLoop",()=>{if(!this.isRunning)return;this.onBeforeRender.forEach(i=>i()),this.isDomDirty&&(this.isDomDirty=!1,this.onLayoutChange.forEach(i=>i(this.pendingMask,this.pendingDeletions)),this.pendingDeletions.clear(),this.pendingMask=ie);const e=window.scrollX,t=window.scrollY;(e!==this.lastScrollX||t!==this.lastScrollY)&&(this.onScrollChange.forEach(i=>i(e,t)),this.lastScrollX=e,this.lastScrollY=t,this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=window.setTimeout(()=>{this.pendingMask|=K,this.isDomDirty=!0,this.scrollTimer=null},150)),this.pendingStyles.size>0&&(this.onStyleChange.forEach(i=>i(this.pendingStyles)),this.pendingStyles.clear()),this.onRender.forEach(i=>i()),requestAnimationFrame(this.renderLoop)});var r,o;this.target=e;const i=(r=t.resizeDebounce)!=null?r:!0;i===!1?this.resizeConfig={enabled:!1,delay:0}:i===!0?this.resizeConfig={enabled:!0,delay:150}:this.resizeConfig={enabled:!0,delay:(o=i.delay)!=null?o:150,onStart:i.onStart,onEnd:i.onEnd},this.observer=new MutationObserver(n=>{let a=ie;for(const c of n)if(c.type==="childList")a|=fe,c.removedNodes.length>0&&c.removedNodes.forEach(l=>{l instanceof HTMLElement&&this.pendingDeletions.add(l)});else if(c.type==="attributes")if(c.attributeName==="style"){a|=K|Q;const l=c.target,d=Me(l.style);this.pendingStyles.set(l,d)}else(c.attributeName==="class"||c.attributeName&&c.attributeName.startsWith("data-"))&&(a|=K|Q);else c.type==="characterData"&&(a|=ge|K);if(a!==ie){if(this.pendingMask|=a,a&fe){this.clearTimers(),this.isDomDirty=!0;return}this.mutationTimer&&clearTimeout(this.mutationTimer),this.mutationTimer=window.setTimeout(()=>{this.mutationTimer=null,this.isDomDirty=!0},200)}})}start(){this.isRunning||(this.isRunning=!0,this.observer.observe(this.target,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),this.target.addEventListener("transitionend",this.onTransitionFinished),this.target.addEventListener("animationend",this.onTransitionFinished),window.addEventListener("resize",this.onWindowResize),this.isDomDirty=!0,this.lastScrollX=window.scrollX,this.lastScrollY=window.scrollY,this.renderLoop())}stop(){this.isRunning=!1,this.observer.disconnect(),this.clearTimers(),this.target.removeEventListener("transitionend",this.onTransitionFinished),this.target.removeEventListener("animationend",this.onTransitionFinished),window.removeEventListener("resize",this.onWindowResize)}clearTimers(){this.mutationTimer&&(clearTimeout(this.mutationTimer),this.mutationTimer=null),this.cssTimer&&(clearTimeout(this.cssTimer),this.cssTimer=null),this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null)}}const H=1,Z=2,Ve=0,_={BASE:0,SELECTED:1,getCaptureLayer:s=>31-s,HIDDEN:31},be=Object.values(D.VALUES);class Ae{static getBaseline(e){if(this.cache.has(e))return this.cache.get(e);const t=this.calculateBaselineFromDOM(e);return this.cache.set(e,t),t}static calculateBaselineFromDOM(e){if(typeof document=="undefined")return 0;const t=document.createElement("div"),i=document.createElement("span"),r=document.createElement("img");t.style.visibility="hidden",t.style.position="absolute",t.style.top="0px",t.style.left="0px",t.style.font=e,t.style.margin="0",t.style.padding="0",t.style.border="none",i.style.margin="0",i.style.padding="0",i.style.border="none",i.style.lineHeight="normal",r.width=1,r.height=1,r.style.verticalAlign="baseline",i.appendChild(document.createTextNode("Hidden Text")),t.appendChild(i),t.appendChild(r),document.body.appendChild(t);const o=r.offsetTop-i.offsetTop;return document.body.removeChild(t),o}}g(Ae,"cache",new Map);class We extends b.MeshBasicMaterial{constructor(t,i,r,o,n=2){super({transparent:!0,side:b.FrontSide,color:16777215});g(this,"canvas");g(this,"ctx");g(this,"qualityFactor");if(this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),!this.ctx)throw new Error("[Mirage] Failed to create canvas context");this.qualityFactor=n,this.map=new b.CanvasTexture(this.canvas),this.map.colorSpace=b.LinearSRGBColorSpace,this.map.minFilter=b.LinearFilter,this.map.magFilter=b.LinearFilter,this.updateText(t,i,r,o)}wrapText(t,i){const r=t.split(`
|
|
2
|
+
`),o=[];return r.forEach(n=>{const a=n.match(/[^\s\-]+\-?|\-|\s+/g)||[];if(a.length===0){o.push("");return}let c=a[0];for(let l=1;l<a.length;l++){const d=a[l];this.ctx.measureText(c+d).width<=i+2?c+=d:(c&&o.push(c),c=d.trimStart())}c&&o.push(c)}),o}updateText(t,i,r,o,n){n!==void 0&&(this.qualityFactor=n);const c=(window.devicePixelRatio||1)*this.qualityFactor,l=r*c,d=o*c;this.canvas.width!==l||this.canvas.height!==d?(this.canvas.width=l,this.canvas.height=d):this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.setTransform(c,0,0,c,0,0),this.ctx.font=i.font,this.ctx.fillStyle=i.color,this.ctx.textBaseline="alphabetic",this.ctx.globalAlpha=1;const h=this.wrapText(t,r),u=i.lineHeight,v=Ae.getBaseline(i.font);h.forEach((f,p)=>{const x=p*u+v;let I=0;i.textAlign==="center"?I=r/2:i.textAlign==="right"&&(I=r),this.ctx.textAlign=i.textAlign,this.ctx.fillText(f,I,x)}),this.map&&(this.map.needsUpdate=!0)}dispose(){this.map&&this.map.dispose(),super.dispose()}}function ee(s){return typeof s=="number"?s:parseFloat(s)||0}function se(s){if(!s||s==="transparent")return{color:new b.Color(16777215),alpha:0};const e=s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(e){const t=parseInt(e[1],10),i=parseInt(e[2],10),r=parseInt(e[3],10),o=e[4]!==void 0?parseFloat(e[4]):1;return{color:new b.Color(`rgb(${t}, ${i}, ${r})`),alpha:o}}return{color:new b.Color(s),alpha:1}}function Pe(s){const e=[];let t="",i=0;for(let r=0;r<s.length;r++){const o=s[r];if(o==="(")i++;else if(o===")")i--;else if(o===","&&i===0){e.push(t.trim()),t="";continue}t+=o}return t&&e.push(t.trim()),e}function He(s){if(!s||typeof s!="string"||!s.includes("linear-gradient"))return null;const e=s.match(/linear-gradient\((.*)\)/);if(!e)return null;const t=e[1],i=Pe(t);let r=Math.PI,o=0;const n=i[0].trim();if(n.startsWith("to "))n==="to top"?r=0:n==="to right"?r=Math.PI/2:n==="to bottom"?r=Math.PI:n==="to left"?r=Math.PI*1.5:n==="to top right"||n==="to right top"?r=Math.PI/4:n==="to bottom right"||n==="to right bottom"?r=Math.PI*.75:n==="to bottom left"||n==="to left bottom"?r=Math.PI*1.25:(n==="to top left"||n==="to left top")&&(r=Math.PI*1.75),o=1;else if(n.endsWith("deg")||n.endsWith("rad")||n.endsWith("turn")){const c=parseFloat(n);n.endsWith("deg")?r=c*(Math.PI/180):n.endsWith("rad")?r=c:n.endsWith("turn")&&(r=c*Math.PI*2),o=1}const a=[];for(let c=o;c<i.length&&!(a.length>=8);c++){const l=i[c].trim(),d=l.lastIndexOf(" ");let h=l,u=null;if(d!==-1&&!l.endsWith(")")){const f=l.substring(d+1);(f.endsWith("%")||f.endsWith("px")||!isNaN(parseFloat(f)))&&(h=l.substring(0,d).trim(),u=f)}const v=se(h);a.push({color:v.color,alpha:v.alpha,rawStop:u,stop:0})}if(a.length>0){for(let l=0;l<a.length;l++)a[l].rawStop!==null&&(a[l].stop=parseFloat(a[l].rawStop)/100);a[0].rawStop===null&&(a[0].stop=0),a.length>1&&a[a.length-1].rawStop===null&&(a[a.length-1].stop=1);let c=0;for(let l=1;l<a.length;l++)if(a[l].rawStop!==null||l===a.length-1){const d=l-c;if(d>1){const h=a[c].stop,v=(a[l].stop-h)/d;for(let f=1;f<d;f++)a[c+f].stop=h+v*f}c=l}}return{angle:r,stops:a}}const Ge=`varying vec2 vUv;
|
|
3
3
|
varying vec4 vScreenPos;
|
|
4
4
|
void main() {
|
|
5
5
|
vUv = uv;
|
|
6
6
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
7
7
|
vScreenPos = gl_Position;
|
|
8
|
-
}`,
|
|
8
|
+
}`,qe=`varying vec2 vUv;
|
|
9
9
|
uniform vec2 uSize;
|
|
10
10
|
uniform vec4 uBorderRadius;
|
|
11
11
|
uniform float uBorderWidth;
|
|
@@ -134,22 +134,22 @@ void main() {
|
|
|
134
134
|
|
|
135
135
|
// #include <colorspace_fragment>
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
`,$e=`uniform sampler2D uTexture;
|
|
138
138
|
varying vec4 vScreenPos;
|
|
139
139
|
uniform vec2 uTextureRepeat;
|
|
140
|
-
uniform vec2 uTextureOffset
|
|
140
|
+
uniform vec2 uTextureOffset;`,je=`vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
|
|
141
141
|
vec2 resultUv = screenUv;
|
|
142
142
|
|
|
143
|
-
`,
|
|
144
|
-
baseColor = blendSrcOver(baseColor, texColor);`,Ie={vertexShader:
|
|
145
|
-
`,
|
|
146
|
-
`,
|
|
147
|
-
`,
|
|
148
|
-
`,
|
|
149
|
-
`,
|
|
143
|
+
`,Ke=`vec4 texColor = texture2D(uTexture, resultUv);
|
|
144
|
+
baseColor = blendSrcOver(baseColor, texColor);`,Ie={vertexShader:Ge,fragmentShader:qe},ye={declChunk:$e,uvChunk:je,baseColorChunk:Ke};function Je(s,e,t,i=null,r){var k;const o=i!==null||!!s.imageSrc;let n="";const a={};if(r!=null&&r.uniforms)for(const[T,E]of Object.entries(r.uniforms))typeof E=="number"?(n+=`uniform float ${T};
|
|
145
|
+
`,a[T]={value:E}):Array.isArray(E)?E.length===2?(n+=`uniform vec2 ${T};
|
|
146
|
+
`,a[T]={value:new b.Vector2(...E)}):E.length===3?(n+=`uniform vec3 ${T};
|
|
147
|
+
`,a[T]={value:new b.Vector3(...E)}):E.length===4&&(n+=`uniform vec4 ${T};
|
|
148
|
+
`,a[T]={value:new b.Vector4(...E)}):(n+=`uniform float ${T};
|
|
149
|
+
`,a[T]={value:E});const c=(o?ye.declChunk:"")+`
|
|
150
150
|
`+n,l=s.isTraveler?ye.uvChunk:`vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
|
|
151
|
-
`,h=c?l+((r==null?void 0:r.uvModifier)||""):"",f=c?ye.baseColorChunk:"",b=(r==null?void 0:r.colorModifier)||"",p=Ie.fragmentShader.replace("#INJECT_DECLARATIONS",a).replace("#INJECT_UV_MODIFIER",h).replace("#INJECT_BASE_COLOR",f).replace("#INJECT_COLOR_MODIFIER",b),u=ce(s.backgroundColor),g=ce(s.borderColor),S={uSize:{value:new v.Vector2(e,t)},uBgColor:{value:new v.Vector4(u.color.r,u.color.g,u.color.b,u.alpha)},uBorderColor:{value:new v.Vector4(g.color.r,g.color.g,g.color.b,g.alpha)},uBorderRadius:{value:new v.Vector4(0,0,0,0)},uBorderWidth:{value:te(s.borderWidth)},uOpacity:{value:(I=s.opacity)!=null?I:1},uTexture:{value:null},uTextureRepeat:{value:new v.Vector2(1,1)},uTextureOffset:{value:new v.Vector2(0,0)},uGradientCount:{value:0},uGradientAngle:{value:0},uGradientColors:{value:Array.from({length:8},()=>new v.Vector4(0,0,0,0))},uGradientStops:{value:new Float32Array(8)}};ke(S.uBorderRadius.value,s.borderRadius),c&&(S.uTexture.value=i);const k=new v.ShaderMaterial({uniforms:J(J({},S),o),vertexShader:Ie.vertexShader,fragmentShader:p,transparent:!0,side:v.FrontSide});return s.backgroundImage&&Ee(k,{backgroundImage:s.backgroundImage}),k}function Je(s,e,t,i,r){const c=te(e.borderWidth);Ee(s,{width:t,height:i,borderRadius:e.borderRadius,borderWidth:c,backgroundColor:e.backgroundColor,borderColor:e.borderColor,opacity:e.opacity,texture:r,backgroundImage:e.backgroundImage})}function Ee(s,e){var i,r,c;if(e.width!==void 0&&e.height!==void 0&&s.uniforms.uSize.value.set(e.width,e.height),e.borderRadius!==void 0&&ke(s.uniforms.uBorderRadius.value,e.borderRadius),e.borderWidth!==void 0&&(s.uniforms.uBorderWidth.value=e.borderWidth),e.backgroundColor!==void 0)if(Array.isArray(e.backgroundColor)){const n=s.uniforms.uBgColor.value.w;s.uniforms.uBgColor.value.set(e.backgroundColor[0],e.backgroundColor[1],e.backgroundColor[2],n)}else if(typeof e.backgroundColor=="string"){const n=ce(e.backgroundColor);s.uniforms.uBgColor.value.set(n.color.r,n.color.g,n.color.b,n.alpha)}else{const n=s.uniforms.uBgColor.value.w;s.uniforms.uBgColor.value.set(e.backgroundColor.r,e.backgroundColor.g,e.backgroundColor.b,n)}if(e.borderColor!==void 0)if(Array.isArray(e.borderColor)){const n=s.uniforms.uBorderColor.value.w;s.uniforms.uBorderColor.value.set(e.borderColor[0],e.borderColor[1],e.borderColor[2],n)}else if(typeof e.borderColor=="string"){const n=ce(e.borderColor);s.uniforms.uBorderColor.value.set(n.color.r,n.color.g,n.color.b,n.alpha)}else{const n=s.uniforms.uBorderColor.value.w;s.uniforms.uBorderColor.value.set(e.borderColor.r,e.borderColor.g,e.borderColor.b,n)}e.opacity!==void 0&&(s.uniforms.uOpacity.value=e.opacity),e.bgOpacity!==void 0&&(s.uniforms.uBgColor.value.w=e.bgOpacity),e.borderOpacity!==void 0&&(s.uniforms.uBorderColor.value.w=e.borderOpacity),s.uniforms.uTexture&&e.texture!==void 0&&(s.uniforms.uTexture.value=e.texture);const t=e.texture!==void 0?e.texture:(i=s.uniforms.uTexture)==null?void 0:i.value;if(t&&(t.image instanceof ImageBitmap||t.image instanceof HTMLImageElement||t.image instanceof HTMLCanvasElement)){const n=t.image.width,o=t.image.height,a=(r=e.width)!=null?r:s.uniforms.uSize.value.x,l=(c=e.height)!=null?c:s.uniforms.uSize.value.y;if(n&&o&&a&&l){const h=n/o,f=a/l;if(h>f){const b=f/h;s.uniforms.uTextureRepeat.value.set(b,1),s.uniforms.uTextureOffset.value.set((1-b)/2,0)}else{const b=h/f;s.uniforms.uTextureRepeat.value.set(1,b),s.uniforms.uTextureOffset.value.set(0,(1-b)/2)}}}else s.uniforms.uTextureRepeat&&(s.uniforms.uTextureRepeat.value.set(1,1),s.uniforms.uTextureOffset.value.set(0,0));if(e.backgroundImage!==void 0){const n=We(e.backgroundImage);if(n){s.uniforms.uGradientCount.value=n.stops.length,s.uniforms.uGradientAngle.value=n.angle;for(let o=0;o<8;o++)if(o<n.stops.length){const a=n.stops[o];s.uniforms.uGradientColors.value[o].set(a.color.r,a.color.g,a.color.b,a.alpha),s.uniforms.uGradientStops.value[o]=a.stop}else s.uniforms.uGradientColors.value[o].set(0,0,0,0),s.uniforms.uGradientStops.value[o]=1}else s.uniforms.uGradientCount.value=0}for(const n of Object.keys(e))n!=="width"&&n!=="height"&&n!=="borderRadius"&&n!=="borderWidth"&&n!=="backgroundColor"&&n!=="borderColor"&&n!=="opacity"&&n!=="bgOpacity"&&n!=="borderOpacity"&&n!=="texture"&&n!=="backgroundImage"&&s.uniforms[n]!==void 0&&(s.uniforms[n].value!==void 0&&s.uniforms[n].value!==null&&typeof s.uniforms[n].value.set=="function"?Array.isArray(e[n])?s.uniforms[n].value.set(...e[n]):e[n]!==void 0&&(e[n].copy?s.uniforms[n].value.copy(e[n]):s.uniforms[n].value=e[n]):s.uniforms[n].value=e[n])}function ke(s,e){var o,a,l,h;if(e==null){s.set(0,0,0,0);return}if(typeof e=="number"){s.set(e,e,e,e);return}if(Array.isArray(e)){s.set(e[0],e[1],e[2],e[3]);return}const t=e.split("/")[0].trim().split(/\s+/),i=te(t[0]),r=te((o=t[1])!=null?o:t[0]),c=te((a=t[2])!=null?a:t[0]),n=te((h=(l=t[3])!=null?l:t[1])!=null?h:t[0]);s.set(i,r,c,n)}const q={create(s,e,t,i,r,c=2,n=null,o){return s==="BOX"?Ke(e,i,r,n,o):s==="TEXT"?new Pe(t||"",e,i,r,c):new v.MeshBasicMaterial({visible:!1})},update(s,e,t,i,r,c,n=2,o){e==="BOX"?Je(s,t,r,c,o):e==="TEXT"&&s.updateText(i||"",t,r,c,n)},forceUpdateUniforms(s,e){Ee(s,e)}};class Ze{constructor(e){d(this,"observer");d(this,"textures",new WeakMap);d(this,"loadStatus",new WeakMap);d(this,"elementUrls",new WeakMap);d(this,"onUpdate");this.onUpdate=e,this.observer=new IntersectionObserver(t=>{for(const i of t){const r=i.target;i.isIntersecting?this.loadTexture(r):this.disposeTexture(r)}},{rootMargin:"300px"})}register(e,t){if(e.nodeType!==Node.ELEMENT_NODE)return;this.elementUrls.get(e)!==t&&(this.elementUrls.set(e,t),this.observer.unobserve(e),this.observer.observe(e))}unregister(e){e.nodeType===Node.ELEMENT_NODE&&this.observer.unobserve(e),this.disposeTexture(e),this.elementUrls.delete(e),this.loadStatus.delete(e)}loadTexture(e){return Xe(this,null,function*(){if(this.loadStatus.get(e)||this.textures.has(e))return;const t=this.elementUrls.get(e);if(t){this.loadStatus.set(e,!0);try{let i;if(t.startsWith("data:image/svg+xml"))i=yield new Promise((c,n)=>{const o=new Image;o.onload=()=>c(o),o.onerror=n,o.src=t});else{const n=yield(yield fetch(t)).blob();i=yield createImageBitmap(n,{imageOrientation:"flipY"})}if(this.elementUrls.get(e)!==t){"close"in i&&i.close();return}const r=new v.Texture(i);i instanceof HTMLImageElement||(r.flipY=!1),r.colorSpace=v.LinearSRGBColorSpace,r.needsUpdate=!0,this.textures.set(e,r),this.onUpdate(e,r)}catch(i){console.warn("[MirageEngine] Failed to load texture:",t,i)}finally{this.elementUrls.has(e)&&this.loadStatus.set(e,!1)}}})}disposeTexture(e){const t=this.textures.get(e);t&&(t.dispose(),this.textures.delete(e),this.onUpdate(e,null)),this.loadStatus.set(e,!1)}get(e){return this.textures.get(e)}disposeAll(){this.observer.disconnect()}}class Qe{constructor(e,t,i,r){d(this,"canvas");d(this,"scene");d(this,"camera");d(this,"renderer");d(this,"renderTargets",[]);d(this,"renderOrder",0);d(this,"qualityFactor",2);d(this,"mode","overlay");d(this,"clipArea",1);d(this,"targetLayer","base");d(this,"target");d(this,"mountContainer");d(this,"registry");d(this,"targetRect");d(this,"travelersByLayer",Array.from({length:A.MAX_LAYERS},()=>new Set));d(this,"textureManager");d(this,"fixedMeshes",new Set);var o,a,l,h;this.target=e,this.mountContainer=i,this.registry=r,this.textureManager=new Ze((f,b)=>{const p=this.registry.get(f);p&&p.material instanceof v.ShaderMaterial&&q.forceUpdateUniforms(p.material,{texture:b})}),this.mode=(o=t.mode)!=null?o:"overlay",this.clipArea=(a=t.travelerClipArea)!=null?a:1,this.targetLayer=(l=t.layer)!=null?l:"base",this.canvas=document.createElement("canvas"),this.scene=new v.Scene,this.targetRect=this.target.getBoundingClientRect();const c=this.targetRect.width,n=this.targetRect.height;this.camera=new v.OrthographicCamera(c/-2,c/2,n/2,n/-2,1,1e3),this.camera.position.z=100,this.camera.layers.set(this.getSceneLayer()),this.renderer=new v.WebGLRenderer({canvas:this.canvas,alpha:!0,antialias:!0}),v.ColorManagement.enabled=!1,this.renderer.outputColorSpace=v.LinearSRGBColorSpace,this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(c,n),this.applyTextQuality((h=t.quality)!=null?h:"medium")}getSceneLayer(){return typeof this.targetLayer=="number"?this.targetLayer:this.targetLayer==="selected"?U.SELECTED:U.BASE}createRenderTarget(){for(let e=0;e<A.MAX_LAYERS;e++)this.renderTargets.push(new v.WebGLRenderTarget(this.targetRect.width*this.qualityFactor,this.targetRect.height*this.qualityFactor,{minFilter:v.LinearFilter,magFilter:v.LinearFilter,format:v.RGBAFormat,stencilBuffer:!1,depthBuffer:!0}))}applyTextQuality(e){if(typeof e=="number"){this.qualityFactor=Math.max(.1,e);return}switch(e){case"low":this.qualityFactor=1;break;case"high":this.qualityFactor=4;break;case"medium":this.qualityFactor=2;break;default:this.qualityFactor=2;break}}mount(){this.mountContainer.prepend(this.canvas),this.canvas.style.pointerEvents=this.mode==="overlay"?"none":"auto",this.updateCanvasLayout()}updateCanvasLayout(){this.canvas.style.width=`${this.targetRect.width}px`,this.canvas.style.height=`${this.targetRect.height}px`,this.mode==="duplicate"?(this.canvas.style.position="",this.canvas.style.top="",this.canvas.style.left="",this.canvas.style.display="block"):(this.canvas.style.position="absolute",this.canvas.style.top=`${this.target.offsetTop}px`,this.canvas.style.left=`${this.target.offsetLeft}px`,this.canvas.style.display="block")}updateUniforms(e,t){const i=this.registry.get(e);i&&(i.traverse(r=>{r.isMesh&&r.material&&q.forceUpdateUniforms(r.material,t)}),i.userData.nativeMesh&&i.userData.nativeMesh.traverse(r=>{r.isMesh&&r.material&&q.forceUpdateUniforms(r.material,t)}))}dispose(){this.renderer.dispose(),this.canvas.remove(),this.textureManager.disposeAll()}setSize(e,t){this.renderer.setSize(e,t);for(const i of this.renderTargets)i.setSize(e*this.qualityFactor,t*this.qualityFactor);this.camera.left=e/-2,this.camera.right=e/2,this.camera.top=t/2,this.camera.bottom=t/-2,this.camera.updateProjectionMatrix()}syncScene(e,t){const i=this.target.getBoundingClientRect(),r=Math.abs(i.width-this.targetRect.width)>.1||Math.abs(i.height-this.targetRect.height)>.1,c=this.mode==="overlay"&&(Math.abs(i.top-this.targetRect.top)>.1||Math.abs(i.left-this.targetRect.left)>.1);r?(this.targetRect=i,this.setSize(this.targetRect.width,this.targetRect.height),this.updateCanvasLayout()):c?(this.targetRect=i,this.updateCanvasLayout()):this.targetRect=i,this.renderOrder=0,this.reconcileNode(e),t.size>0&&t.forEach(n=>{const o=this.registry.get(n);if(o){this.scene.remove(o);for(const a of this.travelersByLayer)a.delete(o);this.fixedMeshes.delete(o),o.geometry.dispose(),o.userData.nativeMesh&&(this.scene.remove(o.userData.nativeMesh),Array.isArray(o.userData.nativeMesh.material)?o.userData.nativeMesh.material.forEach(a=>a.dispose()):o.userData.nativeMesh.material.dispose(),o.userData.nativeMesh.geometry.dispose()),o.traverse(a=>{a instanceof v.Mesh&&(a.geometry&&a.geometry.dispose(),a.material&&(Array.isArray(a.material)?a.material.forEach(l=>l.dispose()):a.material.dispose()))}),this.registry.remove(n),this.textureManager.unregister(n)}})}reconcileNode(e){var i;let t=this.registry.get(e.element);if(!t){const r=new v.PlaneGeometry(1,1),c=e.isTraveler?(i=this.renderTargets[e.captureLayer-2])==null?void 0:i.texture:this.textureManager.get(e.element),n=q.create("BOX",e.styles,"",e.rect.width,e.rect.height,this.qualityFactor,c,e.shaderHooks);t=new v.Mesh(r,n),e.type==="TEXT"&&(t.name="BG_MESH"),this.scene.add(t),this.registry.register(e.element,t),t.userData.baseMaterial=n}if(this.updateMeshProperties(t,e),this.updateMeshLayers(t,e),e.isTraveler)for(let r=0;r<A.MAX_LAYERS;r++)r===e.captureLayer-2?this.travelersByLayer[r].add(t):this.travelersByLayer[r].delete(t);else for(const r of this.travelersByLayer)r.delete(t);if(e.isFixed?this.fixedMeshes.add(t):this.fixedMeshes.delete(t),e.styles.imageSrc?this.textureManager.register(e.element,e.styles.imageSrc):this.textureManager.unregister(e.element),e.type==="BOX")for(const r of e.children)this.reconcileNode(r);else e.type==="TEXT"&&(this.reconcileTextChild(t,e,!1),t.userData.nativeMesh&&e.nativeStyles&&this.reconcileTextChild(t.userData.nativeMesh,e,!0))}reconcileTextChild(e,t,i){var l;const r=t.textLines||[{text:t.textContent||"",rect:t.rect}],c=i?t.nativeStyles:t.textStyles,n=JSON.stringify(c)+t.textContent+r.map(h=>h.text).join("|"),o=(l=e.userData)==null?void 0:l.textChildStyleHash;if(t.dirtyMask&me||n!==o){e.children.filter(u=>u.name.startsWith("TEXT_CHILD")).forEach(u=>{var S;const g=u;(S=g.material.map)==null||S.dispose(),g.geometry.dispose(),e.remove(g)});const f=t.rect,b=f.x+f.width/2,p=f.y+f.height/2;r.forEach((u,g)=>{const S=q.create("TEXT",c,u.text,u.rect.width,u.rect.height,this.qualityFactor),k=new v.PlaneGeometry(1,1),I=new v.Mesh(k,S);I.name=`TEXT_CHILD_${g}`;const C=t.rect.width===0?1:u.rect.width/t.rect.width,T=t.rect.height===0?1:u.rect.height/t.rect.height;I.scale.set(C,T,1);const N=u.rect.x+u.rect.width/2,z=u.rect.y+u.rect.height/2,H=N-b,_=-(z-p);I.position.set(t.rect.width===0?0:H/t.rect.width,t.rect.height===0?0:_/t.rect.height,.005),e.add(I)}),e.userData.textChildStyleHash=n}e.children.forEach(h=>{if(!h.name.startsWith("TEXT_CHILD"))return;const f=h,b=t.visibility&W?U.BASE:U.HIDDEN;if(f.layers.set(b),t.visibility&Z&&f.layers.enable(U.SELECTED),t.visibility&W)if(!i&&t.nativeLayer!==void 0&&t.nativeStyles!==void 0)for(let p=t.captureLayer;p<t.nativeLayer;p++)f.layers.enable(U.getCaptureLayer(p));else if(i&&t.nativeLayer!==void 0)for(let p=Math.max(t.captureLayer,t.nativeLayer);p<=A.MAX_LAYERS+1;p++)f.layers.enable(U.getCaptureLayer(p));else for(let p=t.captureLayer;p<=A.MAX_LAYERS+1;p++)f.layers.enable(U.getCaptureLayer(p))})}updateMeshProperties(e,t){var N,z,H;const{rect:i,styles:r}=t,c=this.renderer.getPixelRatio(),n=this.renderer.domElement.width/c,o=this.renderer.domElement.height/c;e.material=e.userData.baseMaterial,e.scale.set(i.width,i.height,1),e.userData.domRect=Se(J({},i),{width:i.width,height:i.height});const a=.001;this.renderOrder++;const l=this.targetRect.left+window.scrollX,h=this.targetRect.top+window.scrollY,f=i.x-l,b=i.y-h,p=f-n/2+i.width/2,u=-b+o/2-i.height/2;e.position.set(p,u,r.zIndex+this.renderOrder*a);const g=i.x,S=i.y;e.userData.basePosition={x:p,y:u},e.userData.originalBasePosition={x:p,y:u},e.userData.baseSize={width:i.width,height:i.height},e.userData.baseDOM={x:g,y:S},e.userData.isFixed=t.isFixed,e.userData.initialScroll={x:window.scrollX,y:window.scrollY};const k=t.element.nodeType===Node.TEXT_NODE?t.element.parentElement:t.element,I=window.getComputedStyle(k);let C=0,T=0;if(I.transform&&I.transform!=="none"){const _=new DOMMatrix(I.transform);C=_.m41,T=_.m42}if(e.userData.baseTransform={x:C,y:T},delete e.userData.originRatioX,delete e.userData.originRatioY,q.update(e.userData.baseMaterial,"BOX",r,"",i.width,i.height,this.qualityFactor,t.isTraveler?(N=this.renderTargets[t.captureLayer-2])==null?void 0:N.texture:this.textureManager.get(t.element)),t.nativeStyles&&t.nativeRect){if(!e.userData.nativeMesh){const Q=q.create("BOX",t.nativeStyles,"",t.nativeRect.width,t.nativeRect.height,this.qualityFactor,t.isTraveler?(z=this.renderTargets[t.captureLayer-2])==null?void 0:z.texture:this.textureManager.get(t.element),t.shaderHooks),$=new v.Mesh(e.geometry,Q);t.type==="TEXT"&&($.name="BG_MESH"),this.scene.add($),e.userData.nativeMesh=$}const _=e.userData.nativeMesh,B=t.nativeRect.x-l,re=t.nativeRect.y-h,ie=B-n/2+t.nativeRect.width/2,se=-re+o/2-t.nativeRect.height/2;_.scale.set(t.nativeRect.width,t.nativeRect.height,1),_.position.set(ie,se,t.nativeStyles.zIndex+this.renderOrder*a),q.update(_.material,"BOX",t.nativeStyles,"",t.nativeRect.width,t.nativeRect.height,this.qualityFactor,t.isTraveler?(H=this.renderTargets[t.captureLayer-2])==null?void 0:H.texture:this.textureManager.get(t.element))}else e.userData.nativeMesh&&(this.scene.remove(e.userData.nativeMesh),e.userData.nativeMesh.material instanceof v.Material&&e.userData.nativeMesh.material.dispose(),delete e.userData.nativeMesh)}updateMeshLayers(e,t){const i=t.visibility&W?U.BASE:U.HIDDEN;if(e.layers.set(i),t.visibility&Z&&e.layers.enable(U.SELECTED),e.userData.nativeMesh&&t.nativeLayer!==void 0){const r=e.userData.nativeMesh;if(r.layers.set(U.HIDDEN),t.visibility&W){for(let c=t.captureLayer;c<t.nativeLayer;c++)e.layers.enable(U.getCaptureLayer(c));for(let c=Math.max(t.captureLayer,t.nativeLayer);c<=A.MAX_LAYERS+1;c++)r.layers.enable(U.getCaptureLayer(c))}}else if(t.visibility&W)for(let r=t.captureLayer;r<=A.MAX_LAYERS+1;r++)e.layers.enable(U.getCaptureLayer(r))}captureRenderTarget(e,t,i){if(e.size===0||!i)return;const r=new v.Color,c=this.renderer.getClearAlpha();this.renderer.getClearColor(r),this.renderer.setClearColor(0,0),this.renderer.setRenderTarget(i),this.renderer.clear(),this.renderer.autoClear=!1,this.renderer.setScissorTest(!0),this.camera.layers.set(t);const n=new v.Vector3,o=this.targetRect.width,a=this.targetRect.height,l=this.renderer.getPixelRatio();for(const h of e){n.setFromMatrixPosition(h.matrixWorld),n.project(this.camera);const f=(n.x+1)/2*o,b=(n.y+1)/2*a;let p=0,u=1;typeof this.clipArea=="number"?u=this.clipArea:this.clipArea.endsWith("%")?u=parseFloat(this.clipArea)/100:this.clipArea.endsWith("px")&&(p=parseFloat(this.clipArea));const g=h.scale.x*u+.5,S=h.scale.y*u+.5,k=f-g/2,I=b-S/2,C=(k*this.qualityFactor-p)/l,T=(I*this.qualityFactor-p)/l,N=(g*this.qualityFactor+p*2)/l,z=(S*this.qualityFactor+p*2)/l;this.renderer.setScissor(C,T,N,z),this.renderer.render(this.scene,this.camera)}this.renderer.setScissorTest(!1),this.renderer.autoClear=!0,this.renderer.setRenderTarget(null),this.camera.layers.set(this.getSceneLayer()),this.renderer.setClearColor(r,c)}render(){for(let e=0;e<A.MAX_LAYERS;e++){const t=e+1;this.captureRenderTarget(this.travelersByLayer[e],U.getCaptureLayer(t),this.renderTargets[e])}this.renderer.render(this.scene,this.camera)}}function et(s){const e=s.textContent||"",t=[];let i="",r=null,c=-1;const n=(l,h)=>{for(let f=0;f<l.length;f++){const b=l[f],p=document.createRange();p.setStart(s,h+f),p.setEnd(s,h+f+1);const u=p.getBoundingClientRect();if(u.width===0&&u.height===0){i+=b;continue}c===-1||Math.abs(u.top-c)>u.height/2?(i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),i=b,r={left:u.left,top:u.top,right:u.right,bottom:u.bottom},c=u.top):(i+=b,r&&(r.left=Math.min(r.left,u.left),r.top=Math.min(r.top,u.top),r.right=Math.max(r.right,u.right),r.bottom=Math.max(r.bottom,u.bottom)))}},o=e.match(/[^\s\-]+\-?|\-|\s+/g)||[];let a=0;for(const l of o){const h=document.createRange();h.setStart(s,a),h.setEnd(s,a+l.length);const f=h.getClientRects();if(f.length>1)n(l,a);else{const b=f.length===1?f[0]:h.getBoundingClientRect();if(b.width===0&&b.height===0){i+=l,a+=l.length;continue}c===-1||Math.abs(b.top-c)>b.height/2?(i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),i=l,r={left:b.left,top:b.top,right:b.right,bottom:b.bottom},c=b.top):(i+=l,r&&(r.left=Math.min(r.left,b.left),r.top=Math.min(r.top,b.top),r.right=Math.max(r.right,b.right),r.bottom=Math.max(r.bottom,b.bottom)))}a+=l.length}return i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),t.filter(l=>l.text.trim().length>0&&l.rect.width>0&&l.rect.height>0)}function Oe(s){const e=parseFloat(s.fontSize);let t=parseFloat(s.lineHeight);isNaN(t)&&(t=e*1.2);let i=parseFloat(s.letterSpacing);return isNaN(i)&&(i=0),{font:`${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`,fontSize:s.fontSize,color:s.color,textAlign:s.textAlign||"start",textBaseline:"alphabetic",direction:s.direction||"inherit",lineHeight:t,letterSpacing:i}}function Ue(s,e=K|ee|Le|me|pe,t,i=1,r=0,c=2,n,o){var $,le,he,ue,de,fe;if(s.nodeType===Node.TEXT_NODE){const m=s;if(!m.textContent||!m.textContent.trim())return null;const R=m.textContent.replace(/\s+/g," ");if(R.length===0)return null;const O=et(m);if(O.length===0)return null;const X=m.parentElement,L=X?window.getComputedStyle(X):null;if(!L)return null;const Y=Math.min(...O.map(E=>E.rect.left)),x=Math.min(...O.map(E=>E.rect.top)),P=Math.max(...O.map(E=>E.rect.left+E.rect.width)),j=Math.max(...O.map(E=>E.rect.top+E.rect.height));return{id:Math.random().toString(36).substring(2,9),type:"TEXT",element:m,rect:{x:Y+window.scrollX,y:x+window.scrollY,width:P-Y,height:j-x},styles:{backgroundColor:"transparent",backgroundImage:"",opacity:X&&X.dataset[V.KEY]===V.VALUES.HIDE?1:parseFloat(L.opacity),zIndex:(isNaN(parseInt(L.zIndex))?0:parseInt(L.zIndex))+r,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px",isTraveler:!1},textContent:R,textLines:O.map(E=>({text:E.text.trim(),rect:{x:E.rect.left+window.scrollX,y:E.rect.top+window.scrollY,width:E.rect.width,height:E.rect.height}})),textStyles:Oe(L),dirtyMask:e,visibility:t,isTraveler:!1,captureLayer:i,isFixed:L.position==="fixed",nativeLayer:n,nativeStyles:o?J(J({backgroundColor:"transparent",backgroundImage:"",opacity:X&&X.dataset[V.KEY]===V.VALUES.HIDE?1:parseFloat(L.opacity),zIndex:(isNaN(parseInt(L.zIndex))?0:parseInt(L.zIndex))+r,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px",isTraveler:!1},Oe(L)),o):void 0,nativeRect:o?{x:Y+window.scrollX,y:x+window.scrollY,width:P-Y,height:j-x}:void 0,children:[]}}if(s.nodeType!==Node.ELEMENT_NODE)return null;const a=s,l=a.dataset[D.KEY];let h=t,f=t;if(l){const m=new Set(l.split(/\s+/));for(const R of m)if(!ve.includes(R))throw new Error(`[MirageEngine] Invalid filter token: '${R}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(m.has(D.VALUES.END))return null;if(m.has(D.VALUES.INCLUDE_TREE)&&m.has(D.VALUES.EXCLUDE_TREE))throw new Error("[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(m.has(D.VALUES.INCLUDE_SELF)&&m.has(D.VALUES.EXCLUDE_SELF))throw new Error("[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element.");m.has(D.VALUES.INCLUDE_TREE)?h=h|W:m.has(D.VALUES.EXCLUDE_TREE)&&(h=h&~W),f=h,m.has(D.VALUES.INCLUDE_SELF)?f=f|W:m.has(D.VALUES.EXCLUDE_SELF)&&(f=f&~W)}const b=a.dataset[F.KEY];if(b){const m=new Set(b.split(/\s+/));for(const R of m)if(!ve.includes(R))throw new Error(`[MirageEngine] Invalid select token: '${R}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(m.has(F.VALUES.END))return null;if(m.has(F.VALUES.INCLUDE_TREE)&&m.has(F.VALUES.EXCLUDE_TREE))throw new Error("[MirageEngine] Conflicting selects: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(m.has(F.VALUES.INCLUDE_SELF)&&m.has(F.VALUES.EXCLUDE_SELF))throw new Error("[MirageEngine] Conflicting selects: 'include-self' and 'exclude-self' cannot be used together on the same element.");m.has(F.VALUES.INCLUDE_TREE)?h=h|Z:m.has(F.VALUES.EXCLUDE_TREE)&&(h=h&~Z),f=h,m.has(F.VALUES.INCLUDE_SELF)?f=f|Z:m.has(F.VALUES.EXCLUDE_SELF)&&(f=f&~Z)}const p=a.dataset[A.KEY];let u=!1,g=o?J({},o):{},S=n;if(p){let m=1;const R=p.indexOf("{"),O=p.lastIndexOf("}");let X=p;if(R!==-1&&O!==-1&&O>R){X=p.substring(0,R).trim();const x=p.substring(R,O+1);try{g=new Function("return "+x)()}catch(P){console.warn(`[MirageEngine] Failed to parse travel styles JSON: ${x}`)}}const L=X.split(/\s+/);let Y=!1;if(L.includes(A.VALUES.TRAVELER)){u=!0,Y=!0;const x=L.find(P=>!isNaN(parseInt(P,10)));x&&(m=parseInt(x,10))}else if(L.includes(A.VALUES.NATIVE)){u=!1;const x=L.find(P=>!isNaN(parseInt(P,10)));x&&(S=parseInt(x,10))}if(Y){const x=m+1;if(x<i)throw new Error(`[MirageEngine] Traveler layer (${m}) cannot be smaller than inherited capture layer (${i-1}).`);i=Math.min(x,A.MAX_LAYERS+1)}}const k=a.dataset[Re.KEY];let I;k&&(I=JSON.parse(k));const C=a.getBoundingClientRect(),T=window.getComputedStyle(a);if(C.width===0||C.height===0||T.display==="none")return null;let N=a.getAttribute("data-mid");N||(N=Math.random().toString(36).substring(2,11),a.setAttribute("data-mid",N));const z=parseInt(T.zIndex),H=(isNaN(z)?0:z)+r;let _;if(a.tagName==="IMG")_=a.src;else if(a.tagName.toLowerCase()==="svg"){const m=a.cloneNode(!0),R=g==null?void 0:g.color,O=g==null?void 0:g.fill,X=g==null?void 0:g.stroke,L=g==null?void 0:g.opacity,Y=(E,_e)=>{const G=window.getComputedStyle(E),ge=_e,ot=G.fill===G.color,at=G.stroke===G.color,Te=O||(ot?R:void 0)||G.fill;Te&&Te!=="none"&&(ge.style.fill=Te);const Ce=X||(at?R:void 0)||G.stroke;Ce&&Ce!=="none"&&(ge.style.stroke=Ce),G.strokeWidth&&G.strokeWidth!=="0px"&&(ge.style.strokeWidth=G.strokeWidth);const Fe=R||G.color;Fe&&(ge.style.color=Fe);const xe=L||G.opacity;xe&&xe!=="1"&&(ge.style.opacity=xe);for(let be=0;be<E.children.length;be++)Y(E.children[be],_e.children[be])};Y(a,m);const x=a.getBoundingClientRect(),P=window.devicePixelRatio*c;m.hasAttribute("viewBox")||m.setAttribute("viewBox",`0 0 ${x.width} ${x.height}`),m.setAttribute("width",(x.width*P).toString()),m.setAttribute("height",(x.height*P).toString());let j=new XMLSerializer().serializeToString(m);j.includes("xmlns=")||(j=j.replace("<svg",'<svg xmlns="http://www.w3.org/2000/svg"')),_=`data:image/svg+xml;utf8,${encodeURIComponent(j)}`}else if(T.backgroundImage&&T.backgroundImage!=="none"){const m=T.backgroundImage.match(/url\(['"]?(.*?)['"]?\)/);m&&(_=m[1])}const B={backgroundColor:T.backgroundColor,backgroundImage:T.backgroundImage,opacity:a.dataset[V.KEY]===V.VALUES.HIDE?1:parseFloat(T.opacity),zIndex:H,borderRadius:T.borderRadius,borderColor:T.borderColor,borderWidth:T.borderWidth,imageSrc:_,isTraveler:u},re=B;let ie,se;const Q=[];return a.tagName.toLowerCase()!=="svg"&&Array.from(a.childNodes).forEach(m=>{const R=m.nodeType===Node.TEXT_NODE?f:h,O=Ue(m,e,R,i,H,c,S,m.nodeType===Node.TEXT_NODE&&Object.keys(g).length>0?g:void 0);O&&Q.push(O)}),{id:N,type:"BOX",element:a,rect:{x:C.left+window.scrollX,y:C.top+window.scrollY,width:C.width,height:C.height},styles:re,textContent:ie,textStyles:se,dirtyMask:e,visibility:f,isTraveler:u,captureLayer:i,nativeLayer:S,nativeStyles:S!==void 0?Se(J({},B),{backgroundColor:($=g.backgroundColor)!=null?$:B.backgroundColor,backgroundImage:(le=g.backgroundImage)!=null?le:B.backgroundImage,opacity:(he=g.opacity)!=null?he:B.opacity,zIndex:g.zIndex!==void 0?g.zIndex+H:B.zIndex,borderRadius:(ue=g.borderRadius)!=null?ue:B.borderRadius,borderColor:(de=g.borderColor)!=null?de:B.borderColor,borderWidth:(fe=g.borderWidth)!=null?fe:B.borderWidth,isTraveler:B.isTraveler}):void 0,nativeRect:S!==void 0?{x:g.x!==void 0?parseFloat(g.x):C.left+window.scrollX,y:g.y!==void 0?parseFloat(g.y):C.top+window.scrollY,width:g.width!==void 0?parseFloat(g.width):C.width,height:g.height!==void 0?parseFloat(g.height):C.height}:void 0,isFixed:T.position==="fixed",children:Q,shaderHooks:I}}function tt(s,e){e.size!==0&&e.forEach((t,i)=>{var N,z,H,_,B,re,ie,se,Q,$,le,he,ue,de,fe,m,R,O;const r=s.get(i);if(!r||!r.userData.basePosition)return;let{x:c,y:n}=r.userData.basePosition;const{width:o,height:a}=r.userData.baseSize,l=(N=t.width)!=null?N:o,h=(z=t.height)!=null?z:a,f=l-o,b=h-a;if(t.width!==void 0&&r.userData.originRatioX===void 0&&Math.abs(f)>.1){const X=i.getBoundingClientRect(),L=(H=t.x)!=null?H:0,Y=(B=(_=r.userData.baseTransform)==null?void 0:_.x)!=null?B:0,x=r.userData.isFixed?0:window.scrollX;let E=-(X.left+x-L+Y-r.userData.baseDOM.x)/f;Math.abs(E)<.05?E=0:Math.abs(E-1)<.05?E=1:Math.abs(E-.5)<.05&&(E=.5),r.userData.originRatioX=E}if(t.height!==void 0&&r.userData.originRatioY===void 0&&Math.abs(b)>.1){const X=i.getBoundingClientRect(),L=(re=t.y)!=null?re:0,Y=(se=(ie=r.userData.baseTransform)==null?void 0:ie.y)!=null?se:0,x=r.userData.isFixed?0:window.scrollY;let E=-(X.top+x-L+Y-r.userData.baseDOM.y)/b;Math.abs(E)<.05?E=0:Math.abs(E-1)<.05?E=1:Math.abs(E-.5)<.05&&(E=.5),r.userData.originRatioY=E}const p=(Q=r.userData.originRatioX)!=null?Q:.5,u=($=r.userData.originRatioY)!=null?$:.5,g=f*(.5-p),S=b*(.5-u),k=(he=(le=r.userData.baseTransform)==null?void 0:le.x)!=null?he:0,I=(de=(ue=r.userData.baseTransform)==null?void 0:ue.y)!=null?de:0,C=((fe=t.x)!=null?fe:k)-k,T=((m=t.y)!=null?m:I)-I;r.position.setX(c+g+C),r.position.setY(n-(S+T)),r.scale.set(l,h,1),q.forceUpdateUniforms(r.material,{backgroundColor:t.backgroundColor,backgroundImage:t.backgroundImage,opacity:t.opacity,borderRadius:(O=t.borderRadius)!=null?O:(R=r.userData.baseStyles)==null?void 0:R.borderRadius,width:l,height:h})})}function rt(s,e,t){s.forEach(i=>{if(i.userData.isFixed&&i.userData.initialScroll&&i.userData.originalBasePosition){const r=e-i.userData.initialScroll.x,c=t-i.userData.initialScroll.y;i.userData.basePosition.x=i.userData.originalBasePosition.x+r,i.userData.basePosition.y=i.userData.originalBasePosition.y-c,i.position.x=i.userData.basePosition.x,i.position.y=i.userData.basePosition.y}})}class it{constructor(e,t,i,r){d(this,"target");d(this,"renderer");d(this,"registry");d(this,"isTravelEnabled",!1);d(this,"tracker");this.target=e,this.renderer=t,this.registry=i,this.tracker=new De(e,{resizeDebounce:r.resizeDebounce}),this.tracker.onLayoutChange.add((c,n)=>{document.querySelector(`[${A.NAME}~='${A.VALUES.TRAVELER}']`)!==null&&!this.isTravelEnabled&&(this.isTravelEnabled=!0,this.renderer.createRenderTarget());const a=Ue(this.target,c,W,1,0,this.renderer.qualityFactor);a&&this.renderer.syncScene(a,n)}),this.tracker.onScrollChange.add((c,n)=>{rt(this.renderer.fixedMeshes,c,n)}),this.tracker.onStyleChange.add(c=>{tt(this.registry,c)}),this.tracker.onRender.add(()=>{this.renderer.render()})}start(){this.tracker.start()}stop(){this.tracker.stop()}}class st{constructor(){d(this,"store");this.store=new WeakMap}register(e,t){this.store.set(e,t)}get(e){return this.store.get(e)}has(e){return this.store.has(e)}remove(e){this.store.delete(e)}}class nt{constructor(e,t){d(this,"renderer");d(this,"syncer");d(this,"target");d(this,"registry");var r,c,n;if(this.target=e,this.registry=new st,!document.getElementById("mirage-engine-styles")){const o=document.createElement("style");o.id="mirage-engine-styles",o.textContent=`
|
|
152
|
-
[${
|
|
151
|
+
`,d=o?l+((r==null?void 0:r.uvModifier)||""):"",h=o?ye.baseColorChunk:"",u=(r==null?void 0:r.colorModifier)||"",v=Ie.fragmentShader.replace("#INJECT_DECLARATIONS",c).replace("#INJECT_UV_MODIFIER",d).replace("#INJECT_BASE_COLOR",h).replace("#INJECT_COLOR_MODIFIER",u),f=se(s.backgroundColor),p=se(s.borderColor),x={uSize:{value:new b.Vector2(e,t)},uBgColor:{value:new b.Vector4(f.color.r,f.color.g,f.color.b,f.alpha)},uBorderColor:{value:new b.Vector4(p.color.r,p.color.g,p.color.b,p.alpha)},uBorderRadius:{value:new b.Vector4(0,0,0,0)},uBorderWidth:{value:ee(s.borderWidth)},uOpacity:{value:(k=s.opacity)!=null?k:1},uTexture:{value:null},uTextureRepeat:{value:new b.Vector2(1,1)},uTextureOffset:{value:new b.Vector2(0,0)},uGradientCount:{value:0},uGradientAngle:{value:0},uGradientColors:{value:Array.from({length:8},()=>new b.Vector4(0,0,0,0))},uGradientStops:{value:new Float32Array(8)}};ke(x.uBorderRadius.value,s.borderRadius),o&&(x.uTexture.value=i);const I=new b.ShaderMaterial({uniforms:J(J({},x),a),vertexShader:Ie.vertexShader,fragmentShader:v,transparent:!0,side:b.FrontSide});return s.backgroundImage&&we(I,{backgroundImage:s.backgroundImage}),I}function Ze(s,e,t,i,r){const o=ee(e.borderWidth);we(s,{width:t,height:i,borderRadius:e.borderRadius,borderWidth:o,backgroundColor:e.backgroundColor,borderColor:e.borderColor,opacity:e.opacity,texture:r,backgroundImage:e.backgroundImage})}function we(s,e){var i,r,o;if(e.width!==void 0&&e.height!==void 0&&s.uniforms.uSize.value.set(e.width,e.height),e.borderRadius!==void 0&&ke(s.uniforms.uBorderRadius.value,e.borderRadius),e.borderWidth!==void 0&&(s.uniforms.uBorderWidth.value=e.borderWidth),e.backgroundColor!==void 0)if(Array.isArray(e.backgroundColor)){const n=s.uniforms.uBgColor.value.w;s.uniforms.uBgColor.value.set(e.backgroundColor[0],e.backgroundColor[1],e.backgroundColor[2],n)}else if(typeof e.backgroundColor=="string"){const n=se(e.backgroundColor);s.uniforms.uBgColor.value.set(n.color.r,n.color.g,n.color.b,n.alpha)}else{const n=s.uniforms.uBgColor.value.w;s.uniforms.uBgColor.value.set(e.backgroundColor.r,e.backgroundColor.g,e.backgroundColor.b,n)}if(e.borderColor!==void 0)if(Array.isArray(e.borderColor)){const n=s.uniforms.uBorderColor.value.w;s.uniforms.uBorderColor.value.set(e.borderColor[0],e.borderColor[1],e.borderColor[2],n)}else if(typeof e.borderColor=="string"){const n=se(e.borderColor);s.uniforms.uBorderColor.value.set(n.color.r,n.color.g,n.color.b,n.alpha)}else{const n=s.uniforms.uBorderColor.value.w;s.uniforms.uBorderColor.value.set(e.borderColor.r,e.borderColor.g,e.borderColor.b,n)}e.opacity!==void 0&&(s.uniforms.uOpacity.value=e.opacity),e.bgOpacity!==void 0&&(s.uniforms.uBgColor.value.w=e.bgOpacity),e.borderOpacity!==void 0&&(s.uniforms.uBorderColor.value.w=e.borderOpacity),s.uniforms.uTexture&&e.texture!==void 0&&(s.uniforms.uTexture.value=e.texture);const t=e.texture!==void 0?e.texture:(i=s.uniforms.uTexture)==null?void 0:i.value;if(t&&(t.image instanceof ImageBitmap||t.image instanceof HTMLImageElement||t.image instanceof HTMLCanvasElement)){const n=t.image.width,a=t.image.height,c=(r=e.width)!=null?r:s.uniforms.uSize.value.x,l=(o=e.height)!=null?o:s.uniforms.uSize.value.y;if(n&&a&&c&&l){const d=n/a,h=c/l;if(d>h){const u=h/d;s.uniforms.uTextureRepeat.value.set(u,1),s.uniforms.uTextureOffset.value.set((1-u)/2,0)}else{const u=d/h;s.uniforms.uTextureRepeat.value.set(1,u),s.uniforms.uTextureOffset.value.set(0,(1-u)/2)}}}else s.uniforms.uTextureRepeat&&(s.uniforms.uTextureRepeat.value.set(1,1),s.uniforms.uTextureOffset.value.set(0,0));if(e.backgroundImage!==void 0){const n=He(e.backgroundImage);if(n){s.uniforms.uGradientCount.value=n.stops.length,s.uniforms.uGradientAngle.value=n.angle;for(let a=0;a<8;a++)if(a<n.stops.length){const c=n.stops[a];s.uniforms.uGradientColors.value[a].set(c.color.r,c.color.g,c.color.b,c.alpha),s.uniforms.uGradientStops.value[a]=c.stop}else s.uniforms.uGradientColors.value[a].set(0,0,0,0),s.uniforms.uGradientStops.value[a]=1}else s.uniforms.uGradientCount.value=0}for(const n of Object.keys(e))n!=="width"&&n!=="height"&&n!=="borderRadius"&&n!=="borderWidth"&&n!=="backgroundColor"&&n!=="borderColor"&&n!=="opacity"&&n!=="bgOpacity"&&n!=="borderOpacity"&&n!=="texture"&&n!=="backgroundImage"&&s.uniforms[n]!==void 0&&(s.uniforms[n].value!==void 0&&s.uniforms[n].value!==null&&typeof s.uniforms[n].value.set=="function"?Array.isArray(e[n])?s.uniforms[n].value.set(...e[n]):e[n]!==void 0&&(e[n].copy?s.uniforms[n].value.copy(e[n]):s.uniforms[n].value=e[n]):s.uniforms[n].value=e[n])}function ke(s,e){var a,c,l,d;if(e==null){s.set(0,0,0,0);return}if(typeof e=="number"){s.set(e,e,e,e);return}if(Array.isArray(e)){s.set(e[0],e[1],e[2],e[3]);return}const t=e.split("/")[0].trim().split(/\s+/),i=ee(t[0]),r=ee((a=t[1])!=null?a:t[0]),o=ee((c=t[2])!=null?c:t[0]),n=ee((d=(l=t[3])!=null?l:t[1])!=null?d:t[0]);s.set(i,r,o,n)}const $={create(s,e,t,i,r,o=2,n=null,a){return s==="BOX"?Je(e,i,r,n,a):s==="TEXT"?new We(t||"",e,i,r,o):new b.MeshBasicMaterial({visible:!1})},update(s,e,t,i,r,o,n=2,a){e==="BOX"?Ze(s,t,r,o,a):e==="TEXT"&&s.updateText(i||"",t,r,o,n)},forceUpdateUniforms(s,e){we(s,e)}};class Qe{constructor(e,t=!0){g(this,"observer");g(this,"textures",new WeakMap);g(this,"loadStatus",new WeakMap);g(this,"elementUrls",new WeakMap);g(this,"onUpdate");this.onUpdate=e,t&&(this.observer=new IntersectionObserver(i=>{for(const r of i){const o=r.target;r.isIntersecting?this.loadTexture(o):this.disposeTexture(o)}},{rootMargin:"300px"}))}register(e,t){if(e.nodeType!==Node.ELEMENT_NODE)return;this.elementUrls.get(e)!==t&&(this.elementUrls.set(e,t),this.observer?(this.observer.unobserve(e),this.observer.observe(e)):this.loadTexture(e))}unregister(e){e.nodeType===Node.ELEMENT_NODE&&this.observer&&this.observer.unobserve(e),this.disposeTexture(e),this.elementUrls.delete(e),this.loadStatus.delete(e)}loadTexture(e){return Ye(this,null,function*(){if(this.loadStatus.get(e)||this.textures.has(e))return;const t=this.elementUrls.get(e);if(t){this.loadStatus.set(e,!0);try{let i;if(t.startsWith("data:image/svg+xml"))i=yield new Promise((o,n)=>{const a=new Image;a.onload=()=>o(a),a.onerror=n,a.src=t});else{const n=yield(yield fetch(t)).blob();i=yield createImageBitmap(n,{imageOrientation:"flipY"})}if(this.elementUrls.get(e)!==t){"close"in i&&i.close();return}const r=new b.Texture(i);i instanceof HTMLImageElement||(r.flipY=!1),r.colorSpace=b.LinearSRGBColorSpace,r.needsUpdate=!0,this.textures.set(e,r),this.onUpdate(e,r)}catch(i){console.warn("[MirageEngine] Failed to load texture:",t,i)}finally{this.elementUrls.has(e)&&this.loadStatus.set(e,!1)}}})}disposeTexture(e){const t=this.textures.get(e);t&&(t.dispose(),this.textures.delete(e),this.onUpdate(e,null)),this.loadStatus.set(e,!1)}get(e){return this.textures.get(e)}disposeAll(){this.observer&&this.observer.disconnect()}}class et{constructor(e,t,i,r){g(this,"canvas");g(this,"scene");g(this,"camera");g(this,"renderer");g(this,"renderTargets",[]);g(this,"renderOrder",0);g(this,"qualityFactor",2);g(this,"mode","overlay");g(this,"canvasSize","viewport");g(this,"clipArea",1);g(this,"targetLayer","base");g(this,"overscan",200);g(this,"target");g(this,"mountContainer");g(this,"registry");g(this,"targetRect");g(this,"travelersByLayer",Array.from({length:A.MAX_LAYERS},()=>new Set));g(this,"textureManager");g(this,"fixedMeshes",new Set);var a,c,l,d,h;this.target=e,this.mountContainer=i,this.registry=r,this.mode=(a=t.mode)!=null?a:"overlay",this.canvasSize=(c=t.canvasSize)!=null?c:"viewport",this.clipArea=(l=t.travelerClipArea)!=null?l:1,this.targetLayer=(d=t.layer)!=null?d:"base",this.textureManager=new Qe((u,v)=>{const f=this.registry.get(u);f&&f.material instanceof b.ShaderMaterial&&$.forceUpdateUniforms(f.material,{texture:v})},this.isViewport),this.canvas=document.createElement("canvas"),this.scene=new b.Scene,this.targetRect=this.target.getBoundingClientRect();const o=this.isViewport?window.innerWidth+this.overscan*2:this.targetRect.width,n=this.isViewport?window.innerHeight+this.overscan*2:this.targetRect.height;this.camera=new b.OrthographicCamera(o/-2,o/2,n/2,n/-2,1,1e3),this.camera.position.z=100,this.camera.layers.set(this.getSceneLayer()),this.renderer=new b.WebGLRenderer({canvas:this.canvas,alpha:!0,antialias:!0}),b.ColorManagement.enabled=!1,this.renderer.outputColorSpace=b.LinearSRGBColorSpace,this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(o,n),this.applyTextQuality((h=t.quality)!=null?h:"medium")}get isViewport(){return this.mode==="overlay"&&this.canvasSize==="viewport"}getSceneLayer(){return typeof this.targetLayer=="number"?this.targetLayer:this.targetLayer==="selected"?_.SELECTED:_.BASE}createRenderTarget(){for(let e=0;e<A.MAX_LAYERS;e++){const t=this.isViewport?window.innerWidth+this.overscan*2:this.targetRect.width,i=this.isViewport?window.innerHeight+this.overscan*2:this.targetRect.height;this.renderTargets.push(new b.WebGLRenderTarget(t*this.qualityFactor,i*this.qualityFactor,{minFilter:b.LinearFilter,magFilter:b.LinearFilter,format:b.RGBAFormat,stencilBuffer:!1,depthBuffer:!0}))}}applyTextQuality(e){if(typeof e=="number"){this.qualityFactor=Math.max(.1,e);return}switch(e){case"low":this.qualityFactor=1;break;case"high":this.qualityFactor=4;break;case"medium":this.qualityFactor=2;break;default:this.qualityFactor=2;break}}mount(){this.mountContainer.prepend(this.canvas),this.canvas.style.pointerEvents=this.mode==="overlay"?"none":"auto",this.updateCanvasLayout()}updateCanvasLayout(){const e=this.isViewport?window.innerWidth+this.overscan*2:this.targetRect.width,t=this.isViewport?window.innerHeight+this.overscan*2:this.targetRect.height;this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.mode==="duplicate"?(this.canvas.style.position="",this.canvas.style.top="",this.canvas.style.left="",this.canvas.style.display="block"):(this.canvas.style.position=this.isViewport?"fixed":"absolute",this.canvas.style.top=this.isViewport?`-${this.overscan}px`:`${this.target.offsetTop}px`,this.canvas.style.left=this.isViewport?`-${this.overscan}px`:`${this.target.offsetLeft}px`,this.canvas.style.display="block")}updateUniforms(e,t){const i=this.registry.get(e);i&&(i.traverse(r=>{r.isMesh&&r.material&&$.forceUpdateUniforms(r.material,t)}),i.userData.nativeMesh&&i.userData.nativeMesh.traverse(r=>{r.isMesh&&r.material&&$.forceUpdateUniforms(r.material,t)}))}dispose(){this.renderer.dispose(),this.canvas.remove(),this.textureManager.disposeAll()}setSize(e,t){this.renderer.setSize(e,t);for(const i of this.renderTargets)i.setSize(e*this.qualityFactor,t*this.qualityFactor);this.camera.left=e/-2,this.camera.right=e/2,this.camera.top=t/2,this.camera.bottom=t/-2,this.camera.updateProjectionMatrix()}syncScene(e,t){const i=this.target.getBoundingClientRect(),r=this.isViewport?window.innerWidth+this.overscan*2:i.width,o=this.isViewport?window.innerHeight+this.overscan*2:i.height,n=this.isViewport?this.canvas.clientWidth:this.targetRect.width,a=this.isViewport?this.canvas.clientHeight:this.targetRect.height,c=Math.abs(r-n)>.1||Math.abs(o-a)>.1,l=this.mode==="overlay"&&(Math.abs(i.top-this.targetRect.top)>.1||Math.abs(i.left-this.targetRect.left)>.1);c?(this.targetRect=i,this.setSize(r,o),this.updateCanvasLayout()):l?(this.targetRect=i,this.updateCanvasLayout()):this.targetRect=i,this.renderOrder=0,this.reconcileNode(e),t.size>0&&t.forEach(d=>{const h=this.registry.get(d);if(h){this.scene.remove(h);for(const u of this.travelersByLayer)u.delete(h);this.fixedMeshes.delete(h),h.geometry.dispose(),h.userData.nativeMesh&&(this.scene.remove(h.userData.nativeMesh),Array.isArray(h.userData.nativeMesh.material)?h.userData.nativeMesh.material.forEach(u=>u.dispose()):h.userData.nativeMesh.material.dispose(),h.userData.nativeMesh.geometry.dispose()),h.traverse(u=>{u instanceof b.Mesh&&(u.geometry&&u.geometry.dispose(),u.material&&(Array.isArray(u.material)?u.material.forEach(v=>v.dispose()):u.material.dispose()))}),this.registry.remove(d),this.textureManager.unregister(d)}})}reconcileNode(e){var i;let t=this.registry.get(e.element);if(!t){const r=new b.PlaneGeometry(1,1),o=e.isTraveler?(i=this.renderTargets[e.captureLayer-2])==null?void 0:i.texture:this.textureManager.get(e.element),n=$.create("BOX",e.styles,"",e.rect.width,e.rect.height,this.qualityFactor,o,e.shaderHooks);t=new b.Mesh(r,n),e.type==="TEXT"&&(t.name="BG_MESH"),this.scene.add(t),this.registry.register(e.element,t),t.userData.baseMaterial=n}if(this.updateMeshProperties(t,e),this.updateMeshLayers(t,e),e.isTraveler)for(let r=0;r<A.MAX_LAYERS;r++)r===e.captureLayer-2?this.travelersByLayer[r].add(t):this.travelersByLayer[r].delete(t);else for(const r of this.travelersByLayer)r.delete(t);if(e.isFixed?this.fixedMeshes.add(t):this.fixedMeshes.delete(t),e.styles.imageSrc?this.textureManager.register(e.element,e.styles.imageSrc):this.textureManager.unregister(e.element),e.type==="BOX")for(const r of e.children)this.reconcileNode(r);else e.type==="TEXT"&&(this.reconcileTextChild(t,e,!1),t.userData.nativeMesh&&e.nativeStyles&&this.reconcileTextChild(t.userData.nativeMesh,e,!0))}reconcileTextChild(e,t,i){var l;const r=t.textLines||[{text:t.textContent||"",rect:t.rect}],o=i?t.nativeStyles:t.textStyles,n=JSON.stringify(o)+t.textContent+r.map(d=>d.text).join("|"),a=(l=e.userData)==null?void 0:l.textChildStyleHash;if(t.dirtyMask&ge||n!==a){e.children.filter(f=>f.name.startsWith("TEXT_CHILD")).forEach(f=>{var x;const p=f;(x=p.material.map)==null||x.dispose(),p.geometry.dispose(),e.remove(p)});const h=t.rect,u=h.x+h.width/2,v=h.y+h.height/2;r.forEach((f,p)=>{const x=$.create("TEXT",o,f.text,f.rect.width,f.rect.height,this.qualityFactor),I=new b.PlaneGeometry(1,1),k=new b.Mesh(I,x);k.name=`TEXT_CHILD_${p}`;const T=t.rect.width===0?1:f.rect.width/t.rect.width,E=t.rect.height===0?1:f.rect.height/t.rect.height;k.scale.set(T,E,1);const Y=f.rect.x+f.rect.width/2,O=f.rect.y+f.rect.height/2,N=Y-u,V=-(O-v);k.position.set(t.rect.width===0?0:N/t.rect.width,t.rect.height===0?0:V/t.rect.height,.005),e.add(k)}),e.userData.textChildStyleHash=n}e.children.forEach(d=>{if(!d.name.startsWith("TEXT_CHILD"))return;const h=d,u=t.visibility&H?_.BASE:_.HIDDEN;if(h.layers.set(u),t.visibility&Z&&h.layers.enable(_.SELECTED),t.visibility&H)if(!i&&t.nativeLayer!==void 0&&t.nativeStyles!==void 0)for(let v=t.captureLayer;v<t.nativeLayer;v++)h.layers.enable(_.getCaptureLayer(v));else if(i&&t.nativeLayer!==void 0)for(let v=Math.max(t.captureLayer,t.nativeLayer);v<=A.MAX_LAYERS+1;v++)h.layers.enable(_.getCaptureLayer(v));else for(let v=t.captureLayer;v<=A.MAX_LAYERS+1;v++)h.layers.enable(_.getCaptureLayer(v))})}updateMeshProperties(e,t){var T,E,Y;const{rect:i,styles:r}=t,o=this.renderer.getPixelRatio(),n=this.renderer.domElement.width/o,a=this.renderer.domElement.height/o;e.material=e.userData.baseMaterial,e.scale.set(i.width,i.height,1),e.userData.domRect=Se(J({},i),{width:i.width,height:i.height});const c=.001;this.renderOrder++;const l=this.targetRect.left+window.scrollX,d=this.targetRect.top+window.scrollY;let h,u;if(this.isViewport)h=i.x-window.innerWidth/2+i.width/2,u=-i.y+window.innerHeight/2-i.height/2;else{const O=i.x-l,N=i.y-d;h=O-n/2+i.width/2,u=-N+a/2-i.height/2}e.position.set(h,u,r.zIndex+this.renderOrder*c);const v=i.x,f=i.y;e.userData.basePosition={x:h,y:u},e.userData.originalBasePosition={x:h,y:u},e.userData.baseSize={width:i.width,height:i.height},e.userData.baseDOM={x:v,y:f},e.userData.isFixed=t.isFixed,e.userData.initialScroll={x:window.scrollX,y:window.scrollY};const p=t.element.nodeType===Node.TEXT_NODE?t.element.parentElement:t.element,x=window.getComputedStyle(p);let I=0,k=0;if(x.transform&&x.transform!=="none"){const O=new DOMMatrix(x.transform);I=O.m41,k=O.m42}if(e.userData.baseTransform={x:I,y:k},delete e.userData.originRatioX,delete e.userData.originRatioY,$.update(e.userData.baseMaterial,"BOX",r,"",i.width,i.height,this.qualityFactor,t.isTraveler?(T=this.renderTargets[t.captureLayer-2])==null?void 0:T.texture:this.textureManager.get(t.element)),t.nativeStyles&&t.nativeRect){if(!e.userData.nativeMesh){const F=$.create("BOX",t.nativeStyles,"",t.nativeRect.width,t.nativeRect.height,this.qualityFactor,t.isTraveler?(E=this.renderTargets[t.captureLayer-2])==null?void 0:E.texture:this.textureManager.get(t.element),t.shaderHooks),q=new b.Mesh(e.geometry,F);t.type==="TEXT"&&(q.name="BG_MESH"),this.scene.add(q),e.userData.nativeMesh=q}const O=e.userData.nativeMesh;let N,V;if(this.isViewport)N=t.nativeRect.x-window.innerWidth/2+t.nativeRect.width/2,V=-t.nativeRect.y+window.innerHeight/2-t.nativeRect.height/2;else{const F=t.nativeRect.x-l,q=t.nativeRect.y-d;N=F-n/2+t.nativeRect.width/2,V=-q+a/2-t.nativeRect.height/2}O.scale.set(t.nativeRect.width,t.nativeRect.height,1),O.position.set(N,V,t.nativeStyles.zIndex+this.renderOrder*c),$.update(O.material,"BOX",t.nativeStyles,"",t.nativeRect.width,t.nativeRect.height,this.qualityFactor,t.isTraveler?(Y=this.renderTargets[t.captureLayer-2])==null?void 0:Y.texture:this.textureManager.get(t.element))}else e.userData.nativeMesh&&(this.scene.remove(e.userData.nativeMesh),e.userData.nativeMesh.material instanceof b.Material&&e.userData.nativeMesh.material.dispose(),delete e.userData.nativeMesh)}updateMeshLayers(e,t){const i=t.visibility&H?_.BASE:_.HIDDEN;if(e.layers.set(i),t.visibility&Z&&e.layers.enable(_.SELECTED),e.userData.nativeMesh&&t.nativeLayer!==void 0){const r=e.userData.nativeMesh;if(r.layers.set(_.HIDDEN),t.visibility&H){for(let o=t.captureLayer;o<t.nativeLayer;o++)e.layers.enable(_.getCaptureLayer(o));for(let o=Math.max(t.captureLayer,t.nativeLayer);o<=A.MAX_LAYERS+1;o++)r.layers.enable(_.getCaptureLayer(o))}}else if(t.visibility&H)for(let r=t.captureLayer;r<=A.MAX_LAYERS+1;r++)e.layers.enable(_.getCaptureLayer(r))}captureRenderTarget(e,t,i){if(e.size===0||!i)return;const r=new b.Color,o=this.renderer.getClearAlpha();this.renderer.getClearColor(r),this.renderer.setClearColor(0,0),this.renderer.setRenderTarget(i),this.renderer.clear(),this.renderer.autoClear=!1,this.renderer.setScissorTest(!0),this.camera.layers.set(t);const n=new b.Vector3,a=this.isViewport?window.innerWidth+this.overscan*2:this.targetRect.width,c=this.isViewport?window.innerHeight+this.overscan*2:this.targetRect.height,l=this.renderer.getPixelRatio();for(const d of e){n.setFromMatrixPosition(d.matrixWorld),n.project(this.camera);const h=(n.x+1)/2*a,u=(n.y+1)/2*c;let v=0,f=1;typeof this.clipArea=="number"?f=this.clipArea:this.clipArea.endsWith("%")?f=parseFloat(this.clipArea)/100:this.clipArea.endsWith("px")&&(v=parseFloat(this.clipArea));const p=d.scale.x*f+.5,x=d.scale.y*f+.5,I=h-p/2,k=u-x/2,T=(I*this.qualityFactor-v)/l,E=(k*this.qualityFactor-v)/l,Y=(p*this.qualityFactor+v*2)/l,O=(x*this.qualityFactor+v*2)/l;this.renderer.setScissor(T,E,Y,O),this.renderer.render(this.scene,this.camera)}this.renderer.setScissorTest(!1),this.renderer.autoClear=!0,this.renderer.setRenderTarget(null),this.camera.layers.set(this.getSceneLayer()),this.renderer.setClearColor(r,o)}render(){for(let e=0;e<A.MAX_LAYERS;e++){const t=e+1;this.captureRenderTarget(this.travelersByLayer[e],_.getCaptureLayer(t),this.renderTargets[e])}this.renderer.render(this.scene,this.camera)}updateCameraScroll(e,t){this.isViewport&&(this.camera.position.x=e,this.camera.position.y=-t,this.camera.updateMatrixWorld())}}function tt(s){const e=s.textContent||"",t=[];let i="",r=null,o=-1;const n=(l,d)=>{for(let h=0;h<l.length;h++){const u=l[h],v=document.createRange();v.setStart(s,d+h),v.setEnd(s,d+h+1);const f=v.getBoundingClientRect();if(f.width===0&&f.height===0){i+=u;continue}o===-1||Math.abs(f.top-o)>f.height/2?(i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),i=u,r={left:f.left,top:f.top,right:f.right,bottom:f.bottom},o=f.top):(i+=u,r&&(r.left=Math.min(r.left,f.left),r.top=Math.min(r.top,f.top),r.right=Math.max(r.right,f.right),r.bottom=Math.max(r.bottom,f.bottom)))}},a=e.match(/[^\s\-]+\-?|\-|\s+/g)||[];let c=0;for(const l of a){const d=document.createRange();d.setStart(s,c),d.setEnd(s,c+l.length);const h=d.getClientRects();if(h.length>1)n(l,c);else{const u=h.length===1?h[0]:d.getBoundingClientRect();if(u.width===0&&u.height===0){i+=l,c+=l.length;continue}o===-1||Math.abs(u.top-o)>u.height/2?(i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),i=l,r={left:u.left,top:u.top,right:u.right,bottom:u.bottom},o=u.top):(i+=l,r&&(r.left=Math.min(r.left,u.left),r.top=Math.min(r.top,u.top),r.right=Math.max(r.right,u.right),r.bottom=Math.max(r.bottom,u.bottom)))}c+=l.length}return i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),t.filter(l=>l.text.trim().length>0&&l.rect.width>0&&l.rect.height>0)}function Oe(s){const e=parseFloat(s.fontSize);let t=parseFloat(s.lineHeight);isNaN(t)&&(t=e*1.2);let i=parseFloat(s.letterSpacing);return isNaN(i)&&(i=0),{font:`${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`,fontSize:s.fontSize,color:s.color,textAlign:s.textAlign||"start",textBaseline:"alphabetic",direction:s.direction||"inherit",lineHeight:t,letterSpacing:i}}function Ue(s,e=K|Q|Le|ge|fe,t,i=1,r=0,o=2,n,a){var oe,ae,ce,le,he,de;if(s.nodeType===Node.TEXT_NODE){const m=s;if(!m.textContent||!m.textContent.trim())return null;const R=m.textContent.replace(/\s+/g," ");if(R.length===0)return null;const U=tt(m);if(U.length===0)return null;const X=m.parentElement,L=X?window.getComputedStyle(X):null;if(!L)return null;const z=Math.min(...U.map(w=>w.rect.left)),C=Math.min(...U.map(w=>w.rect.top)),W=Math.max(...U.map(w=>w.rect.left+w.rect.width)),j=Math.max(...U.map(w=>w.rect.top+w.rect.height));return{id:Math.random().toString(36).substring(2,9),type:"TEXT",element:m,rect:{x:z+window.scrollX,y:C+window.scrollY,width:W-z,height:j-C},styles:{backgroundColor:"transparent",backgroundImage:"",opacity:X&&X.dataset[P.KEY]===P.VALUES.HIDE?1:parseFloat(L.opacity),zIndex:(isNaN(parseInt(L.zIndex))?0:parseInt(L.zIndex))+r,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px",isTraveler:!1},textContent:R,textLines:U.map(w=>({text:w.text.trim(),rect:{x:w.rect.left+window.scrollX,y:w.rect.top+window.scrollY,width:w.rect.width,height:w.rect.height}})),textStyles:Oe(L),dirtyMask:e,visibility:t,isTraveler:!1,captureLayer:i,isFixed:L.position==="fixed",nativeLayer:n,nativeStyles:a?J(J({backgroundColor:"transparent",backgroundImage:"",opacity:X&&X.dataset[P.KEY]===P.VALUES.HIDE?1:parseFloat(L.opacity),zIndex:(isNaN(parseInt(L.zIndex))?0:parseInt(L.zIndex))+r,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px",isTraveler:!1},Oe(L)),a):void 0,nativeRect:a?{x:z+window.scrollX,y:C+window.scrollY,width:W-z,height:j-C}:void 0,children:[]}}if(s.nodeType!==Node.ELEMENT_NODE)return null;const c=s,l=c.dataset[D.KEY];let d=t,h=t;if(l){const m=new Set(l.split(/\s+/));for(const R of m)if(!be.includes(R))throw new Error(`[MirageEngine] Invalid filter token: '${R}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(m.has(D.VALUES.END))return null;if(m.has(D.VALUES.INCLUDE_TREE)&&m.has(D.VALUES.EXCLUDE_TREE))throw new Error("[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(m.has(D.VALUES.INCLUDE_SELF)&&m.has(D.VALUES.EXCLUDE_SELF))throw new Error("[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element.");m.has(D.VALUES.INCLUDE_TREE)?d=d|H:m.has(D.VALUES.EXCLUDE_TREE)&&(d=d&~H),h=d,m.has(D.VALUES.INCLUDE_SELF)?h=h|H:m.has(D.VALUES.EXCLUDE_SELF)&&(h=h&~H)}const u=c.dataset[B.KEY];if(u){const m=new Set(u.split(/\s+/));for(const R of m)if(!be.includes(R))throw new Error(`[MirageEngine] Invalid select token: '${R}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(m.has(B.VALUES.END))return null;if(m.has(B.VALUES.INCLUDE_TREE)&&m.has(B.VALUES.EXCLUDE_TREE))throw new Error("[MirageEngine] Conflicting selects: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(m.has(B.VALUES.INCLUDE_SELF)&&m.has(B.VALUES.EXCLUDE_SELF))throw new Error("[MirageEngine] Conflicting selects: 'include-self' and 'exclude-self' cannot be used together on the same element.");m.has(B.VALUES.INCLUDE_TREE)?d=d|Z:m.has(B.VALUES.EXCLUDE_TREE)&&(d=d&~Z),h=d,m.has(B.VALUES.INCLUDE_SELF)?h=h|Z:m.has(B.VALUES.EXCLUDE_SELF)&&(h=h&~Z)}const v=c.dataset[A.KEY];let f=!1,p=a?J({},a):{},x=n;if(v){let m=1;const R=v.indexOf("{"),U=v.lastIndexOf("}");let X=v;if(R!==-1&&U!==-1&&U>R){X=v.substring(0,R).trim();const C=v.substring(R,U+1);try{p=new Function("return "+C)()}catch(W){console.warn(`[MirageEngine] Failed to parse travel styles JSON: ${C}`)}}const L=X.split(/\s+/);let z=!1;if(L.includes(A.VALUES.TRAVELER)){f=!0,z=!0;const C=L.find(W=>!isNaN(parseInt(W,10)));C&&(m=parseInt(C,10))}else if(L.includes(A.VALUES.NATIVE)){f=!1;const C=L.find(W=>!isNaN(parseInt(W,10)));C&&(x=parseInt(C,10))}if(z){const C=m+1;if(C<i)throw new Error(`[MirageEngine] Traveler layer (${m}) cannot be smaller than inherited capture layer (${i-1}).`);i=Math.min(C,A.MAX_LAYERS+1)}}const I=c.dataset[Re.KEY];let k;I&&(k=JSON.parse(I));const T=c.getBoundingClientRect(),E=window.getComputedStyle(c);if(T.width===0||T.height===0||E.display==="none")return null;let Y=c.getAttribute("data-mid");Y||(Y=Math.random().toString(36).substring(2,11),c.setAttribute("data-mid",Y));const O=parseInt(E.zIndex),N=(isNaN(O)?0:O)+r;let V;if(c.tagName==="IMG")V=c.src;else if(c.tagName.toLowerCase()==="svg"){const m=c.cloneNode(!0),R=p==null?void 0:p.color,U=p==null?void 0:p.fill,X=p==null?void 0:p.stroke,L=p==null?void 0:p.opacity,z=(w,Fe)=>{const G=window.getComputedStyle(w),ue=Fe,ot=G.fill===G.color,at=G.stroke===G.color,Ee=U||(ot?R:void 0)||G.fill;Ee&&Ee!=="none"&&(ue.style.fill=Ee);const Te=X||(at?R:void 0)||G.stroke;Te&&Te!=="none"&&(ue.style.stroke=Te),G.strokeWidth&&G.strokeWidth!=="0px"&&(ue.style.strokeWidth=G.strokeWidth);const Be=R||G.color;Be&&(ue.style.color=Be);const xe=L||G.opacity;xe&&xe!=="1"&&(ue.style.opacity=xe);for(let ve=0;ve<w.children.length;ve++)z(w.children[ve],Fe.children[ve])};z(c,m);const C=c.getBoundingClientRect(),W=window.devicePixelRatio*o;m.hasAttribute("viewBox")||m.setAttribute("viewBox",`0 0 ${C.width} ${C.height}`),m.setAttribute("width",(C.width*W).toString()),m.setAttribute("height",(C.height*W).toString());let j=new XMLSerializer().serializeToString(m);j.includes("xmlns=")||(j=j.replace("<svg",'<svg xmlns="http://www.w3.org/2000/svg"')),V=`data:image/svg+xml;utf8,${encodeURIComponent(j)}`}else if(E.backgroundImage&&E.backgroundImage!=="none"){const m=E.backgroundImage.match(/url\(['"]?(.*?)['"]?\)/);m&&(V=m[1])}const F={backgroundColor:E.backgroundColor,backgroundImage:E.backgroundImage,opacity:c.dataset[P.KEY]===P.VALUES.HIDE?1:parseFloat(E.opacity),zIndex:N,borderRadius:E.borderRadius,borderColor:E.borderColor,borderWidth:E.borderWidth,imageSrc:V,isTraveler:f},q=F;let pe,me;const ne=[];return c.tagName.toLowerCase()!=="svg"&&Array.from(c.childNodes).forEach(m=>{const R=m.nodeType===Node.TEXT_NODE?h:d,U=Ue(m,e,R,i,N,o,x,m.nodeType===Node.TEXT_NODE&&Object.keys(p).length>0?p:void 0);U&&ne.push(U)}),{id:Y,type:"BOX",element:c,rect:{x:T.left+window.scrollX,y:T.top+window.scrollY,width:T.width,height:T.height},styles:q,textContent:pe,textStyles:me,dirtyMask:e,visibility:h,isTraveler:f,captureLayer:i,nativeLayer:x,nativeStyles:x!==void 0?Se(J({},F),{backgroundColor:(oe=p.backgroundColor)!=null?oe:F.backgroundColor,backgroundImage:(ae=p.backgroundImage)!=null?ae:F.backgroundImage,opacity:(ce=p.opacity)!=null?ce:F.opacity,zIndex:p.zIndex!==void 0?p.zIndex+N:F.zIndex,borderRadius:(le=p.borderRadius)!=null?le:F.borderRadius,borderColor:(he=p.borderColor)!=null?he:F.borderColor,borderWidth:(de=p.borderWidth)!=null?de:F.borderWidth,isTraveler:F.isTraveler}):void 0,nativeRect:x!==void 0?{x:p.x!==void 0?parseFloat(p.x):T.left+window.scrollX,y:p.y!==void 0?parseFloat(p.y):T.top+window.scrollY,width:p.width!==void 0?parseFloat(p.width):T.width,height:p.height!==void 0?parseFloat(p.height):T.height}:void 0,isFixed:E.position==="fixed",children:ne,shaderHooks:k}}function rt(s,e){e.size!==0&&e.forEach((t,i)=>{var Y,O,N,V,F,q,pe,me,ne,oe,ae,ce,le,he,de,m,R,U;const r=s.get(i);if(!r||!r.userData.basePosition)return;let{x:o,y:n}=r.userData.basePosition;const{width:a,height:c}=r.userData.baseSize,l=(Y=t.width)!=null?Y:a,d=(O=t.height)!=null?O:c,h=l-a,u=d-c;if(t.width!==void 0&&r.userData.originRatioX===void 0&&Math.abs(h)>.1){const X=i.getBoundingClientRect(),L=(N=t.x)!=null?N:0,z=(F=(V=r.userData.baseTransform)==null?void 0:V.x)!=null?F:0,C=r.userData.isFixed?0:window.scrollX;let w=-(X.left+C-L+z-r.userData.baseDOM.x)/h;Math.abs(w)<.05?w=0:Math.abs(w-1)<.05?w=1:Math.abs(w-.5)<.05&&(w=.5),r.userData.originRatioX=w}if(t.height!==void 0&&r.userData.originRatioY===void 0&&Math.abs(u)>.1){const X=i.getBoundingClientRect(),L=(q=t.y)!=null?q:0,z=(me=(pe=r.userData.baseTransform)==null?void 0:pe.y)!=null?me:0,C=r.userData.isFixed?0:window.scrollY;let w=-(X.top+C-L+z-r.userData.baseDOM.y)/u;Math.abs(w)<.05?w=0:Math.abs(w-1)<.05?w=1:Math.abs(w-.5)<.05&&(w=.5),r.userData.originRatioY=w}const v=(ne=r.userData.originRatioX)!=null?ne:.5,f=(oe=r.userData.originRatioY)!=null?oe:.5,p=h*(.5-v),x=u*(.5-f),I=(ce=(ae=r.userData.baseTransform)==null?void 0:ae.x)!=null?ce:0,k=(he=(le=r.userData.baseTransform)==null?void 0:le.y)!=null?he:0,T=((de=t.x)!=null?de:I)-I,E=((m=t.y)!=null?m:k)-k;r.position.setX(o+p+T),r.position.setY(n-(x+E)),r.scale.set(l,d,1),$.forceUpdateUniforms(r.material,{backgroundColor:t.backgroundColor,backgroundImage:t.backgroundImage,opacity:t.opacity,borderRadius:(U=t.borderRadius)!=null?U:(R=r.userData.baseStyles)==null?void 0:R.borderRadius,width:l,height:d})})}function _e(s,e,t){s.forEach(i=>{if(i.userData.isFixed&&i.userData.initialScroll&&i.userData.originalBasePosition){const r=e-i.userData.initialScroll.x,o=t-i.userData.initialScroll.y;i.userData.basePosition.x=i.userData.originalBasePosition.x+r,i.userData.basePosition.y=i.userData.originalBasePosition.y-o,i.position.x=i.userData.basePosition.x,i.position.y=i.userData.basePosition.y}})}class it{constructor(e,t,i,r){g(this,"target");g(this,"renderer");g(this,"registry");g(this,"isTravelEnabled",!1);g(this,"tracker");this.target=e,this.renderer=t,this.registry=i,this.tracker=new De(e,{resizeDebounce:r.resizeDebounce}),this.tracker.onLayoutChange.add((o,n)=>{document.querySelector(`[${A.NAME}~='${A.VALUES.TRAVELER}']`)!==null&&!this.isTravelEnabled&&(this.isTravelEnabled=!0,this.renderer.createRenderTarget());const c=Ue(this.target,o,H,1,0,this.renderer.qualityFactor);c&&this.renderer.syncScene(c,n)}),this.tracker.onScrollChange.add((o,n)=>{_e(this.renderer.fixedMeshes,o,n),this.renderer.updateCameraScroll(o,n)}),this.tracker.onStyleChange.add(o=>{rt(this.registry,o)}),this.tracker.onRender.add(()=>{this.renderer.render()})}start(){this.tracker.start(),_e(this.renderer.fixedMeshes,window.scrollX,window.scrollY),this.renderer.updateCameraScroll(window.scrollX,window.scrollY)}stop(){this.tracker.stop()}}class st{constructor(){g(this,"store");this.store=new WeakMap}register(e,t){this.store.set(e,t)}get(e){return this.store.get(e)}has(e){return this.store.has(e)}remove(e){this.store.delete(e)}}class nt{constructor(e,t){g(this,"renderer");g(this,"syncer");g(this,"target");g(this,"registry");var r,o,n;if(this.target=e,this.registry=new st,!document.getElementById("mirage-engine-styles")){const a=document.createElement("style");a.id="mirage-engine-styles",a.textContent=`
|
|
152
|
+
[${P.NAME}="${P.VALUES.HIDE}"] {
|
|
153
153
|
opacity: 0 !important;
|
|
154
154
|
}
|
|
155
|
-
`,document.head.appendChild(
|
|
155
|
+
`,document.head.appendChild(a)}let i;if(t.mode==="duplicate"?i=(o=(r=t.container)!=null?r:this.target.parentElement)!=null?o:void 0:i=(n=this.target.parentElement)!=null?n:void 0,!i)throw new Error("[Mirage] Cannot find a container (parent or option).");this.renderer=new et(this.target,t,i,this.registry),this.renderer.mount(),this.syncer=new it(this.target,this.renderer,this.registry,t)}start(){this.syncer.start()}stop(){this.syncer.stop()}dispose(){this.syncer.stop(),this.renderer.dispose()}getTracker(){return this.syncer.tracker}updateUniforms(e,t){this.renderer.updateUniforms(e,t)}getCanvas(){return this.renderer.canvas}test(){const e=this.registry.get(document.querySelector("#box2"));if(!e)return;const t={ArrowRight:!1,ArrowLeft:!1,ArrowUp:!1,ArrowDown:!1};window.addEventListener("keydown",o=>{t[o.key]!==void 0&&(t[o.key]=!0)}),window.addEventListener("keyup",o=>{t[o.key]!==void 0&&(t[o.key]=!1)});const i=2,r=()=>{requestAnimationFrame(r),t.ArrowRight&&e.position.setX(e.position.x+i),t.ArrowLeft&&e.position.setX(e.position.x-i),t.ArrowUp&&e.position.setY(e.position.y+i),t.ArrowDown&&e.position.setY(e.position.y-i)};r()}}y.ALLOWED_FILTERS=be,y.ATTR_DOM=P,y.ATTR_FILTER=D,y.ATTR_SANDWICH=Ne,y.ATTR_SELECT=B,y.ATTR_SHADER=Re,y.ATTR_TRAVEL=A,y.DIRTY_CONTENT=ge,y.DIRTY_NONE=ie,y.DIRTY_RECT=K,y.DIRTY_STRUCTURE=fe,y.DIRTY_STYLE=Q,y.DIRTY_ZINDEX=Le,y.EXCLUDED=Ve,y.Engine=nt,y.SELECT_LAYER=Z,y.THREE_LAYERS=_,y.TRAVEL_VALUES=re,y.Tracker=De,y.USER_LAYER=H,y.extractFromStyle=Me,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -10,8 +10,11 @@ export declare class Renderer {
|
|
|
10
10
|
private renderOrder;
|
|
11
11
|
qualityFactor: number;
|
|
12
12
|
private mode;
|
|
13
|
+
private canvasSize;
|
|
13
14
|
private clipArea;
|
|
14
15
|
targetLayer: number | LayerTarget;
|
|
16
|
+
private readonly overscan;
|
|
17
|
+
private get isViewport();
|
|
15
18
|
private target;
|
|
16
19
|
private mountContainer;
|
|
17
20
|
private registry;
|
|
@@ -35,4 +38,5 @@ export declare class Renderer {
|
|
|
35
38
|
private updateMeshLayers;
|
|
36
39
|
private captureRenderTarget;
|
|
37
40
|
render(): void;
|
|
41
|
+
updateCameraScroll(scrollX: number, scrollY: number): void;
|
|
38
42
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
2
|
export type TextureReadyCallback = (element: HTMLElement, texture: THREE.Texture | null) => void;
|
|
3
3
|
export declare class TextureLifecycleManager {
|
|
4
|
-
private observer
|
|
4
|
+
private observer?;
|
|
5
5
|
private textures;
|
|
6
6
|
private loadStatus;
|
|
7
7
|
private elementUrls;
|
|
8
8
|
private onUpdate;
|
|
9
|
-
constructor(onUpdate: TextureReadyCallback);
|
|
9
|
+
constructor(onUpdate: TextureReadyCallback, enableCulling?: boolean);
|
|
10
10
|
register(element: HTMLElement, url: string): void;
|
|
11
11
|
unregister(element: HTMLElement): void;
|
|
12
12
|
private loadTexture;
|
|
@@ -21,6 +21,15 @@ interface BaseConfig {
|
|
|
21
21
|
}
|
|
22
22
|
export interface OverlayConfig extends BaseConfig {
|
|
23
23
|
mode?: "overlay";
|
|
24
|
+
/**
|
|
25
|
+
* Defines the render size of the canvas and camera behavior.
|
|
26
|
+
* 'viewport' (default) is optimized for long scrollable pages by allocating canvas size
|
|
27
|
+
* to the current screen viewport only, significantly improving performance (60fps).
|
|
28
|
+
* 'document' allocates the canvas size to match the full height of the target element,
|
|
29
|
+
* which can cause performance drops on very tall documents but might be necessary
|
|
30
|
+
* for specific visual needs.
|
|
31
|
+
*/
|
|
32
|
+
canvasSize?: "viewport" | "document";
|
|
24
33
|
}
|
|
25
34
|
export interface DuplicateConfig extends BaseConfig {
|
|
26
35
|
mode: "duplicate";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirage-engine/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"types": "src/index.ts",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@types/three": "^0.181.0",
|
|
16
|
-
"@mirage-engine/
|
|
17
|
-
"@mirage-engine/
|
|
16
|
+
"@mirage-engine/dom-tracker": "0.3.5",
|
|
17
|
+
"@mirage-engine/painter": "1.0.2"
|
|
18
18
|
},
|
|
19
19
|
"private": false,
|
|
20
20
|
"publishConfig": {
|
package/src/core/Syncer.ts
CHANGED
|
@@ -54,6 +54,7 @@ export class Syncer {
|
|
|
54
54
|
|
|
55
55
|
this.tracker.onScrollChange.add((scrollX, scrollY) => {
|
|
56
56
|
updateFixedMeshesScroll(this.renderer.fixedMeshes, scrollX, scrollY);
|
|
57
|
+
this.renderer.updateCameraScroll(scrollX, scrollY);
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
this.tracker.onStyleChange.add((pendingStyles) => {
|
|
@@ -67,6 +68,8 @@ export class Syncer {
|
|
|
67
68
|
|
|
68
69
|
public start() {
|
|
69
70
|
this.tracker.start();
|
|
71
|
+
updateFixedMeshesScroll(this.renderer.fixedMeshes, window.scrollX, window.scrollY);
|
|
72
|
+
this.renderer.updateCameraScroll(window.scrollX, window.scrollY);
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
public stop() {
|
package/src/renderer/Renderer.ts
CHANGED
|
@@ -25,8 +25,14 @@ export class Renderer {
|
|
|
25
25
|
private renderOrder: number = 0;
|
|
26
26
|
public qualityFactor: number = 2;
|
|
27
27
|
private mode: MirageMode = "overlay";
|
|
28
|
+
private canvasSize: "viewport" | "document" = "viewport";
|
|
28
29
|
private clipArea: travelerClipArea = 1;
|
|
29
30
|
public targetLayer: number | LayerTarget = "base";
|
|
31
|
+
private readonly overscan: number = 200;
|
|
32
|
+
|
|
33
|
+
private get isViewport(): boolean {
|
|
34
|
+
return this.mode === "overlay" && this.canvasSize === "viewport";
|
|
35
|
+
}
|
|
30
36
|
|
|
31
37
|
private target: HTMLElement;
|
|
32
38
|
private mountContainer: HTMLElement;
|
|
@@ -52,22 +58,24 @@ export class Renderer {
|
|
|
52
58
|
this.mountContainer = mountContainer;
|
|
53
59
|
this.registry = registry;
|
|
54
60
|
|
|
61
|
+
this.mode = config.mode ?? "overlay";
|
|
62
|
+
this.canvasSize = (config as any).canvasSize ?? "viewport";
|
|
63
|
+
this.clipArea = config.travelerClipArea ?? 1;
|
|
64
|
+
this.targetLayer = config.layer ?? "base";
|
|
65
|
+
|
|
55
66
|
this.textureManager = new TextureLifecycleManager((el, texture) => {
|
|
56
67
|
const mesh = this.registry.get(el);
|
|
57
68
|
if (mesh && mesh.material instanceof THREE.ShaderMaterial) {
|
|
58
69
|
Painter.forceUpdateUniforms(mesh.material, { texture: texture });
|
|
59
70
|
}
|
|
60
|
-
});
|
|
71
|
+
}, this.isViewport);
|
|
61
72
|
|
|
62
|
-
this.mode = config.mode ?? "overlay";
|
|
63
|
-
this.clipArea = config.travelerClipArea ?? 1;
|
|
64
|
-
this.targetLayer = config.layer ?? "base";
|
|
65
73
|
this.canvas = document.createElement("canvas");
|
|
66
74
|
this.scene = new THREE.Scene();
|
|
67
75
|
|
|
68
76
|
this.targetRect = this.target.getBoundingClientRect();
|
|
69
|
-
const width = this.targetRect.width;
|
|
70
|
-
const height = this.targetRect.height;
|
|
77
|
+
const width = this.isViewport ? window.innerWidth + this.overscan * 2 : this.targetRect.width;
|
|
78
|
+
const height = this.isViewport ? window.innerHeight + this.overscan * 2 : this.targetRect.height;
|
|
71
79
|
|
|
72
80
|
// target duplicate mode
|
|
73
81
|
// const width = target.parentElement!.clientWidth;
|
|
@@ -113,10 +121,12 @@ export class Renderer {
|
|
|
113
121
|
|
|
114
122
|
public createRenderTarget() {
|
|
115
123
|
for (let i = 0; i < ATTR_TRAVEL.MAX_LAYERS; i++) {
|
|
124
|
+
const width = this.isViewport ? window.innerWidth + this.overscan * 2 : this.targetRect.width;
|
|
125
|
+
const height = this.isViewport ? window.innerHeight + this.overscan * 2 : this.targetRect.height;
|
|
116
126
|
this.renderTargets.push(
|
|
117
127
|
new THREE.WebGLRenderTarget(
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
width * this.qualityFactor,
|
|
129
|
+
height * this.qualityFactor,
|
|
120
130
|
{
|
|
121
131
|
minFilter: THREE.LinearFilter,
|
|
122
132
|
magFilter: THREE.LinearFilter,
|
|
@@ -160,8 +170,10 @@ export class Renderer {
|
|
|
160
170
|
}
|
|
161
171
|
|
|
162
172
|
private updateCanvasLayout() {
|
|
163
|
-
this.
|
|
164
|
-
this.
|
|
173
|
+
const width = this.isViewport ? window.innerWidth + this.overscan * 2 : this.targetRect.width;
|
|
174
|
+
const height = this.isViewport ? window.innerHeight + this.overscan * 2 : this.targetRect.height;
|
|
175
|
+
this.canvas.style.width = `${width}px`;
|
|
176
|
+
this.canvas.style.height = `${height}px`;
|
|
165
177
|
|
|
166
178
|
if (this.mode === "duplicate") {
|
|
167
179
|
this.canvas.style.position = "";
|
|
@@ -169,9 +181,9 @@ export class Renderer {
|
|
|
169
181
|
this.canvas.style.left = "";
|
|
170
182
|
this.canvas.style.display = "block";
|
|
171
183
|
} else {
|
|
172
|
-
this.canvas.style.position = "absolute";
|
|
173
|
-
this.canvas.style.top = `${this.target.offsetTop}px`;
|
|
174
|
-
this.canvas.style.left = `${this.target.offsetLeft}px`;
|
|
184
|
+
this.canvas.style.position = this.isViewport ? "fixed" : "absolute";
|
|
185
|
+
this.canvas.style.top = this.isViewport ? `-${this.overscan}px` : `${this.target.offsetTop}px`;
|
|
186
|
+
this.canvas.style.left = this.isViewport ? `-${this.overscan}px` : `${this.target.offsetLeft}px`;
|
|
175
187
|
this.canvas.style.display = "block";
|
|
176
188
|
}
|
|
177
189
|
}
|
|
@@ -222,10 +234,14 @@ export class Renderer {
|
|
|
222
234
|
|
|
223
235
|
public syncScene(graphNode: SceneNode, pendingDeletions: Set<HTMLElement>) {
|
|
224
236
|
const newRect = this.target.getBoundingClientRect();
|
|
237
|
+
const newWidth = this.isViewport ? window.innerWidth + this.overscan * 2 : newRect.width;
|
|
238
|
+
const newHeight = this.isViewport ? window.innerHeight + this.overscan * 2 : newRect.height;
|
|
239
|
+
const oldWidth = this.isViewport ? this.canvas.clientWidth : this.targetRect.width;
|
|
240
|
+
const oldHeight = this.isViewport ? this.canvas.clientHeight : this.targetRect.height;
|
|
225
241
|
|
|
226
242
|
const isResized =
|
|
227
|
-
Math.abs(
|
|
228
|
-
Math.abs(
|
|
243
|
+
Math.abs(newWidth - oldWidth) > 0.1 ||
|
|
244
|
+
Math.abs(newHeight - oldHeight) > 0.1;
|
|
229
245
|
|
|
230
246
|
const isMoved =
|
|
231
247
|
this.mode === "overlay" &&
|
|
@@ -234,7 +250,7 @@ export class Renderer {
|
|
|
234
250
|
|
|
235
251
|
if (isResized) {
|
|
236
252
|
this.targetRect = newRect;
|
|
237
|
-
this.setSize(
|
|
253
|
+
this.setSize(newWidth, newHeight);
|
|
238
254
|
|
|
239
255
|
this.updateCanvasLayout();
|
|
240
256
|
} else if (isMoved) {
|
|
@@ -494,11 +510,16 @@ export class Renderer {
|
|
|
494
510
|
const targetPageX = this.targetRect.left + window.scrollX;
|
|
495
511
|
const targetPageY = this.targetRect.top + window.scrollY;
|
|
496
512
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
513
|
+
let baseX: number, baseY: number;
|
|
514
|
+
if (this.isViewport) {
|
|
515
|
+
baseX = rect.x - window.innerWidth / 2 + rect.width / 2;
|
|
516
|
+
baseY = -rect.y + window.innerHeight / 2 - rect.height / 2;
|
|
517
|
+
} else {
|
|
518
|
+
const localX = rect.x - targetPageX;
|
|
519
|
+
const localY = rect.y - targetPageY;
|
|
520
|
+
baseX = localX - canvasWidth / 2 + rect.width / 2;
|
|
521
|
+
baseY = -localY + canvasHeight / 2 - rect.height / 2;
|
|
522
|
+
}
|
|
502
523
|
|
|
503
524
|
mesh.position.set(
|
|
504
525
|
baseX,
|
|
@@ -571,10 +592,16 @@ export class Renderer {
|
|
|
571
592
|
}
|
|
572
593
|
|
|
573
594
|
const nativeMesh = mesh.userData.nativeMesh as THREE.Mesh;
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
595
|
+
let nativeBaseX: number, nativeBaseY: number;
|
|
596
|
+
if (this.isViewport) {
|
|
597
|
+
nativeBaseX = node.nativeRect.x - window.innerWidth / 2 + node.nativeRect.width / 2;
|
|
598
|
+
nativeBaseY = -node.nativeRect.y + window.innerHeight / 2 - node.nativeRect.height / 2;
|
|
599
|
+
} else {
|
|
600
|
+
const nativeLocalX = node.nativeRect.x - targetPageX;
|
|
601
|
+
const nativeLocalY = node.nativeRect.y - targetPageY;
|
|
602
|
+
nativeBaseX = nativeLocalX - canvasWidth / 2 + node.nativeRect.width / 2;
|
|
603
|
+
nativeBaseY = -nativeLocalY + canvasHeight / 2 - node.nativeRect.height / 2;
|
|
604
|
+
}
|
|
578
605
|
|
|
579
606
|
nativeMesh.scale.set(node.nativeRect.width, node.nativeRect.height, 1);
|
|
580
607
|
nativeMesh.position.set(
|
|
@@ -661,8 +688,8 @@ export class Renderer {
|
|
|
661
688
|
this.camera.layers.set(targetLayer);
|
|
662
689
|
|
|
663
690
|
const vector = new THREE.Vector3();
|
|
664
|
-
const canvasWidth = this.targetRect.width;
|
|
665
|
-
const canvasHeight = this.targetRect.height;
|
|
691
|
+
const canvasWidth = this.isViewport ? window.innerWidth + this.overscan * 2 : this.targetRect.width;
|
|
692
|
+
const canvasHeight = this.isViewport ? window.innerHeight + this.overscan * 2 : this.targetRect.height;
|
|
666
693
|
|
|
667
694
|
const pixelRatio = this.renderer.getPixelRatio();
|
|
668
695
|
|
|
@@ -719,5 +746,11 @@ export class Renderer {
|
|
|
719
746
|
this.renderer.render(this.scene, this.camera);
|
|
720
747
|
}
|
|
721
748
|
|
|
722
|
-
|
|
749
|
+
public updateCameraScroll(scrollX: number, scrollY: number) {
|
|
750
|
+
if (this.isViewport) {
|
|
751
|
+
this.camera.position.x = scrollX;
|
|
752
|
+
this.camera.position.y = -scrollY;
|
|
753
|
+
this.camera.updateMatrixWorld();
|
|
754
|
+
}
|
|
755
|
+
}
|
|
723
756
|
}
|
|
@@ -6,27 +6,29 @@ export type TextureReadyCallback = (
|
|
|
6
6
|
) => void;
|
|
7
7
|
|
|
8
8
|
export class TextureLifecycleManager {
|
|
9
|
-
private observer
|
|
9
|
+
private observer?: IntersectionObserver;
|
|
10
10
|
private textures: WeakMap<HTMLElement, THREE.Texture> = new WeakMap();
|
|
11
11
|
private loadStatus: WeakMap<HTMLElement, boolean> = new WeakMap();
|
|
12
12
|
private elementUrls: WeakMap<HTMLElement, string> = new WeakMap();
|
|
13
13
|
private onUpdate: TextureReadyCallback;
|
|
14
14
|
|
|
15
|
-
constructor(onUpdate: TextureReadyCallback) {
|
|
15
|
+
constructor(onUpdate: TextureReadyCallback, enableCulling: boolean = true) {
|
|
16
16
|
this.onUpdate = onUpdate;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
if (enableCulling) {
|
|
18
|
+
this.observer = new IntersectionObserver(
|
|
19
|
+
(entries) => {
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const el = entry.target as HTMLElement;
|
|
22
|
+
if (entry.isIntersecting) {
|
|
23
|
+
this.loadTexture(el);
|
|
24
|
+
} else {
|
|
25
|
+
this.disposeTexture(el);
|
|
26
|
+
}
|
|
25
27
|
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
},
|
|
29
|
+
{ rootMargin: "300px" },
|
|
30
|
+
);
|
|
31
|
+
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
public register(element: HTMLElement, url: string) {
|
|
@@ -35,13 +37,17 @@ export class TextureLifecycleManager {
|
|
|
35
37
|
if (currentUrl !== url) {
|
|
36
38
|
this.elementUrls.set(element, url);
|
|
37
39
|
// Restart observation to trigger intersecting check
|
|
38
|
-
this.observer
|
|
39
|
-
|
|
40
|
+
if (this.observer) {
|
|
41
|
+
this.observer.unobserve(element);
|
|
42
|
+
this.observer.observe(element);
|
|
43
|
+
} else {
|
|
44
|
+
this.loadTexture(element);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
|
|
43
49
|
public unregister(element: HTMLElement) {
|
|
44
|
-
if (element.nodeType === Node.ELEMENT_NODE) {
|
|
50
|
+
if (element.nodeType === Node.ELEMENT_NODE && this.observer) {
|
|
45
51
|
this.observer.unobserve(element);
|
|
46
52
|
}
|
|
47
53
|
this.disposeTexture(element);
|
|
@@ -118,7 +124,9 @@ export class TextureLifecycleManager {
|
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
public disposeAll() {
|
|
121
|
-
this.observer
|
|
127
|
+
if (this.observer) {
|
|
128
|
+
this.observer.disconnect();
|
|
129
|
+
}
|
|
122
130
|
// Assuming WeakMap handles GC of remaining textures, but in WebGL we must explicitly delete.
|
|
123
131
|
// However, WeakMap is not iterable, so we can't easily iterate and delete.
|
|
124
132
|
// The renderer should unregister nodes upon pendingDeletions.
|