ldr 0.34.10 → 0.34.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/spec.ts
1
+ // ../../../../../../../tmp/ldr-build-vpoU1w/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;
@@ -833,7 +833,7 @@ function fileStepViews(f) {
833
833
  viewMemo.set(f, out);
834
834
  return out;
835
835
  }
836
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/model.ts
836
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/model.ts
837
837
  class ModelLimitError extends Error {
838
838
  limit;
839
839
  code = "ldr-model-limit";
@@ -1274,7 +1274,7 @@ function blendedColourHex(code) {
1274
1274
  const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
1275
1275
  return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
1276
1276
  }
1277
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/instructions.ts
1277
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/instructions.ts
1278
1278
  var MIN_VIS = 0.5;
1279
1279
  var REORIENT = 0.35;
1280
1280
  var deg = Math.PI / 180;
@@ -1642,10 +1642,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
1642
1642
  }
1643
1643
  };
1644
1644
  }
1645
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/render.ts
1646
- import * as THREE from "three";
1645
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/render.ts
1646
+ import * as THREE2 from "three";
1647
1647
 
1648
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/pack-io.ts
1648
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/pack-io.ts
1649
1649
  import { decompress } from "fzstd";
1650
1650
  async function decompressPack(data) {
1651
1651
  const u = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -1668,7 +1668,106 @@ function decodePack(buf) {
1668
1668
  return { header, arr, bytes: buf.byteLength, buffer: buf };
1669
1669
  }
1670
1670
 
1671
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/cull.ts
1671
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/stud-decal.ts
1672
+ import * as THREE from "three";
1673
+ function studDecalUniforms(near = 0) {
1674
+ return { center: { value: new THREE.Vector3 }, near: { value: near } };
1675
+ }
1676
+ var _quad = new Map;
1677
+ function studDecalGeom(grid = 1) {
1678
+ const hit = _quad.get(grid);
1679
+ if (hit)
1680
+ return hit;
1681
+ const y = -4 / grid, r = 10;
1682
+ const pos = new Float32Array([-r, y, -r, r, y, -r, r, y, r, -r, y, -r, r, y, r, -r, y, r]);
1683
+ const nrm = new Int8Array(18);
1684
+ for (let i = 0;i < 6; i++)
1685
+ nrm[i * 3 + 1] = -127;
1686
+ const col = new Uint8Array(24);
1687
+ for (let i = 0;i < 6; i++) {
1688
+ col[i * 4] = col[i * 4 + 1] = col[i * 4 + 2] = 255;
1689
+ col[i * 4 + 3] = 0;
1690
+ }
1691
+ const g = new THREE.BufferGeometry;
1692
+ g.setAttribute("position", new THREE.BufferAttribute(pos, 3));
1693
+ g.setAttribute("normal", new THREE.BufferAttribute(nrm, 3, true));
1694
+ g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
1695
+ g.computeBoundingSphere();
1696
+ g.computeBoundingBox();
1697
+ _quad.set(grid, g);
1698
+ return g;
1699
+ }
1700
+ var cache = new WeakMap;
1701
+ function studDecalMaterial(base, U, grid) {
1702
+ let m = cache.get(base);
1703
+ if (!m)
1704
+ cache.set(base, m = new Map);
1705
+ const hit = m.get(grid);
1706
+ if (hit)
1707
+ return hit;
1708
+ const d = base.clone();
1709
+ const prev = base.onBeforeCompile;
1710
+ const key = base.customProgramCacheKey?.() ?? "";
1711
+ d.polygonOffset = true;
1712
+ d.polygonOffsetFactor = -2;
1713
+ d.polygonOffsetUnits = -4;
1714
+ d.onBeforeCompile = (s, r) => {
1715
+ prev.call(base, s, r);
1716
+ s.uniforms.uStudC = U.center;
1717
+ s.uniforms.uStudNear = U.near;
1718
+ s.vertexShader = s.vertexShader.replace("#include <common>", `#include <common>
1719
+ varying vec2 vSt;
1720
+ varying vec3 vSW;
1721
+ varying vec3 vTx;
1722
+ varying vec3 vTz;`).replace("#include <begin_vertex>", `#include <begin_vertex>
1723
+ vSt = position.xz;
1724
+ mat4 sdM = modelMatrix;
1725
+ #ifdef USE_INSTANCING
1726
+ sdM = modelMatrix * instanceMatrix;
1727
+ #endif
1728
+ vSW = (sdM * vec4(position, 1.0)).xyz;
1729
+ vTx = normalize((viewMatrix * sdM * vec4(1.0, 0.0, 0.0, 0.0)).xyz);
1730
+ vTz = normalize((viewMatrix * sdM * vec4(0.0, 0.0, 1.0, 0.0)).xyz);`);
1731
+ s.fragmentShader = s.fragmentShader.replace("#include <common>", `#include <common>
1732
+ uniform vec3 uStudC;
1733
+ uniform float uStudNear;
1734
+ varying vec2 vSt;
1735
+ varying vec3 vSW;
1736
+ varying vec3 vTx;
1737
+ varying vec3 vTz;`).replace("#include <roughnessmap_fragment>", `#include <roughnessmap_fragment>
1738
+ if (distance(vSW.xz, uStudC.xz) < uStudNear) discard; // the real studs stand here
1739
+ // parallax: march the view ray on from the studs' tops (the quad) down to the plate (they repeat every 20/SG LDU); the first point
1740
+ // inside a stud is its top (the first sample) or its wall (any later one), else the ray reaches the plate between studs
1741
+ const float SG = ${grid.toFixed(1)}, SC = 20.0 / SG, SR = 6.0 / SG, SH = 4.0 / SG; // cell, radius, height (LDU)
1742
+ vec3 sdUp = normalize(vNormal) * (gl_FrontFacing ? 1.0 : -1.0), sdV = normalize(vViewPosition);
1743
+ vec3 sdVt = vec3(dot(sdV, vTx), max(dot(sdV, sdUp), 0.08), dot(sdV, vTz)); // toward the eye, stud space (y: up)
1744
+ vec2 sdStep = sdVt.xz / sdVt.y * (SH / 8.0); if (length(sdStep) > SC * 0.2) sdStep *= SC * 0.2 / length(sdStep);
1745
+ float sdPxA = length(dFdx(vSt)), sdPxB = length(dFdy(vSt)), sdPx = min(sdPxA, sdPxB), sdPxM = max(sdPxA, sdPxB);
1746
+ float sdK = clamp((SC / sdPx - 2.5) / 3.0, 0.0, 1.0); // a stud cell under ~3 px: shading fades to the plate's average (no shimmer)
1747
+ float sdAa = max(sdPxM * 0.7, 0.05);
1748
+ float sdHit = -1.0; vec2 sdC = vec2(0.0);
1749
+ for (int i = 0; i <= 8; i++) { vec2 q = vSt - sdStep * float(i); vec2 c = (fract(q / SC + 0.5) - 0.5) * SC;
1750
+ if (length(c) < SR) { sdHit = float(i); sdC = c; break; } }
1751
+ vec2 sdG = (fract((vSt - sdStep * 8.0) / SC + 0.5) - 0.5) * SC; float sdRg = length(sdG); // the plate point, from its nearest stud
1752
+ float sdTop = sdHit == 0.0 ? 1.0 : 0.0, sdWall = sdHit > 0.0 ? 1.0 : 0.0;
1753
+ float sdRim = sdTop * smoothstep(SR - 0.9 * SH - sdAa, SR, length(sdC)); // the rounded edge of a top
1754
+ vec2 sdD = (sdHit >= 0.0 ? sdC : sdG) / max(length(sdHit >= 0.0 ? sdC : sdG), 1e-4);
1755
+ float sdAo = sdHit >= 0.0 ? 1.0 - 0.22 * sdWall * (sdHit / 8.0) // a wall darkens toward its foot
1756
+ : 1.0 - 0.45 * exp(-(sdRg - SR) / (0.5 * SH)); // the plate darkens next to a stud (contact shadow)
1757
+ float sdEdgeAvg = 0.9; // a cell's average darkening, what the shading fades to
1758
+ diffuseColor.rgb *= mix(sdEdgeAvg, sdAo, sdK);
1759
+ roughnessFactor = clamp(roughnessFactor * mix(1.0, sdTop > 0.5 ? 0.85 : 1.1, sdK), 0.04, 1.0);
1760
+ `).replace("#include <normal_fragment_maps>", `#include <normal_fragment_maps>
1761
+ { vec3 sdN = sdUp; vec3 sdR = vTx * sdD.x + vTz * sdD.y;
1762
+ if (sdWall > 0.5) sdN = normalize(sdR + sdUp * 0.12); else if (sdRim > 0.0) sdN = normalize(sdUp + sdR * 1.2 * sdRim);
1763
+ normal = normalize(mix(normal, sdN, sdK)); }`);
1764
+ };
1765
+ d.customProgramCacheKey = () => key + `|stud-decal-${grid}`;
1766
+ m.set(grid, d);
1767
+ return d;
1768
+ }
1769
+
1770
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/cull.ts
1672
1771
  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;
1673
1772
  var prepCache = new WeakMap;
1674
1773
  var lastH = null;
@@ -1954,17 +2053,14 @@ function cullPass(insts, H, steps, eCap) {
1954
2053
  return v;
1955
2054
  };
1956
2055
  const nI = insts.length;
1957
- let cap = 0, nR = 0;
1958
- for (let idx = 0, lp = "";idx < nI; idx++) {
1959
- const part = insts[idx].part;
1960
- if (part === lp) {
1961
- cap++;
1962
- continue;
1963
- }
1964
- const p = H.parts[part];
1965
- if (p && p.mask) {
1966
- cap++;
1967
- lp = part;
2056
+ let cap = 0, nR = 0, nStuds = 0;
2057
+ const pps = new Array(nI);
2058
+ for (let idx = 0;idx < nI; idx++) {
2059
+ const pp = pps[idx] = prepPart(H, insts[idx].part);
2060
+ if (pp) {
2061
+ nStuds += pp.nStuds;
2062
+ if (pp.mask)
2063
+ cap++;
1968
2064
  }
1969
2065
  }
1970
2066
  const rx0 = new Float64Array(cap), rx1 = new Float64Array(cap), rz0 = new Float64Array(cap), rz1 = new Float64Array(cap);
@@ -1999,7 +2095,7 @@ function cullPass(insts, H, steps, eCap) {
1999
2095
  z1 = wz;
2000
2096
  }
2001
2097
  const lv2 = Math.round((m[1] + b[4]) * 2);
2002
- const pp = prepPart(H, it.part);
2098
+ const pp = pps[idx];
2003
2099
  const cx0 = Math.floor(x0 / CELL), cx1 = Math.floor(x1 / CELL), cz0 = Math.floor(z0 / CELL), cz1 = Math.floor(z1 / CELL);
2004
2100
  if (!((cx1 - cx0 + 1) * (cz1 - cz0 + 1) <= 65536) || !inRange(lv2, cx0, cz0) || !inRange(lv2, cx1, cz1))
2005
2101
  continue;
@@ -2120,12 +2216,6 @@ function cullPass(insts, H, steps, eCap) {
2120
2216
  }
2121
2217
  return best;
2122
2218
  };
2123
- let nStuds = 0;
2124
- for (const it of insts) {
2125
- const pp = prepPart(H, it.part);
2126
- if (pp)
2127
- nStuds += pp.nStuds;
2128
- }
2129
2219
  const studHidden = new Uint8Array(nStuds), studUp = new Uint8Array(nStuds);
2130
2220
  let studsHidden = 0;
2131
2221
  const tops = steps ? new Int3Table(nStuds, 4) : null;
@@ -2134,7 +2224,7 @@ function cullPass(insts, H, steps, eCap) {
2134
2224
  const studHideStep = steps ? new Int32Array(nStuds).fill(STEP_NEVER) : undefined;
2135
2225
  for (let idx = 0, j = 0;idx < insts.length; idx++) {
2136
2226
  const it = insts[idx];
2137
- const pp = prepPart(H, it.part);
2227
+ const pp = pps[idx];
2138
2228
  if (!pp)
2139
2229
  continue;
2140
2230
  const m = it.m, S = pp.studM;
@@ -2259,7 +2349,7 @@ function precomputeCull(instances, H, useTex = true) {
2259
2349
  return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
2260
2350
  }
2261
2351
 
2262
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/render.ts
2352
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/render.ts
2263
2353
  async function loadPack(url) {
2264
2354
  const res = await fetch(url);
2265
2355
  if (!res.ok)
@@ -2283,14 +2373,14 @@ var toF16 = (a) => {
2283
2373
  const o = new Uint16Array(a.length);
2284
2374
  for (let i = 0;i < a.length; i++) {
2285
2375
  const v = a[i];
2286
- o[i] = THREE.DataUtils.toHalfFloat(v > F16_MAX ? F16_MAX : v < -F16_MAX ? -F16_MAX : v);
2376
+ o[i] = THREE2.DataUtils.toHalfFloat(v > F16_MAX ? F16_MAX : v < -F16_MAX ? -F16_MAX : v);
2287
2377
  }
2288
2378
  return o;
2289
2379
  };
2290
2380
  function keepHalf(bm) {
2291
2381
  const p = bm.geometry.getAttribute("position");
2292
2382
  if (p && !p.isFloat16BufferAttribute && p.array instanceof Uint16Array)
2293
- bm.geometry.setAttribute("position", new THREE.Float16BufferAttribute(p.array, p.itemSize));
2383
+ bm.geometry.setAttribute("position", new THREE2.Float16BufferAttribute(p.array, p.itemSize));
2294
2384
  }
2295
2385
  function flatNormals(pos, idx) {
2296
2386
  const n = new Float32Array(pos.length);
@@ -2324,17 +2414,17 @@ function geom(b, arr) {
2324
2414
  let g = c.get(b);
2325
2415
  if (g)
2326
2416
  return g;
2327
- g = new THREE.BufferGeometry;
2417
+ g = new THREE2.BufferGeometry;
2328
2418
  const pos = arr(b.pos);
2329
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(pos), 3));
2419
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(pos), 3));
2330
2420
  const nrm = b.nrm ? arr(b.nrm) : flatNormals(pos, arr(b.idx));
2331
2421
  const col = arr(b.col);
2332
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(nrm), 3, true));
2333
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col instanceof Uint8Array ? col : toU8(col), 4, true));
2422
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(nrm), 3, true));
2423
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col instanceof Uint8Array ? col : toU8(col), 4, true));
2334
2424
  if (b.idx)
2335
- g.setIndex(new THREE.BufferAttribute(arr(b.idx), 1));
2425
+ g.setIndex(new THREE2.BufferAttribute(arr(b.idx), 1));
2336
2426
  if (b.uv)
2337
- g.setAttribute("ldrUV", new THREE.BufferAttribute(arr(b.uv), 2));
2427
+ g.setAttribute("ldrUV", new THREE2.BufferAttribute(arr(b.uv), 2));
2338
2428
  g.computeBoundingSphere();
2339
2429
  g.computeBoundingBox();
2340
2430
  c.set(b, g);
@@ -2359,7 +2449,7 @@ function patchParticleFragment(shader, surface) {
2359
2449
  const frac = Math.max(0.01, Math.min(0.95, surface.particleFraction ?? 0.3));
2360
2450
  const size = Math.max(0.02, surface.particleSize ?? 1);
2361
2451
  const sparkle = surface.finish === "glitter" ? 1 : 0;
2362
- shader.uniforms.ldrParticle = { value: new THREE.Vector4(pr, pg, pb, frac) };
2452
+ shader.uniforms.ldrParticle = { value: new THREE2.Vector4(pr, pg, pb, frac) };
2363
2453
  shader.uniforms.ldrParticleSize = { value: size };
2364
2454
  shader.uniforms.ldrSparkle = { value: sparkle };
2365
2455
  shader.vertexShader = `varying vec3 ldrGrainP;
@@ -2392,16 +2482,16 @@ function makeFinishMaterial(side, surface) {
2392
2482
  transparent: surface.transparent,
2393
2483
  opacity: surface.opacity,
2394
2484
  depthWrite: surface.depthWrite,
2395
- ...surface.emissive > 0 ? { emissive: new THREE.Color(1, 1, 1), emissiveIntensity: surface.emissive } : {}
2485
+ ...surface.emissive > 0 ? { emissive: new THREE2.Color(1, 1, 1), emissiveIntensity: surface.emissive } : {}
2396
2486
  };
2397
- const m = needPhysical ? new THREE.MeshPhysicalMaterial({
2487
+ const m = needPhysical ? new THREE2.MeshPhysicalMaterial({
2398
2488
  ...common,
2399
2489
  clearcoat: surface.clearcoat,
2400
2490
  clearcoatRoughness: surface.clearcoatRoughness,
2401
2491
  sheen: surface.sheen,
2402
2492
  sheenRoughness: surface.sheenRoughness,
2403
- sheenColor: new THREE.Color(1, 1, 1)
2404
- }) : new THREE.MeshStandardMaterial(common);
2493
+ sheenColor: new THREE2.Color(1, 1, 1)
2494
+ }) : new THREE2.MeshStandardMaterial(common);
2405
2495
  const particle = !!surface.particleHex;
2406
2496
  m.onBeforeCompile = (s) => {
2407
2497
  patchLdrColorVertex(s);
@@ -2468,21 +2558,29 @@ function pngHasAlpha(b) {
2468
2558
  return false;
2469
2559
  }
2470
2560
  function packTexture(pack, i, data = false) {
2471
- const t = new THREE.Texture;
2561
+ const t = new THREE2.Texture;
2472
2562
  t.flipY = false;
2473
- t.colorSpace = data ? THREE.NoColorSpace : THREE.SRGBColorSpace;
2474
- t.wrapS = t.wrapT = THREE.ClampToEdgeWrapping;
2563
+ t.colorSpace = data ? THREE2.NoColorSpace : THREE2.SRGBColorSpace;
2564
+ t.wrapS = t.wrapT = THREE2.ClampToEdgeWrapping;
2475
2565
  const e = pack.header.textures?.[i];
2476
2566
  const bytes = e?.data ? pack.arr(e.data) : null;
2477
2567
  if (!bytes || typeof createImageBitmap === "undefined")
2478
2568
  return { texture: t, ready: Promise.resolve() };
2569
+ const done = decoded.get(e);
2570
+ if (done) {
2571
+ t.image = done;
2572
+ t.needsUpdate = true;
2573
+ return { texture: t, ready: Promise.resolve() };
2574
+ }
2479
2575
  const ready = createImageBitmap(new Blob([bytes], { type: e.mime || "image/png" }), { premultiplyAlpha: "none", colorSpaceConversion: "none" }).then((img) => {
2576
+ decoded.set(e, img);
2480
2577
  t.image = img;
2481
2578
  t.needsUpdate = true;
2482
2579
  }).catch(() => {});
2483
2580
  return { texture: t, ready };
2484
2581
  }
2485
- var sharedLineMat = () => new THREE.ShaderMaterial({
2582
+ var decoded = new WeakMap;
2583
+ var sharedLineMat = () => new THREE2.ShaderMaterial({
2486
2584
  vertexShader: `attribute mat4 instanceMatrix; void main(){ gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position,1.0); }`,
2487
2585
  fragmentShader: `void main(){ gl_FragColor = vec4(0.13,0.13,0.13,1.0); }`
2488
2586
  });
@@ -2556,8 +2654,8 @@ function conditionalLines(pack, entry, which = "all") {
2556
2654
  }
2557
2655
  return out;
2558
2656
  }
2559
- var condLineMat = () => new THREE.ShaderMaterial({
2560
- uniforms: { ldrViewProj: { value: new THREE.Matrix4 } },
2657
+ var condLineMat = () => new THREE2.ShaderMaterial({
2658
+ uniforms: { ldrViewProj: { value: new THREE2.Matrix4 } },
2561
2659
  vertexShader: `uniform mat4 ldrViewProj; attribute mat4 instanceMatrix; attribute vec3 ldrP1; attribute vec3 ldrC0; attribute vec3 ldrC1; attribute float ldrSide;
2562
2660
  void main(){
2563
2661
  mat4 mvp = ldrViewProj * instanceMatrix;
@@ -2595,18 +2693,18 @@ function condBuffers(cond) {
2595
2693
  }
2596
2694
  side[l * 2 + 1] = 1;
2597
2695
  }
2598
- return { ib: new THREE.InterleavedBuffer(buf, 12), side: new THREE.BufferAttribute(side, 1) };
2696
+ return { ib: new THREE2.InterleavedBuffer(buf, 12), side: new THREE2.BufferAttribute(side, 1) };
2599
2697
  }
