ldr 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/spec.ts
1
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/spec.ts
2
2
  var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
3
3
  function parseColor(tok) {
4
4
  if (/^0x/i.test(tok))
@@ -690,7 +690,7 @@ function fileStepViews(f) {
690
690
  viewMemo.set(f, out);
691
691
  return out;
692
692
  }
693
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/model.ts
693
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/model.ts
694
694
  var CALLOUT_END = 999999;
695
695
  var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
696
696
  function flatten(doc, opts = {}) {
@@ -848,7 +848,7 @@ function parseLDConfig(text) {
848
848
  }
849
849
  return out;
850
850
  }
851
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/instructions.ts
851
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/instructions.ts
852
852
  var MIN_VIS = 0.5;
853
853
  var REORIENT = 0.35;
854
854
  var deg = Math.PI / 180;
@@ -1216,10 +1216,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
1216
1216
  }
1217
1217
  };
1218
1218
  }
1219
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/render.ts
1219
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/render.ts
1220
1220
  import * as THREE from "three";
1221
1221
 
1222
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/pack-io.ts
1222
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/pack-io.ts
1223
1223
  import { decompress } from "fzstd";
1224
1224
  async function decompressPack(data) {
1225
1225
  const u = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -1238,7 +1238,7 @@ function decodePack(buf) {
1238
1238
  return { header, arr, bytes: buf.byteLength, buffer: buf };
1239
1239
  }
1240
1240
 
1241
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/cull.ts
1241
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/cull.ts
1242
1242
  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;
1243
1243
  var prepCache = new WeakMap;
1244
1244
  function prepPart(H, part) {
@@ -1555,7 +1555,7 @@ function precomputeCull(instances, H, useTex = true) {
1555
1555
  return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
1556
1556
  }
1557
1557
 
1558
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/render.ts
1558
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/render.ts
1559
1559
  async function loadPack(url) {
1560
1560
  const res = await fetch(url);
1561
1561
  if (!res.ok)
@@ -1620,7 +1620,9 @@ function makeMaterial(side) {
1620
1620
  m.onBeforeCompile = (s) => {
1621
1621
  s.vertexShader = `attribute vec4 ldrColor;
1622
1622
  ` + s.vertexShader.replace("#include <color_vertex>", `#include <color_vertex>
1623
- #ifdef USE_INSTANCING_COLOR
1623
+ #ifdef USE_BATCHING_COLOR
1624
+ vColor.rgb = ldrColor.a > 0.5 ? pow(ldrColor.rgb, vec3(2.2)) : getBatchingColor(getIndirectIndex(gl_DrawID)).rgb;
1625
+ #elif defined(USE_INSTANCING_COLOR)
1624
1626
  vColor.rgb = ldrColor.a > 0.5 ? pow(ldrColor.rgb, vec3(2.2)) : instanceColor.rgb; // baked LDConfig colours are sRGB
1625
1627
  #else
1626
1628
  vColor.rgb = pow(ldrColor.rgb, vec3(2.2));
@@ -1996,6 +1998,24 @@ class LdrLodRoot extends THREE.LOD {
1996
1998
  L = -1;
1997
1999
  if (c.boxErr !== undefined && c.boxErr * ppl <= tau)
1998
2000
  L = -1;
2001
+ if (c.mergedLod && L >= 0) {
2002
+ const { bm, gids, errs, underHid, cullUnder } = c.mergedLod;
2003
+ for (let i = 0;i < gids.length; i++) {
2004
+ let Li = 0;
2005
+ const er = errs[i];
2006
+ for (let j = er.length - 1;j > 0; j--)
2007
+ if (er[j] * ppl <= tau) {
2008
+ Li = j;
2009
+ break;
2010
+ }
2011
+ const gd = gids[i];
2012
+ if (gd?.length)
2013
+ bm.setGeometryIdAt(i, gd[Math.min(Li, gd.length - 1)]);
2014
+ if (underHid && !bm.userData._stepMode)
2015
+ bm.setVisibleAt(i, !(cullUnder && underHid[i]));
2016
+ }
2017
+ L = 0;
2018
+ }
1999
2019
  const e = ppl >= eppl;
2000
2020
  if (L !== c.cur || e !== c.edgeOk) {
2001
2021
  c.cur = L;
@@ -2193,6 +2213,7 @@ function buildLdrScene(insts, pack, P, color, mark) {
2193
2213
  let cull = P.cull ?? cullCore(insts, H, steps);
2194
2214
  mark("culling");
2195
2215
  const stepBatches = [];
2216
+ const stepBatched = [];
2196
2217
  const instM = steps ? new Float64Array(insts.length * 12) : null;
2197
2218
  const instPP = [];
2198
2219
  const palette = [];
@@ -2315,96 +2336,306 @@ function buildLdrScene(insts, pack, P, color, mark) {
2315
2336
  });
2316
2337
  const tris = (b) => b ? b.tris ?? 0 : 0;
2317
2338
  const kFor = (t) => LOD ? Math.max(256, Math.min(16384, Math.round(262144 / Math.max(1, t)))) : Infinity;
2339
+ const MERGE_MAX = 16;
2340
+ const geomVerts = (b) => {
2341
+ if (!b)
2342
+ return 0;
2343
+ const p = arr(b.pos);
2344
+ return p.length / 3;
2345
+ };
2346
+ const geomIdx = (b) => {
2347
+ if (!b)
2348
+ return 0;
2349
+ if (!b.idx)
2350
+ return geomVerts(b);
2351
+ return arr(b.idx).length;
2352
+ };
2353
+ const coldByMat = new Map;
2318
2354
  for (const [pk, idsAll] of byPart) {
2319
2355
  const part = pk.replace(/#m$/, "");
2320
2356
  const p = H.parts[part];
2321
2357
  const mat = p.uncert ? (nUncert++, matD) : pk.endsWith("#m") ? matB : matF;
2322
2358
  const textured = wantTex && !!p.tex;
2323
- const bodyB = textured ? p.tbody : p.body;
2324
- const body = geom(bodyB, arr);
2325
- const groups = gridClusters(idsAll.length, (i) => insts[idsAll[i]].m[0], (i) => insts[idsAll[i]].m[2], textured ? Infinity : kFor(tris(p.body) + tris(p.under)));
2326
- for (const g of groups) {
2327
- const ids = Array.from(g, (i) => idsAll[i]);
2328
- let bodyIm = null;
2329
- const lv0 = [];
2330
- const place = (im) => {
2331
- fillInstances(im, ids, insts, color);
2332
- instancedBoundingSphere(im);
2333
- im.userData.ldrPart = part;
2334
- root.add(im);
2335
- };
2336
- if (body) {
2337
- const im = bodyIm = newIM(body, mat, ids.length);
2338
- place(im);
2339
- lv0.push(im);
2340
- }
2341
- if (textured)
2342
- for (const tb of p.tex) {
2343
- const gg = geom(tb, arr);
2344
- const im = newIM(gg, texMat(tb.t, mat, !!tb.wrapU), ids.length);
2345
- texBatches++;
2359
+ if (textured || idsAll.length > MERGE_MAX || EDGES) {
2360
+ const bodyB = textured ? p.tbody : p.body;
2361
+ const body = geom(bodyB, arr);
2362
+ const groups = gridClusters(idsAll.length, (i) => insts[idsAll[i]].m[0], (i) => insts[idsAll[i]].m[2], textured ? Infinity : kFor(tris(p.body) + tris(p.under)));
2363
+ for (const g of groups) {
2364
+ const ids = Array.from(g, (i) => idsAll[i]);
2365
+ let bodyIm = null;
2366
+ const lv0 = [];
2367
+ const place = (im) => {
2368
+ fillInstances(im, ids, insts, color);
2369
+ instancedBoundingSphere(im);
2370
+ im.userData.ldrPart = part;
2371
+ root.add(im);
2372
+ };
2373
+ if (body) {
2374
+ const im = bodyIm = newIM(body, mat, ids.length);
2375
+ place(im);
2346
2376
  lv0.push(im);
2347
- if (bodyIm) {
2348
- im.instanceMatrix = bodyIm.instanceMatrix;
2349
- im.instanceColor = bodyIm.instanceColor;
2350
- im.boundingSphere = bodyIm.boundingSphere;
2351
- root.add(im);
2352
- } else {
2353
- place(im);
2354
- bodyIm = im;
2377
+ }
2378
+ if (textured)
2379
+ for (const tb of p.tex) {
2380
+ const gg = geom(tb, arr);
2381
+ const im = newIM(gg, texMat(tb.t, mat, !!tb.wrapU), ids.length);
2382
+ texBatches++;
2383
+ lv0.push(im);
2384
+ if (bodyIm) {
2385
+ im.instanceMatrix = bodyIm.instanceMatrix;
2386
+ im.instanceColor = bodyIm.instanceColor;
2387
+ im.boundingSphere = bodyIm.boundingSphere;
2388
+ root.add(im);
2389
+ } else {
2390
+ place(im);
2391
+ bodyIm = im;
2392
+ }
2393
+ }
2394
+ if (bodyIm) {
2395
+ const cl = newCluster(bodyIm.boundingSphere);
2396
+ lv0.forEach((o) => o.onBeforeRender = trackVp);
2397
+ cl.lv.push({ objs: lv0, err: 0 }, ...textured ? [] : lodLevels(p.body, bodyIm, mat));
2398
+ if (EDGES && p.edges)
2399
+ addLines(p.edges, bodyIm, cl);
2400
+ addCond(p, bodyIm, cl);
2401
+ if (steps)
2402
+ stepBatches.push({ im: bodyIm, objs: [...cl.lv.flatMap((l) => l.objs), ...cl.lines, ...cl.cond], own: Int32Array.from(ids, (id) => steps[id]), hide: null, flag: "body", inst: Int32Array.from(ids), stud: null, col: Uint16Array.from(ids, (id) => instCol[id]) });
2403
+ }
2404
+ const under = geom(p.under, arr);
2405
+ const uGroups = !under ? [] : LOD && P.lodUnder !== false ? undersideGroups(ids, insts) : [{ ids, ax: null }];
2406
+ for (const { ids: uids, ax } of uGroups) {
2407
+ const ord = [...uids.filter((i) => !cull.underHidden[i]), ...uids.filter((i) => cull.underHidden[i])];
2408
+ const vis = uids.length - uids.reduce((a, i) => a + cull.underHidden[i], 0);
2409
+ stats.undersTotal += uids.length;
2410
+ stats.undersHidden += uids.length - vis;
2411
+ const im = newIM(under, mat, uids.length);
2412
+ fillInstances(im, ord, insts, color);
2413
+ im.onBeforeRender = trackVp;
2414
+ im.userData.ldrUnder = true;
2415
+ im.userData.ldrPart = part;
2416
+ instancedBoundingSphere(im);
2417
+ im.count = P.cullUnder ? vis : uids.length;
2418
+ root.add(im);
2419
+ const cl = newCluster(im.boundingSphere);
2420
+ cl.lv.push({ objs: [im], err: 0 }, ...lodLevels(p.under, im, mat));
2421
+ {
2422
+ const bl = p.body?.lod;
2423
+ const last = bl?.[bl.length - 1];
2424
+ if (LOD && P.lodUnder !== false && last && last.tris === 12)
2425
+ cl.boxErr = last.err;
2355
2426
  }
2427
+ if (ax) {
2428
+ let below = Infinity;
2429
+ for (const id of uids) {
2430
+ const m = insts[id].m;
2431
+ below = Math.min(below, m[0] * ax[0] + m[1] * ax[1] + m[2] * ax[2] + p.bbox[4] * ax[3]);
2432
+ }
2433
+ cl.below = below;
2434
+ cl.ax = ax.slice(0, 3);
2435
+ }
2436
+ addCond(p, im, cl, "under");
2437
+ const objs = [...cl.lv.flatMap((l) => l.objs), ...cl.cond];
2438
+ objs.forEach((o) => {
2439
+ if (!o.isInstancedMesh)
2440
+ o.geometry.instanceCount = im.count;
2441
+ });
2442
+ toggles.push({ mesh: countTo(() => objs), all: uids.length, visible: vis, flag: "under" });
2443
+ if (steps)
2444
+ stepBatches.push({ im, objs, own: Int32Array.from(ord, (id) => steps[id]), hide: Int32Array.from(ord, (id) => cull.underHideStep[id]), flag: "under", inst: Int32Array.from(ord), stud: null, col: Uint16Array.from(ord, (id) => instCol[id]) });
2445
+ }
2446
+ }
2447
+ } else {
2448
+ const list = coldByMat.get(mat) || coldByMat.set(mat, []).get(mat);
2449
+ list.push({ part, p, mat, ids: idsAll });
2450
+ }
2451
+ }
2452
+ const tmpM = new THREE.Matrix4;
2453
+ const tmpC = new THREE.Color;
2454
+ for (const [mat, items] of coldByMat) {
2455
+ const entries = [];
2456
+ for (const it of items)
2457
+ for (const id of it.ids)
2458
+ entries.push({ id, part: it.part, p: it.p });
2459
+ if (!entries.length)
2460
+ continue;
2461
+ const groups = gridClusters(entries.length, (i) => insts[entries[i].id].m[0], (i) => insts[entries[i].id].m[2], LOD ? 256 : Infinity);
2462
+ for (const g of groups) {
2463
+ const members = Array.from(g, (i) => entries[i]);
2464
+ const partSet = new Map;
2465
+ for (const m of members)
2466
+ partSet.set(m.part, m.p);
2467
+ let maxV = 0, maxI = 0;
2468
+ for (const p of partSet.values()) {
2469
+ for (const b of [p.body, ...p.body?.lod ?? []]) {
2470
+ maxV += geomVerts(b);
2471
+ maxI += geomIdx(b);
2472
+ }
2473
+ }
2474
+ if (maxV === 0)
2475
+ continue;
2476
+ const bm = new THREE.BatchedMesh(members.length, Math.max(1, maxV), Math.max(1, maxI), mat);
2477
+ bm.perObjectFrustumCulled = true;
2478
+ bm.sortObjects = false;
2479
+ bm.frustumCulled = true;
2480
+ bm.userData.ldrMerged = true;
2481
+ bm.onBeforeRender = trackVp;
2482
+ root.add(bm);
2483
+ const gidsByPart = new Map;
2484
+ for (const [part, p] of partSet) {
2485
+ const body = geom(p.body, arr);
2486
+ if (!body) {
2487
+ gidsByPart.set(part, []);
2488
+ continue;
2356
2489
  }
2357
- if (bodyIm) {
2358
- const cl = newCluster(bodyIm.boundingSphere);
2359
- lv0.forEach((o) => o.onBeforeRender = trackVp);
2360
- cl.lv.push({ objs: lv0, err: 0 }, ...textured ? [] : lodLevels(p.body, bodyIm, mat));
2361
- if (EDGES && p.edges)
2362
- addLines(p.edges, bodyIm, cl);
2363
- addCond(p, bodyIm, cl);
2364
- if (steps)
2365
- stepBatches.push({ im: bodyIm, objs: [...cl.lv.flatMap((l) => l.objs), ...cl.lines, ...cl.cond], own: Int32Array.from(ids, (id) => steps[id]), hide: null, flag: "body", inst: Int32Array.from(ids), stud: null, col: Uint16Array.from(ids, (id) => instCol[id]) });
2490
+ const ids = [bm.addGeometry(body)];
2491
+ if (LOD && p.body?.lod)
2492
+ for (const l of p.body.lod)
2493
+ ids.push(bm.addGeometry(geom(l, arr)));
2494
+ gidsByPart.set(part, ids);
2366
2495
  }
2367
- const under = geom(p.under, arr);
2368
- const uGroups = !under ? [] : LOD && P.lodUnder !== false ? undersideGroups(ids, insts) : [{ ids, ax: null }];
2369
- for (const { ids: uids, ax } of uGroups) {
2370
- const ord = [...uids.filter((i) => !cull.underHidden[i]), ...uids.filter((i) => cull.underHidden[i])];
2371
- const vis = uids.length - uids.reduce((a, i) => a + cull.underHidden[i], 0);
2372
- stats.undersTotal += uids.length;
2373
- stats.undersHidden += uids.length - vis;
2374
- const im = newIM(under, mat, uids.length);
2375
- fillInstances(im, ord, insts, color);
2376
- im.onBeforeRender = trackVp;
2377
- im.userData.ldrUnder = true;
2378
- im.userData.ldrPart = part;
2379
- instancedBoundingSphere(im);
2380
- im.count = P.cullUnder ? vis : uids.length;
2381
- root.add(im);
2382
- const cl = newCluster(im.boundingSphere);
2383
- cl.lv.push({ objs: [im], err: 0 }, ...lodLevels(p.under, im, mat));
2384
- {
2385
- const bl = p.body?.lod;
2386
- const last = bl?.[bl.length - 1];
2387
- if (LOD && P.lodUnder !== false && last && last.tris === 12)
2388
- cl.boxErr = last.err;
2496
+ const live = members.filter((m) => (gidsByPart.get(m.part)?.length ?? 0) > 0);
2497
+ const instGids = new Array(live.length);
2498
+ const ownArr = steps ? new Int32Array(live.length) : null;
2499
+ const instArr = steps ? new Int32Array(live.length) : null;
2500
+ const m16 = new Float32Array(16);
2501
+ for (let i = 0;i < live.length; i++) {
2502
+ const { id, part, p } = live[i];
2503
+ const gids = gidsByPart.get(part);
2504
+ const iid = bm.addInstance(gids[0]);
2505
+ writeM4(m16, 0, insts[id].m);
2506
+ tmpM.fromArray(m16);
2507
+ bm.setMatrixAt(iid, tmpM);
2508
+ tmpC.copy(color(insts[id].color));
2509
+ bm.setColorAt(iid, tmpC);
2510
+ instGids[iid] = gids;
2511
+ if (ownArr) {
2512
+ ownArr[iid] = steps[id];
2513
+ instArr[iid] = id;
2389
2514
  }
2390
- if (ax) {
2391
- let below = Infinity;
2392
- for (const id of uids) {
2393
- const m = insts[id].m;
2394
- below = Math.min(below, m[0] * ax[0] + m[1] * ax[1] + m[2] * ax[2] + p.bbox[4] * ax[3]);
2515
+ }
2516
+ members.length = 0;
2517
+ members.push(...live);
2518
+ bm.computeBoundingSphere();
2519
+ const cl = newCluster(bm.boundingSphere ?? new THREE.Sphere);
2520
+ const bodyErrs = live.map(({ p }) => [0, ...(p.body?.lod ?? []).map((l) => l.err)]);
2521
+ bm.userData.ldrMergeGids = instGids;
2522
+ cl.mergedLod = { bm, gids: instGids, errs: bodyErrs };
2523
+ cl.setMergedLevel = (L) => {
2524
+ bm.visible = L >= 0;
2525
+ };
2526
+ cl.lv.push({ objs: [bm], err: 0 });
2527
+ if (steps && ownArr)
2528
+ stepBatched.push({ bm, own: ownArr, hide: null, flag: "body", inst: instArr });
2529
+ const withUnder = members.filter((m) => m.p.under);
2530
+ if (withUnder.length) {
2531
+ const uEntries = withUnder.map((m) => m.id);
2532
+ const uGroups = LOD && P.lodUnder !== false ? undersideGroups(uEntries, insts) : [{ ids: uEntries, ax: null }];
2533
+ for (const { ids: uids, ax } of uGroups) {
2534
+ const byId = new Map(members.map((m) => [m.id, m]));
2535
+ const umembers = uids.map((id) => {
2536
+ const m = byId.get(id);
2537
+ return { ...m, hid: !!cull.underHidden[id] };
2538
+ });
2539
+ stats.undersTotal += umembers.length;
2540
+ stats.undersHidden += umembers.filter((m) => m.hid).length;
2541
+ const uPartSet = new Map;
2542
+ for (const m of umembers)
2543
+ uPartSet.set(m.part, m.p);
2544
+ let uV = 0, uI = 0;
2545
+ for (const p of uPartSet.values())
2546
+ for (const b of [p.under, ...p.under?.lod ?? []]) {
2547
+ uV += geomVerts(b);
2548
+ uI += geomIdx(b);
2549
+ }
2550
+ if (!uV)
2551
+ continue;
2552
+ const ubm = new THREE.BatchedMesh(umembers.length, Math.max(1, uV), Math.max(1, uI), mat);
2553
+ ubm.perObjectFrustumCulled = true;
2554
+ ubm.sortObjects = false;
2555
+ ubm.frustumCulled = true;
2556
+ ubm.userData.ldrMerged = true;
2557
+ ubm.userData.ldrUnder = true;
2558
+ ubm.onBeforeRender = trackVp;
2559
+ root.add(ubm);
2560
+ const uGidsByPart = new Map;
2561
+ for (const [part, p] of uPartSet) {
2562
+ const u = geom(p.under, arr);
2563
+ if (!u) {
2564
+ uGidsByPart.set(part, []);
2565
+ continue;
2566
+ }
2567
+ const ids = [ubm.addGeometry(u)];
2568
+ if (LOD && p.under?.lod)
2569
+ for (const l of p.under.lod)
2570
+ ids.push(ubm.addGeometry(geom(l, arr)));
2571
+ uGidsByPart.set(part, ids);
2572
+ }
2573
+ const uLive = umembers.filter((m) => (uGidsByPart.get(m.part)?.length ?? 0) > 0);
2574
+ const uInstGids = new Array(uLive.length);
2575
+ const uOwn = steps ? new Int32Array(uLive.length) : null;
2576
+ const uInst = steps ? new Int32Array(uLive.length) : null;
2577
+ const uHide = steps ? new Int32Array(uLive.length) : null;
2578
+ const uHid = new Uint8Array(uLive.length);
2579
+ for (let i = 0;i < uLive.length; i++) {
2580
+ const { id, part, p, hid } = uLive[i];
2581
+ const gids = uGidsByPart.get(part);
2582
+ const iid = ubm.addInstance(gids[0]);
2583
+ writeM4(m16, 0, insts[id].m);
2584
+ tmpM.fromArray(m16);
2585
+ ubm.setMatrixAt(iid, tmpM);
2586
+ tmpC.copy(color(insts[id].color));
2587
+ ubm.setColorAt(iid, tmpC);
2588
+ uInstGids[iid] = gids;
2589
+ uHid[iid] = hid ? 1 : 0;
2590
+ if (P.cullUnder && hid)
2591
+ ubm.setVisibleAt(iid, false);
2592
+ if (uOwn) {
2593
+ uOwn[iid] = steps[id];
2594
+ uInst[iid] = id;
2595
+ uHide[iid] = cull.underHideStep[id];
2596
+ }
2597
+ }
2598
+ umembers.length = 0;
2599
+ umembers.push(...uLive);
2600
+ ubm.computeBoundingSphere();
2601
+ const ucl = newCluster(ubm.boundingSphere ?? new THREE.Sphere);
2602
+ const uErrs = uLive.map(({ p }) => [0, ...(p.under?.lod ?? []).map((l) => l.err)]);
2603
+ ubm.userData._stepMode = !!steps;
2604
+ ubm.userData.ldrMergeGids = uInstGids;
2605
+ ucl.mergedLod = { bm: ubm, gids: uInstGids, errs: uErrs, underHid: uHid, cullUnder: !!P.cullUnder };
2606
+ ucl.setMergedLevel = (L) => {
2607
+ ubm.visible = L >= 0;
2608
+ };
2609
+ ucl.lv.push({ objs: [ubm], err: 0 });
2610
+ {
2611
+ const sample = umembers[0]?.p;
2612
+ const bl = sample?.body?.lod;
2613
+ const last = bl?.[bl.length - 1];
2614
+ if (LOD && P.lodUnder !== false && last && last.tris === 12)
2615
+ ucl.boxErr = last.err;
2616
+ }
2617
+ if (ax) {
2618
+ let below = Infinity;
2619
+ for (const { id, p } of umembers) {
2620
+ const m = insts[id].m;
2621
+ below = Math.min(below, m[0] * ax[0] + m[1] * ax[1] + m[2] * ax[2] + p.bbox[4] * ax[3]);
2622
+ }
2623
+ ucl.below = below;
2624
+ ucl.ax = ax.slice(0, 3);
2395
2625
  }
2396
- cl.below = below;
2397
- cl.ax = ax.slice(0, 3);
2626
+ toggles.push({
2627
+ mesh: { set count(n) {
2628
+ const showAll = n >= umembers.length;
2629
+ for (let i = 0;i < uHid.length; i++)
2630
+ ubm.setVisibleAt(i, showAll || !uHid[i]);
2631
+ } },
2632
+ all: umembers.length,
2633
+ visible: umembers.length - umembers.filter((m) => m.hid).length,
2634
+ flag: "under"
2635
+ });
2636
+ if (steps && uOwn)
2637
+ stepBatched.push({ bm: ubm, own: uOwn, hide: uHide, flag: "under", inst: uInst, underHidden: uHid });
2398
2638
  }
2399
- addCond(p, im, cl, "under");
2400
- const objs = [...cl.lv.flatMap((l) => l.objs), ...cl.cond];
2401
- objs.forEach((o) => {
2402
- if (!o.isInstancedMesh)
2403
- o.geometry.instanceCount = im.count;
2404
- });
2405
- toggles.push({ mesh: countTo(() => objs), all: uids.length, visible: vis, flag: "under" });
2406
- if (steps)
2407
- stepBatches.push({ im, objs, own: Int32Array.from(ord, (id) => steps[id]), hide: Int32Array.from(ord, (id) => cull.underHideStep[id]), flag: "under", inst: Int32Array.from(ord), stud: null, col: Uint16Array.from(ord, (id) => instCol[id]) });
2408
2639
  }
2409
2640
  }
2410
2641
  }
@@ -2445,11 +2676,14 @@ function buildLdrScene(insts, pack, P, color, mark) {
2445
2676
  stats.uncertBatches = nUncert;
2446
2677
  let condOn = true, edgesOn = true;
2447
2678
  root.apply = (c) => {
2448
- c.lv.forEach((l, i) => {
2449
- for (const o of l.objs)
2450
- o.visible = i === c.cur;
2451
- });
2452
- const lineVis = edgesOn && c.edgeOk && c.cur >= 0 && (c.cur === 0 || !LOD || c.lv[c.cur].objs.length > 0);
2679
+ if (c.setMergedLevel)
2680
+ c.setMergedLevel(c.cur);
2681
+ else
2682
+ c.lv.forEach((l, i) => {
2683
+ for (const o of l.objs)
2684
+ o.visible = i === c.cur;
2685
+ });
2686
+ const lineVis = edgesOn && c.edgeOk && c.cur >= 0 && (c.cur === 0 || !LOD || (c.setMergedLevel ? true : c.lv[c.cur].objs.length > 0));
2453
2687
  for (const o of c.lines)
2454
2688
  o.visible = lineVis;
2455
2689
  for (const o of c.cond)
@@ -2516,6 +2750,20 @@ function buildLdrScene(insts, pack, P, color, mark) {
2516
2750
  o.geometry.instanceCount = w;
2517
2751
  }
2518
2752
  }
2753
+ for (const b of stepBatched) {
2754
+ const useHide = b.flag === "under" ? cullU : false;
2755
+ const { own, hide, inst, bm } = b;
2756
+ for (let i = 0;i < own.length; i++) {
2757
+ const hid = !!hide && hide[i] <= S;
2758
+ if (b.flag === "under") {
2759
+ st.undersTotal++;
2760
+ if (hid)
2761
+ st.undersHidden++;
2762
+ }
2763
+ const on = own[i] <= S && !(useHide && hid) && !(O && !O[inst[i]]);
2764
+ bm.setVisibleAt(i, on);
2765
+ }
2766
+ }
2519
2767
  return st;
2520
2768
  };
2521
2769
  const setCull = (studs, under) => {
@@ -2571,6 +2819,12 @@ function buildLdrScene(insts, pack, P, color, mark) {
2571
2819
  c.edgeOk = true;
2572
2820
  for (const l of c.lines)
2573
2821
  l.geometry.drawRange.count = Infinity;
2822
+ if (c.mergedLod) {
2823
+ const { bm, gids } = c.mergedLod;
2824
+ for (let i = 0;i < gids.length; i++)
2825
+ if (gids[i]?.length)
2826
+ bm.setGeometryIdAt(i, gids[i][0]);
2827
+ }
2574
2828
  }
2575
2829
  refresh();
2576
2830
  }
@@ -2602,7 +2856,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
2602
2856
  await new Promise((r) => setTimeout(r, 0));
2603
2857
  }
2604
2858
  }
2605
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/scene.ts
2859
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/scene.ts
2606
2860
  import * as THREE2 from "three";
2607
2861
  function colorFn(src, pack, fallback) {
2608
2862
  const table = new Map;
@@ -2758,10 +3012,10 @@ function createLdrObject(instances, pack, options = {}) {
2758
3012
  dispose: disposeCur
2759
3013
  });
2760
3014
  }
2761
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/parts-cdn.ts
3015
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/parts-cdn.ts
2762
3016
  import { decompress as decompress2 } from "fzstd";
2763
3017
 
2764
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/embedded.ts
3018
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/embedded.ts
2765
3019
  function splitFiles(text, fallback) {
2766
3020
  const files = new Map;
2767
3021
  let cur = null, saw = false;
@@ -2833,7 +3087,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
2833
3087
  return out;
2834
3088
  }
2835
3089
 
2836
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/parts-cdn.ts
3090
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/parts-cdn.ts
2837
3091
  var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
2838
3092
  var indexCache = new Map;
2839
3093
  var shardCache = new Map;
@@ -2993,10 +3247,10 @@ async function prepareModel(source, o = {}) {
2993
3247
  return { insts, pack, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
2994
3248
  }
2995
3249
 
2996
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/load-worker.gen.ts
3250
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/load-worker.gen.ts
2997
3251
  var load_worker_gen_default = 'var ht=ArrayBuffer,X=Uint8Array,ge=Uint16Array,gt=Int16Array;var be=Int32Array,Se=function(e,t,n){if(X.prototype.slice)return X.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 X(n-t);return r.set(e.subarray(t,n)),r},ce=function(e,t,n,r){if(X.prototype.fill)return X.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},bt=function(e,t,n,r){if(X.prototype.copyWithin)return X.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var dt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],W=function(e,t,n){var r=Error(t||dt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,W);if(!n)throw r;return r},Be=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},yt=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},xt=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,l=r>>6;if(r&8)W(0);var a=6-s,c=i==3?4:i,p=Be(e,a,c);a+=c;var m=l?1<<l:s,h=Be(e,a,m)+(l==1&&256),d=h;if(!s){var S=1<<10+(e[5]>>3);d=S+(S>>3)*(e[5]&7)}if(d>2145386496)W(1);var u=new X((t==1?h||d:t?0:d)+12);return u[0]=1,u[4]=4,u[8]=8,{b:a+m,y:0,l:0,d:p,w:t&&t!=1?t:u.subarray(12),e:d,o:new be(u.buffer,0,3),u:h,c:o,m:Math.min(131072,d)}}else if((n>>4|e[3]<<20)==25481893)return yt(e,4)+8;W(0)},re=function(e){var t=0;for(;1<<t<=e;++t);return t-1},ue=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)W(3);var o=1<<s,i=o,l=-1,a=-1,c=-1,p=o,m=new ht(512+(o<<2)),h=new gt(m,0,256),d=new ge(m,0,256),S=new ge(m,512,o),u=512+(o<<1),b=new X(m,u,o),P=new X(m,u+o);while(l<255&&i>0){var g=re(i+1),f=r>>3,A=(1<<g+1)-1,O=(e[f]|e[f+1]<<8|e[f+2]<<16)>>(r&7)&A,y=(1<<g)-1,M=A-i-1,E=O&y;if(E<M)r+=g,O=E;else if(r+=g+1,O>y)O-=M;if(h[++l]=--O,O==-1)i+=O,b[--p]=l;else i-=O;if(!O)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,l+=a}while(a==3)}if(l>255||i)W(0);var C=0,U=(o>>1)+(o>>3)+3,_=o-1;for(var H=0;H<=l;++H){var v=h[H];if(v<1){d[H]=-v;continue}for(c=0;c<v;++c){b[C]=H;do C=C+U&_;while(C>=p)}}if(C)W(0);for(c=0;c<o;++c){var w=d[b[c]]++,L=P[c]=s-re(w);S[c]=(w<<L)-o}return[r+7>>3,{b:s,s:b,n:P,t:S}]},wt=function(e,t){var n=0,r=-1,s=new X(292),o=e[t],i=s.subarray(0,256),l=s.subarray(256,268),a=new ge(s.buffer,268);if(o<128){var c=ue(e,t+1,6),p=c[0],m=c[1];t+=o;var h=p<<3,d=e[t];if(!d)W(0);var S=0,u=0,b=m.b,P=b,g=(++t<<3)-8+re(d);for(;;){if(g-=b,g<h)break;var f=g>>3;if(S+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<b)-1,i[++r]=m.s[S],g-=P,g<h)break;f=g>>3,u+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<P)-1,i[++r]=m.s[u],b=m.n[S],S=m.t[S],P=m.n[u],u=m.t[u]}if(++r>255)W(0)}else{r=o-127;for(;n<r;n+=2){var A=e[++t];i[n]=A>>4,i[n+1]=A&15}++t}var O=0;for(n=0;n<r;++n){var y=i[n];if(y>11)W(0);O+=y&&1<<y-1}var M=re(O)+1,E=1<<M,D=E-O;if(D&D-1)W(0);i[r++]=re(D)+1;for(n=0;n<r;++n){var y=i[n];++l[i[n]=y&&M+1-y]}var C=new X(E<<1),U=C.subarray(0,E),_=C.subarray(E);a[M]=0;for(n=M;n>0;--n){var H=a[n];ce(_,n,H,a[n-1]=H+l[n]*(1<<M-n))}if(a[0]!=E)W(0);for(n=0;n<r;++n){var v=i[n];if(v){var w=a[v];ce(U,n,w,a[v]=w+(1<<M-v))}}return[t,{n:_,b:M,s:U}]},At=ue(new X([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],vt=ue(new X([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],Mt=ue(new X([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],$e=function(e,t){var n=e.length,r=new be(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Ce=new X(new be([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),St=$e(Ce,0),Pe=new X(new be([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),Ct=$e(Pe,3),le=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,l=-n.b;if(!o)W(0);var a=0,c=n.b,p=(r<<3)-8+re(o)-c,m=-1;for(;p>l&&m<s;){var h=p>>3,d=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(p&7);a=(a<<c|d)&i,t[++m]=n.s[a],p-=c=n.n[a]}if(p!=l||m+1!=s)W(0)},Pt=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,l=o+i;le(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),le(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),le(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,l),n),le(e.subarray(r),t.subarray(l),n)},Et=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var l=o>>3|e[s+1]<<5|e[s+2]<<13,a=(s+=3)+l;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return ce(n,e[s],t.y,t.y+=l),n;return ce(new X(l),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+=l,n;return Se(e,s,a)}if(i==2){var c=e[s],p=c&3,m=c>>2&3,h=c>>4,d=0,S=0;if(p<2)if(m&1)h|=e[++s]<<4|(m&2&&e[++s]<<12);else h=c>>3;else if(S=m,m<2)h|=(e[++s]&63)<<4,d=e[s]>>6|e[++s]<<2;else if(m==2)h|=e[++s]<<4|(e[++s]&3)<<12,d=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,d=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var u=n?n.subarray(t.y,t.y+t.m):new X(t.m),b=u.length-h;if(p==0)u.set(e.subarray(s,s+=h),b);else if(p==1)ce(u,e[s++],b);else{var P=t.h;if(p==2){var g=wt(e,s);d+=s-(s=g[0]),t.h=P=g[1]}else if(!P)W(0);(S?Pt:le)(e.subarray(s,s+=d),u.subarray(b),P)}var f=e[s++];if(f){if(f==255)f=(e[s++]|e[s++]<<8)+32512;else if(f>127)f=f-128<<8|e[s++];var A=e[s++];if(A&3)W(0);var O=[vt,Mt,At];for(var y=2;y>-1;--y){var M=A>>(y<<1)+2&3;if(M==1){var E=new X([0,0,e[s++]]);O[y]={s:E.subarray(2,3),n:E.subarray(0,1),t:new ge(E.buffer,0,1),b:0}}else if(M==2)r=ue(e,s,9-(y&1)),s=r[0],O[y]=r[1];else if(M==3){if(!t.t)W(0);O[y]=t.t[y]}}var D=t.t=O,C=D[0],U=D[1],_=D[2],H=e[a-1];if(!H)W(0);var v=(a<<3)-8+re(H)-_.b,w=v>>3,L=0,V=(e[w]|e[w+1]<<8)>>(v&7)&(1<<_.b)-1;w=(v-=U.b)>>3;var I=(e[w]|e[w+1]<<8)>>(v&7)&(1<<U.b)-1;w=(v-=C.b)>>3;var B=(e[w]|e[w+1]<<8)>>(v&7)&(1<<C.b)-1;for(++f;--f;){var T=_.s[V],x=_.n[V],N=C.s[B],F=C.n[B],R=U.s[I],z=U.n[I];w=(v-=R)>>3;var j=1<<R,k=j+((e[w]|e[w+1]<<8|e[w+2]<<16|e[w+3]<<24)>>>(v&7)&j-1);w=(v-=Pe[N])>>3;var G=Ct[N]+((e[w]|e[w+1]<<8|e[w+2]<<16)>>(v&7)&(1<<Pe[N])-1);w=(v-=Ce[T])>>3;var K=St[T]+((e[w]|e[w+1]<<8|e[w+2]<<16)>>(v&7)&(1<<Ce[T])-1);if(w=(v-=x)>>3,V=_.t[V]+((e[w]|e[w+1]<<8)>>(v&7)&(1<<x)-1),w=(v-=F)>>3,B=C.t[B]+((e[w]|e[w+1]<<8)>>(v&7)&(1<<F)-1),w=(v-=z)>>3,I=U.t[I]+((e[w]|e[w+1]<<8)>>(v&7)&(1<<z)-1),k>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=k-=3;else{var Y=k-(K!=0);if(Y){if(k=Y==3?t.o[0]-1:t.o[Y],Y>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=k}else k=t.o[0]}for(var y=0;y<K;++y)u[L+y]=u[b+y];L+=K,b+=K;var q=L-k;if(q<0){var Z=-q,ee=t.e+q;if(Z>G)Z=G;for(var y=0;y<Z;++y)u[L+y]=t.w[ee+y];L+=Z,G-=Z,q=0}for(var y=0;y<G;++y)u[L+y]=u[q+y];L+=G}if(L!=b)while(b<u.length)u[L++]=u[b++];else L=u.length;if(n)t.y+=L;else u=Se(u,0,L)}else if(n){if(t.y+=h,b)for(var y=0;y<h;++y)u[y]=u[b+y]}else if(b)u=Se(u,b);return t.b=a,u}W(2)},Tt=function(e,t){if(e.length==1)return e[0];var n=new X(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=xt(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var l=Et(e,i,t);if(!l)W(5);if(t)i.e=i.y;else n.push(l),o+=l.length,bt(i.w,0,l.length),i.w.set(l,i.w.length-l.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return Tt(n,o)}function de(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 J=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/");function Ee(e){if(/^0x/i.test(e))return parseInt(e,16);return+e}var Ve=/^~?\\s*moved\\s+to\\s+(.+)$/i,Lt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Je=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),It=new Set(["model","submodel","configuration"]),kt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function He(e){let t=kt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Je.has(n)||It.has(n)?n:void 0}function Ft(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 Rt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every(Number.isFinite))return null;let l=n[2].trim();for(let m=0;m<s;m++)l=l.replace(/^\\S+\\s*/,"");let a=Ft(l);if(!a.length)return null;let c={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)c.a=i[9];if(s===11)c.b=i[10];let p=a.findIndex((m,h)=>h>0&&m.toUpperCase()==="GLOSSMAP");if(p>0&&a[p+1])c.glossmap=a[p+1];if(t)c.next=!0;return c}var Dt=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,""),n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function Ut(e){let t=e.length,n=1,r=(c)=>c===32||c===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let c=n;while(n<t&&!r(e.charCodeAt(n)))n++;return c<n?e.slice(c,n):null},o=s();if(o===null)return null;let i=Array(12);for(let c=0;c<12;c++){let p=s();if(p===null)return null;i[c]=+p}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let l=e.slice(n),a=/[ \\t]{2,}|\\t/.test(l)?l.split(/\\s+/).join(" "):l;return{t:1,color:Ee(o),m:i,file:J(a)}}function Ge(e){let t=+e[0];if(!(t>=1&&t<=5)||e.length<2)return null;let n=Ee(e[1]),r=e.slice(2).map(Number);if(t===1)return{t:1,color:n,m:r.slice(0,12),file:J(e.slice(14).join(" "))};if(t===2)return{t:2,color:n,p:r.slice(0,6)};if(t===3)return{t:3,color:n,p:r.slice(0,9)};if(t===4)return{t:4,color:n,p:r.slice(0,12)};return{t:5,color:n,p:r.slice(0,12)}}function Ze(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",l,a=null,c=[],p=null,m=()=>{if(!a)return;let g=Dt(a.chunks.join("")),f=g[0]===137&&g[1]===80&&g[2]===78&&g[3]===71;(l??=new Map).set(J(a.name),{name:a.name,bytes:g,...f?{mime:"image/png"}:{}}),a=null},h=!0,d=(g)=>{if(m(),o={name:J(g),cmds:[]},s.set(o.name,o),!i)i=o.name;c=[],p=null,h=!0},S=!1,u=!1,b=()=>{if(u)return;u=!0,s.clear(),o=null,i=""},P=(g,f)=>{if(p){g.tex=p,p=null;return}let A=c[c.length-1];if(!A)return;if(A.fallback){if(!f)g.fallback=!0}else g.tex=A.map};for(let g of e.split(`\n`)){let f=g.trim();if(!f)continue;if(r&&f.charCodeAt(0)>=50&&f.charCodeAt(0)<=53&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)){if(a||S)continue;if(!o)d(t);let M=f.slice(2).trimStart(),E=M.search(/\\s/),D={t:f.charCodeAt(0)-48,color:Ee(E<0?M:M.slice(0,E)),p:[],src:f};P(D,!1),o.cmds.push(D),h=!1;continue}if(f.charCodeAt(0)===48&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)){let M=2;while(f.charCodeAt(M)===32||f.charCodeAt(M)===9)M++;let E=M;while(E<f.length&&f.charCodeAt(E)!==32&&f.charCodeAt(E)!==9)E++;let D=f.slice(M,E);if(!Lt.has(D)){if(S||a)continue;if(!o)d(t);let C=f.slice(M),U={t:0,text:C};if(D.charCodeAt(0)===33)U.meta=D;if(p=null,h&&!o.org){let H=He(C);if(H)o.org=H}let _=C.match(Ve);if(_&&!o.movedTo){let H=_[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(H))H+=".dat";o.movedTo=J(H)}o.cmds.push(U);continue}}if(f.charCodeAt(0)===49&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)&&!a&&!S){let M=Ut(f);if(M){if(!o)d(t);P(M,!1),o.cmds.push(M),h=!1;continue}}let A=f.split(/\\s+/);if(+A[0]===0){let M=f.slice(1).trim();if(A[1]==="FILE"){b(),S=!1,d(M.slice(5));continue}if(A[1]==="NOFILE"){m(),o=null,S=!0;continue}if(A[1]==="!DATA"){b(),m(),o=null,S=!1,a={name:M.slice(5).trim(),chunks:[]};continue}if(S)continue;if(a){if(A[1]==="!:")a.chunks.push(A.slice(2).join(""));continue}if(!o)d(t);let E={t:0,text:M};if(A[1]==="STEP")E.step=!0,c=[],p=null;else if(A[1]==="BFC")E.bfc=A.slice(2).join(" ");else if(A[1]==="ROTSTEP")if(E.meta="ROTSTEP",E.step=!0,c=[],p=null,(A[2]??"").toUpperCase()==="END")E.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(A[5]??"REL").toUpperCase();E.rotstep={x:+A[2]||0,y:+A[3]||0,z:+A[4]||0,mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(A[1]==="BUFEXCHG"){E.meta="BUFEXCHG";let C=(A[2]??"").toUpperCase();E.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:A[3]??"A"}}else if(A[1]?.startsWith("!"))E.meta=A[1];if(h&&!o.org){let C=He(M);if(C)o.org=C}if(A[1]==="!TEXMAP"){let C=(A[2]??"").toUpperCase();if(p=null,C==="START"||C==="NEXT"){let U=Rt(M.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(E.texmap={op:C,...U?{map:U}:{}},U)if((o.texmaps??=[]).push(U),C==="START")c.push({map:U,fallback:!1});else p=U}else if(C==="FALLBACK"){E.texmap={op:C};let U=c[c.length-1];if(U)U.fallback=!0}else if(C==="END")E.texmap={op:C},c.pop()}else if(A[1]==="!:"){p=null;let C=Ge(A.slice(2));if(C)P(C,!0),E.geom=C}else p=null;let D=M.match(Ve);if(D&&!o.movedTo){let C=D[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=J(C)}o.cmds.push(E);continue}if(a||S)continue;if(!o)d(t);let y=Ge(A);if(!y)continue;P(y,!1),o.cmds.push(y),h=!1}return m(),l?{main:i,files:s,data:l}:{main:i,files:s}}var tn=Math.PI/180;function qe(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 Qe(e,t){let[n,r,s,o,i,l,a,c,p,m,h,d]=e,[S,u,b,P,g,f,A,O,y,M,E,D]=t;return[o*S+i*u+l*b+n,a*S+c*u+p*b+r,m*S+h*u+d*b+s,o*P+i*A+l*M,o*g+i*O+l*E,o*f+i*y+l*D,a*P+c*A+p*M,a*g+c*O+p*E,a*f+c*y+p*D,m*P+h*A+d*M,m*g+h*O+d*E,m*f+h*y+d*D]}var Te=[0,0,0,1,0,0,0,1,0,0,0,1];var Ke=new WeakMap,Ot=/^(s|8|48)\\//;function Le(e,t){let n=e.files.get(J(t));if(!n)return"part";let r=Ke.get(n);if(r)return r;if(n.org)r=Je.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&&Ot.test(s.file))?"part":"model";return Ke.set(n,r),r}var Xe=new WeakMap;function et(e){let t=Xe.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 Xe.set(e,t),t}var We=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():String(e),zt=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${We(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${We(e.color)} ${e.p.join(" ")}`,Ie=(e,t)=>`${J(e)}#${t}`;function Nt(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){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:Ie(e.name,t),cmds:n}}function tt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Nt(e,t).cmds.map(zt)].join(`\n`)+`\n`}function Bt(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,l,a,c,p,m,h]=e,d=a*h-c*m,S=-(l*h-c*p),u=l*m-a*p,b=s*d+o*S+i*u;if(!Number.isFinite(b)||Math.abs(b)<0.000000000001)return null;let P=1/b,g=[d*P,-(o*h-i*m)*P,(o*c-i*a)*P,S*P,(s*h-i*p)*P,-(s*c-i*l)*P,u*P,-(s*m-o*p)*P,(s*a-o*l)*P];return[-(g[0]*t+g[1]*n+g[2]*r),-(g[3]*t+g[4]*n+g[5]*r),-(g[6]*t+g[7]*n+g[8]*r),...g]}var $t=(e)=>String(+e.toFixed(6)||0),_e=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function rt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map($t).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${_e(t.texture)}${t.glossmap?" GLOSSMAP "+_e(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${J(e)}\n0 !TEXMAP END\n`;return{name:`${J(e)}#tex-${Bt(r)}`,source:r}}var jt=(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 Vt(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),l=Math.cos(t*r),a=Math.sin(n*r),c=Math.cos(n*r);return[l*c,-l*a,i,o*a+s*i*c,o*c-s*i*a,-s*l,s*a-o*i*c,s*c+o*i*a,o*l]}var Ye=new WeakMap;function st(e){let t=Ye.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=Vt(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:jt(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),Ye.set(e,n),n}var ot=999999,it=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~";function Ht(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,l=new Map,a=0,c=(m,h)=>{let d=m.name+"#"+h,S=l.get(d);if(!S){let u;S=Object.assign(()=>u??=tt(m,h),{file:m,step:h}),l.set(d,S)}return S},p=(m,h,d,S,u,b,P,g,f=null,A=[],O=[])=>{let y=m.files.get(h);if(!y||P>r)return;let M=0,E=P>0?++a:0,D=i&&E?[...A,E]:A,C=i&&E?[...O,d]:O,U=i&&!f?new Map:null,_=-1,H=0,v=(T,x,N,F,R,z)=>{if(_!==M)_=M,H=0;let j=U?.get(M+"|"+x);if(j)return j.n++,p(T,T===m?x:T.main,N,F,u+"/"+x,[...R,ot],P+1,z,[...R,ot],D,C);let k=[...R,H++],G=n.length;p(T,T===m?x:T.main,N,F,u+"/"+x,k,P+1,z,f,D,C),U?.set(M+"|"+x,{n:1,from:G,to:n.length})},w=st(y),L=s?et(y):[],V=0,I=(T,x,N,F,R,z,j)=>{if(f)F=f;let k={part:T,color:x,m:N,step:F[0],steps:F,localStep:R,path:u};if(E){if(k.sub=E,i)k.subPath=D,k.subMats=C}if(z)k.embedded=!0;if(j){let K=rt(T,j);k.texPart=K.name,k.texSource=K.source}let G=w[R];if(G)k.view=G;return n.push(k),k},B=(T)=>{while(V<L.length&&L[V]<=T){let x=L[V++];I(Ie(y.name,x),S,d,[...b,x],x,!1,null).source=c(y,x)}};for(let T of y.cmds){if(T.t===0&&T.step){M++;continue}let x=T;if(x.t>=2||x.t===0&&x.geom&&x.geom.t>=2){B(M);continue}if(x.t===0)if(o&&x.geom?.t===1)x=x.geom;else continue;if(x.t!==1)continue;if(o&&x.fallback)continue;let N=x.color===16?S:x.color,F=Qe(d,x.m),R=[...b,M],z=o?x.tex??g:null,j=z?nt(x.m):null,k=z&&j?qe(z,j):null;if(m.files.has(x.file)){if(Le(m,x.file)==="model"){v(m,x.file,F,N,R,k);continue}I(x.file,N,F,R,M,!0,k);continue}let G=t.resolveModel?.(x.file);if(G){v(G,x.file,F,N,R,k);continue}I(x.file,N,F,R,M,!1,k)}if(B(1/0),U){for(let T of U.values())if(T.n>1)for(let x=T.from;x<T.to;x++)n[x].mult??=T.n}};if(Le(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Te],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return p(e,e.main,Te,16,e.main,[],0,null),n}function at(e,t="main.ldr",n){return Ht(Ze(e,t,{geometryText:!0}),n)}function Gt(e,t){let n=new Map,r=null,s=!1;for(let o of e.split(/\\r?\\n/)){let i=/^\\s*0\\s+FILE\\s+(.+)$/i.exec(o);if(i){if(!s)n.clear();s=!0,r=[],n.set(J(i[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(o)){if(!s)n.clear();s=!0,r=null;continue}if(!r){if(s)continue;r=[],n.set(J(t),r)}let l=o.trim().replace(/\\s+/g," ");if(l)r.push(l)}return n}var Kt=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?J(t.slice(14).join(" ")):null};function Xt(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function lt(e,t,n="main.ldr"){let r=Gt(e,n),s=new Map;for(let o of t){let i=J(o);if(!r.has(i)||s.has(i))continue;let l=new Set([i]),a=[i];while(a.length)for(let p of r.get(a.pop())){let m=Kt(p);if(m&&r.has(m)&&!l.has(m))l.add(m),a.push(m)}let c=[i,...[...l].filter((p)=>p!==i).sort()].map((p)=>"0 FILE "+(p===i?"":p)+`\n`+r.get(p).join(`\n`)).join(`\n`);s.set(i,`emb/${Xt(c)}.dat`)}return s}var ct=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,ut=new WeakMap;function ke(e,t){let n=ut.get(e);if(!n)ut.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),l=[],a=[];s.studs.forEach((h,d)=>{l.push(h[0]),a.push(h[1]);for(let S=0;S<12;S++)i[d*12+S]=h[2+S]});let c=null,p=0,m=0;if(s.mask){p=s.mask[0],m=s.mask[1];let h=s.mask[2];c=new Uint8Array(h.length);for(let d=0;d<h.length;d++)c[d]=h.charCodeAt(d)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:l,color:a,mask:c,nx:p,nz:m}),r}var ie=1073741824;class Fe{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,l=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&l[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,l=this.b,a=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,l[s]=t,a[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&l[s]===t&&a[s]===n){let c=this.vals[s];return this.vals[s]=r,c}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var ye=(e,t,n)=>e>-ie&&e<ie&&t>-ie&&t<ie&&n>-ie&&n<ie,fe=2147483647;function Wt(e,t,n){let s=[],o=[],i=[],l=[],a=[],c=[],p=[],m=[],h=new Fe(e.length*2),d=[],S=[];for(let v=0;v<e.length;v++){let w=e[v],L=w.m,V=t.parts[w.part];if(!V||!V.mask||!ct(L))continue;let I=V.bbox,B=1/0,T=-1/0,x=1/0,N=-1/0;for(let z=0;z<2;z++)for(let j=0;j<2;j++){let k=z?I[3]:I[0],G=j?I[5]:I[2],K=L[0]+L[3]*k+L[5]*G,Y=L[2]+L[9]*k+L[11]*G;if(K<B)B=K;if(K>T)T=K;if(Y<x)x=Y;if(Y>N)N=Y}let F=a.length;s.push(B),o.push(T),i.push(x),l.push(N),a.push(v),c.push(ke(t,w.part)),p.push(I[0]),m.push(I[2]);let R=Math.round((L[1]+I[4])*2);for(let z=Math.floor(B/40);z<=Math.floor(T/40);z++)for(let j=Math.floor(x/40);j<=Math.floor(N/40);j++){if(!ye(R,z,j))continue;let k=S.length;S.push(F),d.push(h.put(R,z,j,k))}}let u=[0,5,-5,5,-5],b=[0,5,5,-5,-5],P=NaN,g=NaN,f=NaN,A=-1,O=(v,w,L,V)=>{let I=Math.round(w*2),B=Math.floor(v/40),T=Math.floor(L/40);if(!ye(I,B,T))return fe;let x=fe;if(I!==P||B!==g||T!==f)P=I,g=B,f=T,A=h.get(I,B,T);for(let N=A;N>=0;N=d[N]){let F=S[N];if(a[F]===V||!(v-6>=s[F]-0.5&&v+6<=o[F]+0.5&&L-6>=i[F]-0.5&&L+6<=l[F]+0.5))continue;let R=e[a[F]].m,z=c[F],j=p[F],k=m[F],G=v-R[0],K=w-R[1],Y=L-R[2],q=R[3]*G+R[6]*K+R[9]*Y,Z=R[5]*G+R[8]*K+R[11]*Y,{nx:ee,nz:se,mask:ae}=z,oe=!0;for(let Q=0;Q<5;Q++){let te=Math.floor((q+u[Q]-j)/20),ne=Math.floor((Z+b[Q]-k)/20);if(te<0||ne<0||te>=ee||ne>=se||ae[te*se+ne]!==1){oe=!1;break}}if(oe){if(!n)return 0;let Q=n[a[F]];if(Q<x)x=Q}}return x},y=0;for(let v of e){let w=ke(t,v.part);if(w)y+=w.nStuds}let M=new Uint8Array(y),E=new Uint8Array(y),D=new Fe(y),C=0,U=n?new Int32Array(y).fill(fe):void 0;for(let v=0,w=0;v<e.length;v++){let L=e[v],V=ke(t,L.part);if(!V)continue;let I=L.m,B=V.studM,T=I[0],x=I[1],N=I[2],F=I[3],R=I[4],z=I[5],j=I[6],k=I[7],G=I[8],K=I[9],Y=I[10],q=I[11];for(let Z=0;Z<V.nStuds;Z++,w++){let ee=Z*12,se=B[ee+4],ae=B[ee+7],oe=B[ee+10];if(!(Math.abs(j*se+k*ae+G*oe-1)<0.001&&Math.abs(F*se+R*ae+z*oe)<0.001&&Math.abs(K*se+Y*ae+q*oe)<0.001))continue;E[w]=1;let Q=B[ee],te=B[ee+1],ne=B[ee+2],Re=T+F*Q+R*te+z*ne,De=x+j*Q+k*te+G*ne,Ue=N+K*Q+Y*te+q*ne,Oe=O(Re,De,Ue,v);if(Oe!==fe){if(M[w]=1,C++,U)U[w]=Oe}let pe=Math.round(Re),me=Math.round(De),he=Math.round(Ue);if(!ye(pe,me,he))continue;if(!n){D.put(pe,me,he,1);continue}let ze=n[v],Ne=D.get(pe,me,he);if(Ne<0||ze<Ne)D.put(pe,me,he,ze)}}let _=new Uint8Array(e.length),H=n?new Int32Array(e.length).fill(fe):void 0;for(let v=0;v<e.length;v++){let w=e[v],L=t.parts[w.part];if(!L||!L.under||!ct(w.m))continue;let V=L.bbox,I=Math.round((V[3]-V[0])/20),B=Math.round((V[5]-V[2])/20);if(!I||!B||I*B>4096)continue;let T=w.m,x=!0,N=0;for(let F=0;F<I&&x;F++)for(let R=0;R<B;R++){let z=V[0]+10+20*F,j=V[2]+10+20*R,k=T[0]+T[3]*z+T[5]*j,G=T[2]+T[9]*z+T[11]*j,K=Math.round(k),Y=Math.round(T[1]+V[4]),q=Math.round(G),Z=ye(K,Y,q)?D.get(K,Y,q):-1;if(Z<0){x=!1;break}if(Z>N)N=Z}if(x){if(_[v]=1,H)H[v]=N}}return{nStuds:y,studHidden:M,studUp:E,underHidden:_,studsHidden:C,studHideStep:U,underHideStep:H}}function _t(e,t,n){let r=(a)=>n&&a.texPart&&t.parts[a.texPart]?a.texPart:a.part,s=e.map((a)=>({part:r(a),color:String(a.color),m:a.m,steps:a.steps})),o=s.map((a)=>it(a.steps)),i=[...new Set(o)].sort(),l=new Map(i.map((a,c)=>[a,c]));return{all:s,stepOf:o.map((a)=>l.get(a)),nSteps:i.length}}function xe(e,t,n=!0){let r=_t(e,t,n);return Wt(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Me="https://ldr-demo.vercel.app/cdn/v1/",Ae=new Map,we=new Map;function pt(e=Me,t=fetch){let n=Ae.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(()=>Ae.delete(e)),Ae.set(e,n);return n}var Yt=(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"),ve=(e,t)=>Yt(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>ve(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ve(r,t)])):e;function Jt(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let d=h.buffer;if(!d)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let S=new DataView(d).getUint32(0,!0),u=new Uint8Array(d,4+S),b=r;n.push(u),r+=u.byteLength;let P=(4-r%4)%4;if(P)n.push(new Uint8Array(P)),r+=P;for(let[g,f]of Object.entries(h.header.parts??{}))if(!(g in s))s[g]=ve(f,b);for(let[g,f]of Object.entries(h.header.studKinds??{}))if(!(g in o))o[g]=ve(f,b)}let i=e[0]?.header??{version:1,weld:!0},l=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+l.length)%4)%4,c=4+l.length+a,p=new Uint8Array(c+r);new DataView(p.buffer).setUint32(0,l.length+a,!0),p.set(l,4),p.fill(32,4+l.length,c);let m=c;for(let h of n)p.set(h,m),m+=h.byteLength;return de(p.buffer)}async function Zt(e,t={}){e=[...e];try{return await ft(e,t)}catch(n){let r=t.cdn??Me,s=t.fetch??fetch;Ae.delete(r);let o=(i,l)=>s(i,{...l,cache:"reload"});try{return await ft(e,{...t,fetch:o})}catch{throw n}}}async function ft(e,t){let n=t.cdn??Me,r=t.fetch??fetch,s=t.gap??16384,o=await pt(n,r),i=[...new Set([...e].map(J))],l=[],a=[];for(let u of i){if(we.has(n+u))continue;let b=o.parts[u];if(b)a.push({name:u,off:b[0],len:b[1],file:b[2]??0});else l.push(u)}a.sort((u,b)=>u.file-b.file||u.off-b.off);let c=[];for(let u of a){let b=c[c.length-1];if(b&&b.file===u.file&&u.off-b.end<=s)b.end=Math.max(b.end,u.off+u.len),b.items.push(u);else c.push({file:u.file,start:u.off,end:u.off+u.len,items:[u]})}let p=0,m=0,h=async()=>{while(m<c.length){let u=c[m++],b=await r(new URL(o.archives[u.file],n).href,{headers:{Range:`bytes=${u.start}-${u.end-1}`}});if(!b.ok)throw Error(`ldr: parts CDN ${b.status}`);let P=new Uint8Array(await b.arrayBuffer());if(b.status===200)P=P.subarray(u.start,u.end);p+=P.byteLength;for(let g of u.items){let f=je(P.subarray(g.off-u.start,g.off-u.start+g.len)),A=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);we.set(n+g.name,de(A))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,c.length)},h));let d=i.filter((u)=>we.has(n+u)).map((u)=>we.get(n+u));return{pack:d.length?Jt(d,{colors:o.colors}):de(qt(o.colors)),missing:l,requests:c.length,bytes:p}}function qt(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},colors: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}async function mt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=pt(t.cdn??Me,r);s.catch(()=>{});let o=t.text?e:await r(e).then((f)=>{if(!f.ok)throw Error(`ldr: ${f.status} fetching ${e}`);return f.text()}),i=performance.now(),l=t.name??(t.text?"main.ldr":decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr")),a=at(o,l,{looseGeometry:!1,callouts:t.callouts}),c=performance.now();t.onParsed?.(a),await s;let p=lt(o,new Set(a.filter((f)=>f.embedded).map((f)=>f.part)),l),{pack:m,missing:h,requests:d,bytes:S}=await Zt([...a.filter((f)=>!f.embedded).map((f)=>f.part),...p.values()],t),u=new Map([...p].map(([f,A])=>[A,f])),b=h.map((f)=>u.get(f)??f);for(let[f,A]of p){let O=m.header.parts[A];if(O)m.header.parts[f]=O}let P=performance.now(),g=t.cull?xe(a,m.header,t.textures!==!1):void 0;return{insts:a,pack:m,missing:b,requests:d,bytes:S,cull:g,timings:{fetchModel:i-n,parse:c-i,parts:P-c,...g?{cull:performance.now()-P}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await mt(n,{...r,cull:!1,onParsed:(p)=>self.postMessage({id:t,insts:p})}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),l=xe(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,c=[];for(let p of[l.studHidden,l.studUp,l.underHidden,l.studHideStep,l.underHideStep])if(p)c.push(p.buffer);self.postMessage({id:t,cull:l,ms:a},c)}catch(s){self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
2998
3252
 
2999
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/cdn.ts
3253
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/cdn.ts
3000
3254
  var worker;
3001
3255
  var seq = 0;
3002
3256
  var pending = new Map;
@@ -3105,7 +3359,7 @@ async function loadModel(source, o = {}) {
3105
3359
  timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
3106
3360
  });
3107
3361
  }
3108
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/library.ts
3362
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/library.ts
3109
3363
  import { existsSync, readFileSync } from "fs";
3110
3364
  import { join } from "path";
3111
3365
  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]];
