@ifc-lite/viewer 1.19.0 → 1.21.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.
Files changed (129) hide show
  1. package/.turbo/turbo-build.log +59 -43
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/CHANGELOG.md +496 -0
  4. package/dist/assets/basketViewActivator-Bzw51jhm.js +71 -0
  5. package/dist/assets/{bcf-DOG9_WPX.js → bcf-4K724hw0.js} +18 -18
  6. package/dist/assets/decode-worker-t2EGKAxO.js +1708 -0
  7. package/dist/assets/drawing-2d-Bjy8YPrg.js +257 -0
  8. package/dist/assets/exporters-u0sz2Upj.js +259119 -0
  9. package/dist/assets/geometry-controller.worker-NH8pZmrU.js +7 -0
  10. package/dist/assets/geometry.worker-Bp4rW_R1.js +1 -0
  11. package/dist/assets/ids-B7AXEv7h.js +4067 -0
  12. package/dist/assets/ifc-lite-DfZHk36-.js +7 -0
  13. package/dist/assets/ifc-lite_bg-DlKs5-yM.wasm +0 -0
  14. package/dist/assets/ifc-lite_bg-PqmRe3Ph.wasm +0 -0
  15. package/dist/assets/index-CSWgTe1s.css +1 -0
  16. package/dist/assets/{index-BOi3BuUI.js → index-DVNSvEMh.js} +49877 -28410
  17. package/dist/assets/laz-perf-Cvr_Lepg.js +1 -0
  18. package/dist/assets/laz-perf-DnSyzVYH.wasm +0 -0
  19. package/dist/assets/{native-bridge-CpBeOPQa.js → native-bridge-BiD01jI9.js} +2 -2
  20. package/dist/assets/parser.worker-Bnbrl6gy.js +182 -0
  21. package/dist/assets/{sandbox-Baez7n-t.js → sandbox-DPD1ROr0.js} +548 -530
  22. package/dist/assets/{server-client-BB6cMAXE.js → server-client-DP8fMPY9.js} +1 -1
  23. package/dist/assets/three-CDRZThFA.js +4057 -0
  24. package/dist/assets/{wasm-bridge-CAYCUHbE.js → wasm-bridge-CErti6zX.js} +1 -1
  25. package/dist/assets/workerHelpers-CBbWSJmd.js +36 -0
  26. package/dist/index.html +10 -9
  27. package/dist/samples/building-architecture.ifc +453 -0
  28. package/dist/samples/hello-wall.ifc +1054 -0
  29. package/dist/samples/infra-bridge.ifc +962 -0
  30. package/index.html +1 -1
  31. package/package.json +15 -10
  32. package/public/samples/building-architecture.ifc +453 -0
  33. package/public/samples/hello-wall.ifc +1054 -0
  34. package/public/samples/infra-bridge.ifc +962 -0
  35. package/src/App.tsx +37 -3
  36. package/src/components/mcp/HeroScene.tsx +876 -0
  37. package/src/components/mcp/McpLanding.tsx +1318 -0
  38. package/src/components/mcp/McpPlayground.tsx +524 -0
  39. package/src/components/mcp/PlaygroundChat.tsx +1097 -0
  40. package/src/components/mcp/PlaygroundViewer.tsx +815 -0
  41. package/src/components/mcp/README.md +171 -0
  42. package/src/components/mcp/data.ts +659 -0
  43. package/src/components/mcp/playground-dispatcher.ts +1649 -0
  44. package/src/components/mcp/playground-files.ts +107 -0
  45. package/src/components/mcp/playground-uploads.ts +122 -0
  46. package/src/components/mcp/types.ts +65 -0
  47. package/src/components/mcp/use-mcp-page.ts +109 -0
  48. package/src/components/viewer/BasketPresentationDock.tsx +3 -0
  49. package/src/components/viewer/CesiumOverlay.tsx +165 -120
  50. package/src/components/viewer/DeviationPanel.tsx +172 -0
  51. package/src/components/viewer/HierarchyPanel.tsx +29 -3
  52. package/src/components/viewer/HoverTooltip.tsx +5 -0
  53. package/src/components/viewer/IDSAuditSummary.tsx +389 -0
  54. package/src/components/viewer/IDSPanel.tsx +80 -26
  55. package/src/components/viewer/MainToolbar.tsx +79 -7
  56. package/src/components/viewer/MergeLayersBanner.tsx +108 -0
  57. package/src/components/viewer/MobileToolbar.tsx +326 -0
  58. package/src/components/viewer/PointCloudClasses.tsx +111 -0
  59. package/src/components/viewer/PointCloudLegend.tsx +119 -0
  60. package/src/components/viewer/PointCloudPanel.tsx +52 -1
  61. package/src/components/viewer/PropertiesPanel.tsx +37 -6
  62. package/src/components/viewer/RectSelectionOverlay.tsx +48 -0
  63. package/src/components/viewer/StatusBar.tsx +14 -0
  64. package/src/components/viewer/ViewerLayout.tsx +288 -95
  65. package/src/components/viewer/Viewport.tsx +86 -18
  66. package/src/components/viewer/ViewportContainer.tsx +60 -15
  67. package/src/components/viewer/ViewportOverlays.tsx +41 -26
  68. package/src/components/viewer/mouseHandlerTypes.ts +22 -0
  69. package/src/components/viewer/properties/GeoreferencingPanel.tsx +77 -8
  70. package/src/components/viewer/properties/MaterialCard.tsx +2 -2
  71. package/src/components/viewer/selectionHandlers.ts +41 -0
  72. package/src/components/viewer/tools/SectionPanel.tsx +181 -24
  73. package/src/components/viewer/tools/SectionVisualization.tsx +384 -3
  74. package/src/components/viewer/useAnimationLoop.ts +22 -0
  75. package/src/components/viewer/useMouseControls.ts +296 -3
  76. package/src/components/viewer/usePointCloudSync.ts +8 -1
  77. package/src/components/viewer/useRenderUpdates.ts +21 -1
  78. package/src/components/viewer/useTouchControls.ts +100 -41
  79. package/src/generated/mcp-catalog.json +82 -0
  80. package/src/hooks/federationLoadGate.test.ts +90 -0
  81. package/src/hooks/federationLoadGate.ts +127 -0
  82. package/src/hooks/ids/idsDataAccessor.ts +11 -259
  83. package/src/hooks/ingest/pointCloudIngest.ts +127 -16
  84. package/src/hooks/useDrawingGeneration.ts +81 -8
  85. package/src/hooks/useIDS.ts +90 -10
  86. package/src/hooks/useIfcFederation.ts +94 -16
  87. package/src/hooks/useIfcLoader.ts +289 -64
  88. package/src/hooks/useViewerSelectors.ts +10 -0
  89. package/src/lib/geo/cesium-bridge.ts +84 -67
  90. package/src/lib/geo/clamp-anchor.test.ts +80 -0
  91. package/src/lib/geo/clamp-anchor.ts +57 -0
  92. package/src/lib/geo/effective-georef.test.ts +79 -1
  93. package/src/lib/geo/effective-georef.ts +83 -0
  94. package/src/lib/geo/reproject.ts +26 -13
  95. package/src/lib/geo/terrain-elevation.ts +166 -0
  96. package/src/lib/lens/adapter.ts +1 -1
  97. package/src/lib/llm/context-builder.ts +1 -1
  98. package/src/lib/perf/memoryAccounting.test.ts +92 -0
  99. package/src/lib/perf/memoryAccounting.ts +235 -0
  100. package/src/sdk/adapters/mutation-view.ts +1 -1
  101. package/src/store/constants.ts +39 -2
  102. package/src/store/index.ts +6 -1
  103. package/src/store/slices/cesiumSlice.ts +1 -1
  104. package/src/store/slices/idsSlice.ts +24 -0
  105. package/src/store/slices/loadingSlice.ts +12 -0
  106. package/src/store/slices/pointCloudSlice.ts +72 -1
  107. package/src/store/slices/sectionSlice.test.ts +590 -1
  108. package/src/store/slices/sectionSlice.ts +344 -17
  109. package/src/store/slices/uiSlice.merge-layers.test.ts +217 -0
  110. package/src/store/slices/uiSlice.ts +60 -2
  111. package/src/store/types.ts +42 -0
  112. package/src/store.ts +13 -0
  113. package/src/utils/acquireFileBuffer.test.ts +231 -0
  114. package/src/utils/acquireFileBuffer.ts +128 -0
  115. package/src/utils/ifcConfig.ts +24 -0
  116. package/src/utils/nativeSpatialDataStore.ts +20 -2
  117. package/src/utils/spatialHierarchy.test.ts +116 -0
  118. package/src/utils/spatialHierarchy.ts +23 -0
  119. package/tailwind.config.js +5 -0
  120. package/tsconfig.json +1 -0
  121. package/vite.config.ts +12 -0
  122. package/dist/assets/basketViewActivator-RZy5c3Td.js +0 -1
  123. package/dist/assets/decode-worker-Collf_X_.js +0 -1320
  124. package/dist/assets/drawing-2d-DoxKMqbO.js +0 -257
  125. package/dist/assets/exporters-BraHBeoi.js +0 -81583
  126. package/dist/assets/geometry.worker-DQEZB2rB.js +0 -1
  127. package/dist/assets/ids-DQ5jY0E8.js +0 -1
  128. package/dist/assets/ifc-lite_bg-4yUkDRD8.wasm +0 -0
  129. package/dist/assets/index-0XpVr_S5.css +0 -1
