@mirage-engine/core 0.2.1 → 0.3.0

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,282 +1,840 @@
1
- var k = Object.defineProperty;
2
- var q = (s, e, t) => e in s ? k(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var h = (s, e, t) => (q(s, 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, _ = 16, x = 1, w = 2, ee = 0, W = [
6
- "include-tree",
7
- "exclude-tree",
8
- "include-self",
9
- "exclude-self",
10
- "end"
11
- ];
12
- function U(s, e, t) {
13
- const r = e.split(`
14
- `), i = [];
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 c = n[l];
20
- s.measureText(o + " " + c).width < t ? o += " " + c : (i.push(o), o = c);
1
+ var Be = Object.defineProperty, Oe = Object.defineProperties;
2
+ var Fe = Object.getOwnPropertyDescriptors;
3
+ var Ce = Object.getOwnPropertySymbols;
4
+ var Xe = Object.prototype.hasOwnProperty, _e = Object.prototype.propertyIsEnumerable;
5
+ var ge = (s, e, t) => e in s ? Be(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, G = (s, e) => {
6
+ for (var t in e || (e = {}))
7
+ Xe.call(e, t) && ge(s, t, e[t]);
8
+ if (Ce)
9
+ for (var t of Ce(e))
10
+ _e.call(e, t) && ge(s, t, e[t]);
11
+ return s;
12
+ }, pe = (s, e) => Oe(s, Fe(e));
13
+ var u = (s, e, t) => (ge(s, typeof e != "symbol" ? e + "" : e, t), t);
14
+ var we = (s, e, t) => new Promise((i, r) => {
15
+ var l = (n) => {
16
+ try {
17
+ a(t.next(n));
18
+ } catch (c) {
19
+ r(c);
21
20
  }
22
- i.push(o);
23
- }), i;
21
+ }, o = (n) => {
22
+ try {
23
+ a(t.throw(n));
24
+ } catch (c) {
25
+ r(c);
26
+ }
27
+ }, a = (n) => n.done ? i(n.value) : Promise.resolve(n.value).then(l, o);
28
+ a((t = t.apply(s, e)).next());
29
+ });
30
+ import * as v from "three";
31
+ const Me = {
32
+ INCLUDE_TREE: "include-tree",
33
+ EXCLUDE_TREE: "exclude-tree",
34
+ INCLUDE_SELF: "include-self",
35
+ EXCLUDE_SELF: "exclude-self",
36
+ END: "end"
37
+ }, q = {
38
+ NAME: "data-mirage-dom",
39
+ KEY: "mirageDom",
40
+ VALUES: {
41
+ HIDE: "hide"
42
+ }
43
+ }, Te = {
44
+ TRAVELER: "traveler",
45
+ NATIVE: "native",
46
+ CAPTURE_1: "1",
47
+ CAPTURE_2: "2",
48
+ CAPTURE_3: "3",
49
+ CAPTURE_4: "4",
50
+ CAPTURE_5: "5"
51
+ }, O = {
52
+ NAME: "data-mirage-travel",
53
+ KEY: "mirageTravel",
54
+ VALUES: Te,
55
+ MAX_LAYERS: Object.keys(Te).length - 1
56
+ }, Y = {
57
+ NAME: "data-mirage-filter",
58
+ KEY: "mirageFilter",
59
+ VALUES: Me
60
+ }, z = {
61
+ NAME: "data-mirage-select",
62
+ KEY: "mirageSelect",
63
+ VALUES: Me
64
+ }, Ne = {
65
+ NAME: "data-mirage-shader",
66
+ KEY: "mirageShader"
67
+ }, lt = {
68
+ NAME: "data-mirage-sandwich",
69
+ KEY: "mirageSandwich",
70
+ VALUES: {
71
+ FRONT: "front"
72
+ }
73
+ }, he = 0, j = 1, ae = 2, Ye = 4, be = 8, ve = 16;
74
+ function ze(s) {
75
+ const e = s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
76
+ return e ? {
77
+ r: parseInt(e[1]) / 255,
78
+ g: parseInt(e[2]) / 255,
79
+ b: parseInt(e[3]) / 255
80
+ } : { r: 1, g: 1, b: 1 };
24
81
  }
25
- function N(s, e, t, r, i = 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) * i;
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 c = U(n, s, t), m = e.lineHeight;
32
- c.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;
82
+ function Pe(s) {
83
+ const e = {};
84
+ if (s.opacity && (e.opacity = parseFloat(s.opacity)), s.backgroundColor && s.backgroundColor !== "rgba(0, 0, 0, 0)") {
85
+ const t = ze(s.backgroundColor);
86
+ e.backgroundColor = [t.r, t.g, t.b];
87
+ }
88
+ 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") {
89
+ const t = new DOMMatrix(s.transform);
90
+ e.x = t.m41, e.y = t.m42, e.z = t.m43;
91
+ }
92
+ return e;
39
93
  }
40
- function R(s) {
94
+ class Ve {
95
+ constructor(e, t) {
96
+ u(this, "target");
97
+ u(this, "observer");
98
+ u(this, "pendingDeletions", /* @__PURE__ */ new Set());
99
+ u(this, "pendingStyles", /* @__PURE__ */ new Map());
100
+ u(this, "isDomDirty", !1);
101
+ u(this, "isRunning", !1);
102
+ u(this, "pendingMask", he);
103
+ u(this, "mutationTimer", null);
104
+ u(this, "cssTimer", null);
105
+ u(this, "resizeConfig");
106
+ u(this, "resizeTimer", null);
107
+ u(this, "isResizing", !1);
108
+ u(this, "lastScrollX", 0);
109
+ u(this, "lastScrollY", 0);
110
+ u(this, "scrollTimer", null);
111
+ u(this, "onBeforeRender", /* @__PURE__ */ new Set());
112
+ u(this, "onLayoutChange", /* @__PURE__ */ new Set());
113
+ u(this, "onStyleChange", /* @__PURE__ */ new Set());
114
+ u(this, "onScrollChange", /* @__PURE__ */ new Set());
115
+ u(this, "onRender", /* @__PURE__ */ new Set());
116
+ u(this, "onTransitionFinished", (e) => {
117
+ this.target.contains(e.target) && this.mutationTimer === null && (this.cssTimer && clearTimeout(this.cssTimer), this.pendingStyles.size == 0 && (this.pendingMask |= j | ae, this.cssTimer = window.setTimeout(() => {
118
+ this.isDomDirty = !0, this.cssTimer = null;
119
+ }, 50)));
120
+ });
121
+ u(this, "onWindowResize", () => {
122
+ if (!this.resizeConfig.enabled) {
123
+ this.isDomDirty = !0;
124
+ return;
125
+ }
126
+ this.isResizing || (this.isResizing = !0, this.resizeConfig.onStart && this.resizeConfig.onStart()), this.resizeTimer && clearTimeout(this.resizeTimer), this.resizeTimer = window.setTimeout(() => {
127
+ this.isDomDirty = !0, this.resizeConfig.onEnd && this.resizeConfig.onEnd(), this.isResizing = !1, this.resizeTimer = null;
128
+ }, this.resizeConfig.delay);
129
+ });
130
+ u(this, "renderLoop", () => {
131
+ if (!this.isRunning)
132
+ return;
133
+ this.onBeforeRender.forEach((i) => i()), this.isDomDirty && (this.isDomDirty = !1, this.onLayoutChange.forEach((i) => i(this.pendingMask, this.pendingDeletions)), this.pendingDeletions.clear(), this.pendingMask = he);
134
+ const e = window.scrollX, t = window.scrollY;
135
+ (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(() => {
136
+ this.pendingMask |= j, this.isDomDirty = !0, this.scrollTimer = null;
137
+ }, 150)), this.pendingStyles.size > 0 && (this.onStyleChange.forEach((i) => i(this.pendingStyles)), this.pendingStyles.clear()), this.onRender.forEach((i) => i()), requestAnimationFrame(this.renderLoop);
138
+ });
139
+ var r, l;
140
+ this.target = e;
141
+ const i = (r = t.resizeDebounce) != null ? r : !0;
142
+ i === !1 ? this.resizeConfig = { enabled: !1, delay: 0 } : i === !0 ? this.resizeConfig = { enabled: !0, delay: 150 } : this.resizeConfig = {
143
+ enabled: !0,
144
+ delay: (l = i.delay) != null ? l : 150,
145
+ onStart: i.onStart,
146
+ onEnd: i.onEnd
147
+ }, this.observer = new MutationObserver((o) => {
148
+ let a = he;
149
+ for (const n of o)
150
+ if (n.type === "childList")
151
+ a |= be, n.removedNodes.length > 0 && n.removedNodes.forEach((c) => {
152
+ c instanceof HTMLElement && this.pendingDeletions.add(c);
153
+ });
154
+ else if (n.type === "attributes")
155
+ if (n.attributeName === "style") {
156
+ a |= j | ae;
157
+ const c = n.target, h = Pe(c.style);
158
+ this.pendingStyles.set(c, h);
159
+ } else
160
+ (n.attributeName === "class" || n.attributeName && n.attributeName.startsWith("data-")) && (a |= j | ae);
161
+ else
162
+ n.type === "characterData" && (a |= ve | j);
163
+ if (a !== he) {
164
+ if (this.pendingMask |= a, a & be) {
165
+ this.clearTimers(), this.isDomDirty = !0;
166
+ return;
167
+ }
168
+ this.mutationTimer && clearTimeout(this.mutationTimer), this.mutationTimer = window.setTimeout(() => {
169
+ this.mutationTimer = null, this.isDomDirty = !0;
170
+ }, 200);
171
+ }
172
+ });
173
+ }
174
+ start() {
175
+ this.isRunning || (this.isRunning = !0, this.observer.observe(this.target, {
176
+ childList: !0,
177
+ subtree: !0,
178
+ attributes: !0,
179
+ characterData: !0
180
+ }), 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());
181
+ }
182
+ stop() {
183
+ 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);
184
+ }
185
+ clearTimers() {
186
+ this.mutationTimer && (clearTimeout(this.mutationTimer), this.mutationTimer = null), this.cssTimer && (clearTimeout(this.cssTimer), this.cssTimer = null), this.scrollTimer && (clearTimeout(this.scrollTimer), this.scrollTimer = null);
187
+ }
188
+ }
189
+ const P = 1, Z = 2, ct = 0, A = {
190
+ BASE: 0,
191
+ SELECTED: 1,
192
+ getCaptureLayer: (s) => 31 - s,
193
+ HIDDEN: 31
194
+ }, Se = Object.values(Y.VALUES);
195
+ class De {
196
+ /**
197
+ * Calculates or retrieves the exact alphabetic baseline (in pixels) for the given font.
198
+ * @param font CSS font shorthand string (e.g., "400 16px Inter")
199
+ * @returns Baseline Y offset in pixels
200
+ */
201
+ static getBaseline(e) {
202
+ if (this.cache.has(e))
203
+ return this.cache.get(e);
204
+ const t = this.calculateBaselineFromDOM(e);
205
+ return this.cache.set(e, t), t;
206
+ }
207
+ static calculateBaselineFromDOM(e) {
208
+ if (typeof document == "undefined")
209
+ return 0;
210
+ const t = document.createElement("div"), i = document.createElement("span"), r = document.createElement("img");
211
+ 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);
212
+ const l = r.offsetTop - i.offsetTop;
213
+ return document.body.removeChild(t), l;
214
+ }
215
+ }
216
+ u(De, "cache", /* @__PURE__ */ new Map());
217
+ class We extends v.MeshBasicMaterial {
218
+ constructor(t, i, r, l, o = 2) {
219
+ super({
220
+ transparent: !0,
221
+ side: v.FrontSide,
222
+ color: 16777215
223
+ });
224
+ u(this, "canvas");
225
+ u(this, "ctx");
226
+ u(this, "qualityFactor");
227
+ if (this.canvas = document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), !this.ctx)
228
+ throw new Error("[Mirage] Failed to create canvas context");
229
+ this.qualityFactor = o, this.map = new v.CanvasTexture(this.canvas), this.map.colorSpace = v.LinearSRGBColorSpace, this.map.minFilter = v.LinearFilter, this.map.magFilter = v.LinearFilter, this.updateText(t, i, r, l);
230
+ }
231
+ wrapText(t, i) {
232
+ const r = t.split(`
233
+ `), l = [];
234
+ return r.forEach((o) => {
235
+ const a = o.match(/[^\s\-]+\-?|\-|\s+/g) || [];
236
+ if (a.length === 0) {
237
+ l.push("");
238
+ return;
239
+ }
240
+ let n = a[0];
241
+ for (let c = 1; c < a.length; c++) {
242
+ const h = a[c];
243
+ this.ctx.measureText(n + h).width <= i + 2 ? n += h : (n && l.push(n), n = h.trimStart());
244
+ }
245
+ n && l.push(n);
246
+ }), l;
247
+ }
248
+ updateText(t, i, r, l, o) {
249
+ o !== void 0 && (this.qualityFactor = o);
250
+ const n = (window.devicePixelRatio || 1) * this.qualityFactor, c = r * n, h = l * n;
251
+ this.canvas.width !== c || this.canvas.height !== h ? (this.canvas.width = c, this.canvas.height = h) : this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height), this.ctx.setTransform(n, 0, 0, n, 0, 0), this.ctx.font = i.font, this.ctx.fillStyle = i.color, this.ctx.textBaseline = "alphabetic", this.ctx.globalAlpha = 1;
252
+ const f = this.wrapText(t, r), b = i.lineHeight, p = De.getBaseline(i.font);
253
+ f.forEach((d, g) => {
254
+ const w = g * b + p;
255
+ let L = 0;
256
+ i.textAlign === "center" ? L = r / 2 : i.textAlign === "right" && (L = r), this.ctx.textAlign = i.textAlign, this.ctx.fillText(d, L, w);
257
+ }), this.map && (this.map.needsUpdate = !0);
258
+ }
259
+ dispose() {
260
+ this.map && this.map.dispose(), super.dispose();
261
+ }
262
+ }
263
+ function ee(s) {
41
264
  return typeof s == "number" ? s : parseFloat(s) || 0;
42
265
  }