@@ -3364,11 +3618,11 @@ class Library {
3364
3618
  return insts;
3365
3619
  }
3366
3620
  }
3367
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/build-pack.ts
3621
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/build-pack.ts
3368
3622
  import fs3 from "node:fs";
3369
3623
  import path3 from "node:path";
3370
3624
 
3371
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/resolver.ts
3625
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/resolver.ts
3372
3626
  import fs from "node:fs";
3373
3627
  import path from "node:path";
3374
3628
  var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
@@ -3640,11 +3894,11 @@ function collectDeps(lib, refs) {
3640
3894
  return out;
3641
3895
  }
3642
3896
 
3643
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/compile.ts
3897
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/compile.ts
3644
3898
  import fs2 from "node:fs";
3645
3899
  import path2 from "node:path";
3646
3900
 
3647
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/lod.ts
3901
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/lod.ts
3648
3902
  import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
3649
3903
  await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
3650
3904
  function reorderMesh(P, N, C, I) {
@@ -3836,7 +4090,7 @@ function lodChain(P, C, I) {
3836
4090
  return out;
3837
4091
  }
3838
4092
 
3839
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/compile.ts
4093
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/compile.ts
3840
4094
  function loadColors(root) {
3841
4095
  const map = new Map;
3842
4096
  for (const l of fs2.readFileSync(path2.join(root, "LDConfig.ldr"), "latin1").split(/\r?\n/)) {
@@ -4419,7 +4673,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
4419
4673
  return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
4420
4674
  }
4421
4675
 
4422
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/node/build-pack.ts
4676
+ // ../../../../../../../tmp/ldr-build-E7gTbS/src/node/build-pack.ts
4423
4677
  function buildPack(o) {
4424
4678
  const lib = new Library2(o.ldrawRoot);
4425
4679
  const refs = new Map;