mirage-engine 0.2.17 → 0.2.18

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.
@@ -1,280 +1,639 @@
1
- var k = Object.defineProperty;
2
- var q = (i, e, t) => e in i ? k(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
3
- var c = (i, e, t) => (q(i, typeof e != "symbol" ? e + "" : e, t), t);
4
- import * as d from "three";
5
- const S = 0, z = 1, L = 2, Y = 4, I = 8, N = 16, x = 1, R = 2, W = [
1
+ var de = Object.defineProperty;
2
+ var ue = (i, e, t) => e in i ? de(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
3
+ var u = (i, e, t) => (ue(i, typeof e != "symbol" ? e + "" : e, t), t);
4
+ var se = (i, e, t) => new Promise((s, r) => {
5
+ var a = (c) => {
6
+ try {
7
+ n(t.next(c));
8
+ } catch (l) {
9
+ r(l);
10
+ }
11
+ }, o = (c) => {
12
+ try {
13
+ n(t.throw(c));
14
+ } catch (l) {
15
+ r(l);
16
+ }
17
+ }, n = (c) => c.done ? s(c.value) : Promise.resolve(c.value).then(a, o);
18
+ n((t = t.apply(i, e)).next());
19
+ });
20
+ import * as m from "three";
21
+ const _ = 0, B = 1, N = 2, fe = 4, V = 8, $ = 16, D = 1, X = 2, ge = [
6
22
  "include-tree",
7
23
  "exclude-tree",
8
24
  "include-self",
9
25
  "exclude-self",
10
26
  "end"
11
27
  ];
12
- function U(i, e, t) {
13
- const r = e.split(`
14
- `), s = [];
15
- return r.forEach((a) => {
16
- const n = a.split(" ");
17
- let o = n[0];
18
- for (let l = 1; l < n.length; l++) {
19
- const h = n[l];
20
- i.measureText(o + " " + h).width < t ? o += " " + h : (s.push(o), o = h);
21
- }
22
- s.push(o);
23
- }), s;
28
+ class ne {
29
+ /**
30
+ * Calculates or retrieves the exact alphabetic baseline (in pixels) for the given font.
31
+ * @param font CSS font shorthand string (e.g., "400 16px Inter")
32
+ * @returns Baseline Y offset in pixels
33
+ */
34
+ static getBaseline(e) {
35
+ if (this.cache.has(e))
36
+ return this.cache.get(e);
37
+ const t = this.calculateBaselineFromDOM(e);
38
+ return this.cache.set(e, t), t;
39
+ }
40
+ static calculateBaselineFromDOM(e) {
41
+ if (typeof document == "undefined")
42
+ return 0;
43
+ const t = document.createElement("div"), s = document.createElement("span"), r = document.createElement("img");
44
+ 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", s.style.margin = "0", s.style.padding = "0", s.style.border = "none", s.style.lineHeight = "normal", r.width = 1, r.height = 1, r.style.verticalAlign = "baseline", s.appendChild(document.createTextNode("Hidden Text")), t.appendChild(s), t.appendChild(r), document.body.appendChild(t);
45
+ const a = r.offsetTop - s.offsetTop;
46
+ return document.body.removeChild(t), a;
47
+ }
24
48
  }
25
- function A(i, e, t, r, s = 2) {
26
- const a = document.createElement("canvas"), n = a.getContext("2d");
27
- if (!n)
28
- throw new Error("[Mirage] Failed to create canvas context");
29
- const l = (window.devicePixelRatio || 1) * s;
30
- a.width = t * l, a.height = r * l, n.scale(l, l), n.font = e.font, n.fillStyle = e.color, n.textBaseline = "top", n.globalAlpha = 1;
31
- const h = U(n, i, t), m = e.lineHeight;
32
- h.forEach((g, p) => {
33
- const y = p * m + 2;
34
- let v = 0;
35
- e.textAlign === "center" ? v = t / 2 : e.textAlign === "right" && (v = t), n.textAlign = e.textAlign, n.fillText(g, v, y);
36
- });
37
- const f = new d.CanvasTexture(a);
38
- return f.colorSpace = d.SRGBColorSpace, f.minFilter = d.LinearFilter, f.magFilter = d.LinearFilter, f.needsUpdate = !0, f;
49
+ u(ne, "cache", /* @__PURE__ */ new Map());
50
+ class pe extends m.MeshBasicMaterial {
51
+ constructor(t, s, r, a, o = 2) {
52
+ super({
53
+ transparent: !0,
54
+ side: m.FrontSide,
55
+ color: 16777215
56
+ });
57
+ u(this, "canvas");
58
+ u(this, "ctx");
59
+ u(this, "qualityFactor");
60
+ if (this.canvas = document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), !this.ctx)
61
+ throw new Error("[Mirage] Failed to create canvas context");
62
+ this.qualityFactor = o, this.map = new m.CanvasTexture(this.canvas), this.map.colorSpace = m.LinearSRGBColorSpace, this.map.minFilter = m.LinearFilter, this.map.magFilter = m.LinearFilter, this.updateText(t, s, r, a);
63
+ }
64
+ wrapText(t, s) {
65
+ const r = t.split(`
66
+ `), a = [];
67
+ return r.forEach((o) => {
68
+ const n = o.match(/[^\s\-]+\-?|\-|\s+/g) || [];
69
+ if (n.length === 0) {
70
+ a.push("");
71
+ return;
72
+ }
73
+ let c = n[0];
74
+ for (let l = 1; l < n.length; l++) {
75
+ const d = n[l];
76
+ this.ctx.measureText(c + d).width <= s + 2 ? c += d : (c && a.push(c), c = d.trimStart());
77
+ }
78
+ c && a.push(c);
79
+ }), a;
80
+ }
81
+ updateText(t, s, r, a, o) {
82
+ o !== void 0 && (this.qualityFactor = o);
83
+ const c = (window.devicePixelRatio || 1) * this.qualityFactor, l = r * c, d = a * c;
84
+ 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 = s.font, this.ctx.fillStyle = s.color, this.ctx.textBaseline = "alphabetic", this.ctx.globalAlpha = 1;
85
+ const f = this.wrapText(t, r), h = s.lineHeight, p = ne.getBaseline(s.font);
86
+ f.forEach((g, y) => {
87
+ const x = y * h + p;
88
+ let T = 0;
89
+ s.textAlign === "center" ? T = r / 2 : s.textAlign === "right" && (T = r), this.ctx.textAlign = s.textAlign, this.ctx.fillText(g, T, x);
90
+ }), this.map && (this.map.needsUpdate = !0);
91
+ }
92
+ dispose() {
93
+ this.map && this.map.dispose(), super.dispose();
94
+ }
39
95
  }
40
- function w(i) {
96
+ function F(i) {
41
97
  return typeof i == "number" ? i : parseFloat(i) || 0;
42
98
  }
43
- function X(i, e) {
44
- var o, l, h, m;
45
- if (!e) {
46
- i.set(0, 0, 0, 0);
47
- return;
99
+ function I(i) {
100
+ if (!i || i === "transparent")
101
+ return { color: new m.Color(16777215), alpha: 0 };
102
+ const e = i.match(
103
+ /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
104
+ );
105
+ if (e) {
106
+ const t = parseInt(e[1], 10), s = parseInt(e[2], 10), r = parseInt(e[3], 10), a = e[4] !== void 0 ? parseFloat(e[4]) : 1;
107
+ return { color: new m.Color(`rgb(${t}, ${s}, ${r})`), alpha: a };
108
+ }
109
+ return { color: new m.Color(i), alpha: 1 };
110
+ }
111
+ function me(i) {
112
+ const e = [];
113
+ let t = "", s = 0;
114
+ for (let r = 0; r < i.length; r++) {
115
+ const a = i[r];
116
+ if (a === "(")
117
+ s++;
118
+ else if (a === ")")
119
+ s--;
120
+ else if (a === "," && s === 0) {
121
+ e.push(t.trim()), t = "";
122
+ continue;
123
+ }
124
+ t += a;
125
+ }
126
+ return t && e.push(t.trim()), e;
127
+ }
128
+ function be(i) {
129
+ if (!i || typeof i != "string" || !i.includes("linear-gradient"))
130
+ return null;
131
+ const e = i.match(/linear-gradient\((.*)\)/);
132
+ if (!e)
133
+ return null;
134
+ const t = e[1], s = me(t);
135
+ let r = Math.PI, a = 0;
136
+ const o = s[0].trim();
137
+ if (o.startsWith("to "))
138
+ o === "to top" ? r = 0 : o === "to right" ? r = Math.PI / 2 : o === "to bottom" ? r = Math.PI : o === "to left" ? r = Math.PI * 1.5 : o === "to top right" || o === "to right top" ? r = Math.PI / 4 : o === "to bottom right" || o === "to right bottom" ? r = Math.PI * 0.75 : o === "to bottom left" || o === "to left bottom" ? r = Math.PI * 1.25 : (o === "to top left" || o === "to left top") && (r = Math.PI * 1.75), a = 1;
139
+ else if (o.endsWith("deg") || o.endsWith("rad") || o.endsWith("turn")) {
140
+ const c = parseFloat(o);
141
+ o.endsWith("deg") ? r = c * (Math.PI / 180) : o.endsWith("rad") ? r = c : o.endsWith("turn") && (r = c * Math.PI * 2), a = 1;
142
+ }
143
+ const n = [];
144
+ for (let c = a; c < s.length && !(n.length >= 8); c++) {
145
+ const l = s[c].trim(), d = l.lastIndexOf(" ");
146
+ let f = l, h = null;
147
+ if (d !== -1 && !l.endsWith(")")) {
148
+ const g = l.substring(d + 1);
149
+ (g.endsWith("%") || g.endsWith("px") || !isNaN(parseFloat(g))) && (f = l.substring(0, d).trim(), h = g);
150
+ }
151
+ const p = I(f);
152
+ n.push({
153
+ color: p.color,
154
+ alpha: p.alpha,
155
+ rawStop: h,
156
+ stop: 0
157
+ });
158
+ }
159
+ if (n.length > 0) {
160
+ for (let l = 0; l < n.length; l++)
161
+ n[l].rawStop !== null && (n[l].stop = parseFloat(n[l].rawStop) / 100);
162
+ n[0].rawStop === null && (n[0].stop = 0), n.length > 1 && n[n.length - 1].rawStop === null && (n[n.length - 1].stop = 1);
163
+ let c = 0;
164
+ for (let l = 1; l < n.length; l++)
165
+ if (n[l].rawStop !== null || l === n.length - 1) {
166
+ const d = l - c;
167
+ if (d > 1) {
168
+ const f = n[c].stop, p = (n[l].stop - f) / d;
169
+ for (let g = 1; g < d; g++)
170
+ n[c + g].stop = f + p * g;
171
+ }
172
+ c = l;
173
+ }
48
174
  }
49
- const t = e.split("/")[0].trim().split(/\s+/), r = w(t[0]), s = w((o = t[1]) != null ? o : t[0]), a = w((l = t[2]) != null ? l : t[0]), n = w((m = (h = t[3]) != null ? h : t[1]) != null ? m : t[0]);
50
- i.set(r, s, a, n);
175
+ return { angle: r, stops: n };
51
176
  }
52
- const H = (
53
- /* glsl */
54
- `
55
- varying vec2 vUv;
56
- varying vec4 vScreenPos;
57
- void main() {
58
- vUv = uv;
59
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
60
- vScreenPos = gl_Position;
61
- }
62
- `
63
- ), $ = (
64
- /* glsl */
65
- `
177
+ const xe = `varying vec2 vUv;
178
+ varying vec4 vScreenPos;
179
+ void main() {
180
+ vUv = uv;
181
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
182
+ vScreenPos = gl_Position;
183
+ }`, ve = `varying vec2 vUv;
184
+ uniform vec2 uSize;
185
+ uniform vec4 uBorderRadius;
186
+ uniform float uBorderWidth;
187
+ uniform vec4 uBgColor;
188
+ uniform vec4 uBorderColor;
189
+ uniform float uOpacity;
66
190
 
67
- varying vec2 vUv;
68
-
69
- uniform vec2 uSize;
70
- uniform vec4 uBorderRadius;
71
- uniform float uBorderWidth;
72
- uniform vec3 uBgColor;
73
- uniform vec3 uBorderColor;
74
- uniform float uOpacity;
75
- uniform float uBgOpacity;
76
- uniform float uBorderOpacity;
191
+ uniform int uGradientCount;
192
+ uniform float uGradientAngle;
193
+ uniform vec4 uGradientColors[8];
194
+ uniform float uGradientStops[8];
77
195
 
78
- #INJECT_DECLARATIONS
196
+ #INJECT_DECLARATIONS
79
197
 
80
- float sdRoundedBox(vec2 p, vec2 b, float r) {
81
- vec2 q = abs(p) - b + r;
198
+ vec3 linearToSrgb(vec3 linearColor) {
199
+ vec3 linearPart = 12.92 * linearColor;
200
+ vec3 curvePart = 1.055 * pow(linearColor, vec3(1.0 / 2.4)) - 0.055;
201
+ vec3 switchCondition = step(vec3(0.0031308), linearColor);
202
+ return mix(linearPart, curvePart, switchCondition);
203
+ }
82
204
 
83
- return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
84
- }
205
+ vec3 srgbToLinear(vec3 srgbColor) {
206
+ vec3 linearPart = srgbColor / 12.92;
207
+ vec3 curvePart = pow((srgbColor + vec3(0.055)) / 1.055, vec3(2.4));
208
+ vec3 switchCondition = step(vec3(0.04045), srgbColor);
209
+ return mix(linearPart, curvePart, switchCondition);
210
+ }
85
211
 
86
- void main() {
87
- vec2 p = (vUv - 0.5) * uSize;
88
- vec2 halfSize = uSize * 0.5;
212
+ vec4 blendSrcOverInLinear(vec4 front, vec4 back) {
213
+ front.rgb = srgbToLinear(front.rgb);
214
+ back.rgb = srgbToLinear(back.rgb);
215
+ float aOut = front.a + back.a * (1.0 - front.a);
216
+ float safeAlpha = max(aOut, 0.0001);
217
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
218
+ return vec4(linearToSrgb(cOut), aOut);
219
+ }
89
220
 
90
- #INJECT_UV_MODIFIER
221
+ vec4 blendSrcOver(vec4 front, vec4 back) {
222
+ float aOut = front.a + back.a * (1.0 - front.a);
223
+ float safeAlpha = max(aOut, 0.0001);
224
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
225
+ return vec4(cOut, aOut);
226
+ }
227
+
228
+ float sdRoundedBox(vec2 p, vec2 b, float r) {
229
+ vec2 q = abs(p) - b + r;
230
+ return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
231
+ }
232
+
233
+ float sdVisualBox(vec2 p, vec2 b, float r) {
234
+ vec2 q = abs(p) - b + r;
235
+ float n = 2.01;
236
+ float d = pow(pow(max(q.x, 0.0), n) + pow(max(q.y, 0.0), n), 1.0/n) - r;
237
+ return min(max(q.x, q.y), 0.0) + d;
238
+ }
239
+
240
+ vec4 calculateGradientLayer(vec2 uv) {
241
+ if (uGradientCount < 2) return uGradientColors[0];
242
+
243
+ vec2 dir = vec2(sin(uGradientAngle), cos(uGradientAngle));
244
+ vec2 p = (uv - 0.5) * uSize;
245
+ float proj = dot(p, dir);
246
+ float L = abs(uSize.x * dir.x) + abs(uSize.y * dir.y);
247
+ float t = clamp((proj / L) + 0.5, 0.0, 1.0);
248
+
249
+ vec4 color = uGradientColors[0];
250
+ for (int i = 1; i < 8; i++) {
251
+ if (i >= uGradientCount) break;
252
+ float prevStop = uGradientStops[i-1];
253
+ float currStop = uGradientStops[i];
91
254
 
92
- // color decision pipeline
93
- vec4 baseColor = vec4(uBgColor, uBgOpacity);
255
+ float factor = clamp((t - prevStop) / (currStop - prevStop + 0.00001), 0.0, 1.0);
256
+ color = mix(color, uGradientColors[i], factor);
257
+ }
258
+ // return vec4(linearToSrgb(color.rgb), color.a);
259
+ return vec4(color);
260
+ }
94
261
 
95
- #INJECT_BASE_COLOR
262
+ void main() {
263
+ vec2 p = (vUv - 0.5) * uSize;
264
+ vec2 halfSize = uSize * 0.5;
96
265
 
97
- // sdf shape pipeline
98
- vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
99
- float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
100
- float d = sdRoundedBox(p, halfSize, r);
266
+ #INJECT_UV_MODIFIER
101
267
 
102
- float aa = 1.0;
103
- float bgMask = 1.0 - smoothstep(0.0, aa, d);
268
+ // color decision pipeline
269
+ vec4 baseColor = vec4(uBgColor.rgb, uBgColor.a);
104
270
 
105
- float halfBorder = uBorderWidth * 0.5;
106
- float borderD = abs(d + halfBorder) - halfBorder;
107
- float borderAlpha = (1.0 - smoothstep(0.0, aa, borderD)) * uBorderOpacity;
108
- if (uBorderWidth <= 0.01) {
109
- borderAlpha = 0.0;
110
- }
271
+ if (uGradientCount > 0) {
272
+ vec4 gradColor = calculateGradientLayer(vUv);
273
+ baseColor = blendSrcOver(gradColor, baseColor);
274
+ }
111
275
 
112
- // final blending (border + background)
113
- float aFront = borderAlpha;
114
- float aBack = baseColor.a;
115
- float aOut = aFront + aBack * (1.0 - aFront);
276
+ #INJECT_BASE_COLOR
116
277
 
117
- float safeAlpha = max(aOut, 0.0001);
118
- vec3 cOut = (uBorderColor * aFront + baseColor.rgb * aBack * (1.0 - aFront)) / safeAlpha;
119
- vec4 finalColor = vec4(cOut, aOut);
278
+ // Hybrid SDF
279
+ vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
280
+ float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
281
+ r = min(r, min(halfSize.x, halfSize.y));
120
282
 
121
- // final color control (Tint, Noise)
122
- #INJECT_COLOR_MODIFIER
283
+ float d = sdRoundedBox(p, halfSize, r);
123
284
 
124
- float finalOpacity = finalColor.a * bgMask * uOpacity;
125
- if (finalOpacity < 0.001) discard;
285
+ float d_smooth = sdVisualBox(p, halfSize, r);
286
+ float d_visual = d_smooth / fwidth(d_smooth);
126
287
 
127
- gl_FragColor = vec4(finalColor.rgb, finalOpacity);
288
+ // rendering pipeline
289
+ float bgMask = 1.0 - smoothstep(-0.5, 0.5, d_visual);
128
290
 
129
- #include <colorspace_fragment>
130
- }
131
- `
132
- );
133
- function E(i) {
134
- if (!i || i === "transparent")
135
- return { color: new d.Color(16777215), alpha: 0 };
136
- const e = i.match(
137
- /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
138
- );
139
- if (e) {
140
- const t = parseInt(e[1], 10), r = parseInt(e[2], 10), s = parseInt(e[3], 10), a = e[4] !== void 0 ? parseFloat(e[4]) : 1;
141
- return { color: new d.Color(`rgb(${t}, ${r}, ${s})`), alpha: a };
291
+ float halfBorder = uBorderWidth * 0.5;
292
+ float borderD = abs(d + halfBorder) - halfBorder;
293
+ float borderAlpha = (1.0 - smoothstep(0.0, 1.0, borderD)) * uBorderColor.a;
294
+ if (uBorderWidth <= 0.01) {
295
+ borderAlpha = 0.0;
142
296
  }
143
- return { color: new d.Color(i), alpha: 1 };
297
+
298
+ // final blending (border + background) using blendSrcOver
299
+ vec4 borderLayer = vec4(uBorderColor.rgb, borderAlpha);
300
+ vec4 finalColor = blendSrcOver(borderLayer, baseColor);
301
+ // final color control (Tint, Noise)
302
+ #INJECT_COLOR_MODIFIER
303
+
304
+ float finalOpacity = finalColor.a * bgMask * uOpacity;
305
+ if (finalOpacity < 0.001) discard;
306
+
307
+ gl_FragColor = vec4(finalColor.rgb, finalOpacity);
308
+
309
+
310
+ // #include <colorspace_fragment>
144
311
  }
145
- function G(i, e, t, r = null, s) {
146
- var v;
147
- const a = r !== null, n = a ? (
148
- /* glsl */
149
- `
150
- uniform sampler2D uTexture;
151
- varying vec4 vScreenPos;
152
- `
153
- ) : "", o = a ? (
154
- /* glsl */
155
- `
156
- vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
157
- vec2 resultUv = screenUv;
158
- ${(s == null ? void 0 : s.uvModifier) || ""}
159
- `
160
- ) : "", l = a ? (
161
- /* glsl */
162
- `
163
- baseColor = texture2D(uTexture, resultUv);
164
- `
165
- ) : "", h = (s == null ? void 0 : s.colorModifier) || "", m = $.replace("#INJECT_DECLARATIONS", n).replace("#INJECT_UV_MODIFIER", o).replace("#INJECT_BASE_COLOR", l).replace("#INJECT_COLOR_MODIFIER", h), f = E(i.backgroundColor), g = E(i.borderColor), p = {
166
- uSize: { value: new d.Vector2(e, t) },
167
- uBorderRadius: { value: new d.Vector4(0, 0, 0, 0) },
168
- uBorderWidth: { value: w(i.borderWidth) },
169
- uBgColor: { value: f.color },
170
- uBorderColor: { value: g.color },
171
- uOpacity: { value: (v = i.opacity) != null ? v : 1 },
172
- uBgOpacity: { value: f.alpha },
173
- uBorderOpacity: { value: g.alpha },
174
- uTexture: { value: null }
312
+ `, ye = `uniform sampler2D uTexture;
313
+ varying vec4 vScreenPos;
314
+ uniform vec2 uTextureRepeat;
315
+ uniform vec2 uTextureOffset;`, we = `vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
316
+ vec2 resultUv = screenUv;
317
+
318
+ `, Ce = `vec4 texColor = texture2D(uTexture, resultUv);
319
+ baseColor = blendSrcOver(baseColor, texColor);`, oe = {
320
+ vertexShader: xe,
321
+ fragmentShader: ve
322
+ }, H = {
323
+ declChunk: ye,
324
+ uvChunk: we,
325
+ baseColorChunk: Ce
326
+ };
327
+ function Te(i, e, t, s = null, r) {
328
+ var x;
329
+ const a = s !== null || !!i.imageSrc, o = a ? H.declChunk : "", n = i.isTraveler ? H.uvChunk : `vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
330
+ `, c = a ? n + ((r == null ? void 0 : r.uvModifier) || "") : "", l = a ? H.baseColorChunk : "", d = (r == null ? void 0 : r.colorModifier) || "", f = oe.fragmentShader.replace("#INJECT_DECLARATIONS", o).replace("#INJECT_UV_MODIFIER", c).replace("#INJECT_BASE_COLOR", l).replace("#INJECT_COLOR_MODIFIER", d), h = I(i.backgroundColor), p = I(i.borderColor), g = {
331
+ uSize: { value: new m.Vector2(e, t) },
332
+ uBgColor: {
333
+ value: new m.Vector4(
334
+ h.color.r,
335
+ h.color.g,
336
+ h.color.b,
337
+ h.alpha
338
+ )
339
+ },
340
+ uBorderColor: {
341
+ value: new m.Vector4(
342
+ p.color.r,
343
+ p.color.g,
344
+ p.color.b,
345
+ p.alpha
346
+ )
347
+ },
348
+ uBorderRadius: { value: new m.Vector4(0, 0, 0, 0) },
349
+ uBorderWidth: { value: F(i.borderWidth) },
350
+ uOpacity: { value: (x = i.opacity) != null ? x : 1 },
351
+ uTexture: { value: null },
352
+ uTextureRepeat: { value: new m.Vector2(1, 1) },
353
+ uTextureOffset: { value: new m.Vector2(0, 0) },
354
+ uGradientCount: { value: 0 },
355
+ uGradientAngle: { value: 0 },
356
+ uGradientColors: {
357
+ value: Array.from({ length: 8 }, () => new m.Vector4(0, 0, 0, 0))
358
+ },
359
+ uGradientStops: { value: new Float32Array(8) }
175
360
  };
176
- return X(p.uBorderRadius.value, i.borderRadius), a && (p.uTexture.value = r), new d.ShaderMaterial({
177
- uniforms: p,
178
- vertexShader: H,
179
- fragmentShader: m,
361
+ ae(g.uBorderRadius.value, i.borderRadius), a && (g.uTexture.value = s);
362
+ const y = new m.ShaderMaterial({
363
+ uniforms: g,
364
+ vertexShader: oe.vertexShader,
365
+ fragmentShader: f,
180
366
  transparent: !0,
181
- side: d.FrontSide
367
+ side: m.FrontSide
182
368
  // for better performance
183
369
  });
370
+ return i.backgroundImage && J(y, { backgroundImage: i.backgroundImage }), y;
184
371
  }
185
- function J(i, e, t, r, s) {
186
- var o;
187
- const a = E(e.backgroundColor), n = E(e.borderColor);
188
- i.uniforms.uSize.value.set(t, r), X(i.uniforms.uBorderRadius.value, e.borderRadius), i.uniforms.uBorderWidth.value = w(e.borderWidth), i.uniforms.uBgColor.value.copy(a.color), i.uniforms.uBorderColor.value.copy(n.color), i.uniforms.uOpacity.value = (o = e.opacity) != null ? o : 1, i.uniforms.uBgOpacity.value = a.alpha, i.uniforms.uBorderOpacity.value = n.alpha, i.uniforms.uTexture && s !== void 0 && (i.uniforms.uTexture.value = s);
372
+ function Se(i, e, t, s, r) {
373
+ const a = F(e.borderWidth);
374
+ J(i, {
375
+ width: t,
376
+ height: s,
377
+ borderRadius: e.borderRadius,
378
+ borderWidth: a,
379
+ backgroundColor: e.backgroundColor,
380
+ borderColor: e.borderColor,
381
+ opacity: e.opacity,
382
+ texture: r,
383
+ backgroundImage: e.backgroundImage
384
+ });
189
385
  }
190
- const D = {
191
- create(i, e, t, r, s, a = 2, n = null, o) {
192
- if (i === "BOX")
193
- return G(e, r, s, n, o);
194
- if (i === "TEXT") {
195
- const l = A(
196
- t || "",
197
- e,
198
- r,
199
- s,
200
- a
386
+ function J(i, e) {
387
+ var s, r, a;
388
+ if (e.width !== void 0 && e.height !== void 0 && i.uniforms.uSize.value.set(e.width, e.height), e.borderRadius !== void 0 && ae(i.uniforms.uBorderRadius.value, e.borderRadius), e.borderWidth !== void 0 && (i.uniforms.uBorderWidth.value = e.borderWidth), e.backgroundColor !== void 0)
389
+ if (Array.isArray(e.backgroundColor)) {
390
+ const o = i.uniforms.uBgColor.value.w;
391
+ i.uniforms.uBgColor.value.set(
392
+ e.backgroundColor[0],
393
+ e.backgroundColor[1],
394
+ e.backgroundColor[2],
395
+ o
396
+ );
397
+ } else if (typeof e.backgroundColor == "string") {
398
+ const o = I(e.backgroundColor);
399
+ i.uniforms.uBgColor.value.set(
400
+ o.color.r,
401
+ o.color.g,
402
+ o.color.b,
403
+ o.alpha
404
+ );
405
+ } else {
406
+ const o = i.uniforms.uBgColor.value.w;
407
+ i.uniforms.uBgColor.value.set(
408
+ e.backgroundColor.r,
409
+ e.backgroundColor.g,
410
+ e.backgroundColor.b,
411
+ o
201
412
  );
202
- return new d.MeshBasicMaterial({
203
- map: l,
204
- transparent: !0,
205
- side: d.FrontSide,
206
- color: 16777215
207
- });
208
413
  }
209
- return new d.MeshBasicMaterial({ visible: !1 });
210
- },
211
- update(i, e, t, r, s, a, n = 2, o) {
212
- if (e === "BOX")
213
- J(
214
- i,
215
- t,
216
- s,
217
- a,
414
+ if (e.borderColor !== void 0)
415
+ if (Array.isArray(e.borderColor)) {
416
+ const o = i.uniforms.uBorderColor.value.w;
417
+ i.uniforms.uBorderColor.value.set(
418
+ e.borderColor[0],
419
+ e.borderColor[1],
420
+ e.borderColor[2],
218
421
  o
219
422
  );
220
- else if (e === "TEXT") {
221
- const l = i;
222
- l.map && l.map.dispose();
223
- const h = A(
224
- r || "",
225
- t,
226
- s,
227
- a,
228
- n
423
+ } else if (typeof e.borderColor == "string") {
424
+ const o = I(e.borderColor);
425
+ i.uniforms.uBorderColor.value.set(
426
+ o.color.r,
427
+ o.color.g,
428
+ o.color.b,
429
+ o.alpha
430
+ );
431
+ } else {
432
+ const o = i.uniforms.uBorderColor.value.w;
433
+ i.uniforms.uBorderColor.value.set(
434
+ e.borderColor.r,
435
+ e.borderColor.g,
436
+ e.borderColor.b,
437
+ o
229
438
  );
230
- l.map = h, l.needsUpdate = !0;
231
439
  }
440
+ e.opacity !== void 0 && (i.uniforms.uOpacity.value = e.opacity), e.bgOpacity !== void 0 && (i.uniforms.uBgColor.value.w = e.bgOpacity), e.borderOpacity !== void 0 && (i.uniforms.uBorderColor.value.w = e.borderOpacity), i.uniforms.uTexture && e.texture !== void 0 && (i.uniforms.uTexture.value = e.texture);
441
+ const t = e.texture !== void 0 ? e.texture : (s = i.uniforms.uTexture) == null ? void 0 : s.value;
442
+ if (t && (t.image instanceof ImageBitmap || t.image instanceof HTMLImageElement || t.image instanceof HTMLCanvasElement)) {
443
+ const o = t.image.width, n = t.image.height, c = (r = e.width) != null ? r : i.uniforms.uSize.value.x, l = (a = e.height) != null ? a : i.uniforms.uSize.value.y;
444
+ if (o && n && c && l) {
445
+ const d = o / n, f = c / l;
446
+ if (d > f) {
447
+ const h = f / d;
448
+ i.uniforms.uTextureRepeat.value.set(h, 1), i.uniforms.uTextureOffset.value.set((1 - h) / 2, 0);
449
+ } else {
450
+ const h = d / f;
451
+ i.uniforms.uTextureRepeat.value.set(1, h), i.uniforms.uTextureOffset.value.set(0, (1 - h) / 2);
452
+ }
453
+ }
454
+ } else
455
+ i.uniforms.uTextureRepeat && (i.uniforms.uTextureRepeat.value.set(1, 1), i.uniforms.uTextureOffset.value.set(0, 0));
456
+ if (e.backgroundImage !== void 0) {
457
+ const o = be(e.backgroundImage);
458
+ if (o) {
459
+ i.uniforms.uGradientCount.value = o.stops.length, i.uniforms.uGradientAngle.value = o.angle;
460
+ for (let n = 0; n < 8; n++)
461
+ if (n < o.stops.length) {
462
+ const c = o.stops[n];
463
+ i.uniforms.uGradientColors.value[n].set(
464
+ c.color.r,
465
+ c.color.g,
466
+ c.color.b,
467
+ c.alpha
468
+ ), console.log(c.color.r, c.color.g, c.color.b), i.uniforms.uGradientStops.value[n] = c.stop;
469
+ } else
470
+ i.uniforms.uGradientColors.value[n].set(0, 0, 0, 0), i.uniforms.uGradientStops.value[n] = 1;
471
+ } else
472
+ i.uniforms.uGradientCount.value = 0;
473
+ }
474
+ }
475
+ function ae(i, e) {
476
+ var n, c, l, d;
477
+ if (e == null) {
478
+ i.set(0, 0, 0, 0);
479
+ return;
480
+ }
481
+ if (typeof e == "number") {
482
+ i.set(e, e, e, e);
483
+ return;
484
+ }
485
+ if (Array.isArray(e)) {
486
+ i.set(e[0], e[1], e[2], e[3]);
487
+ return;
488
+ }
489
+ const t = e.split("/")[0].trim().split(/\s+/), s = F(t[0]), r = F((n = t[1]) != null ? n : t[0]), a = F((c = t[2]) != null ? c : t[0]), o = F((d = (l = t[3]) != null ? l : t[1]) != null ? d : t[0]);
490
+ i.set(s, r, a, o);
491
+ }
492
+ const z = {
493
+ create(i, e, t, s, r, a = 2, o = null, n) {
494
+ return i === "BOX" ? Te(
495
+ e,
496
+ s,
497
+ r,
498
+ o,
499
+ n
500
+ ) : i === "TEXT" ? new pe(
501
+ t || "",
502
+ e,
503
+ s,
504
+ r,
505
+ a
506
+ ) : new m.MeshBasicMaterial({ visible: !1 });
507
+ },
508
+ update(i, e, t, s, r, a, o = 2, n) {
509
+ e === "BOX" ? Se(
510
+ i,
511
+ t,
512
+ r,
513
+ a,
514
+ n
515
+ ) : e === "TEXT" && i.updateText(
516
+ s || "",
517
+ t,
518
+ r,
519
+ a,
520
+ o
521
+ );
522
+ },
523
+ forceUpdateUniforms(i, e) {
524
+ J(i, e);
232
525
  }
233
526
  };
234
- class V {
235
- constructor(e, t, r) {
236
- c(this, "canvas");
237
- c(this, "scene");
238
- c(this, "camera");
239
- c(this, "renderer");
240
- c(this, "renderTarget", null);
241
- c(this, "renderOrder", 0);
242
- c(this, "qualityFactor", 2);
243
- c(this, "mode", "overlay");
244
- c(this, "clipArea", 1);
245
- c(this, "target");
246
- c(this, "mountContainer");
247
- c(this, "targetRect");
248
- c(this, "meshMap", /* @__PURE__ */ new Map());
249
- var n, o, l;
250
- this.target = e, this.mountContainer = r, this.mode = (n = t.mode) != null ? n : "overlay", this.clipArea = (o = t.travelerClipArea) != null ? o : 1, this.canvas = document.createElement("canvas"), this.scene = new d.Scene(), this.targetRect = this.target.getBoundingClientRect();
251
- const s = this.targetRect.width, a = this.targetRect.height;
252
- this.camera = new d.OrthographicCamera(
253
- s / -2,
254
- s / 2,
255
- a / 2,
527
+ class Re {
528
+ constructor(e) {
529
+ u(this, "observer");
530
+ u(this, "textures", /* @__PURE__ */ new WeakMap());
531
+ u(this, "loadStatus", /* @__PURE__ */ new WeakMap());
532
+ u(this, "elementUrls", /* @__PURE__ */ new WeakMap());
533
+ u(this, "onUpdate");
534
+ this.onUpdate = e, this.observer = new IntersectionObserver(
535
+ (t) => {
536
+ for (const s of t) {
537
+ const r = s.target;
538
+ s.isIntersecting ? this.loadTexture(r) : this.disposeTexture(r);
539
+ }
540
+ },
541
+ { rootMargin: "300px" }
542
+ );
543
+ }
544
+ register(e, t) {
545
+ if (e.nodeType !== Node.ELEMENT_NODE)
546
+ return;
547
+ this.elementUrls.get(e) !== t && (this.elementUrls.set(e, t), this.observer.unobserve(e), this.observer.observe(e));
548
+ }
549
+ unregister(e) {
550
+ e.nodeType === Node.ELEMENT_NODE && this.observer.unobserve(e), this.disposeTexture(e), this.elementUrls.delete(e), this.loadStatus.delete(e);
551
+ }
552
+ loadTexture(e) {
553
+ return se(this, null, function* () {
554
+ if (this.loadStatus.get(e) || this.textures.has(e))
555
+ return;
556
+ const t = this.elementUrls.get(e);
557
+ if (t) {
558
+ this.loadStatus.set(e, !0);
559
+ try {
560
+ const r = yield (yield fetch(t)).blob(), a = yield createImageBitmap(r, { imageOrientation: "flipY" });
561
+ if (this.elementUrls.get(e) !== t) {
562
+ a.close();
563
+ return;
564
+ }
565
+ const o = new m.CanvasTexture(a);
566
+ o.needsUpdate = !0, this.textures.set(e, o), this.onUpdate(e, o);
567
+ } catch (s) {
568
+ console.warn("[MirageEngine] Failed to load texture:", t, s);
569
+ } finally {
570
+ this.elementUrls.has(e) && this.loadStatus.set(e, !1);
571
+ }
572
+ }
573
+ });
574
+ }
575
+ disposeTexture(e) {
576
+ const t = this.textures.get(e);
577
+ t && (t.dispose(), this.textures.delete(e), this.onUpdate(e, null)), this.loadStatus.set(e, !1);
578
+ }
579
+ get(e) {
580
+ return this.textures.get(e);
581
+ }
582
+ disposeAll() {
583
+ this.observer.disconnect();
584
+ }
585
+ }
586
+ class Me {
587
+ constructor(e, t, s, r) {
588
+ u(this, "canvas");
589
+ u(this, "scene");
590
+ u(this, "camera");
591
+ u(this, "renderer");
592
+ u(this, "renderTarget", null);
593
+ u(this, "renderOrder", 0);
594
+ u(this, "qualityFactor", 2);
595
+ u(this, "mode", "overlay");
596
+ u(this, "clipArea", 1);
597
+ u(this, "target");
598
+ u(this, "mountContainer");
599
+ u(this, "registry");
600
+ u(this, "targetRect");
601
+ u(this, "travelers", /* @__PURE__ */ new Set());
602
+ u(this, "textureManager");
603
+ // private meshMap: Map<HTMLElement, THREE.Mesh> = new Map();
604
+ u(this, "fixedMeshes", /* @__PURE__ */ new Set());
605
+ var n, c, l;
606
+ this.target = e, this.mountContainer = s, this.registry = r, this.textureManager = new Re((d, f) => {
607
+ const h = this.registry.get(d);
608
+ h && h.material instanceof m.ShaderMaterial && z.forceUpdateUniforms(h.material, { texture: f });
609
+ }), this.mode = (n = t.mode) != null ? n : "overlay", this.clipArea = (c = t.travelerClipArea) != null ? c : 1, this.canvas = document.createElement("canvas"), this.scene = new m.Scene(), this.targetRect = this.target.getBoundingClientRect();
610
+ const a = this.targetRect.width, o = this.targetRect.height;
611
+ this.camera = new m.OrthographicCamera(
256
612
  a / -2,
613
+ a / 2,
614
+ o / 2,
615
+ o / -2,
257
616
  1,
258
617
  1e3
259
- ), this.camera.position.z = 100, this.camera.layers.set(0), this.renderer = new d.WebGLRenderer({
618
+ ), this.camera.position.z = 100, this.camera.layers.set(0), this.renderer = new m.WebGLRenderer({
260
619
  canvas: this.canvas,
261
620
  alpha: !0,
262
621
  antialias: !0
263
622
  // [new]
264
623
  // premultipliedAlpha: true
265
- }), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setSize(s, a), this.applyTextQuality((l = t.quality) != null ? l : "medium");
624
+ }), m.ColorManagement.enabled = !1, this.renderer.outputColorSpace = m.LinearSRGBColorSpace, this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setSize(a, o), this.applyTextQuality((l = t.quality) != null ? l : "medium");
266
625
  }
267
626
  createRenderTarget() {
268
- this.renderTarget = new d.WebGLRenderTarget(
627
+ this.renderTarget = new m.WebGLRenderTarget(
269
628
  this.targetRect.width * this.qualityFactor,
270
629
  this.targetRect.height * this.qualityFactor,
271
630
  {
272
- minFilter: d.LinearFilter,
273
- magFilter: d.LinearFilter,
274
- format: d.RGBAFormat,
631
+ minFilter: m.LinearFilter,
632
+ magFilter: m.LinearFilter,
633
+ format: m.RGBAFormat,
275
634
  stencilBuffer: !1,
276
- depthBuffer: !0,
277
- samples: 4
635
+ depthBuffer: !0
636
+ // samples: 0.7,
278
637
  }
279
638
  );
280
639
  }
@@ -303,7 +662,7 @@ class V {
303
662
  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");
304
663
  }
305
664
  dispose() {
306
- this.renderer.dispose(), this.canvas.remove();
665
+ this.renderer.dispose(), this.canvas.remove(), this.textureManager.disposeAll();
307
666
  }
308
667
  setSize(e, t) {
309
668
  this.renderer.setSize(e, t), this.renderTarget && this.renderTarget.setSize(
@@ -311,73 +670,95 @@ class V {
311
670
  t * this.qualityFactor
312
671
  ), this.camera.left = e / -2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = t / -2, this.camera.updateProjectionMatrix();
313
672
  }
314
- syncScene(e) {
315
- const t = this.target.getBoundingClientRect(), r = Math.abs(t.width - this.targetRect.width) > 0.1 || Math.abs(t.height - this.targetRect.height) > 0.1, s = this.mode === "overlay" && (Math.abs(t.top - this.targetRect.top) > 0.1 || Math.abs(t.left - this.targetRect.left) > 0.1);
316
- r ? (this.targetRect = t, this.setSize(this.targetRect.width, this.targetRect.height), this.updateCanvasLayout()) : s ? (this.targetRect = t, this.updateCanvasLayout()) : this.targetRect = t, this.renderOrder = 0;
317
- const a = /* @__PURE__ */ new Set();
318
- this.reconcileNode(e, a);
319
- for (const [n, o] of this.meshMap.entries())
320
- a.has(n) || (this.scene.remove(o), o.geometry.dispose(), o.material instanceof d.Material && o.material.dispose(), this.meshMap.delete(n));
673
+ syncScene(e, t) {
674
+ const s = this.target.getBoundingClientRect(), r = Math.abs(s.width - this.targetRect.width) > 0.1 || Math.abs(s.height - this.targetRect.height) > 0.1, a = this.mode === "overlay" && (Math.abs(s.top - this.targetRect.top) > 0.1 || Math.abs(s.left - this.targetRect.left) > 0.1);
675
+ r ? (this.targetRect = s, this.setSize(this.targetRect.width, this.targetRect.height), this.updateCanvasLayout()) : a ? (this.targetRect = s, this.updateCanvasLayout()) : this.targetRect = s, this.renderOrder = 0, this.reconcileNode(e), t.size > 0 && t.forEach((o) => {
676
+ const n = this.registry.get(o);
677
+ n && (this.scene.remove(n), this.travelers.delete(n), this.fixedMeshes.delete(n), n.geometry.dispose(), n.traverse((c) => {
678
+ c instanceof m.Mesh && (c.geometry && c.geometry.dispose(), c.material && (Array.isArray(c.material) ? c.material.forEach((l) => l.dispose()) : c.material.dispose()));
679
+ }), this.registry.remove(o), this.textureManager.unregister(o));
680
+ });
321
681
  }
322
- reconcileNode(e, t) {
682
+ // 탐색 후 완성된 Scene node를 이용하여 mesh를 만들거나 조정
683
+ // => 이 과정에서 scene node에 있는 ele를 넣은 hash => activeElements
684
+ // => 이후 activeElements를 이용하여 mesh를 정리!!!+ map에서도 삭제
685
+ // private reconcileNode(node: SceneNode, activeElements: Set<HTMLElement>) {
686
+ reconcileNode(e) {
323
687
  var s;
324
- t.add(e.element);
325
- let r = this.meshMap.get(e.element);
326
- if (!r) {
327
- const a = new d.PlaneGeometry(1, 1);
328
- let n;
329
- n = D.create(
688
+ let t = this.registry.get(e.element);
689
+ if (!t) {
690
+ const r = new m.PlaneGeometry(1, 1);
691
+ let a;
692
+ const o = e.isTraveler ? (s = this.renderTarget) == null ? void 0 : s.texture : this.textureManager.get(e.element);
693
+ a = z.create(
330
694
  "BOX",
331
695
  e.styles,
332
696
  "",
333
697
  e.rect.width,
334
698
  e.rect.height,
335
699
  this.qualityFactor,
336
- e.isTraveler ? (s = this.renderTarget) == null ? void 0 : s.texture : void 0,
700
+ o,
337
701
  e.shaderHooks
338
- ), r = new d.Mesh(a, n), e.type === "TEXT" && (r.name = "BG_MESH"), this.scene.add(r), this.meshMap.set(e.element, r);
702
+ ), t = new m.Mesh(r, a), e.type === "TEXT" && (t.name = "BG_MESH"), this.scene.add(t), this.registry.register(e.element, t);
339
703
  }
340
- if (r.userData.domRect = e.rect, this.updateMeshProperties(r, e), this.updateMeshLayers(r, e), e.isTraveler && r.layers.enable(28), e.type === "BOX")
341
- for (const a of e.children)
342
- this.reconcileNode(a, t);
704
+ if (t.userData.domRect = e.rect, this.updateMeshProperties(t, e), this.updateMeshLayers(t, e), e.isTraveler ? (t.layers.enable(28), this.travelers.add(t)) : (t.layers.disable(28), this.travelers.delete(t)), 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")
705
+ for (const r of e.children)
706
+ this.reconcileNode(r);
343
707
  else
344
- e.type === "TEXT" && this.reconcileTextChild(r, e);
708
+ e.type === "TEXT" && this.reconcileTextChild(t, e);
345
709
  }
346
710
  reconcileTextChild(e, t) {
347
- var o, l;
348
- let r = e.children.find(
349
- (h) => h.name === "TEXT_CHILD"
350
- );
351
- const s = JSON.stringify(t.textStyles), a = (o = r == null ? void 0 : r.userData) == null ? void 0 : o.styleHash;
352
- if (!r || t.dirtyMask & N || s !== a) {
353
- r && ((l = r.material.map) == null || l.dispose(), r.geometry.dispose(), e.remove(r));
354
- const h = D.create(
355
- "TEXT",
356
- t.textStyles,
357
- t.textContent || "",
358
- t.rect.width,
359
- t.rect.height,
360
- this.qualityFactor
361
- ), m = new d.PlaneGeometry(1, 1);
362
- r = new d.Mesh(m, h), r.name = "TEXT_CHILD", r.userData = { styleHash: s }, this.updateMeshLayers(r, t), r.position.z = 5e-3, e.add(r);
363
- }
364
- if (r) {
365
- const h = e.userData.domRect, m = h.x + h.width / 2, f = h.y + h.height / 2, g = t.rect.x + t.rect.width / 2, p = t.rect.y + t.rect.height / 2, y = g - m, v = -(p - f);
366
- r.position.set(y, v, 5e-3);
711
+ var n;
712
+ const s = t.textLines || [{ text: t.textContent || "", rect: t.rect }], r = JSON.stringify(t.textStyles) + t.textContent + s.map((c) => c.text).join("|"), a = (n = e.userData) == null ? void 0 : n.textChildStyleHash;
713
+ if (t.dirtyMask & $ || r !== a) {
714
+ e.children.filter((h) => h.name.startsWith("TEXT_CHILD")).forEach((h) => {
715
+ var g;
716
+ const p = h;
717
+ (g = p.material.map) == null || g.dispose(), p.geometry.dispose(), e.remove(p);
718
+ });
719
+ const l = t.rect, d = l.x + l.width / 2, f = l.y + l.height / 2;
720
+ s.forEach((h, p) => {
721
+ const g = z.create(
722
+ "TEXT",
723
+ t.textStyles,
724
+ h.text,
725
+ h.rect.width,
726
+ h.rect.height,
727
+ this.qualityFactor
728
+ ), y = new m.PlaneGeometry(1, 1), x = new m.Mesh(y, g);
729
+ x.name = `TEXT_CHILD_${p}`, this.updateMeshLayers(x, t);
730
+ const T = t.rect.width === 0 ? 1 : h.rect.width / t.rect.width, S = t.rect.height === 0 ? 1 : h.rect.height / t.rect.height;
731
+ x.scale.set(T, S, 1);
732
+ const M = h.rect.x + h.rect.width / 2, E = h.rect.y + h.rect.height / 2, b = M - d, w = -(E - f);
733
+ x.position.set(
734
+ t.rect.width === 0 ? 0 : b / t.rect.width,
735
+ t.rect.height === 0 ? 0 : w / t.rect.height,
736
+ 5e-3
737
+ ), e.add(x);
738
+ }), e.userData.textChildStyleHash = r;
367
739
  }
368
740
  }
369
741
  updateMeshProperties(e, t) {
370
- var p;
371
- const { rect: r, styles: s } = t, a = this.renderer.getPixelRatio(), n = this.renderer.domElement.width / a, o = this.renderer.domElement.height / a;
372
- e.scale.set(r.width, r.height, 1);
373
- const l = 1e-3;
742
+ var b;
743
+ const { rect: s, styles: r } = t, a = this.renderer.getPixelRatio(), o = this.renderer.domElement.width / a, n = this.renderer.domElement.height / a;
744
+ e.scale.set(s.width, s.height, 1);
745
+ const c = 1e-3;
374
746
  this.renderOrder++;
375
- const h = this.targetRect.left + window.scrollX, m = this.targetRect.top + window.scrollY, f = r.x - h, g = r.y - m;
747
+ const l = this.targetRect.left + window.scrollX, d = this.targetRect.top + window.scrollY, f = s.x - l, h = s.y - d, p = f - o / 2 + s.width / 2, g = -h + n / 2 - s.height / 2;
376
748
  e.position.set(
377
- f - n / 2 + r.width / 2,
378
- -g + o / 2 - r.height / 2,
379
- s.zIndex + this.renderOrder * l
380
- ), D.update(
749
+ p,
750
+ g,
751
+ r.zIndex + this.renderOrder * c
752
+ );
753
+ const y = s.x, x = s.y;
754
+ e.userData.basePosition = { x: p, y: g }, e.userData.originalBasePosition = { x: p, y: g }, e.userData.baseSize = { width: s.width, height: s.height }, e.userData.baseDOM = { x: y, y: x }, e.userData.isFixed = t.isFixed, e.userData.initialScroll = { x: window.scrollX, y: window.scrollY };
755
+ const T = t.element.nodeType === Node.TEXT_NODE ? t.element.parentElement : t.element, S = window.getComputedStyle(T);
756
+ let M = 0, E = 0;
757
+ if (S.transform && S.transform !== "none") {
758
+ const w = new DOMMatrix(S.transform);
759
+ M = w.m41, E = w.m42;
760
+ }
761
+ e.userData.baseTransform = { x: M, y: E }, delete e.userData.originRatioX, delete e.userData.originRatioY, z.update(
381
762
  e.material,
382
763
  "BOX",
383
764
  t.styles,
@@ -385,31 +766,28 @@ class V {
385
766
  t.rect.width,
386
767
  t.rect.height,
387
768
  this.qualityFactor,
388
- t.isTraveler ? (p = this.renderTarget) == null ? void 0 : p.texture : void 0
769
+ t.isTraveler ? (b = this.renderTarget) == null ? void 0 : b.texture : this.textureManager.get(t.element)
389
770
  );
390
771
  }
391
772
  updateMeshLayers(e, t) {
392
- const r = (1 - (t.visibility & x)) * 30;
393
- e.layers.set(r), t.visibility === (x | R) && e.layers.enable(29);
773
+ const s = (1 - (t.visibility & D)) * 30;
774
+ e.layers.set(s), t.visibility === (D | X) && e.layers.enable(29);
394
775
  }
395
776
  captureRenderTarget() {
396
- const e = [];
397
- for (const l of this.meshMap.values())
398
- l.layers.mask & 1 << 28 && e.push(l);
399
- if (e.length === 0)
777
+ if (this.travelers.size === 0)
400
778
  return;
401
- const t = new d.Color(), r = this.renderer.getClearAlpha();
402
- this.renderer.getClearColor(t), this.renderer.setClearColor(0, 0), this.renderer.setRenderTarget(this.renderTarget), this.renderer.clear(), this.renderer.autoClear = !1, this.renderer.setScissorTest(!0), this.camera.layers.set(29);
403
- const s = new d.Vector3(), a = this.targetRect.width, n = this.targetRect.height, o = this.renderer.getPixelRatio();
404
- for (const l of e) {
405
- s.setFromMatrixPosition(l.matrixWorld), s.project(this.camera);
406
- const h = (s.x + 1) / 2 * a, m = (s.y + 1) / 2 * n;
407
- let f = 0, g = 1;
408
- typeof this.clipArea == "number" ? g = this.clipArea : this.clipArea.endsWith("%") ? g = parseFloat(this.clipArea) / 100 : this.clipArea.endsWith("px") && (f = parseFloat(this.clipArea));
409
- const p = l.scale.x * g + 0.5, y = l.scale.y * g + 0.5, v = h - p / 2, B = m - y / 2, M = (v * this.qualityFactor - f) / o, F = (B * this.qualityFactor - f) / o, b = (p * this.qualityFactor + f * 2) / o, u = (y * this.qualityFactor + f * 2) / o;
410
- this.renderer.setScissor(M, F, b, u), this.renderer.render(this.scene, this.camera);
779
+ const e = new m.Color(), t = this.renderer.getClearAlpha();
780
+ this.renderer.getClearColor(e), this.renderer.setClearColor(0, 0), this.renderer.setRenderTarget(this.renderTarget), this.renderer.clear(), this.renderer.autoClear = !1, this.renderer.setScissorTest(!0), this.camera.layers.set(29);
781
+ const s = new m.Vector3(), r = this.targetRect.width, a = this.targetRect.height, o = this.renderer.getPixelRatio();
782
+ for (const n of this.travelers) {
783
+ s.setFromMatrixPosition(n.matrixWorld), s.project(this.camera);
784
+ const c = (s.x + 1) / 2 * r, l = (s.y + 1) / 2 * a;
785
+ let d = 0, f = 1;
786
+ typeof this.clipArea == "number" ? f = this.clipArea : this.clipArea.endsWith("%") ? f = parseFloat(this.clipArea) / 100 : this.clipArea.endsWith("px") && (d = parseFloat(this.clipArea));
787
+ const h = n.scale.x * f + 0.5, p = n.scale.y * f + 0.5, g = c - h / 2, y = l - p / 2, x = (g * this.qualityFactor - d) / o, T = (y * this.qualityFactor - d) / o, S = (h * this.qualityFactor + d * 2) / o, M = (p * this.qualityFactor + d * 2) / o;
788
+ this.renderer.setScissor(x, T, S, M), this.renderer.render(this.scene, this.camera);
411
789
  }
412
- this.renderer.setScissorTest(!1), this.renderer.autoClear = !0, this.renderer.setRenderTarget(null), this.camera.layers.set(28), this.renderer.setClearColor(t, r);
790
+ this.renderer.setScissorTest(!1), this.renderer.autoClear = !0, this.renderer.setRenderTarget(null), this.camera.layers.set(0), this.renderer.setClearColor(e, t);
413
791
  }
414
792
  render() {
415
793
  this.renderTarget && this.captureRenderTarget(), this.renderer.render(this.scene, this.camera);
@@ -418,170 +796,302 @@ class V {
418
796
  showScissoredRenderTarget() {
419
797
  if (!this.renderTarget)
420
798
  return;
421
- const e = this.targetRect.width, t = this.targetRect.height, r = new d.PlaneGeometry(e, t), s = new d.MeshBasicMaterial({
799
+ const e = this.targetRect.width, t = this.targetRect.height, s = new m.PlaneGeometry(e, t), r = new m.MeshBasicMaterial({
422
800
  map: this.renderTarget.texture,
423
- side: d.DoubleSide,
801
+ side: m.DoubleSide,
424
802
  transparent: !0,
425
803
  opacity: 0.8
426
- }), a = new d.Mesh(r, s);
804
+ }), a = new m.Mesh(s, r);
427
805
  a.position.set(0, 0, 90), a.layers.set(28), this.scene.add(a);
428
806
  }
429
807
  }
430
- function j(i) {
431
- const e = document.createRange();
432
- e.selectNodeContents(i);
433
- const t = e.getBoundingClientRect();
434
- return {
435
- left: t.left,
436
- top: t.top,
437
- width: t.width,
438
- height: t.height
439
- };
808
+ function Ee(i) {
809
+ const e = i.textContent || "", t = [];
810
+ let s = "", r = null, a = -1;
811
+ const o = (l, d) => {
812
+ for (let f = 0; f < l.length; f++) {
813
+ const h = l[f], p = document.createRange();
814
+ p.setStart(i, d + f), p.setEnd(i, d + f + 1);
815
+ const g = p.getBoundingClientRect();
816
+ if (g.width === 0 && g.height === 0) {
817
+ s += h;
818
+ continue;
819
+ }
820
+ a === -1 || Math.abs(g.top - a) > g.height / 2 ? (s && r && t.push({
821
+ text: s,
822
+ rect: {
823
+ left: r.left,
824
+ top: r.top,
825
+ width: r.right - r.left,
826
+ height: r.bottom - r.top
827
+ }
828
+ }), s = h, r = { left: g.left, top: g.top, right: g.right, bottom: g.bottom }, a = g.top) : (s += h, r && (r.left = Math.min(r.left, g.left), r.top = Math.min(r.top, g.top), r.right = Math.max(r.right, g.right), r.bottom = Math.max(r.bottom, g.bottom)));
829
+ }
830
+ }, n = e.match(/[^\s\-]+\-?|\-|\s+/g) || [];
831
+ let c = 0;
832
+ for (const l of n) {
833
+ const d = document.createRange();
834
+ d.setStart(i, c), d.setEnd(i, c + l.length);
835
+ const f = d.getClientRects();
836
+ if (f.length > 1)
837
+ o(l, c);
838
+ else {
839
+ const h = f.length === 1 ? f[0] : d.getBoundingClientRect();
840
+ if (h.width === 0 && h.height === 0) {
841
+ s += l, c += l.length;
842
+ continue;
843
+ }
844
+ a === -1 || Math.abs(h.top - a) > h.height / 2 ? (s && r && t.push({
845
+ text: s,
846
+ rect: {
847
+ left: r.left,
848
+ top: r.top,
849
+ width: r.right - r.left,
850
+ height: r.bottom - r.top
851
+ }
852
+ }), s = l, r = { left: h.left, top: h.top, right: h.right, bottom: h.bottom }, a = h.top) : (s += l, r && (r.left = Math.min(r.left, h.left), r.top = Math.min(r.top, h.top), r.right = Math.max(r.right, h.right), r.bottom = Math.max(r.bottom, h.bottom)));
853
+ }
854
+ c += l.length;
855
+ }
856
+ return s && r && t.push({
857
+ text: s,
858
+ rect: {
859
+ left: r.left,
860
+ top: r.top,
861
+ width: r.right - r.left,
862
+ height: r.bottom - r.top
863
+ }
864
+ }), t.filter((l) => l.text.trim().length > 0 && l.rect.width > 0 && l.rect.height > 0);
440
865
  }
441
- function Q(i) {
866
+ function De(i) {
442
867
  const e = parseFloat(i.fontSize);
443
868
  let t = parseFloat(i.lineHeight);
444
869
  isNaN(t) && (t = e * 1.2);
445
- let r = parseFloat(i.letterSpacing);
446
- return isNaN(r) && (r = 0), {
870
+ let s = parseFloat(i.letterSpacing);
871
+ return isNaN(s) && (s = 0), {
447
872
  font: `${i.fontStyle} ${i.fontWeight} ${i.fontSize} ${i.fontFamily}`,
873
+ fontSize: i.fontSize,
448
874
  color: i.color,
449
875
  textAlign: i.textAlign || "start",
450
876
  textBaseline: "alphabetic",
451
877
  direction: i.direction || "inherit",
452
878
  lineHeight: t,
453
- letterSpacing: r
879
+ letterSpacing: s
454
880
  };
455
881
  }
456
- function P(i, e = z | L | Y | N | I, t, r) {
882
+ function ce(i, e = B | N | fe | $ | V, t, s) {
457
883
  if (i.nodeType === Node.TEXT_NODE) {
458
- const u = i;
459
- if (!u.textContent || !u.textContent.trim())
884
+ const b = i;
885
+ if (!b.textContent || !b.textContent.trim())
460
886
  return null;
461
- const C = u.textContent.replace(/\s+/g, " ").trim();
462
- if (C.length === 0)
887
+ const w = b.textContent.replace(/\s+/g, " ");
888
+ if (w.length === 0)
463
889
  return null;
464
- const T = j(u);
465
- if (T.width === 0 || T.height === 0)
890
+ const R = Ee(b);
891
+ if (R.length === 0)
466
892
  return null;
467
- const _ = u.parentElement, O = _ ? window.getComputedStyle(_) : null;
468
- return O ? {
893
+ const k = b.parentElement, O = k ? window.getComputedStyle(k) : null;
894
+ if (!O)
895
+ return null;
896
+ const A = Math.min(...R.map((v) => v.rect.left)), L = Math.min(...R.map((v) => v.rect.top)), P = Math.max(...R.map((v) => v.rect.left + v.rect.width)), Y = Math.max(...R.map((v) => v.rect.top + v.rect.height));
897
+ return {
469
898
  id: Math.random().toString(36).substring(2, 9),
470
899
  type: "TEXT",
471
- element: u,
900
+ element: b,
472
901
  rect: {
473
- x: T.left + window.scrollX,
474
- y: T.top + window.scrollY,
475
- width: T.width,
476
- height: T.height
902
+ x: A + window.scrollX,
903
+ y: L + window.scrollY,
904
+ width: P - A,
905
+ height: Y - L
477
906
  },
478
907
  styles: {
479
908
  backgroundColor: "transparent",
480
- opacity: parseFloat(O.opacity),
909
+ backgroundImage: "",
910
+ opacity: k && k.dataset.mirageDom === "hide" ? 1 : parseFloat(O.opacity),
481
911
  zIndex: 0,
482
912
  borderRadius: "0px",
483
913
  borderColor: "transparent",
484
- borderWidth: "0px"
914
+ borderWidth: "0px",
915
+ isTraveler: !1
485
916
  },
486
- textContent: C,
487
- textStyles: Q(O),
917
+ textContent: w,
918
+ textLines: R.map((v) => ({
919
+ text: v.text.trim(),
920
+ rect: {
921
+ x: v.rect.left + window.scrollX,
922
+ y: v.rect.top + window.scrollY,
923
+ width: v.rect.width,
924
+ height: v.rect.height
925
+ }
926
+ })),
927
+ textStyles: De(O),
488
928
  dirtyMask: e,
489
929
  visibility: t,
490
930
  isTraveler: !1,
931
+ isFixed: O.position === "fixed",
491
932
  children: []
492
- } : null;
933
+ };
493
934
  }
494
- const s = i, a = s.dataset.mirageFilter;
495
- let n = t, o = t;
935
+ if (i.nodeType !== Node.ELEMENT_NODE)
936
+ return null;
937
+ const r = i, a = r.dataset.mirageFilter;
938
+ let o = t, n = t;
496
939
  if (a) {
497
- const u = new Set(a.split(/\s+/));
498
- for (const C of u)
499
- if (!W.includes(C))
940
+ const b = new Set(a.split(/\s+/));
941
+ for (const w of b)
942
+ if (!ge.includes(w))
500
943
  throw new Error(
501
- `[MirageEngine] Invalid filter token: '${C}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
944
+ `[MirageEngine] Invalid filter token: '${w}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
502
945
  );
503
- if (u.has("end"))
946
+ if (b.has("end"))
504
947
  return null;
505
- if (u.has("include-tree") && u.has("exclude-tree"))
948
+ if (b.has("include-tree") && b.has("exclude-tree"))
506
949
  throw new Error(
507
950
  "[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element."
508
951
  );
509
- if (u.has("include-self") && u.has("exclude-self"))
952
+ if (b.has("include-self") && b.has("exclude-self"))
510
953
  throw new Error(
511
954
  "[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element."
512
955
  );
513
- u.has("include-tree") ? n = n | x : u.has("exclude-tree") && (n = n & ~x), o = n, u.has("include-self") ? o = o | x : u.has("exclude-self") && (o = o & ~x);
956
+ b.has("include-tree") ? o = o | D : b.has("exclude-tree") && (o = o & ~D), n = o, b.has("include-self") ? n = n | D : b.has("exclude-self") && (n = n & ~D);
514
957
  }
515
- o = o | t & R;
516
- const l = s.dataset.mirageTravel;
517
- let h = !1;
518
- l && new Set(l.split(/\s+/)).has("traveler") && (o = o & ~R, n = n & ~R, h = !0);
519
- const m = s.dataset.mirageShader;
958
+ n = n | t & X;
959
+ const c = r.dataset.mirageTravel;
960
+ let l = !1;
961
+ c && new Set(c.split(/\s+/)).has("traveler") && (n = n & ~X, o = o & ~X, l = !0);
962
+ const d = r.dataset.mirageShader;
520
963
  let f;
521
- m && (f = JSON.parse(m));
522
- const g = s.getBoundingClientRect(), p = window.getComputedStyle(s);
523
- if (g.width === 0 || g.height === 0 || p.display === "none")
964
+ d && (f = JSON.parse(d));
965
+ const h = r.getBoundingClientRect(), p = window.getComputedStyle(r);
966
+ if (h.width === 0 || h.height === 0 || p.display === "none")
524
967
  return null;
525
- let y = s.getAttribute("data-mid");
526
- y || (y = Math.random().toString(36).substring(2, 11), s.setAttribute("data-mid", y));
527
- const v = parseInt(p.zIndex), B = {
968
+ let g = r.getAttribute("data-mid");
969
+ g || (g = Math.random().toString(36).substring(2, 11), r.setAttribute("data-mid", g));
970
+ const y = parseInt(p.zIndex);
971
+ let x;
972
+ if (r.tagName === "IMG")
973
+ x = r.src;
974
+ else if (p.backgroundImage && p.backgroundImage !== "none") {
975
+ const b = p.backgroundImage.match(/url\(['"]?(.*?)['"]?\)/);
976
+ b && (x = b[1]);
977
+ }
978
+ const T = {
528
979
  backgroundColor: p.backgroundColor,
529
- opacity: parseFloat(p.opacity),
530
- zIndex: isNaN(v) ? 0 : v,
980
+ backgroundImage: p.backgroundImage,
981
+ opacity: r.dataset.mirageDom === "hide" ? 1 : parseFloat(p.opacity),
982
+ zIndex: isNaN(y) ? 0 : y,
531
983
  borderRadius: p.borderRadius,
532
984
  borderColor: p.borderColor,
533
- borderWidth: p.borderWidth
985
+ borderWidth: p.borderWidth,
986
+ imageSrc: x,
987
+ isTraveler: l
534
988
  };
535
- let M, F;
536
- const b = [];
537
- return Array.from(s.childNodes).forEach((u) => {
538
- const C = u.nodeType === Node.TEXT_NODE ? o : n, T = P(
539
- u,
989
+ let S, M;
990
+ const E = [];
991
+ return Array.from(r.childNodes).forEach((b) => {
992
+ const w = b.nodeType === Node.TEXT_NODE ? n : o, R = ce(
993
+ b,
540
994
  e,
541
- C
995
+ w
542
996
  );
543
- T && b.push(T);
997
+ R && E.push(R);
544
998
  }), {
545
- id: y,
999
+ id: g,
546
1000
  type: "BOX",
547
- element: s,
1001
+ element: r,
548
1002
  rect: {
549
- x: g.left + window.scrollX,
550
- y: g.top + window.scrollY,
551
- width: g.width,
552
- height: g.height
1003
+ x: h.left + window.scrollX,
1004
+ y: h.top + window.scrollY,
1005
+ width: h.width,
1006
+ height: h.height
553
1007
  },
554
- styles: B,
555
- textContent: M,
556
- textStyles: F,
1008
+ styles: T,
1009
+ textContent: S,
1010
+ textStyles: M,
557
1011
  dirtyMask: e,
558
- visibility: o,
559
- isTraveler: h,
560
- children: b,
1012
+ visibility: n,
1013
+ isTraveler: l,
1014
+ isFixed: p.position === "fixed",
1015
+ children: E,
561
1016
  shaderHooks: f
562
1017
  };
563
1018
  }
564
- class Z {
565
- constructor(e, t, r) {
566
- c(this, "target");
567
- c(this, "renderer");
568
- c(this, "filter");
569
- c(this, "observer");
570
- c(this, "isDomDirty", !1);
571
- c(this, "isRunning", !1);
572
- c(this, "isTravelEnabled", !1);
573
- c(this, "pendingMask", S);
574
- c(this, "mutationTimer", null);
575
- c(this, "cssTimer", null);
576
- c(this, "resizeConfig");
577
- c(this, "resizeTimer", null);
578
- c(this, "isResizing", !1);
579
- c(this, "onTransitionFinished", (e) => {
580
- this.target.contains(e.target) && this.mutationTimer === null && (this.cssTimer && clearTimeout(this.cssTimer), this.pendingMask |= z | L, this.cssTimer = window.setTimeout(() => {
1019
+ function ke(i, e) {
1020
+ e.size !== 0 && e.forEach((t, s) => {
1021
+ var b, w, R, k, O, A, L, P, Y, v, j, Q, Z, K, ee, te, re, ie;
1022
+ const r = i.get(s);
1023
+ if (!r || !r.userData.basePosition)
1024
+ return;
1025
+ let { x: a, y: o } = r.userData.basePosition;
1026
+ const { width: n, height: c } = r.userData.baseSize, l = (b = t.width) != null ? b : n, d = (w = t.height) != null ? w : c, f = l - n, h = d - c;
1027
+ if (t.width !== void 0 && r.userData.originRatioX === void 0 && Math.abs(f) > 0.1) {
1028
+ const U = s.getBoundingClientRect(), W = (R = t.x) != null ? R : 0, G = (O = (k = r.userData.baseTransform) == null ? void 0 : k.x) != null ? O : 0, q = r.userData.isFixed ? 0 : window.scrollX;
1029
+ let C = -(U.left + q - W + G - r.userData.baseDOM.x) / f;
1030
+ Math.abs(C) < 0.05 ? C = 0 : Math.abs(C - 1) < 0.05 ? C = 1 : Math.abs(C - 0.5) < 0.05 && (C = 0.5), r.userData.originRatioX = C;
1031
+ }
1032
+ if (t.height !== void 0 && r.userData.originRatioY === void 0 && Math.abs(h) > 0.1) {
1033
+ const U = s.getBoundingClientRect(), W = (A = t.y) != null ? A : 0, G = (P = (L = r.userData.baseTransform) == null ? void 0 : L.y) != null ? P : 0, q = r.userData.isFixed ? 0 : window.scrollY;
1034
+ let C = -(U.top + q - W + G - r.userData.baseDOM.y) / h;
1035
+ Math.abs(C) < 0.05 ? C = 0 : Math.abs(C - 1) < 0.05 ? C = 1 : Math.abs(C - 0.5) < 0.05 && (C = 0.5), r.userData.originRatioY = C;
1036
+ }
1037
+ const p = (Y = r.userData.originRatioX) != null ? Y : 0.5, g = (v = r.userData.originRatioY) != null ? v : 0.5, y = f * (0.5 - p), x = h * (0.5 - g), T = (Q = (j = r.userData.baseTransform) == null ? void 0 : j.x) != null ? Q : 0, S = (K = (Z = r.userData.baseTransform) == null ? void 0 : Z.y) != null ? K : 0, M = ((ee = t.x) != null ? ee : T) - T, E = ((te = t.y) != null ? te : S) - S;
1038
+ r.position.setX(a + y + M), r.position.setY(o - (x + E)), r.scale.set(l, d, 1), z.forceUpdateUniforms(r.material, {
1039
+ backgroundColor: t.backgroundColor,
1040
+ backgroundImage: t.backgroundImage,
1041
+ opacity: t.opacity,
1042
+ borderRadius: (ie = t.borderRadius) != null ? ie : (re = r.userData.baseStyles) == null ? void 0 : re.borderRadius,
1043
+ width: l,
1044
+ height: d
1045
+ });
1046
+ });
1047
+ }
1048
+ function Oe(i, e, t) {
1049
+ i.forEach((s) => {
1050
+ if (s.userData.isFixed && s.userData.initialScroll && s.userData.originalBasePosition) {
1051
+ const r = e - s.userData.initialScroll.x, a = t - s.userData.initialScroll.y;
1052
+ s.userData.basePosition.x = s.userData.originalBasePosition.x + r, s.userData.basePosition.y = s.userData.originalBasePosition.y - a, s.position.x = s.userData.basePosition.x, s.position.y = s.userData.basePosition.y;
1053
+ }
1054
+ });
1055
+ }
1056
+ function Be(i) {
1057
+ const e = {};
1058
+ if (i.opacity && (e.opacity = parseFloat(i.opacity)), i.backgroundColor && i.backgroundColor !== "rgba(0, 0, 0, 0)") {
1059
+ const t = I(i.backgroundColor);
1060
+ e.backgroundColor = [t.color.r, t.color.g, t.color.b];
1061
+ }
1062
+ if (i.backgroundImage ? e.backgroundImage = i.backgroundImage : i.background && (e.backgroundImage = i.background), i.borderRadius && (e.borderRadius = parseFloat(i.borderRadius)), i.width && (e.width = parseFloat(i.width)), i.height && (e.height = parseFloat(i.height)), i.transform && i.transform !== "none") {
1063
+ const t = new DOMMatrix(i.transform);
1064
+ e.x = t.m41, e.y = t.m42, e.z = t.m43;
1065
+ }
1066
+ return e;
1067
+ }
1068
+ class Fe {
1069
+ constructor(e, t, s, r) {
1070
+ u(this, "target");
1071
+ u(this, "renderer");
1072
+ u(this, "registry");
1073
+ u(this, "filter");
1074
+ u(this, "observer");
1075
+ u(this, "pendingDeletions", /* @__PURE__ */ new Set());
1076
+ u(this, "pendingStyles", /* @__PURE__ */ new Map());
1077
+ u(this, "isDomDirty", !1);
1078
+ u(this, "isRunning", !1);
1079
+ u(this, "isTravelEnabled", !1);
1080
+ u(this, "pendingMask", _);
1081
+ u(this, "mutationTimer", null);
1082
+ u(this, "cssTimer", null);
1083
+ u(this, "resizeConfig");
1084
+ u(this, "resizeTimer", null);
1085
+ u(this, "isResizing", !1);
1086
+ u(this, "lastScrollX", 0);
1087
+ u(this, "lastScrollY", 0);
1088
+ u(this, "scrollTimer", null);
1089
+ u(this, "onTransitionFinished", (e) => {
1090
+ this.target.contains(e.target) && this.mutationTimer === null && (this.cssTimer && clearTimeout(this.cssTimer), this.pendingStyles.size == 0 && (this.pendingMask |= B | N, this.cssTimer = window.setTimeout(() => {
581
1091
  this.isDomDirty = !0, this.cssTimer = null;
582
- }, 50));
1092
+ }, 50)));
583
1093
  });
584
- c(this, "onWindowResize", () => {
1094
+ u(this, "onWindowResize", () => {
585
1095
  if (!this.resizeConfig.enabled) {
586
1096
  this.isDomDirty = !0;
587
1097
  return;
@@ -590,24 +1100,42 @@ class Z {
590
1100
  this.isDomDirty = !0, this.resizeConfig.onEnd && this.resizeConfig.onEnd(), this.isResizing = !1, this.resizeTimer = null;
591
1101
  }, this.resizeConfig.delay);
592
1102
  });
593
- c(this, "renderLoop", () => {
594
- this.isRunning && (this.isDomDirty && this.forceUpdateScene(), this.renderer.render(), requestAnimationFrame(this.renderLoop));
1103
+ u(this, "renderLoop", () => {
1104
+ if (!this.isRunning)
1105
+ return;
1106
+ this.isDomDirty && this.forceUpdateScene();
1107
+ const e = window.scrollX, t = window.scrollY;
1108
+ (e !== this.lastScrollX || t !== this.lastScrollY) && (Oe(this.renderer.fixedMeshes, e, t), this.lastScrollX = e, this.lastScrollY = t, this.scrollTimer && clearTimeout(this.scrollTimer), this.scrollTimer = window.setTimeout(() => {
1109
+ this.pendingMask |= B, this.isDomDirty = !0, this.scrollTimer = null;
1110
+ }, 150)), this.pendingStyles.size > 0 && (ke(this.registry, this.pendingStyles), this.pendingStyles.clear()), this.renderer.render(), requestAnimationFrame(this.renderLoop);
595
1111
  });
596
- var a, n;
597
- this.target = e, this.renderer = t, this.filter = r.filter;
598
- const s = (a = r.resizeDebounce) != null ? a : !0;
599
- s === !1 ? this.resizeConfig = { enabled: !1, delay: 0 } : s === !0 ? this.resizeConfig = { enabled: !0, delay: 150 } : this.resizeConfig = {
1112
+ var o, n;
1113
+ this.target = e, this.renderer = t, this.registry = s, this.filter = r.filter;
1114
+ const a = (o = r.resizeDebounce) != null ? o : !0;
1115
+ a === !1 ? this.resizeConfig = { enabled: !1, delay: 0 } : a === !0 ? this.resizeConfig = { enabled: !0, delay: 150 } : this.resizeConfig = {
600
1116
  enabled: !0,
601
- delay: (n = s.delay) != null ? n : 150,
602
- onStart: s.onStart,
603
- onEnd: s.onEnd
604
- }, this.observer = new MutationObserver((o) => {
605
- let l = S;
606
- for (const h of o)
607
- h.type === "childList" ? l |= I : h.type === "attributes" && (h.attributeName === "style" || h.attributeName === "class") && (l |= z | L);
608
- if (l !== S) {
609
- if (this.pendingMask |= l, l & I) {
610
- this.clearTimers(), console.log("Structural Change detected"), this.isDomDirty = !0;
1117
+ delay: (n = a.delay) != null ? n : 150,
1118
+ onStart: a.onStart,
1119
+ onEnd: a.onEnd
1120
+ }, this.observer = new MutationObserver((c) => {
1121
+ let l = _;
1122
+ for (const d of c)
1123
+ if (d.type === "childList")
1124
+ l |= V, d.removedNodes.length > 0 && d.removedNodes.forEach((f) => {
1125
+ f instanceof HTMLElement && this.pendingDeletions.add(f);
1126
+ });
1127
+ else if (d.type === "attributes")
1128
+ if (d.attributeName === "style") {
1129
+ l |= B | N;
1130
+ const f = d.target, h = Be(f.style);
1131
+ this.pendingStyles.set(f, h);
1132
+ } else
1133
+ d.attributeName === "class" && (l |= B | N);
1134
+ else
1135
+ d.type === "characterData" && (l |= $ | B);
1136
+ if (l !== _) {
1137
+ if (this.pendingMask |= l, l & V) {
1138
+ this.clearTimers(), this.isDomDirty = !0;
611
1139
  return;
612
1140
  }
613
1141
  this.mutationTimer && clearTimeout(this.mutationTimer), this.mutationTimer = window.setTimeout(() => {
@@ -628,32 +1156,71 @@ class Z {
628
1156
  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);
629
1157
  }
630
1158
  clearTimers() {
631
- this.mutationTimer && (clearTimeout(this.mutationTimer), this.mutationTimer = null), this.cssTimer && (clearTimeout(this.cssTimer), this.cssTimer = null);
1159
+ this.mutationTimer && (clearTimeout(this.mutationTimer), this.mutationTimer = null), this.cssTimer && (clearTimeout(this.cssTimer), this.cssTimer = null), this.scrollTimer && (clearTimeout(this.scrollTimer), this.scrollTimer = null);
632
1160
  }
633
1161
  forceUpdateScene() {
634
- this.isDomDirty = !1;
1162
+ this.isDomDirty = !1, this.lastScrollX = window.scrollX, this.lastScrollY = window.scrollY;
635
1163
  const e = document.querySelector("[data-mirage-travel='traveler']") !== null;
636
1164
  e && !this.isTravelEnabled && (this.isTravelEnabled = !0, this.renderer.createRenderTarget());
637
- const t = P(
1165
+ const t = ce(
638
1166
  this.target,
639
1167
  this.pendingMask,
640
- e ? x | R : x,
1168
+ e ? D | X : D,
641
1169
  this.filter
642
1170
  );
643
- t && this.renderer.syncScene(t), this.pendingMask = S;
1171
+ t && (this.renderer.syncScene(t, this.pendingDeletions), this.pendingDeletions.clear()), this.pendingMask = _;
1172
+ }
1173
+ // [ThinkPoint] change call back pattern when after
1174
+ }
1175
+ class Ie {
1176
+ constructor() {
1177
+ u(this, "store");
1178
+ this.store = /* @__PURE__ */ new WeakMap();
1179
+ }
1180
+ register(e, t) {
1181
+ this.store.set(e, t);
1182
+ }
1183
+ get(e) {
1184
+ return this.store.get(e);
1185
+ }
1186
+ // public register(element: HTMLElement, meshGroup: THREE.Group): void {
1187
+ // this.store.set(element, meshGroup);
1188
+ // }
1189
+ // public get(element: HTMLElement): THREE.Group | undefined {
1190
+ // return this.store.get(element);
1191
+ // }
1192
+ has(e) {
1193
+ return this.store.has(e);
1194
+ }
1195
+ // Optional
1196
+ remove(e) {
1197
+ this.store.delete(e);
644
1198
  }
645
1199
  }
646
- class K {
1200
+ class Ae {
647
1201
  constructor(e, t) {
648
- c(this, "renderer");
649
- c(this, "syncer");
650
- c(this, "target");
651
- var s, a, n;
652
- this.target = e;
653
- let r;
654
- if (t.mode === "duplicate" ? r = (a = (s = t.container) != null ? s : this.target.parentElement) != null ? a : void 0 : r = (n = this.target.parentElement) != null ? n : void 0, !r)
1202
+ u(this, "renderer");
1203
+ u(this, "syncer");
1204
+ u(this, "target");
1205
+ u(this, "registry");
1206
+ var r, a, o;
1207
+ if (this.target = e, this.registry = new Ie(), !document.getElementById("mirage-engine-styles")) {
1208
+ const n = document.createElement("style");
1209
+ n.id = "mirage-engine-styles", n.textContent = `
1210
+ [data-mirage-dom="hide"] {
1211
+ opacity: 0 !important;
1212
+ }
1213
+ `, document.head.appendChild(n);
1214
+ }
1215
+ let s;
1216
+ if (t.mode === "duplicate" ? s = (a = (r = t.container) != null ? r : this.target.parentElement) != null ? a : void 0 : s = (o = this.target.parentElement) != null ? o : void 0, !s)
655
1217
  throw new Error("[Mirage] Cannot find a container (parent or option).");
656
- this.renderer = new V(this.target, t, r), this.renderer.mount(), this.syncer = new Z(this.target, this.renderer, t);
1218
+ this.renderer = new Me(
1219
+ this.target,
1220
+ t,
1221
+ s,
1222
+ this.registry
1223
+ ), this.renderer.mount(), this.syncer = new Fe(this.target, this.renderer, this.registry, t);
657
1224
  }
658
1225
  start() {
659
1226
  this.syncer.start();
@@ -664,13 +1231,35 @@ class K {
664
1231
  dispose() {
665
1232
  this.syncer.stop(), this.renderer.dispose();
666
1233
  }
1234
+ test() {
1235
+ const e = this.registry.get(
1236
+ document.querySelector("#box2")
1237
+ );
1238
+ if (!e)
1239
+ return;
1240
+ const t = {
1241
+ ArrowRight: !1,
1242
+ ArrowLeft: !1,
1243
+ ArrowUp: !1,
1244
+ ArrowDown: !1
1245
+ };
1246
+ window.addEventListener("keydown", (a) => {
1247
+ t[a.key] !== void 0 && (t[a.key] = !0);
1248
+ }), window.addEventListener("keyup", (a) => {
1249
+ t[a.key] !== void 0 && (t[a.key] = !1);
1250
+ });
1251
+ const s = 2, r = () => {
1252
+ requestAnimationFrame(r), t.ArrowRight && e.position.setX(e.position.x + s), t.ArrowLeft && e.position.setX(e.position.x - s), t.ArrowUp && e.position.setY(e.position.y + s), t.ArrowDown && e.position.setY(e.position.y - s);
1253
+ };
1254
+ r();
1255
+ }
667
1256
  }
668
- class te {
1257
+ class ze {
669
1258
  constructor(e, t) {
670
- c(this, "_engine");
1259
+ u(this, "_engine");
671
1260
  if (!e)
672
1261
  throw new Error("[Mirage] Target element is required.");
673
- this._engine = new K(e, t);
1262
+ this._engine = new Ae(e, t);
674
1263
  }
675
1264
  start() {
676
1265
  this._engine.start();
@@ -681,7 +1270,10 @@ class te {
681
1270
  destroy() {
682
1271
  this._engine.dispose();
683
1272
  }
1273
+ test() {
1274
+ this._engine.test();
1275
+ }
684
1276
  }
685
1277
  export {
686
- te as Mirage
1278
+ ze as Mirage
687
1279
  };