43
- function X(s, e) {
44
- var o, l, c, m;
45
- if (!e) {
46
- s.set(0, 0, 0, 0);
47
- return;
266
+ function le(s) {
267
+ if (!s || s === "transparent")
268
+ return { color: new v.Color(16777215), alpha: 0 };
269
+ const e = s.match(
270
+ /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
271
+ );
272
+ if (e) {
273
+ const t = parseInt(e[1], 10), i = parseInt(e[2], 10), r = parseInt(e[3], 10), l = e[4] !== void 0 ? parseFloat(e[4]) : 1;
274
+ return { color: new v.Color(`rgb(${t}, ${i}, ${r})`), alpha: l };
48
275
  }
49
- const t = e.split("/")[0].trim().split(/\s+/), r = R(t[0]), i = R((o = t[1]) != null ? o : t[0]), a = R((l = t[2]) != null ? l : t[0]), n = R((m = (c = t[3]) != null ? c : t[1]) != null ? m : t[0]);
50
- s.set(r, i, a, n);
276
+ return { color: new v.Color(s), alpha: 1 };
51
277
  }
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
- `
278
+ function He(s) {
279
+ const e = [];
280
+ let t = "", i = 0;
281
+ for (let r = 0; r < s.length; r++) {
282
+ const l = s[r];
283
+ if (l === "(")
284
+ i++;
285
+ else if (l === ")")
286
+ i--;
287
+ else if (l === "," && i === 0) {
288
+ e.push(t.trim()), t = "";
289
+ continue;
290
+ }
291
+ t += l;
292
+ }
293
+ return t && e.push(t.trim()), e;
294
+ }
295
+ function Ge(s) {
296
+ if (!s || typeof s != "string" || !s.includes("linear-gradient"))
297
+ return null;
298
+ const e = s.match(/linear-gradient\((.*)\)/);
299
+ if (!e)
300
+ return null;
301
+ const t = e[1], i = He(t);
302
+ let r = Math.PI, l = 0;
303
+ const o = i[0].trim();
304
+ if (o.startsWith("to "))
305
+ 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), l = 1;
306
+ else if (o.endsWith("deg") || o.endsWith("rad") || o.endsWith("turn")) {
307
+ const n = parseFloat(o);
308
+ o.endsWith("deg") ? r = n * (Math.PI / 180) : o.endsWith("rad") ? r = n : o.endsWith("turn") && (r = n * Math.PI * 2), l = 1;
309
+ }
310
+ const a = [];
311
+ for (let n = l; n < i.length && !(a.length >= 8); n++) {
312
+ const c = i[n].trim(), h = c.lastIndexOf(" ");
313
+ let f = c, b = null;
314
+ if (h !== -1 && !c.endsWith(")")) {
315
+ const d = c.substring(h + 1);
316
+ (d.endsWith("%") || d.endsWith("px") || !isNaN(parseFloat(d))) && (f = c.substring(0, h).trim(), b = d);
317
+ }
318
+ const p = le(f);
319
+ a.push({
320
+ color: p.color,
321
+ alpha: p.alpha,
322
+ rawStop: b,
323
+ stop: 0
324
+ });
325
+ }
326
+ if (a.length > 0) {
327
+ for (let c = 0; c < a.length; c++)
328
+ a[c].rawStop !== null && (a[c].stop = parseFloat(a[c].rawStop) / 100);
329
+ a[0].rawStop === null && (a[0].stop = 0), a.length > 1 && a[a.length - 1].rawStop === null && (a[a.length - 1].stop = 1);
330
+ let n = 0;
331
+ for (let c = 1; c < a.length; c++)
332
+ if (a[c].rawStop !== null || c === a.length - 1) {
333
+ const h = c - n;
334
+ if (h > 1) {
335
+ const f = a[n].stop, p = (a[c].stop - f) / h;
336
+ for (let d = 1; d < h; d++)
337
+ a[n + d].stop = f + p * d;
338
+ }
339
+ n = c;
340
+ }
341
+ }
342
+ return { angle: r, stops: a };
343
+ }
344
+ const qe = `varying vec2 vUv;
345
+ varying vec4 vScreenPos;
346
+ void main() {
347
+ vUv = uv;
348
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
349
+ vScreenPos = gl_Position;
350
+ }`, $e = `varying vec2 vUv;
351
+ uniform vec2 uSize;
352
+ uniform vec4 uBorderRadius;
353
+ uniform float uBorderWidth;
354
+ uniform vec4 uBgColor;
355
+ uniform vec4 uBorderColor;
356
+ uniform float uOpacity;
66
357
 
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;
358
+ uniform int uGradientCount;
359
+ uniform float uGradientAngle;
360
+ uniform vec4 uGradientColors[8];
361
+ uniform float uGradientStops[8];
77
362
 
78
- #INJECT_DECLARATIONS
363
+ #INJECT_DECLARATIONS
79
364
 
80
- float sdRoundedBox(vec2 p, vec2 b, float r) {
81
- vec2 q = abs(p) - b + r;
365
+ vec3 linearToSrgb(vec3 linearColor) {
366
+ vec3 linearPart = 12.92 * linearColor;
367
+ vec3 curvePart = 1.055 * pow(linearColor, vec3(1.0 / 2.4)) - 0.055;
368
+ vec3 switchCondition = step(vec3(0.0031308), linearColor);
369
+ return mix(linearPart, curvePart, switchCondition);
370
+ }
82
371
 
83
- return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
84
- }
372
+ vec3 srgbToLinear(vec3 srgbColor) {
373
+ vec3 linearPart = srgbColor / 12.92;
374
+ vec3 curvePart = pow((srgbColor + vec3(0.055)) / 1.055, vec3(2.4));
375
+ vec3 switchCondition = step(vec3(0.04045), srgbColor);
376
+ return mix(linearPart, curvePart, switchCondition);
377
+ }
85
378
 
86
- void main() {
87
- vec2 p = (vUv - 0.5) * uSize;
88
- vec2 halfSize = uSize * 0.5;
379
+ vec4 blendSrcOverInLinear(vec4 front, vec4 back) {
380
+ front.rgb = srgbToLinear(front.rgb);
381
+ back.rgb = srgbToLinear(back.rgb);
382
+ float aOut = front.a + back.a * (1.0 - front.a);
383
+ float safeAlpha = max(aOut, 0.0001);
384
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
385
+ return vec4(linearToSrgb(cOut), aOut);
386
+ }
387
+
388
+ vec4 blendSrcOver(vec4 front, vec4 back) {
389
+ float aOut = front.a + back.a * (1.0 - front.a);
390
+ float safeAlpha = max(aOut, 0.0001);
391
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
392
+ return vec4(cOut, aOut);
393
+ }
394
+
395
+ float sdRoundedBox(vec2 p, vec2 b, float r) {
396
+ vec2 q = abs(p) - b + r;
397
+ return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
398
+ }
89
399
 
90
- #INJECT_UV_MODIFIER
400
+ float sdVisualBox(vec2 p, vec2 b, float r) {
401
+ vec2 q = abs(p) - b + r;
402
+ float n = 2.01;
403
+ float d = pow(pow(max(q.x, 0.0), n) + pow(max(q.y, 0.0), n), 1.0/n) - r;
404
+ return min(max(q.x, q.y), 0.0) + d;
405
+ }
406
+
407
+ vec4 calculateGradientLayer(vec2 uv) {
408
+ if (uGradientCount < 2) return uGradientColors[0];
409
+
410
+ vec2 dir = vec2(sin(uGradientAngle), cos(uGradientAngle));
411
+ vec2 p = (uv - 0.5) * uSize;
412
+ float proj = dot(p, dir);
413
+ float L = abs(uSize.x * dir.x) + abs(uSize.y * dir.y);
414
+ float t = clamp((proj / L) + 0.5, 0.0, 1.0);
415
+
416
+ vec4 color = uGradientColors[0];
417
+ for (int i = 1; i < 8; i++) {
418
+ if (i >= uGradientCount) break;
419
+ float prevStop = uGradientStops[i-1];
420
+ float currStop = uGradientStops[i];
91
421
 
92
- // color decision pipeline
93
- vec4 baseColor = vec4(uBgColor, uBgOpacity);
422
+ float factor = clamp((t - prevStop) / (currStop - prevStop + 0.00001), 0.0, 1.0);
423
+ color = mix(color, uGradientColors[i], factor);
424
+ }
425
+ // return vec4(linearToSrgb(color.rgb), color.a);
426
+ return vec4(color);
427
+ }
94
428
 
95
- #INJECT_BASE_COLOR
429
+ void main() {
430
+ vec2 p = (vUv - 0.5) * uSize;
431
+ vec2 halfSize = uSize * 0.5;
96
432
 
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);
433
+ #INJECT_UV_MODIFIER
101
434
 
102
- float aa = 1.0;
103
- float bgMask = 1.0 - smoothstep(0.0, aa, d);
435
+ // color decision pipeline
436
+ vec4 baseColor = vec4(uBgColor.rgb, uBgColor.a);
104
437
 
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
- }
438
+ if (uGradientCount > 0) {
439
+ vec4 gradColor = calculateGradientLayer(vUv);
440
+ baseColor = blendSrcOver(gradColor, baseColor);
441
+ }
111
442
 
112
- // final blending (border + background)
113
- float aFront = borderAlpha;
114
- float aBack = baseColor.a;
115
- float aOut = aFront + aBack * (1.0 - aFront);
443
+ #INJECT_BASE_COLOR
116
444
 
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);
445
+ // Hybrid SDF
446
+ vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
447
+ float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
448
+ r = min(r, min(halfSize.x, halfSize.y));
120
449
 
121
- // final color control (Tint, Noise)
122
- #INJECT_COLOR_MODIFIER
450
+ float d = sdRoundedBox(p, halfSize, r);
123
451
 
124
- float finalOpacity = finalColor.a * bgMask * uOpacity;
125
- if (finalOpacity < 0.001) discard;
452
+ float d_smooth = sdVisualBox(p, halfSize, r);
453
+ float d_visual = d_smooth / fwidth(d_smooth);
126
454
 
127
- gl_FragColor = vec4(finalColor.rgb, finalOpacity);
455
+ // rendering pipeline
456
+ float bgMask = 1.0 - smoothstep(-0.5, 0.5, d_visual);
128
457
 
129
- #include <colorspace_fragment>
458
+ float halfBorder = uBorderWidth * 0.5;
459
+ float borderD = abs(d + halfBorder) - halfBorder;
460
+ float borderAlpha = (1.0 - smoothstep(0.0, 1.0, borderD)) * uBorderColor.a;
461
+ if (uBorderWidth <= 0.01) {
462
+ borderAlpha = 0.0;
130
463
  }
131
- `
132
- );
133
- function E(s) {
134
- if (!s || s === "transparent")
135
- return { color: new d.Color(16777215), alpha: 0 };
136
- const e = s.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), i = parseInt(e[3], 10), a = e[4] !== void 0 ? parseFloat(e[4]) : 1;
141
- return { color: new d.Color(`rgb(${t}, ${r}, ${i})`), alpha: a };
142
- }
143
- return { color: new d.Color(s), alpha: 1 };
464
+
465
+ // final blending (border + background) using blendSrcOver
466
+ vec4 borderLayer = vec4(uBorderColor.rgb, borderAlpha);
467
+ vec4 finalColor = blendSrcOver(borderLayer, baseColor);
468
+ // final color control (Tint, Noise)
469
+ #INJECT_COLOR_MODIFIER
470
+
471
+ float finalOpacity = finalColor.a * bgMask * uOpacity;
472
+ if (finalOpacity < 0.001) discard;
473
+
474
+ gl_FragColor = vec4(finalColor.rgb, finalOpacity);
475
+
476
+
477
+ // #include <colorspace_fragment>
144
478
  }
145
- function G(s, e, t, r = null, i) {
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
- ${(i == null ? void 0 : i.uvModifier) || ""}
159
- `
160
- ) : "", l = a ? (
161
- /* glsl */
162
- `
163
- baseColor = texture2D(uTexture, resultUv);
164
- `
165
- ) : "", c = (i == null ? void 0 : i.colorModifier) || "", m = $.replace("#INJECT_DECLARATIONS", n).replace("#INJECT_UV_MODIFIER", o).replace("#INJECT_BASE_COLOR", l).replace("#INJECT_COLOR_MODIFIER", c), f = E(s.backgroundColor), g = E(s.borderColor), p = {
166
- uSize: { value: new d.Vector2(e, t) },
167
- uBorderRadius: { value: new d.Vector4(0, 0, 0, 0) },
168
- uBorderWidth: { value: R(s.borderWidth) },
169
- uBgColor: { value: f.color },
170
- uBorderColor: { value: g.color },
171
- uOpacity: { value: (v = s.opacity) != null ? v : 1 },
172
- uBgOpacity: { value: f.alpha },
173
- uBorderOpacity: { value: g.alpha },
174
- uTexture: { value: null }
479
+ `, je = `uniform sampler2D uTexture;
480
+ varying vec4 vScreenPos;
481
+ uniform vec2 uTextureRepeat;
482
+ uniform vec2 uTextureOffset;`, Ke = `vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
483
+ vec2 resultUv = screenUv;
484
+
485
+ `, Je = `vec4 texColor = texture2D(uTexture, resultUv);
486
+ baseColor = blendSrcOver(baseColor, texColor);`, Re = {
487
+ vertexShader: qe,
488
+ fragmentShader: $e
489
+ }, me = {
490
+ declChunk: je,
491
+ uvChunk: Ke,
492
+ baseColorChunk: Je
493
+ };
494
+ function Qe(s, e, t, i = null, r) {
495
+ var R;
496
+ const l = i !== null || !!s.imageSrc;
497
+ let o = "";
498
+ const a = {};
499
+ if (r != null && r.uniforms)
500
+ for (const [E, x] of Object.entries(r.uniforms))
501
+ typeof x == "number" ? (o += `uniform float ${E};
502
+ `, a[E] = { value: x }) : Array.isArray(x) ? x.length === 2 ? (o += `uniform vec2 ${E};
503
+ `, a[E] = { value: new v.Vector2(...x) }) : x.length === 3 ? (o += `uniform vec3 ${E};
504
+ `, a[E] = { value: new v.Vector3(...x) }) : x.length === 4 && (o += `uniform vec4 ${E};
505
+ `, a[E] = { value: new v.Vector4(...x) }) : (o += `uniform float ${E};
506
+ `, a[E] = { value: x });
507
+ const n = (l ? me.declChunk : "") + `
508
+ ` + o, c = s.isTraveler ? me.uvChunk : `vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
509
+ `, h = l ? c + ((r == null ? void 0 : r.uvModifier) || "") : "", f = l ? me.baseColorChunk : "", b = (r == null ? void 0 : r.colorModifier) || "", p = Re.fragmentShader.replace("#INJECT_DECLARATIONS", n).replace("#INJECT_UV_MODIFIER", h).replace("#INJECT_BASE_COLOR", f).replace("#INJECT_COLOR_MODIFIER", b), d = le(s.backgroundColor), g = le(s.borderColor), w = {
510
+ uSize: { value: new v.Vector2(e, t) },
511
+ uBgColor: {
512
+ value: new v.Vector4(
513
+ d.color.r,
514
+ d.color.g,
515
+ d.color.b,
516
+ d.alpha
517
+ )
518
+ },
519
+ uBorderColor: {
520
+ value: new v.Vector4(
521
+ g.color.r,
522
+ g.color.g,
523
+ g.color.b,
524
+ g.alpha
525
+ )
526
+ },
527
+ uBorderRadius: { value: new v.Vector4(0, 0, 0, 0) },
528
+ uBorderWidth: { value: ee(s.borderWidth) },
529
+ uOpacity: { value: (R = s.opacity) != null ? R : 1 },
530
+ uTexture: { value: null },
531
+ uTextureRepeat: { value: new v.Vector2(1, 1) },
532
+ uTextureOffset: { value: new v.Vector2(0, 0) },
533
+ uGradientCount: { value: 0 },
534
+ uGradientAngle: { value: 0 },
535
+ uGradientColors: {
536
+ value: Array.from({ length: 8 }, () => new v.Vector4(0, 0, 0, 0))
537
+ },
538
+ uGradientStops: { value: new Float32Array(8) }
175
539
  };
176
- return X(p.uBorderRadius.value, s.borderRadius), a && (p.uTexture.value = r), new d.ShaderMaterial({
177
- uniforms: p,
178
- vertexShader: H,
179
- fragmentShader: m,
540
+ Ae(w.uBorderRadius.value, s.borderRadius), l && (w.uTexture.value = i);
541
+ const L = new v.ShaderMaterial({
542
+ uniforms: G(G({}, w), a),
543
+ vertexShader: Re.vertexShader,
544
+ fragmentShader: p,
180
545
  transparent: !0,
181
- side: d.FrontSide
546
+ side: v.FrontSide
182
547
  // for better performance
183
548
  });
549
+ return s.backgroundImage && ye(L, { backgroundImage: s.backgroundImage }), L;
184
550
  }
185
- function J(s, e, t, r, i) {
186
- var o;
187
- const a = E(e.backgroundColor), n = E(e.borderColor);
188
- s.uniforms.uSize.value.set(t, r), X(s.uniforms.uBorderRadius.value, e.borderRadius), s.uniforms.uBorderWidth.value = R(e.borderWidth), s.uniforms.uBgColor.value.copy(a.color), s.uniforms.uBorderColor.value.copy(n.color), s.uniforms.uOpacity.value = (o = e.opacity) != null ? o : 1, s.uniforms.uBgOpacity.value = a.alpha, s.uniforms.uBorderOpacity.value = n.alpha, s.uniforms.uTexture && i !== void 0 && (s.uniforms.uTexture.value = i);
551
+ function Ze(s, e, t, i, r) {
552
+ const l = ee(e.borderWidth);
553
+ ye(s, {
554
+ width: t,
555
+ height: i,
556
+ borderRadius: e.borderRadius,
557
+ borderWidth: l,
558
+ backgroundColor: e.backgroundColor,
559
+ borderColor: e.borderColor,
560
+ opacity: e.opacity,
561
+ texture: r,
562
+ backgroundImage: e.backgroundImage
563
+ });
189
564
  }
190
- const D = {
191
- create(s, e, t, r, i, a = 2, n = null, o) {
192
- if (s === "BOX")
193
- return G(e, r, i, n, o);
194
- if (s === "TEXT") {
195
- const l = N(
196
- t || "",
197
- e,
198
- r,
199
- i,
200
- a
565
+ function ye(s, e) {
566
+ var i, r, l;
567
+ if (e.width !== void 0 && e.height !== void 0 && s.uniforms.uSize.value.set(e.width, e.height), e.borderRadius !== void 0 && Ae(s.uniforms.uBorderRadius.value, e.borderRadius), e.borderWidth !== void 0 && (s.uniforms.uBorderWidth.value = e.borderWidth), e.backgroundColor !== void 0)
568
+ if (Array.isArray(e.backgroundColor)) {
569
+ const o = s.uniforms.uBgColor.value.w;
570
+ s.uniforms.uBgColor.value.set(
571
+ e.backgroundColor[0],
572
+ e.backgroundColor[1],
573
+ e.backgroundColor[2],
574
+ o
575
+ );
576
+ } else if (typeof e.backgroundColor == "string") {
577
+ const o = le(e.backgroundColor);
578
+ s.uniforms.uBgColor.value.set(
579
+ o.color.r,
580
+ o.color.g,
581
+ o.color.b,
582
+ o.alpha
583
+ );
584
+ } else {
585
+ const o = s.uniforms.uBgColor.value.w;
586
+ s.uniforms.uBgColor.value.set(
587
+ e.backgroundColor.r,
588
+ e.backgroundColor.g,
589
+ e.backgroundColor.b,
590
+ o
201
591
  );
202
- return new d.MeshBasicMaterial({
203
- map: l,
204
- transparent: !0,
205
- side: d.FrontSide,
206
- color: 16777215
207
- });
208
592
  }
209
- return new d.MeshBasicMaterial({ visible: !1 });
210
- },
211
- update(s, e, t, r, i, a, n = 2, o) {
212
- if (e === "BOX")
213
- J(
214
- s,
215
- t,
216
- i,
217
- a,
593
+ if (e.borderColor !== void 0)
594
+ if (Array.isArray(e.borderColor)) {
595
+ const o = s.uniforms.uBorderColor.value.w;
596
+ s.uniforms.uBorderColor.value.set(
597
+ e.borderColor[0],
598
+ e.borderColor[1],
599
+ e.borderColor[2],
218
600
  o
219
601
  );
220
- else if (e === "TEXT") {
221
- const l = s;
222
- l.map && l.map.dispose();
223
- const c = N(
224
- r || "",
225
- t,
226
- i,
227
- a,
228
- n
602
+ } else if (typeof e.borderColor == "string") {
603
+ const o = le(e.borderColor);
604
+ s.uniforms.uBorderColor.value.set(
605
+ o.color.r,
606
+ o.color.g,
607
+ o.color.b,
608
+ o.alpha
229
609
  );
230
- l.map = c, l.needsUpdate = !0;
610
+ } else {
611
+ const o = s.uniforms.uBorderColor.value.w;
612
+ s.uniforms.uBorderColor.value.set(
613
+ e.borderColor.r,
614
+ e.borderColor.g,
615
+ e.borderColor.b,
616
+ o
617
+ );
618
+ }
619
+ 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);
620
+ const t = e.texture !== void 0 ? e.texture : (i = s.uniforms.uTexture) == null ? void 0 : i.value;
621
+ if (t && (t.image instanceof ImageBitmap || t.image instanceof HTMLImageElement || t.image instanceof HTMLCanvasElement)) {
622
+ const o = t.image.width, a = t.image.height, n = (r = e.width) != null ? r : s.uniforms.uSize.value.x, c = (l = e.height) != null ? l : s.uniforms.uSize.value.y;
623
+ if (o && a && n && c) {
624
+ const h = o / a, f = n / c;
625
+ if (h > f) {
626
+ const b = f / h;
627
+ s.uniforms.uTextureRepeat.value.set(b, 1), s.uniforms.uTextureOffset.value.set((1 - b) / 2, 0);
628
+ } else {
629
+ const b = h / f;
630
+ s.uniforms.uTextureRepeat.value.set(1, b), s.uniforms.uTextureOffset.value.set(0, (1 - b) / 2);
631
+ }
231
632
  }
633
+ } else
634
+ s.uniforms.uTextureRepeat && (s.uniforms.uTextureRepeat.value.set(1, 1), s.uniforms.uTextureOffset.value.set(0, 0));
635
+ if (e.backgroundImage !== void 0) {
636
+ const o = Ge(e.backgroundImage);
637
+ if (o) {
638
+ s.uniforms.uGradientCount.value = o.stops.length, s.uniforms.uGradientAngle.value = o.angle;
639
+ for (let a = 0; a < 8; a++)
640
+ if (a < o.stops.length) {
641
+ const n = o.stops[a];
642
+ s.uniforms.uGradientColors.value[a].set(
643
+ n.color.r,
644
+ n.color.g,
645
+ n.color.b,
646
+ n.alpha
647
+ ), s.uniforms.uGradientStops.value[a] = n.stop;
648
+ } else
649
+ s.uniforms.uGradientColors.value[a].set(0, 0, 0, 0), s.uniforms.uGradientStops.value[a] = 1;
650
+ } else
651
+ s.uniforms.uGradientCount.value = 0;
652
+ }
653
+ for (const o of Object.keys(e))
654
+ o !== "width" && o !== "height" && o !== "borderRadius" && o !== "borderWidth" && o !== "backgroundColor" && o !== "borderColor" && o !== "opacity" && o !== "bgOpacity" && o !== "borderOpacity" && o !== "texture" && o !== "backgroundImage" && s.uniforms[o] !== void 0 && (s.uniforms[o].value !== void 0 && s.uniforms[o].value !== null && typeof s.uniforms[o].value.set == "function" ? Array.isArray(e[o]) ? s.uniforms[o].value.set(...e[o]) : e[o] !== void 0 && (e[o].copy ? s.uniforms[o].value.copy(e[o]) : s.uniforms[o].value = e[o]) : s.uniforms[o].value = e[o]);
655
+ }
656
+ function Ae(s, e) {
657
+ var a, n, c, h;
658
+ if (e == null) {
659
+ s.set(0, 0, 0, 0);
660
+ return;
661
+ }
662
+ if (typeof e == "number") {
663
+ s.set(e, e, e, e);
664
+ return;
665
+ }
666
+ if (Array.isArray(e)) {
667
+ s.set(e[0], e[1], e[2], e[3]);
668
+ return;
669
+ }
670
+ const t = e.split("/")[0].trim().split(/\s+/), i = ee(t[0]), r = ee((a = t[1]) != null ? a : t[0]), l = ee((n = t[2]) != null ? n : t[0]), o = ee((h = (c = t[3]) != null ? c : t[1]) != null ? h : t[0]);
671
+ s.set(i, r, l, o);
672
+ }
673
+ const H = {
674
+ create(s, e, t, i, r, l = 2, o = null, a) {
675
+ return s === "BOX" ? Qe(
676
+ e,
677
+ i,
678
+ r,
679
+ o,
680
+ a
681
+ ) : s === "TEXT" ? new We(
682
+ t || "",
683
+ e,
684
+ i,
685
+ r,
686
+ l
687
+ ) : new v.MeshBasicMaterial({ visible: !1 });
688
+ },
689
+ update(s, e, t, i, r, l, o = 2, a) {
690
+ e === "BOX" ? Ze(
691
+ s,
692
+ t,
693
+ r,
694
+ l,
695
+ a
696
+ ) : e === "TEXT" && s.updateText(
697
+ i || "",
698
+ t,
699
+ r,
700
+ l,
701
+ o
702
+ );
703
+ },
704
+ forceUpdateUniforms(s, e) {
705
+ ye(s, e);
232
706
  }
233
707
  };
234
- class V {
235
- constructor(e, t, r) {
236
- h(this, "canvas");
237
- h(this, "scene");
238
- h(this, "camera");
239
- h(this, "renderer");
240
- h(this, "renderTarget", null);
241
- h(this, "renderOrder", 0);
242
- h(this, "qualityFactor", 2);
243
- h(this, "mode", "overlay");
244
- h(this, "clipArea", 1);
245
- h(this, "target");
246
- h(this, "mountContainer");
247
- h(this, "targetRect");
248
- h(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 i = this.targetRect.width, a = this.targetRect.height;
252
- this.camera = new d.OrthographicCamera(
253
- i / -2,
254
- i / 2,
255
- a / 2,
256
- a / -2,
708
+ class et {
709
+ constructor(e) {
710
+ u(this, "observer");
711
+ u(this, "textures", /* @__PURE__ */ new WeakMap());
712
+ u(this, "loadStatus", /* @__PURE__ */ new WeakMap());
713
+ u(this, "elementUrls", /* @__PURE__ */ new WeakMap());
714
+ u(this, "onUpdate");
715
+ this.onUpdate = e, this.observer = new IntersectionObserver(
716
+ (t) => {
717
+ for (const i of t) {
718
+ const r = i.target;
719
+ i.isIntersecting ? this.loadTexture(r) : this.disposeTexture(r);
720
+ }
721
+ },
722
+ { rootMargin: "300px" }
723
+ );
724
+ }
725
+ register(e, t) {
726
+ if (e.nodeType !== Node.ELEMENT_NODE)
727
+ return;
728
+ this.elementUrls.get(e) !== t && (this.elementUrls.set(e, t), this.observer.unobserve(e), this.observer.observe(e));
729
+ }
730
+ unregister(e) {
731
+ e.nodeType === Node.ELEMENT_NODE && this.observer.unobserve(e), this.disposeTexture(e), this.elementUrls.delete(e), this.loadStatus.delete(e);
732
+ }
733
+ loadTexture(e) {
734
+ return we(this, null, function* () {
735
+ if (this.loadStatus.get(e) || this.textures.has(e))
736
+ return;
737
+ const t = this.elementUrls.get(e);
738
+ if (t) {
739
+ this.loadStatus.set(e, !0);
740
+ try {
741
+ let i;
742
+ if (t.startsWith("data:image/svg+xml"))
743
+ i = yield new Promise((l, o) => {
744
+ const a = new Image();
745
+ a.onload = () => l(a), a.onerror = o, a.src = t;
746
+ });
747
+ else {
748
+ const o = yield (yield fetch(t)).blob();
749
+ i = yield createImageBitmap(o, { imageOrientation: "flipY" });
750
+ }
751
+ if (this.elementUrls.get(e) !== t) {
752
+ "close" in i && i.close();
753
+ return;
754
+ }
755
+ const r = new v.Texture(i);
756
+ i instanceof HTMLImageElement || (r.flipY = !1), r.colorSpace = v.LinearSRGBColorSpace, r.needsUpdate = !0, this.textures.set(e, r), this.onUpdate(e, r);
757
+ } catch (i) {
758
+ console.warn("[MirageEngine] Failed to load texture:", t, i);
759
+ } finally {
760
+ this.elementUrls.has(e) && this.loadStatus.set(e, !1);
761
+ }
762
+ }
763
+ });
764
+ }
765
+ disposeTexture(e) {
766
+ const t = this.textures.get(e);
767
+ t && (t.dispose(), this.textures.delete(e), this.onUpdate(e, null)), this.loadStatus.set(e, !1);
768
+ }
769
+ get(e) {
770
+ return this.textures.get(e);
771
+ }
772
+ disposeAll() {
773
+ this.observer.disconnect();
774
+ }
775
+ }
776
+ class tt {
777
+ constructor(e, t, i, r) {
778
+ u(this, "canvas");
779
+ u(this, "scene");
780
+ u(this, "camera");
781
+ u(this, "renderer");
782
+ u(this, "renderTargets", []);
783
+ u(this, "renderOrder", 0);
784
+ u(this, "qualityFactor", 2);
785
+ u(this, "mode", "overlay");
786
+ u(this, "clipArea", 1);
787
+ u(this, "targetLayer", "base");
788
+ u(this, "target");
789
+ u(this, "mountContainer");
790
+ u(this, "registry");
791
+ u(this, "targetRect");
792
+ u(this, "travelersByLayer", Array.from(
793
+ { length: O.MAX_LAYERS },
794
+ () => /* @__PURE__ */ new Set()
795
+ ));
796
+ u(this, "textureManager");
797
+ // private meshMap: Map<HTMLElement, THREE.Mesh> = new Map();
798
+ u(this, "fixedMeshes", /* @__PURE__ */ new Set());
799
+ var a, n, c, h;
800
+ this.target = e, this.mountContainer = i, this.registry = r, this.textureManager = new et((f, b) => {
801
+ const p = this.registry.get(f);
802
+ p && p.material instanceof v.ShaderMaterial && H.forceUpdateUniforms(p.material, { texture: b });
803
+ }), this.mode = (a = t.mode) != null ? a : "overlay", this.clipArea = (n = t.travelerClipArea) != null ? n : 1, this.targetLayer = (c = t.layer) != null ? c : "base", this.canvas = document.createElement("canvas"), this.scene = new v.Scene(), this.targetRect = this.target.getBoundingClientRect();
804
+ const l = this.targetRect.width, o = this.targetRect.height;
805
+ this.camera = new v.OrthographicCamera(
806
+ l / -2,
807
+ l / 2,
808
+ o / 2,
809
+ o / -2,
257
810
  1,
258
811
  1e3
259
- ), this.camera.position.z = 100, this.camera.layers.set(0), this.renderer = new d.WebGLRenderer({
812
+ ), this.camera.position.z = 100, this.camera.layers.set(this.getSceneLayer()), this.renderer = new v.WebGLRenderer({
260
813
  canvas: this.canvas,
261
814
  alpha: !0,
262
815
  antialias: !0
263
816
  // [new]
264
817
  // premultipliedAlpha: true
265
- }), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setSize(i, a), this.applyTextQuality((l = t.quality) != null ? l : "medium");
818
+ }), v.ColorManagement.enabled = !1, this.renderer.outputColorSpace = v.LinearSRGBColorSpace, this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setSize(l, o), this.applyTextQuality((h = t.quality) != null ? h : "medium");
819
+ }
820
+ getSceneLayer() {
821
+ return typeof this.targetLayer == "number" ? this.targetLayer : this.targetLayer === "selected" ? A.SELECTED : A.BASE;
266
822
  }
267
823
  createRenderTarget() {
268
- this.renderTarget = new d.WebGLRenderTarget(
269
- this.targetRect.width * this.qualityFactor,
270
- this.targetRect.height * this.qualityFactor,
271
- {
272
- minFilter: d.LinearFilter,
273
- magFilter: d.LinearFilter,
274
- format: d.RGBAFormat,
275
- stencilBuffer: !1,
276
- depthBuffer: !0,
277
- samples: 4
278
- }
279
- );
824
+ for (let e = 0; e < O.MAX_LAYERS; e++)
825
+ this.renderTargets.push(
826
+ new v.WebGLRenderTarget(
827
+ this.targetRect.width * this.qualityFactor,
828
+ this.targetRect.height * this.qualityFactor,
829
+ {
830
+ minFilter: v.LinearFilter,
831
+ magFilter: v.LinearFilter,
832
+ format: v.RGBAFormat,
833
+ stencilBuffer: !1,
834
+ depthBuffer: !0
835
+ }
836
+ )
837
+ );
280
838
  }
281
839
  applyTextQuality(e) {
282
840
  if (typeof e == "number") {
@@ -291,6 +849,8 @@ class V {
291
849
  this.qualityFactor = 4;
292
850
  break;
293
851
  case "medium":
852
+ this.qualityFactor = 2;
853
+ break;
294
854
  default:
295
855
  this.qualityFactor = 2;
296
856
  break;
@@ -302,358 +862,697 @@ class V {
302
862
  updateCanvasLayout() {
303
863
  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
864
  }
865
+ updateUniforms(e, t) {
866
+ const i = this.registry.get(e);
867
+ i && (i.traverse((r) => {
868
+ r.isMesh && r.material && H.forceUpdateUniforms(
869
+ r.material,
870
+ t
871
+ );
872
+ }), i.userData.nativeMesh && i.userData.nativeMesh.traverse((r) => {
873
+ r.isMesh && r.material && H.forceUpdateUniforms(
874
+ r.material,
875
+ t
876
+ );
877
+ }));
878
+ }
305
879
  dispose() {
306
- this.renderer.dispose(), this.canvas.remove();
880
+ this.renderer.dispose(), this.canvas.remove(), this.textureManager.disposeAll();
307
881
  }
308
882
  setSize(e, t) {
309
- this.renderer.setSize(e, t), this.renderTarget && this.renderTarget.setSize(
310
- e * this.qualityFactor,
311
- t * this.qualityFactor
312
- ), this.camera.left = e / -2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = t / -2, this.camera.updateProjectionMatrix();
313
- }
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, i = 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()) : i ? (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));
321
- }
322
- reconcileNode(e, t) {
883
+ this.renderer.setSize(e, t);
884
+ for (const i of this.renderTargets)
885
+ i.setSize(e * this.qualityFactor, t * this.qualityFactor);
886
+ this.camera.left = e / -2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = t / -2, this.camera.updateProjectionMatrix();
887
+ }
888
+ syncScene(e, t) {
889
+ const i = this.target.getBoundingClientRect(), r = Math.abs(i.width - this.targetRect.width) > 0.1 || Math.abs(i.height - this.targetRect.height) > 0.1, l = this.mode === "overlay" && (Math.abs(i.top - this.targetRect.top) > 0.1 || Math.abs(i.left - this.targetRect.left) > 0.1);
890
+ r ? (this.targetRect = i, this.setSize(this.targetRect.width, this.targetRect.height), this.updateCanvasLayout()) : l ? (this.targetRect = i, this.updateCanvasLayout()) : this.targetRect = i, this.renderOrder = 0, this.reconcileNode(e), t.size > 0 && t.forEach((o) => {
891
+ const a = this.registry.get(o);
892
+ if (a) {
893
+ this.scene.remove(a);
894
+ for (const n of this.travelersByLayer)
895
+ n.delete(a);
896
+ this.fixedMeshes.delete(a), a.geometry.dispose(), a.userData.nativeMesh && (this.scene.remove(a.userData.nativeMesh), Array.isArray(a.userData.nativeMesh.material) ? a.userData.nativeMesh.material.forEach((n) => n.dispose()) : a.userData.nativeMesh.material.dispose(), a.userData.nativeMesh.geometry.dispose()), a.traverse((n) => {
897
+ n instanceof v.Mesh && (n.geometry && n.geometry.dispose(), n.material && (Array.isArray(n.material) ? n.material.forEach((c) => c.dispose()) : n.material.dispose()));
898
+ }), this.registry.remove(o), this.textureManager.unregister(o);
899
+ }
900
+ });
901
+ }
902
+ // 탐색 후 완성된 Scene node를 이용하여 mesh를 만들거나 조정
903
+ // => 이 과정에서 scene node에 있는 ele를 넣은 hash => activeElements
904
+ // => 이후 activeElements를 이용하여 mesh를 정리!!!+ map에서도 삭제
905
+ // private reconcileNode(node: SceneNode, activeElements: Set<HTMLElement>) {
906
+ reconcileNode(e) {
323
907
  var i;
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(
908
+ let t = this.registry.get(e.element);
909
+ if (!t) {
910
+ const r = new v.PlaneGeometry(1, 1), l = e.isTraveler ? (i = this.renderTargets[e.captureLayer - 2]) == null ? void 0 : i.texture : this.textureManager.get(e.element), o = H.create(
330
911
  "BOX",
331
912
  e.styles,
332
913
  "",
333
914
  e.rect.width,
334
915
  e.rect.height,
335
916
  this.qualityFactor,
336
- e.isTraveler ? (i = this.renderTarget) == null ? void 0 : i.texture : void 0,
917
+ l,
337
918
  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);
919
+ );
920
+ t = new v.Mesh(r, o), e.type === "TEXT" && (t.name = "BG_MESH"), this.scene.add(t), this.registry.register(e.element, t), t.userData.baseMaterial = o;
339
921
  }
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);
922
+ if (this.updateMeshProperties(t, e), this.updateMeshLayers(t, e), e.isTraveler)
923
+ for (let r = 0; r < O.MAX_LAYERS; r++)
924
+ r === e.captureLayer - 2 ? this.travelersByLayer[r].add(t) : this.travelersByLayer[r].delete(t);
925
+ else
926
+ for (const r of this.travelersByLayer)
927
+ r.delete(t);
928
+ 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")
929
+ for (const r of e.children)
930
+ this.reconcileNode(r);
343
931
  else
344
- e.type === "TEXT" && this.reconcileTextChild(r, e);
932
+ e.type === "TEXT" && (this.reconcileTextChild(t, e, !1), t.userData.nativeMesh && e.nativeStyles && this.reconcileTextChild(t.userData.nativeMesh, e, !0));
345
933
  }
346
- reconcileTextChild(e, t) {
347
- var o, l;
348
- let r = e.children.find(
349
- (c) => c.name === "TEXT_CHILD"
350
- );
351
- const i = JSON.stringify(t.textStyles), a = (o = r == null ? void 0 : r.userData) == null ? void 0 : o.styleHash;
352
- if (!r || t.dirtyMask & _ || i !== a) {
353
- r && ((l = r.material.map) == null || l.dispose(), r.geometry.dispose(), e.remove(r));
354
- const c = 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, c), r.name = "TEXT_CHILD", r.userData = { styleHash: i }, this.updateMeshLayers(r, t), r.position.z = 5e-3, e.add(r);
363
- }
364
- if (r) {
365
- const c = e.userData.domRect, m = c.x + c.width / 2, f = c.y + c.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);
934
+ reconcileTextChild(e, t, i) {
935
+ var c;
936
+ const r = t.textLines || [
937
+ { text: t.textContent || "", rect: t.rect }
938
+ ], l = i ? t.nativeStyles : t.textStyles, o = JSON.stringify(l) + t.textContent + r.map((h) => h.text).join("|"), a = (c = e.userData) == null ? void 0 : c.textChildStyleHash;
939
+ if (t.dirtyMask & ve || o !== a) {
940
+ e.children.filter(
941
+ (d) => d.name.startsWith("TEXT_CHILD")
942
+ ).forEach((d) => {
943
+ var w;
944
+ const g = d;
945
+ (w = g.material.map) == null || w.dispose(), g.geometry.dispose(), e.remove(g);
946
+ });
947
+ const f = t.rect, b = f.x + f.width / 2, p = f.y + f.height / 2;
948
+ r.forEach((d, g) => {
949
+ const w = H.create(
950
+ "TEXT",
951
+ l,
952
+ d.text,
953
+ d.rect.width,
954
+ d.rect.height,
955
+ this.qualityFactor
956
+ ), L = new v.PlaneGeometry(1, 1), R = new v.Mesh(L, w);
957
+ R.name = `TEXT_CHILD_${g}`;
958
+ const E = t.rect.width === 0 ? 1 : d.rect.width / t.rect.width, x = t.rect.height === 0 ? 1 : d.rect.height / t.rect.height;
959
+ R.scale.set(E, x, 1);
960
+ const U = d.rect.x + d.rect.width / 2, F = d.rect.y + d.rect.height / 2, _ = U - b, D = -(F - p);
961
+ R.position.set(
962
+ t.rect.width === 0 ? 0 : _ / t.rect.width,
963
+ t.rect.height === 0 ? 0 : D / t.rect.height,
964
+ 5e-3
965
+ ), e.add(R);
966
+ }), e.userData.textChildStyleHash = o;
367
967
  }
968
+ e.children.forEach((h) => {
969
+ if (!h.name.startsWith("TEXT_CHILD"))
970
+ return;
971
+ const f = h, b = t.visibility & P ? A.BASE : A.HIDDEN;
972
+ if (f.layers.set(b), t.visibility & Z && f.layers.enable(A.SELECTED), t.visibility & P)
973
+ if (!i && t.nativeLayer !== void 0 && t.nativeStyles !== void 0)
974
+ for (let p = t.captureLayer; p < t.nativeLayer; p++)
975
+ f.layers.enable(A.getCaptureLayer(p));
976
+ else if (i && t.nativeLayer !== void 0)
977
+ for (let p = Math.max(t.captureLayer, t.nativeLayer); p <= O.MAX_LAYERS + 1; p++)
978
+ f.layers.enable(A.getCaptureLayer(p));
979
+ else
980
+ for (let p = t.captureLayer; p <= O.MAX_LAYERS + 1; p++)
981
+ f.layers.enable(A.getCaptureLayer(p));
982
+ });
368
983
  }
369
984
  updateMeshProperties(e, t) {
370
- var p;
371
- const { rect: r, styles: i } = 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;
985
+ var U, F, _;
986
+ const { rect: i, styles: r } = t, l = this.renderer.getPixelRatio(), o = this.renderer.domElement.width / l, a = this.renderer.domElement.height / l;
987
+ e.material = e.userData.baseMaterial, e.scale.set(i.width, i.height, 1), e.userData.domRect = pe(G({}, i), {
988
+ width: i.width,
989
+ height: i.height
990
+ });
991
+ const n = 1e-3;
374
992
  this.renderOrder++;
375
- const c = this.targetRect.left + window.scrollX, m = this.targetRect.top + window.scrollY, f = r.x - c, g = r.y - m;
993
+ const c = this.targetRect.left + window.scrollX, h = this.targetRect.top + window.scrollY, f = i.x - c, b = i.y - h, p = f - o / 2 + i.width / 2, d = -b + a / 2 - i.height / 2;
376
994
  e.position.set(
377
- f - n / 2 + r.width / 2,
378
- -g + o / 2 - r.height / 2,
379
- i.zIndex + this.renderOrder * l
380
- ), D.update(
381
- e.material,
995
+ p,
996
+ d,
997
+ r.zIndex + this.renderOrder * n
998
+ );
999
+ const g = i.x, w = i.y;
1000
+ e.userData.basePosition = { x: p, y: d }, e.userData.originalBasePosition = { x: p, y: d }, e.userData.baseSize = { width: i.width, height: i.height }, e.userData.baseDOM = { x: g, y: w }, e.userData.isFixed = t.isFixed, e.userData.initialScroll = { x: window.scrollX, y: window.scrollY };
1001
+ const L = t.element.nodeType === Node.TEXT_NODE ? t.element.parentElement : t.element, R = window.getComputedStyle(L);
1002
+ let E = 0, x = 0;
1003
+ if (R.transform && R.transform !== "none") {
1004
+ const D = new DOMMatrix(R.transform);
1005
+ E = D.m41, x = D.m42;
1006
+ }
1007
+ if (e.userData.baseTransform = { x: E, y: x }, delete e.userData.originRatioX, delete e.userData.originRatioY, H.update(
1008
+ e.userData.baseMaterial,
382
1009
  "BOX",
383
- t.styles,
1010
+ r,
384
1011
  "",
385
- t.rect.width,
386
- t.rect.height,
1012
+ i.width,
1013
+ i.height,
387
1014
  this.qualityFactor,
388
- t.isTraveler ? (p = this.renderTarget) == null ? void 0 : p.texture : void 0
389
- );
1015
+ t.isTraveler ? (U = this.renderTargets[t.captureLayer - 2]) == null ? void 0 : U.texture : this.textureManager.get(t.element)
1016
+ ), t.nativeStyles && t.nativeRect) {
1017
+ if (!e.userData.nativeMesh) {
1018
+ const $ = H.create(
1019
+ "BOX",
1020
+ t.nativeStyles,
1021
+ "",
1022
+ t.nativeRect.width,
1023
+ t.nativeRect.height,
1024
+ this.qualityFactor,
1025
+ t.isTraveler ? (F = this.renderTargets[t.captureLayer - 2]) == null ? void 0 : F.texture : this.textureManager.get(t.element),
1026
+ t.shaderHooks
1027
+ ), V = new v.Mesh(e.geometry, $);
1028
+ t.type === "TEXT" && (V.name = "BG_MESH"), this.scene.add(V), e.userData.nativeMesh = V;
1029
+ }
1030
+ const D = e.userData.nativeMesh, I = t.nativeRect.x - c, K = t.nativeRect.y - h, J = I - o / 2 + t.nativeRect.width / 2, Q = -K + a / 2 - t.nativeRect.height / 2;
1031
+ D.scale.set(t.nativeRect.width, t.nativeRect.height, 1), D.position.set(
1032
+ J,
1033
+ Q,
1034
+ t.nativeStyles.zIndex + this.renderOrder * n
1035
+ ), H.update(
1036
+ D.material,
1037
+ "BOX",
1038
+ t.nativeStyles,
1039
+ "",
1040
+ t.nativeRect.width,
1041
+ t.nativeRect.height,
1042
+ this.qualityFactor,
1043
+ t.isTraveler ? (_ = this.renderTargets[t.captureLayer - 2]) == null ? void 0 : _.texture : this.textureManager.get(t.element)
1044
+ );
1045
+ } else
1046
+ 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);
390
1047
  }
391
1048
  updateMeshLayers(e, t) {
392
- const r = (1 - (t.visibility & x)) * 30;
393
- e.layers.set(r), t.visibility === (x | w) && e.layers.enable(29);
394
- }
395
- 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)
1049
+ const i = t.visibility & P ? A.BASE : A.HIDDEN;
1050
+ if (e.layers.set(i), t.visibility & Z && e.layers.enable(A.SELECTED), e.userData.nativeMesh && t.nativeLayer !== void 0) {
1051
+ const r = e.userData.nativeMesh;
1052
+ if (r.layers.set(A.HIDDEN), t.visibility & P) {
1053
+ for (let l = t.captureLayer; l < t.nativeLayer; l++)
1054
+ e.layers.enable(A.getCaptureLayer(l));
1055
+ for (let l = Math.max(t.captureLayer, t.nativeLayer); l <= O.MAX_LAYERS + 1; l++)
1056
+ r.layers.enable(A.getCaptureLayer(l));
1057
+ }
1058
+ } else if (t.visibility & P)
1059
+ for (let r = t.captureLayer; r <= O.MAX_LAYERS + 1; r++)
1060
+ e.layers.enable(A.getCaptureLayer(r));
1061
+ }
1062
+ captureRenderTarget(e, t, i) {
1063
+ if (e.size === 0 || !i)
400
1064
  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 i = new d.Vector3(), a = this.targetRect.width, n = this.targetRect.height, o = this.renderer.getPixelRatio();
404
- for (const l of e) {
405
- i.setFromMatrixPosition(l.matrixWorld), i.project(this.camera);
406
- const c = (i.x + 1) / 2 * a, m = (i.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 = c - 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);
1065
+ const r = new v.Color(), l = this.renderer.getClearAlpha();
1066
+ 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);
1067
+ const o = new v.Vector3(), a = this.targetRect.width, n = this.targetRect.height, c = this.renderer.getPixelRatio();
1068
+ for (const h of e) {
1069
+ o.setFromMatrixPosition(h.matrixWorld), o.project(this.camera);
1070
+ const f = (o.x + 1) / 2 * a, b = (o.y + 1) / 2 * n;
1071
+ let p = 0, d = 1;
1072
+ typeof this.clipArea == "number" ? d = this.clipArea : this.clipArea.endsWith("%") ? d = parseFloat(this.clipArea) / 100 : this.clipArea.endsWith("px") && (p = parseFloat(this.clipArea));
1073
+ const g = h.scale.x * d + 0.5, w = h.scale.y * d + 0.5, L = f - g / 2, R = b - w / 2, E = (L * this.qualityFactor - p) / c, x = (R * this.qualityFactor - p) / c, U = (g * this.qualityFactor + p * 2) / c, F = (w * this.qualityFactor + p * 2) / c;
1074
+ this.renderer.setScissor(E, x, U, F), this.renderer.render(this.scene, this.camera);
411
1075
  }
412
- this.renderer.setScissorTest(!1), this.renderer.autoClear = !0, this.renderer.setRenderTarget(null), this.camera.layers.set(28), this.renderer.setClearColor(t, r);
1076
+ this.renderer.setScissorTest(!1), this.renderer.autoClear = !0, this.renderer.setRenderTarget(null), this.camera.layers.set(this.getSceneLayer()), this.renderer.setClearColor(r, l);
413
1077
  }
414
1078
  render() {
415
- this.renderTarget && this.captureRenderTarget(), this.renderer.render(this.scene, this.camera);
416
- }
417
- // for debugging
418
- showScissoredRenderTarget() {
419
- if (!this.renderTarget)
420
- return;
421
- const e = this.targetRect.width, t = this.targetRect.height, r = new d.PlaneGeometry(e, t), i = new d.MeshBasicMaterial({
422
- map: this.renderTarget.texture,
423
- side: d.DoubleSide,
424
- transparent: !0,
425
- opacity: 0.8
426
- }), a = new d.Mesh(r, i);
427
- a.position.set(0, 0, 90), a.layers.set(28), this.scene.add(a);
1079
+ for (let e = 0; e < O.MAX_LAYERS; e++) {
1080
+ const t = e + 1;
1081
+ this.captureRenderTarget(
1082
+ this.travelersByLayer[e],
1083
+ A.getCaptureLayer(t),
1084
+ this.renderTargets[e]
1085
+ );
1086
+ }
1087
+ this.renderer.render(this.scene, this.camera);
428
1088
  }
429
1089
  }
430
- function j(s) {
431
- const e = document.createRange();
432
- e.selectNodeContents(s);
433
- const t = e.getBoundingClientRect();
434
- return {
435
- left: t.left,
436
- top: t.top,
437
- width: t.width,
438
- height: t.height
439
- };
1090
+ function rt(s) {
1091
+ const e = s.textContent || "", t = [];
1092
+ let i = "", r = null, l = -1;
1093
+ const o = (c, h) => {
1094
+ for (let f = 0; f < c.length; f++) {
1095
+ const b = c[f], p = document.createRange();
1096
+ p.setStart(s, h + f), p.setEnd(s, h + f + 1);
1097
+ const d = p.getBoundingClientRect();
1098
+ if (d.width === 0 && d.height === 0) {
1099
+ i += b;
1100
+ continue;
1101
+ }
1102
+ l === -1 || Math.abs(d.top - l) > d.height / 2 ? (i && r && t.push({
1103
+ text: i,
1104
+ rect: {
1105
+ left: r.left,
1106
+ top: r.top,
1107
+ width: r.right - r.left,
1108
+ height: r.bottom - r.top
1109
+ }
1110
+ }), i = b, r = {
1111
+ left: d.left,
1112
+ top: d.top,
1113
+ right: d.right,
1114
+ bottom: d.bottom
1115
+ }, l = d.top) : (i += b, r && (r.left = Math.min(r.left, d.left), r.top = Math.min(r.top, d.top), r.right = Math.max(r.right, d.right), r.bottom = Math.max(
1116
+ r.bottom,
1117
+ d.bottom
1118
+ )));
1119
+ }
1120
+ }, a = e.match(/[^\s\-]+\-?|\-|\s+/g) || [];
1121
+ let n = 0;
1122
+ for (const c of a) {
1123
+ const h = document.createRange();
1124
+ h.setStart(s, n), h.setEnd(s, n + c.length);
1125
+ const f = h.getClientRects();
1126
+ if (f.length > 1)
1127
+ o(c, n);
1128
+ else {
1129
+ const b = f.length === 1 ? f[0] : h.getBoundingClientRect();
1130
+ if (b.width === 0 && b.height === 0) {
1131
+ i += c, n += c.length;
1132
+ continue;
1133
+ }
1134
+ l === -1 || Math.abs(b.top - l) > b.height / 2 ? (i && r && t.push({
1135
+ text: i,
1136
+ rect: {
1137
+ left: r.left,
1138
+ top: r.top,
1139
+ width: r.right - r.left,
1140
+ height: r.bottom - r.top
1141
+ }
1142
+ }), i = c, r = {
1143
+ left: b.left,
1144
+ top: b.top,
1145
+ right: b.right,
1146
+ bottom: b.bottom
1147
+ }, l = b.top) : (i += c, 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(
1148
+ r.bottom,
1149
+ b.bottom
1150
+ )));
1151
+ }
1152
+ n += c.length;
1153
+ }
1154
+ return i && r && t.push({
1155
+ text: i,
1156
+ rect: {
1157
+ left: r.left,
1158
+ top: r.top,
1159
+ width: r.right - r.left,
1160
+ height: r.bottom - r.top
1161
+ }
1162
+ }), t.filter(
1163
+ (c) => c.text.trim().length > 0 && c.rect.width > 0 && c.rect.height > 0
1164
+ );
440
1165
  }
441
- function Q(s) {
1166
+ function Le(s) {
442
1167
  const e = parseFloat(s.fontSize);
443
1168
  let t = parseFloat(s.lineHeight);
444
1169
  isNaN(t) && (t = e * 1.2);
445
- let r = parseFloat(s.letterSpacing);
446
- return isNaN(r) && (r = 0), {
1170
+ let i = parseFloat(s.letterSpacing);
1171
+ return isNaN(i) && (i = 0), {
447
1172
  font: `${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`,
1173
+ fontSize: s.fontSize,
448
1174
  color: s.color,
449
1175
  textAlign: s.textAlign || "start",
450
1176
  textBaseline: "alphabetic",
451
1177
  direction: s.direction || "inherit",
452
1178
  lineHeight: t,
453
- letterSpacing: r
1179
+ letterSpacing: i
454
1180
  };
455
1181
  }
456
- function P(s, e = z | L | Y | _ | I, t, r) {
1182
+ function Ie(s, e = j | ae | Ye | ve | be, t, i = 1, r = 0, l = 2, o, a) {
1183
+ var V, te, re, ie, se, oe;
457
1184
  if (s.nodeType === Node.TEXT_NODE) {
458
- const u = s;
459
- if (!u.textContent || !u.textContent.trim())
1185
+ const m = s;
1186
+ if (!m.textContent || !m.textContent.trim())
460
1187
  return null;
461
- const C = u.textContent.replace(/\s+/g, " ").trim();
462
- if (C.length === 0)
1188
+ const T = m.textContent.replace(/\s+/g, " ");
1189
+ if (T.length === 0)
463
1190
  return null;
464
- const T = j(u);
465
- if (T.width === 0 || T.height === 0)
1191
+ const M = rt(m);
1192
+ if (M.length === 0)
466
1193
  return null;
467
- const A = u.parentElement, O = A ? window.getComputedStyle(A) : null;
468
- return O ? {
1194
+ const k = m.parentElement, S = k ? window.getComputedStyle(k) : null;
1195
+ if (!S)
1196
+ return null;
1197
+ const B = Math.min(...M.map((y) => y.rect.left)), C = Math.min(...M.map((y) => y.rect.top)), X = Math.max(...M.map((y) => y.rect.left + y.rect.width)), W = Math.max(...M.map((y) => y.rect.top + y.rect.height));
1198
+ return {
469
1199
  id: Math.random().toString(36).substring(2, 9),
470
1200
  type: "TEXT",
471
- element: u,
1201
+ element: m,
472
1202
  rect: {
473
- x: T.left + window.scrollX,
474
- y: T.top + window.scrollY,
475
- width: T.width,
476
- height: T.height
1203
+ x: B + window.scrollX,
1204
+ y: C + window.scrollY,
1205
+ width: X - B,
1206
+ height: W - C
477
1207
  },
478
1208
  styles: {
479
1209
  backgroundColor: "transparent",
480
- opacity: parseFloat(O.opacity),
481
- zIndex: 0,
1210
+ backgroundImage: "",
1211
+ opacity: k && k.dataset[q.KEY] === q.VALUES.HIDE ? 1 : parseFloat(S.opacity),
1212
+ zIndex: (isNaN(parseInt(S.zIndex)) ? 0 : parseInt(S.zIndex)) + r,
482
1213
  borderRadius: "0px",
483
1214
  borderColor: "transparent",
484
- borderWidth: "0px"
1215
+ borderWidth: "0px",
1216
+ isTraveler: !1
485
1217
  },
486
- textContent: C,
487
- textStyles: Q(O),
1218
+ textContent: T,
1219
+ textLines: M.map((y) => ({
1220
+ text: y.text.trim(),
1221
+ rect: {
1222
+ x: y.rect.left + window.scrollX,
1223
+ y: y.rect.top + window.scrollY,
1224
+ width: y.rect.width,
1225
+ height: y.rect.height
1226
+ }
1227
+ })),
1228
+ textStyles: Le(S),
488
1229
  dirtyMask: e,
489
1230
  visibility: t,
490
1231
  isTraveler: !1,
1232
+ captureLayer: i,
1233
+ isFixed: S.position === "fixed",
1234
+ nativeLayer: o,
1235
+ nativeStyles: a ? G(G({
1236
+ backgroundColor: "transparent",
1237
+ backgroundImage: "",
1238
+ opacity: k && k.dataset[q.KEY] === q.VALUES.HIDE ? 1 : parseFloat(S.opacity),
1239
+ zIndex: (isNaN(parseInt(S.zIndex)) ? 0 : parseInt(S.zIndex)) + r,
1240
+ borderRadius: "0px",
1241
+ borderColor: "transparent",
1242
+ borderWidth: "0px",
1243
+ isTraveler: !1
1244
+ }, Le(S)), a) : void 0,
1245
+ nativeRect: a ? {
1246
+ x: B + window.scrollX,
1247
+ y: C + window.scrollY,
1248
+ width: X - B,
1249
+ height: W - C
1250
+ } : void 0,
491
1251
  children: []
492
- } : null;
493
- }
494
- const i = s, a = i.dataset.mirageFilter;
495
- let n = t, o = t;
496
- if (a) {
497
- const u = new Set(a.split(/\s+/));
498
- for (const C of u)
499
- if (!W.includes(C))
1252
+ };
1253
+ }
1254
+ if (s.nodeType !== Node.ELEMENT_NODE)
1255
+ return null;
1256
+ const n = s, c = n.dataset[Y.KEY];
1257
+ let h = t, f = t;
1258
+ if (c) {
1259
+ const m = new Set(c.split(/\s+/));
1260
+ for (const T of m)
1261
+ if (!Se.includes(T))
500
1262
  throw new Error(
501
- `[MirageEngine] Invalid filter token: '${C}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
1263
+ `[MirageEngine] Invalid filter token: '${T}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
502
1264
  );
503
- if (u.has("end"))
1265
+ if (m.has(Y.VALUES.END))
504
1266
  return null;
505
- if (u.has("include-tree") && u.has("exclude-tree"))
1267
+ if (m.has(Y.VALUES.INCLUDE_TREE) && m.has(Y.VALUES.EXCLUDE_TREE))
506
1268
  throw new Error(
507
1269
  "[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element."
508
1270
  );
509
- if (u.has("include-self") && u.has("exclude-self"))
1271
+ if (m.has(Y.VALUES.INCLUDE_SELF) && m.has(Y.VALUES.EXCLUDE_SELF))
510
1272
  throw new Error(
511
1273
  "[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element."
512
1274
  );
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);
514
- }
515
- o = o | t & w;
516
- const l = i.dataset.mirageTravel;
517
- let c = !1;
518
- l && new Set(l.split(/\s+/)).has("traveler") && (o = o & ~w, n = n & ~w, c = !0);
519
- const m = i.dataset.mirageShader;
520
- let f;
521
- m && (f = JSON.parse(m));
522
- const g = i.getBoundingClientRect(), p = window.getComputedStyle(i);
523
- if (g.width === 0 || g.height === 0 || p.display === "none")
1275
+ m.has(Y.VALUES.INCLUDE_TREE) ? h = h | P : m.has(Y.VALUES.EXCLUDE_TREE) && (h = h & ~P), f = h, m.has(Y.VALUES.INCLUDE_SELF) ? f = f | P : m.has(Y.VALUES.EXCLUDE_SELF) && (f = f & ~P);
1276
+ }
1277
+ const b = n.dataset[z.KEY];
1278
+ if (b) {
1279
+ const m = new Set(b.split(/\s+/));
1280
+ for (const T of m)
1281
+ if (!Se.includes(T))
1282
+ throw new Error(
1283
+ `[MirageEngine] Invalid select token: '${T}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
1284
+ );
1285
+ if (m.has(z.VALUES.END))
1286
+ return null;
1287
+ if (m.has(z.VALUES.INCLUDE_TREE) && m.has(z.VALUES.EXCLUDE_TREE))
1288
+ throw new Error(
1289
+ "[MirageEngine] Conflicting selects: 'include-tree' and 'exclude-tree' cannot be used together on the same element."
1290
+ );
1291
+ if (m.has(z.VALUES.INCLUDE_SELF) && m.has(z.VALUES.EXCLUDE_SELF))
1292
+ throw new Error(
1293
+ "[MirageEngine] Conflicting selects: 'include-self' and 'exclude-self' cannot be used together on the same element."
1294
+ );
1295
+ m.has(z.VALUES.INCLUDE_TREE) ? h = h | Z : m.has(z.VALUES.EXCLUDE_TREE) && (h = h & ~Z), f = h, m.has(z.VALUES.INCLUDE_SELF) ? f = f | Z : m.has(z.VALUES.EXCLUDE_SELF) && (f = f & ~Z);
1296
+ }
1297
+ const p = n.dataset[O.KEY];
1298
+ let d = !1, g = a ? G({}, a) : {}, w = o;
1299
+ if (p) {
1300
+ let m = 1;
1301
+ const T = p.indexOf("{"), M = p.lastIndexOf("}");
1302
+ let k = p;
1303
+ if (T !== -1 && M !== -1 && M > T) {
1304
+ k = p.substring(0, T).trim();
1305
+ const C = p.substring(T, M + 1);
1306
+ try {
1307
+ g = new Function("return " + C)();
1308
+ } catch (X) {
1309
+ console.warn(
1310
+ `[MirageEngine] Failed to parse travel styles JSON: ${C}`
1311
+ );
1312
+ }
1313
+ }
1314
+ const S = k.split(/\s+/);
1315
+ let B = !1;
1316
+ if (S.includes(O.VALUES.TRAVELER)) {
1317
+ d = !0, B = !0;
1318
+ const C = S.find((X) => !isNaN(parseInt(X, 10)));
1319
+ C && (m = parseInt(C, 10));
1320
+ } else if (S.includes(O.VALUES.NATIVE)) {
1321
+ d = !1;
1322
+ const C = S.find((X) => !isNaN(parseInt(X, 10)));
1323
+ C && (w = parseInt(C, 10));
1324
+ }
1325
+ if (B) {
1326
+ const C = m + 1;
1327
+ if (C < i)
1328
+ throw new Error(
1329
+ `[MirageEngine] Traveler layer (${m}) cannot be smaller than inherited capture layer (${i - 1}).`
1330
+ );
1331
+ i = Math.min(C, O.MAX_LAYERS + 1);
1332
+ }
1333
+ }
1334
+ const L = n.dataset[Ne.KEY];
1335
+ let R;
1336
+ L && (R = JSON.parse(L));
1337
+ const E = n.getBoundingClientRect(), x = window.getComputedStyle(n);
1338
+ if (E.width === 0 || E.height === 0 || x.display === "none")
524
1339
  return null;
