ldr 0.18.0 → 0.20.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.
- package/README.md +3 -2
- package/dist/cli.js +14 -14
- package/dist/index.js +13 -13
- package/dist/node/build-pack.d.ts +1 -1
- package/dist/node/index.d.ts +2 -0
- package/dist/node/index.js +264 -21
- package/dist/node/promote.d.ts +25 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ bunx ldr pack --ldraw ./ldraw -o public/car.pack.zst models/car.ldr
|
|
|
28
28
|
|
|
29
29
|
```
|
|
30
30
|
ldr pack --ldraw <dir> -o <out.bin|.zst|.gz> [model.ldr ...] [--part 3001.dat ...] [--all-parts]
|
|
31
|
-
[--studs low|full] [--prims full
|
|
31
|
+
[--studs low|full] [--prims low|full] [--no-weld] [--no-colors]
|
|
32
32
|
[--cond] [--textures] [--no-loose-geometry] [--no-lod] [--reorder]
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -113,6 +113,7 @@ MPD-embedded parts, such as Studio/OMR unofficial parts or stickers, become part
|
|
|
113
113
|
| `decompressPack(bytes)` / `decodePack(buffer)` | Same, from bytes you already have. |
|
|
114
114
|
| `decodeModelText(bytes) → Promise<string>` / `modelFileName(url)` | Model file bytes to LDraw text (zstd / gzip detected and inflated, then UTF-8), and the file name `loadModel` uses for a URL (`8466-1.mpd.zst` → `8466-1.mpd`). `loadModel` reads model URLs this way, so large models can be hosted as `.mpd.zst`. |
|
|
115
115
|
| `bodyTriangles(insts, pack)` / `BudgetError` / `maxBodyTris` / `maxPackBytes` | Full-detail body triangle count; `prepareModel` / `loadModel` abort with `BudgetError` when the merged pack exceeds the caller's triangle or byte limits (phones). |
|
|
116
|
+
| `promoteFlexParts` / `decimateFlexGeometry` / `prepareFlexParts` (node) | Relabel LDCad flex Model files as embedded parts, then lower tube ring tessellation (16→8) and drop rib-detail quads for cheaper hose meshes. |
|
|
116
117
|
| `createLdrObject(instances, pack, options?) → LdrObject` | High-level three.js object (see below). |
|
|
117
118
|
| `createInstancedEdges(pos, instancedMesh, material?)` | Welded, indexed edge lines that share an `InstancedMesh`'s instance matrices. |
|
|
118
119
|
| `conditionalLines(pack, entry, which?)` / `createInstancedConditionalEdges(cond, instancedMesh, material?)` / `conditionalLineVisible` | Type-5 conditional lines from a `cond` pack. A vertex shader keeps a segment only where both control points project to the same side of the line. |
|
|
@@ -161,7 +162,7 @@ Everything above, plus:
|
|
|
161
162
|
|
|
162
163
|
| export | description |
|
|
163
164
|
|---|---|
|
|
164
|
-
| `buildPack(options) → { data, parts, studKinds, missing, warnings? }` | Builds a pack. Options: `ldrawRoot`, `models`, `parts`, `allParts`, `studs` (`"low"` \| `"full"`), `primitives` (`"
|
|
165
|
+
| `buildPack(options) → { data, parts, studKinds, missing, warnings? }` | Builds a pack. Options: `ldrawRoot`, `models`, `parts`, `allParts`, `studs` (`"low"` \| `"full"`), `primitives` (`"low"` \| `"full"`, default `"low"`), `weld` (`true`), `cond` (`false`), `textures` (`false`), `looseGeometry` (`true`), `colors` (`true`), `lod` (`true`: meshoptimizer-simplified LOD meshes, pack feature `lod`), `reorder` (`false`: vertex-cache order), `onProgress`. |
|
|
165
166
|
| `Library(root, unofficialRoot?)` | Filesystem LDraw resolver: `where`, `flatten`, `mesh`, `colors`, `texture`, `register`. Handles case-insensitive lookup and `~Moved to` aliases. |
|
|
166
167
|
| `Compiler`, `encodePack`, `writePack`, `loadColors` | Lower-level pack compiler. |
|
|
167
168
|
| `ResolverLibrary`, `splitModel`, `flattenWithLibrary`, `collectDeps` | The resolver that `buildPack` uses. |
|
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/cli.ts
|
|
4
4
|
import fs4 from "node:fs";
|
|
5
5
|
import zlib from "node:zlib";
|
|
6
6
|
|
|
7
|
-
// ../../../../../../../tmp/ldr-build-
|
|
7
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/build-pack.ts
|
|
8
8
|
import fs3 from "node:fs";
|
|
9
9
|
import path3 from "node:path";
|
|
10
10
|
|
|
11
|
-
// ../../../../../../../tmp/ldr-build-
|
|
11
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/resolver.ts
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
|
|
15
|
-
// ../../../../../../../tmp/ldr-build-
|
|
15
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/spec.ts
|
|
16
16
|
var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
17
17
|
function parseColor(tok) {
|
|
18
18
|
if (/^0x/i.test(tok))
|
|
@@ -705,7 +705,7 @@ function fileStepViews(f) {
|
|
|
705
705
|
return out;
|
|
706
706
|
}
|
|
707
707
|
|
|
708
|
-
// ../../../../../../../tmp/ldr-build-
|
|
708
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/model.ts
|
|
709
709
|
var CALLOUT_END = 999999;
|
|
710
710
|
var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
|
|
711
711
|
function flatten(doc, opts = {}) {
|
|
@@ -1055,7 +1055,7 @@ function parseLDConfig(text) {
|
|
|
1055
1055
|
return out;
|
|
1056
1056
|
}
|
|
1057
1057
|
|
|
1058
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1058
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/resolver.ts
|
|
1059
1059
|
var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
|
|
1060
1060
|
var UNDER_STUD_RE = /^(stud3|stud3a|stud4.*|stud12|stud16.*|stud18a)\.dat$/i;
|
|
1061
1061
|
var norm2 = (ref) => ref.trim().replace(/\\/g, "/").toLowerCase();
|
|
@@ -1325,11 +1325,11 @@ function collectDeps(lib, refs) {
|
|
|
1325
1325
|
return out;
|
|
1326
1326
|
}
|
|
1327
1327
|
|
|
1328
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1328
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/compile.ts
|
|
1329
1329
|
import fs2 from "node:fs";
|
|
1330
1330
|
import path2 from "node:path";
|
|
1331
1331
|
|
|
1332
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1332
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/lod.ts
|
|
1333
1333
|
import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
|
|
1334
1334
|
await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
|
|
1335
1335
|
function reorderMesh(P, N, C, I) {
|
|
@@ -1521,7 +1521,7 @@ function lodChain(P, C, I) {
|
|
|
1521
1521
|
return out;
|
|
1522
1522
|
}
|
|
1523
1523
|
|
|
1524
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1524
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/compile.ts
|
|
1525
1525
|
function loadColors(root) {
|
|
1526
1526
|
const map = new Map;
|
|
1527
1527
|
for (const l of fs2.readFileSync(path2.join(root, "LDConfig.ldr"), "latin1").split(/\r?\n/)) {
|
|
@@ -2104,7 +2104,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
|
|
|
2104
2104
|
return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
|
|
2105
2105
|
}
|
|
2106
2106
|
|
|
2107
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2107
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/build-pack.ts
|
|
2108
2108
|
function buildPack(o) {
|
|
2109
2109
|
const lib = new Library(o.ldrawRoot);
|
|
2110
2110
|
const refs = new Map;
|
|
@@ -2138,7 +2138,7 @@ function buildPack(o) {
|
|
|
2138
2138
|
if (lib.isPart(k) && /\.dat$/.test(k))
|
|
2139
2139
|
refs.set(k.slice(6), k);
|
|
2140
2140
|
}
|
|
2141
|
-
const comp = new Compiler(lib, { studs: o.studs ?? "low", prims: o.primitives ?? "
|
|
2141
|
+
const comp = new Compiler(lib, { studs: o.studs ?? "low", prims: o.primitives ?? "low", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures });
|
|
2142
2142
|
const parts = new Map, kinds = new Map;
|
|
2143
2143
|
let n = 0;
|
|
2144
2144
|
for (const [ref, key] of refs) {
|
|
@@ -2172,7 +2172,7 @@ function buildPack(o) {
|
|
|
2172
2172
|
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 } : {} };
|
|
2173
2173
|
}
|
|
2174
2174
|
|
|
2175
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2175
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/cli.ts
|
|
2176
2176
|
var HELP = `ldr pack — build a parts pack for the ldr three.js renderer
|
|
2177
2177
|
|
|
2178
2178
|
Usage:
|
|
@@ -2184,7 +2184,7 @@ Options:
|
|
|
2184
2184
|
--part <ref> Include a part (repeatable), e.g. --part 3001.dat
|
|
2185
2185
|
--all-parts Include every part in the library (large)
|
|
2186
2186
|
--studs low|full Stud detail (default low)
|
|
2187
|
-
--prims full
|
|
2187
|
+
--prims low|full Other primitive detail (default low)
|
|
2188
2188
|
--no-weld Don't index/weld vertices
|
|
2189
2189
|
--cond Keep conditional (type-5) lines for curved-surface outlines (pack v2, ~+8-14% zstd)
|
|
2190
2190
|
--textures Keep printed/sticker parts' !TEXMAP geometry + UVs and embed their PNGs (pack v2; packs without
|
|
@@ -2206,7 +2206,7 @@ var parts = [];
|
|
|
2206
2206
|
var ldraw = "";
|
|
2207
2207
|
var out = "";
|
|
2208
2208
|
var studs = "low";
|
|
2209
|
-
var prims = "
|
|
2209
|
+
var prims = "low";
|
|
2210
2210
|
var weld = true;
|
|
2211
2211
|
var colors = true;
|
|
2212
2212
|
var all = false;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/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))
|
|
@@ -689,7 +689,7 @@ function fileStepViews(f) {
|
|
|
689
689
|
viewMemo.set(f, out);
|
|
690
690
|
return out;
|
|
691
691
|
}
|
|
692
|
-
// ../../../../../../../tmp/ldr-build-
|
|
692
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/model.ts
|
|
693
693
|
var CALLOUT_END = 999999;
|
|
694
694
|
var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
|
|
695
695
|
function flatten(doc, opts = {}) {
|
|
@@ -1038,7 +1038,7 @@ function parseLDConfig(text) {
|
|
|
1038
1038
|
}
|
|
1039
1039
|
return out;
|
|
1040
1040
|
}
|
|
1041
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1041
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/instructions.ts
|
|
1042
1042
|
var MIN_VIS = 0.5;
|
|
1043
1043
|
var REORIENT = 0.35;
|
|
1044
1044
|
var deg = Math.PI / 180;
|
|
@@ -1406,10 +1406,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
|
|
|
1406
1406
|
}
|
|
1407
1407
|
};
|
|
1408
1408
|
}
|
|
1409
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1409
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/render.ts
|
|
1410
1410
|
import * as THREE from "three";
|
|
1411
1411
|
|
|
1412
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1412
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/pack-io.ts
|
|
1413
1413
|
import { decompress } from "fzstd";
|
|
1414
1414
|
async function decompressPack(data) {
|
|
1415
1415
|
const u = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
@@ -1432,7 +1432,7 @@ function decodePack(buf) {
|
|
|
1432
1432
|
return { header, arr, bytes: buf.byteLength, buffer: buf };
|
|
1433
1433
|
}
|
|
1434
1434
|
|
|
1435
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1435
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/cull.ts
|
|
1436
1436
|
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;
|
|
1437
1437
|
var prepCache = new WeakMap;
|
|
1438
1438
|
function prepPart(H, part) {
|
|
@@ -1749,7 +1749,7 @@ function precomputeCull(instances, H, useTex = true) {
|
|
|
1749
1749
|
return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
|
|
1750
1750
|
}
|
|
1751
1751
|
|
|
1752
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1752
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/render.ts
|
|
1753
1753
|
async function loadPack(url) {
|
|
1754
1754
|
const res = await fetch(url);
|
|
1755
1755
|
if (!res.ok)
|
|
@@ -3371,7 +3371,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
|
|
|
3371
3371
|
await new Promise((r) => setTimeout(r, 0));
|
|
3372
3372
|
}
|
|
3373
3373
|
}
|
|
3374
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3374
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/scene.ts
|
|
3375
3375
|
import * as THREE2 from "three";
|
|
3376
3376
|
function colorFn(src, pack, fallback) {
|
|
3377
3377
|
const table = new Map;
|
|
@@ -3588,10 +3588,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
|
|
|
3588
3588
|
return finish();
|
|
3589
3589
|
})();
|
|
3590
3590
|
}
|
|
3591
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3591
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/parts-cdn.ts
|
|
3592
3592
|
import { decompress as decompress2 } from "fzstd";
|
|
3593
3593
|
|
|
3594
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3594
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/embedded.ts
|
|
3595
3595
|
function splitFiles(text, fallback) {
|
|
3596
3596
|
const files = new Map;
|
|
3597
3597
|
let cur = null, saw = false;
|
|
@@ -3663,7 +3663,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
|
|
|
3663
3663
|
return out;
|
|
3664
3664
|
}
|
|
3665
3665
|
|
|
3666
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3666
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/parts-cdn.ts
|
|
3667
3667
|
var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
|
|
3668
3668
|
var indexCache = new Map;
|
|
3669
3669
|
var shardCache = new Map;
|
|
@@ -3861,10 +3861,10 @@ async function prepareModel(source, o = {}) {
|
|
|
3861
3861
|
return { insts, pack, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
|
|
3862
3862
|
}
|
|
3863
3863
|
|
|
3864
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3864
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/load-worker.gen.ts
|
|
3865
3865
|
var load_worker_gen_default = 'var dt=ArrayBuffer,W=Uint8Array,ge=Uint16Array,yt=Int16Array;var be=Int32Array,Ee=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},ce=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},xt=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 wt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],K=function(e,t,n){var r=Error(t||wt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,K);if(!n)throw r;return r},je=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},At=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Mt=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)K(0);var a=6-s,c=i==3?4:i,m=je(e,a,c);a+=c;var p=l?1<<l:s,h=je(e,a,p)+(l==1&&256),d=h;if(!s){var T=1<<10+(e[5]>>3);d=T+(T>>3)*(e[5]&7)}if(d>2145386496)K(1);var u=new W((t==1?h||d:t?0:d)+12);return u[0]=1,u[4]=4,u[8]=8,{b:a+p,y:0,l:0,d:m,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 At(e,4)+8;K(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)K(3);var o=1<<s,i=o,l=-1,a=-1,c=-1,m=o,p=new dt(512+(o<<2)),h=new yt(p,0,256),d=new ge(p,0,256),T=new ge(p,512,o),u=512+(o<<1),b=new W(p,u,o),E=new W(p,u+o);while(l<255&&i>0){var g=re(i+1),f=r>>3,w=(1<<g+1)-1,U=(e[f]|e[f+1]<<8|e[f+2]<<16)>>(r&7)&w,y=(1<<g)-1,v=w-i-1,S=U&y;if(S<v)r+=g,U=S;else if(r+=g+1,U>y)U-=v;if(h[++l]=--U,U==-1)i+=U,b[--m]=l;else i-=U;if(!U)do{var R=r>>3;a=(e[R]|e[R+1]<<8)>>(r&7)&3,r+=2,l+=a}while(a==3)}if(l>255||i)K(0);var C=0,D=(o>>1)+(o>>3)+3,X=o-1;for(var H=0;H<=l;++H){var M=h[H];if(M<1){d[H]=-M;continue}for(c=0;c<M;++c){b[C]=H;do C=C+D&X;while(C>=m)}}if(C)K(0);for(c=0;c<o;++c){var A=d[b[c]]++,P=E[c]=s-re(A);T[c]=(A<<P)-o}return[r+7>>3,{b:s,s:b,n:E,t:T}]},vt=function(e,t){var n=0,r=-1,s=new W(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),m=c[0],p=c[1];t+=o;var h=m<<3,d=e[t];if(!d)K(0);var T=0,u=0,b=p.b,E=b,g=(++t<<3)-8+re(d);for(;;){if(g-=b,g<h)break;var f=g>>3;if(T+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<b)-1,i[++r]=p.s[T],g-=E,g<h)break;f=g>>3,u+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<E)-1,i[++r]=p.s[u],b=p.n[T],T=p.t[T],E=p.n[u],u=p.t[u]}if(++r>255)K(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 U=0;for(n=0;n<r;++n){var y=i[n];if(y>11)K(0);U+=y&&1<<y-1}var v=re(U)+1,S=1<<v,R=S-U;if(R&R-1)K(0);i[r++]=re(R)+1;for(n=0;n<r;++n){var y=i[n];++l[i[n]=y&&v+1-y]}var C=new W(S<<1),D=C.subarray(0,S),X=C.subarray(S);a[v]=0;for(n=v;n>0;--n){var H=a[n];ce(X,n,H,a[n-1]=H+l[n]*(1<<v-n))}if(a[0]!=S)K(0);for(n=0;n<r;++n){var M=i[n];if(M){var A=a[M];ce(D,n,A,a[M]=A+(1<<v-M))}}return[t,{n:X,b:v,s:D}]},Tt=ue(new W([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],Ct=ue(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],Et=ue(new W([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],Ve=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},Se=new W(new be([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),St=Ve(Se,0),Le=new W(new be([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),Lt=Ve(Le,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)K(0);var a=0,c=n.b,m=(r<<3)-8+re(o)-c,p=-1;for(;m>l&&p<s;){var h=m>>3,d=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(m&7);a=(a<<c|d)&i,t[++p]=n.s[a],m-=c=n.n[a]}if(m!=l||p+1!=s)K(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)},kt=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 W(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 Ee(e,s,a)}if(i==2){var c=e[s],m=c&3,p=c>>2&3,h=c>>4,d=0,T=0;if(m<2)if(p&1)h|=e[++s]<<4|(p&2&&e[++s]<<12);else h=c>>3;else if(T=p,p<2)h|=(e[++s]&63)<<4,d=e[s]>>6|e[++s]<<2;else if(p==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 W(t.m),b=u.length-h;if(m==0)u.set(e.subarray(s,s+=h),b);else if(m==1)ce(u,e[s++],b);else{var E=t.h;if(m==2){var g=vt(e,s);d+=s-(s=g[0]),t.h=E=g[1]}else if(!E)K(0);(T?Pt:le)(e.subarray(s,s+=d),u.subarray(b),E)}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 w=e[s++];if(w&3)K(0);var U=[Ct,Et,Tt];for(var y=2;y>-1;--y){var v=w>>(y<<1)+2&3;if(v==1){var S=new W([0,0,e[s++]]);U[y]={s:S.subarray(2,3),n:S.subarray(0,1),t:new ge(S.buffer,0,1),b:0}}else if(v==2)r=ue(e,s,9-(y&1)),s=r[0],U[y]=r[1];else if(v==3){if(!t.t)K(0);U[y]=t.t[y]}}var R=t.t=U,C=R[0],D=R[1],X=R[2],H=e[a-1];if(!H)K(0);var M=(a<<3)-8+re(H)-X.b,A=M>>3,P=0,V=(e[A]|e[A+1]<<8)>>(M&7)&(1<<X.b)-1;A=(M-=D.b)>>3;var k=(e[A]|e[A+1]<<8)>>(M&7)&(1<<D.b)-1;A=(M-=C.b)>>3;var N=(e[A]|e[A+1]<<8)>>(M&7)&(1<<C.b)-1;for(++f;--f;){var L=X.s[V],x=X.n[V],O=C.s[N],F=C.n[N],B=D.s[k],z=D.n[k];A=(M-=B)>>3;var j=1<<B,I=j+((e[A]|e[A+1]<<8|e[A+2]<<16|e[A+3]<<24)>>>(M&7)&j-1);A=(M-=Le[O])>>3;var G=Lt[O]+((e[A]|e[A+1]<<8|e[A+2]<<16)>>(M&7)&(1<<Le[O])-1);A=(M-=Se[L])>>3;var _=St[L]+((e[A]|e[A+1]<<8|e[A+2]<<16)>>(M&7)&(1<<Se[L])-1);if(A=(M-=x)>>3,V=X.t[V]+((e[A]|e[A+1]<<8)>>(M&7)&(1<<x)-1),A=(M-=F)>>3,N=C.t[N]+((e[A]|e[A+1]<<8)>>(M&7)&(1<<F)-1),A=(M-=z)>>3,k=D.t[k]+((e[A]|e[A+1]<<8)>>(M&7)&(1<<z)-1),I>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=I-=3;else{var Z=I-(_!=0);if(Z){if(I=Z==3?t.o[0]-1:t.o[Z],Z>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=I}else I=t.o[0]}for(var y=0;y<_;++y)u[P+y]=u[b+y];P+=_,b+=_;var q=P-I;if(q<0){var J=-q,ee=t.e+q;if(J>G)J=G;for(var y=0;y<J;++y)u[P+y]=t.w[ee+y];P+=J,G-=J,q=0}for(var y=0;y<G;++y)u[P+y]=u[q+y];P+=G}if(P!=b)while(b<u.length)u[P++]=u[b++];else P=u.length;if(n)t.y+=P;else u=Ee(u,0,P)}else if(n){if(t.y+=h,b)for(var y=0;y<h;++y)u[y]=u[b+y]}else if(b)u=Ee(u,b);return t.b=a,u}K(2)},It=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 de(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Mt(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=kt(e,i,t);if(!l)K(5);if(t)i.e=i.y;else n.push(l),o+=l.length,xt(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 It(n,o)}async function Ft(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(de(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 He(e){return new TextDecoder().decode(await Ft(e))}var Ge=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function ye(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,"/");function Pe(e){if(/^0x/i.test(e))return parseInt(e,16);return+e}var _e=/^~?\\s*moved\\s+to\\s+(.+)$/i,Bt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Qe=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Rt=new Set(["model","submodel","configuration"]),Dt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function We(e){let t=Dt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Qe.has(n)||Rt.has(n)?n:void 0}function Ut(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function zt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every(Number.isFinite))return null;let l=n[2].trim();for(let p=0;p<s;p++)l=l.replace(/^\\S+\\s*/,"");let a=Ut(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 m=a.findIndex((p,h)=>h>0&&p.toUpperCase()==="GLOSSMAP");if(m>0&&a[m+1])c.glossmap=a[m+1];if(t)c.next=!0;return c}var Ot=(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 Nt(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 m=s();if(m===null)return null;i[c]=+m}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:Pe(o),m:i,file:Y(a)}}function Ke(e){let t=+e[0];if(!(t>=1&&t<=5)||e.length<2)return null;let n=Pe(e[1]),r=e.slice(2).map(Number);if(t===1)return{t:1,color:n,m:r.slice(0,12),file:Y(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 et(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",l,a=null,c=[],m=null,p=()=>{if(!a)return;let g=Ot(a.chunks.join("")),f=g[0]===137&&g[1]===80&&g[2]===78&&g[3]===71;(l??=new Map).set(Y(a.name),{name:a.name,bytes:g,...f?{mime:"image/png"}:{}}),a=null},h=!0,d=(g)=>{if(p(),o={name:Y(g),cmds:[]},s.set(o.name,o),!i)i=o.name;c=[],m=null,h=!0},T=!1,u=!1,b=()=>{if(u)return;u=!0,s.clear(),o=null,i=""},E=(g,f)=>{if(m){g.tex=m,m=null;return}let w=c[c.length-1];if(!w)return;if(w.fallback){if(!f)g.fallback=!0}else g.tex=w.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||T)continue;if(!o)d(t);let v=f.slice(2).trimStart(),S=v.search(/\\s/),R={t:f.charCodeAt(0)-48,color:Pe(S<0?v:v.slice(0,S)),p:[],src:f};E(R,!1),o.cmds.push(R),h=!1;continue}if(f.charCodeAt(0)===48&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)){let v=2;while(f.charCodeAt(v)===32||f.charCodeAt(v)===9)v++;let S=v;while(S<f.length&&f.charCodeAt(S)!==32&&f.charCodeAt(S)!==9)S++;let R=f.slice(v,S);if(!Bt.has(R)){if(T||a)continue;if(!o)d(t);let C=f.slice(v),D={t:0,text:C};if(R.charCodeAt(0)===33)D.meta=R;if(m=null,h&&!o.org){let H=We(C);if(H)o.org=H}let X=C.match(_e);if(X&&!o.movedTo){let H=X[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(H))H+=".dat";o.movedTo=Y(H)}o.cmds.push(D);continue}}if(f.charCodeAt(0)===49&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)&&!a&&!T){let v=Nt(f);if(v){if(!o)d(t);E(v,!1),o.cmds.push(v),h=!1;continue}}let w=f.split(/\\s+/);if(+w[0]===0){let v=f.slice(1).trim();if(w[1]==="FILE"){b(),T=!1,d(v.slice(5));continue}if(w[1]==="NOFILE"){p(),o=null,T=!0;continue}if(w[1]==="!DATA"){b(),p(),o=null,T=!1,a={name:v.slice(5).trim(),chunks:[]};continue}if(T)continue;if(a){if(w[1]==="!:")a.chunks.push(w.slice(2).join(""));continue}if(!o)d(t);let S={t:0,text:v};if(w[1]==="STEP")S.step=!0,c=[],m=null;else if(w[1]==="BFC")S.bfc=w.slice(2).join(" ");else if(w[1]==="ROTSTEP")if(S.meta="ROTSTEP",S.step=!0,c=[],m=null,(w[2]??"").toUpperCase()==="END")S.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(w[5]??"REL").toUpperCase();S.rotstep={x:+w[2]||0,y:+w[3]||0,z:+w[4]||0,mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(w[1]==="BUFEXCHG"){S.meta="BUFEXCHG";let C=(w[2]??"").toUpperCase();S.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:w[3]??"A"}}else if(w[1]?.startsWith("!"))S.meta=w[1];if(h&&!o.org){let C=We(v);if(C)o.org=C}if(w[1]==="!TEXMAP"){let C=(w[2]??"").toUpperCase();if(m=null,C==="START"||C==="NEXT"){let D=zt(v.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(S.texmap={op:C,...D?{map:D}:{}},D)if((o.texmaps??=[]).push(D),C==="START")c.push({map:D,fallback:!1});else m=D}else if(C==="FALLBACK"){S.texmap={op:C};let D=c[c.length-1];if(D)D.fallback=!0}else if(C==="END")S.texmap={op:C},c.pop()}else if(w[1]==="!:"){m=null;let C=Ke(w.slice(2));if(C)E(C,!0),S.geom=C}else m=null;let R=v.match(_e);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(S);continue}if(a||T)continue;if(!o)d(t);let y=Ke(w);if(!y)continue;E(y,!1),o.cmds.push(y),h=!1}return p(),l?{main:i,files:s,data:l}:{main:i,files:s}}var ln=Math.PI/180;function tt(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 nt(e,t){let[n,r,s,o,i,l,a,c,m,p,h,d]=e,[T,u,b,E,g,f,w,U,y,v,S,R]=t;return[o*T+i*u+l*b+n,a*T+c*u+m*b+r,p*T+h*u+d*b+s,o*E+i*w+l*v,o*g+i*U+l*S,o*f+i*y+l*R,a*E+c*w+m*v,a*g+c*U+m*S,a*f+c*y+m*R,p*E+h*w+d*v,p*g+h*U+d*S,p*f+h*y+d*R]}var ke=[0,0,0,1,0,0,0,1,0,0,0,1];var Xe=new WeakMap,$t=/^(s|8|48)\\//;function Ie(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=Xe.get(n);if(r)return r;if(n.org)r=Qe.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&&$t.test(s.file))?"part":"model";return Xe.set(n,r),r}var Ze=new WeakMap;function rt(e){let t=Ze.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 Ze.set(e,t),t}var Ye=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():String(e),jt=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Ye(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Ye(e.color)} ${e.p.join(" ")}`,Fe=(e,t)=>`${Y(e)}#${t}`;function Vt(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:Fe(e.name,t),cmds:n}}function st(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Vt(e,t).cmds.map(jt)].join(`\n`)+`\n`}function Ht(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 ot(e){let[t,n,r,s,o,i,l,a,c,m,p,h]=e,d=a*h-c*p,T=-(l*h-c*m),u=l*p-a*m,b=s*d+o*T+i*u;if(!Number.isFinite(b)||Math.abs(b)<0.000000000001)return null;let E=1/b,g=[d*E,-(o*h-i*p)*E,(o*c-i*a)*E,T*E,(s*h-i*m)*E,-(s*c-i*l)*E,u*E,-(s*p-o*m)*E,(s*a-o*l)*E];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 Gt=(e)=>String(+e.toFixed(6)||0),Je=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function it(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(Gt).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${Je(t.texture)}${t.glossmap?" GLOSSMAP "+Je(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-${Ht(r)}`,source:r}}var _t=(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 Wt(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 qe=new WeakMap;function at(e){let t=qe.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=Wt(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:_t(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),qe.set(e,n),n}var lt=999999,ct=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~";function Kt(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,l=new Map,a=0,c=(p,h)=>{let d=p.name+"#"+h,T=l.get(d);if(!T){let u;T=Object.assign(()=>u??=st(p,h),{file:p,step:h}),l.set(d,T)}return T},m=(p,h,d,T,u,b,E,g,f=null,w=[],U=[])=>{let y=p.files.get(h);if(!y||E>r)return;let v=0,S=E>0?++a:0,R=i&&S?[...w,S]:w,C=i&&S?[...U,d]:U,D=i&&!f?new Map:null,X=-1,H=0,M=(L,x,O,F,B,z)=>{if(X!==v)X=v,H=0;let j=D?.get(v+"|"+x);if(j)return j.n++,m(L,L===p?x:L.main,O,F,u+"/"+x,[...B,lt],E+1,z,[...B,lt],R,C);let I=[...B,H++],G=n.length;m(L,L===p?x:L.main,O,F,u+"/"+x,I,E+1,z,f,R,C),D?.set(v+"|"+x,{n:1,from:G,to:n.length})},A=at(y),P=s?rt(y):[],V=0,k=(L,x,O,F,B,z,j)=>{if(f)F=f;let I={part:L,color:x,m:O,step:F[0],steps:F,localStep:B,path:u};if(S){if(I.sub=S,i)I.subPath=R,I.subMats=C}if(z)I.embedded=!0;if(j){let _=it(L,j);I.texPart=_.name,I.texSource=_.source}let G=A[B];if(G)I.view=G;return n.push(I),I},N=(L)=>{while(V<P.length&&P[V]<=L){let x=P[V++];k(Fe(y.name,x),T,d,[...b,x],x,!1,null).source=c(y,x)}};for(let L of y.cmds){if(L.t===0&&L.step){v++;continue}let x=L;if(x.t>=2||x.t===0&&x.geom&&x.geom.t>=2){N(v);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 O=x.color===16?T:x.color,F=nt(d,x.m),B=[...b,v],z=o?x.tex??g:null,j=z?ot(x.m):null,I=z&&j?tt(z,j):null;if(p.files.has(x.file)){if(Ie(p,x.file)==="model"){M(p,x.file,F,O,B,I);continue}k(x.file,O,F,B,v,!0,I);continue}let G=t.resolveModel?.(x.file);if(G){M(G,x.file,F,O,B,I);continue}k(x.file,O,F,B,v,!1,I)}if(N(1/0),D){for(let L of D.values())if(L.n>1)for(let x=L.from;x<L.to;x++)n[x].mult??=L.n}};if(Ie(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...ke],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return m(e,e.main,ke,16,e.main,[],0,null),n}function ut(e,t="main.ldr",n){return Kt(et(e,t,{geometryText:!0}),n)}function Xt(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(Y(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(Y(t),r)}let l=o.trim().replace(/\\s+/g," ");if(l)r.push(l)}return n}var Zt=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Yt(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 ft(e,t,n="main.ldr"){let r=Xt(e,n),s=new Map;for(let o of t){let i=Y(o);if(!r.has(i)||s.has(i))continue;let l=new Set([i]),a=[i];while(a.length)for(let m of r.get(a.pop())){let p=Zt(m);if(p&&r.has(p)&&!l.has(p))l.add(p),a.push(p)}let c=[i,...[...l].filter((m)=>m!==i).sort()].map((m)=>"0 FILE "+(m===i?"":m)+`\n`+r.get(m).join(`\n`)).join(`\n`);s.set(i,`emb/${Yt(c)}.dat`)}return s}var pt=(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,mt=new WeakMap;function Be(e,t){let n=mt.get(e);if(!n)mt.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 T=0;T<12;T++)i[d*12+T]=h[2+T]});let c=null,m=0,p=0;if(s.mask){m=s.mask[0],p=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:m,nz:p}),r}var ie=1073741824;class Re{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 xe=(e,t,n)=>e>-ie&&e<ie&&t>-ie&&t<ie&&n>-ie&&n<ie,fe=2147483647;function Jt(e,t,n){let s=[],o=[],i=[],l=[],a=[],c=[],m=[],p=[],h=new Re(e.length*2),d=[],T=[];for(let M=0;M<e.length;M++){let A=e[M],P=A.m,V=t.parts[A.part];if(!V||!V.mask||!pt(P))continue;let k=V.bbox,N=1/0,L=-1/0,x=1/0,O=-1/0;for(let z=0;z<2;z++)for(let j=0;j<2;j++){let I=z?k[3]:k[0],G=j?k[5]:k[2],_=P[0]+P[3]*I+P[5]*G,Z=P[2]+P[9]*I+P[11]*G;if(_<N)N=_;if(_>L)L=_;if(Z<x)x=Z;if(Z>O)O=Z}let F=a.length;s.push(N),o.push(L),i.push(x),l.push(O),a.push(M),c.push(Be(t,A.part)),m.push(k[0]),p.push(k[2]);let B=Math.round((P[1]+k[4])*2);for(let z=Math.floor(N/40);z<=Math.floor(L/40);z++)for(let j=Math.floor(x/40);j<=Math.floor(O/40);j++){if(!xe(B,z,j))continue;let I=T.length;T.push(F),d.push(h.put(B,z,j,I))}}let u=[0,5,-5,5,-5],b=[0,5,5,-5,-5],E=NaN,g=NaN,f=NaN,w=-1,U=(M,A,P,V)=>{let k=Math.round(A*2),N=Math.floor(M/40),L=Math.floor(P/40);if(!xe(k,N,L))return fe;let x=fe;if(k!==E||N!==g||L!==f)E=k,g=N,f=L,w=h.get(k,N,L);for(let O=w;O>=0;O=d[O]){let F=T[O];if(a[F]===V||!(M-6>=s[F]-0.5&&M+6<=o[F]+0.5&&P-6>=i[F]-0.5&&P+6<=l[F]+0.5))continue;let B=e[a[F]].m,z=c[F],j=m[F],I=p[F],G=M-B[0],_=A-B[1],Z=P-B[2],q=B[3]*G+B[6]*_+B[9]*Z,J=B[5]*G+B[8]*_+B[11]*Z,{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((J+b[Q]-I)/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 M of e){let A=Be(t,M.part);if(A)y+=A.nStuds}let v=new Uint8Array(y),S=new Uint8Array(y),R=new Re(y),C=0,D=n?new Int32Array(y).fill(fe):void 0;for(let M=0,A=0;M<e.length;M++){let P=e[M],V=Be(t,P.part);if(!V)continue;let k=P.m,N=V.studM,L=k[0],x=k[1],O=k[2],F=k[3],B=k[4],z=k[5],j=k[6],I=k[7],G=k[8],_=k[9],Z=k[10],q=k[11];for(let J=0;J<V.nStuds;J++,A++){let ee=J*12,se=N[ee+4],ae=N[ee+7],oe=N[ee+10];if(!(Math.abs(j*se+I*ae+G*oe-1)<0.001&&Math.abs(F*se+B*ae+z*oe)<0.001&&Math.abs(_*se+Z*ae+q*oe)<0.001))continue;S[A]=1;let Q=N[ee],te=N[ee+1],ne=N[ee+2],De=L+F*Q+B*te+z*ne,Ue=x+j*Q+I*te+G*ne,ze=O+_*Q+Z*te+q*ne,Oe=U(De,Ue,ze,M);if(Oe!==fe){if(v[A]=1,C++,D)D[A]=Oe}let pe=Math.round(De),me=Math.round(Ue),he=Math.round(ze);if(!xe(pe,me,he))continue;if(!n){R.put(pe,me,he,1);continue}let Ne=n[M],$e=R.get(pe,me,he);if($e<0||Ne<$e)R.put(pe,me,he,Ne)}}let X=new Uint8Array(e.length),H=n?new Int32Array(e.length).fill(fe):void 0;for(let M=0;M<e.length;M++){let A=e[M],P=t.parts[A.part];if(!P||!P.under||!pt(A.m))continue;let V=P.bbox,k=Math.round((V[3]-V[0])/20),N=Math.round((V[5]-V[2])/20);if(!k||!N||k*N>4096)continue;let L=A.m,x=!0,O=0;for(let F=0;F<k&&x;F++)for(let B=0;B<N;B++){let z=V[0]+10+20*F,j=V[2]+10+20*B,I=L[0]+L[3]*z+L[5]*j,G=L[2]+L[9]*z+L[11]*j,_=Math.round(I),Z=Math.round(L[1]+V[4]),q=Math.round(G),J=xe(_,Z,q)?R.get(_,Z,q):-1;if(J<0){x=!1;break}if(J>O)O=J}if(x){if(X[M]=1,H)H[M]=O}}return{nStuds:y,studHidden:v,studUp:S,underHidden:X,studsHidden:C,studHideStep:D,underHideStep:H}}function qt(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)=>ct(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 we(e,t,n=!0){let r=qt(e,t,n);return Jt(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Te="https://ldr-demo.vercel.app/cdn/v1/",Me=new Map,Ae=new Map;function gt(e=Te,t=fetch){let n=Me.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(()=>Me.delete(e)),Me.set(e,n);return n}var Qt=(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)=>Qt(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 en(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 T=new DataView(d).getUint32(0,!0),u=new Uint8Array(d,4+T),b=r;n.push(u),r+=u.byteLength;let E=(4-r%4)%4;if(E)n.push(new Uint8Array(E)),r+=E;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,m=new Uint8Array(c+r);new DataView(m.buffer).setUint32(0,l.length+a,!0),m.set(l,4),m.fill(32,4+l.length,c);let p=c;for(let h of n)m.set(h,p),p+=h.byteLength;return ye(m.buffer)}async function tn(e,t={}){e=[...e];try{return await ht(e,t)}catch(n){let r=t.cdn??Te,s=t.fetch??fetch;Me.delete(r);let o=(i,l)=>s(i,{...l,cache:"reload"});try{return await ht(e,{...t,fetch:o})}catch{throw n}}}async function ht(e,t){let n=t.cdn??Te,r=t.fetch??fetch,s=t.gap??16384,o=await gt(n,r),i=[...new Set([...e].map(Y))],l=[],a=[];for(let u of i){if(Ae.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 m=0,p=0,h=async()=>{while(p<c.length){let u=c[p++],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 E=new Uint8Array(await b.arrayBuffer());if(b.status===200)E=E.subarray(u.start,u.end);m+=E.byteLength;for(let g of u.items){let f=de(E.subarray(g.off-u.start,g.off-u.start+g.len)),w=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);Ae.set(n+g.name,ye(w))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,c.length)},h));let d=i.filter((u)=>Ae.has(n+u)).map((u)=>Ae.get(n+u));return{pack:d.length?en(d,{colors:o.colors}):ye(nn(o.colors)),missing:l,requests:c.length,bytes:m}}function nn(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}function rn(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}class Ce 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 bt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=gt(t.cdn??Te,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(f)=>{if(!f.ok)throw Error(`ldr: ${f.status} fetching ${e}`);return He(await f.arrayBuffer())}),i=performance.now(),l=t.name??(t.text?"main.ldr":Ge(e)),a=ut(o,l,{looseGeometry:!1,callouts:t.callouts}),c=performance.now();t.onParsed?.(a),await s;let m=ft(o,new Set(a.filter((f)=>f.embedded).map((f)=>f.part)),l),{pack:p,missing:h,requests:d,bytes:T}=await tn([...a.filter((f)=>!f.embedded).map((f)=>f.part),...m.values()],t),u=new Map([...m].map(([f,w])=>[w,f])),b=h.map((f)=>u.get(f)??f);for(let[f,w]of m){let U=p.header.parts[w];if(U)p.header.parts[f]=U}let E=performance.now();if(t.maxBodyTris!=null||t.maxPackBytes!=null){let f=p.buffer?.byteLength??p.bytes??0,w=rn(a,p);if(t.maxBodyTris!=null&&w>t.maxBodyTris||t.maxPackBytes!=null&&f>t.maxPackBytes)throw new Ce({bodyTris:w,packBytes:f,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes})}let g=t.cull?we(a,p.header,t.textures!==!1):void 0;return{insts:a,pack:p,missing:b,requests:d,bytes:T,cull:g,timings:{fetchModel:i-n,parse:c-i,parts:E-c,...g?{cull:performance.now()-E}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await bt(n,{...r,cull:!1,onParsed:(m)=>self.postMessage({id:t,insts:m})}),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=we(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,c=[];for(let m of[l.studHidden,l.studUp,l.underHidden,l.studHideStep,l.underHideStep])if(m)c.push(m.buffer);self.postMessage({id:t,cull:l,ms:a},c)}catch(s){if(s instanceof Ce||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';
|
|
3866
3866
|
|
|
3867
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3867
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/cdn.ts
|
|
3868
3868
|
var worker;
|
|
3869
3869
|
var seq = 0;
|
|
3870
3870
|
var pending = new Map;
|
|
@@ -12,7 +12,7 @@ export interface BuildPackOptions {
|
|
|
12
12
|
allParts?: boolean;
|
|
13
13
|
/** Stud geometry: 'low' uses p/8 low-res primitives (default, ~visually lossless at distance); 'full' keeps full detail. */
|
|
14
14
|
studs?: "low" | "full";
|
|
15
|
-
/** Non-stud primitive detail.
|
|
15
|
+
/** Non-stud primitive detail: 'low' uses p/8 (default, matches studs; ~25% fewer body tris on Technic). 'full' keeps hi-res / 48 primitives. */
|
|
16
16
|
primitives?: "low" | "full";
|
|
17
17
|
/** Weld + index vertices (smaller GPU buffers, faster). Default true. */
|
|
18
18
|
weld?: boolean;
|
package/dist/node/index.d.ts
CHANGED
|
@@ -5,3 +5,5 @@ export type { BuildPackOptions, BuildPackResult } from "./build-pack.js";
|
|
|
5
5
|
export { Compiler, encodePack, writePack, loadColors } from "./compile.js";
|
|
6
6
|
export type { Compiled, Opts as CompileOptions, Bucket } from "./compile.js";
|
|
7
7
|
export { Library as ResolverLibrary, splitModel, flatten as flattenWithLibrary, collectDeps } from "./resolver.js";
|
|
8
|
+
export { promoteFlexParts, decimateFlexGeometry, prepareFlexParts } from "./promote.js";
|
|
9
|
+
export type { DecimateFlexOptions } from "./promote.js";
|
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/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-
|
|
693
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/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 = {}) {
|
|
@@ -1039,7 +1039,7 @@ function parseLDConfig(text) {
|
|
|
1039
1039
|
}
|
|
1040
1040
|
return out;
|
|
1041
1041
|
}
|
|
1042
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1042
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/instructions.ts
|
|
1043
1043
|
var MIN_VIS = 0.5;
|
|
1044
1044
|
var REORIENT = 0.35;
|
|
1045
1045
|
var deg = Math.PI / 180;
|
|
@@ -1407,10 +1407,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
|
|
|
1407
1407
|
}
|
|
1408
1408
|
};
|
|
1409
1409
|
}
|
|
1410
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1410
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/render.ts
|
|
1411
1411
|
import * as THREE from "three";
|
|
1412
1412
|
|
|
1413
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1413
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/pack-io.ts
|
|
1414
1414
|
import { decompress } from "fzstd";
|
|
1415
1415
|
async function decompressPack(data) {
|
|
1416
1416
|
const u = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
@@ -1433,7 +1433,7 @@ function decodePack(buf) {
|
|
|
1433
1433
|
return { header, arr, bytes: buf.byteLength, buffer: buf };
|
|
1434
1434
|
}
|
|
1435
1435
|
|
|
1436
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1436
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/cull.ts
|
|
1437
1437
|
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;
|
|
1438
1438
|
var prepCache = new WeakMap;
|
|
1439
1439
|
function prepPart(H, part) {
|
|
@@ -1750,7 +1750,7 @@ function precomputeCull(instances, H, useTex = true) {
|
|
|
1750
1750
|
return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
|
|
1751
1751
|
}
|
|
1752
1752
|
|
|
1753
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1753
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/render.ts
|
|
1754
1754
|
async function loadPack(url) {
|
|
1755
1755
|
const res = await fetch(url);
|
|
1756
1756
|
if (!res.ok)
|
|
@@ -3372,7 +3372,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
|
|
|
3372
3372
|
await new Promise((r) => setTimeout(r, 0));
|
|
3373
3373
|
}
|
|
3374
3374
|
}
|
|
3375
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3375
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/scene.ts
|
|
3376
3376
|
import * as THREE2 from "three";
|
|
3377
3377
|
function colorFn(src, pack, fallback) {
|
|
3378
3378
|
const table = new Map;
|
|
@@ -3589,10 +3589,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
|
|
|
3589
3589
|
return finish();
|
|
3590
3590
|
})();
|
|
3591
3591
|
}
|
|
3592
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3592
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/parts-cdn.ts
|
|
3593
3593
|
import { decompress as decompress2 } from "fzstd";
|
|
3594
3594
|
|
|
3595
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3595
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/embedded.ts
|
|
3596
3596
|
function splitFiles(text, fallback) {
|
|
3597
3597
|
const files = new Map;
|
|
3598
3598
|
let cur = null, saw = false;
|
|
@@ -3664,7 +3664,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
|
|
|
3664
3664
|
return out;
|
|
3665
3665
|
}
|
|
3666
3666
|
|
|
3667
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3667
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/parts-cdn.ts
|
|
3668
3668
|
var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
|
|
3669
3669
|
var indexCache = new Map;
|
|
3670
3670
|
var shardCache = new Map;
|
|
@@ -3862,10 +3862,10 @@ async function prepareModel(source, o = {}) {
|
|
|
3862
3862
|
return { insts, pack, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
|
|
3863
3863
|
}
|
|
3864
3864
|
|
|
3865
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3865
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/load-worker.gen.ts
|
|
3866
3866
|
var load_worker_gen_default = 'var dt=ArrayBuffer,W=Uint8Array,ge=Uint16Array,yt=Int16Array;var be=Int32Array,Ee=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},ce=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},xt=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 wt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],K=function(e,t,n){var r=Error(t||wt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,K);if(!n)throw r;return r},je=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},At=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Mt=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)K(0);var a=6-s,c=i==3?4:i,m=je(e,a,c);a+=c;var p=l?1<<l:s,h=je(e,a,p)+(l==1&&256),d=h;if(!s){var T=1<<10+(e[5]>>3);d=T+(T>>3)*(e[5]&7)}if(d>2145386496)K(1);var u=new W((t==1?h||d:t?0:d)+12);return u[0]=1,u[4]=4,u[8]=8,{b:a+p,y:0,l:0,d:m,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 At(e,4)+8;K(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)K(3);var o=1<<s,i=o,l=-1,a=-1,c=-1,m=o,p=new dt(512+(o<<2)),h=new yt(p,0,256),d=new ge(p,0,256),T=new ge(p,512,o),u=512+(o<<1),b=new W(p,u,o),E=new W(p,u+o);while(l<255&&i>0){var g=re(i+1),f=r>>3,w=(1<<g+1)-1,U=(e[f]|e[f+1]<<8|e[f+2]<<16)>>(r&7)&w,y=(1<<g)-1,v=w-i-1,S=U&y;if(S<v)r+=g,U=S;else if(r+=g+1,U>y)U-=v;if(h[++l]=--U,U==-1)i+=U,b[--m]=l;else i-=U;if(!U)do{var R=r>>3;a=(e[R]|e[R+1]<<8)>>(r&7)&3,r+=2,l+=a}while(a==3)}if(l>255||i)K(0);var C=0,D=(o>>1)+(o>>3)+3,X=o-1;for(var H=0;H<=l;++H){var M=h[H];if(M<1){d[H]=-M;continue}for(c=0;c<M;++c){b[C]=H;do C=C+D&X;while(C>=m)}}if(C)K(0);for(c=0;c<o;++c){var A=d[b[c]]++,P=E[c]=s-re(A);T[c]=(A<<P)-o}return[r+7>>3,{b:s,s:b,n:E,t:T}]},vt=function(e,t){var n=0,r=-1,s=new W(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),m=c[0],p=c[1];t+=o;var h=m<<3,d=e[t];if(!d)K(0);var T=0,u=0,b=p.b,E=b,g=(++t<<3)-8+re(d);for(;;){if(g-=b,g<h)break;var f=g>>3;if(T+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<b)-1,i[++r]=p.s[T],g-=E,g<h)break;f=g>>3,u+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<E)-1,i[++r]=p.s[u],b=p.n[T],T=p.t[T],E=p.n[u],u=p.t[u]}if(++r>255)K(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 U=0;for(n=0;n<r;++n){var y=i[n];if(y>11)K(0);U+=y&&1<<y-1}var v=re(U)+1,S=1<<v,R=S-U;if(R&R-1)K(0);i[r++]=re(R)+1;for(n=0;n<r;++n){var y=i[n];++l[i[n]=y&&v+1-y]}var C=new W(S<<1),D=C.subarray(0,S),X=C.subarray(S);a[v]=0;for(n=v;n>0;--n){var H=a[n];ce(X,n,H,a[n-1]=H+l[n]*(1<<v-n))}if(a[0]!=S)K(0);for(n=0;n<r;++n){var M=i[n];if(M){var A=a[M];ce(D,n,A,a[M]=A+(1<<v-M))}}return[t,{n:X,b:v,s:D}]},Tt=ue(new W([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],Ct=ue(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],Et=ue(new W([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],Ve=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},Se=new W(new be([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),St=Ve(Se,0),Le=new W(new be([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),Lt=Ve(Le,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)K(0);var a=0,c=n.b,m=(r<<3)-8+re(o)-c,p=-1;for(;m>l&&p<s;){var h=m>>3,d=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(m&7);a=(a<<c|d)&i,t[++p]=n.s[a],m-=c=n.n[a]}if(m!=l||p+1!=s)K(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)},kt=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 W(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 Ee(e,s,a)}if(i==2){var c=e[s],m=c&3,p=c>>2&3,h=c>>4,d=0,T=0;if(m<2)if(p&1)h|=e[++s]<<4|(p&2&&e[++s]<<12);else h=c>>3;else if(T=p,p<2)h|=(e[++s]&63)<<4,d=e[s]>>6|e[++s]<<2;else if(p==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 W(t.m),b=u.length-h;if(m==0)u.set(e.subarray(s,s+=h),b);else if(m==1)ce(u,e[s++],b);else{var E=t.h;if(m==2){var g=vt(e,s);d+=s-(s=g[0]),t.h=E=g[1]}else if(!E)K(0);(T?Pt:le)(e.subarray(s,s+=d),u.subarray(b),E)}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 w=e[s++];if(w&3)K(0);var U=[Ct,Et,Tt];for(var y=2;y>-1;--y){var v=w>>(y<<1)+2&3;if(v==1){var S=new W([0,0,e[s++]]);U[y]={s:S.subarray(2,3),n:S.subarray(0,1),t:new ge(S.buffer,0,1),b:0}}else if(v==2)r=ue(e,s,9-(y&1)),s=r[0],U[y]=r[1];else if(v==3){if(!t.t)K(0);U[y]=t.t[y]}}var R=t.t=U,C=R[0],D=R[1],X=R[2],H=e[a-1];if(!H)K(0);var M=(a<<3)-8+re(H)-X.b,A=M>>3,P=0,V=(e[A]|e[A+1]<<8)>>(M&7)&(1<<X.b)-1;A=(M-=D.b)>>3;var k=(e[A]|e[A+1]<<8)>>(M&7)&(1<<D.b)-1;A=(M-=C.b)>>3;var N=(e[A]|e[A+1]<<8)>>(M&7)&(1<<C.b)-1;for(++f;--f;){var L=X.s[V],x=X.n[V],O=C.s[N],F=C.n[N],B=D.s[k],z=D.n[k];A=(M-=B)>>3;var j=1<<B,I=j+((e[A]|e[A+1]<<8|e[A+2]<<16|e[A+3]<<24)>>>(M&7)&j-1);A=(M-=Le[O])>>3;var G=Lt[O]+((e[A]|e[A+1]<<8|e[A+2]<<16)>>(M&7)&(1<<Le[O])-1);A=(M-=Se[L])>>3;var _=St[L]+((e[A]|e[A+1]<<8|e[A+2]<<16)>>(M&7)&(1<<Se[L])-1);if(A=(M-=x)>>3,V=X.t[V]+((e[A]|e[A+1]<<8)>>(M&7)&(1<<x)-1),A=(M-=F)>>3,N=C.t[N]+((e[A]|e[A+1]<<8)>>(M&7)&(1<<F)-1),A=(M-=z)>>3,k=D.t[k]+((e[A]|e[A+1]<<8)>>(M&7)&(1<<z)-1),I>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=I-=3;else{var Z=I-(_!=0);if(Z){if(I=Z==3?t.o[0]-1:t.o[Z],Z>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=I}else I=t.o[0]}for(var y=0;y<_;++y)u[P+y]=u[b+y];P+=_,b+=_;var q=P-I;if(q<0){var J=-q,ee=t.e+q;if(J>G)J=G;for(var y=0;y<J;++y)u[P+y]=t.w[ee+y];P+=J,G-=J,q=0}for(var y=0;y<G;++y)u[P+y]=u[q+y];P+=G}if(P!=b)while(b<u.length)u[P++]=u[b++];else P=u.length;if(n)t.y+=P;else u=Ee(u,0,P)}else if(n){if(t.y+=h,b)for(var y=0;y<h;++y)u[y]=u[b+y]}else if(b)u=Ee(u,b);return t.b=a,u}K(2)},It=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 de(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Mt(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=kt(e,i,t);if(!l)K(5);if(t)i.e=i.y;else n.push(l),o+=l.length,xt(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 It(n,o)}async function Ft(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(de(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 He(e){return new TextDecoder().decode(await Ft(e))}var Ge=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function ye(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,"/");function Pe(e){if(/^0x/i.test(e))return parseInt(e,16);return+e}var _e=/^~?\\s*moved\\s+to\\s+(.+)$/i,Bt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Qe=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Rt=new Set(["model","submodel","configuration"]),Dt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function We(e){let t=Dt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Qe.has(n)||Rt.has(n)?n:void 0}function Ut(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function zt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every(Number.isFinite))return null;let l=n[2].trim();for(let p=0;p<s;p++)l=l.replace(/^\\S+\\s*/,"");let a=Ut(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 m=a.findIndex((p,h)=>h>0&&p.toUpperCase()==="GLOSSMAP");if(m>0&&a[m+1])c.glossmap=a[m+1];if(t)c.next=!0;return c}var Ot=(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 Nt(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 m=s();if(m===null)return null;i[c]=+m}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:Pe(o),m:i,file:Y(a)}}function Ke(e){let t=+e[0];if(!(t>=1&&t<=5)||e.length<2)return null;let n=Pe(e[1]),r=e.slice(2).map(Number);if(t===1)return{t:1,color:n,m:r.slice(0,12),file:Y(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 et(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",l,a=null,c=[],m=null,p=()=>{if(!a)return;let g=Ot(a.chunks.join("")),f=g[0]===137&&g[1]===80&&g[2]===78&&g[3]===71;(l??=new Map).set(Y(a.name),{name:a.name,bytes:g,...f?{mime:"image/png"}:{}}),a=null},h=!0,d=(g)=>{if(p(),o={name:Y(g),cmds:[]},s.set(o.name,o),!i)i=o.name;c=[],m=null,h=!0},T=!1,u=!1,b=()=>{if(u)return;u=!0,s.clear(),o=null,i=""},E=(g,f)=>{if(m){g.tex=m,m=null;return}let w=c[c.length-1];if(!w)return;if(w.fallback){if(!f)g.fallback=!0}else g.tex=w.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||T)continue;if(!o)d(t);let v=f.slice(2).trimStart(),S=v.search(/\\s/),R={t:f.charCodeAt(0)-48,color:Pe(S<0?v:v.slice(0,S)),p:[],src:f};E(R,!1),o.cmds.push(R),h=!1;continue}if(f.charCodeAt(0)===48&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)){let v=2;while(f.charCodeAt(v)===32||f.charCodeAt(v)===9)v++;let S=v;while(S<f.length&&f.charCodeAt(S)!==32&&f.charCodeAt(S)!==9)S++;let R=f.slice(v,S);if(!Bt.has(R)){if(T||a)continue;if(!o)d(t);let C=f.slice(v),D={t:0,text:C};if(R.charCodeAt(0)===33)D.meta=R;if(m=null,h&&!o.org){let H=We(C);if(H)o.org=H}let X=C.match(_e);if(X&&!o.movedTo){let H=X[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(H))H+=".dat";o.movedTo=Y(H)}o.cmds.push(D);continue}}if(f.charCodeAt(0)===49&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)&&!a&&!T){let v=Nt(f);if(v){if(!o)d(t);E(v,!1),o.cmds.push(v),h=!1;continue}}let w=f.split(/\\s+/);if(+w[0]===0){let v=f.slice(1).trim();if(w[1]==="FILE"){b(),T=!1,d(v.slice(5));continue}if(w[1]==="NOFILE"){p(),o=null,T=!0;continue}if(w[1]==="!DATA"){b(),p(),o=null,T=!1,a={name:v.slice(5).trim(),chunks:[]};continue}if(T)continue;if(a){if(w[1]==="!:")a.chunks.push(w.slice(2).join(""));continue}if(!o)d(t);let S={t:0,text:v};if(w[1]==="STEP")S.step=!0,c=[],m=null;else if(w[1]==="BFC")S.bfc=w.slice(2).join(" ");else if(w[1]==="ROTSTEP")if(S.meta="ROTSTEP",S.step=!0,c=[],m=null,(w[2]??"").toUpperCase()==="END")S.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(w[5]??"REL").toUpperCase();S.rotstep={x:+w[2]||0,y:+w[3]||0,z:+w[4]||0,mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(w[1]==="BUFEXCHG"){S.meta="BUFEXCHG";let C=(w[2]??"").toUpperCase();S.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:w[3]??"A"}}else if(w[1]?.startsWith("!"))S.meta=w[1];if(h&&!o.org){let C=We(v);if(C)o.org=C}if(w[1]==="!TEXMAP"){let C=(w[2]??"").toUpperCase();if(m=null,C==="START"||C==="NEXT"){let D=zt(v.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(S.texmap={op:C,...D?{map:D}:{}},D)if((o.texmaps??=[]).push(D),C==="START")c.push({map:D,fallback:!1});else m=D}else if(C==="FALLBACK"){S.texmap={op:C};let D=c[c.length-1];if(D)D.fallback=!0}else if(C==="END")S.texmap={op:C},c.pop()}else if(w[1]==="!:"){m=null;let C=Ke(w.slice(2));if(C)E(C,!0),S.geom=C}else m=null;let R=v.match(_e);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(S);continue}if(a||T)continue;if(!o)d(t);let y=Ke(w);if(!y)continue;E(y,!1),o.cmds.push(y),h=!1}return p(),l?{main:i,files:s,data:l}:{main:i,files:s}}var ln=Math.PI/180;function tt(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 nt(e,t){let[n,r,s,o,i,l,a,c,m,p,h,d]=e,[T,u,b,E,g,f,w,U,y,v,S,R]=t;return[o*T+i*u+l*b+n,a*T+c*u+m*b+r,p*T+h*u+d*b+s,o*E+i*w+l*v,o*g+i*U+l*S,o*f+i*y+l*R,a*E+c*w+m*v,a*g+c*U+m*S,a*f+c*y+m*R,p*E+h*w+d*v,p*g+h*U+d*S,p*f+h*y+d*R]}var ke=[0,0,0,1,0,0,0,1,0,0,0,1];var Xe=new WeakMap,$t=/^(s|8|48)\\//;function Ie(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=Xe.get(n);if(r)return r;if(n.org)r=Qe.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&&$t.test(s.file))?"part":"model";return Xe.set(n,r),r}var Ze=new WeakMap;function rt(e){let t=Ze.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 Ze.set(e,t),t}var Ye=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():String(e),jt=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Ye(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Ye(e.color)} ${e.p.join(" ")}`,Fe=(e,t)=>`${Y(e)}#${t}`;function Vt(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:Fe(e.name,t),cmds:n}}function st(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Vt(e,t).cmds.map(jt)].join(`\n`)+`\n`}function Ht(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 ot(e){let[t,n,r,s,o,i,l,a,c,m,p,h]=e,d=a*h-c*p,T=-(l*h-c*m),u=l*p-a*m,b=s*d+o*T+i*u;if(!Number.isFinite(b)||Math.abs(b)<0.000000000001)return null;let E=1/b,g=[d*E,-(o*h-i*p)*E,(o*c-i*a)*E,T*E,(s*h-i*m)*E,-(s*c-i*l)*E,u*E,-(s*p-o*m)*E,(s*a-o*l)*E];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 Gt=(e)=>String(+e.toFixed(6)||0),Je=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function it(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(Gt).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${Je(t.texture)}${t.glossmap?" GLOSSMAP "+Je(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-${Ht(r)}`,source:r}}var _t=(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 Wt(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 qe=new WeakMap;function at(e){let t=qe.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=Wt(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:_t(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),qe.set(e,n),n}var lt=999999,ct=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~";function Kt(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,l=new Map,a=0,c=(p,h)=>{let d=p.name+"#"+h,T=l.get(d);if(!T){let u;T=Object.assign(()=>u??=st(p,h),{file:p,step:h}),l.set(d,T)}return T},m=(p,h,d,T,u,b,E,g,f=null,w=[],U=[])=>{let y=p.files.get(h);if(!y||E>r)return;let v=0,S=E>0?++a:0,R=i&&S?[...w,S]:w,C=i&&S?[...U,d]:U,D=i&&!f?new Map:null,X=-1,H=0,M=(L,x,O,F,B,z)=>{if(X!==v)X=v,H=0;let j=D?.get(v+"|"+x);if(j)return j.n++,m(L,L===p?x:L.main,O,F,u+"/"+x,[...B,lt],E+1,z,[...B,lt],R,C);let I=[...B,H++],G=n.length;m(L,L===p?x:L.main,O,F,u+"/"+x,I,E+1,z,f,R,C),D?.set(v+"|"+x,{n:1,from:G,to:n.length})},A=at(y),P=s?rt(y):[],V=0,k=(L,x,O,F,B,z,j)=>{if(f)F=f;let I={part:L,color:x,m:O,step:F[0],steps:F,localStep:B,path:u};if(S){if(I.sub=S,i)I.subPath=R,I.subMats=C}if(z)I.embedded=!0;if(j){let _=it(L,j);I.texPart=_.name,I.texSource=_.source}let G=A[B];if(G)I.view=G;return n.push(I),I},N=(L)=>{while(V<P.length&&P[V]<=L){let x=P[V++];k(Fe(y.name,x),T,d,[...b,x],x,!1,null).source=c(y,x)}};for(let L of y.cmds){if(L.t===0&&L.step){v++;continue}let x=L;if(x.t>=2||x.t===0&&x.geom&&x.geom.t>=2){N(v);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 O=x.color===16?T:x.color,F=nt(d,x.m),B=[...b,v],z=o?x.tex??g:null,j=z?ot(x.m):null,I=z&&j?tt(z,j):null;if(p.files.has(x.file)){if(Ie(p,x.file)==="model"){M(p,x.file,F,O,B,I);continue}k(x.file,O,F,B,v,!0,I);continue}let G=t.resolveModel?.(x.file);if(G){M(G,x.file,F,O,B,I);continue}k(x.file,O,F,B,v,!1,I)}if(N(1/0),D){for(let L of D.values())if(L.n>1)for(let x=L.from;x<L.to;x++)n[x].mult??=L.n}};if(Ie(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...ke],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return m(e,e.main,ke,16,e.main,[],0,null),n}function ut(e,t="main.ldr",n){return Kt(et(e,t,{geometryText:!0}),n)}function Xt(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(Y(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(Y(t),r)}let l=o.trim().replace(/\\s+/g," ");if(l)r.push(l)}return n}var Zt=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Yt(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 ft(e,t,n="main.ldr"){let r=Xt(e,n),s=new Map;for(let o of t){let i=Y(o);if(!r.has(i)||s.has(i))continue;let l=new Set([i]),a=[i];while(a.length)for(let m of r.get(a.pop())){let p=Zt(m);if(p&&r.has(p)&&!l.has(p))l.add(p),a.push(p)}let c=[i,...[...l].filter((m)=>m!==i).sort()].map((m)=>"0 FILE "+(m===i?"":m)+`\n`+r.get(m).join(`\n`)).join(`\n`);s.set(i,`emb/${Yt(c)}.dat`)}return s}var pt=(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,mt=new WeakMap;function Be(e,t){let n=mt.get(e);if(!n)mt.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 T=0;T<12;T++)i[d*12+T]=h[2+T]});let c=null,m=0,p=0;if(s.mask){m=s.mask[0],p=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:m,nz:p}),r}var ie=1073741824;class Re{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 xe=(e,t,n)=>e>-ie&&e<ie&&t>-ie&&t<ie&&n>-ie&&n<ie,fe=2147483647;function Jt(e,t,n){let s=[],o=[],i=[],l=[],a=[],c=[],m=[],p=[],h=new Re(e.length*2),d=[],T=[];for(let M=0;M<e.length;M++){let A=e[M],P=A.m,V=t.parts[A.part];if(!V||!V.mask||!pt(P))continue;let k=V.bbox,N=1/0,L=-1/0,x=1/0,O=-1/0;for(let z=0;z<2;z++)for(let j=0;j<2;j++){let I=z?k[3]:k[0],G=j?k[5]:k[2],_=P[0]+P[3]*I+P[5]*G,Z=P[2]+P[9]*I+P[11]*G;if(_<N)N=_;if(_>L)L=_;if(Z<x)x=Z;if(Z>O)O=Z}let F=a.length;s.push(N),o.push(L),i.push(x),l.push(O),a.push(M),c.push(Be(t,A.part)),m.push(k[0]),p.push(k[2]);let B=Math.round((P[1]+k[4])*2);for(let z=Math.floor(N/40);z<=Math.floor(L/40);z++)for(let j=Math.floor(x/40);j<=Math.floor(O/40);j++){if(!xe(B,z,j))continue;let I=T.length;T.push(F),d.push(h.put(B,z,j,I))}}let u=[0,5,-5,5,-5],b=[0,5,5,-5,-5],E=NaN,g=NaN,f=NaN,w=-1,U=(M,A,P,V)=>{let k=Math.round(A*2),N=Math.floor(M/40),L=Math.floor(P/40);if(!xe(k,N,L))return fe;let x=fe;if(k!==E||N!==g||L!==f)E=k,g=N,f=L,w=h.get(k,N,L);for(let O=w;O>=0;O=d[O]){let F=T[O];if(a[F]===V||!(M-6>=s[F]-0.5&&M+6<=o[F]+0.5&&P-6>=i[F]-0.5&&P+6<=l[F]+0.5))continue;let B=e[a[F]].m,z=c[F],j=m[F],I=p[F],G=M-B[0],_=A-B[1],Z=P-B[2],q=B[3]*G+B[6]*_+B[9]*Z,J=B[5]*G+B[8]*_+B[11]*Z,{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((J+b[Q]-I)/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 M of e){let A=Be(t,M.part);if(A)y+=A.nStuds}let v=new Uint8Array(y),S=new Uint8Array(y),R=new Re(y),C=0,D=n?new Int32Array(y).fill(fe):void 0;for(let M=0,A=0;M<e.length;M++){let P=e[M],V=Be(t,P.part);if(!V)continue;let k=P.m,N=V.studM,L=k[0],x=k[1],O=k[2],F=k[3],B=k[4],z=k[5],j=k[6],I=k[7],G=k[8],_=k[9],Z=k[10],q=k[11];for(let J=0;J<V.nStuds;J++,A++){let ee=J*12,se=N[ee+4],ae=N[ee+7],oe=N[ee+10];if(!(Math.abs(j*se+I*ae+G*oe-1)<0.001&&Math.abs(F*se+B*ae+z*oe)<0.001&&Math.abs(_*se+Z*ae+q*oe)<0.001))continue;S[A]=1;let Q=N[ee],te=N[ee+1],ne=N[ee+2],De=L+F*Q+B*te+z*ne,Ue=x+j*Q+I*te+G*ne,ze=O+_*Q+Z*te+q*ne,Oe=U(De,Ue,ze,M);if(Oe!==fe){if(v[A]=1,C++,D)D[A]=Oe}let pe=Math.round(De),me=Math.round(Ue),he=Math.round(ze);if(!xe(pe,me,he))continue;if(!n){R.put(pe,me,he,1);continue}let Ne=n[M],$e=R.get(pe,me,he);if($e<0||Ne<$e)R.put(pe,me,he,Ne)}}let X=new Uint8Array(e.length),H=n?new Int32Array(e.length).fill(fe):void 0;for(let M=0;M<e.length;M++){let A=e[M],P=t.parts[A.part];if(!P||!P.under||!pt(A.m))continue;let V=P.bbox,k=Math.round((V[3]-V[0])/20),N=Math.round((V[5]-V[2])/20);if(!k||!N||k*N>4096)continue;let L=A.m,x=!0,O=0;for(let F=0;F<k&&x;F++)for(let B=0;B<N;B++){let z=V[0]+10+20*F,j=V[2]+10+20*B,I=L[0]+L[3]*z+L[5]*j,G=L[2]+L[9]*z+L[11]*j,_=Math.round(I),Z=Math.round(L[1]+V[4]),q=Math.round(G),J=xe(_,Z,q)?R.get(_,Z,q):-1;if(J<0){x=!1;break}if(J>O)O=J}if(x){if(X[M]=1,H)H[M]=O}}return{nStuds:y,studHidden:v,studUp:S,underHidden:X,studsHidden:C,studHideStep:D,underHideStep:H}}function qt(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)=>ct(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 we(e,t,n=!0){let r=qt(e,t,n);return Jt(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Te="https://ldr-demo.vercel.app/cdn/v1/",Me=new Map,Ae=new Map;function gt(e=Te,t=fetch){let n=Me.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(()=>Me.delete(e)),Me.set(e,n);return n}var Qt=(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)=>Qt(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 en(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 T=new DataView(d).getUint32(0,!0),u=new Uint8Array(d,4+T),b=r;n.push(u),r+=u.byteLength;let E=(4-r%4)%4;if(E)n.push(new Uint8Array(E)),r+=E;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,m=new Uint8Array(c+r);new DataView(m.buffer).setUint32(0,l.length+a,!0),m.set(l,4),m.fill(32,4+l.length,c);let p=c;for(let h of n)m.set(h,p),p+=h.byteLength;return ye(m.buffer)}async function tn(e,t={}){e=[...e];try{return await ht(e,t)}catch(n){let r=t.cdn??Te,s=t.fetch??fetch;Me.delete(r);let o=(i,l)=>s(i,{...l,cache:"reload"});try{return await ht(e,{...t,fetch:o})}catch{throw n}}}async function ht(e,t){let n=t.cdn??Te,r=t.fetch??fetch,s=t.gap??16384,o=await gt(n,r),i=[...new Set([...e].map(Y))],l=[],a=[];for(let u of i){if(Ae.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 m=0,p=0,h=async()=>{while(p<c.length){let u=c[p++],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 E=new Uint8Array(await b.arrayBuffer());if(b.status===200)E=E.subarray(u.start,u.end);m+=E.byteLength;for(let g of u.items){let f=de(E.subarray(g.off-u.start,g.off-u.start+g.len)),w=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);Ae.set(n+g.name,ye(w))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,c.length)},h));let d=i.filter((u)=>Ae.has(n+u)).map((u)=>Ae.get(n+u));return{pack:d.length?en(d,{colors:o.colors}):ye(nn(o.colors)),missing:l,requests:c.length,bytes:m}}function nn(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}function rn(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}class Ce 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 bt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=gt(t.cdn??Te,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(f)=>{if(!f.ok)throw Error(`ldr: ${f.status} fetching ${e}`);return He(await f.arrayBuffer())}),i=performance.now(),l=t.name??(t.text?"main.ldr":Ge(e)),a=ut(o,l,{looseGeometry:!1,callouts:t.callouts}),c=performance.now();t.onParsed?.(a),await s;let m=ft(o,new Set(a.filter((f)=>f.embedded).map((f)=>f.part)),l),{pack:p,missing:h,requests:d,bytes:T}=await tn([...a.filter((f)=>!f.embedded).map((f)=>f.part),...m.values()],t),u=new Map([...m].map(([f,w])=>[w,f])),b=h.map((f)=>u.get(f)??f);for(let[f,w]of m){let U=p.header.parts[w];if(U)p.header.parts[f]=U}let E=performance.now();if(t.maxBodyTris!=null||t.maxPackBytes!=null){let f=p.buffer?.byteLength??p.bytes??0,w=rn(a,p);if(t.maxBodyTris!=null&&w>t.maxBodyTris||t.maxPackBytes!=null&&f>t.maxPackBytes)throw new Ce({bodyTris:w,packBytes:f,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes})}let g=t.cull?we(a,p.header,t.textures!==!1):void 0;return{insts:a,pack:p,missing:b,requests:d,bytes:T,cull:g,timings:{fetchModel:i-n,parse:c-i,parts:E-c,...g?{cull:performance.now()-E}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await bt(n,{...r,cull:!1,onParsed:(m)=>self.postMessage({id:t,insts:m})}),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=we(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,c=[];for(let m of[l.studHidden,l.studUp,l.underHidden,l.studHideStep,l.underHideStep])if(m)c.push(m.buffer);self.postMessage({id:t,cull:l,ms:a},c)}catch(s){if(s instanceof Ce||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';
|
|
3867
3867
|
|
|
3868
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3868
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/cdn.ts
|
|
3869
3869
|
var worker;
|
|
3870
3870
|
var seq = 0;
|
|
3871
3871
|
var pending = new Map;
|
|
@@ -3978,7 +3978,7 @@ async function loadModel(source, o = {}) {
|
|
|
3978
3978
|
timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
|
|
3979
3979
|
});
|
|
3980
3980
|
}
|
|
3981
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3981
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/library.ts
|
|
3982
3982
|
import { existsSync, readFileSync } from "fs";
|
|
3983
3983
|
import { join } from "path";
|
|
3984
3984
|
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]];
|
|
@@ -4229,11 +4229,11 @@ class Library {
|
|
|
4229
4229
|
return insts;
|
|
4230
4230
|
}
|
|
4231
4231
|
}
|
|
4232
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4232
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/build-pack.ts
|
|
4233
4233
|
import fs3 from "node:fs";
|
|
4234
4234
|
import path3 from "node:path";
|
|
4235
4235
|
|
|
4236
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4236
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/resolver.ts
|
|
4237
4237
|
import fs from "node:fs";
|
|
4238
4238
|
import path from "node:path";
|
|
4239
4239
|
var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
|
|
@@ -4505,11 +4505,11 @@ function collectDeps(lib, refs) {
|
|
|
4505
4505
|
return out;
|
|
4506
4506
|
}
|
|
4507
4507
|
|
|
4508
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4508
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/compile.ts
|
|
4509
4509
|
import fs2 from "node:fs";
|
|
4510
4510
|
import path2 from "node:path";
|
|
4511
4511
|
|
|
4512
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4512
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/lod.ts
|
|
4513
4513
|
import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
|
|
4514
4514
|
await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
|
|
4515
4515
|
function reorderMesh(P, N, C, I) {
|
|
@@ -4701,7 +4701,7 @@ function lodChain(P, C, I) {
|
|
|
4701
4701
|
return out;
|
|
4702
4702
|
}
|
|
4703
4703
|
|
|
4704
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4704
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/compile.ts
|
|
4705
4705
|
function loadColors(root) {
|
|
4706
4706
|
const map = new Map;
|
|
4707
4707
|
for (const l of fs2.readFileSync(path2.join(root, "LDConfig.ldr"), "latin1").split(/\r?\n/)) {
|
|
@@ -5284,7 +5284,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
|
|
|
5284
5284
|
return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
|
|
5285
5285
|
}
|
|
5286
5286
|
|
|
5287
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5287
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/build-pack.ts
|
|
5288
5288
|
function buildPack(o) {
|
|
5289
5289
|
const lib = new Library2(o.ldrawRoot);
|
|
5290
5290
|
const refs = new Map;
|
|
@@ -5318,7 +5318,7 @@ function buildPack(o) {
|
|
|
5318
5318
|
if (lib.isPart(k) && /\.dat$/.test(k))
|
|
5319
5319
|
refs.set(k.slice(6), k);
|
|
5320
5320
|
}
|
|
5321
|
-
const comp = new Compiler(lib, { studs: o.studs ?? "low", prims: o.primitives ?? "
|
|
5321
|
+
const comp = new Compiler(lib, { studs: o.studs ?? "low", prims: o.primitives ?? "low", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures });
|
|
5322
5322
|
const parts = new Map, kinds = new Map;
|
|
5323
5323
|
let n = 0;
|
|
5324
5324
|
for (const [ref, key] of refs) {
|
|
@@ -5351,6 +5351,246 @@ function buildPack(o) {
|
|
|
5351
5351
|
const warnings = [...lib.conflicts].map((n) => `${n}: defined differently by two models; the first definition is used`);
|
|
5352
5352
|
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 } : {} };
|
|
5353
5353
|
}
|
|
5354
|
+
// ../../../../../../../tmp/ldr-build-9Rl9le/src/node/promote.ts
|
|
5355
|
+
var GEOM = /^\s*[2-5]\s/;
|
|
5356
|
+
var REF = /^\s*1\s/;
|
|
5357
|
+
var FILE = /^\s*0\s+FILE\s+(.+?)\s*$/i;
|
|
5358
|
+
var END = /^\s*0\s+(NOFILE|!DATA)(\s|$)/i;
|
|
5359
|
+
var MODEL_ORG2 = /^(\s*0\s+!LDRAW_ORG\s+)(?:Unofficial_)?(?:Model|Submodel)\b/i;
|
|
5360
|
+
var PART_ORG2 = /^\s*0\s+!LDRAW_ORG\s+(?:Unofficial_)?Part\b/i;
|
|
5361
|
+
var key = (s) => s.trim().toLowerCase().replace(/\\/g, "/");
|
|
5362
|
+
function promoteFlexParts(text) {
|
|
5363
|
+
const lines = text.split(/(?<=\n)/);
|
|
5364
|
+
const blocks = [];
|
|
5365
|
+
let cur = null;
|
|
5366
|
+
for (let i = 0;i < lines.length; i++) {
|
|
5367
|
+
const l = lines[i], f = FILE.exec(l);
|
|
5368
|
+
if (f) {
|
|
5369
|
+
blocks.push(cur = { name: f[1], org: -1, geom: 0, refs: [] });
|
|
5370
|
+
continue;
|
|
5371
|
+
}
|
|
5372
|
+
if (END.test(l)) {
|
|
5373
|
+
cur = null;
|
|
5374
|
+
continue;
|
|
5375
|
+
}
|
|
5376
|
+
if (!cur)
|
|
5377
|
+
continue;
|
|
5378
|
+
if (GEOM.test(l))
|
|
5379
|
+
cur.geom++;
|
|
5380
|
+
else if (REF.test(l)) {
|
|
5381
|
+
const t = l.trim().split(/\s+/);
|
|
5382
|
+
if (t.length >= 15)
|
|
5383
|
+
cur.refs.push(key(t.slice(14).join(" ")));
|
|
5384
|
+
} else if (cur.org < 0 && MODEL_ORG2.test(l))
|
|
5385
|
+
cur.org = i;
|
|
5386
|
+
}
|
|
5387
|
+
const plainModel = new Set(blocks.filter((b, i) => i > 0 && b.org >= 0 && !b.geom).map((b) => key(b.name)));
|
|
5388
|
+
const promoted = [];
|
|
5389
|
+
for (const b of blocks.slice(1)) {
|
|
5390
|
+
if (b.org < 0 || !b.geom || b.refs.some((r) => plainModel.has(r)))
|
|
5391
|
+
continue;
|
|
5392
|
+
lines[b.org] = lines[b.org].replace(MODEL_ORG2, "$1Unofficial_Part");
|
|
5393
|
+
promoted.push(b.name);
|
|
5394
|
+
}
|
|
5395
|
+
return { text: promoted.length ? lines.join("") : text, promoted };
|
|
5396
|
+
}
|
|
5397
|
+
var close = (a, b, eps = 0.08) => {
|
|
5398
|
+
const dx = a[0] - b[0], dy = a[1] - b[1], dz = a[2] - b[2];
|
|
5399
|
+
return dx * dx + dy * dy + dz * dz < eps * eps;
|
|
5400
|
+
};
|
|
5401
|
+
var sharedVerts = (a, b) => {
|
|
5402
|
+
let n = 0;
|
|
5403
|
+
for (const p of a)
|
|
5404
|
+
for (const q of b)
|
|
5405
|
+
if (close(p, q))
|
|
5406
|
+
n++;
|
|
5407
|
+
return n;
|
|
5408
|
+
};
|
|
5409
|
+
function parseQuadLine(line) {
|
|
5410
|
+
const trimmed = line.replace(/\r?\n$/, "");
|
|
5411
|
+
const m = /^\s*4\s+(\S+)\s+(.+)$/.exec(trimmed);
|
|
5412
|
+
if (!m)
|
|
5413
|
+
return null;
|
|
5414
|
+
const nums = m[2].trim().split(/\s+/).map(Number);
|
|
5415
|
+
if (nums.length < 12 || nums.some((x) => !Number.isFinite(x)))
|
|
5416
|
+
return null;
|
|
5417
|
+
const pts = [
|
|
5418
|
+
[nums[0], nums[1], nums[2]],
|
|
5419
|
+
[nums[3], nums[4], nums[5]],
|
|
5420
|
+
[nums[6], nums[7], nums[8]],
|
|
5421
|
+
[nums[9], nums[10], nums[11]]
|
|
5422
|
+
];
|
|
5423
|
+
const nl = line.endsWith(`\r
|
|
5424
|
+
`) ? `\r
|
|
5425
|
+
` : line.endsWith(`
|
|
5426
|
+
`) ? `
|
|
5427
|
+
` : "";
|
|
5428
|
+
return { col: m[1], pts, nl };
|
|
5429
|
+
}
|
|
5430
|
+
function ringLen(quads, start, minRing) {
|
|
5431
|
+
let n = 1;
|
|
5432
|
+
while (start + n < quads.length && sharedVerts(quads[start + n - 1].pts, quads[start + n].pts) >= 2) {
|
|
5433
|
+
n++;
|
|
5434
|
+
if (n >= minRing && sharedVerts(quads[start + n - 1].pts, quads[start].pts) >= 2)
|
|
5435
|
+
return n;
|
|
5436
|
+
if (n > 64)
|
|
5437
|
+
return null;
|
|
5438
|
+
}
|
|
5439
|
+
return null;
|
|
5440
|
+
}
|
|
5441
|
+
function mergePair(col, a, b, nl) {
|
|
5442
|
+
const fmt = (pts) => `4 ${col} ${pts.map((p) => p.map((x) => +x.toFixed(4)).join(" ")).join(" ")}${nl}`;
|
|
5443
|
+
for (let s = 0;s < 4; s++) {
|
|
5444
|
+
const a0 = a[s], a1 = a[(s + 1) % 4], a2 = a[(s + 2) % 4];
|
|
5445
|
+
if (b.some((p) => close(p, a1)) && b.some((p) => close(p, a2)) && !b.some((p) => close(p, a0))) {
|
|
5446
|
+
for (let t = 0;t < 4; t++) {
|
|
5447
|
+
const b0 = b[t], b1 = b[(t + 1) % 4], b2 = b[(t + 2) % 4], b3 = b[(t + 3) % 4];
|
|
5448
|
+
if (close(b0, a1) && close(b1, a2))
|
|
5449
|
+
return fmt([a0, a1, b2, b3]);
|
|
5450
|
+
if (close(b0, a2) && close(b1, a1))
|
|
5451
|
+
return fmt([a0, a1, b3, b2]);
|
|
5452
|
+
}
|
|
5453
|
+
}
|
|
5454
|
+
}
|
|
5455
|
+
return null;
|
|
5456
|
+
}
|
|
5457
|
+
function decimateBlock(lines, opts) {
|
|
5458
|
+
const quads = [];
|
|
5459
|
+
for (let i = 0;i < lines.length; i++) {
|
|
5460
|
+
if (!/^\s*4\s/.test(lines[i]))
|
|
5461
|
+
continue;
|
|
5462
|
+
const q = parseQuadLine(lines[i]);
|
|
5463
|
+
if (q)
|
|
5464
|
+
quads.push({ ...q, li: i });
|
|
5465
|
+
}
|
|
5466
|
+
if (quads.length < opts.minRing)
|
|
5467
|
+
return null;
|
|
5468
|
+
const inRing = new Uint8Array(quads.length);
|
|
5469
|
+
const rings = [];
|
|
5470
|
+
for (let pos = 0;pos < quads.length; ) {
|
|
5471
|
+
const n = ringLen(quads, pos, opts.minRing);
|
|
5472
|
+
if (!n) {
|
|
5473
|
+
pos++;
|
|
5474
|
+
continue;
|
|
5475
|
+
}
|
|
5476
|
+
rings.push({ start: pos, n });
|
|
5477
|
+
for (let k = 0;k < n; k++)
|
|
5478
|
+
inRing[pos + k] = 1;
|
|
5479
|
+
pos += n;
|
|
5480
|
+
}
|
|
5481
|
+
if (!rings.length)
|
|
5482
|
+
return null;
|
|
5483
|
+
const keep = new Uint8Array(lines.length);
|
|
5484
|
+
for (let i = 0;i < lines.length; i++) {
|
|
5485
|
+
const l = lines[i];
|
|
5486
|
+
if (/^\s*4\s/.test(l))
|
|
5487
|
+
keep[i] = 0;
|
|
5488
|
+
else if (opts.dropCond && /^\s*5\s/.test(l))
|
|
5489
|
+
keep[i] = 0;
|
|
5490
|
+
else
|
|
5491
|
+
keep[i] = 1;
|
|
5492
|
+
}
|
|
5493
|
+
const insert = new Map;
|
|
5494
|
+
let quadsOut = 0;
|
|
5495
|
+
for (const { start, n } of rings) {
|
|
5496
|
+
const at = quads[start].li;
|
|
5497
|
+
const out = [];
|
|
5498
|
+
if (opts.halveRings && n % 2 === 0) {
|
|
5499
|
+
let ok = true;
|
|
5500
|
+
for (let i = 0;i < n; i += 2) {
|
|
5501
|
+
const a = quads[start + i], b = quads[start + i + 1];
|
|
5502
|
+
const m = mergePair(a.col, a.pts, b.pts, a.nl);
|
|
5503
|
+
if (!m) {
|
|
5504
|
+
ok = false;
|
|
5505
|
+
break;
|
|
5506
|
+
}
|
|
5507
|
+
out.push(m);
|
|
5508
|
+
}
|
|
5509
|
+
if (ok && out.length >= 3) {
|
|
5510
|
+
insert.set(at, out);
|
|
5511
|
+
quadsOut += out.length;
|
|
5512
|
+
continue;
|
|
5513
|
+
}
|
|
5514
|
+
}
|
|
5515
|
+
const orig = [];
|
|
5516
|
+
for (let i = 0;i < n; i++)
|
|
5517
|
+
orig.push(lines[quads[start + i].li]);
|
|
5518
|
+
insert.set(at, orig);
|
|
5519
|
+
quadsOut += n;
|
|
5520
|
+
}
|
|
5521
|
+
if (!opts.dropNonRing) {
|
|
5522
|
+
for (let i = 0;i < quads.length; i++)
|
|
5523
|
+
if (!inRing[i]) {
|
|
5524
|
+
insert.set(quads[i].li, [lines[quads[i].li]]);
|
|
5525
|
+
quadsOut++;
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
const next = [];
|
|
5529
|
+
for (let i = 0;i < lines.length; i++) {
|
|
5530
|
+
if (insert.has(i))
|
|
5531
|
+
next.push(...insert.get(i));
|
|
5532
|
+
else if (keep[i])
|
|
5533
|
+
next.push(lines[i]);
|
|
5534
|
+
}
|
|
5535
|
+
return { lines: next, quadsIn: quads.length, quadsOut };
|
|
5536
|
+
}
|
|
5537
|
+
function decimateFlexGeometry(text, opts = {}) {
|
|
5538
|
+
const o = {
|
|
5539
|
+
halveRings: opts.halveRings !== false,
|
|
5540
|
+
minRing: opts.minRing ?? 8,
|
|
5541
|
+
dropCond: opts.dropCond !== false,
|
|
5542
|
+
dropNonRing: opts.dropNonRing !== false
|
|
5543
|
+
};
|
|
5544
|
+
const lines = text.split(/(?<=\n)/);
|
|
5545
|
+
const blocks = [];
|
|
5546
|
+
let cur = null;
|
|
5547
|
+
for (let i = 0;i < lines.length; i++) {
|
|
5548
|
+
const f = FILE.exec(lines[i]);
|
|
5549
|
+
if (f) {
|
|
5550
|
+
if (cur)
|
|
5551
|
+
cur.end = i;
|
|
5552
|
+
blocks.push(cur = { name: f[1], start: i, end: lines.length, isPart: false, quads: 0 });
|
|
5553
|
+
continue;
|
|
5554
|
+
}
|
|
5555
|
+
if (END.test(lines[i])) {
|
|
5556
|
+
if (cur)
|
|
5557
|
+
cur.end = i;
|
|
5558
|
+
cur = null;
|
|
5559
|
+
continue;
|
|
5560
|
+
}
|
|
5561
|
+
if (!cur)
|
|
5562
|
+
continue;
|
|
5563
|
+
if (PART_ORG2.test(lines[i]))
|
|
5564
|
+
cur.isPart = true;
|
|
5565
|
+
if (/^\s*4\s/.test(lines[i]))
|
|
5566
|
+
cur.quads++;
|
|
5567
|
+
}
|
|
5568
|
+
if (cur)
|
|
5569
|
+
cur.end = lines.length;
|
|
5570
|
+
const decimated = [];
|
|
5571
|
+
let quadsIn = 0, quadsOut = 0;
|
|
5572
|
+
for (let bi = blocks.length - 1;bi >= 0; bi--) {
|
|
5573
|
+
const b = blocks[bi];
|
|
5574
|
+
if (!b.isPart || b.quads < o.minRing)
|
|
5575
|
+
continue;
|
|
5576
|
+
const r = decimateBlock(lines.slice(b.start, b.end), o);
|
|
5577
|
+
if (!r)
|
|
5578
|
+
continue;
|
|
5579
|
+
lines.splice(b.start, b.end - b.start, ...r.lines);
|
|
5580
|
+
quadsIn += r.quadsIn;
|
|
5581
|
+
quadsOut += r.quadsOut;
|
|
5582
|
+
decimated.push(b.name);
|
|
5583
|
+
}
|
|
5584
|
+
decimated.reverse();
|
|
5585
|
+
return { text: decimated.length ? lines.join("") : text, decimated, quadsIn, quadsOut };
|
|
5586
|
+
}
|
|
5587
|
+
function prepareFlexParts(text, decimate = {}) {
|
|
5588
|
+
const p = promoteFlexParts(text);
|
|
5589
|
+
if (decimate === false)
|
|
5590
|
+
return { text: p.text, promoted: p.promoted, decimated: [], quadsIn: 0, quadsOut: 0 };
|
|
5591
|
+
const d = decimateFlexGeometry(p.text, decimate);
|
|
5592
|
+
return { text: d.text, promoted: p.promoted, decimated: d.decimated, quadsIn: d.quadsIn, quadsOut: d.quadsOut };
|
|
5593
|
+
}
|
|
5354
5594
|
export {
|
|
5355
5595
|
BudgetError,
|
|
5356
5596
|
CALLOUT_END,
|
|
@@ -5377,6 +5617,7 @@ export {
|
|
|
5377
5617
|
createLdrObject,
|
|
5378
5618
|
createLdrObjectAsync,
|
|
5379
5619
|
cullCore,
|
|
5620
|
+
decimateFlexGeometry,
|
|
5380
5621
|
decodeModelText,
|
|
5381
5622
|
decodePack,
|
|
5382
5623
|
decompressPack,
|
|
@@ -5415,7 +5656,9 @@ export {
|
|
|
5415
5656
|
parseTexMap,
|
|
5416
5657
|
planStepViews,
|
|
5417
5658
|
precomputeCull,
|
|
5659
|
+
prepareFlexParts,
|
|
5418
5660
|
prepareModel,
|
|
5661
|
+
promoteFlexParts,
|
|
5419
5662
|
resolveTexture,
|
|
5420
5663
|
rotStepMatrix,
|
|
5421
5664
|
sceneInstances,
|
package/dist/node/promote.d.ts
CHANGED
|
@@ -9,3 +9,28 @@ export declare function promoteFlexParts(text: string): {
|
|
|
9
9
|
text: string;
|
|
10
10
|
promoted: string[];
|
|
11
11
|
};
|
|
12
|
+
export type DecimateFlexOptions = {
|
|
13
|
+
/** Merge every pair of adjacent ring quads (default true → 16-gon becomes 8-gon). */
|
|
14
|
+
halveRings?: boolean;
|
|
15
|
+
/** Minimum quads in a closed ring (default 8). */
|
|
16
|
+
minRing?: number;
|
|
17
|
+
/** Drop type-5 conditional lines in decimated parts (default true). */
|
|
18
|
+
dropCond?: boolean;
|
|
19
|
+
/** Drop type-4 quads not in a detected tube ring (rib fillet detail; default true). */
|
|
20
|
+
dropNonRing?: boolean;
|
|
21
|
+
};
|
|
22
|
+
/** Decimate tube rings in promoted flex `Unofficial_Part` files: 16→8 sides and drop non-ring rib detail. */
|
|
23
|
+
export declare function decimateFlexGeometry(text: string, opts?: DecimateFlexOptions): {
|
|
24
|
+
text: string;
|
|
25
|
+
decimated: string[];
|
|
26
|
+
quadsIn: number;
|
|
27
|
+
quadsOut: number;
|
|
28
|
+
};
|
|
29
|
+
/** Promote LDCad flex files to embedded parts, then decimate tube rings (Round 35 + 37). */
|
|
30
|
+
export declare function prepareFlexParts(text: string, decimate?: DecimateFlexOptions | false): {
|
|
31
|
+
text: string;
|
|
32
|
+
promoted: string[];
|
|
33
|
+
decimated: string[];
|
|
34
|
+
quadsIn: number;
|
|
35
|
+
quadsOut: number;
|
|
36
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ldr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "High-performance LEGO (LDraw) rendering for three.js: instanced parts packs, hidden stud/tube culling, low-detail studs, indexed edges, build steps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Evan Bacon",
|