ldr 0.33.2 → 0.33.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +294 -74
- package/dist/index.d.ts +2 -2
- package/dist/index.js +205 -65
- package/dist/load-worker.gen.d.ts +1 -1
- package/dist/model.d.ts +12 -1
- package/dist/node/build-pack.d.ts +4 -1
- package/dist/node/compile.d.ts +5 -0
- package/dist/node/index.js +415 -117
- package/dist/node/library.d.ts +9 -1
- package/dist/spec.d.ts +3 -0
- package/package.json +2 -1
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/spec.ts
|
|
2
2
|
var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
3
3
|
var COLOUR_ID_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
4
4
|
var namedCodes = new Map;
|
|
@@ -25,6 +25,8 @@ function parseColor(tok) {
|
|
|
25
25
|
}
|
|
26
26
|
var MOVED_RE = /^~?\s*moved\s+to\s+(.+)$/i;
|
|
27
27
|
var SPECIAL0 = new Set(["FILE", "NOFILE", "!DATA", "!:", "STEP", "BFC", "ROTSTEP", "BUFEXCHG", "!TEXMAP"]);
|
|
28
|
+
var BLOCK0 = new Set(["FILE", "NOFILE", "!DATA"]);
|
|
29
|
+
var MAX_COORD = 1000000000000000;
|
|
28
30
|
var PART_ORG = new Set(["part", "subpart", "primitive", "8_primitive", "48_primitive", "shortcut", "helper"]);
|
|
29
31
|
var MODEL_ORG = new Set(["model", "submodel", "configuration"]);
|
|
30
32
|
var ORG_RE = /^(?:!?LDRAW_ORG|Unofficial|Official\s+LCAD)\s+(\S+)/i;
|
|
@@ -75,7 +77,9 @@ function parseTexMap(tail, next = false) {
|
|
|
75
77
|
if (parts.length < n + 1)
|
|
76
78
|
return null;
|
|
77
79
|
const v = parts.slice(0, n).map(Number);
|
|
78
|
-
if (!v.every(Number.isFinite))
|
|
80
|
+
if (!v.every((x) => Number.isFinite(x) && Math.abs(x) <= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))
|
|
81
|
+
return null;
|
|
82
|
+
if (n >= 10 && !(Math.abs(v[9]) >= 0.000001) || n === 11 && !(Math.abs(v[10]) >= 0.000001))
|
|
79
83
|
return null;
|
|
80
84
|
let rest = m[2].trim();
|
|
81
85
|
for (let k = 0;k < n; k++)
|
|
@@ -96,7 +100,9 @@ function parseTexMap(tail, next = false) {
|
|
|
96
100
|
return t;
|
|
97
101
|
}
|
|
98
102
|
var b64 = (s) => {
|
|
99
|
-
|
|
103
|
+
let clean = s.replace(/[^A-Za-z0-9+/]/g, "");
|
|
104
|
+
if (clean.length % 4 === 1)
|
|
105
|
+
clean = clean.slice(0, -1);
|
|
100
106
|
const pad = clean + "=".repeat((4 - clean.length % 4) % 4);
|
|
101
107
|
const bin = atob(pad);
|
|
102
108
|
const out = new Uint8Array(bin.length);
|
|
@@ -124,7 +130,10 @@ function type1Fast(line) {
|
|
|
124
130
|
const t = next();
|
|
125
131
|
if (t === null)
|
|
126
132
|
return null;
|
|
127
|
-
|
|
133
|
+
const v = +t;
|
|
134
|
+
if (!Number.isFinite(v))
|
|
135
|
+
return null;
|
|
136
|
+
m[k] = v;
|
|
128
137
|
}
|
|
129
138
|
while (i < n && ws(line.charCodeAt(i)))
|
|
130
139
|
i++;
|
|
@@ -132,23 +141,37 @@ function type1Fast(line) {
|
|
|
132
141
|
return null;
|
|
133
142
|
const rest = line.slice(i);
|
|
134
143
|
const file = /[ \t]{2,}|\t/.test(rest) ? rest.split(/\s+/).join(" ") : rest;
|
|
135
|
-
|
|
144
|
+
const color = parseColor(ct);
|
|
145
|
+
if (!Number.isFinite(color))
|
|
146
|
+
return null;
|
|
147
|
+
return { t: 1, color, m, file: norm(file) };
|
|
136
148
|
}
|
|
149
|
+
var NUMS = [0, 12, 6, 9, 12, 12];
|
|
137
150
|
function geomLine(tk) {
|
|
138
151
|
const t = +tk[0];
|
|
139
|
-
if (!(t >= 1 && t <= 5) || tk.length < 2)
|
|
152
|
+
if (!(t >= 1 && t <= 5 && Number.isInteger(t)) || tk.length < 2)
|
|
153
|
+
return null;
|
|
154
|
+
const color = parseColor(tk[1]), n = NUMS[t];
|
|
155
|
+
if (!Number.isFinite(color) || tk.length < 2 + n + (t === 1 ? 1 : 0))
|
|
140
156
|
return null;
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
157
|
+
const nums = new Array(n);
|
|
158
|
+
for (let k = 0;k < n; k++) {
|
|
159
|
+
const v = +tk[2 + k];
|
|
160
|
+
if (!Number.isFinite(v))
|
|
161
|
+
return null;
|
|
162
|
+
nums[k] = v;
|
|
163
|
+
}
|
|
164
|
+
if (t === 1) {
|
|
165
|
+
const file = norm(tk.slice(14).join(" "));
|
|
166
|
+
return file ? { t: 1, color, m: nums, file } : null;
|
|
167
|
+
}
|
|
145
168
|
if (t === 2)
|
|
146
|
-
return { t: 2, color, p: nums
|
|
169
|
+
return { t: 2, color, p: nums };
|
|
147
170
|
if (t === 3)
|
|
148
|
-
return { t: 3, color, p: nums
|
|
171
|
+
return { t: 3, color, p: nums };
|
|
149
172
|
if (t === 4)
|
|
150
|
-
return { t: 4, color, p: nums
|
|
151
|
-
return { t: 5, color, p: nums
|
|
173
|
+
return { t: 4, color, p: nums };
|
|
174
|
+
return { t: 5, color, p: nums };
|
|
152
175
|
}
|
|
153
176
|
function parse(src, name = "main.ldr", popts = {}) {
|
|
154
177
|
const gtext = !!popts.geometryText;
|
|
@@ -228,7 +251,8 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
228
251
|
while (b < line.length && line.charCodeAt(b) !== 32 && line.charCodeAt(b) !== 9)
|
|
229
252
|
b++;
|
|
230
253
|
const kw = line.slice(a, b);
|
|
231
|
-
|
|
254
|
+
const k2 = /[^\x21-\x7e]/.test(kw) ? line.slice(a).trim().split(/\s+/)[0] : kw;
|
|
255
|
+
if (!SPECIAL0.has(k2) && !(k2.length >= 4 && k2.length <= 6 && BLOCK0.has(k2.toUpperCase()))) {
|
|
232
256
|
if (skip || dataCur)
|
|
233
257
|
continue;
|
|
234
258
|
if (!cur)
|
|
@@ -269,19 +293,23 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
269
293
|
const t = +tk[0];
|
|
270
294
|
if (t === 0) {
|
|
271
295
|
const text = line.slice(1).trim();
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
296
|
+
const k1 = tk.length > 1 && tk[1].length >= 4 && tk[1].length <= 6 ? tk[1].toUpperCase() : tk[1];
|
|
297
|
+
if (k1 === "FILE") {
|
|
298
|
+
const fn = text.slice(5).trimStart().split("\r")[0].trim();
|
|
299
|
+
if (fn) {
|
|
300
|
+
firstBlock();
|
|
301
|
+
skip = false;
|
|
302
|
+
start(fn);
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
277
305
|
}
|
|
278
|
-
if (
|
|
306
|
+
if (k1 === "NOFILE") {
|
|
279
307
|
closeData();
|
|
280
308
|
cur = null;
|
|
281
309
|
skip = true;
|
|
282
310
|
continue;
|
|
283
311
|
}
|
|
284
|
-
if (
|
|
312
|
+
if (k1 === "!DATA") {
|
|
285
313
|
firstBlock();
|
|
286
314
|
closeData();
|
|
287
315
|
cur = null;
|
|
@@ -314,7 +342,11 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
314
342
|
c.rotstep = { x: 0, y: 0, z: 0, mode: "END" };
|
|
315
343
|
else {
|
|
316
344
|
const mode = (tk[5] ?? "REL").toUpperCase();
|
|
317
|
-
|
|
345
|
+
const ang = (s) => {
|
|
346
|
+
const v = Number(s);
|
|
347
|
+
return Number.isFinite(v) ? v : 0;
|
|
348
|
+
};
|
|
349
|
+
c.rotstep = { x: ang(tk[2]), y: ang(tk[3]), z: ang(tk[4]), mode: ["REL", "ABS", "ADD"].includes(mode) ? mode : "REL" };
|
|
318
350
|
}
|
|
319
351
|
} else if (tk[1] === "BUFEXCHG") {
|
|
320
352
|
c.meta = "BUFEXCHG";
|
|
@@ -373,8 +405,11 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
373
405
|
if (!cur)
|
|
374
406
|
start(name);
|
|
375
407
|
const g = geomLine(tk);
|
|
376
|
-
if (!g)
|
|
408
|
+
if (!g) {
|
|
409
|
+
if (/^[2-5][ \t]/.test(line))
|
|
410
|
+
inHeader = false;
|
|
377
411
|
continue;
|
|
412
|
+
}
|
|
378
413
|
annotate(g, false);
|
|
379
414
|
cur.cmds.push(g);
|
|
380
415
|
inHeader = false;
|
|
@@ -449,12 +484,18 @@ function texmapTriangleUV(map, pts) {
|
|
|
449
484
|
} else {
|
|
450
485
|
const pd = unit3(sub3(p, p1));
|
|
451
486
|
const c = dot3(pd, n);
|
|
487
|
+
const q = radial(p, p1, n);
|
|
452
488
|
if (Math.abs(c) > 1 - 0.000000001) {
|
|
453
489
|
miss.push(i);
|
|
454
490
|
out[i * 2 + 1] = 0.5 + (c > 0 ? -Math.PI / 2 : Math.PI / 2) / B;
|
|
455
491
|
return;
|
|
456
492
|
}
|
|
457
|
-
|
|
493
|
+
if (!q) {
|
|
494
|
+
miss.push(i);
|
|
495
|
+
out[i * 2 + 1] = 0.5;
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
const a = sAng(q);
|
|
458
499
|
uSum += a;
|
|
459
500
|
out[i * 2] = 0.5 + a / A;
|
|
460
501
|
const th = -a, ct = Math.cos(th), st = Math.sin(th), cr = cross3(n, pd), k = dot3(n, pd) * (1 - ct);
|
|
@@ -529,18 +570,48 @@ function smoothNormals(pos, edges, cond, creaseDeg = 35) {
|
|
|
529
570
|
};
|
|
530
571
|
for (const [key, corners] of byV) {
|
|
531
572
|
const faces = corners.map((c) => c / 3 | 0), par = faces.map((_, i) => i);
|
|
532
|
-
const f = (i) =>
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
573
|
+
const f = (i) => {
|
|
574
|
+
let r = i;
|
|
575
|
+
while (par[r] !== r)
|
|
576
|
+
r = par[r];
|
|
577
|
+
while (par[i] !== r) {
|
|
578
|
+
const n = par[i];
|
|
579
|
+
par[i] = r;
|
|
580
|
+
i = n;
|
|
581
|
+
}
|
|
582
|
+
return r;
|
|
583
|
+
};
|
|
584
|
+
const byO = new Map;
|
|
585
|
+
for (let i = 0;i < faces.length; i++) {
|
|
586
|
+
const A = faces[i];
|
|
587
|
+
for (let k = 0;k < 3; k++) {
|
|
588
|
+
const o = vk[A * 3 + k];
|
|
589
|
+
if (o === key)
|
|
590
|
+
continue;
|
|
591
|
+
const l = byO.get(o);
|
|
592
|
+
if (!l)
|
|
593
|
+
byO.set(o, [i]);
|
|
594
|
+
else if (l[l.length - 1] !== i)
|
|
595
|
+
l.push(i);
|
|
543
596
|
}
|
|
597
|
+
}
|
|
598
|
+
for (const [o, L] of byO) {
|
|
599
|
+
if (L.length < 2)
|
|
600
|
+
continue;
|
|
601
|
+
const e = ek(key, o);
|
|
602
|
+
if ((edgeFaces.get(e)?.length ?? 0) < 2)
|
|
603
|
+
continue;
|
|
604
|
+
if (L.length > 256) {
|
|
605
|
+
for (let a = 0;a + 1 < L.length; a++)
|
|
606
|
+
if (joinable(e, faces[L[a]], faces[L[a + 1]]))
|
|
607
|
+
par[f(L[a])] = f(L[a + 1]);
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
for (let a = 0;a < L.length; a++)
|
|
611
|
+
for (let b = a + 1;b < L.length; b++)
|
|
612
|
+
if (joinable(e, faces[L[a]], faces[L[b]]))
|
|
613
|
+
par[f(L[a])] = f(L[b]);
|
|
614
|
+
}
|
|
544
615
|
const acc = new Map;
|
|
545
616
|
faces.forEach((F, i) => {
|
|
546
617
|
const r = f(i), s = acc.get(r) ?? [0, 0, 0];
|
|
@@ -731,7 +802,22 @@ function fileStepViews(f) {
|
|
|
731
802
|
viewMemo.set(f, out);
|
|
732
803
|
return out;
|
|
733
804
|
}
|
|
734
|
-
// ../../../../../../../tmp/ldr-build-
|
|
805
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/model.ts
|
|
806
|
+
class ModelLimitError extends Error {
|
|
807
|
+
limit;
|
|
808
|
+
code = "ldr-model-limit";
|
|
809
|
+
constructor(what, limit) {
|
|
810
|
+
super(`ldr: ${what} expands past ${limit.toLocaleString("en-US")} (see maxInstances)`);
|
|
811
|
+
this.limit = limit;
|
|
812
|
+
this.name = "ModelLimitError";
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
var inRange12 = (m) => {
|
|
816
|
+
for (let i = 0;i < 12; i++)
|
|
817
|
+
if (!(Math.abs(m[i]) <= MAX_COORD))
|
|
818
|
+
return false;
|
|
819
|
+
return true;
|
|
820
|
+
};
|
|
735
821
|
var CALLOUT_END = 999999;
|
|
736
822
|
var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
|
|
737
823
|
var defLine = new WeakMap;
|
|
@@ -766,6 +852,9 @@ function flatten(doc, opts = {}) {
|
|
|
766
852
|
const loose = opts.looseGeometry !== false, tx = !!opts.textures, co = !!opts.callouts;
|
|
767
853
|
const src = new Map;
|
|
768
854
|
let subs = 0;
|
|
855
|
+
const open = new Set;
|
|
856
|
+
const maxN = opts.maxInstances ?? 2000000;
|
|
857
|
+
let work = 0;
|
|
769
858
|
const lazy = (f, k) => {
|
|
770
859
|
const key = f.name + "#" + k;
|
|
771
860
|
let fn = src.get(key);
|
|
@@ -778,8 +867,11 @@ function flatten(doc, opts = {}) {
|
|
|
778
867
|
};
|
|
779
868
|
const walk = (d, fname, m, color, path, stepPath, depth, texIn, fixed = null, subPath = [], subMats = [], colour = undefined, scope0 = null) => {
|
|
780
869
|
const f = d.files.get(fname);
|
|
781
|
-
if (!f || depth > maxDepth)
|
|
870
|
+
if (!f || depth > maxDepth || open.has(f))
|
|
782
871
|
return;
|
|
872
|
+
if (++work > maxN)
|
|
873
|
+
throw new ModelLimitError("model", maxN);
|
|
874
|
+
open.add(f);
|
|
783
875
|
let scope = scope0;
|
|
784
876
|
let s = 0;
|
|
785
877
|
const subId = depth > 0 ? ++subs : 0;
|
|
@@ -807,6 +899,8 @@ function flatten(doc, opts = {}) {
|
|
|
807
899
|
const emit = (part, col, mm, sp, k, embedded, tex, cd, sc) => {
|
|
808
900
|
if (fixed)
|
|
809
901
|
sp = fixed;
|
|
902
|
+
if (++work > maxN)
|
|
903
|
+
throw new ModelLimitError("model", maxN);
|
|
810
904
|
const i = { part, color: col, m: mm, step: sp[0], steps: sp, localStep: k, path };
|
|
811
905
|
if (cd)
|
|
812
906
|
i.colour = cd;
|
|
@@ -868,7 +962,10 @@ function flatten(doc, opts = {}) {
|
|
|
868
962
|
continue;
|
|
869
963
|
if (tx && c.fallback)
|
|
870
964
|
continue;
|
|
871
|
-
const
|
|
965
|
+
const mm = mul(m, c.m);
|
|
966
|
+
if (!inRange12(mm))
|
|
967
|
+
continue;
|
|
968
|
+
const col = c.color === 16 ? color : c.color, cd = c.color === 16 ? colour : scope?.get(c.color), sp = [...stepPath, s];
|
|
872
969
|
const tex = tx ? c.tex ?? texIn : null;
|
|
873
970
|
const local = tex ? invert(c.m) : null;
|
|
874
971
|
const lt = tex && local ? transformTexMap(tex, local) : null;
|
|
@@ -888,6 +985,7 @@ function flatten(doc, opts = {}) {
|
|
|
888
985
|
emit(c.file, col, mm, sp, s, false, lt, cd, scope);
|
|
889
986
|
}
|
|
890
987
|
flushLoose(Infinity);
|
|
988
|
+
open.delete(f);
|
|
891
989
|
if (groups) {
|
|
892
990
|
for (const g of groups.values())
|
|
893
991
|
if (g.n > 1)
|
|
@@ -1145,7 +1243,7 @@ function blendedColourHex(code) {
|
|
|
1145
1243
|
const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
|
|
1146
1244
|
return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1147
1245
|
}
|
|
1148
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1246
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/instructions.ts
|
|
1149
1247
|
var MIN_VIS = 0.5;
|
|
1150
1248
|
var REORIENT = 0.35;
|
|
1151
1249
|
var deg = Math.PI / 180;
|
|
@@ -1513,10 +1611,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
|
|
|
1513
1611
|
}
|
|
1514
1612
|
};
|
|
1515
1613
|
}
|
|
1516
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1614
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/render.ts
|
|
1517
1615
|
import * as THREE from "three";
|
|
1518
1616
|
|
|
1519
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1617
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/pack-io.ts
|
|
1520
1618
|
import { decompress } from "fzstd";
|
|
1521
1619
|
async function decompressPack(data) {
|
|
1522
1620
|
const u = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
@@ -1539,7 +1637,7 @@ function decodePack(buf) {
|
|
|
1539
1637
|
return { header, arr, bytes: buf.byteLength, buffer: buf };
|
|
1540
1638
|
}
|
|
1541
1639
|
|
|
1542
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1640
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/cull.ts
|
|
1543
1641
|
var upright = (m, o = 0) => Math.abs(m[o + 7] - 1) < 0.001 && Math.abs(m[o + 4]) < 0.001 && Math.abs(m[o + 10]) < 0.001;
|
|
1544
1642
|
var prepCache = new WeakMap;
|
|
1545
1643
|
function prepPart(H, part) {
|
|
@@ -1695,7 +1793,7 @@ function cullCore(insts, H, steps) {
|
|
|
1695
1793
|
clear.set(c, v = seeThrough(H, c));
|
|
1696
1794
|
return v;
|
|
1697
1795
|
};
|
|
1698
|
-
const rx0 = [], rx1 = [], rz0 = [], rz1 = [], rInst = [], rPrep = [], rBx = [], rBz = [];
|
|
1796
|
+
const rx0 = [], rx1 = [], rz0 = [], rz1 = [], rInst = [], rInst2 = [], rPrep = [], rBx = [], rBz = [];
|
|
1699
1797
|
const cells = new Int3Table(insts.length * 2);
|
|
1700
1798
|
const nextE = [], rectE = [];
|
|
1701
1799
|
for (let idx = 0;idx < insts.length; idx++) {
|
|
@@ -1719,18 +1817,49 @@ function cullCore(insts, H, steps) {
|
|
|
1719
1817
|
if (wz > z1)
|
|
1720
1818
|
z1 = wz;
|
|
1721
1819
|
}
|
|
1820
|
+
const lv2 = Math.round((m[1] + b[4]) * 2);
|
|
1821
|
+
const pp = prepPart(H, it.part);
|
|
1822
|
+
const cx0 = Math.floor(x0 / CELL), cx1 = Math.floor(x1 / CELL), cz0 = Math.floor(z0 / CELL), cz1 = Math.floor(z1 / CELL);
|
|
1823
|
+
if (!((cx1 - cx0 + 1) * (cz1 - cz0 + 1) <= 65536) || !inRange(lv2, cx0, cz0) || !inRange(lv2, cx1, cz1))
|
|
1824
|
+
continue;
|
|
1825
|
+
let dup = -1;
|
|
1826
|
+
for (let e = cells.get(lv2, cx0, cz0), k = 0;e >= 0 && k < 8; e = nextE[e], k++) {
|
|
1827
|
+
const q = rectE[e];
|
|
1828
|
+
if (rx0[q] !== x0 || rx1[q] !== x1 || rz0[q] !== z0 || rz1[q] !== z1 || rPrep[q] !== pp)
|
|
1829
|
+
continue;
|
|
1830
|
+
const qm = insts[rInst[q]].m;
|
|
1831
|
+
let same = true;
|
|
1832
|
+
for (let i = 0;i < 12; i++)
|
|
1833
|
+
if (qm[i] !== m[i]) {
|
|
1834
|
+
same = false;
|
|
1835
|
+
break;
|
|
1836
|
+
}
|
|
1837
|
+
if (same) {
|
|
1838
|
+
dup = q;
|
|
1839
|
+
break;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
if (dup >= 0) {
|
|
1843
|
+
const st = steps ? steps[idx] : 0;
|
|
1844
|
+
if (steps && st < steps[rInst[dup]]) {
|
|
1845
|
+
rInst2[dup] = rInst[dup];
|
|
1846
|
+
rInst[dup] = idx;
|
|
1847
|
+
} else if (rInst2[dup] < 0 || steps && st < steps[rInst2[dup]])
|
|
1848
|
+
rInst2[dup] = idx;
|
|
1849
|
+
continue;
|
|
1850
|
+
}
|
|
1722
1851
|
const ri = rInst.length;
|
|
1723
1852
|
rx0.push(x0);
|
|
1724
1853
|
rx1.push(x1);
|
|
1725
1854
|
rz0.push(z0);
|
|
1726
1855
|
rz1.push(z1);
|
|
1727
1856
|
rInst.push(idx);
|
|
1728
|
-
|
|
1857
|
+
rInst2.push(-1);
|
|
1858
|
+
rPrep.push(pp);
|
|
1729
1859
|
rBx.push(b[0]);
|
|
1730
1860
|
rBz.push(b[2]);
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
for (let cz = Math.floor(z0 / CELL);cz <= Math.floor(z1 / CELL); cz++) {
|
|
1861
|
+
for (let cx = cx0;cx <= cx1; cx++)
|
|
1862
|
+
for (let cz = cz0;cz <= cz1; cz++) {
|
|
1734
1863
|
if (!inRange(lv2, cx, cz))
|
|
1735
1864
|
continue;
|
|
1736
1865
|
const e = rectE.length;
|
|
@@ -1753,7 +1882,10 @@ function cullCore(insts, H, steps) {
|
|
|
1753
1882
|
}
|
|
1754
1883
|
for (let e = ke;e >= 0; e = nextE[e]) {
|
|
1755
1884
|
const ri = rectE[e];
|
|
1756
|
-
|
|
1885
|
+
let by = rInst[ri];
|
|
1886
|
+
if (by === self && (by = rInst2[ri]) < 0)
|
|
1887
|
+
continue;
|
|
1888
|
+
if (!(x - 6 >= rx0[ri] - 0.5 && x + 6 <= rx1[ri] + 0.5 && z - 6 >= rz0[ri] - 0.5 && z + 6 <= rz1[ri] + 0.5))
|
|
1757
1889
|
continue;
|
|
1758
1890
|
const m = insts[rInst[ri]].m;
|
|
1759
1891
|
const pp = rPrep[ri];
|
|
@@ -1772,7 +1904,7 @@ function cullCore(insts, H, steps) {
|
|
|
1772
1904
|
if (ok) {
|
|
1773
1905
|
if (!steps)
|
|
1774
1906
|
return 0;
|
|
1775
|
-
const st = steps[
|
|
1907
|
+
const st = steps[by];
|
|
1776
1908
|
if (st < best)
|
|
1777
1909
|
best = st;
|
|
1778
1910
|
}
|
|
@@ -1888,7 +2020,7 @@ function precomputeCull(instances, H, useTex = true) {
|
|
|
1888
2020
|
return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
|
|
1889
2021
|
}
|
|
1890
2022
|
|
|
1891
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2023
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/render.ts
|
|
1892
2024
|
async function loadPack(url) {
|
|
1893
2025
|
const res = await fetch(url);
|
|
1894
2026
|
if (!res.ok)
|
|
@@ -1907,10 +2039,13 @@ var toU8 = (a) => {
|
|
|
1907
2039
|
o[i] = Math.round(Math.max(0, Math.min(1, a[i])) * 255);
|
|
1908
2040
|
return o;
|
|
1909
2041
|
};
|
|
2042
|
+
var F16_MAX = 65504;
|
|
1910
2043
|
var toF16 = (a) => {
|
|
1911
2044
|
const o = new Uint16Array(a.length);
|
|
1912
|
-
for (let i = 0;i < a.length; i++)
|
|
1913
|
-
|
|
2045
|
+
for (let i = 0;i < a.length; i++) {
|
|
2046
|
+
const v = a[i];
|
|
2047
|
+
o[i] = THREE.DataUtils.toHalfFloat(v > F16_MAX ? F16_MAX : v < -F16_MAX ? -F16_MAX : v);
|
|
2048
|
+
}
|
|
1914
2049
|
return o;
|
|
1915
2050
|
};
|
|
1916
2051
|
function keepHalf(bm) {
|
|
@@ -3879,7 +4014,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
|
|
|
3879
4014
|
await new Promise((r) => setTimeout(r, 0));
|
|
3880
4015
|
}
|
|
3881
4016
|
}
|
|
3882
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4017
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/scene.ts
|
|
3883
4018
|
import * as THREE2 from "three";
|
|
3884
4019
|
var _box = new THREE2.Box3;
|
|
3885
4020
|
var _m4 = new THREE2.Matrix4;
|
|
@@ -4234,32 +4369,35 @@ function createLdrObjectInner(instances, pack, options, progressive) {
|
|
|
4234
4369
|
return finish();
|
|
4235
4370
|
})();
|
|
4236
4371
|
}
|
|
4237
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4372
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/parts-cdn.ts
|
|
4238
4373
|
import { decompress as decompress2 } from "fzstd";
|
|
4239
4374
|
|
|
4240
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4375
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/embedded.ts
|
|
4241
4376
|
function splitFiles(text, fallback) {
|
|
4242
4377
|
const files = new Map;
|
|
4243
|
-
let cur = null, saw = false;
|
|
4378
|
+
let cur = null, saw = false, skip = false;
|
|
4244
4379
|
for (const raw of text.split(/\r?\n/)) {
|
|
4245
|
-
const m = /^\s*0\s+FILE\s+(
|
|
4380
|
+
const m = /^\s*0\s+FILE\s+(\S[^\r]*)/i.exec(raw);
|
|
4246
4381
|
if (m) {
|
|
4247
4382
|
if (!saw)
|
|
4248
4383
|
files.clear();
|
|
4249
4384
|
saw = true;
|
|
4385
|
+
skip = false;
|
|
4250
4386
|
cur = [];
|
|
4251
4387
|
files.set(norm(m[1]), cur);
|
|
4252
4388
|
continue;
|
|
4253
4389
|
}
|
|
4254
4390
|
if (/^\s*0\s+(NOFILE|!DATA)(\s|$)/i.test(raw)) {
|
|
4255
|
-
if (!saw)
|
|
4391
|
+
if (!saw && /!DATA/i.test(raw)) {
|
|
4256
4392
|
files.clear();
|
|
4257
|
-
|
|
4393
|
+
saw = true;
|
|
4394
|
+
}
|
|
4258
4395
|
cur = null;
|
|
4396
|
+
skip = true;
|
|
4259
4397
|
continue;
|
|
4260
4398
|
}
|
|
4261
4399
|
if (!cur) {
|
|
4262
|
-
if (saw)
|
|
4400
|
+
if (saw || skip)
|
|
4263
4401
|
continue;
|
|
4264
4402
|
cur = [];
|
|
4265
4403
|
files.set(norm(fallback), cur);
|
|
@@ -4309,7 +4447,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
|
|
|
4309
4447
|
return out;
|
|
4310
4448
|
}
|
|
4311
4449
|
|
|
4312
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4450
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/parts-cdn.ts
|
|
4313
4451
|
var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
|
|
4314
4452
|
var indexCache = new Map;
|
|
4315
4453
|
var shardCache = new Map;
|
|
@@ -4563,10 +4701,10 @@ async function prepareModel(source, o = {}) {
|
|
|
4563
4701
|
return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
|
|
4564
4702
|
}
|
|
4565
4703
|
|
|
4566
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4567
|
-
var load_worker_gen_default = 'var Pt=ArrayBuffer,Y=Uint8Array,be=Uint16Array,kt=Int16Array;var ye=Int32Array,Pe=function(e,t,n){if(Y.prototype.slice)return Y.prototype.slice.call(e,t,n);if(t==null||t<0)t=0;if(n==null||n>e.length)n=e.length;var r=new Y(n-t);return r.set(e.subarray(t,n)),r},fe=function(e,t,n,r){if(Y.prototype.fill)return Y.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},It=function(e,t,n,r){if(Y.prototype.copyWithin)return Y.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var Ft=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],J=function(e,t,n){var r=Error(t||Ft[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,J);if(!n)throw r;return r},Ye=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},Rt=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Bt=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,l=r>>6;if(r&8)J(0);var f=6-s,c=i==3?4:i,u=Ye(e,f,c);f+=c;var a=l?1<<l:s,p=Ye(e,f,a)+(l==1&&256),d=p;if(!s){var y=1<<10+(e[5]>>3);d=y+(y>>3)*(e[5]&7)}if(d>2145386496)J(1);var b=new Y((t==1?p||d:t?0:d)+12);return b[0]=1,b[4]=4,b[8]=8,{b:f+a,y:0,l:0,d:u,w:t&&t!=1?t:b.subarray(12),e:d,o:new ye(b.buffer,0,3),u:p,c:o,m:Math.min(131072,d)}}else if((n>>4|e[3]<<20)==25481893)return Rt(e,4)+8;J(0)},oe=function(e){var t=0;for(;1<<t<=e;++t);return t-1},pe=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)J(3);var o=1<<s,i=o,l=-1,f=-1,c=-1,u=o,a=new Pt(512+(o<<2)),p=new kt(a,0,256),d=new be(a,0,256),y=new be(a,512,o),b=512+(o<<1),C=new Y(a,b,o),v=new Y(a,b+o);while(l<255&&i>0){var m=oe(i+1),g=r>>3,w=(1<<m+1)-1,B=(e[g]|e[g+1]<<8|e[g+2]<<16)>>(r&7)&w,A=(1<<m)-1,T=w-i-1,M=B&A;if(M<T)r+=m,B=M;else if(r+=m+1,B>A)B-=T;if(p[++l]=--B,B==-1)i+=B,C[--u]=l;else i-=B;if(!B)do{var k=r>>3;f=(e[k]|e[k+1]<<8)>>(r&7)&3,r+=2,l+=f}while(f==3)}if(l>255||i)J(0);var h=0,S=(o>>1)+(o>>3)+3,_=o-1;for(var j=0;j<=l;++j){var D=p[j];if(D<1){d[j]=-D;continue}for(c=0;c<D;++c){C[h]=j;do h=h+S&_;while(h>=u)}}if(h)J(0);for(c=0;c<o;++c){var E=d[C[c]]++,L=v[c]=s-oe(E);y[c]=(E<<L)-o}return[r+7>>3,{b:s,s:C,n:v,t:y}]},Dt=function(e,t){var n=0,r=-1,s=new Y(292),o=e[t],i=s.subarray(0,256),l=s.subarray(256,268),f=new be(s.buffer,268);if(o<128){var c=pe(e,t+1,6),u=c[0],a=c[1];t+=o;var p=u<<3,d=e[t];if(!d)J(0);var y=0,b=0,C=a.b,v=C,m=(++t<<3)-8+oe(d);for(;;){if(m-=C,m<p)break;var g=m>>3;if(y+=(e[g]|e[g+1]<<8)>>(m&7)&(1<<C)-1,i[++r]=a.s[y],m-=v,m<p)break;g=m>>3,b+=(e[g]|e[g+1]<<8)>>(m&7)&(1<<v)-1,i[++r]=a.s[b],C=a.n[y],y=a.t[y],v=a.n[b],b=a.t[b]}if(++r>255)J(0)}else{r=o-127;for(;n<r;n+=2){var w=e[++t];i[n]=w>>4,i[n+1]=w&15}++t}var B=0;for(n=0;n<r;++n){var A=i[n];if(A>11)J(0);B+=A&&1<<A-1}var T=oe(B)+1,M=1<<T,k=M-B;if(k&k-1)J(0);i[r++]=oe(k)+1;for(n=0;n<r;++n){var A=i[n];++l[i[n]=A&&T+1-A]}var h=new Y(M<<1),S=h.subarray(0,M),_=h.subarray(M);f[T]=0;for(n=T;n>0;--n){var j=f[n];fe(_,n,j,f[n-1]=j+l[n]*(1<<T-n))}if(f[0]!=M)J(0);for(n=0;n<r;++n){var D=i[n];if(D){var E=f[D];fe(S,n,E,f[D]=E+(1<<T-D))}}return[t,{n:_,b:T,s:S}]},Ut=pe(new Y([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],Ot=pe(new Y([33,20,196,24,99,140,33,132,16,66,8,33,132,16,66,8,33,68,68,68,68,68,68,68,68,36,9]),0,6)[1],Nt=pe(new Y([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],Je=function(e,t){var n=e.length,r=new ye(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},ke=new Y(new ye([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),zt=Je(ke,0),Ie=new Y(new ye([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),$t=Je(Ie,3),ue=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,l=-n.b;if(!o)J(0);var f=0,c=n.b,u=(r<<3)-8+oe(o)-c,a=-1;for(;u>l&&a<s;){var p=u>>3,d=(e[p]|e[p+1]<<8|e[p+2]<<16)>>(u&7);f=(f<<c|d)&i,t[++a]=n.s[f],u-=c=n.n[f]}if(u!=l||a+1!=s)J(0)},jt=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,l=o+i;ue(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),ue(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),ue(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,l),n),ue(e.subarray(r),t.subarray(l),n)},Vt=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var l=o>>3|e[s+1]<<5|e[s+2]<<13,f=(s+=3)+l;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return fe(n,e[s],t.y,t.y+=l),n;return fe(new Y(l),e[s])}if(f>e.length)return;if(i==0){if(t.b=f,n)return n.set(e.subarray(s,f),t.y),t.y+=l,n;return Pe(e,s,f)}if(i==2){var c=e[s],u=c&3,a=c>>2&3,p=c>>4,d=0,y=0;if(u<2)if(a&1)p|=e[++s]<<4|(a&2&&e[++s]<<12);else p=c>>3;else if(y=a,a<2)p|=(e[++s]&63)<<4,d=e[s]>>6|e[++s]<<2;else if(a==2)p|=e[++s]<<4|(e[++s]&3)<<12,d=e[s]>>2|e[++s]<<6;else p|=e[++s]<<4|(e[++s]&63)<<12,d=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var b=n?n.subarray(t.y,t.y+t.m):new Y(t.m),C=b.length-p;if(u==0)b.set(e.subarray(s,s+=p),C);else if(u==1)fe(b,e[s++],C);else{var v=t.h;if(u==2){var m=Dt(e,s);d+=s-(s=m[0]),t.h=v=m[1]}else if(!v)J(0);(y?jt:ue)(e.subarray(s,s+=d),b.subarray(C),v)}var g=e[s++];if(g){if(g==255)g=(e[s++]|e[s++]<<8)+32512;else if(g>127)g=g-128<<8|e[s++];var w=e[s++];if(w&3)J(0);var B=[Ot,Nt,Ut];for(var A=2;A>-1;--A){var T=w>>(A<<1)+2&3;if(T==1){var M=new Y([0,0,e[s++]]);B[A]={s:M.subarray(2,3),n:M.subarray(0,1),t:new be(M.buffer,0,1),b:0}}else if(T==2)r=pe(e,s,9-(A&1)),s=r[0],B[A]=r[1];else if(T==3){if(!t.t)J(0);B[A]=t.t[A]}}var k=t.t=B,h=k[0],S=k[1],_=k[2],j=e[f-1];if(!j)J(0);var D=(f<<3)-8+oe(j)-_.b,E=D>>3,L=0,O=(e[E]|e[E+1]<<8)>>(D&7)&(1<<_.b)-1;E=(D-=S.b)>>3;var H=(e[E]|e[E+1]<<8)>>(D&7)&(1<<S.b)-1;E=(D-=h.b)>>3;var W=(e[E]|e[E+1]<<8)>>(D&7)&(1<<h.b)-1;for(++g;--g;){var F=_.s[O],G=_.n[O],K=h.s[W],P=h.n[W],x=S.s[H],N=S.n[H];E=(D-=x)>>3;var U=1<<x,I=U+((e[E]|e[E+1]<<8|e[E+2]<<16|e[E+3]<<24)>>>(D&7)&U-1);E=(D-=Ie[K])>>3;var z=$t[K]+((e[E]|e[E+1]<<8|e[E+2]<<16)>>(D&7)&(1<<Ie[K])-1);E=(D-=ke[F])>>3;var X=zt[F]+((e[E]|e[E+1]<<8|e[E+2]<<16)>>(D&7)&(1<<ke[F])-1);if(E=(D-=G)>>3,O=_.t[O]+((e[E]|e[E+1]<<8)>>(D&7)&(1<<G)-1),E=(D-=P)>>3,W=h.t[W]+((e[E]|e[E+1]<<8)>>(D&7)&(1<<P)-1),E=(D-=N)>>3,H=S.t[H]+((e[E]|e[E+1]<<8)>>(D&7)&(1<<N)-1),I>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=I-=3;else{var Z=I-(X!=0);if(Z){if(I=Z==3?t.o[0]-1:t.o[Z],Z>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=I}else I=t.o[0]}for(var A=0;A<X;++A)b[L+A]=b[C+A];L+=X,C+=X;var V=L-I;if(V<0){var R=-V,q=t.e+V;if(R>z)R=z;for(var A=0;A<R;++A)b[L+A]=t.w[q+A];L+=R,z-=R,V=0}for(var A=0;A<z;++A)b[L+A]=b[V+A];L+=z}if(L!=C)while(C<b.length)b[L++]=b[C++];else L=b.length;if(n)t.y+=L;else b=Pe(b,0,L)}else if(n){if(t.y+=p,C)for(var A=0;A<p;++A)b[A]=b[C+A]}else if(C)b=Pe(b,C);return t.b=f,b}J(2)},_t=function(e,t){if(e.length==1)return e[0];var n=new Y(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function xe(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Bt(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var l=Vt(e,i,t);if(!l)J(5);if(t)i.e=i.y;else n.push(l),o+=l.length,It(i.w,0,l.length),i.w.set(l,i.w.length-l.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return _t(n,o)}async function Ht(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=(r)=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);if(t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253)return n(xe(t));if(t[0]===31&&t[1]===139)return new Response(new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();return n(t)}async function Qe(e){return new TextDecoder().decode(await Ht(e))}var qe=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function we(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var Q=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),Re=/^[A-Za-z][A-Za-z0-9_]*$/,Fe=new Map;function Be(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!Fe.has(r))Fe.set(r,t);return r}function De(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&Re.test(e))return Be(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var et=/^~?\\s*moved\\s+to\\s+(.+)$/i,Gt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),lt=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Wt=new Set(["model","submodel","configuration"]),Kt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function tt(e){let t=Kt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return lt.has(n)||Wt.has(n)?n:void 0}function Xt(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function Zt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every(Number.isFinite))return null;let l=n[2].trim();for(let a=0;a<s;a++)l=l.replace(/^\\S+\\s*/,"");let f=Xt(l);if(!f.length)return null;let c={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:f[0]};if(s>=10)c.a=i[9];if(s===11)c.b=i[10];let u=f.findIndex((a,p)=>p>0&&a.toUpperCase()==="GLOSSMAP");if(u>0&&f[u+1])c.glossmap=f[u+1];if(t)c.next=!0;return c}var Yt=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,""),n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function Jt(e){let t=e.length,n=1,r=(c)=>c===32||c===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let c=n;while(n<t&&!r(e.charCodeAt(n)))n++;return c<n?e.slice(c,n):null},o=s();if(o===null)return null;let i=Array(12);for(let c=0;c<12;c++){let u=s();if(u===null)return null;i[c]=+u}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let l=e.slice(n),f=/[ \\t]{2,}|\\t/.test(l)?l.split(/\\s+/).join(" "):l;return{t:1,color:De(o),m:i,file:Q(f)}}function nt(e){let t=+e[0];if(!(t>=1&&t<=5)||e.length<2)return null;let n=De(e[1]),r=e.slice(2).map(Number);if(t===1)return{t:1,color:n,m:r.slice(0,12),file:Q(e.slice(14).join(" "))};if(t===2)return{t:2,color:n,p:r.slice(0,6)};if(t===3)return{t:3,color:n,p:r.slice(0,9)};if(t===4)return{t:4,color:n,p:r.slice(0,12)};return{t:5,color:n,p:r.slice(0,12)}}function ct(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",l,f=null,c=[],u=null,a=()=>{if(!f)return;let m=Yt(f.chunks.join("")),g=m[0]===137&&m[1]===80&&m[2]===78&&m[3]===71;(l??=new Map).set(Q(f.name),{name:f.name,bytes:m,...g?{mime:"image/png"}:{}}),f=null},p=!0,d=(m)=>{if(a(),o={name:Q(m),cmds:[]},s.set(o.name,o),!i)i=o.name;c=[],u=null,p=!0},y=!1,b=!1,C=()=>{if(b)return;b=!0,s.clear(),o=null,i=""},v=(m,g)=>{if(u){m.tex=u,u=null;return}let w=c[c.length-1];if(!w)return;if(w.fallback){if(!g)m.fallback=!0}else m.tex=w.map};for(let m of e.split(`\n`)){let g=m.trim();if(!g)continue;if(r&&g.charCodeAt(0)>=50&&g.charCodeAt(0)<=53&&(g.charCodeAt(1)===32||g.charCodeAt(1)===9)){if(f||y)continue;if(!o)d(t);let T=g.slice(2).trimStart(),M=T.search(/\\s/),k={t:g.charCodeAt(0)-48,color:De(M<0?T:T.slice(0,M)),p:[],src:g};v(k,!1),o.cmds.push(k),p=!1;continue}if(g.charCodeAt(0)===48&&(g.charCodeAt(1)===32||g.charCodeAt(1)===9)){let T=2;while(g.charCodeAt(T)===32||g.charCodeAt(T)===9)T++;let M=T;while(M<g.length&&g.charCodeAt(M)!==32&&g.charCodeAt(M)!==9)M++;let k=g.slice(T,M);if(!Gt.has(k)){if(y||f)continue;if(!o)d(t);let h=g.slice(T),S={t:0,text:h};if(k.charCodeAt(0)===33)S.meta=k;if(u=null,p&&!o.org){let j=tt(h);if(j)o.org=j}let _=h.match(et);if(_&&!o.movedTo){let j=_[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(j))j+=".dat";o.movedTo=Q(j)}o.cmds.push(S);continue}}if(g.charCodeAt(0)===49&&(g.charCodeAt(1)===32||g.charCodeAt(1)===9)&&!f&&!y){let T=Jt(g);if(T){if(!o)d(t);v(T,!1),o.cmds.push(T),p=!1;continue}}let w=g.split(/\\s+/);if(+w[0]===0){let T=g.slice(1).trim();if(w[1]==="FILE"){C(),y=!1,d(T.slice(5));continue}if(w[1]==="NOFILE"){a(),o=null,y=!0;continue}if(w[1]==="!DATA"){C(),a(),o=null,y=!1,f={name:T.slice(5).trim(),chunks:[]};continue}if(y)continue;if(f){if(w[1]==="!:")f.chunks.push(w.slice(2).join(""));continue}if(!o)d(t);let M={t:0,text:T};if(w[1]==="STEP")M.step=!0,c=[],u=null;else if(w[1]==="BFC")M.bfc=w.slice(2).join(" ");else if(w[1]==="ROTSTEP")if(M.meta="ROTSTEP",M.step=!0,c=[],u=null,(w[2]??"").toUpperCase()==="END")M.rotstep={x:0,y:0,z:0,mode:"END"};else{let h=(w[5]??"REL").toUpperCase();M.rotstep={x:+w[2]||0,y:+w[3]||0,z:+w[4]||0,mode:["REL","ABS","ADD"].includes(h)?h:"REL"}}else if(w[1]==="BUFEXCHG"){M.meta="BUFEXCHG";let h=(w[2]??"").toUpperCase();M.bufexchg={op:h==="RETRIEVE"?"RETRIEVE":"STORE",buf:w[3]??"A"}}else if(w[1]?.startsWith("!"))M.meta=w[1];if(p&&!o.org){let h=tt(T);if(h)o.org=h}if(w[1]==="!TEXMAP"){let h=(w[2]??"").toUpperCase();if(u=null,h==="START"||h==="NEXT"){let S=Zt(T.replace(/^!TEXMAP\\s+\\S+/i,""),h==="NEXT");if(M.texmap={op:h,...S?{map:S}:{}},S)if((o.texmaps??=[]).push(S),h==="START")c.push({map:S,fallback:!1});else u=S}else if(h==="FALLBACK"){M.texmap={op:h};let S=c[c.length-1];if(S)S.fallback=!0}else if(h==="END")M.texmap={op:h},c.pop()}else if(w[1]==="!:"){u=null;let h=nt(w.slice(2));if(h)v(h,!0),M.geom=h}else u=null;let k=T.match(et);if(k&&!o.movedTo){let h=k[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(h))h+=".dat";o.movedTo=Q(h)}o.cmds.push(M);continue}if(f||y)continue;if(!o)d(t);let A=nt(w);if(!A)continue;v(A,!1),o.cmds.push(A),p=!1}return a(),l?{main:i,files:s,data:l}:{main:i,files:s}}var Cn=Math.PI/180;function ut(e,t){let n=(r)=>[t[3]*r[0]+t[4]*r[1]+t[5]*r[2]+t[0],t[6]*r[0]+t[7]*r[1]+t[8]*r[2]+t[1],t[9]*r[0]+t[10]*r[1]+t[11]*r[2]+t[2]];return{...e,p1:n(e.p1),p2:n(e.p2),p3:n(e.p3)}}function ft(e,t){let[n,r,s,o,i,l,f,c,u,a,p,d]=e,[y,b,C,v,m,g,w,B,A,T,M,k]=t;return[o*y+i*b+l*C+n,f*y+c*b+u*C+r,a*y+p*b+d*C+s,o*v+i*w+l*T,o*m+i*B+l*M,o*g+i*A+l*k,f*v+c*w+u*T,f*m+c*B+u*M,f*g+c*A+u*k,a*v+p*w+d*T,a*m+p*B+d*M,a*g+p*A+d*k]}var Ue=[0,0,0,1,0,0,0,1,0,0,0,1];var rt=new WeakMap,Qt=/^(s|8|48)\\//;function Oe(e,t){let n=e.files.get(Q(t));if(!n)return"part";let r=rt.get(n);if(r)return r;if(n.org)r=lt.has(n.org)?"part":"model";else if(n.name===e.main)r="model";else r=n.cmds.some((s)=>s.t>=2||s.t===0&&!!s.geom||s.t===1&&Qt.test(s.file))?"part":"model";return rt.set(n,r),r}var st=new WeakMap;function pt(e){let t=st.get(e);if(t)return t;t=[];let n=0;for(let r of e.cmds){if(r.t===0&&r.step){n++;continue}if((r.t>=2||r.t===0&&r.geom&&r.geom.t>=2)&&t[t.length-1]!==n)t.push(n)}return st.set(e,t),t}var ot=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?Fe.get(e)??String(e):String(e),qt=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${ot(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${ot(e.color)} ${e.p.join(" ")}`,Ne=(e,t)=>`${Q(e)}#${t}`;function en(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:Ne(e.name,t),cmds:n}}function mt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...en(e,t).cmds.map(qt)].join(`\n`)+`\n`}function ze(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function ht(e){let[t,n,r,s,o,i,l,f,c,u,a,p]=e,d=f*p-c*a,y=-(l*p-c*u),b=l*a-f*u,C=s*d+o*y+i*b;if(!Number.isFinite(C)||Math.abs(C)<0.000000000001)return null;let v=1/C,m=[d*v,-(o*p-i*a)*v,(o*c-i*f)*v,y*v,(s*p-i*u)*v,-(s*c-i*l)*v,b*v,-(s*a-o*u)*v,(s*f-o*l)*v];return[-(m[0]*t+m[1]*n+m[2]*r),-(m[3]*t+m[4]*n+m[5]*r),-(m[6]*t+m[7]*n+m[8]*r),...m]}var tn=(e)=>String(+e.toFixed(6)||0),it=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function gt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(tn).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${it(t.texture)}${t.glossmap?" GLOSSMAP "+it(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${Q(e)}\n0 !TEXMAP END\n`;return{name:`${Q(e)}#tex-${ze(r)}`,source:r}}var nn=(e,t)=>{let n=[,,,,,,,,,];for(let r=0;r<3;r++)for(let s=0;s<3;s++)n[r*3+s]=e[r*3]*t[s]+e[r*3+1]*t[3+s]+e[r*3+2]*t[6+s];return n};function rn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),l=Math.cos(t*r),f=Math.sin(n*r),c=Math.cos(n*r);return[l*c,-l*f,i,o*f+s*i*c,o*c-s*i*f,-s*l,s*f-o*i*c,s*c+o*i*f,o*l]}var at=new WeakMap;function dt(e){let t=at.get(e);if(t)return t;let n=[],r=null;for(let s of e.cmds){if(s.t!==0||!s.step)continue;let o=s.rotstep;if(o)if(o.mode==="END")r=null;else{let i=rn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:nn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),at.set(e,n),n}var bt=999999,wt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Mt=new WeakMap,yt=new WeakMap;function sn(e,t){let n=yt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Mt.get(o)??"",l=i.indexOf("!COLOUR");return l<0?"":"0 "+i.slice(l).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},yt.set(t,n);let r=n.parts.get(e);if(!r){let s=Q(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${ze(o)}`,source:o},n.parts.set(e,r)}return r}function on(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,l=new Map,f=0,c=(a,p)=>{let d=a.name+"#"+p,y=l.get(d);if(!y){let b;y=Object.assign(()=>b??=mt(a,p),{file:a,step:p}),l.set(d,y)}return y},u=(a,p,d,y,b,C,v,m,g=null,w=[],B=[],A=void 0,T=null)=>{let M=a.files.get(p);if(!M||v>r)return;let k=T,h=0,S=v>0?++f:0,_=i&&S?[...w,S]:w,j=i&&S?[...B,d]:B,D=i&&!g?new Map:null,E=-1,L=0,O=(P,x,N,U,I,z,X)=>{if(E!==h)E=h,L=0;let Z=D?.get(h+"|"+x);if(Z)return Z.n++,u(P,P===a?x:P.main,N,U,b+"/"+x,[...I,bt],v+1,z,[...I,bt],_,j,X,k);let V=[...I,L++],R=n.length;u(P,P===a?x:P.main,N,U,b+"/"+x,V,v+1,z,g,_,j,X,k),D?.set(h+"|"+x,{n:1,from:R,to:n.length})},H=dt(M),W=s?pt(M):[],F=0,G=(P,x,N,U,I,z,X,Z,V)=>{if(g)U=g;let R={part:P,color:x,m:N,step:U[0],steps:U,localStep:I,path:b};if(Z)R.colour=Z;if(S){if(R.sub=S,i)R.subPath=_,R.subMats=j}if(z)R.embedded=!0;if(X){let ee=gt(P,X);R.texPart=ee.name,R.texSource=ee.source}else if(V){let ee=sn(P,V);R.colPart=ee.name,R.colSource=ee.source}let q=H[I];if(q)R.view=q;return n.push(R),R},K=(P)=>{while(F<W.length&&W[F]<=P){let x=W[F++];G(Ne(M.name,x),y,d,[...C,x],x,!1,null,A,T).source=c(M,x)}};for(let P of M.cmds){if(P.t===0&&P.step){h++;continue}let x=P;if(x.t>=2||x.t===0&&x.geom&&x.geom.t>=2){K(h);continue}if(x.t===0){if(x.meta==="!COLOUR"){let q=ln(x.text);if(q&&q.code!==16&&q.code!==24)Mt.set(q,x.text),(k=new Map(k??[])).set(q.code,q);continue}if(o&&x.geom?.t===1)x=x.geom;else continue}if(x.t!==1)continue;if(o&&x.fallback)continue;let N=x.color===16?y:x.color,U=x.color===16?A:k?.get(x.color),I=ft(d,x.m),z=[...C,h],X=o?x.tex??m:null,Z=X?ht(x.m):null,V=X&&Z?ut(X,Z):null;if(a.files.has(x.file)){if(Oe(a,x.file)==="model"){O(a,x.file,I,N,z,V,U);continue}G(x.file,N,I,z,h,!0,V,U,k);continue}let R=t.resolveModel?.(x.file);if(R){O(R,x.file,I,N,z,V,U);continue}G(x.file,N,I,z,h,!1,V,U,k)}if(K(1/0),D){for(let P of D.values())if(P.n>1)for(let x=P.from;x<P.to;x++)n[x].mult??=P.n}};if(Oe(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Ue],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return u(e,e.main,Ue,16,e.main,[],0,null),n}function At(e,t="main.ldr",n){return on(ct(e,t,{geometryText:!0}),n)}var an=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function $e(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function xt(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=$e(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function ln(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",l=255,f=0,c={type:"default"},u=1;while(u<n.length){let a=n[u].toUpperCase(),p=n[u+1];if(a==="CODE")s=p!==void 0&&Re.test(p)?Be(p):p!==void 0&&/^\\d+$/.test(p)?+p:NaN,u+=2;else if(a==="VALUE"){let d=$e(p);if(d)o=d;u+=2}else if(a==="EDGE")i=$e(p)??p,u+=2;else if(a==="ALPHA")l=+p,u+=2;else if(a==="LUMINANCE")f=+p,u+=2;else if(a==="CHROME")c={type:"chrome"},u+=1;else if(a==="PEARLESCENT")c={type:"pearlescent"},u+=1;else if(a==="RUBBER")c={type:"rubber"},u+=1;else if(a==="MATTE_METALLIC")c={type:"matte_metallic"},u+=1;else if(a==="METAL")c={type:"metal"},u+=1;else if(a==="MATERIAL"){let d=(n[u+1]||"").toUpperCase();if(d==="GLITTER"){let{grain:y,next:b}=xt(n,u+2);c={type:"glitter",material:y},u=b}else if(d==="SPECKLE"){let{grain:y,next:b}=xt(n,u+2);c={type:"speckle",material:y},u=b}else if(d==="FABRIC"){let y=(n[u+2]||"").toUpperCase(),b=["VELVET","CANVAS","STRING","FUR"].includes(y)?y.toLowerCase():void 0;c={type:"fabric",kind:b},u+=b?3:2}else u=n.length}else if(an.has(a))u+=1;else u+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(l)?l:255,luminance:Number.isFinite(f)?f:0,finish:c}}function cn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,l=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:l,finish:"glitter"}}case"speckle":{let i=e.finish.material,l=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:l,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function je(e){let t=cn(e),n=!t.transparent?"op":t.opacity>=0.75?"a200":t.opacity>=0.4?"a128":`a${Math.round(t.opacity*255)}`,r=t.emissive>0?`L${Math.round(t.emissive*16)}`:"",s=`${t.finish}:${n}${r}`;if(t.particleHex)s+=`:${t.particleHex}:${(t.particleFraction??0).toFixed(2)}`;return s}function un(e,t){let n=new Map,r=null,s=!1;for(let o of e.split(/\\r?\\n/)){let i=/^\\s*0\\s+FILE\\s+(.+)$/i.exec(o);if(i){if(!s)n.clear();s=!0,r=[],n.set(Q(i[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(o)){if(!s)n.clear();s=!0,r=null;continue}if(!r){if(s)continue;r=[],n.set(Q(t),r)}let l=o.trim().replace(/\\s+/g," ");if(l)r.push(l)}return n}var fn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Q(t.slice(14).join(" ")):null};function pn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function vt(e,t,n="main.ldr"){let r=un(e,n),s=new Map;for(let o of t){let i=Q(o);if(!r.has(i)||s.has(i))continue;let l=new Set([i]),f=[i];while(f.length)for(let u of r.get(f.pop())){let a=fn(u);if(a&&r.has(a)&&!l.has(a))l.add(a),f.push(a)}let c=[i,...[...l].filter((u)=>u!==i).sort()].map((u)=>"0 FILE "+(u===i?"":u)+`\n`+r.get(u).join(`\n`)).join(`\n`);s.set(i,`emb/${pn(c)}.dat`)}return s}var Ct=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Tt=new WeakMap;function Ve(e,t){let n=Tt.get(e);if(!n)Tt.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),l=[],f=[];s.studs.forEach((p,d)=>{l.push(p[0]),f.push(p[1]);for(let y=0;y<12;y++)i[d*12+y]=p[2+y]});let c=null,u=0,a=0;if(s.mask){u=s.mask[0],a=s.mask[1];let p=s.mask[2];c=new Uint8Array(p.length);for(let d=0;d<p.length;d++)c[d]=p.charCodeAt(d)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:l,color:f,mask:c,nx:u,nz:a}),r}var le=1073741824;class _e{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,l=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&l[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,l=this.b,f=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,l[s]=t,f[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&l[s]===t&&f[s]===n){let c=this.vals[s];return this.vals[s]=r,c}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var Me=(e,t,n)=>e>-le&&e<le&&t>-le&&t<le&&n>-le&&n<le,me=2147483647;function mn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function hn(e,t,n){let s=new Map,o=(L)=>{let O=s.get(L);if(O===void 0)s.set(L,O=mn(t,L));return O},i=[],l=[],f=[],c=[],u=[],a=[],p=[],d=[],y=new _e(e.length*2),b=[],C=[];for(let L=0;L<e.length;L++){let O=e[L],H=O.m,W=t.parts[O.part];if(!W||!W.mask||!Ct(H)||o(O.color))continue;let F=W.bbox,G=1/0,K=-1/0,P=1/0,x=-1/0;for(let I=0;I<2;I++)for(let z=0;z<2;z++){let X=I?F[3]:F[0],Z=z?F[5]:F[2],V=H[0]+H[3]*X+H[5]*Z,R=H[2]+H[9]*X+H[11]*Z;if(V<G)G=V;if(V>K)K=V;if(R<P)P=R;if(R>x)x=R}let N=u.length;i.push(G),l.push(K),f.push(P),c.push(x),u.push(L),a.push(Ve(t,O.part)),p.push(F[0]),d.push(F[2]);let U=Math.round((H[1]+F[4])*2);for(let I=Math.floor(G/40);I<=Math.floor(K/40);I++)for(let z=Math.floor(P/40);z<=Math.floor(x/40);z++){if(!Me(U,I,z))continue;let X=C.length;C.push(N),b.push(y.put(U,I,z,X))}}let v=[0,5,-5,5,-5],m=[0,5,5,-5,-5],g=NaN,w=NaN,B=NaN,A=-1,T=(L,O,H,W)=>{let F=Math.round(O*2),G=Math.floor(L/40),K=Math.floor(H/40);if(!Me(F,G,K))return me;let P=me;if(F!==g||G!==w||K!==B)g=F,w=G,B=K,A=y.get(F,G,K);for(let x=A;x>=0;x=b[x]){let N=C[x];if(u[N]===W||!(L-6>=i[N]-0.5&&L+6<=l[N]+0.5&&H-6>=f[N]-0.5&&H+6<=c[N]+0.5))continue;let U=e[u[N]].m,I=a[N],z=p[N],X=d[N],Z=L-U[0],V=O-U[1],R=H-U[2],q=U[3]*Z+U[6]*V+U[9]*R,ee=U[5]*Z+U[8]*V+U[11]*R,{nx:ne,nz:ie,mask:ce}=I,ae=!0;for(let te=0;te<5;te++){let re=Math.floor((q+v[te]-z)/20),se=Math.floor((ee+m[te]-X)/20);if(re<0||se<0||re>=ne||se>=ie||ce[re*ie+se]!==1){ae=!1;break}}if(ae){if(!n)return 0;let te=n[u[N]];if(te<P)P=te}}return P},M=0;for(let L of e){let O=Ve(t,L.part);if(O)M+=O.nStuds}let k=new Uint8Array(M),h=new Uint8Array(M),S=new _e(M),_=0,j=n?new Int32Array(M).fill(me):void 0;for(let L=0,O=0;L<e.length;L++){let H=e[L],W=Ve(t,H.part);if(!W)continue;let F=H.m,G=W.studM,K=F[0],P=F[1],x=F[2],N=F[3],U=F[4],I=F[5],z=F[6],X=F[7],Z=F[8],V=F[9],R=F[10],q=F[11];for(let ee=0;ee<W.nStuds;ee++,O++){let ne=ee*12,ie=G[ne+4],ce=G[ne+7],ae=G[ne+10];if(!(Math.abs(z*ie+X*ce+Z*ae-1)<0.001&&Math.abs(N*ie+U*ce+I*ae)<0.001&&Math.abs(V*ie+R*ce+q*ae)<0.001))continue;h[O]=1;let te=G[ne],re=G[ne+1],se=G[ne+2],He=K+N*te+U*re+I*se,Ge=P+z*te+X*re+Z*se,We=x+V*te+R*re+q*se,Ke=T(He,Ge,We,L);if(Ke!==me){if(k[O]=1,_++,j)j[O]=Ke}let he=Math.round(He),ge=Math.round(Ge),de=Math.round(We);if(!Me(he,ge,de))continue;if(!n){S.put(he,ge,de,1);continue}let Xe=n[L],Ze=S.get(he,ge,de);if(Ze<0||Xe<Ze)S.put(he,ge,de,Xe)}}let D=new Uint8Array(e.length),E=n?new Int32Array(e.length).fill(me):void 0;for(let L=0;L<e.length;L++){let O=e[L],H=t.parts[O.part];if(!H||!H.under||!Ct(O.m)||o(O.color))continue;let W=H.bbox,F=Math.round((W[3]-W[0])/20),G=Math.round((W[5]-W[2])/20);if(!F||!G||F*G>4096)continue;let K=O.m,P=!0,x=0;for(let N=0;N<F&&P;N++)for(let U=0;U<G;U++){let I=W[0]+10+20*N,z=W[2]+10+20*U,X=K[0]+K[3]*I+K[5]*z,Z=K[2]+K[9]*I+K[11]*z,V=Math.round(X),R=Math.round(K[1]+W[4]),q=Math.round(Z),ee=Me(V,R,q)?S.get(V,R,q):-1;if(ee<0){P=!1;break}if(ee>x)x=ee}if(P){if(D[L]=1,E)E[L]=x}}return{nStuds:M,studHidden:k,studUp:h,underHidden:D,studsHidden:_,studHideStep:j,underHideStep:E}}function gn(e,t,n){let r=(a)=>a.colPart&&t.parts[a.colPart]?a.colPart:n&&a.texPart&&t.parts[a.texPart]?a.texPart:a.part,s=new Map,o=new Map,i=(a)=>{let p=a.colour;if(!p)return String(a.color);let d=o.get(p);if(d!==void 0)return d;let y=t.colorTable?.[a.color],b=y?.hex??t.colors?.[a.color],C=y?je({alpha:y.alpha??255,luminance:y.luminance??0,finish:y.finish??{type:"default"}}):"default:op",v=je(p);if(d=b&&b.toUpperCase()===p.hex.toUpperCase()&&C===v?String(a.color):p.hex.toUpperCase()+"/"+v,d!==String(a.color))s.set(d,p);return o.set(p,d),d},l=e.map((a)=>({part:r(a),color:i(a),m:a.m,steps:a.steps})),f=l.map((a)=>wt(a.steps)),c=[...new Set(f)].sort(),u=new Map(c.map((a,p)=>[a,p]));return{all:l,stepOf:f.map((a)=>u.get(a)),nSteps:c.length,localColours:s}}function Ae(e,t,n=!0){let r=gn(e,t,n);return hn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Se="https://ldr-demo.vercel.app/cdn/v1/",Ce=new Map,ve=new Map;function Te(e=Se,t=fetch){let n=Ce.get(e);if(!n)n=t(e+"parts.json").then((r)=>{if(!r.ok)throw Error(`ldr: parts CDN index ${r.status} (${e}parts.json)`);return r.json()}),n.catch(()=>Ce.delete(e)),Ce.set(e,n);return n}var dn=(e)=>Array.isArray(e)&&e.length===3&&typeof e[0]==="number"&&typeof e[1]==="number"&&(e[2]==="f32"||e[2]==="u16"||e[2]==="u8"||e[2]==="u32"),Le=(e,t)=>dn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Le(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Le(r,t)])):e;function bn(e,t={}){let n=[],r=0,s={},o={};for(let p of e){let d=p.buffer;if(!d)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let y=new DataView(d).getUint32(0,!0),b=new Uint8Array(d,4+y),C=r;n.push(b),r+=b.byteLength;let v=(4-r%4)%4;if(v)n.push(new Uint8Array(v)),r+=v;for(let[m,g]of Object.entries(p.header.parts??{}))if(!(m in s))s[m]=Le(g,C);for(let[m,g]of Object.entries(p.header.studKinds??{}))if(!(m in o))o[m]=Le(g,C)}let i=e[0]?.header??{version:1,weld:!0},l=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),f=(4-(4+l.length)%4)%4,c=4+l.length+f,u=new Uint8Array(c+r);new DataView(u.buffer).setUint32(0,l.length+f,!0),u.set(l,4),u.fill(32,4+l.length,c);let a=c;for(let p of n)u.set(p,a),a+=p.byteLength;return we(u.buffer)}async function yn(e,t={}){e=[...e];try{return await Lt(e,t)}catch(n){let r=t.cdn??Se,s=t.fetch??fetch;Ce.delete(r);let o=(i,l)=>s(i,{...l,cache:"reload"});try{return await Lt(e,{...t,fetch:o})}catch{throw n}}}async function Lt(e,t){let n=t.cdn??Se,r=t.fetch??fetch,s=t.gap??16384,o=await Te(n,r),i=[...new Set([...e].map(Q))],l=[],f=[];for(let m of i){if(ve.has(n+m))continue;let g=o.parts[m];if(g)f.push({name:m,off:g[0],len:g[1],file:g[2]??0});else l.push(m)}f.sort((m,g)=>m.file-g.file||m.off-g.off);let c=[];for(let m of f){let g=c[c.length-1];if(g&&g.file===m.file&&m.off-g.end<=s)g.end=Math.max(g.end,m.off+m.len),g.items.push(m);else c.push({file:m.file,start:m.off,end:m.off+m.len,items:[m]})}let u=0,a=0,p=0,d=new Map,y=async()=>{while(p<c.length){let m=c[p++],g=d.get(m.file);if(g)g=g.subarray(m.start,m.end);else{let w=await r(new URL(o.archives[m.file],n).href,{headers:{Range:`bytes=${m.start}-${m.end-1}`,"Accept-Encoding":"identity"}});if(!w.ok)throw Error(`ldr: parts CDN ${w.status}`);if(a++,g=new Uint8Array(await w.arrayBuffer()),u+=g.byteLength,w.status===200)d.set(m.file,g),g=g.subarray(m.start,m.end)}for(let w of m.items){let B=xe(g.subarray(w.off-m.start,w.off-m.start+w.len)),A=B.buffer.slice(B.byteOffset,B.byteOffset+B.byteLength);ve.set(n+w.name,we(A))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,c.length)},y));let b=i.filter((m)=>ve.has(n+m)).map((m)=>ve.get(n+m)),C={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:b.length?bn(b,C):we(xn(C)),missing:l,requests:a,bytes:u}}function xn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function wn(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function St(e,t,n){let r=0,s=0,o=!1,i=new Set;for(let l of e){let f=l.embedded?t.get(l.part):Q(l.part),c=f?n.parts[f]:void 0;if(!c)continue;if(c[3]!=null)o=!0,r+=c[3];if(!i.has(f))i.add(f),s+=c[1]}return{bodyTris:r,packBytes:s,known:o}}class Ee extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function Et(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Te(t.cdn??Se,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(h)=>{if(!h.ok)throw Error(`ldr: ${h.status} fetching ${e}`);return Qe(await h.arrayBuffer())}),i=performance.now(),l=t.name??(t.text?"main.ldr":qe(e)),f=At(o,l,{looseGeometry:!1,callouts:t.callouts}),c=performance.now();t.onParsed?.(f),await s;let u=vt(o,new Set(f.filter((h)=>h.embedded).map((h)=>h.part)),l),a=(h,S)=>t.maxBodyTris!=null&&h>t.maxBodyTris||t.maxPackBytes!=null&&S>t.maxPackBytes,p=t.maxBodyTris!=null||t.maxPackBytes!=null,d=(h)=>new Ee({...h,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),y="full";if(p){let h=St(f,u,await s);if(a(h.known?h.bodyTris:0,h.packBytes)){if(!t.lowCdn)throw d(h);let S=await Te(t.lowCdn,r).catch(()=>null);if(!S)throw d(h);let _=St(f,u,S);if(a(_.known?_.bodyTris:0,_.packBytes))throw d(_);y="low"}}let b=[...f.filter((h)=>!h.embedded).map((h)=>h.part),...u.values()],C=async()=>{let h=await yn(b,y==="low"?{...t,cdn:t.lowCdn}:t);for(let[S,_]of u){let j=h.pack.header.parts[_];if(j)h.pack.header.parts[S]=j}return{...h,packBytes:h.pack.buffer?.byteLength??h.pack.bytes??0,bodyTris:wn(f,h.pack)}},v=await C();if(p&&a(v.bodyTris,v.packBytes)&&y==="full"&&t.lowCdn&&await Te(t.lowCdn,r).then(()=>!0,()=>!1)){y="low";let h=v;v=await C(),v.requests+=h.requests,v.bytes+=h.bytes}if(p&&a(v.bodyTris,v.packBytes))throw d(v);let{pack:m,missing:g,requests:w,bytes:B}=v,A=new Map([...u].map(([h,S])=>[S,h])),T=g.map((h)=>A.get(h)??h),M=performance.now(),k=t.cull?Ae(f,m.header,t.textures!==!1):void 0;return{insts:f,pack:m,tier:y,missing:T,requests:w,bytes:B,cull:k,timings:{fetchModel:i-n,parse:c-i,parts:M-c,...k?{cull:performance.now()-M}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await Et(n,{...r,cull:!1,onParsed:(u)=>self.postMessage({id:t,insts:u})}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,tier:s.tier,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),l=Ae(s.insts,s.pack.header,r.textures!==!1),f=performance.now()-i,c=[];for(let u of[l.studHidden,l.studUp,l.underHidden,l.studHideStep,l.underHideStep])if(u)c.push(u.buffer);self.postMessage({id:t,cull:l,ms:f},c)}catch(s){if(s instanceof Ee||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
|
|
4704
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/load-worker.gen.ts
|
|
4705
|
+
var load_worker_gen_default = 'var Ft=ArrayBuffer,ee=Uint8Array,we=Uint16Array,Rt=Int16Array;var Me=Int32Array,Ie=function(e,t,n){if(ee.prototype.slice)return ee.prototype.slice.call(e,t,n);if(t==null||t<0)t=0;if(n==null||n>e.length)n=e.length;var r=new ee(n-t);return r.set(e.subarray(t,n)),r},he=function(e,t,n,r){if(ee.prototype.fill)return ee.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},Bt=function(e,t,n,r){if(ee.prototype.copyWithin)return ee.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var Dt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],te=function(e,t,n){var r=Error(t||Dt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,te);if(!n)throw r;return r},Qe=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},Ut=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ot=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,c=r>>6;if(r&8)te(0);var u=6-s,f=i==3?4:i,a=Qe(e,u,f);u+=f;var l=c?1<<c:s,m=Qe(e,u,l)+(c==1&&256),g=m;if(!s){var d=1<<10+(e[5]>>3);g=d+(d>>3)*(e[5]&7)}if(g>2145386496)te(1);var b=new ee((t==1?m||g:t?0:g)+12);return b[0]=1,b[4]=4,b[8]=8,{b:u+l,y:0,l:0,d:a,w:t&&t!=1?t:b.subarray(12),e:g,o:new Me(b.buffer,0,3),u:m,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return Ut(e,4)+8;te(0)},le=function(e){var t=0;for(;1<<t<=e;++t);return t-1},ge=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)te(3);var o=1<<s,i=o,c=-1,u=-1,f=-1,a=o,l=new Ft(512+(o<<2)),m=new Rt(l,0,256),g=new we(l,0,256),d=new we(l,512,o),b=512+(o<<1),C=new ee(l,b,o),A=new ee(l,b+o);while(c<255&&i>0){var p=le(i+1),h=r>>3,M=(1<<p+1)-1,D=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(r&7)&M,v=(1<<p)-1,L=M-i-1,R=D&v;if(R<L)r+=p,D=R;else if(r+=p+1,D>v)D-=L;if(m[++c]=--D,D==-1)i+=D,C[--a]=c;else i-=D;if(!D)do{var T=r>>3;u=(e[T]|e[T+1]<<8)>>(r&7)&3,r+=2,c+=u}while(u==3)}if(c>255||i)te(0);var x=0,w=(o>>1)+(o>>3)+3,E=o-1;for(var z=0;z<=c;++z){var k=m[z];if(k<1){g[z]=-k;continue}for(f=0;f<k;++f){C[x]=z;do x=x+w&E;while(x>=a)}}if(x)te(0);for(f=0;f<o;++f){var P=g[C[f]]++,Y=A[f]=s-le(P);d[f]=(P<<Y)-o}return[r+7>>3,{b:s,s:C,n:A,t:d}]},Nt=function(e,t){var n=0,r=-1,s=new ee(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),u=new we(s.buffer,268);if(o<128){var f=ge(e,t+1,6),a=f[0],l=f[1];t+=o;var m=a<<3,g=e[t];if(!g)te(0);var d=0,b=0,C=l.b,A=C,p=(++t<<3)-8+le(g);for(;;){if(p-=C,p<m)break;var h=p>>3;if(d+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<C)-1,i[++r]=l.s[d],p-=A,p<m)break;h=p>>3,b+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<A)-1,i[++r]=l.s[b],C=l.n[d],d=l.t[d],A=l.n[b],b=l.t[b]}if(++r>255)te(0)}else{r=o-127;for(;n<r;n+=2){var M=e[++t];i[n]=M>>4,i[n+1]=M&15}++t}var D=0;for(n=0;n<r;++n){var v=i[n];if(v>11)te(0);D+=v&&1<<v-1}var L=le(D)+1,R=1<<L,T=R-D;if(T&T-1)te(0);i[r++]=le(T)+1;for(n=0;n<r;++n){var v=i[n];++c[i[n]=v&&L+1-v]}var x=new ee(R<<1),w=x.subarray(0,R),E=x.subarray(R);u[L]=0;for(n=L;n>0;--n){var z=u[n];he(E,n,z,u[n-1]=z+c[n]*(1<<L-n))}if(u[0]!=R)te(0);for(n=0;n<r;++n){var k=i[n];if(k){var P=u[k];he(w,n,P,u[k]=P+(1<<L-k))}}return[t,{n:E,b:L,s:w}]},zt=ge(new ee([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],$t=ge(new ee([33,20,196,24,99,140,33,132,16,66,8,33,132,16,66,8,33,68,68,68,68,68,68,68,68,36,9]),0,6)[1],jt=ge(new ee([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],qe=function(e,t){var n=e.length,r=new Me(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Fe=new ee(new Me([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),Vt=qe(Fe,0),Re=new ee(new Me([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),_t=qe(Re,3),me=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,c=-n.b;if(!o)te(0);var u=0,f=n.b,a=(r<<3)-8+le(o)-f,l=-1;for(;a>c&&l<s;){var m=a>>3,g=(e[m]|e[m+1]<<8|e[m+2]<<16)>>(a&7);u=(u<<f|g)&i,t[++l]=n.s[u],a-=f=n.n[u]}if(a!=c||l+1!=s)te(0)},Ht=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;me(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),me(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),me(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),me(e.subarray(r),t.subarray(c),n)},Gt=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var c=o>>3|e[s+1]<<5|e[s+2]<<13,u=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return he(n,e[s],t.y,t.y+=c),n;return he(new ee(c),e[s])}if(u>e.length)return;if(i==0){if(t.b=u,n)return n.set(e.subarray(s,u),t.y),t.y+=c,n;return Ie(e,s,u)}if(i==2){var f=e[s],a=f&3,l=f>>2&3,m=f>>4,g=0,d=0;if(a<2)if(l&1)m|=e[++s]<<4|(l&2&&e[++s]<<12);else m=f>>3;else if(d=l,l<2)m|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(l==2)m|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else m|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var b=n?n.subarray(t.y,t.y+t.m):new ee(t.m),C=b.length-m;if(a==0)b.set(e.subarray(s,s+=m),C);else if(a==1)he(b,e[s++],C);else{var A=t.h;if(a==2){var p=Nt(e,s);g+=s-(s=p[0]),t.h=A=p[1]}else if(!A)te(0);(d?Ht:me)(e.subarray(s,s+=g),b.subarray(C),A)}var h=e[s++];if(h){if(h==255)h=(e[s++]|e[s++]<<8)+32512;else if(h>127)h=h-128<<8|e[s++];var M=e[s++];if(M&3)te(0);var D=[$t,jt,zt];for(var v=2;v>-1;--v){var L=M>>(v<<1)+2&3;if(L==1){var R=new ee([0,0,e[s++]]);D[v]={s:R.subarray(2,3),n:R.subarray(0,1),t:new we(R.buffer,0,1),b:0}}else if(L==2)r=ge(e,s,9-(v&1)),s=r[0],D[v]=r[1];else if(L==3){if(!t.t)te(0);D[v]=t.t[v]}}var T=t.t=D,x=T[0],w=T[1],E=T[2],z=e[u-1];if(!z)te(0);var k=(u<<3)-8+le(z)-E.b,P=k>>3,Y=0,I=(e[P]|e[P+1]<<8)>>(k&7)&(1<<E.b)-1;P=(k-=w.b)>>3;var j=(e[P]|e[P+1]<<8)>>(k&7)&(1<<w.b)-1;P=(k-=x.b)>>3;var H=(e[P]|e[P+1]<<8)>>(k&7)&(1<<x.b)-1;for(++h;--h;){var Z=E.s[I],O=E.n[I],G=x.s[H],K=x.n[H],J=w.s[j],Q=w.n[j];P=(k-=J)>>3;var S=1<<J,y=S+((e[P]|e[P+1]<<8|e[P+2]<<16|e[P+3]<<24)>>>(k&7)&S-1);P=(k-=Re[G])>>3;var B=_t[G]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Re[G])-1);P=(k-=Fe[Z])>>3;var _=Vt[Z]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Fe[Z])-1);if(P=(k-=O)>>3,I=E.t[I]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<O)-1),P=(k-=K)>>3,H=x.t[H]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<K)-1),P=(k-=Q)>>3,j=w.t[j]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<Q)-1),y>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=y-=3;else{var W=y-(_!=0);if(W){if(y=W==3?t.o[0]-1:t.o[W],W>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=y}else y=t.o[0]}for(var v=0;v<_;++v)b[Y+v]=b[C+v];Y+=_,C+=_;var X=Y-y;if(X<0){var N=-X,q=t.e+X;if(N>B)N=B;for(var v=0;v<N;++v)b[Y+v]=t.w[q+v];Y+=N,B-=N,X=0}for(var v=0;v<B;++v)b[Y+v]=b[X+v];Y+=B}if(Y!=C)while(C<b.length)b[Y++]=b[C++];else Y=b.length;if(n)t.y+=Y;else b=Ie(b,0,Y)}else if(n){if(t.y+=m,C)for(var v=0;v<m;++v)b[v]=b[C+v]}else if(C)b=Ie(b,C);return t.b=u,b}te(2)},Wt=function(e,t){if(e.length==1)return e[0];var n=new ee(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function Ae(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Ot(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var c=Gt(e,i,t);if(!c)te(5);if(t)i.e=i.y;else n.push(c),o+=c.length,Bt(i.w,0,c.length),i.w.set(c,i.w.length-c.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return Wt(n,o)}async function Kt(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=(r)=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);if(t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253)return n(Ae(t));if(t[0]===31&&t[1]===139)return new Response(new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();return n(t)}async function et(e){return new TextDecoder().decode(await Kt(e))}var tt=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function ve(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var ne=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),De=/^[A-Za-z][A-Za-z0-9_]*$/,Be=new Map;function Ue(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!Be.has(r))Be.set(r,t);return r}function Oe(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&De.test(e))return Ue(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var nt=/^~?\\s*moved\\s+to\\s+(.+)$/i,Xt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Zt=new Set(["FILE","NOFILE","!DATA"]),ut=1000000000000000,ft=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Yt=new Set(["model","submodel","configuration"]),Jt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function rt(e){let t=Jt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return ft.has(n)||Yt.has(n)?n:void 0}function Qt(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function qt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every((l)=>Number.isFinite(l)&&Math.abs(l)<=1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))return null;if(s>=10&&!(Math.abs(i[9])>=0.000001)||s===11&&!(Math.abs(i[10])>=0.000001))return null;let c=n[2].trim();for(let l=0;l<s;l++)c=c.replace(/^\\S+\\s*/,"");let u=Qt(c);if(!u.length)return null;let f={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:u[0]};if(s>=10)f.a=i[9];if(s===11)f.b=i[10];let a=u.findIndex((l,m)=>m>0&&l.toUpperCase()==="GLOSSMAP");if(a>0&&u[a+1])f.glossmap=u[a+1];if(t)f.next=!0;return f}var en=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,"");if(t.length%4===1)t=t.slice(0,-1);let n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function tn(e){let t=e.length,n=1,r=(a)=>a===32||a===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let a=n;while(n<t&&!r(e.charCodeAt(n)))n++;return a<n?e.slice(a,n):null},o=s();if(o===null)return null;let i=Array(12);for(let a=0;a<12;a++){let l=s();if(l===null)return null;let m=+l;if(!Number.isFinite(m))return null;i[a]=m}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let c=e.slice(n),u=/[ \\t]{2,}|\\t/.test(c)?c.split(/\\s+/).join(" "):c,f=Oe(o);if(!Number.isFinite(f))return null;return{t:1,color:f,m:i,file:ne(u)}}var nn=[0,12,6,9,12,12];function st(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=Oe(e[1]),r=nn[t];if(!Number.isFinite(n)||e.length<2+r+(t===1?1:0))return null;let s=Array(r);for(let o=0;o<r;o++){let i=+e[2+o];if(!Number.isFinite(i))return null;s[o]=i}if(t===1){let o=ne(e.slice(14).join(" "));return o?{t:1,color:n,m:s,file:o}:null}if(t===2)return{t:2,color:n,p:s};if(t===3)return{t:3,color:n,p:s};if(t===4)return{t:4,color:n,p:s};return{t:5,color:n,p:s}}function pt(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,u=null,f=[],a=null,l=()=>{if(!u)return;let p=en(u.chunks.join("")),h=p[0]===137&&p[1]===80&&p[2]===78&&p[3]===71;(c??=new Map).set(ne(u.name),{name:u.name,bytes:p,...h?{mime:"image/png"}:{}}),u=null},m=!0,g=(p)=>{if(l(),o={name:ne(p),cmds:[]},s.set(o.name,o),!i)i=o.name;f=[],a=null,m=!0},d=!1,b=!1,C=()=>{if(b)return;b=!0,s.clear(),o=null,i=""},A=(p,h)=>{if(a){p.tex=a,a=null;return}let M=f[f.length-1];if(!M)return;if(M.fallback){if(!h)p.fallback=!0}else p.tex=M.map};for(let p of e.split(`\n`)){let h=p.trim();if(!h)continue;if(r&&h.charCodeAt(0)>=50&&h.charCodeAt(0)<=53&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){if(u||d)continue;if(!o)g(t);let L=h.slice(2).trimStart(),R=L.search(/\\s/),T={t:h.charCodeAt(0)-48,color:Oe(R<0?L:L.slice(0,R)),p:[],src:h};A(T,!1),o.cmds.push(T),m=!1;continue}if(h.charCodeAt(0)===48&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){let L=2;while(h.charCodeAt(L)===32||h.charCodeAt(L)===9)L++;let R=L;while(R<h.length&&h.charCodeAt(R)!==32&&h.charCodeAt(R)!==9)R++;let T=h.slice(L,R),x=/[^\\x21-\\x7e]/.test(T)?h.slice(L).trim().split(/\\s+/)[0]:T;if(!Xt.has(x)&&!(x.length>=4&&x.length<=6&&Zt.has(x.toUpperCase()))){if(d||u)continue;if(!o)g(t);let w=h.slice(L),E={t:0,text:w};if(T.charCodeAt(0)===33)E.meta=T;if(a=null,m&&!o.org){let k=rt(w);if(k)o.org=k}let z=w.match(nt);if(z&&!o.movedTo){let k=z[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(k))k+=".dat";o.movedTo=ne(k)}o.cmds.push(E);continue}}if(h.charCodeAt(0)===49&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)&&!u&&!d){let L=tn(h);if(L){if(!o)g(t);A(L,!1),o.cmds.push(L),m=!1;continue}}let M=h.split(/\\s+/);if(+M[0]===0){let L=h.slice(1).trim(),R=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(R==="FILE"){let w=L.slice(5).trimStart().split("\\r")[0].trim();if(w){C(),d=!1,g(w);continue}}if(R==="NOFILE"){l(),o=null,d=!0;continue}if(R==="!DATA"){C(),l(),o=null,d=!1,u={name:L.slice(5).trim(),chunks:[]};continue}if(d)continue;if(u){if(M[1]==="!:")u.chunks.push(M.slice(2).join(""));continue}if(!o)g(t);let T={t:0,text:L};if(M[1]==="STEP")T.step=!0,f=[],a=null;else if(M[1]==="BFC")T.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(T.meta="ROTSTEP",T.step=!0,f=[],a=null,(M[2]??"").toUpperCase()==="END")T.rotstep={x:0,y:0,z:0,mode:"END"};else{let w=(M[5]??"REL").toUpperCase(),E=(z)=>{let k=Number(z);return Number.isFinite(k)?k:0};T.rotstep={x:E(M[2]),y:E(M[3]),z:E(M[4]),mode:["REL","ABS","ADD"].includes(w)?w:"REL"}}else if(M[1]==="BUFEXCHG"){T.meta="BUFEXCHG";let w=(M[2]??"").toUpperCase();T.bufexchg={op:w==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))T.meta=M[1];if(m&&!o.org){let w=rt(L);if(w)o.org=w}if(M[1]==="!TEXMAP"){let w=(M[2]??"").toUpperCase();if(a=null,w==="START"||w==="NEXT"){let E=qt(L.replace(/^!TEXMAP\\s+\\S+/i,""),w==="NEXT");if(T.texmap={op:w,...E?{map:E}:{}},E)if((o.texmaps??=[]).push(E),w==="START")f.push({map:E,fallback:!1});else a=E}else if(w==="FALLBACK"){T.texmap={op:w};let E=f[f.length-1];if(E)E.fallback=!0}else if(w==="END")T.texmap={op:w},f.pop()}else if(M[1]==="!:"){a=null;let w=st(M.slice(2));if(w)A(w,!0),T.geom=w}else a=null;let x=L.match(nt);if(x&&!o.movedTo){let w=x[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(w))w+=".dat";o.movedTo=ne(w)}o.cmds.push(T);continue}if(u||d)continue;if(!o)g(t);let v=st(M);if(!v){if(/^[2-5][ \\t]/.test(h))m=!1;continue}A(v,!1),o.cmds.push(v),m=!1}return l(),c?{main:i,files:s,data:c}:{main:i,files:s}}var Pn=Math.PI/180;function mt(e,t){let n=(r)=>[t[3]*r[0]+t[4]*r[1]+t[5]*r[2]+t[0],t[6]*r[0]+t[7]*r[1]+t[8]*r[2]+t[1],t[9]*r[0]+t[10]*r[1]+t[11]*r[2]+t[2]];return{...e,p1:n(e.p1),p2:n(e.p2),p3:n(e.p3)}}function ht(e,t){let[n,r,s,o,i,c,u,f,a,l,m,g]=e,[d,b,C,A,p,h,M,D,v,L,R,T]=t;return[o*d+i*b+c*C+n,u*d+f*b+a*C+r,l*d+m*b+g*C+s,o*A+i*M+c*L,o*p+i*D+c*R,o*h+i*v+c*T,u*A+f*M+a*L,u*p+f*D+a*R,u*h+f*v+a*T,l*A+m*M+g*L,l*p+m*D+g*R,l*h+m*v+g*T]}var Ne=[0,0,0,1,0,0,0,1,0,0,0,1];var ot=new WeakMap,rn=/^(s|8|48)\\//;function ze(e,t){let n=e.files.get(ne(t));if(!n)return"part";let r=ot.get(n);if(r)return r;if(n.org)r=ft.has(n.org)?"part":"model";else if(n.name===e.main)r="model";else r=n.cmds.some((s)=>s.t>=2||s.t===0&&!!s.geom||s.t===1&&rn.test(s.file))?"part":"model";return ot.set(n,r),r}var it=new WeakMap;function gt(e){let t=it.get(e);if(t)return t;t=[];let n=0;for(let r of e.cmds){if(r.t===0&&r.step){n++;continue}if((r.t>=2||r.t===0&&r.geom&&r.geom.t>=2)&&t[t.length-1]!==n)t.push(n)}return it.set(e,t),t}var at=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?Be.get(e)??String(e):String(e),sn=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${at(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${at(e.color)} ${e.p.join(" ")}`,$e=(e,t)=>`${ne(e)}#${t}`;function on(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:$e(e.name,t),cmds:n}}function dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...on(e,t).cmds.map(sn)].join(`\n`)+`\n`}function je(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function bt(e){let[t,n,r,s,o,i,c,u,f,a,l,m]=e,g=u*m-f*l,d=-(c*m-f*a),b=c*l-u*a,C=s*g+o*d+i*b;if(!Number.isFinite(C)||Math.abs(C)<0.000000000001)return null;let A=1/C,p=[g*A,-(o*m-i*l)*A,(o*f-i*u)*A,d*A,(s*m-i*a)*A,-(s*f-i*c)*A,b*A,-(s*l-o*a)*A,(s*u-o*c)*A];return[-(p[0]*t+p[1]*n+p[2]*r),-(p[3]*t+p[4]*n+p[5]*r),-(p[6]*t+p[7]*n+p[8]*r),...p]}var an=(e)=>String(+e.toFixed(6)||0),lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function yt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(an).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${lt(t.texture)}${t.glossmap?" GLOSSMAP "+lt(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${ne(e)}\n0 !TEXMAP END\n`;return{name:`${ne(e)}#tex-${je(r)}`,source:r}}var ln=(e,t)=>{let n=[,,,,,,,,,];for(let r=0;r<3;r++)for(let s=0;s<3;s++)n[r*3+s]=e[r*3]*t[s]+e[r*3+1]*t[3+s]+e[r*3+2]*t[6+s];return n};function cn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),c=Math.cos(t*r),u=Math.sin(n*r),f=Math.cos(n*r);return[c*f,-c*u,i,o*u+s*i*f,o*f-s*i*u,-s*c,s*u-o*i*f,s*f+o*i*u,o*c]}var ct=new WeakMap;function xt(e){let t=ct.get(e);if(t)return t;let n=[],r=null;for(let s of e.cmds){if(s.t!==0||!s.step)continue;let o=s.rotstep;if(o)if(o.mode==="END")r=null;else{let i=cn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:ln(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),ct.set(e,n),n}class Ve extends Error{limit;code="ldr-model-limit";constructor(e,t){super(`ldr: ${e} expands past ${t.toLocaleString("en-US")} (see maxInstances)`);this.limit=t;this.name="ModelLimitError"}}var un=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=ut))return!1;return!0},wt=999999,vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Ct=new WeakMap,Mt=new WeakMap;function fn(e,t){let n=Mt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Ct.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},Mt.set(t,n);let r=n.parts.get(e);if(!r){let s=ne(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${je(o)}`,source:o},n.parts.set(e,r)}return r}function pn(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,u=0,f=new Set,a=t.maxInstances??2000000,l=0,m=(d,b)=>{let C=d.name+"#"+b,A=c.get(C);if(!A){let p;A=Object.assign(()=>p??=dt(d,b),{file:d,step:b}),c.set(C,A)}return A},g=(d,b,C,A,p,h,M,D,v=null,L=[],R=[],T=void 0,x=null)=>{let w=d.files.get(b);if(!w||M>r||f.has(w))return;if(++l>a)throw new Ve("model",a);f.add(w);let E=x,z=0,k=M>0?++u:0,P=i&&k?[...L,k]:L,Y=i&&k?[...R,C]:R,I=i&&!v?new Map:null,j=-1,H=0,Z=(S,y,B,_,W,X,N)=>{if(j!==z)j=z,H=0;let q=I?.get(z+"|"+y);if(q)return q.n++,g(S,S===d?y:S.main,B,_,p+"/"+y,[...W,wt],M+1,X,[...W,wt],P,Y,N,E);let U=[...W,H++],F=n.length;g(S,S===d?y:S.main,B,_,p+"/"+y,U,M+1,X,v,P,Y,N,E),I?.set(z+"|"+y,{n:1,from:F,to:n.length})},O=xt(w),G=s?gt(w):[],K=0,J=(S,y,B,_,W,X,N,q,U)=>{if(v)_=v;if(++l>a)throw new Ve("model",a);let F={part:S,color:y,m:B,step:_[0],steps:_,localStep:W,path:p};if(q)F.colour=q;if(k){if(F.sub=k,i)F.subPath=P,F.subMats=Y}if(X)F.embedded=!0;if(N){let re=yt(S,N);F.texPart=re.name,F.texSource=re.source}else if(U){let re=fn(S,U);F.colPart=re.name,F.colSource=re.source}let V=O[W];if(V)F.view=V;return n.push(F),F},Q=(S)=>{while(K<G.length&&G[K]<=S){let y=G[K++];J($e(w.name,y),A,C,[...h,y],y,!1,null,T,x).source=m(w,y)}};for(let S of w.cmds){if(S.t===0&&S.step){z++;continue}let y=S;if(y.t>=2||y.t===0&&y.geom&&y.geom.t>=2){Q(z);continue}if(y.t===0){if(y.meta==="!COLOUR"){let V=hn(y.text);if(V&&V.code!==16&&V.code!==24)Ct.set(V,y.text),(E=new Map(E??[])).set(V.code,V);continue}if(o&&y.geom?.t===1)y=y.geom;else continue}if(y.t!==1)continue;if(o&&y.fallback)continue;let B=ht(C,y.m);if(!un(B))continue;let _=y.color===16?A:y.color,W=y.color===16?T:E?.get(y.color),X=[...h,z],N=o?y.tex??D:null,q=N?bt(y.m):null,U=N&&q?mt(N,q):null;if(d.files.has(y.file)){if(ze(d,y.file)==="model"){Z(d,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!0,U,W,E);continue}let F=t.resolveModel?.(y.file);if(F){Z(F,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!1,U,W,E)}if(Q(1/0),f.delete(w),I){for(let S of I.values())if(S.n>1)for(let y=S.from;y<S.to;y++)n[y].mult??=S.n}};if(ze(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Ne],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,Ne,16,e.main,[],0,null),n}function Tt(e,t="main.ldr",n){return pn(pt(e,t,{geometryText:!0}),n)}var mn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function _e(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function At(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=_e(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function hn(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",c=255,u=0,f={type:"default"},a=1;while(a<n.length){let l=n[a].toUpperCase(),m=n[a+1];if(l==="CODE")s=m!==void 0&&De.test(m)?Ue(m):m!==void 0&&/^\\d+$/.test(m)?+m:NaN,a+=2;else if(l==="VALUE"){let g=_e(m);if(g)o=g;a+=2}else if(l==="EDGE")i=_e(m)??m,a+=2;else if(l==="ALPHA")c=+m,a+=2;else if(l==="LUMINANCE")u=+m,a+=2;else if(l==="CHROME")f={type:"chrome"},a+=1;else if(l==="PEARLESCENT")f={type:"pearlescent"},a+=1;else if(l==="RUBBER")f={type:"rubber"},a+=1;else if(l==="MATTE_METALLIC")f={type:"matte_metallic"},a+=1;else if(l==="METAL")f={type:"metal"},a+=1;else if(l==="MATERIAL"){let g=(n[a+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:d,next:b}=At(n,a+2);f={type:"glitter",material:d},a=b}else if(g==="SPECKLE"){let{grain:d,next:b}=At(n,a+2);f={type:"speckle",material:d},a=b}else if(g==="FABRIC"){let d=(n[a+2]||"").toUpperCase(),b=["VELVET","CANVAS","STRING","FUR"].includes(d)?d.toLowerCase():void 0;f={type:"fabric",kind:b},a+=b?3:2}else a=n.length}else if(mn.has(l))a+=1;else a+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(c)?c:255,luminance:Number.isFinite(u)?u:0,finish:f}}function gn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"glitter"}}case"speckle":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function He(e){let t=gn(e),n=!t.transparent?"op":t.opacity>=0.75?"a200":t.opacity>=0.4?"a128":`a${Math.round(t.opacity*255)}`,r=t.emissive>0?`L${Math.round(t.emissive*16)}`:"",s=`${t.finish}:${n}${r}`;if(t.particleHex)s+=`:${t.particleHex}:${(t.particleFraction??0).toFixed(2)}`;return s}function dn(e,t){let n=new Map,r=null,s=!1,o=!1;for(let i of e.split(/\\r?\\n/)){let c=/^\\s*0\\s+FILE\\s+(\\S[^\\r]*)/i.exec(i);if(c){if(!s)n.clear();s=!0,o=!1,r=[],n.set(ne(c[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(i)){if(!s&&/!DATA/i.test(i))n.clear(),s=!0;r=null,o=!0;continue}if(!r){if(s||o)continue;r=[],n.set(ne(t),r)}let u=i.trim().replace(/\\s+/g," ");if(u)r.push(u)}return n}var bn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?ne(t.slice(14).join(" ")):null};function yn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function Lt(e,t,n="main.ldr"){let r=dn(e,n),s=new Map;for(let o of t){let i=ne(o);if(!r.has(i)||s.has(i))continue;let c=new Set([i]),u=[i];while(u.length)for(let a of r.get(u.pop())){let l=bn(a);if(l&&r.has(l)&&!c.has(l))c.add(l),u.push(l)}let f=[i,...[...c].filter((a)=>a!==i).sort()].map((a)=>"0 FILE "+(a===i?"":a)+`\n`+r.get(a).join(`\n`)).join(`\n`);s.set(i,`emb/${yn(f)}.dat`)}return s}var St=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Et=new WeakMap;function Ge(e,t){let n=Et.get(e);if(!n)Et.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),c=[],u=[];s.studs.forEach((m,g)=>{c.push(m[0]),u.push(m[1]);for(let d=0;d<12;d++)i[g*12+d]=m[2+d]});let f=null,a=0,l=0;if(s.mask){a=s.mask[0],l=s.mask[1];let m=s.mask[2];f=new Uint8Array(m.length);for(let g=0;g<m.length;g++)f[g]=m.charCodeAt(g)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:c,color:u,mask:f,nx:a,nz:l}),r}var fe=1073741824;class We{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,c=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&c[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,c=this.b,u=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,c[s]=t,u[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&c[s]===t&&u[s]===n){let f=this.vals[s];return this.vals[s]=r,f}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var pe=(e,t,n)=>e>-fe&&e<fe&&t>-fe&&t<fe&&n>-fe&&n<fe,de=2147483647;function xn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function wn(e,t,n){let s=new Map,o=(I)=>{let j=s.get(I);if(j===void 0)s.set(I,j=xn(t,I));return j},i=[],c=[],u=[],f=[],a=[],l=[],m=[],g=[],d=[],b=new We(e.length*2),C=[],A=[];for(let I=0;I<e.length;I++){let j=e[I],H=j.m,Z=t.parts[j.part];if(!Z||!Z.mask||!St(H)||o(j.color))continue;let O=Z.bbox,G=1/0,K=-1/0,J=1/0,Q=-1/0;for(let U=0;U<2;U++)for(let F=0;F<2;F++){let V=U?O[3]:O[0],re=F?O[5]:O[2],oe=H[0]+H[3]*V+H[5]*re,se=H[2]+H[9]*V+H[11]*re;if(oe<G)G=oe;if(oe>K)K=oe;if(se<J)J=se;if(se>Q)Q=se}let S=Math.round((H[1]+O[4])*2),y=Ge(t,j.part),B=Math.floor(G/40),_=Math.floor(K/40),W=Math.floor(J/40),X=Math.floor(Q/40);if(!((_-B+1)*(X-W+1)<=65536)||!pe(S,B,W)||!pe(S,_,X))continue;let N=-1;for(let U=b.get(S,B,W),F=0;U>=0&&F<8;U=C[U],F++){let V=A[U];if(i[V]!==G||c[V]!==K||u[V]!==J||f[V]!==Q||m[V]!==y)continue;let re=e[a[V]].m,oe=!0;for(let se=0;se<12;se++)if(re[se]!==H[se]){oe=!1;break}if(oe){N=V;break}}if(N>=0){let U=n?n[I]:0;if(n&&U<n[a[N]])l[N]=a[N],a[N]=I;else if(l[N]<0||n&&U<n[l[N]])l[N]=I;continue}let q=a.length;i.push(G),c.push(K),u.push(J),f.push(Q),a.push(I),l.push(-1),m.push(y),g.push(O[0]),d.push(O[2]);for(let U=B;U<=_;U++)for(let F=W;F<=X;F++){if(!pe(S,U,F))continue;let V=A.length;A.push(q),C.push(b.put(S,U,F,V))}}let p=[0,5,-5,5,-5],h=[0,5,5,-5,-5],M=NaN,D=NaN,v=NaN,L=-1,R=(I,j,H,Z)=>{let O=Math.round(j*2),G=Math.floor(I/40),K=Math.floor(H/40);if(!pe(O,G,K))return de;let J=de;if(O!==M||G!==D||K!==v)M=O,D=G,v=K,L=b.get(O,G,K);for(let Q=L;Q>=0;Q=C[Q]){let S=A[Q],y=a[S];if(y===Z&&(y=l[S])<0)continue;if(!(I-6>=i[S]-0.5&&I+6<=c[S]+0.5&&H-6>=u[S]-0.5&&H+6<=f[S]+0.5))continue;let B=e[a[S]].m,_=m[S],W=g[S],X=d[S],N=I-B[0],q=j-B[1],U=H-B[2],F=B[3]*N+B[6]*q+B[9]*U,V=B[5]*N+B[8]*q+B[11]*U,{nx:re,nz:oe,mask:se}=_,ce=!0;for(let ie=0;ie<5;ie++){let ae=Math.floor((F+p[ie]-W)/20),ue=Math.floor((V+h[ie]-X)/20);if(ae<0||ue<0||ae>=re||ue>=oe||se[ae*oe+ue]!==1){ce=!1;break}}if(ce){if(!n)return 0;let ie=n[y];if(ie<J)J=ie}}return J},T=0;for(let I of e){let j=Ge(t,I.part);if(j)T+=j.nStuds}let x=new Uint8Array(T),w=new Uint8Array(T),E=new We(T),z=0,k=n?new Int32Array(T).fill(de):void 0;for(let I=0,j=0;I<e.length;I++){let H=e[I],Z=Ge(t,H.part);if(!Z)continue;let O=H.m,G=Z.studM,K=O[0],J=O[1],Q=O[2],S=O[3],y=O[4],B=O[5],_=O[6],W=O[7],X=O[8],N=O[9],q=O[10],U=O[11];for(let F=0;F<Z.nStuds;F++,j++){let V=F*12,re=G[V+4],oe=G[V+7],se=G[V+10];if(!(Math.abs(_*re+W*oe+X*se-1)<0.001&&Math.abs(S*re+y*oe+B*se)<0.001&&Math.abs(N*re+q*oe+U*se)<0.001))continue;w[j]=1;let ce=G[V],ie=G[V+1],ae=G[V+2],ue=K+S*ce+y*ie+B*ae,Ke=J+_*ce+W*ie+X*ae,Xe=Q+N*ce+q*ie+U*ae,Ze=R(ue,Ke,Xe,I);if(Ze!==de){if(x[j]=1,z++,k)k[j]=Ze}let be=Math.round(ue),ye=Math.round(Ke),xe=Math.round(Xe);if(!pe(be,ye,xe))continue;if(!n){E.put(be,ye,xe,1);continue}let Ye=n[I],Je=E.get(be,ye,xe);if(Je<0||Ye<Je)E.put(be,ye,xe,Ye)}}let P=new Uint8Array(e.length),Y=n?new Int32Array(e.length).fill(de):void 0;for(let I=0;I<e.length;I++){let j=e[I],H=t.parts[j.part];if(!H||!H.under||!St(j.m)||o(j.color))continue;let Z=H.bbox,O=Math.round((Z[3]-Z[0])/20),G=Math.round((Z[5]-Z[2])/20);if(!O||!G||O*G>4096)continue;let K=j.m,J=!0,Q=0;for(let S=0;S<O&&J;S++)for(let y=0;y<G;y++){let B=Z[0]+10+20*S,_=Z[2]+10+20*y,W=K[0]+K[3]*B+K[5]*_,X=K[2]+K[9]*B+K[11]*_,N=Math.round(W),q=Math.round(K[1]+Z[4]),U=Math.round(X),F=pe(N,q,U)?E.get(N,q,U):-1;if(F<0){J=!1;break}if(F>Q)Q=F}if(J){if(P[I]=1,Y)Y[I]=Q}}return{nStuds:T,studHidden:x,studUp:w,underHidden:P,studsHidden:z,studHideStep:k,underHideStep:Y}}function Mn(e,t,n){let r=(l)=>l.colPart&&t.parts[l.colPart]?l.colPart:n&&l.texPart&&t.parts[l.texPart]?l.texPart:l.part,s=new Map,o=new Map,i=(l)=>{let m=l.colour;if(!m)return String(l.color);let g=o.get(m);if(g!==void 0)return g;let d=t.colorTable?.[l.color],b=d?.hex??t.colors?.[l.color],C=d?He({alpha:d.alpha??255,luminance:d.luminance??0,finish:d.finish??{type:"default"}}):"default:op",A=He(m);if(g=b&&b.toUpperCase()===m.hex.toUpperCase()&&C===A?String(l.color):m.hex.toUpperCase()+"/"+A,g!==String(l.color))s.set(g,m);return o.set(m,g),g},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),u=c.map((l)=>vt(l.steps)),f=[...new Set(u)].sort(),a=new Map(f.map((l,m)=>[l,m]));return{all:c,stepOf:u.map((l)=>a.get(l)),nSteps:f.length,localColours:s}}function Ce(e,t,n=!0){let r=Mn(e,t,n);return wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var ke="https://ldr-demo.vercel.app/cdn/v1/",Le=new Map,Te=new Map;function Se(e=ke,t=fetch){let n=Le.get(e);if(!n)n=t(e+"parts.json").then((r)=>{if(!r.ok)throw Error(`ldr: parts CDN index ${r.status} (${e}parts.json)`);return r.json()}),n.catch(()=>Le.delete(e)),Le.set(e,n);return n}var An=(e)=>Array.isArray(e)&&e.length===3&&typeof e[0]==="number"&&typeof e[1]==="number"&&(e[2]==="f32"||e[2]==="u16"||e[2]==="u8"||e[2]==="u32"),Ee=(e,t)=>An(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Ee(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ee(r,t)])):e;function vn(e,t={}){let n=[],r=0,s={},o={};for(let m of e){let g=m.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let d=new DataView(g).getUint32(0,!0),b=new Uint8Array(g,4+d),C=r;n.push(b),r+=b.byteLength;let A=(4-r%4)%4;if(A)n.push(new Uint8Array(A)),r+=A;for(let[p,h]of Object.entries(m.header.parts??{}))if(!(p in s))s[p]=Ee(h,C);for(let[p,h]of Object.entries(m.header.studKinds??{}))if(!(p in o))o[p]=Ee(h,C)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),u=(4-(4+c.length)%4)%4,f=4+c.length+u,a=new Uint8Array(f+r);new DataView(a.buffer).setUint32(0,c.length+u,!0),a.set(c,4),a.fill(32,4+c.length,f);let l=f;for(let m of n)a.set(m,l),l+=m.byteLength;return ve(a.buffer)}async function Cn(e,t={}){e=[...e];try{return await kt(e,t)}catch(n){let r=t.cdn??ke,s=t.fetch??fetch;Le.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await kt(e,{...t,fetch:o})}catch{throw n}}}async function kt(e,t){let n=t.cdn??ke,r=t.fetch??fetch,s=t.gap??16384,o=await Se(n,r),i=[...new Set([...e].map(ne))],c=[],u=[];for(let p of i){if(Te.has(n+p))continue;let h=o.parts[p];if(h)u.push({name:p,off:h[0],len:h[1],file:h[2]??0});else c.push(p)}u.sort((p,h)=>p.file-h.file||p.off-h.off);let f=[];for(let p of u){let h=f[f.length-1];if(h&&h.file===p.file&&p.off-h.end<=s)h.end=Math.max(h.end,p.off+p.len),h.items.push(p);else f.push({file:p.file,start:p.off,end:p.off+p.len,items:[p]})}let a=0,l=0,m=0,g=new Map,d=async()=>{while(m<f.length){let p=f[m++],h=g.get(p.file);if(h)h=h.subarray(p.start,p.end);else{let M=await r(new URL(o.archives[p.file],n).href,{headers:{Range:`bytes=${p.start}-${p.end-1}`,"Accept-Encoding":"identity"}});if(!M.ok)throw Error(`ldr: parts CDN ${M.status}`);if(l++,h=new Uint8Array(await M.arrayBuffer()),a+=h.byteLength,M.status===200)g.set(p.file,h),h=h.subarray(p.start,p.end)}for(let M of p.items){let D=Ae(h.subarray(M.off-p.start,M.off-p.start+M.len)),v=D.buffer.slice(D.byteOffset,D.byteOffset+D.byteLength);Te.set(n+M.name,ve(v))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,f.length)},d));let b=i.filter((p)=>Te.has(n+p)).map((p)=>Te.get(n+p)),C={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:b.length?vn(b,C):ve(Tn(C)),missing:c,requests:l,bytes:a}}function Tn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function Ln(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function Pt(e,t,n){let r=0,s=0,o=!1,i=new Set;for(let c of e){let u=c.embedded?t.get(c.part):ne(c.part),f=u?n.parts[u]:void 0;if(!f)continue;if(f[3]!=null)o=!0,r+=f[3];if(!i.has(u))i.add(u),s+=f[1]}return{bodyTris:r,packBytes:s,known:o}}class Pe extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function It(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Se(t.cdn??ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(x)=>{if(!x.ok)throw Error(`ldr: ${x.status} fetching ${e}`);return et(await x.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":tt(e)),u=Tt(o,c,{looseGeometry:!1,callouts:t.callouts}),f=performance.now();t.onParsed?.(u),await s;let a=Lt(o,new Set(u.filter((x)=>x.embedded).map((x)=>x.part)),c),l=(x,w)=>t.maxBodyTris!=null&&x>t.maxBodyTris||t.maxPackBytes!=null&&w>t.maxPackBytes,m=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(x)=>new Pe({...x,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),d="full";if(m){let x=Pt(u,a,await s);if(l(x.known?x.bodyTris:0,x.packBytes)){if(!t.lowCdn)throw g(x);let w=await Se(t.lowCdn,r).catch(()=>null);if(!w)throw g(x);let E=Pt(u,a,w);if(l(E.known?E.bodyTris:0,E.packBytes))throw g(E);d="low"}}let b=[...u.filter((x)=>!x.embedded).map((x)=>x.part),...a.values()],C=async()=>{let x=await Cn(b,d==="low"?{...t,cdn:t.lowCdn}:t);for(let[w,E]of a){let z=x.pack.header.parts[E];if(z)x.pack.header.parts[w]=z}return{...x,packBytes:x.pack.buffer?.byteLength??x.pack.bytes??0,bodyTris:Ln(u,x.pack)}},A=await C();if(m&&l(A.bodyTris,A.packBytes)&&d==="full"&&t.lowCdn&&await Se(t.lowCdn,r).then(()=>!0,()=>!1)){d="low";let x=A;A=await C(),A.requests+=x.requests,A.bytes+=x.bytes}if(m&&l(A.bodyTris,A.packBytes))throw g(A);let{pack:p,missing:h,requests:M,bytes:D}=A,v=new Map([...a].map(([x,w])=>[w,x])),L=h.map((x)=>v.get(x)??x),R=performance.now(),T=t.cull?Ce(u,p.header,t.textures!==!1):void 0;return{insts:u,pack:p,tier:d,missing:L,requests:M,bytes:D,cull:T,timings:{fetchModel:i-n,parse:f-i,parts:R-f,...T?{cull:performance.now()-R}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await It(n,{...r,cull:!1,onParsed:(a)=>self.postMessage({id:t,insts:a})}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,tier:s.tier,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),c=Ce(s.insts,s.pack.header,r.textures!==!1),u=performance.now()-i,f=[];for(let a of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(a)f.push(a.buffer);self.postMessage({id:t,cull:c,ms:u},f)}catch(s){if(s instanceof Pe||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
|
|
4568
4706
|
|
|
4569
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4707
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/cdn.ts
|
|
4570
4708
|
var worker;
|
|
4571
4709
|
var seq = 0;
|
|
4572
4710
|
var pending = new Map;
|
|
@@ -4680,11 +4818,20 @@ async function loadModel(source, o = {}) {
|
|
|
4680
4818
|
timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
|
|
4681
4819
|
});
|
|
4682
4820
|
}
|
|
4683
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4684
|
-
import { existsSync, readFileSync } from "fs";
|
|
4821
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/library.ts
|
|
4822
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
4685
4823
|
import { join } from "path";
|
|
4686
4824
|
var xf = (m, x, y, z) => [m[3] * x + m[4] * y + m[5] * z + m[0], m[6] * x + m[7] * y + m[8] * z + m[1], m[9] * x + m[10] * y + m[11] * z + m[2]];
|
|
4687
4825
|
var det = (m) => m[3] * (m[7] * m[11] - m[8] * m[10]) - m[4] * (m[6] * m[11] - m[8] * m[9]) + m[5] * (m[6] * m[10] - m[7] * m[9]);
|
|
4826
|
+
var f32 = (x) => Number.isFinite(Math.fround(x));
|
|
4827
|
+
var inRange3 = (x) => Math.abs(x) <= MAX_COORD;
|
|
4828
|
+
var inRange122 = (m) => {
|
|
4829
|
+
for (let i = 0;i < 12; i++)
|
|
4830
|
+
if (!inRange3(m[i]))
|
|
4831
|
+
return false;
|
|
4832
|
+
return true;
|
|
4833
|
+
};
|
|
4834
|
+
var MESH_WORK_LIMIT = 1e6;
|
|
4688
4835
|
var IDENTITY12 = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
4689
4836
|
function isPlainAlias(f, target) {
|
|
4690
4837
|
if (STUB_OVERRIDES[norm(f.name)] === target)
|
|
@@ -4757,8 +4904,10 @@ class Library {
|
|
|
4757
4904
|
}
|
|
4758
4905
|
resolveFile(root, dir, name) {
|
|
4759
4906
|
const exact = join(root, dir, name);
|
|
4760
|
-
|
|
4761
|
-
|
|
4907
|
+
try {
|
|
4908
|
+
if (statSync(exact).isFile())
|
|
4909
|
+
return exact;
|
|
4910
|
+
} catch {}
|
|
4762
4911
|
return null;
|
|
4763
4912
|
}
|
|
4764
4913
|
colors() {
|
|
@@ -4785,6 +4934,8 @@ class Library {
|
|
|
4785
4934
|
if (hit)
|
|
4786
4935
|
return hit;
|
|
4787
4936
|
const pos = [], col = [], edges = [], cond = [];
|
|
4937
|
+
this.work = 0;
|
|
4938
|
+
this.open.clear();
|
|
4788
4939
|
const tx = opts.texmap ? { uv: [], tri: [], names: [], gloss: [] } : undefined;
|
|
4789
4940
|
const r = this.where(name);
|
|
4790
4941
|
if (r)
|
|
@@ -4820,14 +4971,19 @@ class Library {
|
|
|
4820
4971
|
}
|
|
4821
4972
|
return null;
|
|
4822
4973
|
}
|
|
4823
|
-
|
|
4974
|
+
open = new Set;
|
|
4975
|
+
work = 0;
|
|
4976
|
+
workLimit = MESH_WORK_LIMIT;
|
|
4977
|
+
flatY(doc, fname, m = I, depth = 0, budget = { n: 1e5 }) {
|
|
4824
4978
|
const f = doc.files.get(fname);
|
|
4825
4979
|
if (!f || depth > 40)
|
|
4826
4980
|
return true;
|
|
4981
|
+
if (--budget.n < 0)
|
|
4982
|
+
return false;
|
|
4827
4983
|
for (const c of f.cmds) {
|
|
4828
4984
|
if (c.t === 1) {
|
|
4829
4985
|
const sub = doc.files.has(c.file) ? doc : this.where(c.file)?.doc;
|
|
4830
|
-
if (sub && !this.flatY(sub, sub === doc ? c.file : sub.main, mul(m, c.m), depth + 1))
|
|
4986
|
+
if (sub && !this.flatY(sub, sub === doc ? c.file : sub.main, mul(m, c.m), depth + 1, budget))
|
|
4831
4987
|
return false;
|
|
4832
4988
|
continue;
|
|
4833
4989
|
}
|
|
@@ -4842,8 +4998,11 @@ class Library {
|
|
|
4842
4998
|
}
|
|
4843
4999
|
emit(doc, fname, m, color, inv, clip, pos, col, edges, cond, tx, texIn = null, scope0 = null) {
|
|
4844
5000
|
const f = doc.files.get(fname);
|
|
4845
|
-
if (!f)
|
|
5001
|
+
if (!f || this.open.has(f))
|
|
4846
5002
|
return;
|
|
5003
|
+
if (++this.work > this.workLimit)
|
|
5004
|
+
throw new ModelLimitError("part", this.workLimit);
|
|
5005
|
+
this.open.add(f);
|
|
4847
5006
|
let ccw = true, invertNext = false, clipLocal = true, certified = null, scope = scope0;
|
|
4848
5007
|
const flip = inv !== det(m) < 0;
|
|
4849
5008
|
const cc = (c) => {
|
|
@@ -4910,13 +5069,20 @@ class Library {
|
|
|
4910
5069
|
if (c.t === 1) {
|
|
4911
5070
|
const sub = doc.files.has(c.file) ? doc : this.where(c.file)?.doc;
|
|
4912
5071
|
const sf = sub ? sub === doc ? c.file : sub.main : "", fx = sub ? singularFix(c.m, () => this.flatY(sub, sf)) : null;
|
|
4913
|
-
|
|
4914
|
-
|
|
5072
|
+
const mm = sub ? mul(m, fx ? fx.m : c.m) : null;
|
|
5073
|
+
if (sub && inRange122(mm))
|
|
5074
|
+
this.emit(sub, sf, mm, cc(c.color), inv !== invertThis, cull && (!fx || fx.cull), pos, col, edges, cond, tx, tex, scope);
|
|
4915
5075
|
continue;
|
|
4916
5076
|
}
|
|
4917
5077
|
const p = c.p, v = [];
|
|
4918
|
-
|
|
4919
|
-
|
|
5078
|
+
let ok = p.length >= (c.t === 2 ? 6 : c.t === 3 ? 9 : 12);
|
|
5079
|
+
for (let i = 0;i + 2 < p.length && ok; i += 3) {
|
|
5080
|
+
const q = xf(m, p[i], p[i + 1], p[i + 2]);
|
|
5081
|
+
ok = inRange3(q[0]) && inRange3(q[1]) && inRange3(q[2]);
|
|
5082
|
+
v.push(q);
|
|
5083
|
+
}
|
|
5084
|
+
if (!ok)
|
|
5085
|
+
continue;
|
|
4920
5086
|
if (c.t === 2) {
|
|
4921
5087
|
edges.push(...v[0], ...v[1]);
|
|
4922
5088
|
continue;
|
|
@@ -4929,12 +5095,16 @@ class Library {
|
|
|
4929
5095
|
const ti = tx && tex ? texIdx(tex) : -1;
|
|
4930
5096
|
const code = cc(c.color);
|
|
4931
5097
|
const tri = (a, b, d) => {
|
|
5098
|
+
if (++this.work > this.workLimit)
|
|
5099
|
+
throw new ModelLimitError("part", this.workLimit);
|
|
4932
5100
|
pos.push(...a, ...b, ...d);
|
|
4933
5101
|
col.push(code);
|
|
4934
5102
|
if (tx) {
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
5103
|
+
const w = tex ? texmapTriangleUV(tex, [a, b, d]) : null;
|
|
5104
|
+
const good = !!w && w.every(f32);
|
|
5105
|
+
tx.tri.push(good ? ti : -1);
|
|
5106
|
+
if (good)
|
|
5107
|
+
tx.uv.push(...w);
|
|
4938
5108
|
else
|
|
4939
5109
|
tx.uv.push(NaN, NaN, NaN, NaN, NaN, NaN);
|
|
4940
5110
|
}
|
|
@@ -4948,6 +5118,7 @@ class Library {
|
|
|
4948
5118
|
if (!cull)
|
|
4949
5119
|
emitFace([...ordered].reverse());
|
|
4950
5120
|
}
|
|
5121
|
+
this.open.delete(f);
|
|
4951
5122
|
}
|
|
4952
5123
|
flatten(doc, opts = {}) {
|
|
4953
5124
|
for (const f of doc.files.keys())
|
|
@@ -4997,11 +5168,11 @@ class Library {
|
|
|
4997
5168
|
return insts;
|
|
4998
5169
|
}
|
|
4999
5170
|
}
|
|
5000
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5171
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/build-pack.ts
|
|
5001
5172
|
import fs3 from "node:fs";
|
|
5002
5173
|
import path3 from "node:path";
|
|
5003
5174
|
|
|
5004
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5175
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/resolver.ts
|
|
5005
5176
|
import fs from "node:fs";
|
|
5006
5177
|
import path from "node:path";
|
|
5007
5178
|
var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
|
|
@@ -5220,7 +5391,7 @@ function splitModel(text, fallbackName = "main.ldr") {
|
|
|
5220
5391
|
main = null;
|
|
5221
5392
|
};
|
|
5222
5393
|
for (const line of text.split(/\r?\n/)) {
|
|
5223
|
-
const m = /^\s*0\s+FILE\s+(
|
|
5394
|
+
const m = /^\s*0\s+FILE\s+(\S[^\r]*)/i.exec(line);
|
|
5224
5395
|
if (m) {
|
|
5225
5396
|
firstBlock();
|
|
5226
5397
|
flush();
|
|
@@ -5330,11 +5501,11 @@ function collectDeps(lib, refs) {
|
|
|
5330
5501
|
return out;
|
|
5331
5502
|
}
|
|
5332
5503
|
|
|
5333
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5504
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/compile.ts
|
|
5334
5505
|
import fs2 from "node:fs";
|
|
5335
5506
|
import path2 from "node:path";
|
|
5336
5507
|
|
|
5337
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5508
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/lod.ts
|
|
5338
5509
|
import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
|
|
5339
5510
|
await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
|
|
5340
5511
|
function reorderMesh(P, N, C, I) {
|
|
@@ -5526,7 +5697,7 @@ function lodChain(P, C, I) {
|
|
|
5526
5697
|
return out;
|
|
5527
5698
|
}
|
|
5528
5699
|
|
|
5529
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5700
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/compile.ts
|
|
5530
5701
|
class BfcState {
|
|
5531
5702
|
accum;
|
|
5532
5703
|
ccw = true;
|
|
@@ -5607,6 +5778,20 @@ var hexRgba = (hex) => {
|
|
|
5607
5778
|
return [(v >> 16) / 255, (v >> 8 & 255) / 255, (v & 255) / 255, 1];
|
|
5608
5779
|
};
|
|
5609
5780
|
var det3 = (m) => m[3] * (m[7] * m[11] - m[8] * m[10]) - m[4] * (m[6] * m[11] - m[8] * m[9]) + m[5] * (m[6] * m[10] - m[7] * m[9]);
|
|
5781
|
+
var inRangeM = (v) => {
|
|
5782
|
+
for (let i = 0;i < v.length; i++)
|
|
5783
|
+
if (!(Math.abs(v[i]) <= MAX_COORD))
|
|
5784
|
+
return false;
|
|
5785
|
+
return true;
|
|
5786
|
+
};
|
|
5787
|
+
var finiteAll = (v) => {
|
|
5788
|
+
for (let i = 0;i < v.length; i++)
|
|
5789
|
+
if (!Number.isFinite(v[i]))
|
|
5790
|
+
return false;
|
|
5791
|
+
return true;
|
|
5792
|
+
};
|
|
5793
|
+
var f322 = (p) => Math.abs(p[0]) <= MAX_COORD && Math.abs(p[1]) <= MAX_COORD && Math.abs(p[2]) <= MAX_COORD;
|
|
5794
|
+
var PART_WORK_LIMIT = 1e6;
|
|
5610
5795
|
|
|
5611
5796
|
class Compiler {
|
|
5612
5797
|
lib;
|
|
@@ -5623,15 +5808,18 @@ class Compiler {
|
|
|
5623
5808
|
const hit = this.flat.get(key);
|
|
5624
5809
|
if (hit !== undefined)
|
|
5625
5810
|
return hit;
|
|
5811
|
+
let budget = 1e5;
|
|
5626
5812
|
const walk = (fk, M, depth) => {
|
|
5627
5813
|
if (depth > 40)
|
|
5628
5814
|
return true;
|
|
5815
|
+
if (--budget < 0)
|
|
5816
|
+
return false;
|
|
5629
5817
|
for (const raw of this.lib.read(fk).split(/\r?\n/)) {
|
|
5630
5818
|
const t = raw.trim();
|
|
5631
5819
|
const c = t[0];
|
|
5632
5820
|
if (c === "1") {
|
|
5633
5821
|
const r = parseType1(t);
|
|
5634
|
-
if (!r)
|
|
5822
|
+
if (!r || !finiteAll(r.m))
|
|
5635
5823
|
continue;
|
|
5636
5824
|
const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
|
|
5637
5825
|
const k = this.resolve(r.name, TOP_STUD_RE.test(base));
|
|
@@ -5677,10 +5865,19 @@ class Compiler {
|
|
|
5677
5865
|
if (this.cache.has(ck))
|
|
5678
5866
|
return this.cache.get(ck);
|
|
5679
5867
|
const out = { body: { pos: [], col: [] }, under: { pos: [], col: [] }, edges: [], condLines: 0, cond: this.opts.cond ? [] : undefined, condUnder: this.opts.cond ? [] : undefined, studs: [], bbox: [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity], fullBottom: false };
|
|
5680
|
-
const colorOf = (code) => code === "16" ? [1, 1, 1, 0] : [...this.colors.get(code) || (code.startsWith("0x2") ? [parseInt(code.slice(3, 5), 16) / 255, parseInt(code.slice(5, 7), 16) / 255, parseInt(code.slice(7, 9), 16) / 255] : blendedRgb(code) ?? [1, 0, 1]), 1];
|
|
5868
|
+
const colorOf = (code) => code === "16" ? [1, 1, 1, 0] : code.charCodeAt(1) === 120 && !/^0x2[0-9a-f]{6}/i.test(code) && String(parseColor(code)) !== code ? colorOf(String(parseColor(code))) : [...this.colors.get(code) || (code.startsWith("0x2") ? [parseInt(code.slice(3, 5), 16) / 255, parseInt(code.slice(5, 7), 16) / 255, parseInt(code.slice(7, 9), 16) / 255] : blendedRgb(code) ?? [1, 0, 1]), 1];
|
|
5869
|
+
const open = new Set;
|
|
5870
|
+
let work = 0;
|
|
5871
|
+
const lim = this.opts.workLimit ?? PART_WORK_LIMIT;
|
|
5872
|
+
const step = () => {
|
|
5873
|
+
if (++work > lim)
|
|
5874
|
+
throw new ModelLimitError(`part ${key}`, lim);
|
|
5875
|
+
};
|
|
5681
5876
|
const walk = (fk, M, color, invert, target, depth, inh = null, scope0 = null, cull = true) => {
|
|
5682
|
-
if (depth > 40)
|
|
5877
|
+
if (depth > 40 || open.has(fk))
|
|
5683
5878
|
return;
|
|
5879
|
+
step();
|
|
5880
|
+
open.add(fk);
|
|
5684
5881
|
const bfc = new BfcState(cull);
|
|
5685
5882
|
let scope = scope0;
|
|
5686
5883
|
for (const raw of this.lib.read(fk).split(/\r?\n/)) {
|
|
@@ -5703,7 +5900,7 @@ class Compiler {
|
|
|
5703
5900
|
if (c === "1") {
|
|
5704
5901
|
const invertNext = bfc.takeInvert();
|
|
5705
5902
|
const r = parseType1(t);
|
|
5706
|
-
if (!r)
|
|
5903
|
+
if (!r || !finiteAll(r.m))
|
|
5707
5904
|
continue;
|
|
5708
5905
|
const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
|
|
5709
5906
|
const isTop = TOP_STUD_RE.test(base), isUnder = UNDER_STUD_RE.test(base);
|
|
@@ -5713,6 +5910,8 @@ class Compiler {
|
|
|
5713
5910
|
const childColor = r.color === "16" ? color : r.color, childInh = r.color === "16" ? inh : this.local(r.color, scope);
|
|
5714
5911
|
const fx = singularFix(r.m, () => this.flatY(ck2)), rm = fx ? fx.m : r.m, subCull = bfc.cull && (!fx || fx.cull);
|
|
5715
5912
|
const Mc = compose(M, rm);
|
|
5913
|
+
if (!inRangeM(Mc))
|
|
5914
|
+
continue;
|
|
5716
5915
|
const inv = invert !== invertNext !== det3(rm) < 0;
|
|
5717
5916
|
if (isTop && separateStuds && (!fx || fx.cull)) {
|
|
5718
5917
|
out.studs.push({ kind: ck2, color: childInh ? this.studToken(childColor, childInh) : childColor, m: Mc });
|
|
@@ -5726,7 +5925,11 @@ class Compiler {
|
|
|
5726
5925
|
const tok = t.split(/\s+/);
|
|
5727
5926
|
if (c === "2") {
|
|
5728
5927
|
const v = tok.slice(2, 8).map(Number);
|
|
5729
|
-
|
|
5928
|
+
if (v.length < 6 || !finiteAll(v))
|
|
5929
|
+
continue;
|
|
5930
|
+
const a = xf2(M, v.slice(0, 3)), b = xf2(M, v.slice(3, 6));
|
|
5931
|
+
if (f322(a) && f322(b))
|
|
5932
|
+
out.edges.push(...a, ...b);
|
|
5730
5933
|
continue;
|
|
5731
5934
|
}
|
|
5732
5935
|
if (c === "5") {
|
|
@@ -5734,18 +5937,26 @@ class Compiler {
|
|
|
5734
5937
|
const dst = target === "under" ? out.condUnder : out.cond;
|
|
5735
5938
|
if (dst) {
|
|
5736
5939
|
const v = t.split(/\s+/).slice(2, 14).map(Number);
|
|
5737
|
-
if (v.length === 12 && v.every(Number.isFinite))
|
|
5738
|
-
|
|
5739
|
-
|
|
5940
|
+
if (v.length === 12 && v.every(Number.isFinite)) {
|
|
5941
|
+
const q = [0, 3, 6, 9].map((i) => xf2(M, v.slice(i, i + 3)));
|
|
5942
|
+
if (q.every(f322))
|
|
5943
|
+
for (const p of q)
|
|
5944
|
+
dst.push(...p);
|
|
5945
|
+
}
|
|
5740
5946
|
}
|
|
5741
5947
|
continue;
|
|
5742
5948
|
}
|
|
5743
5949
|
if (c === "3" || c === "4") {
|
|
5744
5950
|
const n = c === "3" ? 3 : 4;
|
|
5745
5951
|
const v = tok.slice(2, 2 + n * 3).map(Number);
|
|
5952
|
+
if (v.length < n * 3 || !finiteAll(v))
|
|
5953
|
+
continue;
|
|
5746
5954
|
const pts = [];
|
|
5747
5955
|
for (let i = 0;i < n; i++)
|
|
5748
5956
|
pts.push(xf2(M, v.slice(i * 3, i * 3 + 3)));
|
|
5957
|
+
if (!pts.every(f322))
|
|
5958
|
+
continue;
|
|
5959
|
+
step();
|
|
5749
5960
|
for (const p of pts)
|
|
5750
5961
|
grow(out.bbox, p);
|
|
5751
5962
|
const flip = !bfc.ccw !== invert, rgba = this.rgbaAt(tok[1], color, inh, scope, colorOf), b = out[target];
|
|
@@ -5766,6 +5977,7 @@ class Compiler {
|
|
|
5766
5977
|
}
|
|
5767
5978
|
if (!bfc.certified)
|
|
5768
5979
|
out.uncertified = true;
|
|
5980
|
+
open.delete(fk);
|
|
5769
5981
|
};
|
|
5770
5982
|
const fullKind = new Map;
|
|
5771
5983
|
let culled = 0;
|
|
@@ -5866,9 +6078,11 @@ class Compiler {
|
|
|
5866
6078
|
}
|
|
5867
6079
|
texPass(key, out, separateStuds, colorOf) {
|
|
5868
6080
|
const tbody = { pos: [], col: [] }, texb = new Map;
|
|
6081
|
+
const open = new Set;
|
|
5869
6082
|
const walk = (fk, M, color, invert, target, depth, texIn, inh = null, scope0 = null, cull = true) => {
|
|
5870
|
-
if (depth > 40)
|
|
6083
|
+
if (depth > 40 || open.has(fk))
|
|
5871
6084
|
return;
|
|
6085
|
+
open.add(fk);
|
|
5872
6086
|
const bfc = new BfcState(cull);
|
|
5873
6087
|
let scope = scope0;
|
|
5874
6088
|
let stack = [];
|
|
@@ -5944,7 +6158,7 @@ class Compiler {
|
|
|
5944
6158
|
}
|
|
5945
6159
|
if (c === "1") {
|
|
5946
6160
|
const r = parseType1(t);
|
|
5947
|
-
if (!r)
|
|
6161
|
+
if (!r || !finiteAll(r.m))
|
|
5948
6162
|
continue;
|
|
5949
6163
|
const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
|
|
5950
6164
|
const isTop = TOP_STUD_RE.test(base), isUnder = UNDER_STUD_RE.test(base);
|
|
@@ -5955,7 +6169,10 @@ class Compiler {
|
|
|
5955
6169
|
const inv = invert !== invertNext !== det3(rm) < 0;
|
|
5956
6170
|
if (isTop && separateStuds && (!fx || fx.cull))
|
|
5957
6171
|
continue;
|
|
5958
|
-
|
|
6172
|
+
const Mc = compose(M, rm);
|
|
6173
|
+
if (!inRangeM(Mc))
|
|
6174
|
+
continue;
|
|
6175
|
+
walk(ck2, Mc, r.color === "16" ? color : r.color, inv, isUnder ? "under" : target, depth + 1, tex, r.color === "16" ? inh : this.local(r.color, scope), scope, subCull);
|
|
5959
6176
|
continue;
|
|
5960
6177
|
}
|
|
5961
6178
|
if (c !== "3" && c !== "4")
|
|
@@ -5963,11 +6180,17 @@ class Compiler {
|
|
|
5963
6180
|
const tok = t.split(/\s+/);
|
|
5964
6181
|
const n = c === "3" ? 3 : 4;
|
|
5965
6182
|
const v = tok.slice(2, 2 + n * 3).map(Number);
|
|
6183
|
+
if (v.length < n * 3 || !finiteAll(v))
|
|
6184
|
+
continue;
|
|
5966
6185
|
const pts = [];
|
|
5967
6186
|
for (let i = 0;i < n; i++)
|
|
5968
6187
|
pts.push(xf2(M, v.slice(i * 3, i * 3 + 3)));
|
|
6188
|
+
if (!pts.every(f322))
|
|
6189
|
+
continue;
|
|
5969
6190
|
const order = windOrder(n, !bfc.ccw !== invert, bfc.cull || !!out.uncertified);
|
|
5970
6191
|
const rgba = this.rgbaAt(tok[1], color, inh, scope, colorOf);
|
|
6192
|
+
if (tex && !texmapTriangleUV(tex, pts).every((x) => Number.isFinite(Math.fround(x))))
|
|
6193
|
+
tex = null;
|
|
5971
6194
|
if (tex) {
|
|
5972
6195
|
const tk = tex.glossmap ? tex.texture + "\x00" + tex.glossmap : tex.texture;
|
|
5973
6196
|
let b = texb.get(tk);
|
|
@@ -5990,6 +6213,7 @@ class Compiler {
|
|
|
5990
6213
|
tbody.col.push(...rgba);
|
|
5991
6214
|
}
|
|
5992
6215
|
}
|
|
6216
|
+
open.delete(fk);
|
|
5993
6217
|
};
|
|
5994
6218
|
walk(key, IDENT, "16", false, "body", 0, null);
|
|
5995
6219
|
if (texb.size) {
|
|
@@ -6094,22 +6318,91 @@ function seatStuds(out, fullKind, kindBox) {
|
|
|
6094
6318
|
if (!out.studs.length)
|
|
6095
6319
|
return;
|
|
6096
6320
|
const tris = [out.body.pos, out.under.pos];
|
|
6097
|
-
const
|
|
6098
|
-
|
|
6321
|
+
const nTri = (out.body.pos.length + out.under.pos.length) / 9;
|
|
6322
|
+
let nChk = 0;
|
|
6323
|
+
for (let i = 0;i < out.studs.length; i++) {
|
|
6324
|
+
const f = fullKind.get(i);
|
|
6325
|
+
if (f && f !== out.studs[i].kind)
|
|
6326
|
+
nChk++;
|
|
6327
|
+
}
|
|
6328
|
+
let grid = null;
|
|
6329
|
+
if (nChk * 9 * nTri > 4000000) {
|
|
6330
|
+
const box = [];
|
|
6331
|
+
const sz = [];
|
|
6332
|
+
const seen = new Set;
|
|
6333
|
+
for (let t = 0;t < 2; t++) {
|
|
6334
|
+
const p = tris[t];
|
|
6099
6335
|
for (let i = 0;i < p.length; i += 9) {
|
|
6100
|
-
const
|
|
6101
|
-
|
|
6102
|
-
if (nl < 0.000000001)
|
|
6336
|
+
const dk = p[i] + "," + p[i + 1] + "," + p[i + 2] + "," + p[i + 3] + "," + p[i + 4] + "," + p[i + 5] + "," + p[i + 6] + "," + p[i + 7] + "," + p[i + 8];
|
|
6337
|
+
if (seen.has(dk))
|
|
6103
6338
|
continue;
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
const
|
|
6107
|
-
|
|
6339
|
+
seen.add(dk);
|
|
6340
|
+
const L = Math.max(Math.hypot(p[i + 3] - p[i], p[i + 4] - p[i + 1], p[i + 5] - p[i + 2]), Math.hypot(p[i + 6] - p[i], p[i + 7] - p[i + 1], p[i + 8] - p[i + 2]), Math.hypot(p[i + 6] - p[i + 3], p[i + 7] - p[i + 4], p[i + 8] - p[i + 5]));
|
|
6341
|
+
const g = 0.06 + 0.0004 * L;
|
|
6342
|
+
const b = [Math.min(p[i], p[i + 3], p[i + 6]) - g, Math.min(p[i + 1], p[i + 4], p[i + 7]) - g, Math.min(p[i + 2], p[i + 5], p[i + 8]) - g, Math.max(p[i], p[i + 3], p[i + 6]) + g, Math.max(p[i + 1], p[i + 4], p[i + 7]) + g, Math.max(p[i + 2], p[i + 5], p[i + 8]) + g, t, i];
|
|
6343
|
+
box.push(b);
|
|
6344
|
+
sz.push(Math.max(b[3] - b[0], b[4] - b[1], b[5] - b[2]));
|
|
6345
|
+
}
|
|
6346
|
+
}
|
|
6347
|
+
sz.sort((x, y) => x - y);
|
|
6348
|
+
const h = Math.max(2 * (sz[sz.length >> 1] ?? 1), 0.5);
|
|
6349
|
+
grid = { levels: [], big: [] };
|
|
6350
|
+
const G = grid;
|
|
6351
|
+
for (const b of box) {
|
|
6352
|
+
const ref = b[6] * 1073741824 + b[7];
|
|
6353
|
+
let placed = false;
|
|
6354
|
+
for (let lv = 0, hl = h;lv < 8 && !placed; lv++, hl *= 8) {
|
|
6355
|
+
const ax = Math.floor(b[0] / hl), bx = Math.floor(b[3] / hl), ay = Math.floor(b[1] / hl), by = Math.floor(b[4] / hl), az = Math.floor(b[2] / hl), bz = Math.floor(b[5] / hl);
|
|
6356
|
+
if (!((bx - ax + 1) * (by - ay + 1) * (bz - az + 1) <= 512))
|
|
6108
6357
|
continue;
|
|
6109
|
-
const
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6358
|
+
const L = G.levels[lv] ??= { h: hl, cells: new Map };
|
|
6359
|
+
placed = true;
|
|
6360
|
+
for (let x = ax;x <= bx; x++)
|
|
6361
|
+
for (let y = ay;y <= by; y++)
|
|
6362
|
+
for (let z = az;z <= bz; z++) {
|
|
6363
|
+
const key = x + "," + y + "," + z;
|
|
6364
|
+
let l = L.cells.get(key);
|
|
6365
|
+
if (!l)
|
|
6366
|
+
L.cells.set(key, l = []);
|
|
6367
|
+
l.push(ref);
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6370
|
+
if (!placed)
|
|
6371
|
+
G.big.push(ref);
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
const hit = (p, i, c, up) => {
|
|
6375
|
+
const ax = p[i], ay = p[i + 1], az = p[i + 2], ux = p[i + 3] - ax, uy = p[i + 4] - ay, uz = p[i + 5] - az, vx = p[i + 6] - ax, vy = p[i + 7] - ay, vz = p[i + 8] - az;
|
|
6376
|
+
const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx, nl = Math.hypot(nx, ny, nz);
|
|
6377
|
+
if (nl < 0.000000001)
|
|
6378
|
+
return false;
|
|
6379
|
+
if (!out.uncertified && nx * up[0] + ny * up[1] + nz * up[2] <= 0)
|
|
6380
|
+
return false;
|
|
6381
|
+
const wx = c[0] - ax, wy = c[1] - ay, wz = c[2] - az;
|
|
6382
|
+
if (Math.abs((wx * nx + wy * ny + wz * nz) / nl) > 0.05)
|
|
6383
|
+
return false;
|
|
6384
|
+
const uu = ux * ux + uy * uy + uz * uz, vv = vx * vx + vy * vy + vz * vz, uv = ux * vx + uy * vy + uz * vz, wu = wx * ux + wy * uy + wz * uz, wv = wx * vx + wy * vy + wz * vz;
|
|
6385
|
+
const d = uv * uv - uu * vv, s = (uv * wv - vv * wu) / d, t = (uv * wu - uu * wv) / d, e = 0.0001;
|
|
6386
|
+
return s >= -e && t >= -e && s + t <= 1 + e;
|
|
6387
|
+
};
|
|
6388
|
+
const covered = (c, up) => {
|
|
6389
|
+
if (!grid) {
|
|
6390
|
+
for (const p of tris)
|
|
6391
|
+
for (let i = 0;i < p.length; i += 9)
|
|
6392
|
+
if (hit(p, i, c, up))
|
|
6393
|
+
return true;
|
|
6394
|
+
return false;
|
|
6395
|
+
}
|
|
6396
|
+
const G = grid;
|
|
6397
|
+
const at = (ref) => hit(tris[ref >= 1073741824 ? 1 : 0], ref % 1073741824, c, up);
|
|
6398
|
+
for (const r of G.big)
|
|
6399
|
+
if (at(r))
|
|
6400
|
+
return true;
|
|
6401
|
+
for (const L of G.levels)
|
|
6402
|
+
if (L) {
|
|
6403
|
+
for (const r of L.cells.get(Math.floor(c[0] / L.h) + "," + Math.floor(c[1] / L.h) + "," + Math.floor(c[2] / L.h)) ?? [])
|
|
6404
|
+
if (at(r))
|
|
6405
|
+
return true;
|
|
6113
6406
|
}
|
|
6114
6407
|
return false;
|
|
6115
6408
|
};
|
|
@@ -6336,9 +6629,9 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
|
|
|
6336
6629
|
return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
|
|
6337
6630
|
}
|
|
6338
6631
|
|
|
6339
|
-
// ../../../../../../../tmp/ldr-build-
|
|
6632
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/build-pack.ts
|
|
6340
6633
|
function packCompilerOpts(o) {
|
|
6341
|
-
return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures };
|
|
6634
|
+
return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures, ...o.partWorkLimit ? { workLimit: o.partWorkLimit } : {} };
|
|
6342
6635
|
}
|
|
6343
6636
|
function buildPack(o) {
|
|
6344
6637
|
const lib = new Library2(o.ldrawRoot);
|
|
@@ -6408,13 +6701,14 @@ function buildPack(o) {
|
|
|
6408
6701
|
const warnings = [...lib.conflicts].map((n) => `${n}: defined differently by two models; the first definition is used`);
|
|
6409
6702
|
return { data: encodePack(parts, kinds, comp.opts.weld, extra, { texture, lod: o.lod !== false, reorder: !!o.reorder }), parts: parts.size, studKinds: kinds.size, missing: [...missing], ...warnings.length ? { warnings } : {} };
|
|
6410
6703
|
}
|
|
6411
|
-
// ../../../../../../../tmp/ldr-build-
|
|
6704
|
+
// ../../../../../../../tmp/ldr-build-fQmQmL/src/node/promote.ts
|
|
6412
6705
|
var GEOM = /^\s*[2-5]\s/;
|
|
6413
6706
|
var REF = /^\s*1\s/;
|
|
6414
|
-
var FILE = /^\s*0\s+FILE\s+(
|
|
6707
|
+
var FILE = /^\s*0\s+FILE\s+(\S.*?)\s*$/i;
|
|
6415
6708
|
var END = /^\s*0\s+(NOFILE|!DATA)(\s|$)/i;
|
|
6416
6709
|
var MODEL_ORG2 = /^(\s*0\s+!LDRAW_ORG\s+)(?:Unofficial_)?(?:Model|Submodel)\b/i;
|
|
6417
6710
|
var PART_ORG2 = /^\s*0\s+!LDRAW_ORG\s+(?:Unofficial_)?Part\b/i;
|
|
6711
|
+
var ANY_ORG = /^\s*0\s+!LDRAW_ORG\s/i;
|
|
6418
6712
|
var key = (s) => s.trim().toLowerCase().replace(/\\/g, "/");
|
|
6419
6713
|
function promoteFlexParts(text) {
|
|
6420
6714
|
const lines = text.split(/(?<=\n)/);
|
|
@@ -6423,7 +6717,7 @@ function promoteFlexParts(text) {
|
|
|
6423
6717
|
for (let i = 0;i < lines.length; i++) {
|
|
6424
6718
|
const l = lines[i], f = FILE.exec(l);
|
|
6425
6719
|
if (f) {
|
|
6426
|
-
blocks.push(cur = { name: f[1], org: -1, geom: 0, refs: [] });
|
|
6720
|
+
blocks.push(cur = { name: f[1], org: -1, model: false, geom: 0, refs: [] });
|
|
6427
6721
|
continue;
|
|
6428
6722
|
}
|
|
6429
6723
|
if (END.test(l)) {
|
|
@@ -6438,13 +6732,15 @@ function promoteFlexParts(text) {
|
|
|
6438
6732
|
const t = l.trim().split(/\s+/);
|
|
6439
6733
|
if (t.length >= 15)
|
|
6440
6734
|
cur.refs.push(key(t.slice(14).join(" ")));
|
|
6441
|
-
} else if (cur.org < 0 &&
|
|
6735
|
+
} else if (cur.org < 0 && ANY_ORG.test(l)) {
|
|
6442
6736
|
cur.org = i;
|
|
6737
|
+
cur.model = MODEL_ORG2.test(l);
|
|
6738
|
+
}
|
|
6443
6739
|
}
|
|
6444
|
-
const plainModel = new Set(blocks.filter((b, i) => i > 0 && b.
|
|
6740
|
+
const plainModel = new Set(blocks.filter((b, i) => i > 0 && b.model && !b.geom).map((b) => key(b.name)));
|
|
6445
6741
|
const promoted = [];
|
|
6446
6742
|
for (const b of blocks.slice(1)) {
|
|
6447
|
-
if (b.
|
|
6743
|
+
if (!b.model || !b.geom || b.refs.some((r) => plainModel.has(r)))
|
|
6448
6744
|
continue;
|
|
6449
6745
|
lines[b.org] = lines[b.org].replace(MODEL_ORG2, "$1Unofficial_Part");
|
|
6450
6746
|
promoted.push(b.name);
|
|
@@ -6655,7 +6951,9 @@ export {
|
|
|
6655
6951
|
DEFAULT_PARTS_CDN,
|
|
6656
6952
|
I as IDENTITY,
|
|
6657
6953
|
Library,
|
|
6954
|
+
MAX_COORD,
|
|
6658
6955
|
MIN_VIS,
|
|
6956
|
+
ModelLimitError,
|
|
6659
6957
|
REORIENT,
|
|
6660
6958
|
Library2 as ResolverLibrary,
|
|
6661
6959
|
blendedColourHex,
|