@@ -0,0 +1,1708 @@
1
+ (async ()=>{
2
+ function zt(n) {
3
+ const t = n.positions.buffer, e = [
4
+ t
5
+ ], o = {
6
+ positions: t,
7
+ pointCount: n.pointCount,
8
+ bbox: n.bbox
9
+ };
10
+ if (n.colors) {
11
+ const r = n.colors.buffer;
12
+ o.colors = r, e.push(r);
13
+ }
14
+ if (n.classifications) {
15
+ const r = n.classifications.buffer;
16
+ o.classifications = r, e.push(r);
17
+ }
18
+ if (n.intensities) {
19
+ const r = n.intensities.buffer;
20
+ o.intensities = r, e.push(r);
21
+ }
22
+ return {
23
+ payload: o,
24
+ transfer: e
25
+ };
26
+ }
27
+ const Ut = 1179861324, bt = {
28
+ 0: 20,
29
+ 1: 28,
30
+ 2: 26,
31
+ 3: 34,
32
+ 4: 57,
33
+ 5: 63,
34
+ 6: 30,
35
+ 7: 36,
36
+ 8: 38,
37
+ 9: 59,
38
+ 10: 67
39
+ }, Ot = new Set([
40
+ 1,
41
+ 3,
42
+ 4,
43
+ 5,
44
+ 6,
45
+ 7,
46
+ 8,
47
+ 9,
48
+ 10
49
+ ]), Dt = new Set([
50
+ 2,
51
+ 3,
52
+ 5,
53
+ 7,
54
+ 8,
55
+ 10
56
+ ]);
57
+ function Ct(n) {
58
+ const t = n instanceof Uint8Array ? n : new Uint8Array(n);
59
+ if (t.length < 227) throw new Error("LAS: header truncated");
60
+ const e = new DataView(t.buffer, t.byteOffset, t.byteLength);
61
+ if (e.getUint32(0, !0) !== Ut) throw new Error('LAS: bad magic — expected "LASF"');
62
+ const o = e.getUint8(24), r = e.getUint8(25), i = e.getUint16(94, !0), c = e.getUint32(96, !0), l = e.getUint32(100, !0), s = e.getUint8(104) & 63, a = e.getUint16(105, !0);
63
+ let w = e.getUint32(107, !0);
64
+ if (o >= 1 && r >= 4 && t.length >= 255) {
65
+ const I = $t(e, 247);
66
+ I > 0 && (w = I);
67
+ }
68
+ if (!Number.isFinite(w) || w < 0) throw new Error("LAS: invalid point count");
69
+ const m = [
70
+ e.getFloat64(131, !0),
71
+ e.getFloat64(139, !0),
72
+ e.getFloat64(147, !0)
73
+ ], d = [
74
+ e.getFloat64(155, !0),
75
+ e.getFloat64(163, !0),
76
+ e.getFloat64(171, !0)
77
+ ], f = e.getFloat64(179, !0), p = e.getFloat64(187, !0), h = e.getFloat64(195, !0), b = e.getFloat64(203, !0), g = e.getFloat64(211, !0), y = e.getFloat64(219, !0), C = {
78
+ min: [
79
+ p,
80
+ b,
81
+ y
82
+ ],
83
+ max: [
84
+ f,
85
+ h,
86
+ g
87
+ ]
88
+ };
89
+ if (bt[s] === void 0) throw new Error(`LAS: unsupported point data format ${s}`);
90
+ const x = bt[s];
91
+ if (a < x) throw new Error(`LAS: header point-record length (${a}) smaller than format ${s} baseline (${x})`);
92
+ return {
93
+ versionMajor: o,
94
+ versionMinor: r,
95
+ headerSize: i,
96
+ pointDataOffset: c,
97
+ numberOfVlrs: l,
98
+ pointDataFormatId: s,
99
+ pointRecordLength: a,
100
+ pointCount: w,
101
+ scale: m,
102
+ offset: d,
103
+ bbox: C,
104
+ hasGpsTime: Ot.has(s),
105
+ hasRgb: Dt.has(s)
106
+ };
107
+ }
108
+ function st(n, t, e, o = t.pointRecordLength, r = 1) {
109
+ if (n.length < e * o) throw new Error(`LAS: decode expects ${e * o} bytes, got ${n.length}`);
110
+ const i = new DataView(n.buffer, n.byteOffset, n.byteLength), c = new Float32Array(e * 3), l = new Uint16Array(e), s = new Uint8Array(e), a = t.hasRgb ? new Float32Array(e * 3) : void 0, u = Ft(t.pointDataFormatId), w = t.pointDataFormatId >= 6 ? 16 : 15;
111
+ let m = 1 / 0, d = 1 / 0, f = 1 / 0, p = -1 / 0, h = -1 / 0, b = -1 / 0;
112
+ for(let g = 0; g < e; g++){
113
+ const y = g * o, C = i.getInt32(y, !0) * t.scale[0] + t.offset[0], x = i.getInt32(y + 4, !0) * t.scale[1] + t.offset[1], I = i.getInt32(y + 8, !0) * t.scale[2] + t.offset[2];
114
+ if (c[g * 3] = C, c[g * 3 + 1] = x, c[g * 3 + 2] = I, C < m && (m = C), C > p && (p = C), x < d && (d = x), x > h && (h = x), I < f && (f = I), I > b && (b = I), l[g] = i.getUint16(y + 12, !0), s[g] = t.pointDataFormatId >= 6 ? i.getUint8(y + w) : i.getUint8(y + w) & 31, a && u >= 0) {
115
+ const E = i.getUint16(y + u, !0), A = i.getUint16(y + u + 2, !0), S = i.getUint16(y + u + 4, !0);
116
+ a[g * 3] = E * r / 65535, a[g * 3 + 1] = A * r / 65535, a[g * 3 + 2] = S * r / 65535;
117
+ }
118
+ }
119
+ return {
120
+ positions: c,
121
+ colors: a,
122
+ classifications: s,
123
+ intensities: l,
124
+ pointCount: e,
125
+ bbox: {
126
+ min: [
127
+ m,
128
+ d,
129
+ f
130
+ ],
131
+ max: [
132
+ p,
133
+ h,
134
+ b
135
+ ]
136
+ }
137
+ };
138
+ }
139
+ function It(n, t, e = 1024) {
140
+ if (!t.hasRgb) return 0;
141
+ const o = t.pointRecordLength, r = Math.min(t.pointCount, Math.floor(n.length / o));
142
+ if (r === 0) return 0;
143
+ const i = new DataView(n.buffer, n.byteOffset, n.byteLength), c = Ft(t.pointDataFormatId);
144
+ if (c < 0) return 0;
145
+ const l = Math.max(1, Math.floor(r / Math.min(e, r)));
146
+ let s = 0;
147
+ for(let a = 0; a < r; a += l){
148
+ const u = a * o, w = i.getUint16(u + c, !0), m = i.getUint16(u + c + 2, !0), d = i.getUint16(u + c + 4, !0);
149
+ w > s && (s = w), m > s && (s = m), d > s && (s = d);
150
+ }
151
+ return s;
152
+ }
153
+ function Ft(n) {
154
+ switch(n){
155
+ case 2:
156
+ return 20;
157
+ case 3:
158
+ return 28;
159
+ case 5:
160
+ return 28;
161
+ case 7:
162
+ return 30;
163
+ case 8:
164
+ return 30;
165
+ case 10:
166
+ return 30;
167
+ default:
168
+ return -1;
169
+ }
170
+ }
171
+ function $t(n, t) {
172
+ const e = n.getUint32(t, !0);
173
+ return n.getUint32(t + 4, !0) * 4294967296 + e;
174
+ }
175
+ class Nt {
176
+ constructor(t){
177
+ this.blob = t;
178
+ }
179
+ get size() {
180
+ return this.blob.size;
181
+ }
182
+ async read(t, e) {
183
+ const o = Math.max(0, t), r = Math.min(e, this.blob.size);
184
+ if (r <= o) return new Uint8Array(0);
185
+ const c = await this.blob.slice(o, r).arrayBuffer();
186
+ return new Uint8Array(c);
187
+ }
188
+ }
189
+ const Rt = 1024, Bt = 4096;
190
+ class _t {
191
+ bytes;
192
+ header = null;
193
+ cursor = 0;
194
+ rgbScale = 1;
195
+ downsample;
196
+ label;
197
+ constructor(t, e = {}){
198
+ this.bytes = new Nt(t), this.downsample = e.downsample ?? {
199
+ stride: 1
200
+ }, this.label = e.label;
201
+ }
202
+ async open(t) {
203
+ if (this.header) return this.toInfo(this.header);
204
+ T(t);
205
+ const e = await this.bytes.read(0, Rt);
206
+ T(t);
207
+ const o = Ct(e);
208
+ let r = 1;
209
+ if (o.hasRgb) {
210
+ const i = Math.min(Bt * o.pointRecordLength, Math.max(0, this.bytes.size - o.pointDataOffset));
211
+ if (i > 0) {
212
+ const c = await this.bytes.read(o.pointDataOffset, o.pointDataOffset + i);
213
+ T(t);
214
+ const l = It(c, o);
215
+ r = l > 0 && l <= 255 ? 65535 / 255 : 1;
216
+ }
217
+ }
218
+ return this.header = o, this.rgbScale = r, this.cursor = 0, this.toInfo(o);
219
+ }
220
+ async next(t, e) {
221
+ if (T(e), !Number.isFinite(t) || t <= 0) throw new Error(`LasStreamingSource: maxPoints must be > 0 (got ${t})`);
222
+ if (!this.header) throw new Error("LasStreamingSource: open() must be awaited before next()");
223
+ const o = Math.max(1, this.downsample.stride | 0);
224
+ if (this.cursor >= this.header.pointCount) return null;
225
+ if (o === 1) {
226
+ const d = this.header.pointCount - this.cursor, f = Math.min(t, d), p = this.header.pointDataOffset + this.cursor * this.header.pointRecordLength, h = p + f * this.header.pointRecordLength, b = await this.bytes.read(p, h);
227
+ T(e);
228
+ const g = st(b, this.header, f, this.header.pointRecordLength, this.rgbScale);
229
+ return this.cursor += f, g;
230
+ }
231
+ const r = this.header.pointCount - this.cursor, i = Math.min(t * o, r), c = Math.ceil(i / o), l = this.header.pointDataOffset + this.cursor * this.header.pointRecordLength, s = l + i * this.header.pointRecordLength, a = await this.bytes.read(l, s);
232
+ T(e);
233
+ const u = new Uint8Array(c * this.header.pointRecordLength);
234
+ let w = 0;
235
+ for(let d = 0; d < c; d++){
236
+ const f = d * o * this.header.pointRecordLength;
237
+ u.set(a.subarray(f, f + this.header.pointRecordLength), w), w += this.header.pointRecordLength;
238
+ }
239
+ const m = st(u, this.header, c, this.header.pointRecordLength, this.rgbScale);
240
+ return this.cursor += i, m;
241
+ }
242
+ close() {
243
+ this.header = null, this.cursor = 0;
244
+ }
245
+ toInfo(t) {
246
+ const e = Math.max(1, this.downsample.stride | 0);
247
+ return {
248
+ totalPointCount: e === 1 ? t.pointCount : Math.ceil(t.pointCount / e),
249
+ bbox: t.bbox,
250
+ hasColor: t.hasRgb,
251
+ hasClassification: !0,
252
+ hasIntensity: !0,
253
+ label: this.label
254
+ };
255
+ }
256
+ }
257
+ function T(n) {
258
+ if (n?.aborted) throw new DOMException("Aborted", "AbortError");
259
+ }
260
+ let K = null;
261
+ async function vt() {
262
+ return K || (K = (async ()=>{
263
+ const n = await Tt(), t = await import("./index-XwKzDuw6.js").then(function(i) {
264
+ return i.i;
265
+ }), e = t.default, r = [
266
+ t.createLazPerf,
267
+ typeof e == "object" && e !== null ? e.createLazPerf : void 0,
268
+ e,
269
+ t
270
+ ].find((i)=>typeof i == "function");
271
+ if (!r) {
272
+ const i = Object.keys(t).join(", ");
273
+ throw new Error(`laz-perf: could not find createLazPerf factory (saw keys: ${i || "<empty>"})`);
274
+ }
275
+ return r({
276
+ wasmBinary: n
277
+ });
278
+ })()), K;
279
+ }
280
+ async function Tt() {
281
+ let n;
282
+ try {
283
+ n = (await import("./laz-perf-Cvr_Lepg.js")).default;
284
+ } catch (o) {
285
+ throw new Error(`laz-perf: could not resolve wasm asset URL (${o instanceof Error ? o.message : String(o)}). Ensure the bundler treats \`laz-perf/lib/web/laz-perf.wasm?url\` as a static asset.`);
286
+ }
287
+ const t = await fetch(n);
288
+ if (!t.ok) throw new Error(`laz-perf: wasm fetch failed (${t.status} ${t.statusText}) for ${n}`);
289
+ const e = await t.arrayBuffer();
290
+ return new Uint8Array(e);
291
+ }
292
+ class kt {
293
+ blob;
294
+ downsample;
295
+ label;
296
+ mod = null;
297
+ laszip = null;
298
+ header = null;
299
+ fileBytes = null;
300
+ filePtr = 0;
301
+ pointPtr = 0;
302
+ pointBuffer = null;
303
+ cursor = 0;
304
+ rgbScale = 1;
305
+ constructor(t, e = {}){
306
+ this.blob = t, this.downsample = e.downsample ?? {
307
+ stride: 1
308
+ }, this.label = e.label;
309
+ }
310
+ async open(t) {
311
+ if (this.header) return this.toInfo(this.header);
312
+ G(t);
313
+ let e, o = 0, r = 0, i;
314
+ try {
315
+ const c = await this.blob.arrayBuffer();
316
+ G(t);
317
+ const l = new Uint8Array(c), s = Ct(l);
318
+ e = await vt(), G(t), o = e._malloc(l.byteLength), e.HEAPU8.set(l, o), i = new e.LASZip, i.open(o, l.byteLength);
319
+ const a = i.getPointLength();
320
+ r = e._malloc(a);
321
+ const u = new Uint8Array(a);
322
+ let w = 1;
323
+ if (s.hasRgb) {
324
+ const m = Math.min(4096, s.pointCount), d = new Uint8Array(m * a);
325
+ for(let p = 0; p < m; p++)i.getPoint(r), d.set(e.HEAPU8.subarray(r, r + a), p * a);
326
+ const f = It(d, s);
327
+ w = f > 0 && f <= 255 ? 65535 / 255 : 1, i.delete(), i = new e.LASZip, i.open(o, l.byteLength);
328
+ }
329
+ return this.fileBytes = l, this.mod = e, this.filePtr = o, this.laszip = i, this.pointPtr = r, this.pointBuffer = u, this.rgbScale = w, this.header = s, this.cursor = 0, this.toInfo(s);
330
+ } catch (c) {
331
+ try {
332
+ i?.delete();
333
+ } catch {}
334
+ if (e && r) try {
335
+ e._free(r);
336
+ } catch {}
337
+ if (e && o) try {
338
+ e._free(o);
339
+ } catch {}
340
+ throw c;
341
+ }
342
+ }
343
+ async next(t, e) {
344
+ if (G(e), !Number.isFinite(t) || t <= 0) throw new Error(`LazStreamingSource: maxPoints must be > 0 (got ${t})`);
345
+ if (!this.header || !this.mod || !this.laszip || !this.pointBuffer) throw new Error("LazStreamingSource: open() must be awaited before next()");
346
+ const o = Math.max(1, this.downsample.stride | 0);
347
+ if (this.cursor >= this.header.pointCount) return null;
348
+ const r = this.pointBuffer.byteLength, i = this.header.pointCount - this.cursor, c = Math.min(o === 1 ? t : t * o, i), l = o === 1 ? c : Math.ceil(c / o), s = new Uint8Array(l * r);
349
+ let a = 0;
350
+ for(let u = 0; u < c; u++)this.laszip.getPoint(this.pointPtr), (o === 1 || u % o === 0) && (s.set(this.mod.HEAPU8.subarray(this.pointPtr, this.pointPtr + r), a * r), a++);
351
+ return this.cursor += c, st(s, this.header, l, r, this.rgbScale);
352
+ }
353
+ close() {
354
+ try {
355
+ this.laszip?.delete();
356
+ } catch {}
357
+ if (this.mod && this.pointPtr) try {
358
+ this.mod._free(this.pointPtr);
359
+ } catch {}
360
+ if (this.mod && this.filePtr) try {
361
+ this.mod._free(this.filePtr);
362
+ } catch {}
363
+ this.laszip = null, this.mod = null, this.header = null, this.fileBytes = null, this.pointBuffer = null, this.filePtr = 0, this.pointPtr = 0, this.cursor = 0;
364
+ }
365
+ toInfo(t) {
366
+ const e = Math.max(1, this.downsample.stride | 0);
367
+ return {
368
+ totalPointCount: e === 1 ? t.pointCount : Math.ceil(t.pointCount / e),
369
+ bbox: t.bbox,
370
+ hasColor: t.hasRgb,
371
+ hasClassification: !0,
372
+ hasIntensity: !0,
373
+ label: this.label
374
+ };
375
+ }
376
+ }
377
+ function G(n) {
378
+ if (n?.aborted) throw new DOMException("Aborted", "AbortError");
379
+ }
380
+ const Yt = {
381
+ char: 1,
382
+ int8: 1,
383
+ uchar: 1,
384
+ uint8: 1,
385
+ short: 2,
386
+ int16: 2,
387
+ ushort: 2,
388
+ uint16: 2,
389
+ int: 4,
390
+ int32: 4,
391
+ uint: 4,
392
+ uint32: 4,
393
+ float: 4,
394
+ float32: 4,
395
+ double: 8,
396
+ float64: 8
397
+ }, Et = new TextDecoder;
398
+ function At(n) {
399
+ const t = Math.min(65536, n.length), e = Et.decode(n.subarray(0, t));
400
+ if (!e.startsWith("ply")) throw new Error('PLY: missing magic — file does not start with "ply"');
401
+ const o = e.indexOf("end_header");
402
+ if (o < 0) throw new Error("PLY: missing end_header line in first " + t + " bytes");
403
+ const r = e.indexOf(`
404
+ `, o);
405
+ if (r < 0) throw new Error("PLY: end_header line not terminated by newline");
406
+ const i = e.slice(0, r + 1), c = r + 1, l = i.split(`
407
+ `).map((m)=>m.trim()).filter((m)=>m.length > 0);
408
+ let s = null, a = "1.0";
409
+ const u = [];
410
+ let w = null;
411
+ for (const m of l)if (!(m === "ply" || m === "end_header") && !m.startsWith("comment") && !m.startsWith("obj_info")) {
412
+ if (m.startsWith("format ")) {
413
+ const d = m.split(/\s+/), f = d[1];
414
+ if (a = d[2] ?? "1.0", f === "ascii" || f === "binary_little_endian" || f === "binary_big_endian") s = f;
415
+ else throw new Error(`PLY: unsupported format "${f}"`);
416
+ continue;
417
+ }
418
+ if (m.startsWith("element ")) {
419
+ const d = m.split(/\s+/);
420
+ w = {
421
+ name: d[1],
422
+ count: parseInt(d[2], 10),
423
+ properties: [],
424
+ recordSize: 0
425
+ }, u.push(w);
426
+ continue;
427
+ }
428
+ if (m.startsWith("property ")) {
429
+ if (!w) throw new Error(`PLY: property declared before any element: "${m}"`);
430
+ const d = m.split(/\s+/);
431
+ if (d[1] === "list") continue;
432
+ const f = d[1], p = d[2], h = Yt[f];
433
+ if (h === void 0) throw new Error(`PLY: unknown property type "${f}"`);
434
+ w.properties.push({
435
+ name: p,
436
+ type: f,
437
+ size: h,
438
+ offset: w.recordSize
439
+ }), w.recordSize += h;
440
+ continue;
441
+ }
442
+ }
443
+ if (!s) throw new Error("PLY: missing `format` line in header");
444
+ if (!u.some((m)=>m.name === "vertex")) throw new Error("PLY: missing `vertex` element");
445
+ return {
446
+ format: s,
447
+ version: a,
448
+ elements: u,
449
+ bodyOffset: c
450
+ };
451
+ }
452
+ function Zt(n) {
453
+ const t = At(n), e = t.elements.find((p)=>p.name === "vertex");
454
+ if (!e) throw new Error("PLY: no vertex element");
455
+ if (t.elements[0] !== e) throw new Error(`PLY: vertex element must appear first; saw "${t.elements[0]?.name}" first`);
456
+ const o = e.properties.find((p)=>p.name === "x"), r = e.properties.find((p)=>p.name === "y"), i = e.properties.find((p)=>p.name === "z");
457
+ if (!o || !r || !i) throw new Error("PLY: vertex element must define x, y, z properties");
458
+ const c = e.properties.find((p)=>p.name === "red" || p.name === "r"), l = e.properties.find((p)=>p.name === "green" || p.name === "g"), s = e.properties.find((p)=>p.name === "blue" || p.name === "b"), a = !!(c && l && s), u = e.properties.find((p)=>p.name === "intensity" || p.name === "scalar_Intensity"), w = e.count, m = new Float32Array(w * 3), d = a ? new Float32Array(w * 3) : void 0, f = u ? new Uint16Array(w) : void 0;
459
+ return t.format === "ascii" ? Xt(n, t, e, m, d, f) : Wt(n, t, e, m, d, f, t.format === "binary_little_endian"), {
460
+ positions: m,
461
+ colors: d,
462
+ intensities: f,
463
+ pointCount: w,
464
+ bbox: Vt(m)
465
+ };
466
+ }
467
+ function Xt(n, t, e, o, r, i) {
468
+ const c = Et.decode(n.subarray(t.bodyOffset)), l = e.properties.findIndex((h)=>h.name === "x"), s = e.properties.findIndex((h)=>h.name === "y"), a = e.properties.findIndex((h)=>h.name === "z"), u = e.properties.findIndex((h)=>h.name === "red" || h.name === "r"), w = e.properties.findIndex((h)=>h.name === "green" || h.name === "g"), m = e.properties.findIndex((h)=>h.name === "blue" || h.name === "b"), d = e.properties.findIndex((h)=>h.name === "intensity" || h.name === "scalar_Intensity");
469
+ let f = 0, p = 0;
470
+ for(; p < e.count && f < c.length;){
471
+ let h = c.indexOf(`
472
+ `, f);
473
+ h < 0 && (h = c.length);
474
+ const b = c.slice(f, h).trim();
475
+ if (f = h + 1, !b) continue;
476
+ const g = b.split(/\s+/);
477
+ o[p * 3] = Number(g[l]), o[p * 3 + 1] = Number(g[s]), o[p * 3 + 2] = Number(g[a]), r && u >= 0 && w >= 0 && m >= 0 && (r[p * 3] = Z(Number(g[u]) / 255), r[p * 3 + 1] = Z(Number(g[w]) / 255), r[p * 3 + 2] = Z(Number(g[m]) / 255)), i && d >= 0 && (i[p] = Math.min(65535, Math.max(0, Number(g[d]) | 0))), p++;
478
+ }
479
+ if (p !== e.count) throw new Error(`PLY ascii: expected ${e.count} vertex lines, got ${p}`);
480
+ }
481
+ function Wt(n, t, e, o, r, i, c) {
482
+ const l = e.recordSize, s = e.count * l;
483
+ if (n.length < t.bodyOffset + s) throw new Error(`PLY binary: expected ${s} body bytes, got ${n.length - t.bodyOffset}`);
484
+ const a = new DataView(n.buffer, n.byteOffset + t.bodyOffset, s), u = e.properties.find((b)=>b.name === "x"), w = e.properties.find((b)=>b.name === "y"), m = e.properties.find((b)=>b.name === "z"), d = r ? e.properties.find((b)=>b.name === "red" || b.name === "r") : void 0, f = r ? e.properties.find((b)=>b.name === "green" || b.name === "g") : void 0, p = r ? e.properties.find((b)=>b.name === "blue" || b.name === "b") : void 0, h = i ? e.properties.find((b)=>b.name === "intensity" || b.name === "scalar_Intensity") : void 0;
485
+ for(let b = 0; b < e.count; b++){
486
+ const g = b * l;
487
+ o[b * 3] = $(a, g + u.offset, u, c), o[b * 3 + 1] = $(a, g + w.offset, w, c), o[b * 3 + 2] = $(a, g + m.offset, m, c), r && d && f && p && (r[b * 3] = Z($(a, g + d.offset, d, c) / 255), r[b * 3 + 1] = Z($(a, g + f.offset, f, c) / 255), r[b * 3 + 2] = Z($(a, g + p.offset, p, c) / 255)), i && h && (i[b] = Math.min(65535, Math.max(0, $(a, g + h.offset, h, c) | 0)));
488
+ }
489
+ }
490
+ function $(n, t, e, o) {
491
+ switch(e.type){
492
+ case "char":
493
+ case "int8":
494
+ return n.getInt8(t);
495
+ case "uchar":
496
+ case "uint8":
497
+ return n.getUint8(t);
498
+ case "short":
499
+ case "int16":
500
+ return n.getInt16(t, o);
501
+ case "ushort":
502
+ case "uint16":
503
+ return n.getUint16(t, o);
504
+ case "int":
505
+ case "int32":
506
+ return n.getInt32(t, o);
507
+ case "uint":
508
+ case "uint32":
509
+ return n.getUint32(t, o);
510
+ case "float":
511
+ case "float32":
512
+ return n.getFloat32(t, o);
513
+ case "double":
514
+ case "float64":
515
+ return n.getFloat64(t, o);
516
+ default:
517
+ throw new Error(`PLY: cannot read scalar of type "${e.type}"`);
518
+ }
519
+ }
520
+ function Z(n) {
521
+ return n < 0 ? 0 : n > 1 ? 1 : n;
522
+ }
523
+ function Vt(n) {
524
+ let t = 1 / 0, e = 1 / 0, o = 1 / 0, r = -1 / 0, i = -1 / 0, c = -1 / 0;
525
+ for(let l = 0; l < n.length; l += 3){
526
+ const s = n[l], a = n[l + 1], u = n[l + 2];
527
+ s < t && (t = s), s > r && (r = s), a < e && (e = a), a > i && (i = a), u < o && (o = u), u > c && (c = u);
528
+ }
529
+ return {
530
+ min: [
531
+ t,
532
+ e,
533
+ o
534
+ ],
535
+ max: [
536
+ r,
537
+ i,
538
+ c
539
+ ]
540
+ };
541
+ }
542
+ class qt {
543
+ blob;
544
+ downsample;
545
+ label;
546
+ chunk = null;
547
+ served = !1;
548
+ constructor(t, e = {}){
549
+ this.blob = t, this.downsample = e.downsample ?? {
550
+ stride: 1
551
+ }, this.label = e.label;
552
+ }
553
+ async open(t) {
554
+ J(t);
555
+ const e = await this.blob.arrayBuffer();
556
+ J(t);
557
+ const o = new Uint8Array(e), i = At(o).elements.find((a)=>a.name === "vertex");
558
+ if (!i) throw new Error("PLY: no vertex element");
559
+ const c = !!i.properties.find((a)=>a.name === "red" || a.name === "r") && !!i.properties.find((a)=>a.name === "green" || a.name === "g") && !!i.properties.find((a)=>a.name === "blue" || a.name === "b"), l = !!i.properties.find((a)=>a.name === "intensity" || a.name === "scalar_Intensity"), s = Zt(o);
560
+ return this.chunk = Ht(s, this.downsample.stride), {
561
+ totalPointCount: this.chunk.pointCount,
562
+ bbox: this.chunk.bbox,
563
+ hasColor: c,
564
+ hasClassification: !1,
565
+ hasIntensity: l,
566
+ label: this.label
567
+ };
568
+ }
569
+ async next(t, e) {
570
+ return J(e), !this.chunk || this.served ? null : (this.served = !0, this.chunk);
571
+ }
572
+ close() {
573
+ this.chunk = null, this.served = !1;
574
+ }
575
+ }
576
+ function Ht(n, t) {
577
+ const e = Math.max(1, t | 0);
578
+ if (e === 1) return n;
579
+ const o = Math.ceil(n.pointCount / e), r = new Float32Array(o * 3), i = n.colors ? new Float32Array(o * 3) : void 0, c = n.classifications ? new Uint8Array(o) : void 0, l = n.intensities ? new Uint16Array(o) : void 0;
580
+ let s = 0;
581
+ for(let a = 0; a < n.pointCount; a += e)r[s * 3] = n.positions[a * 3], r[s * 3 + 1] = n.positions[a * 3 + 1], r[s * 3 + 2] = n.positions[a * 3 + 2], i && n.colors && (i[s * 3] = n.colors[a * 3], i[s * 3 + 1] = n.colors[a * 3 + 1], i[s * 3 + 2] = n.colors[a * 3 + 2]), c && n.classifications && (c[s] = n.classifications[a]), l && n.intensities && (l[s] = n.intensities[a]), s++;
582
+ return {
583
+ positions: r,
584
+ colors: i,
585
+ classifications: c,
586
+ intensities: l,
587
+ pointCount: o,
588
+ bbox: n.bbox
589
+ };
590
+ }
591
+ function J(n) {
592
+ if (n?.aborted) throw new DOMException("Aborted", "AbortError");
593
+ }
594
+ function Gt(n, t) {
595
+ const e = new Uint8Array(t);
596
+ let o = 0, r = 0;
597
+ const i = n.length;
598
+ for(; o < i;){
599
+ let c = n[o++];
600
+ if (c < 32) {
601
+ const l = c + 1;
602
+ if (o + l > i) throw new Error("LZF: literal run exceeds input bounds");
603
+ if (r + l > t) throw new Error("LZF: literal run exceeds output bounds");
604
+ e.set(n.subarray(o, o + l), r), o += l, r += l;
605
+ } else {
606
+ let l = c >> 5;
607
+ if (l === 7) {
608
+ if (o >= i) throw new Error("LZF: truncated extended length");
609
+ l += n[o++];
610
+ }
611
+ if (l += 2, o >= i) throw new Error("LZF: truncated back-reference offset");
612
+ const s = r - ((c & 31) << 8) - n[o++] - 1;
613
+ if (s < 0) throw new Error("LZF: back-reference points before output start");
614
+ if (r + l > t) throw new Error("LZF: back-reference exceeds output bounds");
615
+ for(let a = 0; a < l; a++)e[r + a] = e[s + a];
616
+ r += l;
617
+ }
618
+ }
619
+ if (r !== t) throw new Error(`LZF: decompressed ${r} bytes, expected ${t}`);
620
+ return e;
621
+ }
622
+ const Pt = new TextDecoder;
623
+ function jt(n) {
624
+ const t = Kt(n);
625
+ let e, o;
626
+ return t.data === "ascii" ? { positions: e, colors: o } = Jt(n, t) : t.data === "binary" ? { positions: e, colors: o } = te(n, t) : { positions: e, colors: o } = ee(n, t), {
627
+ positions: e,
628
+ colors: o,
629
+ pointCount: t.pointCount,
630
+ bbox: ie(e)
631
+ };
632
+ }
633
+ function Kt(n) {
634
+ const t = Math.min(65536, n.length), e = Pt.decode(n.subarray(0, t)), o = e.search(/^DATA\s+(\S+)/m);
635
+ if (o < 0) throw new Error("PCD: missing DATA line in header (scanned first " + t + " bytes)");
636
+ const r = e.slice(0, o), i = e.slice(o).match(/^DATA\s+(\S+)\s*\n/);
637
+ if (!i) throw new Error("PCD: malformed DATA line");
638
+ const c = i[1].toLowerCase();
639
+ if (c !== "ascii" && c !== "binary" && c !== "binary_compressed") throw new Error(`PCD: unsupported DATA kind "${c}"`);
640
+ const l = o + i[0].length, s = new Map;
641
+ for (const x of r.split(`
642
+ `)){
643
+ const I = x.replace(/#.*$/, "").trim();
644
+ if (!I) continue;
645
+ const E = I.split(/\s+/), A = E[0].toUpperCase();
646
+ s.set(A, E.slice(1));
647
+ }
648
+ const a = s.get("FIELDS") ?? [], u = (s.get("SIZE") ?? []).map(Number), w = s.get("TYPE") ?? [], m = (s.get("COUNT") ?? []).map(Number), d = s.get("WIDTH")?.[0], f = s.get("HEIGHT")?.[0], p = s.get("POINTS")?.[0];
649
+ if (a.length === 0) throw new Error("PCD: missing FIELDS");
650
+ if (u.length !== a.length) throw new Error("PCD: SIZE/FIELDS length mismatch");
651
+ if (w.length !== a.length) throw new Error("PCD: TYPE/FIELDS length mismatch");
652
+ const h = [];
653
+ let b = 0;
654
+ for(let x = 0; x < a.length; x++){
655
+ const I = m[x] ?? 1, E = u[x], A = w[x];
656
+ if (A !== "F" && A !== "I" && A !== "U") throw new Error(`PCD: unsupported field TYPE "${A}"`);
657
+ h.push({
658
+ name: a[x],
659
+ size: E,
660
+ type: A,
661
+ count: I,
662
+ offset: b
663
+ }), b += E * I;
664
+ }
665
+ const g = d !== void 0 ? parseInt(d, 10) : 0, y = f !== void 0 ? parseInt(f, 10) : 1, C = p !== void 0 ? parseInt(p, 10) : g * y;
666
+ if (!Number.isFinite(C) || C <= 0) throw new Error("PCD: invalid point count");
667
+ return {
668
+ version: s.get("VERSION")?.[0] ?? "0.7",
669
+ fields: h,
670
+ width: g,
671
+ height: y,
672
+ pointCount: C,
673
+ pointStride: b,
674
+ data: c,
675
+ bodyOffset: l
676
+ };
677
+ }
678
+ function lt(n) {
679
+ const t = {};
680
+ for (const e of n.fields){
681
+ const o = e.name.toLowerCase();
682
+ o === "x" ? t.xField = e : o === "y" ? t.yField = e : o === "z" ? t.zField = e : (o === "rgb" || o === "rgba") && (t.rgbField = e);
683
+ }
684
+ if (!t.xField || !t.yField || !t.zField) throw new Error("PCD: x/y/z fields are required");
685
+ return t;
686
+ }
687
+ function Jt(n, t) {
688
+ const e = lt(t), o = Pt.decode(n.subarray(t.bodyOffset)), r = new Float32Array(t.pointCount * 3), i = e.rgbField ? new Float32Array(t.pointCount * 3) : void 0, c = Qt(t, e);
689
+ let l = 0, s = 0, a = 0;
690
+ for(; a < t.pointCount && s < o.length;){
691
+ let u = o.indexOf(`
692
+ `, s);
693
+ u < 0 && (u = o.length);
694
+ const w = o.slice(s, u).trim();
695
+ if (s = u + 1, !w) continue;
696
+ const m = w.split(/\s+/);
697
+ if (r[l * 3] = Number(m[c.xCol]), r[l * 3 + 1] = Number(m[c.yCol]), r[l * 3 + 2] = Number(m[c.zCol]), i && c.rgbCol >= 0) {
698
+ const d = re(m[c.rgbCol], e.rgbField);
699
+ i[l * 3] = (d >> 16 & 255) / 255, i[l * 3 + 1] = (d >> 8 & 255) / 255, i[l * 3 + 2] = (d & 255) / 255;
700
+ }
701
+ l++, a++;
702
+ }
703
+ if (a !== t.pointCount) throw new Error(`PCD ascii: expected ${t.pointCount} points, got ${a}`);
704
+ return {
705
+ positions: r,
706
+ colors: i
707
+ };
708
+ }
709
+ function Qt(n, t) {
710
+ let e = 0, o = -1, r = -1, i = -1, c = -1;
711
+ for (const l of n.fields)l === t.xField && (o = e), l === t.yField && (r = e), l === t.zField && (i = e), l === t.rgbField && (c = e), e += l.count;
712
+ return {
713
+ xCol: o,
714
+ yCol: r,
715
+ zCol: i,
716
+ rgbCol: c
717
+ };
718
+ }
719
+ function te(n, t) {
720
+ const e = lt(t), o = new DataView(n.buffer, n.byteOffset + t.bodyOffset, t.pointCount * t.pointStride), r = new Float32Array(t.pointCount * 3), i = e.rgbField ? new Float32Array(t.pointCount * 3) : void 0;
721
+ for(let c = 0; c < t.pointCount; c++){
722
+ const l = c * t.pointStride;
723
+ if (r[c * 3] = X(o, l + e.xField.offset, e.xField), r[c * 3 + 1] = X(o, l + e.yField.offset, e.yField), r[c * 3 + 2] = X(o, l + e.zField.offset, e.zField), i && e.rgbField) {
724
+ const s = o.getUint32(l + e.rgbField.offset, !0);
725
+ i[c * 3] = (s >> 16 & 255) / 255, i[c * 3 + 1] = (s >> 8 & 255) / 255, i[c * 3 + 2] = (s & 255) / 255;
726
+ }
727
+ }
728
+ return {
729
+ positions: r,
730
+ colors: i
731
+ };
732
+ }
733
+ function ee(n, t) {
734
+ if (n.length < t.bodyOffset + 8) throw new Error("PCD binary_compressed: truncated size header");
735
+ const e = new DataView(n.buffer, n.byteOffset + t.bodyOffset, 8), o = e.getUint32(0, !0), r = e.getUint32(4, !0), i = t.pointCount * t.pointStride;
736
+ if (r !== i) throw new Error(`PCD binary_compressed: declared uncompressed=${r} does not match fields*points=${i}`);
737
+ const c = n.subarray(t.bodyOffset + 8, t.bodyOffset + 8 + o), l = Gt(c, r), s = lt(t), a = new Map;
738
+ let u = 0;
739
+ for (const g of t.fields)a.set(g, u), u += t.pointCount * g.size * g.count;
740
+ const w = new DataView(l.buffer, l.byteOffset, l.byteLength), m = new Float32Array(t.pointCount * 3), d = s.rgbField ? new Float32Array(t.pointCount * 3) : void 0, f = a.get(s.xField), p = a.get(s.yField), h = a.get(s.zField), b = s.rgbField ? a.get(s.rgbField) : 0;
741
+ for(let g = 0; g < t.pointCount; g++)if (m[g * 3] = X(w, f + g * s.xField.size, s.xField), m[g * 3 + 1] = X(w, p + g * s.yField.size, s.yField), m[g * 3 + 2] = X(w, h + g * s.zField.size, s.zField), d && s.rgbField) {
742
+ const y = w.getUint32(b + g * s.rgbField.size, !0);
743
+ d[g * 3] = (y >> 16 & 255) / 255, d[g * 3 + 1] = (y >> 8 & 255) / 255, d[g * 3 + 2] = (y & 255) / 255;
744
+ }
745
+ return {
746
+ positions: m,
747
+ colors: d
748
+ };
749
+ }
750
+ function X(n, t, e) {
751
+ if (e.type === "F") return e.size === 8 ? n.getFloat64(t, !0) : n.getFloat32(t, !0);
752
+ if (e.type === "U") {
753
+ if (e.size === 1) return n.getUint8(t);
754
+ if (e.size === 2) return n.getUint16(t, !0);
755
+ if (e.size === 4) return n.getUint32(t, !0);
756
+ } else {
757
+ if (e.size === 1) return n.getInt8(t);
758
+ if (e.size === 2) return n.getInt16(t, !0);
759
+ if (e.size === 4) return n.getInt32(t, !0);
760
+ }
761
+ throw new Error(`PCD: unsupported field width ${e.size} for type ${e.type}`);
762
+ }
763
+ const Mt = new ArrayBuffer(4), ne = new Float32Array(Mt), oe = new Uint32Array(Mt);
764
+ function re(n, t) {
765
+ return t.type === "F" ? (ne[0] = Number(n), oe[0]) : Number(n) >>> 0;
766
+ }
767
+ function ie(n) {
768
+ let t = 1 / 0, e = 1 / 0, o = 1 / 0, r = -1 / 0, i = -1 / 0, c = -1 / 0;
769
+ for(let l = 0; l < n.length; l += 3){
770
+ const s = n[l], a = n[l + 1], u = n[l + 2];
771
+ s < t && (t = s), s > r && (r = s), a < e && (e = a), a > i && (i = a), u < o && (o = u), u > c && (c = u);
772
+ }
773
+ return {
774
+ min: [
775
+ t,
776
+ e,
777
+ o
778
+ ],
779
+ max: [
780
+ r,
781
+ i,
782
+ c
783
+ ]
784
+ };
785
+ }
786
+ class se {
787
+ blob;
788
+ downsample;
789
+ label;
790
+ chunk = null;
791
+ served = !1;
792
+ constructor(t, e = {}){
793
+ this.blob = t, this.downsample = e.downsample ?? {
794
+ stride: 1
795
+ }, this.label = e.label;
796
+ }
797
+ async open(t) {
798
+ Q(t);
799
+ const e = await this.blob.arrayBuffer();
800
+ Q(t);
801
+ const o = jt(new Uint8Array(e));
802
+ return this.chunk = ae(o, this.downsample.stride), {
803
+ totalPointCount: this.chunk.pointCount,
804
+ bbox: this.chunk.bbox,
805
+ hasColor: !!this.chunk.colors,
806
+ hasClassification: !!this.chunk.classifications,
807
+ hasIntensity: !!this.chunk.intensities,
808
+ label: this.label
809
+ };
810
+ }
811
+ async next(t, e) {
812
+ return Q(e), !this.chunk || this.served ? null : (this.served = !0, this.chunk);
813
+ }
814
+ close() {
815
+ this.chunk = null, this.served = !1;
816
+ }
817
+ }
818
+ function ae(n, t) {
819
+ const e = Math.max(1, t | 0);
820
+ if (e === 1) return n;
821
+ const o = Math.ceil(n.pointCount / e), r = new Float32Array(o * 3), i = n.colors ? new Float32Array(o * 3) : void 0, c = n.classifications ? new Uint8Array(o) : void 0, l = n.intensities ? new Uint16Array(o) : void 0;
822
+ let s = 0;
823
+ for(let a = 0; a < n.pointCount; a += e)r[s * 3] = n.positions[a * 3], r[s * 3 + 1] = n.positions[a * 3 + 1], r[s * 3 + 2] = n.positions[a * 3 + 2], i && n.colors && (i[s * 3] = n.colors[a * 3], i[s * 3 + 1] = n.colors[a * 3 + 1], i[s * 3 + 2] = n.colors[a * 3 + 2]), c && n.classifications && (c[s] = n.classifications[a]), l && n.intensities && (l[s] = n.intensities[a]), s++;
824
+ return {
825
+ positions: r,
826
+ colors: i,
827
+ classifications: c,
828
+ intensities: l,
829
+ pointCount: o,
830
+ bbox: n.bbox
831
+ };
832
+ }
833
+ function Q(n) {
834
+ if (n?.aborted) throw new DOMException("Aborted", "AbortError");
835
+ }
836
+ const wt = "ASTM-E57";
837
+ function ce(n) {
838
+ if (n.length < 48) throw new Error("E57: header truncated (need 48 bytes)");
839
+ const t = String.fromCharCode(...n.subarray(0, 8));
840
+ if (t !== wt) throw new Error(`E57: bad magic "${t}" (expected "${wt}")`);
841
+ const e = new DataView(n.buffer, n.byteOffset, n.byteLength);
842
+ return {
843
+ majorVersion: e.getUint32(8, !0),
844
+ minorVersion: e.getUint32(12, !0),
845
+ fileLogicalSize: k(e, 16),
846
+ xmlLogicalOffset: at(k(e, 24), k(e, 40)),
847
+ xmlLogicalLength: k(e, 32),
848
+ pageSize: k(e, 40)
849
+ };
850
+ }
851
+ function le(n, t) {
852
+ if (t <= 4) throw new Error("E57: pageSize too small");
853
+ const e = t - 4, o = Math.floor(n.length / t), r = n.length - o * t, i = new Uint8Array(o * e + Math.max(0, r - 4));
854
+ let c = 0;
855
+ for(let l = 0; l < o; l++){
856
+ const s = l * t;
857
+ i.set(n.subarray(s, s + e), c), c += e;
858
+ }
859
+ if (r > 4) {
860
+ const l = o * t;
861
+ i.set(n.subarray(l, l + r - 4), c);
862
+ }
863
+ return i;
864
+ }
865
+ function at(n, t) {
866
+ const e = t - 4, o = Math.floor(n / t), r = n - o * t;
867
+ return o * e + r;
868
+ }
869
+ function fe(n, t, e) {
870
+ const o = at(t, e);
871
+ if (o + 32 > n.length) throw new Error(`E57: CompressedVector section header at logical ${o} runs past end of file (length ${n.length})`);
872
+ const r = new DataView(n.buffer, n.byteOffset + o, 32), i = r.getUint8(0);
873
+ if (i !== 1) throw new Error(`E57: expected CompressedVector section (id=1) at physical ${t}, got id=${i}`);
874
+ const c = k(r, 16);
875
+ return at(c, e);
876
+ }
877
+ function k(n, t) {
878
+ const e = n.getUint32(t, !0);
879
+ return n.getUint32(t + 4, !0) * 4294967296 + e;
880
+ }
881
+ function ue(n) {
882
+ const t = {
883
+ name: "",
884
+ attrs: new Map,
885
+ children: [],
886
+ text: ""
887
+ }, e = [
888
+ t
889
+ ];
890
+ let o = 0;
891
+ const r = n.length;
892
+ let i = -1;
893
+ const c = (l)=>{
894
+ if (i < 0 || i >= l) {
895
+ i = -1;
896
+ return;
897
+ }
898
+ const s = n.slice(i, l).trim();
899
+ if (s.length > 0) {
900
+ const a = e[e.length - 1];
901
+ a.children.length === 0 && (a.text = a.text + Lt(s));
902
+ }
903
+ i = -1;
904
+ };
905
+ for(; o < r;){
906
+ if (n.charCodeAt(o) !== 60) {
907
+ i < 0 && (i = o), o++;
908
+ continue;
909
+ }
910
+ if (c(o), n.startsWith("<?", o)) {
911
+ const h = n.indexOf("?>", o + 2);
912
+ o = h < 0 ? r : h + 2;
913
+ continue;
914
+ }
915
+ if (n.startsWith("<!--", o)) {
916
+ const h = n.indexOf("-->", o + 4);
917
+ o = h < 0 ? r : h + 3;
918
+ continue;
919
+ }
920
+ if (n.startsWith("<![CDATA[", o)) {
921
+ const h = n.indexOf("]]>", o + 9), b = n.slice(o + 9, h < 0 ? r : h), g = e[e.length - 1];
922
+ g.children.length === 0 && (g.text = g.text + b), o = h < 0 ? r : h + 3;
923
+ continue;
924
+ }
925
+ if (n.startsWith("<!", o)) {
926
+ const h = n.indexOf(">", o + 2);
927
+ o = h < 0 ? r : h + 1;
928
+ continue;
929
+ }
930
+ if (n.charCodeAt(o + 1) === 47) {
931
+ const h = n.indexOf(">", o + 2);
932
+ if (h < 0) throw new Error("XML: unterminated closing tag");
933
+ const b = n.slice(o + 2, h).trim(), g = e[e.length - 1];
934
+ if (g.name !== b) throw new Error(`XML: mismatched closing tag </${b}> (expected </${g.name}>)`);
935
+ e.pop(), o = h + 1;
936
+ continue;
937
+ }
938
+ const s = de(n, o + 1);
939
+ if (s < 0) throw new Error("XML: unterminated tag");
940
+ let a = n.slice(o + 1, s).trim(), u = !1;
941
+ a.endsWith("/") && (u = !0, a = a.slice(0, -1).trim());
942
+ const w = a.match(/^([A-Za-z_][\w:.\-]*)/);
943
+ if (!w) {
944
+ o = s + 1;
945
+ continue;
946
+ }
947
+ const m = w[1], d = a.slice(m.length).trim(), f = he(d), p = {
948
+ name: m,
949
+ attrs: f,
950
+ children: [],
951
+ text: ""
952
+ };
953
+ e.length === 1 && t.name === "" ? (t.name = m, t.attrs = f, u || e.push(t)) : (e[e.length - 1].children.push(p), u || e.push(p)), o = s + 1;
954
+ }
955
+ if (c(r), e.length !== 1) throw new Error(`XML: unclosed tag <${e[e.length - 1].name}>`);
956
+ if (t.name === "") throw new Error("XML: missing root element");
957
+ return t;
958
+ }
959
+ function de(n, t) {
960
+ let e = !1;
961
+ for(let o = t; o < n.length; o++){
962
+ const r = n.charCodeAt(o);
963
+ if (r === 34) e = !e;
964
+ else if (r === 62 && !e) return o;
965
+ }
966
+ return -1;
967
+ }
968
+ const gt = /([A-Za-z_][\w:.\-]*)\s*=\s*"([^"]*)"/g;
969
+ function he(n) {
970
+ const t = new Map;
971
+ if (!n) return t;
972
+ let e;
973
+ for(gt.lastIndex = 0; (e = gt.exec(n)) !== null;)t.set(e[1], Lt(e[2]));
974
+ return t;
975
+ }
976
+ function Lt(n) {
977
+ return n.indexOf("&") < 0 ? n : n.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&#(\d+);/g, (t, e)=>String.fromCharCode(parseInt(e, 10))).replace(/&#x([0-9a-fA-F]+);/g, (t, e)=>String.fromCharCode(parseInt(e, 16))).replace(/&amp;/g, "&");
978
+ }
979
+ function N(n, t) {
980
+ for (const e of n.children)if (e.name === t) return e;
981
+ return null;
982
+ }
983
+ function me(n, t) {
984
+ return n.children.filter((e)=>e.name === t);
985
+ }
986
+ function U(n, t) {
987
+ const e = N(n, t);
988
+ if (!e) return null;
989
+ const o = e.text.trim();
990
+ return o.length > 0 ? o : null;
991
+ }
992
+ function pe(n) {
993
+ const t = ue(n);
994
+ if (t.name !== "e57Root") throw new Error(`E57: XML root is not <e57Root> (saw <${t.name || "?"}>)`);
995
+ const e = N(t, "data3D");
996
+ if (!e) return [];
997
+ const o = [];
998
+ for (const r of me(e, "vectorChild")){
999
+ const i = N(r, "points");
1000
+ if (!i || i.attrs.get("type") !== "CompressedVector") continue;
1001
+ const c = i.attrs.get("fileOffset"), l = i.attrs.get("recordCount");
1002
+ if (!c || !l) continue;
1003
+ const s = Number(c), a = Number(l);
1004
+ if (!Number.isFinite(s) || s < 0 || !Number.isFinite(a) || a < 0) continue;
1005
+ const u = N(i, "prototype");
1006
+ if (!u) continue;
1007
+ const w = [];
1008
+ for (const m of u.children){
1009
+ const d = m.attrs.get("type") ?? "";
1010
+ d === "Float" ? w.push({
1011
+ name: m.name,
1012
+ kind: "Float",
1013
+ precision: m.attrs.get("precision") === "single" ? "single" : "double"
1014
+ }) : d === "ScaledInteger" ? w.push({
1015
+ name: m.name,
1016
+ kind: "ScaledInteger",
1017
+ scale: Number(m.attrs.get("scale") ?? "1"),
1018
+ offset: Number(m.attrs.get("offset") ?? "0"),
1019
+ minimum: Number(m.attrs.get("minimum") ?? "0"),
1020
+ maximum: Number(m.attrs.get("maximum") ?? "0")
1021
+ }) : d === "Integer" && w.push({
1022
+ name: m.name,
1023
+ kind: "Integer",
1024
+ minimum: Number(m.attrs.get("minimum") ?? "0"),
1025
+ maximum: Number(m.attrs.get("maximum") ?? "0")
1026
+ });
1027
+ }
1028
+ o.push({
1029
+ guid: U(r, "guid") ?? "",
1030
+ name: U(r, "name") ?? void 0,
1031
+ recordCount: a,
1032
+ binaryFileOffset: s,
1033
+ prototype: w,
1034
+ pose: be(N(r, "pose")) ?? void 0
1035
+ });
1036
+ }
1037
+ return o;
1038
+ }
1039
+ function be(n) {
1040
+ if (!n) return null;
1041
+ const t = N(n, "rotation"), e = N(n, "translation");
1042
+ if (!t || !e) return null;
1043
+ const o = Number(U(t, "w") ?? "1"), r = Number(U(t, "x") ?? "0"), i = Number(U(t, "y") ?? "0"), c = Number(U(t, "z") ?? "0"), l = Number(U(e, "x") ?? "0"), s = Number(U(e, "y") ?? "0"), a = Number(U(e, "z") ?? "0");
1044
+ return [
1045
+ o,
1046
+ r,
1047
+ i,
1048
+ c,
1049
+ l,
1050
+ s,
1051
+ a
1052
+ ].every(Number.isFinite) ? {
1053
+ rotation: {
1054
+ w: o,
1055
+ x: r,
1056
+ y: i,
1057
+ z: c
1058
+ },
1059
+ translation: {
1060
+ x: l,
1061
+ y: s,
1062
+ z: a
1063
+ }
1064
+ } : null;
1065
+ }
1066
+ function D(n, t) {
1067
+ return n.find((e)=>e.name === t);
1068
+ }
1069
+ function we(n, t) {
1070
+ const e = D(t.prototype, "cartesianX"), o = D(t.prototype, "cartesianY"), r = D(t.prototype, "cartesianZ");
1071
+ if (!e || !o || !r) throw new Error("E57: prototype missing cartesianX/Y/Z");
1072
+ for (const g of [
1073
+ e,
1074
+ o,
1075
+ r
1076
+ ])if (g.kind === "Integer") throw new Error(`E57: cartesian${g.name.slice(-1)} encoded as plain Integer (only Float / ScaledInteger supported)`);
1077
+ const i = D(t.prototype, "colorRed"), c = D(t.prototype, "colorGreen"), l = D(t.prototype, "colorBlue"), s = !!(i && c && l), a = D(t.prototype, "intensity"), u = D(t.prototype, "classification"), w = new Float32Array(t.recordCount * 3), m = s ? new Float32Array(t.recordCount * 3) : void 0, d = a && (a.kind === "Float" || a.kind === "Integer" || a.kind === "ScaledInteger") ? new Uint16Array(t.recordCount) : void 0, f = u && (u.kind === "Integer" || u.kind === "ScaledInteger") ? new Uint8Array(t.recordCount) : void 0;
1078
+ let p = t.binaryFileOffset;
1079
+ const h = new DataView(n.buffer, n.byteOffset, n.byteLength);
1080
+ let b = 0;
1081
+ for(; b < t.recordCount && p < n.length;){
1082
+ if (p + 4 > n.length) throw new Error("E57: truncated DataPacket header");
1083
+ const g = h.getUint8(p), y = h.getUint16(p + 2, !0) + 1;
1084
+ if (g !== 1) {
1085
+ p += y;
1086
+ continue;
1087
+ }
1088
+ const C = p + y;
1089
+ if (C > n.length) throw new Error("E57: DataPacket runs past end of logical bytes");
1090
+ const x = C;
1091
+ if (p + 6 > x) throw new Error("E57: truncated DataPacket header");
1092
+ const I = h.getUint16(p + 4, !0);
1093
+ if (I !== t.prototype.length) throw new Error(`E57: packet bytestreamCount (${I}) ≠ prototype length (${t.prototype.length})`);
1094
+ const E = [];
1095
+ let A = p + 6;
1096
+ for(let M = 0; M < I; M++){
1097
+ if (A + 2 > x) throw new Error("E57: truncated bytestream length table");
1098
+ E.push(h.getUint16(A, !0)), A += 2;
1099
+ }
1100
+ const S = new Map;
1101
+ let R = A;
1102
+ for(let M = 0; M < I; M++){
1103
+ if (R + E[M] > x) throw new Error(`E57: bytestream ${t.prototype[M].name} (${E[M]} bytes) runs past packet payload at offset ${R}`);
1104
+ S.set(t.prototype[M].name, {
1105
+ start: R,
1106
+ length: E[M]
1107
+ }), R += E[M];
1108
+ }
1109
+ const B = S.get("cartesianX"), _ = S.get("cartesianY"), H = S.get("cartesianZ"), z = nt(e, B.length), F = nt(o, _.length), P = nt(r, H.length), O = Math.min(z, F, P), L = Math.min(O, t.recordCount - b);
1110
+ et(n, h, e, B.start, w, b, L, 0), et(n, h, o, _.start, w, b, L, 1), et(n, h, r, H.start, w, b, L, 2), m && i && c && l && (tt(h, S.get("colorRed").start, i, m, b, L, 0, n), tt(h, S.get("colorGreen").start, c, m, b, L, 1, n), tt(h, S.get("colorBlue").start, l, m, b, L, 2, n)), d && a && ge(n, h, a, S.get("intensity").start, d, b, L), f && u && ye(n, h, u, S.get("classification").start, f, b, L), b += L, p = C;
1111
+ }
1112
+ return b < t.recordCount ? yt(w.subarray(0, b * 3), m?.subarray(0, b * 3), d?.subarray(0, b), f?.subarray(0, b), b) : yt(w, m, d, f, t.recordCount);
1113
+ }
1114
+ function tt(n, t, e, o, r, i, c, l) {
1115
+ if (e.kind === "Float") {
1116
+ const s = e.precision === "single" ? 4 : 8;
1117
+ for(let a = 0; a < i; a++){
1118
+ const u = s === 4 ? n.getFloat32(t + a * s, !0) : n.getFloat64(t + a * s, !0);
1119
+ o[(r + a) * 3 + c] = ot(u);
1120
+ }
1121
+ } else if (e.kind === "Integer") {
1122
+ const s = e.minimum ?? 0, a = e.maximum ?? 255, u = a - s, w = u > 0 ? 1 / u : 1, d = Math.max(Math.abs(s), Math.abs(a)) > 255 ? 2 : 1, f = s < 0;
1123
+ for(let p = 0; p < i; p++){
1124
+ const h = t + p * d, b = d === 2 ? f ? n.getInt16(h, !0) : n.getUint16(h, !0) : f ? n.getInt8(h) : n.getUint8(h);
1125
+ o[(r + p) * 3 + c] = ot((b - s) * w);
1126
+ }
1127
+ } else {
1128
+ const s = e.minimum ?? 0, u = (e.maximum ?? 1) - s, w = u > 0 ? 1 / u : 1, m = q(e), d = t * 8;
1129
+ for(let f = 0; f < i; f++){
1130
+ const p = j(l, d + f * m, m);
1131
+ o[(r + f) * 3 + c] = ot(p * w);
1132
+ }
1133
+ }
1134
+ }
1135
+ function et(n, t, e, o, r, i, c, l) {
1136
+ if (e.kind === "Float") {
1137
+ const d = e.precision === "single" ? 4 : 8;
1138
+ if (d === 4) for(let f = 0; f < c; f++)r[(i + f) * 3 + l] = t.getFloat32(o + f * d, !0);
1139
+ else for(let f = 0; f < c; f++)r[(i + f) * 3 + l] = t.getFloat64(o + f * d, !0);
1140
+ return;
1141
+ }
1142
+ const s = q(e), a = e.minimum ?? 0, u = e.scale ?? 1, w = e.offset ?? 0, m = o * 8;
1143
+ for(let d = 0; d < c; d++){
1144
+ const f = j(n, m + d * s, s);
1145
+ r[(i + d) * 3 + l] = (f + a) * u + w;
1146
+ }
1147
+ }
1148
+ function ge(n, t, e, o, r, i, c) {
1149
+ if (e.kind === "Float") {
1150
+ const d = e.precision === "single" ? 4 : 8;
1151
+ for(let f = 0; f < c; f++){
1152
+ const p = d === 4 ? t.getFloat32(o + f * d, !0) : t.getFloat64(o + f * d, !0);
1153
+ r[i + f] = Math.min(65535, Math.max(0, Math.round(p * 65535)));
1154
+ }
1155
+ return;
1156
+ }
1157
+ if (e.kind === "Integer") {
1158
+ const d = e.minimum ?? 0, f = e.maximum ?? 65535, p = f - d, h = p > 0 ? 1 / p : 1, g = Math.max(Math.abs(d), Math.abs(f)) > 255 ? 2 : 1, y = d < 0;
1159
+ for(let C = 0; C < c; C++){
1160
+ const x = o + C * g, E = ((g === 2 ? y ? t.getInt16(x, !0) : t.getUint16(x, !0) : y ? t.getInt8(x) : t.getUint8(x)) - d) * h;
1161
+ r[i + C] = Math.min(65535, Math.max(0, Math.round(E * 65535)));
1162
+ }
1163
+ return;
1164
+ }
1165
+ const l = q(e), s = e.minimum ?? 0, u = (e.maximum ?? s) - s, w = u > 0 ? 1 / u : 1, m = o * 8;
1166
+ for(let d = 0; d < c; d++){
1167
+ const f = j(n, m + d * l, l);
1168
+ r[i + d] = Math.min(65535, Math.max(0, Math.round(f * w * 65535)));
1169
+ }
1170
+ }
1171
+ function q(n) {
1172
+ const t = n.minimum ?? 0, e = n.maximum ?? t, o = Math.max(0, e - t);
1173
+ if (o === 0) return 1;
1174
+ const r = Math.ceil(Math.log2(o + 1));
1175
+ if (r > 53) throw new Error(`E57: ScaledInteger field "${n.name}" needs ${r} bits — exceeds the 53-bit Number-precision limit`);
1176
+ return Math.max(1, r);
1177
+ }
1178
+ function nt(n, t) {
1179
+ if (n.kind === "Float") {
1180
+ const c = n.precision === "single" ? 4 : 8;
1181
+ return Math.floor(t / c);
1182
+ }
1183
+ if (n.kind === "ScaledInteger") {
1184
+ const c = q(n);
1185
+ return Math.floor(t * 8 / c);
1186
+ }
1187
+ const e = n.minimum ?? 0, o = n.maximum ?? 255, i = Math.max(Math.abs(e), Math.abs(o)) > 255 ? 2 : 1;
1188
+ return Math.floor(t / i);
1189
+ }
1190
+ function j(n, t, e) {
1191
+ let o = 0, r = 0, i = t >>> 3, c = t & 7;
1192
+ for(; r < e;){
1193
+ const l = 8 - c, s = Math.min(l, e - r), a = (1 << s) - 1, u = n[i] >>> c & a;
1194
+ o += u * Math.pow(2, r), r += s, c = 0, i++;
1195
+ }
1196
+ return o;
1197
+ }
1198
+ function yt(n, t, e, o, r) {
1199
+ return {
1200
+ positions: new Float32Array(n),
1201
+ colors: t ? new Float32Array(t) : void 0,
1202
+ intensities: e ? new Uint16Array(e) : void 0,
1203
+ classifications: o ? new Uint8Array(o) : void 0,
1204
+ pointCount: r,
1205
+ bbox: ct(n)
1206
+ };
1207
+ }
1208
+ function ye(n, t, e, o, r, i, c) {
1209
+ if (e.kind === "Integer") {
1210
+ const u = e.minimum ?? 0, w = e.maximum ?? 255, d = Math.max(Math.abs(u), Math.abs(w)) > 255 ? 2 : 1, f = u < 0;
1211
+ for(let p = 0; p < c; p++){
1212
+ const h = o + p * d, b = d === 2 ? f ? t.getInt16(h, !0) : t.getUint16(h, !0) : f ? t.getInt8(h) : t.getUint8(h);
1213
+ r[i + p] = Math.max(0, Math.min(255, b));
1214
+ }
1215
+ return;
1216
+ }
1217
+ const l = q(e), s = e.minimum ?? 0, a = o * 8;
1218
+ for(let u = 0; u < c; u++){
1219
+ const w = j(n, a + u * l, l);
1220
+ r[i + u] = Math.max(0, Math.min(255, w + s));
1221
+ }
1222
+ }
1223
+ function ot(n) {
1224
+ return n < 0 ? 0 : n > 1 ? 1 : n;
1225
+ }
1226
+ function ct(n) {
1227
+ if (n.length < 3) return {
1228
+ min: [
1229
+ 0,
1230
+ 0,
1231
+ 0
1232
+ ],
1233
+ max: [
1234
+ 0,
1235
+ 0,
1236
+ 0
1237
+ ]
1238
+ };
1239
+ let t = 1 / 0, e = 1 / 0, o = 1 / 0, r = -1 / 0, i = -1 / 0, c = -1 / 0, l = !1;
1240
+ for(let s = 0; s + 2 < n.length; s += 3){
1241
+ const a = n[s], u = n[s + 1], w = n[s + 2];
1242
+ !Number.isFinite(a) || !Number.isFinite(u) || !Number.isFinite(w) || (l = !0, a < t && (t = a), a > r && (r = a), u < e && (e = u), u > i && (i = u), w < o && (o = w), w > c && (c = w));
1243
+ }
1244
+ return l ? {
1245
+ min: [
1246
+ t,
1247
+ e,
1248
+ o
1249
+ ],
1250
+ max: [
1251
+ r,
1252
+ i,
1253
+ c
1254
+ ]
1255
+ } : {
1256
+ min: [
1257
+ 0,
1258
+ 0,
1259
+ 0
1260
+ ],
1261
+ max: [
1262
+ 0,
1263
+ 0,
1264
+ 0
1265
+ ]
1266
+ };
1267
+ }
1268
+ const xe = new TextDecoder;
1269
+ function Ce(n) {
1270
+ const t = ce(n), e = le(n, t.pageSize), o = e.subarray(t.xmlLogicalOffset, t.xmlLogicalOffset + t.xmlLogicalLength), r = xe.decode(o), i = pe(r);
1271
+ if (i.length === 0) return null;
1272
+ const c = i.map((f)=>{
1273
+ const p = fe(e, f.binaryFileOffset, t.pageSize), h = we(e, {
1274
+ ...f,
1275
+ binaryFileOffset: p
1276
+ });
1277
+ return f.pose && (Ie(h.positions, h.pointCount, f.pose), h.bbox = ct(h.positions)), h;
1278
+ });
1279
+ if (c.length === 1) return c[0];
1280
+ let l = 0;
1281
+ for (const f of c)l += f.pointCount;
1282
+ const s = new Float32Array(l * 3), a = c.some((f)=>f.colors), u = c.some((f)=>f.intensities), w = a ? new Float32Array(l * 3) : void 0, m = u ? new Uint16Array(l) : void 0;
1283
+ let d = 0;
1284
+ for (const f of c)s.set(f.positions, d * 3), w && f.colors && w.set(f.colors, d * 3), m && f.intensities && m.set(f.intensities, d), d += f.pointCount;
1285
+ return {
1286
+ positions: s,
1287
+ colors: w,
1288
+ intensities: m,
1289
+ pointCount: l,
1290
+ bbox: ct(s)
1291
+ };
1292
+ }
1293
+ function Ie(n, t, e) {
1294
+ const { w: o, x: r, y: i, z: c } = e.rotation, l = e.translation.x, s = e.translation.y, a = e.translation.z, u = 1 - 2 * (i * i + c * c), w = 2 * (r * i - o * c), m = 2 * (r * c + o * i), d = 2 * (r * i + o * c), f = 1 - 2 * (r * r + c * c), p = 2 * (i * c - o * r), h = 2 * (r * c - o * i), b = 2 * (i * c + o * r), g = 1 - 2 * (r * r + i * i);
1295
+ for(let y = 0; y < t; y++){
1296
+ const C = n[y * 3], x = n[y * 3 + 1], I = n[y * 3 + 2];
1297
+ n[y * 3] = u * C + w * x + m * I + l, n[y * 3 + 1] = d * C + f * x + p * I + s, n[y * 3 + 2] = h * C + b * x + g * I + a;
1298
+ }
1299
+ }
1300
+ class Fe {
1301
+ blob;
1302
+ downsample;
1303
+ label;
1304
+ chunk = null;
1305
+ served = !1;
1306
+ constructor(t, e = {}){
1307
+ this.blob = t, this.downsample = e.downsample ?? {
1308
+ stride: 1
1309
+ }, this.label = e.label;
1310
+ }
1311
+ async open(t) {
1312
+ rt(t);
1313
+ const e = await this.blob.arrayBuffer();
1314
+ rt(t);
1315
+ const o = Ce(new Uint8Array(e));
1316
+ if (!o) throw new Error("E57: file contains no Data3D scans");
1317
+ return this.chunk = Ee(o, this.downsample.stride), {
1318
+ totalPointCount: this.chunk.pointCount,
1319
+ bbox: this.chunk.bbox,
1320
+ hasColor: !!this.chunk.colors,
1321
+ hasClassification: !!this.chunk.classifications,
1322
+ hasIntensity: !!this.chunk.intensities,
1323
+ label: this.label
1324
+ };
1325
+ }
1326
+ async next(t, e) {
1327
+ return rt(e), !this.chunk || this.served ? null : (this.served = !0, this.chunk);
1328
+ }
1329
+ close() {
1330
+ this.chunk = null, this.served = !1;
1331
+ }
1332
+ }
1333
+ function Ee(n, t) {
1334
+ const e = Math.max(1, t | 0);
1335
+ if (e === 1) return n;
1336
+ const o = Math.ceil(n.pointCount / e), r = new Float32Array(o * 3), i = n.colors ? new Float32Array(o * 3) : void 0, c = n.intensities ? new Uint16Array(o) : void 0, l = n.classifications ? new Uint8Array(o) : void 0;
1337
+ let s = 0;
1338
+ for(let a = 0; a < n.pointCount; a += e)r[s * 3] = n.positions[a * 3], r[s * 3 + 1] = n.positions[a * 3 + 1], r[s * 3 + 2] = n.positions[a * 3 + 2], i && n.colors && (i[s * 3] = n.colors[a * 3], i[s * 3 + 1] = n.colors[a * 3 + 1], i[s * 3 + 2] = n.colors[a * 3 + 2]), c && n.intensities && (c[s] = n.intensities[a]), l && n.classifications && (l[s] = n.classifications[a]), s++;
1339
+ return {
1340
+ positions: r,
1341
+ colors: i,
1342
+ intensities: c,
1343
+ classifications: l,
1344
+ pointCount: o,
1345
+ bbox: n.bbox
1346
+ };
1347
+ }
1348
+ function rt(n) {
1349
+ if (n?.aborted) throw new DOMException("Aborted", "AbortError");
1350
+ }
1351
+ const St = new TextDecoder;
1352
+ function Ae(n, t) {
1353
+ const e = Math.min(16384, n.length), r = St.decode(n.subarray(0, e)).split(/\r?\n/);
1354
+ let i = null, c = !1;
1355
+ for(let u = 0; u < r.length; u++){
1356
+ const w = r[u].trim();
1357
+ if (w.length !== 0 && !(w.startsWith("#") || w.startsWith("//"))) {
1358
+ if (u === 0 || !c) {
1359
+ const m = w.split(/\s+/);
1360
+ if (m.length === 1 && /^\d+$/.test(m[0])) {
1361
+ c = !0;
1362
+ continue;
1363
+ }
1364
+ }
1365
+ i = w;
1366
+ break;
1367
+ }
1368
+ }
1369
+ if (i === null) return null;
1370
+ const l = i.split(/\s+/), s = l.length;
1371
+ for (const u of l)if (!Number.isFinite(Number(u))) return null;
1372
+ const a = Pe(s, t);
1373
+ return a ? {
1374
+ columns: s,
1375
+ hasHeaderCount: c,
1376
+ fields: a
1377
+ } : null;
1378
+ }
1379
+ function Pe(n, t) {
1380
+ switch(n){
1381
+ case 3:
1382
+ return [
1383
+ "x",
1384
+ "y",
1385
+ "z"
1386
+ ];
1387
+ case 4:
1388
+ return [
1389
+ "x",
1390
+ "y",
1391
+ "z",
1392
+ "i"
1393
+ ];
1394
+ case 6:
1395
+ return [
1396
+ "x",
1397
+ "y",
1398
+ "z",
1399
+ "r",
1400
+ "g",
1401
+ "b"
1402
+ ];
1403
+ case 7:
1404
+ return [
1405
+ "x",
1406
+ "y",
1407
+ "z",
1408
+ "i",
1409
+ "r",
1410
+ "g",
1411
+ "b"
1412
+ ];
1413
+ case 9:
1414
+ return [
1415
+ "x",
1416
+ "y",
1417
+ "z",
1418
+ "r",
1419
+ "g",
1420
+ "b",
1421
+ "skip",
1422
+ "skip",
1423
+ "skip"
1424
+ ];
1425
+ case 10:
1426
+ return [
1427
+ "x",
1428
+ "y",
1429
+ "z",
1430
+ "i",
1431
+ "r",
1432
+ "g",
1433
+ "b",
1434
+ "skip",
1435
+ "skip",
1436
+ "skip"
1437
+ ];
1438
+ default:
1439
+ if (n >= 3 && t === "xyz") {
1440
+ const e = [
1441
+ "x",
1442
+ "y",
1443
+ "z"
1444
+ ];
1445
+ for(let o = 3; o < n; o++)e.push("skip");
1446
+ return e;
1447
+ }
1448
+ return null;
1449
+ }
1450
+ }
1451
+ function Me(n, t) {
1452
+ const e = Ae(n, t);
1453
+ if (!e) throw new Error(`${t.toUpperCase()}: file does not look like ASCII point data`);
1454
+ const o = St.decode(n);
1455
+ return Le(o, e);
1456
+ }
1457
+ function Le(n, t) {
1458
+ const e = n.split(/\r?\n/);
1459
+ let o = 0, r = !t.hasHeaderCount;
1460
+ for (const z of e){
1461
+ const F = z.trim();
1462
+ if (F.length !== 0 && !(F.startsWith("#") || F.startsWith("//"))) {
1463
+ if (!r) {
1464
+ r = !0;
1465
+ continue;
1466
+ }
1467
+ o++;
1468
+ }
1469
+ }
1470
+ const i = t.fields.indexOf("x"), c = t.fields.indexOf("y"), l = t.fields.indexOf("z"), s = t.fields.indexOf("i"), a = t.fields.indexOf("r"), u = t.fields.indexOf("g"), w = t.fields.indexOf("b"), m = s >= 0, d = a >= 0 && u >= 0 && w >= 0, f = new Float32Array(o * 3), p = m ? new Float32Array(o) : null, h = d ? new Float32Array(o * 3) : null;
1471
+ let b = 0, g = 0, y = 0, C = 1 / 0, x = 1 / 0, I = 1 / 0, E = -1 / 0, A = -1 / 0, S = -1 / 0;
1472
+ r = !t.hasHeaderCount;
1473
+ for (const z of e){
1474
+ const F = z.trim();
1475
+ if (F.length === 0 || F.startsWith("#") || F.startsWith("//")) continue;
1476
+ if (!r) {
1477
+ r = !0;
1478
+ continue;
1479
+ }
1480
+ const P = F.split(/\s+/);
1481
+ if (P.length < t.columns) continue;
1482
+ const O = Number(P[i]), L = Number(P[c]), M = Number(P[l]);
1483
+ if (!(!Number.isFinite(O) || !Number.isFinite(L) || !Number.isFinite(M))) {
1484
+ if (f[b * 3] = O, f[b * 3 + 1] = L, f[b * 3 + 2] = M, O < C && (C = O), O > E && (E = O), L < x && (x = L), L > A && (A = L), M < I && (I = M), M > S && (S = M), p) {
1485
+ const W = Number(P[s]), v = Number.isFinite(W) ? W : 0;
1486
+ p[b] = v, v > g && (g = v);
1487
+ }
1488
+ if (h) {
1489
+ const W = Number(P[a]), v = Number(P[u]), ut = Number(P[w]), dt = Number.isFinite(W) ? W : 0, ht = Number.isFinite(v) ? v : 0, mt = Number.isFinite(ut) ? ut : 0;
1490
+ h[b * 3] = dt, h[b * 3 + 1] = ht, h[b * 3 + 2] = mt;
1491
+ const pt = Math.max(dt, ht, mt);
1492
+ pt > y && (y = pt);
1493
+ }
1494
+ b++;
1495
+ }
1496
+ }
1497
+ const R = b === o ? f : f.subarray(0, b * 3);
1498
+ let B;
1499
+ if (p) {
1500
+ B = new Uint16Array(b);
1501
+ const z = g > 1 ? g > 255 ? 65535 / g : 65535 / 255 : 65535;
1502
+ for(let F = 0; F < b; F++){
1503
+ const P = p[F] * z;
1504
+ B[F] = P < 0 ? 0 : P > 65535 ? 65535 : Math.round(P);
1505
+ }
1506
+ }
1507
+ let _;
1508
+ if (h) {
1509
+ _ = new Float32Array(b * 3);
1510
+ const z = y > 1 ? 1 / 255 : 1;
1511
+ for(let F = 0; F < b * 3; F++){
1512
+ const P = h[F] * z;
1513
+ _[F] = P < 0 ? 0 : P > 1 ? 1 : P;
1514
+ }
1515
+ }
1516
+ const H = b === 0 ? {
1517
+ min: [
1518
+ 0,
1519
+ 0,
1520
+ 0
1521
+ ],
1522
+ max: [
1523
+ 0,
1524
+ 0,
1525
+ 0
1526
+ ]
1527
+ } : {
1528
+ min: [
1529
+ C,
1530
+ x,
1531
+ I
1532
+ ],
1533
+ max: [
1534
+ E,
1535
+ A,
1536
+ S
1537
+ ]
1538
+ };
1539
+ return {
1540
+ positions: b === o ? f : new Float32Array(R),
1541
+ colors: _,
1542
+ intensities: B,
1543
+ pointCount: b,
1544
+ bbox: H
1545
+ };
1546
+ }
1547
+ class xt {
1548
+ blob;
1549
+ format;
1550
+ downsample;
1551
+ label;
1552
+ chunk = null;
1553
+ served = !1;
1554
+ constructor(t, e, o = {}){
1555
+ this.blob = t, this.format = e, this.downsample = o.downsample ?? {
1556
+ stride: 1
1557
+ }, this.label = o.label;
1558
+ }
1559
+ async open(t) {
1560
+ it(t);
1561
+ const e = await this.blob.arrayBuffer();
1562
+ it(t);
1563
+ const o = new Uint8Array(e), r = Me(o, this.format);
1564
+ return this.chunk = Se(r, this.downsample.stride), {
1565
+ totalPointCount: this.chunk.pointCount,
1566
+ bbox: this.chunk.bbox,
1567
+ hasColor: !!this.chunk.colors,
1568
+ hasClassification: !1,
1569
+ hasIntensity: !!this.chunk.intensities,
1570
+ label: this.label
1571
+ };
1572
+ }
1573
+ async next(t, e) {
1574
+ return it(e), !this.chunk || this.served ? null : (this.served = !0, this.chunk);
1575
+ }
1576
+ close() {
1577
+ this.chunk = null, this.served = !1;
1578
+ }
1579
+ }
1580
+ function Se(n, t) {
1581
+ const e = Math.max(1, t | 0);
1582
+ if (e === 1) return n;
1583
+ const o = Math.ceil(n.pointCount / e), r = new Float32Array(o * 3), i = n.colors ? new Float32Array(o * 3) : void 0, c = n.intensities ? new Uint16Array(o) : void 0;
1584
+ let l = 0;
1585
+ for(let s = 0; s < n.pointCount; s += e)r[l * 3] = n.positions[s * 3], r[l * 3 + 1] = n.positions[s * 3 + 1], r[l * 3 + 2] = n.positions[s * 3 + 2], i && n.colors && (i[l * 3] = n.colors[s * 3], i[l * 3 + 1] = n.colors[s * 3 + 1], i[l * 3 + 2] = n.colors[s * 3 + 2]), c && n.intensities && (c[l] = n.intensities[s]), l++;
1586
+ return {
1587
+ positions: r,
1588
+ colors: i,
1589
+ intensities: c,
1590
+ pointCount: o,
1591
+ bbox: n.bbox
1592
+ };
1593
+ }
1594
+ function it(n) {
1595
+ if (n?.aborted) throw new DOMException("Aborted", "AbortError");
1596
+ }
1597
+ const V = new Map;
1598
+ let ze = 1;
1599
+ self.onmessage = (n)=>{
1600
+ const t = n.data;
1601
+ switch(t.kind){
1602
+ case "open":
1603
+ Ue(t);
1604
+ return;
1605
+ case "next":
1606
+ Oe(t);
1607
+ return;
1608
+ case "close":
1609
+ De(t.sourceId);
1610
+ return;
1611
+ case "abort":
1612
+ $e(t.sourceId);
1613
+ return;
1614
+ }
1615
+ };
1616
+ async function Ue(n) {
1617
+ try {
1618
+ const t = Ne(n.format, n.blob, {
1619
+ label: n.label,
1620
+ downsample: {
1621
+ stride: Math.max(1, n.stride | 0)
1622
+ }
1623
+ }), e = new AbortController, o = await t.open(e.signal), r = ze++;
1624
+ V.set(r, {
1625
+ source: t,
1626
+ abort: e
1627
+ }), Y({
1628
+ kind: "opened",
1629
+ requestId: n.requestId,
1630
+ sourceId: r,
1631
+ info: o
1632
+ });
1633
+ } catch (t) {
1634
+ Y({
1635
+ kind: "error",
1636
+ requestId: n.requestId,
1637
+ message: ft(t)
1638
+ });
1639
+ }
1640
+ }
1641
+ async function Oe(n) {
1642
+ const t = V.get(n.sourceId);
1643
+ if (!t) {
1644
+ Y({
1645
+ kind: "error",
1646
+ requestId: n.requestId,
1647
+ message: `Unknown sourceId ${n.sourceId}`
1648
+ });
1649
+ return;
1650
+ }
1651
+ try {
1652
+ const e = await t.source.next(n.maxPoints, t.abort.signal);
1653
+ if (!e) {
1654
+ Y({
1655
+ kind: "chunk",
1656
+ requestId: n.requestId,
1657
+ sourceId: n.sourceId,
1658
+ chunk: null
1659
+ });
1660
+ return;
1661
+ }
1662
+ const { payload: o, transfer: r } = zt(e);
1663
+ Y({
1664
+ kind: "chunk",
1665
+ requestId: n.requestId,
1666
+ sourceId: n.sourceId,
1667
+ chunk: o
1668
+ }, r);
1669
+ } catch (e) {
1670
+ Y({
1671
+ kind: "error",
1672
+ requestId: n.requestId,
1673
+ message: ft(e)
1674
+ });
1675
+ }
1676
+ }
1677
+ function De(n) {
1678
+ const t = V.get(n);
1679
+ if (t) {
1680
+ try {
1681
+ t.abort.abort(), t.source.close();
1682
+ } catch (e) {
1683
+ console.warn("[decode-worker] close failed:", ft(e));
1684
+ }
1685
+ V.delete(n);
1686
+ }
1687
+ }
1688
+ function $e(n) {
1689
+ const t = V.get(n);
1690
+ t && t.abort.abort();
1691
+ }
1692
+ function Ne(n, t, e) {
1693
+ if (n === "las") return new _t(t, e);
1694
+ if (n === "laz") return new kt(t, e);
1695
+ if (n === "ply") return new qt(t, e);
1696
+ if (n === "pcd") return new se(t, e);
1697
+ if (n === "e57") return new Fe(t, e);
1698
+ if (n === "pts") return new xt(t, "pts", e);
1699
+ if (n === "xyz") return new xt(t, "xyz", e);
1700
+ throw new Error(`decode-worker: unknown format "${n}"`);
1701
+ }
1702
+ function Y(n, t = []) {
1703
+ self.postMessage(n, t);
1704
+ }
1705
+ function ft(n) {
1706
+ return n instanceof Error ? n.message : String(n);
1707
+ }
1708
+ })();