525
- let y = i.getAttribute("data-mid");
526
- y || (y = Math.random().toString(36).substring(2, 11), i.setAttribute("data-mid", y));
527
- const v = parseInt(p.zIndex), B = {
528
- backgroundColor: p.backgroundColor,
529
- opacity: parseFloat(p.opacity),
530
- zIndex: isNaN(v) ? 0 : v,
531
- borderRadius: p.borderRadius,
532
- borderColor: p.borderColor,
533
- borderWidth: p.borderWidth
534
- };
535
- let M, F;
536
- const b = [];
537
- return Array.from(i.childNodes).forEach((u) => {
538
- const C = u.nodeType === Node.TEXT_NODE ? o : n, T = P(
539
- u,
1340
+ let U = n.getAttribute("data-mid");
1341
+ U || (U = Math.random().toString(36).substring(2, 11), n.setAttribute("data-mid", U));
1342
+ const F = parseInt(x.zIndex), _ = (isNaN(F) ? 0 : F) + r;
1343
+ let D;
1344
+ if (n.tagName === "IMG")
1345
+ D = n.src;
1346
+ else if (n.tagName.toLowerCase() === "svg") {
1347
+ const m = n.cloneNode(!0), T = g == null ? void 0 : g.color, M = g == null ? void 0 : g.fill, k = g == null ? void 0 : g.stroke, S = g == null ? void 0 : g.opacity, B = (y, xe) => {
1348
+ const N = window.getComputedStyle(y), ne = xe, ke = N.fill === N.color, Ue = N.stroke === N.color, de = M || (ke ? T : void 0) || N.fill;
1349
+ de && de !== "none" && (ne.style.fill = de);
1350
+ const ue = k || (Ue ? T : void 0) || N.stroke;
1351
+ ue && ue !== "none" && (ne.style.stroke = ue), N.strokeWidth && N.strokeWidth !== "0px" && (ne.style.strokeWidth = N.strokeWidth);
1352
+ const Ee = T || N.color;
1353
+ Ee && (ne.style.color = Ee);
1354
+ const fe = S || N.opacity;
1355
+ fe && fe !== "1" && (ne.style.opacity = fe);
1356
+ for (let ce = 0; ce < y.children.length; ce++)
1357
+ B(y.children[ce], xe.children[ce]);
1358
+ };
1359
+ B(n, m);
1360
+ const C = n.getBoundingClientRect(), X = window.devicePixelRatio * l;
1361
+ m.hasAttribute("viewBox") || m.setAttribute("viewBox", `0 0 ${C.width} ${C.height}`), m.setAttribute("width", (C.width * X).toString()), m.setAttribute("height", (C.height * X).toString());
1362
+ let W = new XMLSerializer().serializeToString(m);
1363
+ W.includes("xmlns=") || (W = W.replace(
1364
+ "<svg",
1365
+ '<svg xmlns="http://www.w3.org/2000/svg"'
1366
+ )), D = `data:image/svg+xml;utf8,${encodeURIComponent(W)}`;
1367
+ } else if (x.backgroundImage && x.backgroundImage !== "none") {
1368
+ const m = x.backgroundImage.match(/url\(['"]?(.*?)['"]?\)/);
1369
+ m && (D = m[1]);
1370
+ }
1371
+ const I = {
1372
+ backgroundColor: x.backgroundColor,
1373
+ backgroundImage: x.backgroundImage,
1374
+ opacity: n.dataset[q.KEY] === q.VALUES.HIDE ? 1 : parseFloat(x.opacity),
1375
+ zIndex: _,
1376
+ borderRadius: x.borderRadius,
1377
+ borderColor: x.borderColor,
1378
+ borderWidth: x.borderWidth,
1379
+ imageSrc: D,
1380
+ isTraveler: d
1381
+ }, K = I;
1382
+ let J, Q;
1383
+ const $ = [];
1384
+ return n.tagName.toLowerCase() !== "svg" && Array.from(n.childNodes).forEach((m) => {
1385
+ const T = m.nodeType === Node.TEXT_NODE ? f : h, M = Ie(
1386
+ m,
540
1387
  e,
541
- C
1388
+ T,
1389
+ i,
1390
+ _,
1391
+ l,
1392
+ w,
1393
+ m.nodeType === Node.TEXT_NODE && Object.keys(g).length > 0 ? g : void 0
542
1394
  );
543
- T && b.push(T);
1395
+ M && $.push(M);
544
1396
  }), {
545
- id: y,
1397
+ id: U,
546
1398
  type: "BOX",
547
- element: i,
1399
+ element: n,
548
1400
  rect: {
549
- x: g.left + window.scrollX,
550
- y: g.top + window.scrollY,
551
- width: g.width,
552
- height: g.height
1401
+ x: E.left + window.scrollX,
1402
+ y: E.top + window.scrollY,
1403
+ width: E.width,
1404
+ height: E.height
553
1405
  },
554
- styles: B,
555
- textContent: M,
556
- textStyles: F,
1406
+ styles: K,
1407
+ textContent: J,
1408
+ textStyles: Q,
557
1409
  dirtyMask: e,
558
- visibility: o,
559
- isTraveler: c,
560
- children: b,
561
- shaderHooks: f
1410
+ visibility: f,
1411
+ isTraveler: d,
1412
+ captureLayer: i,
1413
+ nativeLayer: w,
1414
+ nativeStyles: w !== void 0 ? pe(G({}, I), {
1415
+ backgroundColor: (V = g.backgroundColor) != null ? V : I.backgroundColor,
1416
+ backgroundImage: (te = g.backgroundImage) != null ? te : I.backgroundImage,
1417
+ opacity: (re = g.opacity) != null ? re : I.opacity,
1418
+ zIndex: g.zIndex !== void 0 ? g.zIndex + _ : I.zIndex,
1419
+ borderRadius: (ie = g.borderRadius) != null ? ie : I.borderRadius,
1420
+ borderColor: (se = g.borderColor) != null ? se : I.borderColor,
1421
+ borderWidth: (oe = g.borderWidth) != null ? oe : I.borderWidth,
1422
+ isTraveler: I.isTraveler
1423
+ }) : void 0,
1424
+ nativeRect: w !== void 0 ? {
1425
+ x: g.x !== void 0 ? parseFloat(g.x) : E.left + window.scrollX,
1426
+ y: g.y !== void 0 ? parseFloat(g.y) : E.top + window.scrollY,
1427
+ width: g.width !== void 0 ? parseFloat(g.width) : E.width,
1428
+ height: g.height !== void 0 ? parseFloat(g.height) : E.height
1429
+ } : void 0,
1430
+ isFixed: x.position === "fixed",
1431
+ children: $,
1432
+ shaderHooks: R
562
1433
  };
563
1434
  }
564
- class Z {
565
- constructor(e, t, r) {
566
- h(this, "target");
567
- h(this, "renderer");
568
- h(this, "filter");
569
- h(this, "observer");
570
- h(this, "isDomDirty", !1);
571
- h(this, "isRunning", !1);
572
- h(this, "isTravelEnabled", !1);
573
- h(this, "pendingMask", S);
574
- h(this, "mutationTimer", null);
575
- h(this, "cssTimer", null);
576
- h(this, "resizeConfig");
577
- h(this, "resizeTimer", null);
578
- h(this, "isResizing", !1);
579
- h(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(() => {
581
- this.isDomDirty = !0, this.cssTimer = null;
582
- }, 50));
583
- });
584
- h(this, "onWindowResize", () => {
585
- if (!this.resizeConfig.enabled) {
586
- this.isDomDirty = !0;
587
- return;
588
- }
589
- this.isResizing || (this.isResizing = !0, this.resizeConfig.onStart && this.resizeConfig.onStart()), this.resizeTimer && clearTimeout(this.resizeTimer), this.resizeTimer = window.setTimeout(() => {
590
- this.isDomDirty = !0, this.resizeConfig.onEnd && this.resizeConfig.onEnd(), this.isResizing = !1, this.resizeTimer = null;
591
- }, this.resizeConfig.delay);
592
- });
593
- h(this, "renderLoop", () => {
594
- this.isRunning && (this.isDomDirty && this.forceUpdateScene(), this.renderer.render(), requestAnimationFrame(this.renderLoop));
1435
+ function it(s, e) {
1436
+ e.size !== 0 && e.forEach((t, i) => {
1437
+ var U, F, _, D, I, K, J, Q, $, V, te, re, ie, se, oe, m, T, M;
1438
+ const r = s.get(i);
1439
+ if (!r || !r.userData.basePosition)
1440
+ return;
1441
+ let { x: l, y: o } = r.userData.basePosition;
1442
+ const { width: a, height: n } = r.userData.baseSize, c = (U = t.width) != null ? U : a, h = (F = t.height) != null ? F : n, f = c - a, b = h - n;
1443
+ if (t.width !== void 0 && r.userData.originRatioX === void 0 && Math.abs(f) > 0.1) {
1444
+ const k = i.getBoundingClientRect(), S = (_ = t.x) != null ? _ : 0, B = (I = (D = r.userData.baseTransform) == null ? void 0 : D.x) != null ? I : 0, C = r.userData.isFixed ? 0 : window.scrollX;
1445
+ let y = -(k.left + C - S + B - r.userData.baseDOM.x) / f;
1446
+ Math.abs(y) < 0.05 ? y = 0 : Math.abs(y - 1) < 0.05 ? y = 1 : Math.abs(y - 0.5) < 0.05 && (y = 0.5), r.userData.originRatioX = y;
1447
+ }
1448
+ if (t.height !== void 0 && r.userData.originRatioY === void 0 && Math.abs(b) > 0.1) {
1449
+ const k = i.getBoundingClientRect(), S = (K = t.y) != null ? K : 0, B = (Q = (J = r.userData.baseTransform) == null ? void 0 : J.y) != null ? Q : 0, C = r.userData.isFixed ? 0 : window.scrollY;
1450
+ let y = -(k.top + C - S + B - r.userData.baseDOM.y) / b;
1451
+ Math.abs(y) < 0.05 ? y = 0 : Math.abs(y - 1) < 0.05 ? y = 1 : Math.abs(y - 0.5) < 0.05 && (y = 0.5), r.userData.originRatioY = y;
1452
+ }
1453
+ const p = ($ = r.userData.originRatioX) != null ? $ : 0.5, d = (V = r.userData.originRatioY) != null ? V : 0.5, g = f * (0.5 - p), w = b * (0.5 - d), L = (re = (te = r.userData.baseTransform) == null ? void 0 : te.x) != null ? re : 0, R = (se = (ie = r.userData.baseTransform) == null ? void 0 : ie.y) != null ? se : 0, E = ((oe = t.x) != null ? oe : L) - L, x = ((m = t.y) != null ? m : R) - R;
1454
+ r.position.setX(l + g + E), r.position.setY(o - (w + x)), r.scale.set(c, h, 1), H.forceUpdateUniforms(r.material, {
1455
+ backgroundColor: t.backgroundColor,
1456
+ backgroundImage: t.backgroundImage,
1457
+ opacity: t.opacity,
1458
+ borderRadius: (M = t.borderRadius) != null ? M : (T = r.userData.baseStyles) == null ? void 0 : T.borderRadius,
1459
+ width: c,
1460
+ height: h
595
1461
  });
596
- var a, n;
597
- this.target = e, this.renderer = t, this.filter = r.filter;
598
- const i = (a = r.resizeDebounce) != null ? a : !0;
599
- i === !1 ? this.resizeConfig = { enabled: !1, delay: 0 } : i === !0 ? this.resizeConfig = { enabled: !0, delay: 150 } : this.resizeConfig = {
600
- enabled: !0,
601
- delay: (n = i.delay) != null ? n : 150,
602
- onStart: i.onStart,
603
- onEnd: i.onEnd
604
- }, this.observer = new MutationObserver((o) => {
605
- let l = S;
606
- for (const c of o)
607
- c.type === "childList" ? l |= I : c.type === "attributes" && (c.attributeName === "style" || c.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;
611
- return;
612
- }
613
- this.mutationTimer && clearTimeout(this.mutationTimer), this.mutationTimer = window.setTimeout(() => {
614
- this.mutationTimer = null, this.isDomDirty = !0;
615
- }, 200);
616
- }
1462
+ });
1463
+ }
1464
+ function st(s, e, t) {
1465
+ s.forEach((i) => {
1466
+ if (i.userData.isFixed && i.userData.initialScroll && i.userData.originalBasePosition) {
1467
+ const r = e - i.userData.initialScroll.x, l = t - i.userData.initialScroll.y;
1468
+ i.userData.basePosition.x = i.userData.originalBasePosition.x + r, i.userData.basePosition.y = i.userData.originalBasePosition.y - l, i.position.x = i.userData.basePosition.x, i.position.y = i.userData.basePosition.y;
1469
+ }
1470
+ });
1471
+ }
1472
+ class ot {
1473
+ constructor(e, t, i, r) {
1474
+ u(this, "target");
1475
+ u(this, "renderer");
1476
+ u(this, "registry");
1477
+ u(this, "isTravelEnabled", !1);
1478
+ u(this, "tracker");
1479
+ this.target = e, this.renderer = t, this.registry = i, this.tracker = new Ve(e, {
1480
+ resizeDebounce: r.resizeDebounce
1481
+ }), this.tracker.onLayoutChange.add((l, o) => {
1482
+ document.querySelector(`[${O.NAME}~='${O.VALUES.TRAVELER}']`) !== null && !this.isTravelEnabled && (this.isTravelEnabled = !0, this.renderer.createRenderTarget());
1483
+ const n = Ie(
1484
+ this.target,
1485
+ l,
1486
+ P,
1487
+ 1,
1488
+ 0,
1489
+ this.renderer.qualityFactor
1490
+ );
1491
+ n && this.renderer.syncScene(n, o);
1492
+ }), this.tracker.onScrollChange.add((l, o) => {
1493
+ st(this.renderer.fixedMeshes, l, o);
1494
+ }), this.tracker.onStyleChange.add((l) => {
1495
+ it(this.registry, l);
1496
+ }), this.tracker.onRender.add(() => {
1497
+ this.renderer.render();
617
1498
  });
618
1499
  }
619
1500
  start() {
620
- this.isRunning || (this.isRunning = !0, this.observer.observe(this.target, {
621
- childList: !0,
622
- subtree: !0,
623
- attributes: !0,
624
- characterData: !0
625
- }), this.target.addEventListener("transitionend", this.onTransitionFinished), this.target.addEventListener("animationend", this.onTransitionFinished), window.addEventListener("resize", this.onWindowResize), this.forceUpdateScene(), this.renderLoop());
1501
+ this.tracker.start();
626
1502
  }
627
1503
  stop() {
628
- 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);
1504
+ this.tracker.stop();
629
1505
  }
630
- clearTimers() {
631
- this.mutationTimer && (clearTimeout(this.mutationTimer), this.mutationTimer = null), this.cssTimer && (clearTimeout(this.cssTimer), this.cssTimer = null);
1506
+ }
1507
+ class nt {
1508
+ constructor() {
1509
+ u(this, "store");
1510
+ this.store = /* @__PURE__ */ new WeakMap();
632
1511
  }
633
- forceUpdateScene() {
634
- this.isDomDirty = !1;
635
- const e = document.querySelector("[data-mirage-travel='traveler']") !== null;
636
- e && !this.isTravelEnabled && (this.isTravelEnabled = !0, this.renderer.createRenderTarget());
637
- const t = P(
638
- this.target,
639
- this.pendingMask,
640
- e ? x | w : x,
641
- this.filter
642
- );
643
- t && this.renderer.syncScene(t), this.pendingMask = S;
1512
+ register(e, t) {
1513
+ this.store.set(e, t);
1514
+ }
1515
+ get(e) {
1516
+ return this.store.get(e);
1517
+ }
1518
+ // public register(element: HTMLElement, meshGroup: THREE.Group): void {
1519
+ // this.store.set(element, meshGroup);
1520
+ // }
1521
+ // public get(element: HTMLElement): THREE.Group | undefined {
1522
+ // return this.store.get(element);
1523
+ // }
1524
+ has(e) {
1525
+ return this.store.has(e);
1526
+ }
1527
+ // Optional
1528
+ remove(e) {
1529
+ this.store.delete(e);
644
1530
  }
645
1531
  }
646
- class te {
1532
+ class ht {
647
1533
  constructor(e, t) {
648
- h(this, "renderer");
649
- h(this, "syncer");
650
- h(this, "target");
651
- var i, a, n;
652
- this.target = e;
653
- let r;
654
- if (t.mode === "duplicate" ? r = (a = (i = t.container) != null ? i : this.target.parentElement) != null ? a : void 0 : r = (n = this.target.parentElement) != null ? n : void 0, !r)
1534
+ u(this, "renderer");
1535
+ u(this, "syncer");
1536
+ u(this, "target");
1537
+ u(this, "registry");
1538
+ var r, l, o;
1539
+ if (this.target = e, this.registry = new nt(), !document.getElementById("mirage-engine-styles")) {
1540
+ const a = document.createElement("style");
1541
+ a.id = "mirage-engine-styles", a.textContent = `
1542
+ [${q.NAME}="${q.VALUES.HIDE}"] {
1543
+ opacity: 0 !important;
1544
+ }
1545
+ `, document.head.appendChild(a);
1546
+ }
1547
+ let i;
1548
+ if (t.mode === "duplicate" ? i = (l = (r = t.container) != null ? r : this.target.parentElement) != null ? l : void 0 : i = (o = this.target.parentElement) != null ? o : void 0, !i)
655
1549
  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);
1550
+ this.renderer = new tt(
1551
+ this.target,
1552
+ t,
1553
+ i,
1554
+ this.registry
1555
+ ), this.renderer.mount(), this.syncer = new ot(this.target, this.renderer, this.registry, t);
657
1556
  }
658
1557
  start() {
659
1558
  this.syncer.start();
@@ -664,17 +1563,58 @@ class te {
664
1563
  dispose() {
665
1564
  this.syncer.stop(), this.renderer.dispose();
666
1565
  }
1566
+ getTracker() {
1567
+ return this.syncer.tracker;
1568
+ }
1569
+ updateUniforms(e, t) {
1570
+ this.renderer.updateUniforms(e, t);
1571
+ }
1572
+ getCanvas() {
1573
+ return this.renderer.canvas;
1574
+ }
1575
+ test() {
1576
+ const e = this.registry.get(
1577
+ document.querySelector("#box2")
1578
+ );
1579
+ if (!e)
1580
+ return;
1581
+ const t = {
1582
+ ArrowRight: !1,
1583
+ ArrowLeft: !1,
1584
+ ArrowUp: !1,
1585
+ ArrowDown: !1
1586
+ };
1587
+ window.addEventListener("keydown", (l) => {
1588
+ t[l.key] !== void 0 && (t[l.key] = !0);
1589
+ }), window.addEventListener("keyup", (l) => {
1590
+ t[l.key] !== void 0 && (t[l.key] = !1);
1591
+ });
1592
+ const i = 2, r = () => {
1593
+ 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);
1594
+ };
1595
+ r();
1596
+ }
667
1597
  }
668
1598
  export {
669
- W as ALLOWED_FILTERS,
670
- _ as DIRTY_CONTENT,
671
- S as DIRTY_NONE,
672
- z as DIRTY_RECT,
673
- I as DIRTY_STRUCTURE,
674
- L as DIRTY_STYLE,
675
- Y as DIRTY_ZINDEX,
676
- ee as EXCLUDED,
677
- te as Engine,
678
- w as SYSTEM_LAYER,
679
- x as USER_LAYER
1599
+ Se as ALLOWED_FILTERS,
1600
+ q as ATTR_DOM,
1601
+ Y as ATTR_FILTER,
1602
+ lt as ATTR_SANDWICH,
1603
+ z as ATTR_SELECT,
1604
+ Ne as ATTR_SHADER,
1605
+ O as ATTR_TRAVEL,
1606
+ ve as DIRTY_CONTENT,
1607
+ he as DIRTY_NONE,
1608
+ j as DIRTY_RECT,
1609
+ be as DIRTY_STRUCTURE,
1610
+ ae as DIRTY_STYLE,
1611
+ Ye as DIRTY_ZINDEX,
1612
+ ct as EXCLUDED,
1613
+ ht as Engine,
1614
+ Z as SELECT_LAYER,
1615
+ A as THREE_LAYERS,
1616
+ Te as TRAVEL_VALUES,
1617
+ Ve as Tracker,
1618
+ P as USER_LAYER,
1619
+ Pe as extractFromStyle
680
1620
  };