2600
2698
  function condEdges({ ib, side }, im, material) {
2601
- const g = new THREE.InstancedBufferGeometry;
2602
- g.setAttribute("position", new THREE.InterleavedBufferAttribute(ib, 3, 0));
2603
- g.setAttribute("ldrP1", new THREE.InterleavedBufferAttribute(ib, 3, 3));
2604
- g.setAttribute("ldrC0", new THREE.InterleavedBufferAttribute(ib, 3, 6));
2605
- g.setAttribute("ldrC1", new THREE.InterleavedBufferAttribute(ib, 3, 9));
2699
+ const g = new THREE2.InstancedBufferGeometry;
2700
+ g.setAttribute("position", new THREE2.InterleavedBufferAttribute(ib, 3, 0));
2701
+ g.setAttribute("ldrP1", new THREE2.InterleavedBufferAttribute(ib, 3, 3));
2702
+ g.setAttribute("ldrC0", new THREE2.InterleavedBufferAttribute(ib, 3, 6));
2703
+ g.setAttribute("ldrC1", new THREE2.InterleavedBufferAttribute(ib, 3, 9));
2606
2704
  g.setAttribute("ldrSide", side);
2607
2705
  g.setAttribute("instanceMatrix", im.instanceMatrix);
2608
2706
  g.instanceCount = im.count;
2609
- const l = new THREE.LineSegments(g, material);
2707
+ const l = new THREE2.LineSegments(g, material);
2610
2708
  l.frustumCulled = false;
2611
2709
  l.name = "ldrCondLines";
2612
2710
  l.onBeforeRender = (_r, _s, cam, _g, mat) => {
@@ -2621,12 +2719,12 @@ function condEdges({ ib, side }, im, material) {
2621
2719
  }
2622
2720
  function sharedLines(pos, im, material = sharedLineMat()) {
2623
2721
  const { P, I } = weldLines(pos);
2624
- const g = new THREE.InstancedBufferGeometry;
2625
- g.setAttribute("position", new THREE.BufferAttribute(P, 3));
2626
- g.setIndex(new THREE.BufferAttribute(I, 1));
2722
+ const g = new THREE2.InstancedBufferGeometry;
2723
+ g.setAttribute("position", new THREE2.BufferAttribute(P, 3));
2724
+ g.setIndex(new THREE2.BufferAttribute(I, 1));
2627
2725
  g.setAttribute("instanceMatrix", im.instanceMatrix);
2628
2726
  g.instanceCount = im.count;
2629
- const l = new THREE.LineSegments(g, material);
2727
+ const l = new THREE2.LineSegments(g, material);
2630
2728
  l.frustumCulled = false;
2631
2729
  return l;
2632
2730
  }
@@ -2649,8 +2747,8 @@ function writeM4(t, o, m, mo = 0) {
2649
2747
  t[o + 15] = 1;
2650
2748
  }
2651
2749
  function newIM(g, mat, n) {
2652
- const im = new THREE.InstancedMesh(g, mat, 0);
2653
- im.instanceMatrix = new THREE.InstancedBufferAttribute(new Float32Array(n * 16), 16);
2750
+ const im = new THREE2.InstancedMesh(g, mat, 0);
2751
+ im.instanceMatrix = new THREE2.InstancedBufferAttribute(new Float32Array(n * 16), 16);
2654
2752
  im.count = n;
2655
2753
  return im;
2656
2754
  }
@@ -2713,7 +2811,7 @@ function sphereUnion(S, A, n) {
2713
2811
  S[3] = r;
2714
2812
  }
2715
2813
  function setSphere(im, S) {
2716
- const sph = im.boundingSphere ?? new THREE.Sphere;
2814
+ const sph = im.boundingSphere ?? new THREE2.Sphere;
2717
2815
  sph.center.set(S[0], S[1], S[2]);
2718
2816
  sph.radius = S[3];
2719
2817
  if (S[3] < 0)
@@ -2783,7 +2881,7 @@ function fillInstances(im, ids, insts, color) {
2783
2881
  writeM4(M, k * 16, it.m);
2784
2882
  color(it.color).toArray(C, k * 3);
2785
2883
  }
2786
- im.instanceColor = new THREE.InstancedBufferAttribute(C, 3);
2884
+ im.instanceColor = new THREE2.InstancedBufferAttribute(C, 3);
2787
2885
  }
2788
2886
  function computeCulling(insts, H) {
2789
2887
  const c = cullCore(insts, H);
@@ -2915,10 +3013,10 @@ function studDiscGeom() {
2915
3013
  col[i * 4 + 2] = 255;
2916
3014
  col[i * 4 + 3] = 0;
2917
3015
  }
2918
- const g = new THREE.BufferGeometry;
2919
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(pos), 3));
2920
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(nrm), 3, true));
2921
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
3016
+ const g = new THREE2.BufferGeometry;
3017
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(pos), 3));
3018
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(nrm), 3, true));
3019
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col, 4, true));
2922
3020
  g.computeBoundingSphere();
2923
3021
  g.computeBoundingBox();
2924
3022
  return _studDisc = g;
@@ -2965,11 +3063,11 @@ function studBoxGeom(w) {
2965
3063
  col[i * 4 + 2] = 255;
2966
3064
  col[i * 4 + 3] = 0;
2967
3065
  }
2968
- g = new THREE.BufferGeometry;
2969
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
2970
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
2971
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
2972
- g.setIndex(new THREE.BufferAttribute(new Uint16Array(idx), 1));
3066
+ g = new THREE2.BufferGeometry;
3067
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
3068
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
3069
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col, 4, true));
3070
+ g.setIndex(new THREE2.BufferAttribute(new Uint16Array(idx), 1));
2973
3071
  g.computeBoundingSphere();
2974
3072
  g.computeBoundingBox();
2975
3073
  _studBox.set(w, g);
@@ -3036,11 +3134,11 @@ function studTubeGeom(w, wi) {
3036
3134
  col[i * 4 + 2] = 255;
3037
3135
  col[i * 4 + 3] = 0;
3038
3136
  }
3039
- g = new THREE.BufferGeometry;
3040
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
3041
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
3042
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
3043
- g.setIndex(new THREE.BufferAttribute(new Uint16Array(idx), 1));
3137
+ g = new THREE2.BufferGeometry;
3138
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
3139
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
3140
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col, 4, true));
3141
+ g.setIndex(new THREE2.BufferAttribute(new Uint16Array(idx), 1));
3044
3142
  g.computeBoundingSphere();
3045
3143
  g.computeBoundingBox();
3046
3144
  _studTube.set(key, g);
@@ -3186,7 +3284,7 @@ function studTopClosed(b, arr) {
3186
3284
  }
3187
3285
  var EDGE_CAP_MIN = 4;
3188
3286
 
3189
- class LdrLodRoot extends THREE.LOD {
3287
+ class LdrLodRoot extends THREE2.LOD {
3190
3288
  clusters = [];
3191
3289
  vpH = 1080;
3192
3290
  px = 0.5;
@@ -3195,8 +3293,8 @@ class LdrLodRoot extends THREE.LOD {
3195
3293
  edgeCap = 0;
3196
3294
  enabled = true;
3197
3295
  apply = () => {};
3198
- inv = new THREE.Matrix4;
3199
- cp = new THREE.Vector3;
3296
+ inv = new THREE2.Matrix4;
3297
+ cp = new THREE2.Vector3;
3200
3298
  lastW = new Float32Array(16).fill(NaN);
3201
3299
  constructor() {
3202
3300
  super();
@@ -3328,7 +3426,51 @@ function fillBucketIds(bIds, fill, studBucket, j0, j1) {
3328
3426
  bIds[b][fill[b]++] = j;
3329
3427
  }
3330
3428
  }
3331
- function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colorIndex, trim = false) {
3429
+ var _studGrid = new WeakMap;
3430
+ function studGridGeom(g, n) {
3431
+ if (n <= 1)
3432
+ return g;
3433
+ let m = _studGrid.get(g);
3434
+ if (!m)
3435
+ _studGrid.set(g, m = new Map);
3436
+ const hit = m.get(n);
3437
+ if (hit)
3438
+ return hit;
3439
+ const src = g;
3440
+ const P = src.getAttribute("position"), nv = P.count, k = n * n, pos = new Float32Array(nv * 3 * k), out = new THREE2.BufferGeometry;
3441
+ for (let a = 0, c = 0;a < n; a++)
3442
+ for (let b = 0;b < n; b++, c++) {
3443
+ const ox = ((a + 0.5) / n - 0.5) * 20, oz = ((b + 0.5) / n - 0.5) * 20, o = c * nv * 3;
3444
+ for (let v = 0;v < nv; v++) {
3445
+ pos[o + v * 3] = P.getX(v) / n + ox;
3446
+ pos[o + v * 3 + 1] = P.getY(v) / n;
3447
+ pos[o + v * 3 + 2] = P.getZ(v) / n + oz;
3448
+ }
3449
+ }
3450
+ out.setAttribute("position", g.getAttribute("position") instanceof THREE2.Float16BufferAttribute ? new THREE2.Float16BufferAttribute(toF16(pos), 3) : new THREE2.BufferAttribute(pos, 3));
3451
+ for (const name of Object.keys(src.attributes)) {
3452
+ if (name === "position")
3453
+ continue;
3454
+ const A = src.getAttribute(name);
3455
+ const sa = A.array, dst = new sa.constructor(sa.length * k);
3456
+ for (let c = 0;c < k; c++)
3457
+ dst.set(sa, c * sa.length);
3458
+ out.setAttribute(name, new A.constructor(dst, A.itemSize, A.normalized));
3459
+ }
3460
+ const I = src.getIndex();
3461
+ if (I) {
3462
+ const ia = I.array, ni = ia.length, big = nv * k > 65535, dst = big ? new Uint32Array(ni * k) : new Uint16Array(ni * k);
3463
+ for (let c = 0;c < k; c++)
3464
+ for (let i = 0;i < ni; i++)
3465
+ dst[c * ni + i] = ia[i] + c * nv;
3466
+ out.setIndex(new THREE2.BufferAttribute(dst, 1));
3467
+ }
3468
+ out.computeBoundingSphere();
3469
+ out.computeBoundingBox();
3470
+ m.set(n, out);
3471
+ return out;
3472
+ }
3473
+ function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colorIndex, trim = false, grid = 1) {
3332
3474
  const bKind = [], bMat = [];
3333
3475
  const bAll = [];
3334
3476
  const studBucket = new Uint16Array(cull.nStuds);
@@ -3446,7 +3588,7 @@ function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colo
3446
3588
  }
3447
3589
  const n = trim ? v : c.length;
3448
3590
  const im = newIM(g, bMat[b], n);
3449
- im.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(n * 3), 3);
3591
+ im.instanceColor = new THREE2.InstancedBufferAttribute(new Float32Array(n * 3), 3);
3450
3592
  sMesh.push({ im, kind, vis: v, all: c.length, ...steps ? { slots: { own: new Int32Array(n), hide: new Int32Array(n), inst: new Int32Array(n), stud: new Int16Array(n), col: new Uint16Array(n) } } : {} });
3451
3593
  }
3452
3594
  };
@@ -3454,10 +3596,10 @@ function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colo
3454
3596
  if (b)
3455
3597
  yield;
3456
3598
  const kind = bKind[b];
3457
- const g = geom(H.studKinds[kind].body, arr);
3599
+ const g0 = geom(H.studKinds[kind].body, arr), g = g0 && studGridGeom(g0, grid);
3458
3600
  const ids = bIds[b];
3459
3601
  const studTris = g ? (g.getIndex() ? g.getIndex().count : g.getAttribute("position").count) / 3 : 24;
3460
- const kStud = LOD ? Math.max(256, Math.min(4096, Math.round(65536 / Math.max(1, studTris)))) : Infinity;
3602
+ const kStud = LOD ? Math.max(256, Math.min(4096, Math.round(65536 * grid / Math.max(1, studTris)))) : Infinity;
3461
3603
  const clusters = yield* gridClustersGen(ids.length, (i) => sx[ids[i]], (i) => sz[ids[i]], kStud);
3462
3604
  for (let c0 = 0;c0 < clusters.length; c0 += 4) {
3463
3605
  if (c0)
@@ -3605,6 +3747,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3605
3747
  const { header: H, arr } = pack;
3606
3748
  const LOD = P.lod !== false;
3607
3749
  const EDGES = !!P.edges;
3750
+ const G = Math.max(1, Math.round(P.studGrid ?? 1));
3608
3751
  const root = new LdrLodRoot;
3609
3752
  root.enabled = LOD;
3610
3753
  root.px = P.lodPx ?? 0.5;
@@ -3625,8 +3768,8 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3625
3768
  base.apply(this, a);
3626
3769
  };
3627
3770
  };
3628
- const matF = makeMaterial(P.side === "front" ? THREE.FrontSide : THREE.DoubleSide), matB = makeMaterial(P.side === "front" ? THREE.BackSide : THREE.DoubleSide);
3629
- const matD = makeMaterial(THREE.DoubleSide);
3771
+ const matF = makeMaterial(P.side === "front" ? THREE2.FrontSide : THREE2.DoubleSide), matB = makeMaterial(P.side === "front" ? THREE2.BackSide : THREE2.DoubleSide);
3772
+ const matD = makeMaterial(THREE2.DoubleSide);
3630
3773
  let nUncert = 0;
3631
3774
  matF.userData.ldrSideRole = "F";
3632
3775
  matB.userData.ldrSideRole = "B";
@@ -3659,7 +3802,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3659
3802
  const key = fk + "|" + role;
3660
3803
  let m = matCache.get(key);
3661
3804
  if (!m) {
3662
- const side = uncert ? THREE.DoubleSide : P.side === "front" ? mirror ? THREE.BackSide : THREE.FrontSide : THREE.DoubleSide;
3805
+ const side = uncert ? THREE2.DoubleSide : P.side === "front" ? mirror ? THREE2.BackSide : THREE2.FrontSide : THREE2.DoubleSide;
3663
3806
  if (fk === "default:op" && lc.luminance === 0) {
3664
3807
  m = role === "D" ? matD : role === "B" ? matB : matF;
3665
3808
  } else {
@@ -3773,7 +3916,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3773
3916
  let w = lineCache.get(ref);
3774
3917
  if (!w) {
3775
3918
  const r = weldLines(src ? src.pos : arr(ref), LOD && !src?.lens);
3776
- lineCache.set(ref, w = { P: new THREE.BufferAttribute(r.P, 3), I: new THREE.BufferAttribute(r.I, 1), lens: src?.lens ?? r.lens, order: r.order });
3919
+ lineCache.set(ref, w = { P: new THREE2.BufferAttribute(r.P, 3), I: new THREE2.BufferAttribute(r.I, 1), lens: src?.lens ?? r.lens, order: r.order });
3777
3920
  }
3778
3921
  return lineObj(w, im, cl);
3779
3922
  };
@@ -3793,17 +3936,17 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3793
3936
  I[n * 2 + 1] = FI[k * 2 + 1];
3794
3937
  lens[n++] = full.lens[k];
3795
3938
  }
3796
- lineCache.set(ref, w = { P: full.P, I: new THREE.BufferAttribute(I.subarray(0, n * 2), 1), lens: lens.subarray(0, n) });
3939
+ lineCache.set(ref, w = { P: full.P, I: new THREE2.BufferAttribute(I.subarray(0, n * 2), 1), lens: lens.subarray(0, n) });
3797
3940
  }
3798
3941
  return lineObj(w, im, cl);
3799
3942
  };
3800
3943
  const lineObj = (w, im, cl) => {
3801
- const g = new THREE.InstancedBufferGeometry;
3944
+ const g = new THREE2.InstancedBufferGeometry;
3802
3945
  g.setAttribute("position", w.P);
3803
3946
  g.setIndex(w.I);
3804
3947
  g.setAttribute("instanceMatrix", im.instanceMatrix);
3805
3948
  g.instanceCount = im.count;
3806
- const l = new THREE.LineSegments(g, lmat());
3949
+ const l = new THREE2.LineSegments(g, lmat());
3807
3950
  l.frustumCulled = false;
3808
3951
  if (LOD)
3809
3952
  l.userData.ldrLens = w.lens;
@@ -3854,7 +3997,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3854
3997
  return gm ?? undefined;
3855
3998
  };
3856
3999
  const texMat = (t, base, wrapU, g) => {
3857
- const role = base.userData?.ldrSideRole ?? (base.side === THREE.BackSide ? "B" : base.side === THREE.DoubleSide ? "D" : "F");
4000
+ const role = base.userData?.ldrSideRole ?? (base.side === THREE2.BackSide ? "B" : base.side === THREE2.DoubleSide ? "D" : "F");
3858
4001
  const fin = base.userData?.ldrFinish ?? "default";
3859
4002
  const gloss = glossOf(g);
3860
4003
  const k = t + ":" + role + ":" + fin + ":" + (wrapU ? 1 : 0) + (gloss ? ":g" + g : "");
@@ -3880,7 +4023,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3880
4023
  return c;
3881
4024
  };
3882
4025
  const lodLevels = (b, base, mat) => !LOD || !b?.lod ? [] : b.lod.map((l) => {
3883
- const im = new THREE.InstancedMesh(geom(l, arr), mat, 0);
4026
+ const im = new THREE2.InstancedMesh(geom(l, arr), mat, 0);
3884
4027
  im.userData = { ...base.userData };
3885
4028
  im.instanceMatrix = base.instanceMatrix;
3886
4029
  im.count = base.count;
@@ -4072,8 +4215,8 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4072
4215
  }
4073
4216
  }
4074
4217
  yield root;
4075
- const tmpM = new THREE.Matrix4;
4076
- const tmpC = new THREE.Color;
4218
+ const tmpM = new THREE2.Matrix4;
4219
+ const tmpC = new THREE2.Color;
4077
4220
  for (const [mat, items] of coldByMat) {
4078
4221
  yield root;
4079
4222
  const entries = [];
@@ -4113,7 +4256,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4113
4256
  yield root;
4114
4257
  }
4115
4258
  }
4116
- const bm = new THREE.BatchedMesh(members.length, Math.max(1, maxV), Math.max(1, maxI), mat);
4259
+ const bm = new THREE2.BatchedMesh(members.length, Math.max(1, maxV), Math.max(1, maxI), mat);
4117
4260
  bm.perObjectFrustumCulled = true;
4118
4261
  bm.sortObjects = false;
4119
4262
  bm.frustumCulled = true;
@@ -4157,7 +4300,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4157
4300
  members.length = 0;
4158
4301
  members.push(...live);
4159
4302
  bm.computeBoundingSphere();
4160
- const cl = newCluster(bm.boundingSphere ?? new THREE.Sphere, bm);
4303
+ const cl = newCluster(bm.boundingSphere ?? new THREE2.Sphere, bm);
4161
4304
  const bodyErrs = live.map(({ p }) => [0, ...(p.body?.lod ?? []).map((l) => l.err)]);
4162
4305
  bm.userData.ldrMergeGids = instGids;
4163
4306
  cl.mergedLod = { bm, gids: instGids, errs: bodyErrs };
@@ -4178,7 +4321,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4178
4321
  continue;
4179
4322
  if (!pp.edges && !(wantCond && (pp.condl || pp.condlu)))
4180
4323
  continue;
4181
- const ghost = newIM(geom(pp.body, arr) || new THREE.BufferGeometry, mat, ids.length);
4324
+ const ghost = newIM(geom(pp.body, arr) || new THREE2.BufferGeometry, mat, ids.length);
4182
4325
  fillInstances(ghost, ids, insts, color);
4183
4326
  const nL = cl.lines.length, nC = cl.cond.length;
4184
4327
  if (pp.edges)
@@ -4228,7 +4371,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4228
4371
  yield root;
4229
4372
  }
4230
4373
  }
4231
- const ubm = new THREE.BatchedMesh(umembers.length, Math.max(1, uV), Math.max(1, uI), mat);
4374
+ const ubm = new THREE2.BatchedMesh(umembers.length, Math.max(1, uV), Math.max(1, uI), mat);
4232
4375
  ubm.perObjectFrustumCulled = true;
4233
4376
  ubm.sortObjects = false;
4234
4377
  ubm.frustumCulled = true;
@@ -4278,7 +4421,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4278
4421
  umembers.length = 0;
4279
4422
  umembers.push(...uLive);
4280
4423
  ubm.computeBoundingSphere();
4281
- const ucl = newCluster(ubm.boundingSphere ?? new THREE.Sphere, ubm);
4424
+ const ucl = newCluster(ubm.boundingSphere ?? new THREE2.Sphere, ubm);
4282
4425
  const uErrs = uLive.map(({ p }) => [0, ...(p.under?.lod ?? []).map((l) => l.err)]);
4283
4426
  ubm.userData._stepMode = !!steps;
4284
4427
  ubm.userData.ldrMergeGids = uInstGids;
@@ -4300,7 +4443,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4300
4443
  continue;
4301
4444
  const ord = [...ids.filter((id) => !cull.underHidden[id]), ...ids.filter((id) => cull.underHidden[id])];
4302
4445
  const vis = ids.length - ids.reduce((a, id) => a + cull.underHidden[id], 0);
4303
- const ghost = newIM(geom(pp.under, arr) || new THREE.BufferGeometry, mat, ord.length);
4446
+ const ghost = newIM(geom(pp.under, arr) || new THREE2.BufferGeometry, mat, ord.length);
4304
4447
  fillInstances(ghost, ord, insts, color);
4305
4448
  const nC = ucl.cond.length;
4306
4449
  addCond(pp, ghost, ucl, "under");
@@ -4352,7 +4495,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4352
4495
  }
4353
4496
  }
4354
4497
  yield root;
4355
- const _studGen = buildStudMeshesGen(insts, H, cull, arr, LOD, color, (c, mirror) => materialFor(c, mirror, false), steps, steps && colorIndex, !steps && !!P.cullStuds);
4498
+ const _studGen = buildStudMeshesGen(insts, H, cull, arr, LOD, color, (c, mirror) => materialFor(c, mirror, false), steps, steps && colorIndex, !steps && !!P.cullStuds, G);
4356
4499
  let _studR = _studGen.next();
4357
4500
  while (!_studR.done) {
4358
4501
  yield root;
@@ -4361,10 +4504,10 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4361
4504
  const sMesh = _studR.value;
4362
4505
  const sKind = sMesh.map((x) => x?.kind ?? "");
4363
4506
  const sVis = sMesh.map((x) => x?.vis ?? 0);
4364
- const STUD_ERR = 12;
4365
- const STUD_BOX_ERR = 2.49;
4507
+ const STUD_ERR = 12 / G;
4508
+ const STUD_BOX_ERR = 2.49 / G;
4366
4509
  const STUD_BOX_W_LOW = 5.317;
4367
- const STUD_DISC_ERR = 8;
4510
+ const STUD_DISC_ERR = 8 / G;
4368
4511
  let _coopS = 0;
4369
4512
  const sqLineKey = new Map;
4370
4513
  for (let ci = 0;ci < sMesh.length; ci++) {
@@ -4395,7 +4538,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4395
4538
  const h = studTopClosed(k.body, arr) ? null : studHole(k.body, arr);
4396
4539
  const hole = h ? { r: h.r, w: h.r * Math.sqrt(Math.PI) / 2 } : undefined;
4397
4540
  if (LOD && (hole || studTopClosed(k.body, arr)) && (im.geometry.getIndex()?.count ?? im.geometry.getAttribute("position").count) > 30) {
4398
- const box = new THREE.InstancedMesh(hole ? studTubeGeom(sqW, hole.w) : studBoxGeom(sqW), im.material, 0);
4541
+ const box = new THREE2.InstancedMesh(studGridGeom(hole ? studTubeGeom(sqW, hole.w) : studBoxGeom(sqW), G), im.material, 0);
4399
4542
  box.userData = { ldrStud: true, ldrLod: true };
4400
4543
  box.instanceMatrix = im.instanceMatrix;
4401
4544
  box.count = im.count;
@@ -4405,11 +4548,11 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4405
4548
  box.onBeforeRender = trackVp;
4406
4549
  root.add(box);
4407
4550
  discObjs.push(box);
4408
- cl.lv.push({ objs: [box], err: h ? Math.max(STUD_BOX_ERR, 6 * Math.SQRT2 - h.out) : STUD_BOX_ERR });
4551
+ cl.lv.push({ objs: [box], err: h ? Math.max(STUD_BOX_ERR, (6 * Math.SQRT2 - h.out) / G) : STUD_BOX_ERR });
4409
4552
  cl.studLineLv = 1;
4410
4553
  }
4411
4554
  if (LOD) {
4412
- const disc = new THREE.InstancedMesh(studDiscGeom(), im.material, 0);
4555
+ const disc = new THREE2.InstancedMesh(studGridGeom(studDiscGeom(), G), im.material, 0);
4413
4556
  disc.userData = { ldrStud: true, ldrLod: true };
4414
4557
  disc.instanceMatrix = im.instanceMatrix;
4415
4558
  disc.count = im.count;
@@ -4422,7 +4565,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4422
4565
  cl.lv.push({ objs: [disc], err: STUD_DISC_ERR });
4423
4566
  cl.lv.push({ objs: [], err: STUD_ERR });
4424
4567
  }
4425
- if (EDGES && k.edges) {
4568
+ if (EDGES && k.edges && G === 1) {
4426
4569
  const round = addLines(k.edges, im, cl);
4427
4570
  let sq = cl.studLineLv === 1 && round ? sqLineKey.get(kind) : null;
4428
4571
  if (sq === undefined) {
@@ -4448,6 +4591,18 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4448
4591
  toggles.push({ mesh: countTo(() => objs), all: trim ? vis : all, visible: vis, flag: "studs" });
4449
4592
  if (sm.slots)
4450
4593
  stepBatches.push({ im, objs, flag: "studs", ...sm.slots });
4594
+ if (sm.slots && P.studDecal && im.material.opacity === 1 && !im.material.transparent) {
4595
+ const n = im.instanceMatrix.count, decal = new THREE2.InstancedMesh(studDecalGeom(G), studDecalMaterial(im.material, P.studDecal, G), n);
4596
+ decal.instanceMatrix = new THREE2.InstancedBufferAttribute(im.instanceMatrix.array.slice(), 16);
4597
+ decal.instanceColor = new THREE2.InstancedBufferAttribute(im.instanceColor.array.slice(), 3);
4598
+ decal.count = im.count;
4599
+ decal.boundingSphere = im.boundingSphere;
4600
+ decal.visible = false;
4601
+ decal.userData = { ldrStudDecal: true };
4602
+ root.add(decal);
4603
+ stepBatches[stepBatches.length - 1].decal = decal;
4604
+ stats.studDecals = (stats.studDecals ?? 0) + 1;
4605
+ }
4451
4606
  }
4452
4607
  yield root;
4453
4608
  stats.uncertParts = Object.values(H.parts).filter((x) => x.uncert).length;
@@ -4489,12 +4644,17 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4489
4644
  const texturesReady = Promise.all(pending).then(() => {});
4490
4645
  let stepS = STEP_NEVER - 1, cullS = !!P.cullStuds, cullU = !!P.cullUnder;
4491
4646
  let only = null;
4492
- const applySteps = () => {
4647
+ let studMask = null;
4648
+ const applySteps = (studsOnly = false) => {
4493
4649
  const st = { studsTotal: 0, studsHidden: 0, undersTotal: 0, undersHidden: 0 };
4494
- const S = stepS, O = only;
4650
+ const S = stepS, O = only, SM = studMask, SA = SM && !("r" in SM) ? SM : null, SCi = SM && "r" in SM ? SM : null, SR2 = SCi ? Math.sign(SCi.r) * SCi.r * SCi.r : 0;
4495
4651
  const wm = new Float64Array(12);
4496
4652
  for (const b of stepBatches) {
4653
+ if (studsOnly && b.flag !== "studs")
4654
+ continue;
4497
4655
  const MA = b.im.instanceMatrix.array, CA = b.im.instanceColor.array;
4656
+ const D = b.decal, DM = D?.instanceMatrix.array, DC = D?.instanceColor.array, sm = b.flag === "studs" ? SM : null;
4657
+ let w2 = 0;
4498
4658
  const useHide = b.flag === "studs" ? cullS : b.flag === "under" ? cullU : false;
4499
4659
  const { own, hide, inst, stud, col } = b;
4500
4660
  let w = 0;
@@ -4516,14 +4676,31 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4516
4676
  const n = inst[i];
4517
4677
  if (O && !O[n])
4518
4678
  continue;
4519
- if (stud) {
4679
+ if (stud)
4520
4680
  mul12To(instM, instPP[n].studM, stud[i] * 12, wm, n * 12);
4681
+ const real = !sm || (SA ? !!SA[n] : (wm[0] - SCi.x) ** 2 + (wm[2] - SCi.z) ** 2 < SR2);
4682
+ if (!real && !D)
4683
+ continue;
4684
+ if (D) {
4685
+ writeM4(DM, w2 * 16, wm);
4686
+ palette[col[i]].toArray(DC, w2 * 3);
4687
+ w2++;
4688
+ }
4689
+ if (!real)
4690
+ continue;
4691
+ if (stud)
4521
4692
  writeM4(MA, w * 16, wm);
4522
- } else
4693
+ else
4523
4694
  writeM4(MA, w * 16, instM, n * 12);
4524
4695
  palette[col[i]].toArray(CA, w * 3);
4525
4696
  w++;
4526
4697
  }
4698
+ if (D) {
4699
+ D.instanceMatrix.needsUpdate = true;
4700
+ D.instanceColor.needsUpdate = true;
4701
+ D.count = w2;
4702
+ D.visible = !!SM;
4703
+ }
4527
4704
  b.im.instanceMatrix.needsUpdate = true;
4528
4705
  b.im.instanceColor.needsUpdate = true;
4529
4706
  for (const o of b.objs) {
@@ -4533,20 +4710,21 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4533
4710
  o.geometry.instanceCount = w;
4534
4711
  }
4535
4712
  }
4536
- for (const b of stepBatched) {
4537
- const useHide = b.flag === "under" ? cullU : false;
4538
- const { own, hide, inst, bm } = b;
4539
- for (let i = 0;i < own.length; i++) {
4540
- const hid = !!hide && hide[i] <= S;
4541
- if (b.flag === "under") {
4542
- st.undersTotal++;
4543
- if (hid)
4544
- st.undersHidden++;
4713
+ if (!studsOnly)
4714
+ for (const b of stepBatched) {
4715
+ const useHide = b.flag === "under" ? cullU : false;
4716
+ const { own, hide, inst, bm } = b;
4717
+ for (let i = 0;i < own.length; i++) {
4718
+ const hid = !!hide && hide[i] <= S;
4719
+ if (b.flag === "under") {
4720
+ st.undersTotal++;
4721
+ if (hid)
4722
+ st.undersHidden++;
4723
+ }
4724
+ const on = own[i] <= S && !(useHide && hid) && !(O && !O[inst[i]]);
4725
+ bm.setVisibleAt(i, on);
4545
4726
  }
4546
- const on = own[i] <= S && !(useHide && hid) && !(O && !O[inst[i]]);
4547
- bm.setVisibleAt(i, on);
4548
4727
  }
4549
- }
4550
4728
  return st;
4551
4729
  };
4552
4730
  const setCull = (studs, under) => {
@@ -4566,7 +4744,14 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4566
4744
  only = mask;
4567
4745
  return applySteps();
4568
4746
  };
4569
- const box = new THREE.Box3;
4747
+ const setStudMask = (mask) => {
4748
+ if (!steps)
4749
+ return false;
4750
+ studMask = mask;
4751
+ applySteps(true);
4752
+ return true;
4753
+ };
4754
+ const box = new THREE2.Box3;
4570
4755
  for (const it of insts) {
4571
4756
  if (!H.parts[it.part])
4572
4757
  continue;
@@ -4588,11 +4773,11 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4588
4773
  for (const m of new Set([matF, matB, matD, ...matCache.values(), ...texMats.values()])) {
4589
4774
  const role = m.userData?.ldrSideRole;
4590
4775
  if (role === "D") {
4591
- m.side = THREE.DoubleSide;
4776
+ m.side = THREE2.DoubleSide;
4592
4777
  } else if (role === "B") {
4593
- m.side = front ? THREE.BackSide : THREE.DoubleSide;
4778
+ m.side = front ? THREE2.BackSide : THREE2.DoubleSide;
4594
4779
  } else {
4595
- m.side = front ? THREE.FrontSide : THREE.DoubleSide;
4780
+ m.side = front ? THREE2.FrontSide : THREE2.DoubleSide;
4596
4781
  }
4597
4782
  m.needsUpdate = true;
4598
4783
  }
@@ -4624,7 +4809,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4624
4809
  o.matrixAutoUpdate = false;
4625
4810
  o.matrixWorldNeedsUpdate = true;
4626
4811
  }
4627
- return { root, stats, setCull, setSide, setEdges, setCond, setLod, setStep, box, texturesReady, trimmed };
4812
+ return { root, stats, setCull, setSide, setEdges, setCond, setLod, setStep, setStudMask, box, texturesReady, trimmed };
4628
4813
  }
4629
4814
  function buildLdrScene(insts, pack, P, color, mark) {
4630
4815
  const g = buildLdrSceneGen(insts, pack, P, color, mark);
@@ -4702,18 +4887,18 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
4702
4887
  await new Promise((r) => setTimeout(r, 0));
4703
4888
  }
4704
4889
  }
4705
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/scene.ts
4706
- import * as THREE2 from "three";
4707
- var _box = new THREE2.Box3;
4708
- var _m4 = new THREE2.Matrix4;
4890
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/scene.ts
4891
+ import * as THREE3 from "three";
4892
+ var _box = new THREE3.Box3;
4893
+ var _m4 = new THREE3.Matrix4;
4709
4894
  function ghostMaterial(side, g) {
4710
- const m = new THREE2.MeshStandardMaterial({ color: 16777215, roughness: 0.85, metalness: 0, side, transparent: false, depthWrite: true, opacity: g.opacity });
4711
- m.blending = THREE2.CustomBlending;
4712
- m.blendSrc = THREE2.SrcAlphaFactor;
4713
- m.blendDst = THREE2.OneMinusSrcAlphaFactor;
4714
- m.blendSrcAlpha = THREE2.OneFactor;
4715
- m.blendDstAlpha = THREE2.OneMinusSrcAlphaFactor;
4716
- const tint = new THREE2.Color(g.color);
4895
+ const m = new THREE3.MeshStandardMaterial({ color: 16777215, roughness: 0.85, metalness: 0, side, transparent: false, depthWrite: true, opacity: g.opacity, polygonOffset: true, polygonOffsetFactor: 1, polygonOffsetUnits: 1 });
4896
+ m.blending = THREE3.CustomBlending;
4897
+ m.blendSrc = THREE3.SrcAlphaFactor;
4898
+ m.blendDst = THREE3.OneMinusSrcAlphaFactor;
4899
+ m.blendSrcAlpha = THREE3.OneFactor;
4900
+ m.blendDstAlpha = THREE3.OneMinusSrcAlphaFactor;
4901
+ const tint = new THREE3.Color(g.color);
4717
4902
  const u = { ldrGhostTint: { value: tint }, ldrGhostMix: { value: g.whiten } };
4718
4903
  m.onBeforeCompile = (sh) => {
4719
4904
  Object.assign(sh.uniforms, u);
@@ -4727,13 +4912,13 @@ function ghostMaterial(side, g) {
4727
4912
  }
4728
4913
  function colorFn(src, pack, fallback) {
4729
4914
  const table = new Map;
4730
- const put = (k, v) => table.set(String(k), new THREE2.Color(typeof v === "string" ? v : v.hex));
4915
+ const put = (k, v) => table.set(String(k), new THREE3.Color(typeof v === "string" ? v : v.hex));
4731
4916
  if (typeof src === "function") {
4732
4917
  return (c) => {
4733
4918
  let col = table.get(c);
4734
4919
  if (!col) {
4735
4920
  const v = src(+c);
4736
- col = v === undefined ? direct(c) ?? fallback : new THREE2.Color(v);
4921
+ col = v === undefined ? direct(c) ?? fallback : new THREE3.Color(v);
4737
4922
  table.set(c, col);
4738
4923
  }
4739
4924
  return col;
@@ -4751,14 +4936,14 @@ function colorFn(src, pack, fallback) {
4751
4936
  var direct = (c) => {
4752
4937
  const n = +c;
4753
4938
  if (n > 16777215 && n >>> 24 === 2)
4754
- return new THREE2.Color(n & 16777215);
4939
+ return new THREE3.Color(n & 16777215);
4755
4940
  const b = blendedColourHex(n);
4756
- return b ? new THREE2.Color(b) : null;
4941
+ return b ? new THREE3.Color(b) : null;
4757
4942
  };
4758
4943
  function withLocalColours(base, local) {
4759
4944
  if (!local.size)
4760
4945
  return base;
4761
- const own = new Map([...local].map(([k, v]) => [k, new THREE2.Color(v.hex)]));
4946
+ const own = new Map([...local].map(([k, v]) => [k, new THREE3.Color(v.hex)]));
4762
4947
  return (c) => own.get(c) ?? base(c);
4763
4948
  }
4764
4949
  var plasticCache = new WeakMap;
@@ -4770,7 +4955,7 @@ function toPlastic(old) {
4770
4955
  return old;
4771
4956
  let m = plasticCache.get(old);
4772
4957
  if (!m) {
4773
- const p = new THREE2.MeshPhysicalMaterial({
4958
+ const p = new THREE3.MeshPhysicalMaterial({
4774
4959
  vertexColors: true,
4775
4960
  roughness: 0.3,
4776
4961
  clearcoat: 0.3,
@@ -4781,8 +4966,11 @@ function toPlastic(old) {
4781
4966
  opacity: old.opacity,
4782
4967
  depthWrite: old.depthWrite,
4783
4968
  metalness: old.metalness,
4784
- emissive: old.emissive?.clone?.() ?? new THREE2.Color(0),
4785
- emissiveIntensity: old.emissiveIntensity ?? 0
4969
+ emissive: old.emissive?.clone?.() ?? new THREE3.Color(0),
4970
+ emissiveIntensity: old.emissiveIntensity ?? 0,
4971
+ polygonOffset: old.polygonOffset,
4972
+ polygonOffsetFactor: old.polygonOffsetFactor,
4973
+ polygonOffsetUnits: old.polygonOffsetUnits
4786
4974
  });
4787
4975
  p.onBeforeCompile = old.onBeforeCompile;
4788
4976
  p.customProgramCacheKey = () => "Phys" + old.customProgramCacheKey() + old.side;
@@ -4802,14 +4990,24 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4802
4990
  const useTex = o.textures !== false;
4803
4991
  const { all, stepOf, nSteps, localColours } = sceneInstances(instances, pack.header, useTex);
4804
4992
  const uniq = { length: nSteps };
4805
- const color = withLocalColours(colorFn(o.colors, pack, new THREE2.Color(o.fallbackColor ?? 10528169)), localColours);
4993
+ const color = withLocalColours(colorFn(o.colors, pack, new THREE3.Color(o.fallbackColor ?? 10528169)), localColours);
4806
4994
  const stepViews = new Array(uniq.length).fill(null);
4807
4995
  instances.forEach((i, k) => {
4808
4996
  if (i.view)
4809
4997
  stepViews[stepOf[k]] = i.view;
4810
4998
  });
4811
- const missing = [...new Set(all.filter((i) => !pack.header.parts[i.part]).map((i) => i.part))];
4812
- const object = new THREE2.Group;
4999
+ const parts = pack.header.parts;
5000
+ const miss = new Set;
5001
+ let drawnAll = 0;
5002
+ for (let k = 0;k < all.length; k++) {
5003
+ const p = all[k].part;
5004
+ if (parts[p])
5005
+ drawnAll++;
5006
+ else
5007
+ miss.add(p);
5008
+ }
5009
+ const missing = [...miss];
5010
+ const object = new THREE3.Group;
4813
5011
  object.name = "ldr";
4814
5012
  if (!o.ldrawSpace)
4815
5013
  object.rotation.x = Math.PI;
@@ -4828,7 +5026,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4828
5026
  x.geometry?.dispose?.();
4829
5027
  if (x.material)
4830
5028
  mats.add(x.material);
4831
- if (x.dispose && x.isInstancedMesh)
5029
+ if (x.dispose && (x.isInstancedMesh || x.isBatchedMesh))
4832
5030
  x.dispose();
4833
5031
  });
4834
5032
  for (const m of [...mats, ...pairs.values()]) {
@@ -4839,16 +5037,17 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4839
5037
  cur = null;
4840
5038
  };
4841
5039
  let ghostOn = false, ghost = null, ghostBuild = null, ghostGen = 0;
4842
- let shownStep = null, shownMask = null;
5040
+ let studMaskShown = null;
5041
+ let shownStep = null, shownMask = null, shownGhost = null;
4843
5042
  const ghostOpts = { opacity: 0.2, color: 16777215, whiten: 0.75 };
4844
5043
  const ghostMats = new Map;
4845
5044
  const syncGhost = () => {
4846
5045
  if (!ghost)
4847
5046
  return;
4848
- const show = ghostOn && shownStep != null && shownStep < uniq.length - 1;
5047
+ const show = ghostOn && shownStep != null && shownGhost != null && shownGhost < uniq.length - 1;
4849
5048
  ghost.root.visible = show;
4850
5049
  if (show)
4851
- ghost.setStep(uniq.length - 2 - shownStep, shownMask);
5050
+ ghost.setStep(uniq.length - 2 - shownGhost, shownMask);
4852
5051
  };
4853
5052
  const disposeGhost = () => {
4854
5053
  ghostGen++;
@@ -4873,7 +5072,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4873
5072
  const rev = new Int32Array(stepOf.length);
4874
5073
  for (let k = 0;k < rev.length; k++)
4875
5074
  rev[k] = n - 1 - stepOf[k];
4876
- const so = { ...sceneOpts(), edges: false, cond: false, tex: false, steps: rev, cull: undefined };
5075
+ const so = { ...sceneOpts(), studDecal: undefined, edges: false, cond: false, tex: false, steps: rev, cull: undefined };
4877
5076
  so.cull = cullCore(all, pack.header, rev);
4878
5077
  const g = await buildLdrSceneAsync(all, pack, so, color, () => {}, { postPaintSliceMs: 12 });
4879
5078
  if (my !== ghostGen) {
@@ -4889,9 +5088,9 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4889
5088
  return;
4890
5089
  if (x.material)
4891
5090
  old.add(x.material);
4892
- let m = ghostMats.get(x.material?.side ?? THREE2.FrontSide);
5091
+ let m = ghostMats.get(x.material?.side ?? THREE3.FrontSide);
4893
5092
  if (!m)
4894
- ghostMats.set(x.material?.side ?? THREE2.FrontSide, m = ghostMaterial(x.material?.side ?? THREE2.FrontSide, ghostOpts));
5093
+ ghostMats.set(x.material?.side ?? THREE3.FrontSide, m = ghostMaterial(x.material?.side ?? THREE3.FrontSide, ghostOpts));
4895
5094
  x.material = m;
4896
5095
  x.castShadow = x.receiveShadow = false;
4897
5096
  x.renderOrder = 1;
@@ -4908,8 +5107,28 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4908
5107
  syncGhost();
4909
5108
  })();
4910
5109
  const multiStep = uniq.length > 1;
4911
- const drawnAt = (step, mask) => all.filter((i, k) => (step == null || stepOf[k] <= step) && (!mask || mask[k]) && pack.header.parts[i.part]).length;
4912
- const sceneOpts = () => ({ localColours: localColours.size ? localColours : undefined, cullStuds: cs, cullUnder: cu, edges: o.edges, side, cond: o.conditionalLines, condStuds: o.conditionalStudLines !== false, tex: o.textures !== false, lod: o.lod !== false, lodPx: o.lodPx, lodEdgePx: o.lodEdgePx, lodEdgeMinPx: o.lodEdgeMinPx, lodEdgeCap: o.lodEdgeCap, lodUnder: o.lodUnder, steps: multiStep ? stepOf : undefined, cull: o.precomputedCull });
5110
+ const drawnAt = (step, mask) => {
5111
+ if (step == null && !mask)
5112
+ return drawnAll;
5113
+ let n = 0;
5114
+ for (let k = 0;k < all.length; k++)
5115
+ if ((step == null || stepOf[k] <= step) && (!mask || mask[k]) && parts[all[k].part])
5116
+ n++;
5117
+ return n;
5118
+ };
5119
+ let stepMode = multiStep && (o.step != null || !!o.eagerSteps);
5120
+ let flatCull = o.precomputedCull, stepCull = o.precomputedCull?.studHideStep ? o.precomputedCull : undefined;
5121
+ const withCull = (so) => {
5122
+ if (!so.cull) {
5123
+ so.cull = cullCore(all, pack.header, so.steps);
5124
+ if (so.steps)
5125
+ stepCull = so.cull;
5126
+ else
5127
+ flatCull = so.cull;
5128
+ }
5129
+ return so;
5130
+ };
5131
+ const sceneOpts = () => ({ localColours: localColours.size ? localColours : undefined, cullStuds: cs, cullUnder: cu, studGrid: o.studGrid, studDecal: o.studDecal, edges: o.edges, side, cond: o.conditionalLines, condStuds: o.conditionalStudLines !== false, tex: o.textures !== false, lod: o.lod !== false, lodPx: o.lodPx, lodEdgePx: o.lodEdgePx, lodEdgeMinPx: o.lodEdgeMinPx, lodEdgeCap: o.lodEdgeCap, lodUnder: o.lodUnder, steps: stepMode ? stepOf : undefined, cull: stepMode ? stepCull : flatCull });
4913
5132
  const applyBuilt = (built, t0) => {
4914
5133
  cur = built;
4915
5134
  pairs.clear();
@@ -4932,15 +5151,28 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4932
5151
  cur.setLod(false);
4933
5152
  if (cur.root.parent !== object)
4934
5153
  object.add(cur.root);
5154
+ if (studMaskShown && stepMode)
5155
+ cur.setStudMask(studMaskShown);
4935
5156
  Object.assign(stats, { drawn: drawnAt(null), studsTotal: cur.stats.studsTotal, studsHidden: cur.stats.studsHidden, undersTotal: cur.stats.undersTotal, undersHidden: cur.stats.undersHidden, condBatches: cur.stats.condBatches ?? 0, texBatches: cur.stats.texBatches ?? 0, textures: cur.stats.textures ?? 0, glossmaps: cur.stats.glossmaps ?? 0, clusters: cur.stats.clusters ?? 0, longestSliceMs: cur.stats.longestSliceMs, buildYields: cur.stats.buildYields, buildMs: performance.now() - t0 });
4936
5157
  api.texturesReady = cur.texturesReady;
4937
5158
  };
4938
- const setStep = (step, mask = null) => {
5159
+ const setStep = (step, mask = null, ghostAfter) => {
4939
5160
  if (!multiStep)
4940
5161
  return;
4941
5162
  const t0 = performance.now();
4942
5163
  shownStep = step;
4943
5164
  shownMask = mask;
5165
+ shownGhost = step == null ? null : Math.max(step, ghostAfter ?? step);
5166
+ if (!stepMode) {
5167
+ if (!mask && (step == null || step >= uniq.length - 1)) {
5168
+ Object.assign(stats, { drawn: drawnAt(null), buildMs: performance.now() - t0 });
5169
+ syncGhost();
5170
+ return;
5171
+ }
5172
+ stepMode = true;
5173
+ disposeCur();
5174
+ applyBuilt(buildLdrScene(all, pack, withCull(sceneOpts()), color, () => {}), t0);
5175
+ }
4944
5176
  Object.assign(stats, cur.setStep(step, mask), { drawn: drawnAt(step, mask), buildMs: performance.now() - t0 });
4945
5177
  if (ghostOn && step != null && !ghost)
4946
5178
  buildGhost();
@@ -4956,6 +5188,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4956
5188
  stepCount: uniq.length,
4957
5189
  stepViews,
4958
5190
  setStep,
5191
+ setStudMask: (m) => {
5192
+ studMaskShown = m;
5193
+ return stepMode ? cur.setStudMask(m) : false;
5194
+ },
4959
5195
  setEdges: (v) => {
4960
5196
  edges = v;
4961
5197
  cur.setEdges(v);
@@ -4970,7 +5206,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4970
5206
  if (!a && cur.trimmed.studs || !b && cur.trimmed.under) {
4971
5207
  disposeCur();
4972
5208
  const t0 = performance.now();
4973
- applyBuilt(buildLdrScene(all, pack, sceneOpts(), color, () => {}), t0);
5209
+ applyBuilt(buildLdrScene(all, pack, withCull(sceneOpts()), color, () => {}), t0);
4974
5210
  } else
4975
5211
  cur.setCull(a, b);
4976
5212
  ghost?.setCull(a, b);
@@ -5007,7 +5243,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
5007
5243
  p.needsUpdate = true;
5008
5244
  }
5009
5245
  },
5010
- getBox: (target = new THREE2.Box3) => {
5246
+ getBox: (target = new THREE3.Box3) => {
5011
5247
  object.updateMatrixWorld(true);
5012
5248
  target.makeEmpty();
5013
5249
  object.traverse((x) => {
@@ -5036,14 +5272,12 @@ function createLdrObjectInner(instances, pack, options, progressive) {
5036
5272
  };
5037
5273
  if (!progressive) {
5038
5274
  const t0 = performance.now();
5039
- applyBuilt(buildLdrScene(all, pack, sceneOpts(), color, () => {}), t0);
5275
+ applyBuilt(buildLdrScene(all, pack, withCull(sceneOpts()), color, () => {}), t0);
5040
5276
  return finish();
5041
5277
  }
5042
5278
  return (async () => {
5043
5279
  const t0 = performance.now();
5044
- const so = sceneOpts();
5045
- if (!so.cull)
5046
- so.cull = cullCore(all, pack.header, so.steps);
5280
+ const so = withCull(sceneOpts());
5047
5281
  const built = await buildLdrSceneAsync(all, pack, so, color, () => {}, {
5048
5282
  sliceMs: o.sliceMs,
5049
5283
  postPaintSliceMs: o.postPaintSliceMs,
@@ -5057,10 +5291,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
5057
5291
  return finish();
5058
5292
  })();
5059
5293
  }
5060
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/parts-cdn.ts
5294
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/parts-cdn.ts
5061
5295
  import { decompress as decompress2 } from "fzstd";
5062
5296
 
5063
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/embedded.ts
5297
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/embedded.ts
5064
5298
  function splitFiles(text, fallback) {
5065
5299
  const files = new Map;
5066
5300
  let cur = null, saw = false, skip = false;
@@ -5138,8 +5372,8 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
5138
5372
  return out;
5139
5373
  }
5140
5374
 
5141
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/parts-cdn.ts
5142
- var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
5375
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/parts-cdn.ts
5376
+ var DEFAULT_PARTS_CDN = "https://ldr-parts-cdn.baconbrix.workers.dev/v1/";
5143
5377
  var indexCache = new Map;
5144
5378
  var shardCache = new Map;
5145
5379
  function loadPartsIndex(cdn = DEFAULT_PARTS_CDN, f = fetch) {
@@ -5399,10 +5633,10 @@ async function prepareModel(source, o = {}) {
5399
5633
  return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
5400
5634
  }
5401
5635
 
5402
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/load-worker.gen.ts
5403
- var load_worker_gen_default = 'var nn=ArrayBuffer,W=Uint8Array,ze=Uint16Array,rn=Int16Array;var $e=Int32Array,Ye=function(e,t,n){if(W.prototype.slice)return W.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 W(n-t);return r.set(e.subarray(t,n)),r},Re=function(e,t,n,r){if(W.prototype.fill)return W.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},sn=function(e,t,n,r){if(W.prototype.copyWithin)return W.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 on=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],Z=function(e,t,n){var r=Error(t||on[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,Z);if(!n)throw r;return r},bt=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},an=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},ln=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)Z(0);var a=6-s,u=i==3?4:i,l=bt(e,a,u);a+=u;var f=c?1<<c:s,h=bt(e,a,f)+(c==1&&256),g=h;if(!s){var p=1<<10+(e[5]>>3);g=p+(p>>3)*(e[5]&7)}if(g>2145386496)Z(1);var m=new W((t==1?h||g:t?0:g)+12);return m[0]=1,m[4]=4,m[8]=8,{b:a+f,y:0,l:0,d:l,w:t&&t!=1?t:m.subarray(12),e:g,o:new $e(m.buffer,0,3),u:h,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return an(e,4)+8;Z(0)},Se=function(e){var t=0;for(;1<<t<=e;++t);return t-1},Be=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)Z(3);var o=1<<s,i=o,c=-1,a=-1,u=-1,l=o,f=new nn(512+(o<<2)),h=new rn(f,0,256),g=new ze(f,0,256),p=new ze(f,512,o),m=512+(o<<1),A=new W(f,m,o),x=new W(f,m+o);while(c<255&&i>0){var d=Se(i+1),w=r>>3,b=(1<<d+1)-1,M=(e[w]|e[w+1]<<8|e[w+2]<<16)>>(r&7)&b,k=(1<<d)-1,N=b-i-1,P=M&k;if(P<N)r+=d,M=P;else if(r+=d+1,M>k)M-=N;if(h[++c]=--M,M==-1)i+=M,A[--l]=c;else i-=M;if(!M)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,c+=a}while(a==3)}if(c>255||i)Z(0);var y=0,B=(o>>1)+(o>>3)+3,C=o-1;for(var I=0;I<=c;++I){var R=h[I];if(R<1){g[I]=-R;continue}for(u=0;u<R;++u){A[y]=I;do y=y+B&C;while(y>=l)}}if(y)Z(0);for(u=0;u<o;++u){var S=g[A[u]]++,V=x[u]=s-Se(S);p[u]=(S<<V)-o}return[r+7>>3,{b:s,s:A,n:x,t:p}]},cn=function(e,t){var n=0,r=-1,s=new W(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),a=new ze(s.buffer,268);if(o<128){var u=Be(e,t+1,6),l=u[0],f=u[1];t+=o;var h=l<<3,g=e[t];if(!g)Z(0);var p=0,m=0,A=f.b,x=A,d=(++t<<3)-8+Se(g);for(;;){if(d-=A,d<h)break;var w=d>>3;if(p+=(e[w]|e[w+1]<<8)>>(d&7)&(1<<A)-1,i[++r]=f.s[p],d-=x,d<h)break;w=d>>3,m+=(e[w]|e[w+1]<<8)>>(d&7)&(1<<x)-1,i[++r]=f.s[m],A=f.n[p],p=f.t[p],x=f.n[m],m=f.t[m]}if(++r>255)Z(0)}else{r=o-127;for(;n<r;n+=2){var b=e[++t];i[n]=b>>4,i[n+1]=b&15}++t}var M=0;for(n=0;n<r;++n){var k=i[n];if(k>11)Z(0);M+=k&&1<<k-1}var N=Se(M)+1,P=1<<N,D=P-M;if(D&D-1)Z(0);i[r++]=Se(D)+1;for(n=0;n<r;++n){var k=i[n];++c[i[n]=k&&N+1-k]}var y=new W(P<<1),B=y.subarray(0,P),C=y.subarray(P);a[N]=0;for(n=N;n>0;--n){var I=a[n];Re(C,n,I,a[n-1]=I+c[n]*(1<<N-n))}if(a[0]!=P)Z(0);for(n=0;n<r;++n){var R=i[n];if(R){var S=a[R];Re(B,n,S,a[R]=S+(1<<N-R))}}return[t,{n:C,b:N,s:B}]},un=Be(new W([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],fn=Be(new W([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],pn=Be(new W([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],yt=function(e,t){var n=e.length,r=new $e(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Je=new W(new $e([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),mn=yt(Je,0),Qe=new W(new $e([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),hn=yt(Qe,3),Fe=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)Z(0);var a=0,u=n.b,l=(r<<3)-8+Se(o)-u,f=-1;for(;l>c&&f<s;){var h=l>>3,g=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(l&7);a=(a<<u|g)&i,t[++f]=n.s[a],l-=u=n.n[a]}if(l!=c||f+1!=s)Z(0)},gn=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;Fe(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),Fe(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),Fe(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),Fe(e.subarray(r),t.subarray(c),n)},dn=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,a=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return Re(n,e[s],t.y,t.y+=c),n;return Re(new W(c),e[s])}if(a>e.length)return;if(i==0){if(t.b=a,n)return n.set(e.subarray(s,a),t.y),t.y+=c,n;return Ye(e,s,a)}if(i==2){var u=e[s],l=u&3,f=u>>2&3,h=u>>4,g=0,p=0;if(l<2)if(f&1)h|=e[++s]<<4|(f&2&&e[++s]<<12);else h=u>>3;else if(p=f,f<2)h|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(f==2)h|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var m=n?n.subarray(t.y,t.y+t.m):new W(t.m),A=m.length-h;if(l==0)m.set(e.subarray(s,s+=h),A);else if(l==1)Re(m,e[s++],A);else{var x=t.h;if(l==2){var d=cn(e,s);g+=s-(s=d[0]),t.h=x=d[1]}else if(!x)Z(0);(p?gn:Fe)(e.subarray(s,s+=g),m.subarray(A),x)}var w=e[s++];if(w){if(w==255)w=(e[s++]|e[s++]<<8)+32512;else if(w>127)w=w-128<<8|e[s++];var b=e[s++];if(b&3)Z(0);var M=[fn,pn,un];for(var k=2;k>-1;--k){var N=b>>(k<<1)+2&3;if(N==1){var P=new W([0,0,e[s++]]);M[k]={s:P.subarray(2,3),n:P.subarray(0,1),t:new ze(P.buffer,0,1),b:0}}else if(N==2)r=Be(e,s,9-(k&1)),s=r[0],M[k]=r[1];else if(N==3){if(!t.t)Z(0);M[k]=t.t[k]}}var D=t.t=M,y=D[0],B=D[1],C=D[2],I=e[a-1];if(!I)Z(0);var R=(a<<3)-8+Se(I)-C.b,S=R>>3,V=0,he=(e[S]|e[S+1]<<8)>>(R&7)&(1<<C.b)-1;S=(R-=B.b)>>3;var ce=(e[S]|e[S+1]<<8)>>(R&7)&(1<<B.b)-1;S=(R-=y.b)>>3;var Me=(e[S]|e[S+1]<<8)>>(R&7)&(1<<y.b)-1;for(++w;--w;){var re=C.s[he],Te=C.n[he],be=y.s[Me],ve=y.n[Me],fe=B.s[ce],ke=B.n[ce];S=(R-=fe)>>3;var O=1<<fe,T=O+((e[S]|e[S+1]<<8|e[S+2]<<16|e[S+3]<<24)>>>(R&7)&O-1);S=(R-=Qe[be])>>3;var _=hn[be]+((e[S]|e[S+1]<<8|e[S+2]<<16)>>(R&7)&(1<<Qe[be])-1);S=(R-=Je[re])>>3;var X=mn[re]+((e[S]|e[S+1]<<8|e[S+2]<<16)>>(R&7)&(1<<Je[re])-1);if(S=(R-=Te)>>3,he=C.t[he]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<Te)-1),S=(R-=ve)>>3,Me=y.t[Me]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<ve)-1),S=(R-=ke)>>3,ce=B.t[ce]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<ke)-1),T>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=T-=3;else{var q=T-(X!=0);if(q){if(T=q==3?t.o[0]-1:t.o[q],q>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=T}else T=t.o[0]}for(var k=0;k<X;++k)m[V+k]=m[A+k];V+=X,A+=X;var ee=V-T;if(ee<0){var J=-ee,L=t.e+ee;if(J>_)J=_;for(var k=0;k<J;++k)m[V+k]=t.w[L+k];V+=J,_-=J,ee=0}for(var k=0;k<_;++k)m[V+k]=m[ee+k];V+=_}if(V!=A)while(A<m.length)m[V++]=m[A++];else V=m.length;if(n)t.y+=V;else m=Ye(m,0,V)}else if(n){if(t.y+=h,A)for(var k=0;k<h;++k)m[k]=m[A+k]}else if(A)m=Ye(m,A);return t.b=a,m}Z(2)},bn=function(e,t){if(e.length==1)return e[0];var n=new W(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 je(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=ln(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=dn(e,i,t);if(!c)Z(5);if(t)i.e=i.y;else n.push(c),o+=c.length,sn(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 bn(n,o)}async function yn(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(je(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 xt(e){return new TextDecoder().decode(await yn(e))}var wt=(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 Y=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),et=/^[A-Za-z][A-Za-z0-9_]*$/,qe=new Map;function tt(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(!qe.has(r))qe.set(r,t);return r}function nt(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&et.test(e))return tt(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var At=/^~?\\s*moved\\s+to\\s+(.+)$/i,xn=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),wn=new Set(["FILE","NOFILE","!DATA"]),Et=1000000000000000,Pt=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),An=new Set(["model","submodel","configuration"]),Mn=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function Mt(e){let t=Mn.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Pt.has(n)||An.has(n)?n:void 0}function vn(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 Cn(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((f)=>Number.isFinite(f)&&Math.abs(f)<=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 f=0;f<s;f++)c=c.replace(/^\\S+\\s*/,"");let a=vn(c);if(!a.length)return null;let u={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)u.a=i[9];if(s===11)u.b=i[10];let l=a.findIndex((f,h)=>h>0&&f.toUpperCase()==="GLOSSMAP");if(l>0&&a[l+1])u.glossmap=a[l+1];if(t)u.next=!0;return u}var kn=(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,t){let n=e.length,r=1,s=(p)=>p===32||p===9,o=()=>{while(r<n&&s(e.charCodeAt(r)))r++;let p=r,m=e.charCodeAt(r),A=m===45;if(A)m=e.charCodeAt(++r);let x=0,d=0;while(m>=48&&m<=57)x=x*10+(m-48),d++,m=e.charCodeAt(++r);if(d>0&&d<=15&&(r>=n||s(m)))return A?-x:x;while(r<n&&!s(e.charCodeAt(r)))r++;return p<r?+e.slice(p,r):NaN};while(r<n&&s(e.charCodeAt(r)))r++;let i=r;if(r>=n)return null;let c=e.charCodeAt(r),a=c===45,u=0,l=0;if(a)c=e.charCodeAt(++r);while(c>=48&&c<=57)u=u*10+(c-48),l++,c=e.charCodeAt(++r);if(l>0&&l<=15&&(r>=n||s(c))){if(a)u=-u}else{while(r<n&&!s(e.charCodeAt(r)))r++;u=nt(e.slice(i,r))}let f=Array(12);for(let p=0;p<12;p++){let m=o();if(!Number.isFinite(m))return null;f[p]=m}while(r<n&&s(e.charCodeAt(r)))r++;if(r>=n)return null;let h=e.slice(r),g=t.get(h);if(g===void 0)g=Y(/[ \\t]{2,}|\\t/.test(h)?h.split(/\\s+/).join(" "):h),t.set(h,g);if(!Number.isFinite(u))return null;return{t:1,color:u,m:f,file:g}}var Ln=[0,12,6,9,12,12];function vt(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=nt(e[1]),r=Ln[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=Y(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 It(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,a=null,u=[],l=null,f=()=>{if(!a)return;let w=kn(a.chunks.join("")),b=w[0]===137&&w[1]===80&&w[2]===78&&w[3]===71;(c??=new Map).set(Y(a.name),{name:a.name,bytes:w,...b?{mime:"image/png"}:{}}),a=null},h=new Map,g=!0,p=(w)=>{if(f(),o={name:Y(w),cmds:[]},s.set(o.name,o),!i)i=o.name;u=[],l=null,g=!0},m=!1,A=!1,x=()=>{if(A)return;A=!0,s.clear(),o=null,i=""},d=(w,b)=>{if(l){w.tex=l,l=null;return}let M=u[u.length-1];if(!M)return;if(M.fallback){if(!b)w.fallback=!0}else w.tex=M.map};for(let w of e.split(`\n`)){let b=w.trim();if(!b)continue;if(r&&b.charCodeAt(0)>=50&&b.charCodeAt(0)<=53&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)){if(a||m)continue;if(!o)p(t);let P=b.slice(2).trimStart(),D=P.search(/\\s/),y={t:b.charCodeAt(0)-48,color:nt(D<0?P:P.slice(0,D)),p:[],src:b};d(y,!1),o.cmds.push(y),g=!1;continue}if(b.charCodeAt(0)===48&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)){let P=2;while(b.charCodeAt(P)===32||b.charCodeAt(P)===9)P++;let D=P;while(D<b.length&&b.charCodeAt(D)!==32&&b.charCodeAt(D)!==9)D++;let y=b.slice(P,D),B=/[^\\x21-\\x7e]/.test(y)?b.slice(P).trim().split(/\\s+/)[0]:y;if(!xn.has(B)&&!(B.length>=4&&B.length<=6&&wn.has(B.toUpperCase()))){if(m||a)continue;if(!o)p(t);let C=b.slice(P),I={t:0,text:C};if(y.charCodeAt(0)===33)I.meta=y;if(l=null,g&&!o.org){let S=Mt(C);if(S)o.org=S}let R=C.match(At);if(R&&!o.movedTo){let S=R[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(S))S+=".dat";o.movedTo=Y(S)}o.cmds.push(I);continue}}if(b.charCodeAt(0)===49&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)&&!a&&!m){let P=Tn(b,h);if(P){if(!o)p(t);d(P,!1),o.cmds.push(P),g=!1;continue}}let M=b.split(/\\s+/);if(+M[0]===0){let P=b.slice(1).trim(),D=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(D==="FILE"){let C=P.slice(5).trimStart().split("\\r")[0].trim();if(C){x(),m=!1,p(C);continue}}if(D==="NOFILE"){f(),o=null,m=!0;continue}if(D==="!DATA"){x(),f(),o=null,m=!1,a={name:P.slice(5).trim(),chunks:[]};continue}if(m)continue;if(a){if(M[1]==="!:")a.chunks.push(M.slice(2).join(""));continue}if(!o)p(t);let y={t:0,text:P};if(M[1]==="STEP")y.step=!0,u=[],l=null;else if(M[1]==="BFC")y.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(y.meta="ROTSTEP",y.step=!0,u=[],l=null,(M[2]??"").toUpperCase()==="END")y.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(M[5]??"REL").toUpperCase(),I=(R)=>{let S=Number(R);return Number.isFinite(S)?S:0};y.rotstep={x:I(M[2]),y:I(M[3]),z:I(M[4]),mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(M[1]==="BUFEXCHG"){y.meta="BUFEXCHG";let C=(M[2]??"").toUpperCase();y.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))y.meta=M[1];if(g&&!o.org){let C=Mt(P);if(C)o.org=C}if(M[1]==="!TEXMAP"){let C=(M[2]??"").toUpperCase();if(l=null,C==="START"||C==="NEXT"){let I=Cn(P.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(y.texmap={op:C,...I?{map:I}:{}},I)if((o.texmaps??=[]).push(I),C==="START")u.push({map:I,fallback:!1});else l=I}else if(C==="FALLBACK"){y.texmap={op:C};let I=u[u.length-1];if(I)I.fallback=!0}else if(C==="END")y.texmap={op:C},u.pop()}else if(M[1]==="!:"){l=null;let C=vt(M.slice(2));if(C)d(C,!0),y.geom=C}else l=null;let B=P.match(At);if(B&&!o.movedTo){let C=B[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=Y(C)}o.cmds.push(y);continue}if(a||m)continue;if(!o)p(t);let N=vt(M);if(!N){if(/^[2-5][ \\t]/.test(b))g=!1;continue}d(N,!1),o.cmds.push(N),g=!1}return f(),c?{main:i,files:s,data:c}:{main:i,files:s}}var rr=Math.PI/180;function Ft(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 Rt(e,t){let[n,r,s,o,i,c,a,u,l,f,h,g]=e,[p,m,A,x,d,w,b,M,k,N,P,D]=t;return[o*p+i*m+c*A+n,a*p+u*m+l*A+r,f*p+h*m+g*A+s,o*x+i*b+c*N,o*d+i*M+c*P,o*w+i*k+c*D,a*x+u*b+l*N,a*d+u*M+l*P,a*w+u*k+l*D,f*x+h*b+g*N,f*d+h*M+g*P,f*w+h*k+g*D]}var rt=[0,0,0,1,0,0,0,1,0,0,0,1];var Ct=new WeakMap,Sn=/^(s|8|48)\\//;function st(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=Ct.get(n);if(r)return r;if(n.org)r=Pt.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&&Sn.test(s.file))?"part":"model";return Ct.set(n,r),r}var kt=new WeakMap;function Bt(e){let t=kt.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 kt.set(e,t),t}var Tt=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?qe.get(e)??String(e):String(e),En=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Tt(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Tt(e.color)} ${e.p.join(" ")}`,ot=(e,t)=>`${Y(e)}#${t}`;function Pn(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:ot(e.name,t),cmds:n}}function Dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Pn(e,t).cmds.map(En)].join(`\n`)+`\n`}function it(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 Ut(e){let[t,n,r,s,o,i,c,a,u,l,f,h]=e,g=a*h-u*f,p=-(c*h-u*l),m=c*f-a*l,A=s*g+o*p+i*m;if(!Number.isFinite(A)||Math.abs(A)<0.000000000001)return null;let x=1/A,d=[g*x,-(o*h-i*f)*x,(o*u-i*a)*x,p*x,(s*h-i*l)*x,-(s*u-i*c)*x,m*x,-(s*f-o*l)*x,(s*a-o*c)*x];return[-(d[0]*t+d[1]*n+d[2]*r),-(d[3]*t+d[4]*n+d[5]*r),-(d[6]*t+d[7]*n+d[8]*r),...d]}var In=(e)=>String(+e.toFixed(6)||0),Lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function Nt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(In).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 ${Y(e)}\n0 !TEXMAP END\n`;return{name:`${Y(e)}#tex-${it(r)}`,source:r}}var Fn=(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),c=Math.cos(t*r),a=Math.sin(n*r),u=Math.cos(n*r);return[c*u,-c*a,i,o*a+s*i*u,o*u-s*i*a,-s*c,s*a-o*i*u,s*u+o*i*a,o*c]}var St=new WeakMap;function Ot(e){let t=St.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:Fn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),St.set(e,n),n}class at 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 Bn=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=Et))return!1;return!0},zt=999999,Vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",_t=new WeakMap,$t=new WeakMap;function Dn(e,t){let n=$t.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=_t.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},$t.set(t,n);let r=n.parts.get(e);if(!r){let s=Y(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-${it(o)}`,source:o},n.parts.set(e,r)}return r}function Un(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,a=0,u=new Set,l=t.maxInstances??2000000,f=0,h=(p,m)=>{let A=p.name+"#"+m,x=c.get(A);if(!x){let d;x=Object.assign(()=>d??=Dt(p,m),{file:p,step:m}),c.set(A,x)}return x},g=(p,m,A,x,d,w,b,M,k=null,N=[],P=[],D=void 0,y=null)=>{let B=p.files.get(m);if(!B||b>r||u.has(B))return;if(++f>l)throw new at("model",l);u.add(B);let C=y,I=0,R=b>0?++a:0,S=i&&R?[...N,R]:N,V=i&&R?[...P,A]:P,he=i&&!k?new Map:null,ce=-1,Me=0,re=(O,T,_,X,q,ee,J)=>{if(ce!==I)ce=I,Me=0;let L=he?.get(I+"|"+T);if(L)return L.n++,g(O,O===p?T:O.main,_,X,d+"/"+T,[...q,zt],b+1,ee,[...q,zt],S,V,J,C);let F=[...q,Me++],v=n.length;g(O,O===p?T:O.main,_,X,d+"/"+T,F,b+1,ee,k,S,V,J,C),he?.set(I+"|"+T,{n:1,from:v,to:n.length})},Te=Ot(B),be=s?Bt(B):[],ve=0,fe=(O,T,_,X,q,ee,J,L,F)=>{if(k)X=k;if(++f>l)throw new at("model",l);let v={part:O,color:T,m:_,step:X[0],steps:X,localStep:q,path:d};if(L)v.colour=L;if(R){if(v.sub=R,i)v.subPath=S,v.subMats=V}if(ee)v.embedded=!0;if(J){let E=Nt(O,J);v.texPart=E.name,v.texSource=E.source}else if(F){let E=Dn(O,F);v.colPart=E.name,v.colSource=E.source}let U=Te[q];if(U)v.view=U;return n.push(v),v},ke=(O)=>{while(ve<be.length&&be[ve]<=O){let T=be[ve++];fe(ot(B.name,T),x,A,[...w,T],T,!1,null,D,y).source=h(B,T)}};for(let O of B.cmds){if(O.t===0&&O.step){I++;continue}let T=O;if(T.t>=2||T.t===0&&T.geom&&T.geom.t>=2){ke(I);continue}if(T.t===0){if(T.meta==="!COLOUR"){let U=On(T.text);if(U&&U.code!==16&&U.code!==24)_t.set(U,T.text),(C=new Map(C??[])).set(U.code,U);continue}if(o&&T.geom?.t===1)T=T.geom;else continue}if(T.t!==1)continue;if(o&&T.fallback)continue;let _=Rt(A,T.m);if(!Bn(_))continue;let X=T.color===16?x:T.color,q=T.color===16?D:C?.get(T.color),ee=[...w,I],J=o?T.tex??M:null,L=J?Ut(T.m):null,F=J&&L?Ft(J,L):null;if(p.files.has(T.file)){if(st(p,T.file)==="model"){re(p,T.file,_,X,ee,F,q);continue}fe(T.file,X,_,ee,I,!0,F,q,C);continue}let v=t.resolveModel?.(T.file);if(v){re(v,T.file,_,X,ee,F,q);continue}fe(T.file,X,_,ee,I,!1,F,q,C)}if(ke(1/0),u.delete(B),he){for(let O of he.values())if(O.n>1)for(let T=O.from;T<O.to;T++)n[T].mult??=O.n}};if(st(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...rt],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,rt,16,e.main,[],0,null),n}function Gt(e,t="main.ldr",n){return Un(It(e,t,{geometryText:!0}),n)}var Nn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function lt(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 jt(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=lt(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 On(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,a=0,u={type:"default"},l=1;while(l<n.length){let f=n[l].toUpperCase(),h=n[l+1];if(f==="CODE")s=h!==void 0&&et.test(h)?tt(h):h!==void 0&&/^\\d+$/.test(h)?+h:NaN,l+=2;else if(f==="VALUE"){let g=lt(h);if(g)o=g;l+=2}else if(f==="EDGE")i=lt(h)??h,l+=2;else if(f==="ALPHA")c=+h,l+=2;else if(f==="LUMINANCE")a=+h,l+=2;else if(f==="CHROME")u={type:"chrome"},l+=1;else if(f==="PEARLESCENT")u={type:"pearlescent"},l+=1;else if(f==="RUBBER")u={type:"rubber"},l+=1;else if(f==="MATTE_METALLIC")u={type:"matte_metallic"},l+=1;else if(f==="METAL")u={type:"metal"},l+=1;else if(f==="MATERIAL"){let g=(n[l+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:p,next:m}=jt(n,l+2);u={type:"glitter",material:p},l=m}else if(g==="SPECKLE"){let{grain:p,next:m}=jt(n,l+2);u={type:"speckle",material:p},l=m}else if(g==="FABRIC"){let p=(n[l+2]||"").toUpperCase(),m=["VELVET","CANVAS","STRING","FUR"].includes(p)?p.toLowerCase():void 0;u={type:"fabric",kind:m},l+=m?3:2}else l=n.length}else if(Nn.has(f))l+=1;else l+=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(a)?a:0,finish:u}}function zn(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 ct(e){let t=zn(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 $n(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(Y(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(Y(t),r)}let a=i.trim().replace(/\\s+/g," ");if(a)r.push(a)}return n}var jn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Vn(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 Wt(e,t,n="main.ldr"){let r=[...t],s=new Map;if(!r.length)return s;let o=$n(e,n);for(let i of r){let c=Y(i);if(!o.has(c)||s.has(c))continue;let a=new Set([c]),u=[c];while(u.length)for(let f of o.get(u.pop())){let h=jn(f);if(h&&o.has(h)&&!a.has(h))a.add(h),u.push(h)}let l=[c,...[...a].filter((f)=>f!==c).sort()].map((f)=>"0 FILE "+(f===c?"":f)+`\n`+o.get(f).join(`\n`)).join(`\n`);s.set(c,`emb/${Vn(l)}.dat`)}return s}var Xt=(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,Ht=new WeakMap,ut=null,ft="",pt=null;function mt(e,t){if(e===ut&&t===ft)return pt;let n=Ht.get(e);if(!n)Ht.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return ut=e,ft=t,pt=r,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=[],a=[];s.studs.forEach((g,p)=>{c.push(g[0]),a.push(g[1]);for(let m=0;m<12;m++)i[p*12+m]=g[2+m]});let u=null,l=0,f=0;if(s.mask){l=s.mask[0],f=s.mask[1];let g=s.mask[2];u=new Uint8Array(g.length);for(let p=0;p<g.length;p++)u[p]=g.charCodeAt(p)===49?1:0}let h=!!u;if(u){for(let g=0;g<u.length;g++)if(u[g]!==1){h=!1;break}}return n.set(t,r={nStuds:o,studM:i,kind:c,color:a,mask:u,nx:l,nz:f,full:h}),ut=e,ft=t,pt=r,r}var Pe=1073741824;class Ee{t;tag;mask;size=0;shift;constructor(e=1024,t=-1){let n=1024;while(n<e*2)n*=2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.shift=t}slot(e,t,n){let r=this.shift;if(r<0){let o=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return o^=o>>>15,o=Math.imul(o,739982445),o^=o>>>12,o&this.mask}let s=Math.imul(e>>r+2,2654435761)^Math.imul(t,2246822507)^Math.imul(n>>r+2,3266489909);return s^=s>>>15,s=Math.imul(s,739982445),s^=s>>>12,(s<<4|(e>>r&3)<<2|n>>r&3)&this.mask}static tagOf(e,t,n){return Math.imul(e^Math.imul(t,374761393)^Math.imul(n,668265261),2654435761)>>>24|1}get(e,t,n){let r=Ee.tagOf(e,t,n),s=this.tag,o=this.t,i=this.mask,c=this.slot(e,t,n);for(;;){let a=s[c];if(a===0)return-1;if(a===r){let u=c<<2;if(o[u]===e&&o[u+1]===t&&o[u+2]===n)return o[u+3]}c=c+1&i}}put(e,t,n,r){if((this.size+1)*2>this.tag.length)this.grow();let s=Ee.tagOf(e,t,n),o=this.tag,i=this.t,c=this.mask,a=this.slot(e,t,n);for(;;){let u=o[a],l=a<<2;if(u===0)return o[a]=s,i[l]=e,i[l+1]=t,i[l+2]=n,i[l+3]=r,this.size++,-1;if(u===s&&i[l]===e&&i[l+1]===t&&i[l+2]===n){let f=i[l+3];return i[l+3]=r,f}a=a+1&c}}grow(){let e=this.t,t=this.tag,n=t.length*2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.size=0;for(let r=0;r<t.length;r++)if(t[r]){let s=r<<2;this.put(e[s],e[s+1],e[s+2],e[s+3])}}}class Zt{grp=new Ee(64);gBits=[];gX0=[];gZ0=[];gNz=[];gNx=[];bits;rest;lk=NaN;lpx=NaN;lpz=NaN;lg=-1;group(e,t,n){if(e!==this.lk||t!==this.lpx||n!==this.lpz)this.lk=e,this.lpx=t,this.lpz=n,this.lg=this.grp.get(e,t,n);return this.lg}constructor(e,t,n,r){let s=[],o=[],i=[],c=[],a=[];for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=(h%20+20)%20,A=(p%20+20)%20,x=this.group(g,m,A);if(x<0)x=s.length,this.grp.put(g,m,A,x),this.lg=x,s.push(0),o.push(h),i.push(h),c.push(p),a.push(p);if(s[x]++,h<o[x])o[x]=h;else if(h>i[x])i[x]=h;if(p<c[x])c[x]=p;else if(p>a[x])a[x]=p}let u=0,l=0;for(let f=0;f<s.length;f++){let h=(i[f]-o[f])/20+1,g=(a[f]-c[f])/20+1,p=h*g;if(this.gX0.push(o[f]),this.gZ0.push(c[f]),this.gNx.push(h),this.gNz.push(g),p<=64*s[f]+1024&&u+p<2147483648)this.gBits.push(u),u+=p;else this.gBits.push(-1),l+=s[f]}this.bits=new Uint8Array(Math.ceil(u/8)),this.rest=new Ee(l);for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=this.group(g,(h%20+20)%20,(p%20+20)%20),A=this.gBits[m];if(A<0){this.rest.put(h,g,p,1);continue}let x=A+(h-this.gX0[m])/20*this.gNz[m]+(p-this.gZ0[m])/20;this.bits[x>>>3]|=1<<(x&7)}}has(e,t,n){let r=this.group(t,(e%20+20)%20,(n%20+20)%20);if(r<0)return!1;let s=this.gBits[r];if(s<0)return this.rest.get(e,t,n)>=0;let o=(e-this.gX0[r])/20,i=(n-this.gZ0[r])/20;if(o<0||i<0||o>=this.gNx[r]||i>=this.gNz[r])return!1;let c=s+o*this.gNz[r]+i;return(this.bits[c>>>3]&1<<(c&7))!==0}}var _n=(e,t,n,r)=>e===0&&r===0&&(t===1||t===-1)&&(n===1||n===-1)||t===0&&n===0&&(e===1||e===-1)&&(r===1||r===-1),Ie=(e,t,n)=>e>-Pe&&e<Pe&&t>-Pe&&t<Pe&&n>-Pe&&n<Pe,De=2147483647;function Gn(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){return Kt(e,t,n,-1)??Kt(e,t,n,Yt)}var Yt=0;function Kt(e,t,n,r){let o=new Map,i=(L)=>{let F=o.get(L);if(F===void 0)o.set(L,F=Gn(t,L));return F},c=e.length,a=0,u=0;for(let L=0,F="";L<c;L++){let v=e[L].part;if(v===F){a++;continue}let U=t.parts[v];if(U&&U.mask)a++,F=v}let l=new Float64Array(a),f=new Float64Array(a),h=new Float64Array(a),g=new Float64Array(a),p=new Int32Array(a),m=new Int32Array(a),A=new Float64Array(a),x=new Float64Array(a),d=[],w=new Int32Array(a),b=new Float64Array(a*9),M=new Uint8Array(a);if(r<0)r=a*4+64;let k=new Ee(e.length*2),N=new Int32Array(r),P=new Int32Array(r),D=0,y=0;for(let L=0;L<e.length;L++){let F=e[L],v=F.m,U=t.parts[F.part];if(!U||!U.mask||!Xt(v)||i(F.color))continue;let E=U.bbox,z=1/0,j=-1/0,te=1/0,H=-1/0;for(let K=0;K<2;K++)for(let le=0;le<2;le++){let ne=K?E[3]:E[0],Le=le?E[5]:E[2],Ae=v[0]+v[3]*ne+v[5]*Le,de=v[2]+v[9]*ne+v[11]*Le;if(Ae<z)z=Ae;if(Ae>j)j=Ae;if(de<te)te=de;if(de>H)H=de}let G=Math.round((v[1]+E[4])*2),Q=mt(t,F.part),ue=Math.floor(z/40),ye=Math.floor(j/40),xe=Math.floor(te/40),we=Math.floor(H/40);if(!((ye-ue+1)*(we-xe+1)<=65536)||!Ie(G,ue,xe)||!Ie(G,ye,we))continue;let ge=Math.floor((z+5)/40),se=Math.floor((j-5)/40),oe=Math.floor((te+5)/40),ie=Math.floor((H-5)/40),Ce=ge<=se&&oe<=ie?(se-ge+1)*(ie-oe+1):0;y+=Ce;let pe=-1;for(let K=ge<=se&&oe<=ie?k.get(G,ge,oe):-1,le=0;K>=0&&le<8;K=N[K],le++){let ne=P[K];if(l[ne]!==z||f[ne]!==j||h[ne]!==te||g[ne]!==H||d[ne]!==Q)continue;let Le=e[p[ne]].m,Ae=!0;for(let de=0;de<12;de++)if(Le[de]!==v[de]){Ae=!1;break}if(Ae){pe=ne;break}}if(pe>=0){let K=n?n[L]:0;if(n&&K<n[p[pe]])m[pe]=p[pe],p[pe]=L;else if(m[pe]<0||n&&K<n[m[pe]])m[pe]=L;continue}let ae=u++;l[ae]=z,f[ae]=j,h[ae]=te,g[ae]=H,p[ae]=L,m[ae]=-1,d.push(Q),A[ae]=E[0],x[ae]=E[2],w[ae]=G;let me=ae*9;if(b[me]=v[0],b[me+1]=v[1],b[me+2]=v[2],b[me+3]=v[3],b[me+4]=v[6],b[me+5]=v[9],b[me+6]=v[5],b[me+7]=v[8],b[me+8]=v[11],M[ae]=Q.full&&E[3]-E[0]<=20*Q.nx&&E[5]-E[2]<=20*Q.nz&&v[4]===0&&v[6]===0&&v[8]===0&&v[10]===0&&_n(v[3],v[5],v[9],v[11])?1:0,D+Ce>r){D=r+1;continue}for(let K=ge;K<=se;K++)for(let le=oe;le<=ie;le++){if(!Ie(G,K,le))continue;let ne=D++;P[ne]=ae,N[ne]=k.put(G,K,le,ne)}}if(D>r)return Yt=y,null;let B=[0,5,-5,5,-5],C=[0,5,5,-5,-5],I=(L,F,v,U)=>{if(!(F-6>=l[L]-0.5&&F+6<=f[L]+0.5&&U-6>=h[L]-0.5&&U+6<=g[L]+0.5))return!1;if(M[L]===1)return!0;let E=L*9,z=d[L],j=A[L],te=x[L],H=F-b[E],G=v-b[E+1],Q=U-b[E+2],ue=b[E+3]*H+b[E+4]*G+b[E+5]*Q,ye=b[E+6]*H+b[E+7]*G+b[E+8]*Q,{nx:xe,nz:we,mask:ge}=z;for(let se=0;se<5;se++){let oe=Math.floor((ue+B[se]-j)/20),ie=Math.floor((ye+C[se]-te)/20);if(oe<0||ie<0||oe>=xe||ie>=we||ge[oe*we+ie]!==1)return!1}return!0},R=NaN,S=NaN,V=NaN,he=-1,ce=-1,Me=(L,F,v,U)=>{let E=Math.round(F*2),z=Math.floor(L/40),j=Math.floor(v/40);if(!Ie(E,z,j))return De;let te=De;if(!n&&ce>=0&&w[ce]===E&&(p[ce]!==U||m[ce]>=0)&&I(ce,L,F,v))return 0;if(E!==R||z!==S||j!==V)R=E,S=z,V=j,he=k.get(E,z,j);for(let H=he;H>=0;H=N[H]){let G=P[H],Q=p[G];if(Q===U&&(Q=m[G])<0)continue;if(!I(G,L,F,v))continue;if(!n)return ce=G,0;let ue=n[Q];if(ue<te)te=ue}return te},re=0;for(let L of e){let F=mt(t,L.part);if(F)re+=F.nStuds}let Te=new Uint8Array(re),be=new Uint8Array(re),ve=0,fe=n?new Ee(re,4):null,ke=n?null:new Int32Array(re),O=n?null:new Int32Array(re),T=n?null:new Int32Array(re),_=0,X=n?new Int32Array(re).fill(De):void 0;for(let L=0,F=0;L<e.length;L++){let v=e[L],U=mt(t,v.part);if(!U)continue;let E=v.m,z=U.studM,j=E[0],te=E[1],H=E[2],G=E[3],Q=E[4],ue=E[5],ye=E[6],xe=E[7],we=E[8],ge=E[9],se=E[10],oe=E[11];for(let ie=0;ie<U.nStuds;ie++,F++){let Ce=ie*12,pe=z[Ce+4],ae=z[Ce+7],me=z[Ce+10];if(!(Math.abs(ye*pe+xe*ae+we*me-1)<0.001&&Math.abs(G*pe+Q*ae+ue*me)<0.001&&Math.abs(ge*pe+se*ae+oe*me)<0.001))continue;be[F]=1;let K=z[Ce],le=z[Ce+1],ne=z[Ce+2],Le=j+G*K+Q*le+ue*ne,Ae=te+ye*K+xe*le+we*ne,de=H+ge*K+se*le+oe*ne,ht=Me(Le,Ae,de,L);if(ht!==De){if(Te[F]=1,ve++,X)X[F]=ht}let Ue=Math.round(Le),Ne=Math.round(Ae),Oe=Math.round(de);if(!Ie(Ue,Ne,Oe))continue;if(!fe){ke[_]=Ue,O[_]=Ne,T[_++]=Oe;continue}let gt=n[L],dt=fe.get(Ue,Ne,Oe);if(dt<0||gt<dt)fe.put(Ue,Ne,Oe,gt)}}let q=fe?null:new Zt(ke,O,T,_),ee=new Uint8Array(e.length),J=n?new Int32Array(e.length).fill(De):void 0;for(let L=0;L<e.length;L++){let F=e[L],v=t.parts[F.part];if(!v||!v.under||!Xt(F.m)||i(F.color))continue;let U=v.bbox,E=Math.round((U[3]-U[0])/20),z=Math.round((U[5]-U[2])/20);if(!E||!z||E*z>4096)continue;let j=F.m,te=Math.round(j[1]+U[4]),H=!0,G=0;for(let Q=0;Q<E&&H;Q++)for(let ue=0;ue<z;ue++){let ye=U[0]+10+20*Q,xe=U[2]+10+20*ue,we=j[0]+j[3]*ye+j[5]*xe,ge=j[2]+j[9]*ye+j[11]*xe,se=Math.round(we),oe=Math.round(ge),ie=!Ie(se,te,oe)?-1:fe?fe.get(se,te,oe):q.has(se,te,oe)?1:-1;if(ie<0){H=!1;break}if(ie>G)G=ie}if(H){if(ee[L]=1,J)J[L]=G}}return{nStuds:re,studHidden:Te,studUp:be,underHidden:ee,studsHidden:ve,studHideStep:X,underHideStep:J}}function Xn(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 f=l.colour;if(!f)return String(l.color);let h=o.get(f);if(h!==void 0)return h;let g=t.colorTable?.[l.color],p=g?.hex??t.colors?.[l.color],m=g?ct({alpha:g.alpha??255,luminance:g.luminance??0,finish:g.finish??{type:"default"}}):"default:op",A=ct(f);if(h=p&&p.toUpperCase()===f.hex.toUpperCase()&&m===A?String(l.color):f.hex.toUpperCase()+"/"+A,h!==String(l.color))s.set(h,f);return o.set(f,h),h},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),{stepOf:a,nSteps:u}=Hn(c);return{all:c,stepOf:a,nSteps:u,localColours:s}}function Hn(e){let t=!0;for(let o=0;o<e.length;o++){let i=e[o].steps;if(i.length!==1){t=!1;break}let c=i[0];if(!(Number.isInteger(c)&&c>=0&&c<1e6)){t=!1;break}}if(t){let o=new Set;for(let a=0;a<e.length;a++)o.add(e[a].steps[0]);let i=[...o].sort((a,u)=>a-u),c=new Map(i.map((a,u)=>[a,u]));return{stepOf:e.map((a)=>c.get(a.steps[0])),nSteps:i.length}}let n=e.map((o)=>Vt(o.steps)),r=[...new Set(n)].sort(),s=new Map(r.map((o,i)=>[o,i]));return{stepOf:n.map((o)=>s.get(o)),nSteps:r.length}}function _e(e,t,n=!0){let r=Xn(e,t,n);return Wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Ke="https://ldr-demo.vercel.app/cdn/v1/",We=new Map,Ge=new Map;function Xe(e=Ke,t=fetch){let n=We.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(()=>We.delete(e)),We.set(e,n);return n}var Kn=(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"),He=(e,t)=>Kn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>He(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,He(r,t)])):e;function Zn(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let g=h.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let p=new DataView(g).getUint32(0,!0),m=new Uint8Array(g,4+p),A=r;n.push(m),r+=m.byteLength;let x=(4-r%4)%4;if(x)n.push(new Uint8Array(x)),r+=x;for(let[d,w]of Object.entries(h.header.parts??{}))if(!(d in s))s[d]=He(w,A);for(let[d,w]of Object.entries(h.header.studKinds??{}))if(!(d in o))o[d]=He(w,A)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+c.length)%4)%4,u=4+c.length+a,l=new Uint8Array(u+r);new DataView(l.buffer).setUint32(0,c.length+a,!0),l.set(c,4),l.fill(32,4+c.length,u);let f=u;for(let h of n)l.set(h,f),f+=h.byteLength;return Ve(l.buffer)}async function Yn(e,t={}){e=[...e];try{return await Jt(e,t)}catch(n){let r=t.cdn??Ke,s=t.fetch??fetch;We.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await Jt(e,{...t,fetch:o})}catch{throw n}}}async function Jt(e,t){let n=t.cdn??Ke,r=t.fetch??fetch,s=t.gap??16384,o=await Xe(n,r),i=[...new Set([...new Set(e)].map(Y))],c=[],a=[];for(let d of i){if(Ge.has(n+d))continue;let w=o.parts[d];if(w)a.push({name:d,off:w[0],len:w[1],file:w[2]??0});else c.push(d)}a.sort((d,w)=>d.file-w.file||d.off-w.off);let u=[];for(let d of a){let w=u[u.length-1];if(w&&w.file===d.file&&d.off-w.end<=s)w.end=Math.max(w.end,d.off+d.len),w.items.push(d);else u.push({file:d.file,start:d.off,end:d.off+d.len,items:[d]})}let l=0,f=0,h=0,g=new Map,p=async()=>{while(h<u.length){let d=u[h++],w=g.get(d.file);if(w)w=w.subarray(d.start,d.end);else{let b=await r(new URL(o.archives[d.file],n).href,{headers:{Range:`bytes=${d.start}-${d.end-1}`,"Accept-Encoding":"identity"}});if(!b.ok)throw Error(`ldr: parts CDN ${b.status}`);if(f++,w=new Uint8Array(await b.arrayBuffer()),l+=w.byteLength,b.status===200)g.set(d.file,w),w=w.subarray(d.start,d.end)}for(let b of d.items){let M=je(w.subarray(b.off-d.start,b.off-d.start+b.len)),k=M.buffer.slice(M.byteOffset,M.byteOffset+M.byteLength);Ge.set(n+b.name,Ve(k))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,u.length)},p));let m=i.filter((d)=>Ge.has(n+d)).map((d)=>Ge.get(n+d)),A={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:m.length?Zn(m,A):Ve(Jn(A)),missing:c,requests:f,bytes:l}}function Jn(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 Qn(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 Qt(e,t,n){let r=0,s=0,o=!1,i=new Set,c=new Map;for(let a of e){let u;if(a.embedded)u=t.get(a.part);else if(u=c.get(a.part),u===void 0)c.set(a.part,u=Y(a.part));let l=u?n.parts[u]:void 0;if(!l)continue;if(l[3]!=null)o=!0,r+=l[3];if(!i.has(u))i.add(u),s+=l[1]}return{bodyTris:r,packBytes:s,known:o}}class Ze 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 qt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Xe(t.cdn??Ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(y)=>{if(!y.ok)throw Error(`ldr: ${y.status} fetching ${e}`);return xt(await y.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":wt(e)),a=Gt(o,c,{looseGeometry:!1,callouts:t.callouts}),u=performance.now();t.onParsed?.(a),await s;let l=Wt(o,new Set(a.filter((y)=>y.embedded).map((y)=>y.part)),c),f=(y,B)=>t.maxBodyTris!=null&&y>t.maxBodyTris||t.maxPackBytes!=null&&B>t.maxPackBytes,h=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(y)=>new Ze({...y,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),p="full";if(h){let y=Qt(a,l,await s);if(f(y.known?y.bodyTris:0,y.packBytes)){if(!t.lowCdn)throw g(y);let B=await Xe(t.lowCdn,r).catch(()=>null);if(!B)throw g(y);let C=Qt(a,l,B);if(f(C.known?C.bodyTris:0,C.packBytes))throw g(C);p="low"}}let m=[...a.filter((y)=>!y.embedded).map((y)=>y.part),...l.values()],A=async()=>{let y=await Yn(m,p==="low"?{...t,cdn:t.lowCdn}:t);for(let[B,C]of l){let I=y.pack.header.parts[C];if(I)y.pack.header.parts[B]=I}return{...y,packBytes:y.pack.buffer?.byteLength??y.pack.bytes??0,bodyTris:Qn(a,y.pack)}},x=await A();if(h&&f(x.bodyTris,x.packBytes)&&p==="full"&&t.lowCdn&&await Xe(t.lowCdn,r).then(()=>!0,()=>!1)){p="low";let y=x;x=await A(),x.requests+=y.requests,x.bytes+=y.bytes}if(h&&f(x.bodyTris,x.packBytes))throw g(x);let{pack:d,missing:w,requests:b,bytes:M}=x,k=new Map([...l].map(([y,B])=>[B,y])),N=w.map((y)=>k.get(y)??y),P=performance.now(),D=t.cull?_e(a,d.header,t.textures!==!1):void 0;return{insts:a,pack:d,tier:p,missing:N,requests:b,bytes:M,cull:D,timings:{fetchModel:i-n,parse:u-i,parts:P-u,...D?{cull:performance.now()-P}:{}}}}var qn=new Set(["part","color","m","step","steps","localStep","path"]);function en(e){let t=e.length,n=0;for(let p of e){if(typeof p.part!=="string"||typeof p.path!=="string"||typeof p.color!=="number"||typeof p.step!=="number"||typeof p.localStep!=="number"||!Array.isArray(p.m)||p.m.length!==12||!Array.isArray(p.steps))return null;n+=p.steps.length}let r=[],s=new Map,o=(p)=>{let m=s.get(p);if(m===void 0)s.set(p,m=r.length),r.push(p);return m},i=new Uint32Array(t),c=new Uint32Array(t),a=new Float64Array(t*3),u=new Float64Array(t*12),l=new Uint32Array(t+1),f=new Float64Array(n),h=[],g=0;for(let p=0;p<t;p++){let m=e[p];i[p]=o(m.part),c[p]=o(m.path),a[p*3]=m.color,a[p*3+1]=m.step,a[p*3+2]=m.localStep;let A=m.m,x=p*12;for(let b=0;b<12;b++)u[x+b]=A[b];let d=m.steps;for(let b=0;b<d.length;b++)f[g++]=d[b];l[p+1]=g;let w=null;for(let b in m)if(!qn.has(b))(w??={})[b]=m[b];if(w)h.push([p,w])}return{n:t,strs:r,part:i,path:c,num:a,m:u,so:l,steps:f,extra:h}}var tn=(e)=>[e.part.buffer,e.path.buffer,e.num.buffer,e.m.buffer,e.so.buffer,e.steps.buffer];self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await qt(n,{...r,cull:!1,onParsed:(l)=>{let f=en(l);if(f)self.postMessage({id:t,packed:f},tn(f));else self.postMessage({id:t,insts:l})}}),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=_e(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,u=[];for(let l of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(l)u.push(l.buffer);self.postMessage({id:t,cull:c,ms:a},u)}catch(s){if(s instanceof Ze||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';
5636
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/load-worker.gen.ts
5637
+ var load_worker_gen_default = 'var sn=ArrayBuffer,H=Uint8Array,$e=Uint16Array,on=Int16Array;var je=Int32Array,Ye=function(e,t,n){if(H.prototype.slice)return H.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 H(n-t);return r.set(e.subarray(t,n)),r},Be=function(e,t,n,r){if(H.prototype.fill)return H.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},an=function(e,t,n,r){if(H.prototype.copyWithin)return H.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 ln=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],Z=function(e,t,n){var r=Error(t||ln[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,Z);if(!n)throw r;return r},yt=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},cn=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},un=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)Z(0);var a=6-s,u=i==3?4:i,l=yt(e,a,u);a+=u;var f=c?1<<c:s,h=yt(e,a,f)+(c==1&&256),g=h;if(!s){var p=1<<10+(e[5]>>3);g=p+(p>>3)*(e[5]&7)}if(g>2145386496)Z(1);var m=new H((t==1?h||g:t?0:g)+12);return m[0]=1,m[4]=4,m[8]=8,{b:a+f,y:0,l:0,d:l,w:t&&t!=1?t:m.subarray(12),e:g,o:new je(m.buffer,0,3),u:h,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return cn(e,4)+8;Z(0)},Se=function(e){var t=0;for(;1<<t<=e;++t);return t-1},De=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)Z(3);var o=1<<s,i=o,c=-1,a=-1,u=-1,l=o,f=new sn(512+(o<<2)),h=new on(f,0,256),g=new $e(f,0,256),p=new $e(f,512,o),m=512+(o<<1),A=new H(f,m,o),b=new H(f,m+o);while(c<255&&i>0){var d=Se(i+1),x=r>>3,w=(1<<d+1)-1,v=(e[x]|e[x+1]<<8|e[x+2]<<16)>>(r&7)&w,M=(1<<d)-1,U=w-i-1,S=v&M;if(S<U)r+=d,v=S;else if(r+=d+1,v>M)v-=U;if(h[++c]=--v,v==-1)i+=v,A[--l]=c;else i-=v;if(!v)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,c+=a}while(a==3)}if(c>255||i)Z(0);var y=0,R=(o>>1)+(o>>3)+3,C=o-1;for(var F=0;F<=c;++F){var B=h[F];if(B<1){g[F]=-B;continue}for(u=0;u<B;++u){A[y]=F;do y=y+R&C;while(y>=l)}}if(y)Z(0);for(u=0;u<o;++u){var L=g[A[u]]++,V=b[u]=s-Se(L);p[u]=(L<<V)-o}return[r+7>>3,{b:s,s:A,n:b,t:p}]},fn=function(e,t){var n=0,r=-1,s=new H(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),a=new $e(s.buffer,268);if(o<128){var u=De(e,t+1,6),l=u[0],f=u[1];t+=o;var h=l<<3,g=e[t];if(!g)Z(0);var p=0,m=0,A=f.b,b=A,d=(++t<<3)-8+Se(g);for(;;){if(d-=A,d<h)break;var x=d>>3;if(p+=(e[x]|e[x+1]<<8)>>(d&7)&(1<<A)-1,i[++r]=f.s[p],d-=b,d<h)break;x=d>>3,m+=(e[x]|e[x+1]<<8)>>(d&7)&(1<<b)-1,i[++r]=f.s[m],A=f.n[p],p=f.t[p],b=f.n[m],m=f.t[m]}if(++r>255)Z(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 v=0;for(n=0;n<r;++n){var M=i[n];if(M>11)Z(0);v+=M&&1<<M-1}var U=Se(v)+1,S=1<<U,D=S-v;if(D&D-1)Z(0);i[r++]=Se(D)+1;for(n=0;n<r;++n){var M=i[n];++c[i[n]=M&&U+1-M]}var y=new H(S<<1),R=y.subarray(0,S),C=y.subarray(S);a[U]=0;for(n=U;n>0;--n){var F=a[n];Be(C,n,F,a[n-1]=F+c[n]*(1<<U-n))}if(a[0]!=S)Z(0);for(n=0;n<r;++n){var B=i[n];if(B){var L=a[B];Be(R,n,L,a[B]=L+(1<<U-B))}}return[t,{n:C,b:U,s:R}]},pn=De(new H([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],mn=De(new H([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],hn=De(new H([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],xt=function(e,t){var n=e.length,r=new je(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Je=new H(new je([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),gn=xt(Je,0),Qe=new H(new je([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),dn=xt(Qe,3),Re=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)Z(0);var a=0,u=n.b,l=(r<<3)-8+Se(o)-u,f=-1;for(;l>c&&f<s;){var h=l>>3,g=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(l&7);a=(a<<u|g)&i,t[++f]=n.s[a],l-=u=n.n[a]}if(l!=c||f+1!=s)Z(0)},bn=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;Re(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),Re(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),Re(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),Re(e.subarray(r),t.subarray(c),n)},yn=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,a=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return Be(n,e[s],t.y,t.y+=c),n;return Be(new H(c),e[s])}if(a>e.length)return;if(i==0){if(t.b=a,n)return n.set(e.subarray(s,a),t.y),t.y+=c,n;return Ye(e,s,a)}if(i==2){var u=e[s],l=u&3,f=u>>2&3,h=u>>4,g=0,p=0;if(l<2)if(f&1)h|=e[++s]<<4|(f&2&&e[++s]<<12);else h=u>>3;else if(p=f,f<2)h|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(f==2)h|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var m=n?n.subarray(t.y,t.y+t.m):new H(t.m),A=m.length-h;if(l==0)m.set(e.subarray(s,s+=h),A);else if(l==1)Be(m,e[s++],A);else{var b=t.h;if(l==2){var d=fn(e,s);g+=s-(s=d[0]),t.h=b=d[1]}else if(!b)Z(0);(p?bn:Re)(e.subarray(s,s+=g),m.subarray(A),b)}var x=e[s++];if(x){if(x==255)x=(e[s++]|e[s++]<<8)+32512;else if(x>127)x=x-128<<8|e[s++];var w=e[s++];if(w&3)Z(0);var v=[mn,hn,pn];for(var M=2;M>-1;--M){var U=w>>(M<<1)+2&3;if(U==1){var S=new H([0,0,e[s++]]);v[M]={s:S.subarray(2,3),n:S.subarray(0,1),t:new $e(S.buffer,0,1),b:0}}else if(U==2)r=De(e,s,9-(M&1)),s=r[0],v[M]=r[1];else if(U==3){if(!t.t)Z(0);v[M]=t.t[M]}}var D=t.t=v,y=D[0],R=D[1],C=D[2],F=e[a-1];if(!F)Z(0);var B=(a<<3)-8+Se(F)-C.b,L=B>>3,V=0,me=(e[L]|e[L+1]<<8)>>(B&7)&(1<<C.b)-1;L=(B-=R.b)>>3;var be=(e[L]|e[L+1]<<8)>>(B&7)&(1<<R.b)-1;L=(B-=y.b)>>3;var ye=(e[L]|e[L+1]<<8)>>(B&7)&(1<<y.b)-1;for(++x;--x;){var ue=C.s[me],Pe=C.n[me],xe=y.s[ye],Ce=y.n[ye],ke=R.s[be],he=R.n[be];L=(B-=ke)>>3;var O=1<<ke,k=O+((e[L]|e[L+1]<<8|e[L+2]<<16|e[L+3]<<24)>>>(B&7)&O-1);L=(B-=Qe[xe])>>3;var J=dn[xe]+((e[L]|e[L+1]<<8|e[L+2]<<16)>>(B&7)&(1<<Qe[xe])-1);L=(B-=Je[ue])>>3;var _=gn[ue]+((e[L]|e[L+1]<<8|e[L+2]<<16)>>(B&7)&(1<<Je[ue])-1);if(L=(B-=Pe)>>3,me=C.t[me]+((e[L]|e[L+1]<<8)>>(B&7)&(1<<Pe)-1),L=(B-=Ce)>>3,ye=y.t[ye]+((e[L]|e[L+1]<<8)>>(B&7)&(1<<Ce)-1),L=(B-=he)>>3,be=R.t[be]+((e[L]|e[L+1]<<8)>>(B&7)&(1<<he)-1),k>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=k-=3;else{var W=k-(_!=0);if(W){if(k=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]=k}else k=t.o[0]}for(var M=0;M<_;++M)m[V+M]=m[A+M];V+=_,A+=_;var ne=V-k;if(ne<0){var q=-ne,le=t.e+ne;if(q>J)q=J;for(var M=0;M<q;++M)m[V+M]=t.w[le+M];V+=q,J-=q,ne=0}for(var M=0;M<J;++M)m[V+M]=m[ne+M];V+=J}if(V!=A)while(A<m.length)m[V++]=m[A++];else V=m.length;if(n)t.y+=V;else m=Ye(m,0,V)}else if(n){if(t.y+=h,A)for(var M=0;M<h;++M)m[M]=m[A+M]}else if(A)m=Ye(m,A);return t.b=a,m}Z(2)},xn=function(e,t){if(e.length==1)return e[0];var n=new H(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 Ve(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=un(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=yn(e,i,t);if(!c)Z(5);if(t)i.e=i.y;else n.push(c),o+=c.length,an(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 xn(n,o)}async function wn(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(Ve(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 wt(e){return new TextDecoder().decode(await wn(e))}var At=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function _e(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 Y=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),et=/^[A-Za-z][A-Za-z0-9_]*$/,qe=new Map;function tt(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(!qe.has(r))qe.set(r,t);return r}function nt(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&et.test(e))return tt(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var Mt=/^~?\\s*moved\\s+to\\s+(.+)$/i,An=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Mn=new Set(["FILE","NOFILE","!DATA"]),Pt=1000000000000000,It=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),vn=new Set(["model","submodel","configuration"]),Cn=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function vt(e){let t=Cn.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return It.has(n)||vn.has(n)?n:void 0}function kn(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 Tn(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((f)=>Number.isFinite(f)&&Math.abs(f)<=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 f=0;f<s;f++)c=c.replace(/^\\S+\\s*/,"");let a=kn(c);if(!a.length)return null;let u={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)u.a=i[9];if(s===11)u.b=i[10];let l=a.findIndex((f,h)=>h>0&&f.toUpperCase()==="GLOSSMAP");if(l>0&&a[l+1])u.glossmap=a[l+1];if(t)u.next=!0;return u}var Ln=(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 Sn(e,t){let n=e.length,r=1,s=(p)=>p===32||p===9,o=()=>{while(r<n&&s(e.charCodeAt(r)))r++;let p=r,m=e.charCodeAt(r),A=m===45;if(A)m=e.charCodeAt(++r);let b=0,d=0;while(m>=48&&m<=57)b=b*10+(m-48),d++,m=e.charCodeAt(++r);if(d>0&&d<=15&&(r>=n||s(m)))return A?-b:b;while(r<n&&!s(e.charCodeAt(r)))r++;return p<r?+e.slice(p,r):NaN};while(r<n&&s(e.charCodeAt(r)))r++;let i=r;if(r>=n)return null;let c=e.charCodeAt(r),a=c===45,u=0,l=0;if(a)c=e.charCodeAt(++r);while(c>=48&&c<=57)u=u*10+(c-48),l++,c=e.charCodeAt(++r);if(l>0&&l<=15&&(r>=n||s(c))){if(a)u=-u}else{while(r<n&&!s(e.charCodeAt(r)))r++;u=nt(e.slice(i,r))}let f=Array(12);for(let p=0;p<12;p++){let m=o();if(!Number.isFinite(m))return null;f[p]=m}while(r<n&&s(e.charCodeAt(r)))r++;if(r>=n)return null;let h=e.slice(r),g=t.get(h);if(g===void 0)g=Y(/[ \\t]{2,}|\\t/.test(h)?h.split(/\\s+/).join(" "):h),t.set(h,g);if(!Number.isFinite(u))return null;return{t:1,color:u,m:f,file:g}}var En=[0,12,6,9,12,12];function Ct(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=nt(e[1]),r=En[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=Y(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 Ft(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,a=null,u=[],l=null,f=()=>{if(!a)return;let x=Ln(a.chunks.join("")),w=x[0]===137&&x[1]===80&&x[2]===78&&x[3]===71;(c??=new Map).set(Y(a.name),{name:a.name,bytes:x,...w?{mime:"image/png"}:{}}),a=null},h=new Map,g=!0,p=(x)=>{if(f(),o={name:Y(x),cmds:[]},s.set(o.name,o),!i)i=o.name;u=[],l=null,g=!0},m=!1,A=!1,b=()=>{if(A)return;A=!0,s.clear(),o=null,i=""},d=(x,w)=>{if(l){x.tex=l,l=null;return}let v=u[u.length-1];if(!v)return;if(v.fallback){if(!w)x.fallback=!0}else x.tex=v.map};for(let x of e.split(`\n`)){let w=x.trim();if(!w)continue;if(r&&w.charCodeAt(0)>=50&&w.charCodeAt(0)<=53&&(w.charCodeAt(1)===32||w.charCodeAt(1)===9)){if(a||m)continue;if(!o)p(t);let S=w.slice(2).trimStart(),D=S.search(/\\s/),y={t:w.charCodeAt(0)-48,color:nt(D<0?S:S.slice(0,D)),p:[],src:w};d(y,!1),o.cmds.push(y),g=!1;continue}if(w.charCodeAt(0)===48&&(w.charCodeAt(1)===32||w.charCodeAt(1)===9)){let S=2;while(w.charCodeAt(S)===32||w.charCodeAt(S)===9)S++;let D=S;while(D<w.length&&w.charCodeAt(D)!==32&&w.charCodeAt(D)!==9)D++;let y=w.slice(S,D),R=/[^\\x21-\\x7e]/.test(y)?w.slice(S).trim().split(/\\s+/)[0]:y;if(!An.has(R)&&!(R.length>=4&&R.length<=6&&Mn.has(R.toUpperCase()))){if(m||a)continue;if(!o)p(t);let C=w.slice(S),F={t:0,text:C};if(y.charCodeAt(0)===33)F.meta=y;if(l=null,g&&!o.org){let L=vt(C);if(L)o.org=L}let B=C.match(Mt);if(B&&!o.movedTo){let L=B[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(L))L+=".dat";o.movedTo=Y(L)}o.cmds.push(F);continue}}if(w.charCodeAt(0)===49&&(w.charCodeAt(1)===32||w.charCodeAt(1)===9)&&!a&&!m){let S=Sn(w,h);if(S){if(!o)p(t);d(S,!1),o.cmds.push(S),g=!1;continue}}let v=w.split(/\\s+/);if(+v[0]===0){let S=w.slice(1).trim(),D=v.length>1&&v[1].length>=4&&v[1].length<=6?v[1].toUpperCase():v[1];if(D==="FILE"){let C=S.slice(5).trimStart().split("\\r")[0].trim();if(C){b(),m=!1,p(C);continue}}if(D==="NOFILE"){f(),o=null,m=!0;continue}if(D==="!DATA"){b(),f(),o=null,m=!1,a={name:S.slice(5).trim(),chunks:[]};continue}if(m)continue;if(a){if(v[1]==="!:")a.chunks.push(v.slice(2).join(""));continue}if(!o)p(t);let y={t:0,text:S};if(v[1]==="STEP")y.step=!0,u=[],l=null;else if(v[1]==="BFC")y.bfc=v.slice(2).join(" ");else if(v[1]==="ROTSTEP")if(y.meta="ROTSTEP",y.step=!0,u=[],l=null,(v[2]??"").toUpperCase()==="END")y.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(v[5]??"REL").toUpperCase(),F=(B)=>{let L=Number(B);return Number.isFinite(L)?L:0};y.rotstep={x:F(v[2]),y:F(v[3]),z:F(v[4]),mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(v[1]==="BUFEXCHG"){y.meta="BUFEXCHG";let C=(v[2]??"").toUpperCase();y.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:v[3]??"A"}}else if(v[1]?.startsWith("!"))y.meta=v[1];if(g&&!o.org){let C=vt(S);if(C)o.org=C}if(v[1]==="!TEXMAP"){let C=(v[2]??"").toUpperCase();if(l=null,C==="START"||C==="NEXT"){let F=Tn(S.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(y.texmap={op:C,...F?{map:F}:{}},F)if((o.texmaps??=[]).push(F),C==="START")u.push({map:F,fallback:!1});else l=F}else if(C==="FALLBACK"){y.texmap={op:C};let F=u[u.length-1];if(F)F.fallback=!0}else if(C==="END")y.texmap={op:C},u.pop()}else if(v[1]==="!:"){l=null;let C=Ct(v.slice(2));if(C)d(C,!0),y.geom=C}else l=null;let R=S.match(Mt);if(R&&!o.movedTo){let C=R[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=Y(C)}o.cmds.push(y);continue}if(a||m)continue;if(!o)p(t);let U=Ct(v);if(!U){if(/^[2-5][ \\t]/.test(w))g=!1;continue}d(U,!1),o.cmds.push(U),g=!1}return f(),c?{main:i,files:s,data:c}:{main:i,files:s}}var sr=Math.PI/180;function Rt(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 Bt(e,t){let[n,r,s,o,i,c,a,u,l,f,h,g]=e,[p,m,A,b,d,x,w,v,M,U,S,D]=t;return[o*p+i*m+c*A+n,a*p+u*m+l*A+r,f*p+h*m+g*A+s,o*b+i*w+c*U,o*d+i*v+c*S,o*x+i*M+c*D,a*b+u*w+l*U,a*d+u*v+l*S,a*x+u*M+l*D,f*b+h*w+g*U,f*d+h*v+g*S,f*x+h*M+g*D]}var rt=[0,0,0,1,0,0,0,1,0,0,0,1];var kt=new WeakMap,Pn=/^(s|8|48)\\//;function st(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=kt.get(n);if(r)return r;if(n.org)r=It.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&&Pn.test(s.file))?"part":"model";return kt.set(n,r),r}var Tt=new WeakMap;function Dt(e){let t=Tt.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 Tt.set(e,t),t}var Lt=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?qe.get(e)??String(e):String(e),In=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Lt(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Lt(e.color)} ${e.p.join(" ")}`,ot=(e,t)=>`${Y(e)}#${t}`;function Fn(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:ot(e.name,t),cmds:n}}function Ut(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Fn(e,t).cmds.map(In)].join(`\n`)+`\n`}function it(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 Nt(e){let[t,n,r,s,o,i,c,a,u,l,f,h]=e,g=a*h-u*f,p=-(c*h-u*l),m=c*f-a*l,A=s*g+o*p+i*m;if(!Number.isFinite(A)||Math.abs(A)<0.000000000001)return null;let b=1/A,d=[g*b,-(o*h-i*f)*b,(o*u-i*a)*b,p*b,(s*h-i*l)*b,-(s*u-i*c)*b,m*b,-(s*f-o*l)*b,(s*a-o*c)*b];return[-(d[0]*t+d[1]*n+d[2]*r),-(d[3]*t+d[4]*n+d[5]*r),-(d[6]*t+d[7]*n+d[8]*r),...d]}var Rn=(e)=>String(+e.toFixed(6)||0),St=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function Ot(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(Rn).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${St(t.texture)}${t.glossmap?" GLOSSMAP "+St(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${Y(e)}\n0 !TEXMAP END\n`;return{name:`${Y(e)}#tex-${it(r)}`,source:r}}var Bn=(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 Dn(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),a=Math.sin(n*r),u=Math.cos(n*r);return[c*u,-c*a,i,o*a+s*i*u,o*u-s*i*a,-s*c,s*a-o*i*u,s*u+o*i*a,o*c]}var Et=new WeakMap;function zt(e){let t=Et.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=Dn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:Bn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),Et.set(e,n),n}class at 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])<=Pt))return!1;return!0},$t=999999,_t=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Gt=new WeakMap,jt=new WeakMap;function Nn(e,t){let n=jt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Gt.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},jt.set(t,n);let r=n.parts.get(e);if(!r){let s=Y(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-${it(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,c=new Map,a=0,u=new Set,l=t.maxInstances??2000000,f=0,h=(p,m)=>{let A=p.name+"#"+m,b=c.get(A);if(!b){let d;b=Object.assign(()=>d??=Ut(p,m),{file:p,step:m}),c.set(A,b)}return b},g=(p,m,A,b,d,x,w,v,M=null,U=[],S=[],D=void 0,y=null)=>{let R=p.files.get(m);if(!R||w>r||u.has(R))return;if(++f>l)throw new at("model",l);u.add(R);let C=y,F=0,B=w>0?++a:0,L=i&&B?[...U,B]:U,V=i&&B?[...S,A]:S,me=i&&!M?new Map:null,be=-1,ye=0,ue=(O,k,J,_,W,ne,q)=>{if(be!==F)be=F,ye=0;let le=me?.get(F+"|"+k);if(le)return le.n++,g(O,O===p?k:O.main,J,_,d+"/"+k,[...W,$t],w+1,ne,[...W,$t],L,V,q,C);let T=[...W,ye++],P=n.length;g(O,O===p?k:O.main,J,_,d+"/"+k,T,w+1,ne,M,L,V,q,C),me?.set(F+"|"+k,{n:1,from:P,to:n.length})},Pe=zt(R),xe=s?Dt(R):[],Ce=0,ke=(O,k,J,_,W,ne,q,le,T)=>{if(M)_=M;if(++f>l)throw new at("model",l);let P={part:O,color:k,m:J,step:_[0],steps:_,localStep:W,path:d};if(le)P.colour=le;if(B){if(P.sub=B,i)P.subPath=L,P.subMats=V}if(ne)P.embedded=!0;if(q){let N=Ot(O,q);P.texPart=N.name,P.texSource=N.source}else if(T){let N=Nn(O,T);P.colPart=N.name,P.colSource=N.source}let E=Pe[W];if(E)P.view=E;return n.push(P),P},he=(O)=>{while(Ce<xe.length&&xe[Ce]<=O){let k=xe[Ce++];ke(ot(R.name,k),b,A,[...x,k],k,!1,null,D,y).source=h(R,k)}};for(let O of R.cmds){if(O.t===0&&O.step){F++;continue}let k=O;if(k.t>=2||k.t===0&&k.geom&&k.geom.t>=2){he(F);continue}if(k.t===0){if(k.meta==="!COLOUR"){let E=$n(k.text);if(E&&E.code!==16&&E.code!==24)Gt.set(E,k.text),(C=new Map(C??[])).set(E.code,E);continue}if(o&&k.geom?.t===1)k=k.geom;else continue}if(k.t!==1)continue;if(o&&k.fallback)continue;let J=Bt(A,k.m);if(!Un(J))continue;let _=k.color===16?b:k.color,W=k.color===16?D:C?.get(k.color),ne=[...x,F],q=o?k.tex??v:null,le=q?Nt(k.m):null,T=q&&le?Rt(q,le):null;if(p.files.has(k.file)){if(st(p,k.file)==="model"){ue(p,k.file,J,_,ne,T,W);continue}ke(k.file,_,J,ne,F,!0,T,W,C);continue}let P=t.resolveModel?.(k.file);if(P){ue(P,k.file,J,_,ne,T,W);continue}ke(k.file,_,J,ne,F,!1,T,W,C)}if(he(1/0),u.delete(R),me){for(let O of me.values())if(O.n>1)for(let k=O.from;k<O.to;k++)n[k].mult??=O.n}};if(st(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...rt],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,rt,16,e.main,[],0,null),n}function Ht(e,t="main.ldr",n){return On(Ft(e,t,{geometryText:!0}),n)}var zn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function lt(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 Vt(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=lt(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 $n(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,a=0,u={type:"default"},l=1;while(l<n.length){let f=n[l].toUpperCase(),h=n[l+1];if(f==="CODE")s=h!==void 0&&et.test(h)?tt(h):h!==void 0&&/^\\d+$/.test(h)?+h:NaN,l+=2;else if(f==="VALUE"){let g=lt(h);if(g)o=g;l+=2}else if(f==="EDGE")i=lt(h)??h,l+=2;else if(f==="ALPHA")c=+h,l+=2;else if(f==="LUMINANCE")a=+h,l+=2;else if(f==="CHROME")u={type:"chrome"},l+=1;else if(f==="PEARLESCENT")u={type:"pearlescent"},l+=1;else if(f==="RUBBER")u={type:"rubber"},l+=1;else if(f==="MATTE_METALLIC")u={type:"matte_metallic"},l+=1;else if(f==="METAL")u={type:"metal"},l+=1;else if(f==="MATERIAL"){let g=(n[l+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:p,next:m}=Vt(n,l+2);u={type:"glitter",material:p},l=m}else if(g==="SPECKLE"){let{grain:p,next:m}=Vt(n,l+2);u={type:"speckle",material:p},l=m}else if(g==="FABRIC"){let p=(n[l+2]||"").toUpperCase(),m=["VELVET","CANVAS","STRING","FUR"].includes(p)?p.toLowerCase():void 0;u={type:"fabric",kind:m},l+=m?3:2}else l=n.length}else if(zn.has(f))l+=1;else l+=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(a)?a:0,finish:u}}function jn(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 ct(e){let t=jn(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 Vn(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(Y(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(Y(t),r)}let a=i.trim().replace(/\\s+/g," ");if(a)r.push(a)}return n}var _n=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Gn(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 Wt(e,t,n="main.ldr"){let r=[...t],s=new Map;if(!r.length)return s;let o=Vn(e,n);for(let i of r){let c=Y(i);if(!o.has(c)||s.has(c))continue;let a=new Set([c]),u=[c];while(u.length)for(let f of o.get(u.pop())){let h=_n(f);if(h&&o.has(h)&&!a.has(h))a.add(h),u.push(h)}let l=[c,...[...a].filter((f)=>f!==c).sort()].map((f)=>"0 FILE "+(f===c?"":f)+`\n`+o.get(f).join(`\n`)).join(`\n`);s.set(c,`emb/${Gn(l)}.dat`)}return s}var Xt=(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,Kt=new WeakMap,ut=null,ft="",pt=null;function Hn(e,t){if(e===ut&&t===ft)return pt;let n=Kt.get(e);if(!n)Kt.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return ut=e,ft=t,pt=r,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=[],a=[];s.studs.forEach((g,p)=>{c.push(g[0]),a.push(g[1]);for(let m=0;m<12;m++)i[p*12+m]=g[2+m]});let u=null,l=0,f=0;if(s.mask){l=s.mask[0],f=s.mask[1];let g=s.mask[2];u=new Uint8Array(g.length);for(let p=0;p<g.length;p++)u[p]=g.charCodeAt(p)===49?1:0}let h=!!u;if(u){for(let g=0;g<u.length;g++)if(u[g]!==1){h=!1;break}}return n.set(t,r={nStuds:o,studM:i,kind:c,color:a,mask:u,nx:l,nz:f,full:h}),ut=e,ft=t,pt=r,r}var Ie=1073741824;class Ee{t;tag;mask;size=0;shift;constructor(e=1024,t=-1){let n=1024;while(n<e*2)n*=2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.shift=t}slot(e,t,n){let r=this.shift;if(r<0){let o=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return o^=o>>>15,o=Math.imul(o,739982445),o^=o>>>12,o&this.mask}let s=Math.imul(e>>r+2,2654435761)^Math.imul(t,2246822507)^Math.imul(n>>r+2,3266489909);return s^=s>>>15,s=Math.imul(s,739982445),s^=s>>>12,(s<<4|(e>>r&3)<<2|n>>r&3)&this.mask}static tagOf(e,t,n){return Math.imul(e^Math.imul(t,374761393)^Math.imul(n,668265261),2654435761)>>>24|1}get(e,t,n){let r=Ee.tagOf(e,t,n),s=this.tag,o=this.t,i=this.mask,c=this.slot(e,t,n);for(;;){let a=s[c];if(a===0)return-1;if(a===r){let u=c<<2;if(o[u]===e&&o[u+1]===t&&o[u+2]===n)return o[u+3]}c=c+1&i}}put(e,t,n,r){if((this.size+1)*2>this.tag.length)this.grow();let s=Ee.tagOf(e,t,n),o=this.tag,i=this.t,c=this.mask,a=this.slot(e,t,n);for(;;){let u=o[a],l=a<<2;if(u===0)return o[a]=s,i[l]=e,i[l+1]=t,i[l+2]=n,i[l+3]=r,this.size++,-1;if(u===s&&i[l]===e&&i[l+1]===t&&i[l+2]===n){let f=i[l+3];return i[l+3]=r,f}a=a+1&c}}grow(){let e=this.t,t=this.tag,n=t.length*2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.size=0;for(let r=0;r<t.length;r++)if(t[r]){let s=r<<2;this.put(e[s],e[s+1],e[s+2],e[s+3])}}}class Yt{grp=new Ee(64);gBits=[];gX0=[];gZ0=[];gNz=[];gNx=[];bits;rest;lk=NaN;lpx=NaN;lpz=NaN;lg=-1;group(e,t,n){if(e!==this.lk||t!==this.lpx||n!==this.lpz)this.lk=e,this.lpx=t,this.lpz=n,this.lg=this.grp.get(e,t,n);return this.lg}constructor(e,t,n,r){let s=[],o=[],i=[],c=[],a=[];for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=(h%20+20)%20,A=(p%20+20)%20,b=this.group(g,m,A);if(b<0)b=s.length,this.grp.put(g,m,A,b),this.lg=b,s.push(0),o.push(h),i.push(h),c.push(p),a.push(p);if(s[b]++,h<o[b])o[b]=h;else if(h>i[b])i[b]=h;if(p<c[b])c[b]=p;else if(p>a[b])a[b]=p}let u=0,l=0;for(let f=0;f<s.length;f++){let h=(i[f]-o[f])/20+1,g=(a[f]-c[f])/20+1,p=h*g;if(this.gX0.push(o[f]),this.gZ0.push(c[f]),this.gNx.push(h),this.gNz.push(g),p<=64*s[f]+1024&&u+p<2147483648)this.gBits.push(u),u+=p;else this.gBits.push(-1),l+=s[f]}this.bits=new Uint8Array(Math.ceil(u/8)),this.rest=new Ee(l);for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=this.group(g,(h%20+20)%20,(p%20+20)%20),A=this.gBits[m];if(A<0){this.rest.put(h,g,p,1);continue}let b=A+(h-this.gX0[m])/20*this.gNz[m]+(p-this.gZ0[m])/20;this.bits[b>>>3]|=1<<(b&7)}}has(e,t,n){let r=this.group(t,(e%20+20)%20,(n%20+20)%20);if(r<0)return!1;let s=this.gBits[r];if(s<0)return this.rest.get(e,t,n)>=0;let o=(e-this.gX0[r])/20,i=(n-this.gZ0[r])/20;if(o<0||i<0||o>=this.gNx[r]||i>=this.gNz[r])return!1;let c=s+o*this.gNz[r]+i;return(this.bits[c>>>3]&1<<(c&7))!==0}}var Wn=(e,t,n,r)=>e===0&&r===0&&(t===1||t===-1)&&(n===1||n===-1)||t===0&&n===0&&(e===1||e===-1)&&(r===1||r===-1),Fe=(e,t,n)=>e>-Ie&&e<Ie&&t>-Ie&&t<Ie&&n>-Ie&&n<Ie,Ue=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 mt(e,t,n){return Zt(e,t,n,-1)??Zt(e,t,n,Jt)}var Jt=0;function Zt(e,t,n,r){let o=new Map,i=(T)=>{let P=o.get(T);if(P===void 0)o.set(T,P=Xn(t,T));return P},c=e.length,a=0,u=0,l=0,f=Array(c);for(let T=0;T<c;T++){let P=f[T]=Hn(t,e[T].part);if(P){if(l+=P.nStuds,P.mask)a++}}let h=new Float64Array(a),g=new Float64Array(a),p=new Float64Array(a),m=new Float64Array(a),A=new Int32Array(a),b=new Int32Array(a),d=new Float64Array(a),x=new Float64Array(a),w=[],v=new Int32Array(a),M=new Float64Array(a*9),U=new Uint8Array(a);if(r<0)r=a*4+64;let S=new Ee(e.length*2),D=new Int32Array(r),y=new Int32Array(r),R=0,C=0;for(let T=0;T<e.length;T++){let P=e[T],E=P.m,N=t.parts[P.part];if(!N||!N.mask||!Xt(E)||i(P.color))continue;let I=N.bbox,z=1/0,j=-1/0,ee=1/0,X=-1/0;for(let K=0;K<2;K++)for(let ae=0;ae<2;ae++){let te=K?I[3]:I[0],Le=ae?I[5]:I[2],ve=E[0]+E[3]*te+E[5]*Le,de=E[2]+E[9]*te+E[11]*Le;if(ve<z)z=ve;if(ve>j)j=ve;if(de<ee)ee=de;if(de>X)X=de}let G=Math.round((E[1]+I[4])*2),Q=f[T],ce=Math.floor(z/40),we=Math.floor(j/40),Ae=Math.floor(ee/40),Me=Math.floor(X/40);if(!((we-ce+1)*(Me-Ae+1)<=65536)||!Fe(G,ce,Ae)||!Fe(G,we,Me))continue;let ge=Math.floor((z+5)/40),re=Math.floor((j-5)/40),se=Math.floor((ee+5)/40),oe=Math.floor((X-5)/40),Te=ge<=re&&se<=oe?(re-ge+1)*(oe-se+1):0;C+=Te;let fe=-1;for(let K=ge<=re&&se<=oe?S.get(G,ge,se):-1,ae=0;K>=0&&ae<8;K=D[K],ae++){let te=y[K];if(h[te]!==z||g[te]!==j||p[te]!==ee||m[te]!==X||w[te]!==Q)continue;let Le=e[A[te]].m,ve=!0;for(let de=0;de<12;de++)if(Le[de]!==E[de]){ve=!1;break}if(ve){fe=te;break}}if(fe>=0){let K=n?n[T]:0;if(n&&K<n[A[fe]])b[fe]=A[fe],A[fe]=T;else if(b[fe]<0||n&&K<n[b[fe]])b[fe]=T;continue}let ie=u++;h[ie]=z,g[ie]=j,p[ie]=ee,m[ie]=X,A[ie]=T,b[ie]=-1,w.push(Q),d[ie]=I[0],x[ie]=I[2],v[ie]=G;let pe=ie*9;if(M[pe]=E[0],M[pe+1]=E[1],M[pe+2]=E[2],M[pe+3]=E[3],M[pe+4]=E[6],M[pe+5]=E[9],M[pe+6]=E[5],M[pe+7]=E[8],M[pe+8]=E[11],U[ie]=Q.full&&I[3]-I[0]<=20*Q.nx&&I[5]-I[2]<=20*Q.nz&&E[4]===0&&E[6]===0&&E[8]===0&&E[10]===0&&Wn(E[3],E[5],E[9],E[11])?1:0,R+Te>r){R=r+1;continue}for(let K=ge;K<=re;K++)for(let ae=se;ae<=oe;ae++){if(!Fe(G,K,ae))continue;let te=R++;y[te]=ie,D[te]=S.put(G,K,ae,te)}}if(R>r)return Jt=C,null;let F=[0,5,-5,5,-5],B=[0,5,5,-5,-5],L=(T,P,E,N)=>{if(!(P-6>=h[T]-0.5&&P+6<=g[T]+0.5&&N-6>=p[T]-0.5&&N+6<=m[T]+0.5))return!1;if(U[T]===1)return!0;let I=T*9,z=w[T],j=d[T],ee=x[T],X=P-M[I],G=E-M[I+1],Q=N-M[I+2],ce=M[I+3]*X+M[I+4]*G+M[I+5]*Q,we=M[I+6]*X+M[I+7]*G+M[I+8]*Q,{nx:Ae,nz:Me,mask:ge}=z;for(let re=0;re<5;re++){let se=Math.floor((ce+F[re]-j)/20),oe=Math.floor((we+B[re]-ee)/20);if(se<0||oe<0||se>=Ae||oe>=Me||ge[se*Me+oe]!==1)return!1}return!0},V=NaN,me=NaN,be=NaN,ye=-1,ue=-1,Pe=(T,P,E,N)=>{let I=Math.round(P*2),z=Math.floor(T/40),j=Math.floor(E/40);if(!Fe(I,z,j))return Ue;let ee=Ue;if(!n&&ue>=0&&v[ue]===I&&(A[ue]!==N||b[ue]>=0)&&L(ue,T,P,E))return 0;if(I!==V||z!==me||j!==be)V=I,me=z,be=j,ye=S.get(I,z,j);for(let X=ye;X>=0;X=D[X]){let G=y[X],Q=A[G];if(Q===N&&(Q=b[G])<0)continue;if(!L(G,T,P,E))continue;if(!n)return ue=G,0;let ce=n[Q];if(ce<ee)ee=ce}return ee},xe=new Uint8Array(l),Ce=new Uint8Array(l),ke=0,he=n?new Ee(l,4):null,O=n?null:new Int32Array(l),k=n?null:new Int32Array(l),J=n?null:new Int32Array(l),_=0,W=n?new Int32Array(l).fill(Ue):void 0;for(let T=0,P=0;T<e.length;T++){let E=e[T],N=f[T];if(!N)continue;let I=E.m,z=N.studM,j=I[0],ee=I[1],X=I[2],G=I[3],Q=I[4],ce=I[5],we=I[6],Ae=I[7],Me=I[8],ge=I[9],re=I[10],se=I[11];for(let oe=0;oe<N.nStuds;oe++,P++){let Te=oe*12,fe=z[Te+4],ie=z[Te+7],pe=z[Te+10];if(!(Math.abs(we*fe+Ae*ie+Me*pe-1)<0.001&&Math.abs(G*fe+Q*ie+ce*pe)<0.001&&Math.abs(ge*fe+re*ie+se*pe)<0.001))continue;Ce[P]=1;let K=z[Te],ae=z[Te+1],te=z[Te+2],Le=j+G*K+Q*ae+ce*te,ve=ee+we*K+Ae*ae+Me*te,de=X+ge*K+re*ae+se*te,gt=Pe(Le,ve,de,T);if(gt!==Ue){if(xe[P]=1,ke++,W)W[P]=gt}let Ne=Math.round(Le),Oe=Math.round(ve),ze=Math.round(de);if(!Fe(Ne,Oe,ze))continue;if(!he){O[_]=Ne,k[_]=Oe,J[_++]=ze;continue}let dt=n[T],bt=he.get(Ne,Oe,ze);if(bt<0||dt<bt)he.put(Ne,Oe,ze,dt)}}let ne=he?null:new Yt(O,k,J,_),q=new Uint8Array(e.length),le=n?new Int32Array(e.length).fill(Ue):void 0;for(let T=0;T<e.length;T++){let P=e[T],E=t.parts[P.part];if(!E||!E.under||!Xt(P.m)||i(P.color))continue;let N=E.bbox,I=Math.round((N[3]-N[0])/20),z=Math.round((N[5]-N[2])/20);if(!I||!z||I*z>4096)continue;let j=P.m,ee=Math.round(j[1]+N[4]),X=!0,G=0;for(let Q=0;Q<I&&X;Q++)for(let ce=0;ce<z;ce++){let we=N[0]+10+20*Q,Ae=N[2]+10+20*ce,Me=j[0]+j[3]*we+j[5]*Ae,ge=j[2]+j[9]*we+j[11]*Ae,re=Math.round(Me),se=Math.round(ge),oe=!Fe(re,ee,se)?-1:he?he.get(re,ee,se):ne.has(re,ee,se)?1:-1;if(oe<0){X=!1;break}if(oe>G)G=oe}if(X){if(q[T]=1,le)le[T]=G}}return{nStuds:l,studHidden:xe,studUp:Ce,underHidden:q,studsHidden:ke,studHideStep:W,underHideStep:le}}function ht(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 f=l.colour;if(!f)return String(l.color);let h=o.get(f);if(h!==void 0)return h;let g=t.colorTable?.[l.color],p=g?.hex??t.colors?.[l.color],m=g?ct({alpha:g.alpha??255,luminance:g.luminance??0,finish:g.finish??{type:"default"}}):"default:op",A=ct(f);if(h=p&&p.toUpperCase()===f.hex.toUpperCase()&&m===A?String(l.color):f.hex.toUpperCase()+"/"+A,h!==String(l.color))s.set(h,f);return o.set(f,h),h},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),{stepOf:a,nSteps:u}=Kn(c);return{all:c,stepOf:a,nSteps:u,localColours:s}}function Kn(e){let t=!0;for(let o=0;o<e.length;o++){let i=e[o].steps;if(i.length!==1){t=!1;break}let c=i[0];if(!(Number.isInteger(c)&&c>=0&&c<1e6)){t=!1;break}}if(t){let o=new Set;for(let a=0;a<e.length;a++)o.add(e[a].steps[0]);let i=[...o].sort((a,u)=>a-u),c=new Map(i.map((a,u)=>[a,u]));return{stepOf:e.map((a)=>c.get(a.steps[0])),nSteps:i.length}}let n=e.map((o)=>_t(o.steps)),r=[...new Set(n)].sort(),s=new Map(r.map((o,i)=>[o,i]));return{stepOf:n.map((o)=>s.get(o)),nSteps:r.length}}function Qt(e,t,n=!0){let r=ht(e,t,n);return mt(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Ke="https://ldr-parts-cdn.baconbrix.workers.dev/v1/",He=new Map,Ge=new Map;function We(e=Ke,t=fetch){let n=He.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(()=>He.delete(e)),He.set(e,n);return n}var Zn=(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"),Xe=(e,t)=>Zn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Xe(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Xe(r,t)])):e;function Yn(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let g=h.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let p=new DataView(g).getUint32(0,!0),m=new Uint8Array(g,4+p),A=r;n.push(m),r+=m.byteLength;let b=(4-r%4)%4;if(b)n.push(new Uint8Array(b)),r+=b;for(let[d,x]of Object.entries(h.header.parts??{}))if(!(d in s))s[d]=Xe(x,A);for(let[d,x]of Object.entries(h.header.studKinds??{}))if(!(d in o))o[d]=Xe(x,A)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+c.length)%4)%4,u=4+c.length+a,l=new Uint8Array(u+r);new DataView(l.buffer).setUint32(0,c.length+a,!0),l.set(c,4),l.fill(32,4+c.length,u);let f=u;for(let h of n)l.set(h,f),f+=h.byteLength;return _e(l.buffer)}async function Jn(e,t={}){e=[...e];try{return await qt(e,t)}catch(n){let r=t.cdn??Ke,s=t.fetch??fetch;He.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await qt(e,{...t,fetch:o})}catch{throw n}}}async function qt(e,t){let n=t.cdn??Ke,r=t.fetch??fetch,s=t.gap??16384,o=await We(n,r),i=[...new Set([...new Set(e)].map(Y))],c=[],a=[];for(let d of i){if(Ge.has(n+d))continue;let x=o.parts[d];if(x)a.push({name:d,off:x[0],len:x[1],file:x[2]??0});else c.push(d)}a.sort((d,x)=>d.file-x.file||d.off-x.off);let u=[];for(let d of a){let x=u[u.length-1];if(x&&x.file===d.file&&d.off-x.end<=s)x.end=Math.max(x.end,d.off+d.len),x.items.push(d);else u.push({file:d.file,start:d.off,end:d.off+d.len,items:[d]})}let l=0,f=0,h=0,g=new Map,p=async()=>{while(h<u.length){let d=u[h++],x=g.get(d.file);if(x)x=x.subarray(d.start,d.end);else{let w=await r(new URL(o.archives[d.file],n).href,{headers:{Range:`bytes=${d.start}-${d.end-1}`,"Accept-Encoding":"identity"}});if(!w.ok)throw Error(`ldr: parts CDN ${w.status}`);if(f++,x=new Uint8Array(await w.arrayBuffer()),l+=x.byteLength,w.status===200)g.set(d.file,x),x=x.subarray(d.start,d.end)}for(let w of d.items){let v=Ve(x.subarray(w.off-d.start,w.off-d.start+w.len)),M=v.buffer.slice(v.byteOffset,v.byteOffset+v.byteLength);Ge.set(n+w.name,_e(M))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,u.length)},p));let m=i.filter((d)=>Ge.has(n+d)).map((d)=>Ge.get(n+d)),A={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:m.length?Yn(m,A):_e(Qn(A)),missing:c,requests:f,bytes:l}}function Qn(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 qn(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 en(e,t,n){let r=0,s=0,o=!1,i=new Set,c=new Map;for(let a of e){let u;if(a.embedded)u=t.get(a.part);else if(u=c.get(a.part),u===void 0)c.set(a.part,u=Y(a.part));let l=u?n.parts[u]:void 0;if(!l)continue;if(l[3]!=null)o=!0,r+=l[3];if(!i.has(u))i.add(u),s+=l[1]}return{bodyTris:r,packBytes:s,known:o}}class Ze 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 tn(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=We(t.cdn??Ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(y)=>{if(!y.ok)throw Error(`ldr: ${y.status} fetching ${e}`);return wt(await y.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":At(e)),a=Ht(o,c,{looseGeometry:!1,callouts:t.callouts}),u=performance.now();t.onParsed?.(a),await s;let l=Wt(o,new Set(a.filter((y)=>y.embedded).map((y)=>y.part)),c),f=(y,R)=>t.maxBodyTris!=null&&y>t.maxBodyTris||t.maxPackBytes!=null&&R>t.maxPackBytes,h=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(y)=>new Ze({...y,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),p="full";if(h){let y=en(a,l,await s);if(f(y.known?y.bodyTris:0,y.packBytes)){if(!t.lowCdn)throw g(y);let R=await We(t.lowCdn,r).catch(()=>null);if(!R)throw g(y);let C=en(a,l,R);if(f(C.known?C.bodyTris:0,C.packBytes))throw g(C);p="low"}}let m=[...a.filter((y)=>!y.embedded).map((y)=>y.part),...l.values()],A=async()=>{let y=await Jn(m,p==="low"?{...t,cdn:t.lowCdn}:t);for(let[R,C]of l){let F=y.pack.header.parts[C];if(F)y.pack.header.parts[R]=F}return{...y,packBytes:y.pack.buffer?.byteLength??y.pack.bytes??0,bodyTris:qn(a,y.pack)}},b=await A();if(h&&f(b.bodyTris,b.packBytes)&&p==="full"&&t.lowCdn&&await We(t.lowCdn,r).then(()=>!0,()=>!1)){p="low";let y=b;b=await A(),b.requests+=y.requests,b.bytes+=y.bytes}if(h&&f(b.bodyTris,b.packBytes))throw g(b);let{pack:d,missing:x,requests:w,bytes:v}=b,M=new Map([...l].map(([y,R])=>[R,y])),U=x.map((y)=>M.get(y)??y),S=performance.now(),D=t.cull?Qt(a,d.header,t.textures!==!1):void 0;return{insts:a,pack:d,tier:p,missing:U,requests:w,bytes:v,cull:D,timings:{fetchModel:i-n,parse:u-i,parts:S-u,...D?{cull:performance.now()-S}:{}}}}var er=new Set(["part","color","m","step","steps","localStep","path"]);function nn(e){let t=e.length,n=0;for(let p of e){if(typeof p.part!=="string"||typeof p.path!=="string"||typeof p.color!=="number"||typeof p.step!=="number"||typeof p.localStep!=="number"||!Array.isArray(p.m)||p.m.length!==12||!Array.isArray(p.steps))return null;n+=p.steps.length}let r=[],s=new Map,o=(p)=>{let m=s.get(p);if(m===void 0)s.set(p,m=r.length),r.push(p);return m},i=new Uint32Array(t),c=new Uint32Array(t),a=new Float64Array(t*3),u=new Float64Array(t*12),l=new Uint32Array(t+1),f=new Float64Array(n),h=[],g=0;for(let p=0;p<t;p++){let m=e[p];i[p]=o(m.part),c[p]=o(m.path),a[p*3]=m.color,a[p*3+1]=m.step,a[p*3+2]=m.localStep;let A=m.m,b=p*12;for(let w=0;w<12;w++)u[b+w]=A[w];let d=m.steps;for(let w=0;w<d.length;w++)f[g++]=d[w];l[p+1]=g;let x=null;for(let w in m)if(!er.has(w))(x??={})[w]=m[w];if(x)h.push([p,x])}return{n:t,strs:r,part:i,path:c,num:a,m:u,so:l,steps:f,extra:h}}var rn=(e)=>[e.part.buffer,e.path.buffer,e.num.buffer,e.m.buffer,e.so.buffer,e.steps.buffer];self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await tn(n,{...r,cull:!1,onParsed:(f)=>{let h=nn(f);if(h)self.postMessage({id:t,packed:h},rn(h));else self.postMessage({id:t,insts:f})}}),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=ht(s.insts,s.pack.header,r.textures!==!1),a=mt(c.all,s.pack.header,r.stepCull&&c.nSteps>1?c.stepOf:void 0),u=performance.now()-i,l=[];for(let f of[a.studHidden,a.studUp,a.underHidden,a.studHideStep,a.underHideStep])if(f)l.push(f.buffer);self.postMessage({id:t,cull:a,ms:u},l)}catch(s){if(s instanceof Ze||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';
5404
5638
 
5405
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/inst-io.ts
5639
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/inst-io.ts
5406
5640
  var CORE = new Set(["part", "color", "m", "step", "steps", "localStep", "path"]);
5407
5641
  function unpackInstances(p) {
5408
5642
  const { n, strs, part, path, num, m, so, steps, extra } = p;
@@ -5427,7 +5661,7 @@ function unpackInstances(p) {
5427
5661
  return out;
5428
5662
  }
5429
5663
 
5430
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/cdn.ts
5664
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/cdn.ts
5431
5665
  var worker;
5432
5666
  var seq = 0;
5433
5667
  var pending = new Map;
@@ -5476,6 +5710,7 @@ function getWorker() {
5476
5710
  return worker = null;
5477
5711
  }
5478
5712
  }
5713
+ var eagerSteps = (o) => o.step != null || (o.eagerSteps ?? !!o.callouts);
5479
5714
  var abs = (u) => {
5480
5715
  try {
5481
5716
  return new URL(u, globalThis.location?.href).href;
@@ -5485,7 +5720,7 @@ var abs = (u) => {
5485
5720
  };
5486
5721
  function prepareInWorker(w, source, o) {
5487
5722
  const id = ++seq;
5488
- const opts = { cdn: abs(o.cdn ?? DEFAULT_PARTS_CDN), gap: o.gap, concurrency: o.concurrency, text: o.text, name: o.name, cull: true, textures: o.textures, callouts: o.callouts, maxBodyTris: o.maxBodyTris, maxPackBytes: o.maxPackBytes, lowCdn: o.lowCdn && abs(o.lowCdn) };
5723
+ const opts = { cdn: abs(o.cdn ?? DEFAULT_PARTS_CDN), gap: o.gap, concurrency: o.concurrency, text: o.text, name: o.name, cull: true, stepCull: eagerSteps(o), textures: o.textures, callouts: o.callouts, maxBodyTris: o.maxBodyTris, maxPackBytes: o.maxPackBytes, lowCdn: o.lowCdn && abs(o.lowCdn) };
5489
5724
  const name = o.name ?? (o.text ? undefined : modelFileName(source));
5490
5725
  let insts;
5491
5726
  pendingInsts.set(id, (v) => {
@@ -5526,7 +5761,8 @@ async function loadModel(source, o = {}) {
5526
5761
  } else
5527
5762
  prep = await prepareModel(source, o);
5528
5763
  const t3 = performance.now();
5529
- const obj = await createLdrObjectAsync(prep.insts, prep.pack, prep.cull ? { ...o, precomputedCull: prep.cull } : o);
5764
+ const oo = { ...o, eagerSteps: eagerSteps(o) };
5765
+ const obj = await createLdrObjectAsync(prep.insts, prep.pack, prep.cull ? { ...oo, precomputedCull: prep.cull } : oo);
5530
5766
  for (const m of prep.missing)
5531
5767
  if (!obj.stats.missing.includes(m))
5532
5768
  obj.stats.missing.push(m);
@@ -5541,7 +5777,7 @@ async function loadModel(source, o = {}) {
5541
5777
  timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
5542
5778
  });
5543
5779
  }
5544
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/usdz.ts
5780
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/usdz.ts
5545
5781
  var IDENT = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
5546
5782
  var MAX_ERR = 8;
5547
5783
  var REL_ERR = 0.1;
@@ -6173,7 +6409,7 @@ function hiddenInstances(n, items, geo, clear, RES = 512) {
6173
6409
  hidden[k] = seen[k] ? 0 : 1;
6174
6410
  return hidden;
6175
6411
  }
6176
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/library.ts
6412
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/library.ts
6177
6413
  import { existsSync, readFileSync, statSync } from "fs";
6178
6414
  import { join } from "path";
6179
6415
  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]];
@@ -6523,11 +6759,11 @@ class Library {
6523
6759
  return insts;
6524
6760
  }
6525
6761
  }
6526
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/build-pack.ts
6762
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/build-pack.ts
6527
6763
  import fs3 from "node:fs";
6528
6764
  import path3 from "node:path";
6529
6765
 
6530
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/resolver.ts
6766
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/resolver.ts
6531
6767
  import fs from "node:fs";
6532
6768
  import path from "node:path";
6533
6769
  var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
@@ -6856,11 +7092,11 @@ function collectDeps(lib, refs) {
6856
7092
  return out;
6857
7093
  }
6858
7094
 
6859
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/compile.ts
7095
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/compile.ts
6860
7096
  import fs2 from "node:fs";
6861
7097
  import path2 from "node:path";
6862
7098
 
6863
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/lod.ts
7099
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/lod.ts
6864
7100
  import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
6865
7101
  await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
6866
7102
  function reorderMesh(P, N, C, I) {
@@ -7166,7 +7402,7 @@ function levelLines(P, I, E, err, always, tol = 0.01) {
7166
7402
  return out;
7167
7403
  }
7168
7404
 
7169
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/compile.ts
7405
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/compile.ts
7170
7406
  class BfcState {
7171
7407
  accum;
7172
7408
  ccw = true;
@@ -7469,6 +7705,22 @@ class Compiler {
7469
7705
  seatStuds(out, fullKind, (k) => this.compile(k, false).bbox);
7470
7706
  if (this.opts.tex && this.hasTex(key))
7471
7707
  this.texPass(key, out, separateStuds, colorOf);
7708
+ const cap = OPEN_BOTTOM[key.replace(/^.*[\\/]/, "").toLowerCase()];
7709
+ if (cap && isFinite(out.bbox[0])) {
7710
+ const [cx0, cz0, cx1, cz1] = cap, y = out.bbox[4], b = out.body, per = b.col.length / (b.pos.length / 3);
7711
+ let v = -1;
7712
+ for (let i = 1;i < b.pos.length; i += 3)
7713
+ if (Math.abs(b.pos[i] - y) < 0.01) {
7714
+ v = (i - 1) / 3;
7715
+ break;
7716
+ }
7717
+ if (v >= 0) {
7718
+ const rgba = b.col.slice(v * per, v * per + per);
7719
+ b.pos.push(cx0, y, cz0, cx0, y, cz1, cx1, y, cz1, cx0, y, cz0, cx1, y, cz1, cx1, y, cz0);
7720
+ for (let k = 0;k < 6; k++)
7721
+ b.col.push(...rgba);
7722
+ }
7723
+ }
7472
7724
  const [x0, y0, z0, x1, y1, z1] = out.bbox;
7473
7725
  let ax0 = Infinity, ax1 = -Infinity, az0 = Infinity, az1 = -Infinity;
7474
7726
  for (const b of [out.body, out.under])
@@ -7694,6 +7946,7 @@ class Compiler {
7694
7946
  }
7695
7947
  }
7696
7948
  }
7949
+ var OPEN_BOTTOM = { "11477.dat": [-10, -20, 10, 20] };
7697
7950
  function underEnclosed(c) {
7698
7951
  const u = c.under.pos;
7699
7952
  let uy0 = Infinity, uy1 = -Infinity, ux0 = Infinity, ux1 = -Infinity, uz0 = Infinity, uz1 = -Infinity;
@@ -8110,7 +8363,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
8110
8363
  return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
8111
8364
  }
8112
8365
 
8113
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/build-pack.ts
8366
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/build-pack.ts
8114
8367
  function packCompilerOpts(o) {
8115
8368
  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 } : {} };
8116
8369
  }
@@ -8182,7 +8435,7 @@ function buildPack(o) {
8182
8435
  const warnings = [...lib.conflicts].map((n) => `${n}: defined differently by two models; the first definition is used`);
8183
8436
  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 } : {} };
8184
8437
  }
8185
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/node/promote.ts
8438
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/node/promote.ts
8186
8439
  var GEOM = /^\s*[2-5]\s/;
8187
8440
  var REF = /^\s*1\s/;
8188
8441
  var FILE = /^\s*0\s+FILE\s+(\S.*?)\s*$/i;
@@ -8511,6 +8764,7 @@ export {
8511
8764
  splitModel,
8512
8765
  stepKey,
8513
8766
  stepViewMatrix,
8767
+ studDecalUniforms,
8514
8768
  texWrapper,
8515
8769
  texmapTriangleUV,
8516
8770
  texmapUV,