@ifc-lite/pointcloud 0.2.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 (87) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +26 -0
  3. package/dist/formats/e57.d.ts +129 -0
  4. package/dist/formats/e57.d.ts.map +1 -0
  5. package/dist/formats/e57.js +495 -0
  6. package/dist/formats/e57.js.map +1 -0
  7. package/dist/formats/ifcx-points.d.ts +26 -0
  8. package/dist/formats/ifcx-points.d.ts.map +1 -0
  9. package/dist/formats/ifcx-points.js +134 -0
  10. package/dist/formats/ifcx-points.js.map +1 -0
  11. package/dist/formats/las.d.ts +54 -0
  12. package/dist/formats/las.d.ts.map +1 -0
  13. package/dist/formats/las.js +203 -0
  14. package/dist/formats/las.js.map +1 -0
  15. package/dist/formats/pcd.d.ts +3 -0
  16. package/dist/formats/pcd.d.ts.map +1 -0
  17. package/dist/formats/pcd.js +302 -0
  18. package/dist/formats/pcd.js.map +1 -0
  19. package/dist/formats/ply.d.ts +40 -0
  20. package/dist/formats/ply.d.ts.map +1 -0
  21. package/dist/formats/ply.js +250 -0
  22. package/dist/formats/ply.js.map +1 -0
  23. package/dist/from-ifcx-attributes.d.ts +10 -0
  24. package/dist/from-ifcx-attributes.d.ts.map +1 -0
  25. package/dist/from-ifcx-attributes.js +49 -0
  26. package/dist/from-ifcx-attributes.js.map +1 -0
  27. package/dist/index.d.ts +26 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +21 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/lzf.d.ts +10 -0
  32. package/dist/lzf.d.ts.map +1 -0
  33. package/dist/lzf.js +64 -0
  34. package/dist/lzf.js.map +1 -0
  35. package/dist/streaming/blob-source.d.ts +15 -0
  36. package/dist/streaming/blob-source.d.ts.map +1 -0
  37. package/dist/streaming/blob-source.js +30 -0
  38. package/dist/streaming/blob-source.js.map +1 -0
  39. package/dist/streaming/decode-worker.d.ts +2 -0
  40. package/dist/streaming/decode-worker.d.ts.map +1 -0
  41. package/dist/streaming/decode-worker.js +131 -0
  42. package/dist/streaming/decode-worker.js.map +1 -0
  43. package/dist/streaming/e57-source.d.ts +17 -0
  44. package/dist/streaming/e57-source.d.ts.map +1 -0
  45. package/dist/streaming/e57-source.js +83 -0
  46. package/dist/streaming/e57-source.js.map +1 -0
  47. package/dist/streaming/host.d.ts +54 -0
  48. package/dist/streaming/host.d.ts.map +1 -0
  49. package/dist/streaming/host.js +120 -0
  50. package/dist/streaming/host.js.map +1 -0
  51. package/dist/streaming/las-source.d.ts +28 -0
  52. package/dist/streaming/las-source.d.ts.map +1 -0
  53. package/dist/streaming/las-source.js +117 -0
  54. package/dist/streaming/las-source.js.map +1 -0
  55. package/dist/streaming/laz-source.d.ts +35 -0
  56. package/dist/streaming/laz-source.d.ts.map +1 -0
  57. package/dist/streaming/laz-source.js +205 -0
  58. package/dist/streaming/laz-source.js.map +1 -0
  59. package/dist/streaming/pcd-source.d.ts +25 -0
  60. package/dist/streaming/pcd-source.d.ts.map +1 -0
  61. package/dist/streaming/pcd-source.js +86 -0
  62. package/dist/streaming/pcd-source.js.map +1 -0
  63. package/dist/streaming/ply-source.d.ts +26 -0
  64. package/dist/streaming/ply-source.d.ts.map +1 -0
  65. package/dist/streaming/ply-source.js +98 -0
  66. package/dist/streaming/ply-source.js.map +1 -0
  67. package/dist/streaming/protocol.d.ts +62 -0
  68. package/dist/streaming/protocol.d.ts.map +1 -0
  69. package/dist/streaming/protocol.js +45 -0
  70. package/dist/streaming/protocol.js.map +1 -0
  71. package/dist/streaming/types.d.ts +41 -0
  72. package/dist/streaming/types.d.ts.map +1 -0
  73. package/dist/streaming/types.js +5 -0
  74. package/dist/streaming/types.js.map +1 -0
  75. package/dist/streaming/worker-client.d.ts +20 -0
  76. package/dist/streaming/worker-client.d.ts.map +1 -0
  77. package/dist/streaming/worker-client.js +152 -0
  78. package/dist/streaming/worker-client.js.map +1 -0
  79. package/dist/types.d.ts +36 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +5 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/xml-mini.d.ts +29 -0
  84. package/dist/xml-mini.d.ts.map +1 -0
  85. package/dist/xml-mini.js +181 -0
  86. package/dist/xml-mini.js.map +1 -0
  87. package/package.json +51 -0
@@ -0,0 +1,10 @@
1
+ import type { DecodedPointChunk } from './types.js';
2
+ export declare const POINTCLOUD_ATTR: {
3
+ readonly PCD_BASE64: "pcd::base64";
4
+ readonly POINTS_ARRAY: "points::array";
5
+ readonly POINTS_BASE64: "points::base64";
6
+ };
7
+ /** Set of attribute keys that signal a point cloud node. */
8
+ export declare const POINTCLOUD_ATTR_KEYS: ReadonlySet<string>;
9
+ export declare function decodeIfcxPointAttribute(attributes: ReadonlyMap<string, unknown>): DecodedPointChunk | null;
10
+ //# sourceMappingURL=from-ifcx-attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-ifcx-attributes.d.ts","sourceRoot":"","sources":["../src/from-ifcx-attributes.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAA2C,CAAC;AAEjG,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GACvC,iBAAiB,GAAG,IAAI,CAc1B"}
@@ -0,0 +1,49 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Adapter: given a node's attribute map (already composed by IFCx), pick
6
+ * the appropriate decoder for the three buildingSMART point cloud schemas
7
+ * and produce a DecodedPointChunk.
8
+ *
9
+ * Returns null if the node carries none of the supported attributes.
10
+ */
11
+ import { decodePcd } from './formats/pcd.js';
12
+ import { decodePointsArray, decodePointsBase64, } from './formats/ifcx-points.js';
13
+ export const POINTCLOUD_ATTR = {
14
+ PCD_BASE64: 'pcd::base64',
15
+ POINTS_ARRAY: 'points::array',
16
+ POINTS_BASE64: 'points::base64',
17
+ };
18
+ /** Set of attribute keys that signal a point cloud node. */
19
+ export const POINTCLOUD_ATTR_KEYS = new Set(Object.values(POINTCLOUD_ATTR));
20
+ export function decodeIfcxPointAttribute(attributes) {
21
+ const pcd = attributes.get(POINTCLOUD_ATTR.PCD_BASE64);
22
+ if (typeof pcd === 'string' && pcd.length > 0) {
23
+ return decodePcd(base64ToBytes(pcd));
24
+ }
25
+ const arr = attributes.get(POINTCLOUD_ATTR.POINTS_ARRAY);
26
+ if (arr && typeof arr === 'object') {
27
+ return decodePointsArray(arr);
28
+ }
29
+ const b64 = attributes.get(POINTCLOUD_ATTR.POINTS_BASE64);
30
+ if (b64 && typeof b64 === 'object') {
31
+ return decodePointsBase64(b64);
32
+ }
33
+ return null;
34
+ }
35
+ function base64ToBytes(b64) {
36
+ if (typeof atob === 'function') {
37
+ const binary = atob(b64);
38
+ const out = new Uint8Array(binary.length);
39
+ for (let i = 0; i < binary.length; i++)
40
+ out[i] = binary.charCodeAt(i);
41
+ return out;
42
+ }
43
+ const buf = globalThis.Buffer;
44
+ if (buf && typeof buf.from === 'function') {
45
+ return new Uint8Array(buf.from(b64, 'base64'));
46
+ }
47
+ throw new Error('No base64 decoder available in this environment');
48
+ }
49
+ //# sourceMappingURL=from-ifcx-attributes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-ifcx-attributes.js","sourceRoot":"","sources":["../src/from-ifcx-attributes.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAGnB,MAAM,0BAA0B,CAAC;AAGlC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EAAE,aAAa;IACzB,YAAY,EAAE,eAAe;IAC7B,aAAa,EAAE,gBAAgB;CACvB,CAAC;AAEX,4DAA4D;AAC5D,MAAM,CAAC,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;AAEjG,MAAM,UAAU,wBAAwB,CACtC,UAAwC;IAExC,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACzD,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,iBAAiB,CAAC,GAA2B,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IAC1D,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,kBAAkB,CAAC,GAA4B,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,GAAG,GAAI,UAAqF,CAAC,MAAM,CAAC;IAC1G,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC1C,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @ifc-lite/pointcloud — point cloud decoders, streaming sources, and
3
+ * a worker-backed host for off-main-thread decoding.
4
+ *
5
+ * Phase 0: IFCx schemas (`pcd::base64`, `points::array`, `points::base64`).
6
+ * Phase 1: streaming `.las` from local Files / fetched Blobs.
7
+ * Phase 2: streaming `.laz` (laz-perf in the worker).
8
+ */
9
+ export type { DecodedPointChunk, PointCloudBBox } from './types.js';
10
+ export { decodePcd } from './formats/pcd.js';
11
+ export { decodePointsArray, decodePointsBase64, type PointsArrayAttribute, type PointsBase64Attribute, } from './formats/ifcx-points.js';
12
+ export { decompressLZF } from './lzf.js';
13
+ export { POINTCLOUD_ATTR, POINTCLOUD_ATTR_KEYS, decodeIfcxPointAttribute, } from './from-ifcx-attributes.js';
14
+ export { parseLasHeader, decodeLasPoints, sampleMaxRgbChannel, type LasHeader, } from './formats/las.js';
15
+ export type { StreamingPointSource, PointSourceInfo, DownsampleHint, } from './streaming/types.js';
16
+ export { LasStreamingSource } from './streaming/las-source.js';
17
+ export { LazStreamingSource } from './streaming/laz-source.js';
18
+ export { PlyStreamingSource } from './streaming/ply-source.js';
19
+ export { PcdStreamingSource } from './streaming/pcd-source.js';
20
+ export { E57StreamingSource } from './streaming/e57-source.js';
21
+ export { parsePlyHeader } from './formats/ply.js';
22
+ export { parseE57FileHeader, parseE57Xml, stripPageCrc as stripE57PageCrc, decodeE57, decodeE57Scan, type E57FileHeader, type Data3DEntry, } from './formats/e57.js';
23
+ export { BlobByteSource } from './streaming/blob-source.js';
24
+ export { createDecodeWorkerSource, type CreateDecodeWorkerSourceOptions, type DecodeWorkerOptions, type DecodeWorkerFormat, } from './streaming/worker-client.js';
25
+ export { streamPointCloud, type StreamPointCloudOptions, type StreamHandle, } from './streaming/host.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,KAAK,SAAS,GACf,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,YAAY,IAAI,eAAe,EAC/B,SAAS,EACT,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,EACpC,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ // Inline / IFCx decoders (Phase 0)
5
+ export { decodePcd } from './formats/pcd.js';
6
+ export { decodePointsArray, decodePointsBase64, } from './formats/ifcx-points.js';
7
+ export { decompressLZF } from './lzf.js';
8
+ export { POINTCLOUD_ATTR, POINTCLOUD_ATTR_KEYS, decodeIfcxPointAttribute, } from './from-ifcx-attributes.js';
9
+ // LAS reader primitives
10
+ export { parseLasHeader, decodeLasPoints, sampleMaxRgbChannel, } from './formats/las.js';
11
+ export { LasStreamingSource } from './streaming/las-source.js';
12
+ export { LazStreamingSource } from './streaming/laz-source.js';
13
+ export { PlyStreamingSource } from './streaming/ply-source.js';
14
+ export { PcdStreamingSource } from './streaming/pcd-source.js';
15
+ export { E57StreamingSource } from './streaming/e57-source.js';
16
+ export { parsePlyHeader } from './formats/ply.js';
17
+ export { parseE57FileHeader, parseE57Xml, stripPageCrc as stripE57PageCrc, decodeE57, decodeE57Scan, } from './formats/e57.js';
18
+ export { BlobByteSource } from './streaming/blob-source.js';
19
+ export { createDecodeWorkerSource, } from './streaming/worker-client.js';
20
+ export { streamPointCloud, } from './streaming/host.js';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAa/D,mCAAmC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAGnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,wBAAwB;AACxB,OAAO,EACL,cAAc,EACd,eAAe,EACf,mBAAmB,GAEpB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,YAAY,IAAI,eAAe,EAC/B,SAAS,EACT,aAAa,GAGd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACL,wBAAwB,GAIzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,gBAAgB,GAGjB,MAAM,qBAAqB,CAAC"}
package/dist/lzf.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * LZF decompressor — Marc Lehmann's algorithm.
3
+ *
4
+ * Used by PCL's PCD `binary_compressed` data section. Pure decompression:
5
+ * we never need to encode. Algorithm reference: liblzf 3.x lzf_d.c.
6
+ *
7
+ * Throws if the bitstream over-runs the input or the declared output length.
8
+ */
9
+ export declare function decompressLZF(input: Uint8Array, outputSize: number): Uint8Array;
10
+ //# sourceMappingURL=lzf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lzf.d.ts","sourceRoot":"","sources":["../src/lzf.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAqD/E"}
package/dist/lzf.js ADDED
@@ -0,0 +1,64 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * LZF decompressor — Marc Lehmann's algorithm.
6
+ *
7
+ * Used by PCL's PCD `binary_compressed` data section. Pure decompression:
8
+ * we never need to encode. Algorithm reference: liblzf 3.x lzf_d.c.
9
+ *
10
+ * Throws if the bitstream over-runs the input or the declared output length.
11
+ */
12
+ export function decompressLZF(input, outputSize) {
13
+ const output = new Uint8Array(outputSize);
14
+ let ip = 0; // input cursor
15
+ let op = 0; // output cursor
16
+ const ie = input.length;
17
+ while (ip < ie) {
18
+ let ctrl = input[ip++];
19
+ if (ctrl < 0x20) {
20
+ // Literal run: copy ctrl+1 bytes verbatim
21
+ const run = ctrl + 1;
22
+ if (ip + run > ie) {
23
+ throw new Error('LZF: literal run exceeds input bounds');
24
+ }
25
+ if (op + run > outputSize) {
26
+ throw new Error('LZF: literal run exceeds output bounds');
27
+ }
28
+ output.set(input.subarray(ip, ip + run), op);
29
+ ip += run;
30
+ op += run;
31
+ }
32
+ else {
33
+ // Back reference
34
+ let len = ctrl >> 5;
35
+ if (len === 7) {
36
+ if (ip >= ie)
37
+ throw new Error('LZF: truncated extended length');
38
+ len += input[ip++];
39
+ }
40
+ len += 2;
41
+ if (ip >= ie)
42
+ throw new Error('LZF: truncated back-reference offset');
43
+ const ref = op - ((ctrl & 0x1f) << 8) - input[ip++] - 1;
44
+ if (ref < 0) {
45
+ throw new Error('LZF: back-reference points before output start');
46
+ }
47
+ if (op + len > outputSize) {
48
+ throw new Error('LZF: back-reference exceeds output bounds');
49
+ }
50
+ // The reference can overlap the current write position — the original
51
+ // C code uses byte-by-byte copy for that exact reason (run-length
52
+ // expansion). Mirror that.
53
+ for (let i = 0; i < len; i++) {
54
+ output[op + i] = output[ref + i];
55
+ }
56
+ op += len;
57
+ }
58
+ }
59
+ if (op !== outputSize) {
60
+ throw new Error(`LZF: decompressed ${op} bytes, expected ${outputSize}`);
61
+ }
62
+ return output;
63
+ }
64
+ //# sourceMappingURL=lzf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lzf.js","sourceRoot":"","sources":["../src/lzf.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,UAAkB;IACjE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,EAAE,GAAG,CAAC,CAAC,CAAa,eAAe;IACvC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAa,gBAAgB;IACxC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;IAExB,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;QACf,IAAI,IAAI,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAEvB,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;YAChB,0CAA0C;YAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;YACrB,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;YACD,IAAI,EAAE,GAAG,GAAG,GAAG,UAAU,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,EAAE,IAAI,GAAG,CAAC;YACV,EAAE,IAAI,GAAG,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,iBAAiB;YACjB,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC;YACpB,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;gBACd,IAAI,EAAE,IAAI,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBAChE,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACrB,CAAC;YACD,GAAG,IAAI,CAAC,CAAC;YAET,IAAI,EAAE,IAAI,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACtE,MAAM,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACxD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;YACpE,CAAC;YACD,IAAI,EAAE,GAAG,GAAG,GAAG,UAAU,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC/D,CAAC;YAED,sEAAsE;YACtE,kEAAkE;YAClE,2BAA2B;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YACnC,CAAC;YACD,EAAE,IAAI,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,qBAAqB,EAAE,oBAAoB,UAAU,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Byte-range reader backed by a Blob.
3
+ *
4
+ * Works for both browser `File` objects (drag-and-drop) and `fetch()`
5
+ * responses materialised via `await response.blob()`. Reads return
6
+ * `Uint8Array` — the underlying ArrayBuffer is owned by the caller and
7
+ * safe to transfer across postMessage boundaries.
8
+ */
9
+ export declare class BlobByteSource {
10
+ private readonly blob;
11
+ constructor(blob: Blob);
12
+ get size(): number;
13
+ read(start: number, end: number): Promise<Uint8Array>;
14
+ }
15
+ //# sourceMappingURL=blob-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob-source.d.ts","sourceRoot":"","sources":["../../src/streaming/blob-source.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEvC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEK,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAQ5D"}
@@ -0,0 +1,30 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Byte-range reader backed by a Blob.
6
+ *
7
+ * Works for both browser `File` objects (drag-and-drop) and `fetch()`
8
+ * responses materialised via `await response.blob()`. Reads return
9
+ * `Uint8Array` — the underlying ArrayBuffer is owned by the caller and
10
+ * safe to transfer across postMessage boundaries.
11
+ */
12
+ export class BlobByteSource {
13
+ blob;
14
+ constructor(blob) {
15
+ this.blob = blob;
16
+ }
17
+ get size() {
18
+ return this.blob.size;
19
+ }
20
+ async read(start, end) {
21
+ const safeStart = Math.max(0, start);
22
+ const safeEnd = Math.min(end, this.blob.size);
23
+ if (safeEnd <= safeStart)
24
+ return new Uint8Array(0);
25
+ const slice = this.blob.slice(safeStart, safeEnd);
26
+ const buf = await slice.arrayBuffer();
27
+ return new Uint8Array(buf);
28
+ }
29
+ }
30
+ //# sourceMappingURL=blob-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob-source.js","sourceRoot":"","sources":["../../src/streaming/blob-source.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;IAAG,CAAC;IAE3C,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,GAAW;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,OAAO,IAAI,SAAS;YAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;QACtC,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=decode-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode-worker.d.ts","sourceRoot":"","sources":["../../src/streaming/decode-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,131 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { chunkToWire, } from './protocol.js';
5
+ import { LasStreamingSource } from './las-source.js';
6
+ import { LazStreamingSource } from './laz-source.js';
7
+ import { PlyStreamingSource } from './ply-source.js';
8
+ import { PcdStreamingSource } from './pcd-source.js';
9
+ import { E57StreamingSource } from './e57-source.js';
10
+ const sources = new Map();
11
+ let nextSourceId = 1;
12
+ self.onmessage = (event) => {
13
+ const msg = event.data;
14
+ switch (msg.kind) {
15
+ case 'open':
16
+ void handleOpen(msg);
17
+ return;
18
+ case 'next':
19
+ void handleNext(msg);
20
+ return;
21
+ case 'close':
22
+ handleClose(msg.sourceId);
23
+ return;
24
+ case 'abort':
25
+ handleAbort(msg.sourceId);
26
+ return;
27
+ }
28
+ };
29
+ async function handleOpen(msg) {
30
+ try {
31
+ const source = createSource(msg.format, msg.blob, {
32
+ label: msg.label,
33
+ downsample: { stride: Math.max(1, msg.stride | 0) },
34
+ });
35
+ const abort = new AbortController();
36
+ const info = await source.open(abort.signal);
37
+ const sourceId = nextSourceId++;
38
+ sources.set(sourceId, { source, abort });
39
+ post({
40
+ kind: 'opened',
41
+ requestId: msg.requestId,
42
+ sourceId,
43
+ info,
44
+ });
45
+ }
46
+ catch (err) {
47
+ post({
48
+ kind: 'error',
49
+ requestId: msg.requestId,
50
+ message: errMessage(err),
51
+ });
52
+ }
53
+ }
54
+ async function handleNext(msg) {
55
+ const open = sources.get(msg.sourceId);
56
+ if (!open) {
57
+ post({
58
+ kind: 'error',
59
+ requestId: msg.requestId,
60
+ message: `Unknown sourceId ${msg.sourceId}`,
61
+ });
62
+ return;
63
+ }
64
+ try {
65
+ const chunk = await open.source.next(msg.maxPoints, open.abort.signal);
66
+ if (!chunk) {
67
+ post({
68
+ kind: 'chunk',
69
+ requestId: msg.requestId,
70
+ sourceId: msg.sourceId,
71
+ chunk: null,
72
+ });
73
+ return;
74
+ }
75
+ const { payload, transfer } = chunkToWire(chunk);
76
+ post({
77
+ kind: 'chunk',
78
+ requestId: msg.requestId,
79
+ sourceId: msg.sourceId,
80
+ chunk: payload,
81
+ }, transfer);
82
+ }
83
+ catch (err) {
84
+ post({
85
+ kind: 'error',
86
+ requestId: msg.requestId,
87
+ message: errMessage(err),
88
+ });
89
+ }
90
+ }
91
+ function handleClose(sourceId) {
92
+ const open = sources.get(sourceId);
93
+ if (!open)
94
+ return;
95
+ try {
96
+ open.abort.abort();
97
+ open.source.close();
98
+ }
99
+ catch (err) {
100
+ console.warn('[decode-worker] close failed:', errMessage(err));
101
+ }
102
+ sources.delete(sourceId);
103
+ }
104
+ function handleAbort(sourceId) {
105
+ const open = sources.get(sourceId);
106
+ if (!open)
107
+ return;
108
+ open.abort.abort();
109
+ }
110
+ function createSource(format, blob, opts) {
111
+ if (format === 'las')
112
+ return new LasStreamingSource(blob, opts);
113
+ if (format === 'laz')
114
+ return new LazStreamingSource(blob, opts);
115
+ if (format === 'ply')
116
+ return new PlyStreamingSource(blob, opts);
117
+ if (format === 'pcd')
118
+ return new PcdStreamingSource(blob, opts);
119
+ if (format === 'e57')
120
+ return new E57StreamingSource(blob, opts);
121
+ throw new Error(`decode-worker: unknown format "${format}"`);
122
+ }
123
+ function post(msg, transfer = []) {
124
+ self.postMessage(msg, transfer);
125
+ }
126
+ function errMessage(err) {
127
+ if (err instanceof Error)
128
+ return err.message;
129
+ return String(err);
130
+ }
131
+ //# sourceMappingURL=decode-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode-worker.js","sourceRoot":"","sources":["../../src/streaming/decode-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { DecodedPointChunk } from '../types.js';
2
+ import type { DownsampleHint, PointSourceInfo, StreamingPointSource } from './types.js';
3
+ export declare class E57StreamingSource implements StreamingPointSource {
4
+ private blob;
5
+ private downsample;
6
+ private label?;
7
+ private chunk;
8
+ private served;
9
+ constructor(blob: Blob, options?: {
10
+ label?: string;
11
+ downsample?: DownsampleHint;
12
+ });
13
+ open(signal?: AbortSignal): Promise<PointSourceInfo>;
14
+ next(maxPoints: number, signal?: AbortSignal): Promise<DecodedPointChunk | null>;
15
+ close(): void;
16
+ }
17
+ //# sourceMappingURL=e57-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e57-source.d.ts","sourceRoot":"","sources":["../../src/streaming/e57-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,cAAc,CAAA;KAAO;IAM/E,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAmBpD,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAQtF,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,83 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { decodeE57 } from '../formats/e57.js';
5
+ export class E57StreamingSource {
6
+ blob;
7
+ downsample;
8
+ label;
9
+ chunk = null;
10
+ served = false;
11
+ constructor(blob, options = {}) {
12
+ this.blob = blob;
13
+ this.downsample = options.downsample ?? { stride: 1 };
14
+ this.label = options.label;
15
+ }
16
+ async open(signal) {
17
+ abortIfAborted(signal);
18
+ const buf = await this.blob.arrayBuffer();
19
+ abortIfAborted(signal);
20
+ const decoded = decodeE57(new Uint8Array(buf));
21
+ if (!decoded) {
22
+ throw new Error('E57: file contains no Data3D scans');
23
+ }
24
+ this.chunk = applyStride(decoded, this.downsample.stride);
25
+ return {
26
+ totalPointCount: this.chunk.pointCount,
27
+ bbox: this.chunk.bbox,
28
+ hasColor: !!this.chunk.colors,
29
+ hasClassification: false,
30
+ hasIntensity: !!this.chunk.intensities,
31
+ label: this.label,
32
+ };
33
+ }
34
+ async next(maxPoints, signal) {
35
+ abortIfAborted(signal);
36
+ if (!this.chunk || this.served)
37
+ return null;
38
+ void maxPoints;
39
+ this.served = true;
40
+ return this.chunk;
41
+ }
42
+ close() {
43
+ this.chunk = null;
44
+ this.served = false;
45
+ }
46
+ }
47
+ function applyStride(chunk, stride) {
48
+ const s = Math.max(1, stride | 0);
49
+ if (s === 1)
50
+ return chunk;
51
+ const newCount = Math.ceil(chunk.pointCount / s);
52
+ const positions = new Float32Array(newCount * 3);
53
+ const colors = chunk.colors ? new Float32Array(newCount * 3) : undefined;
54
+ const intensities = chunk.intensities ? new Uint16Array(newCount) : undefined;
55
+ let dst = 0;
56
+ for (let i = 0; i < chunk.pointCount; i += s) {
57
+ positions[dst * 3] = chunk.positions[i * 3];
58
+ positions[dst * 3 + 1] = chunk.positions[i * 3 + 1];
59
+ positions[dst * 3 + 2] = chunk.positions[i * 3 + 2];
60
+ if (colors && chunk.colors) {
61
+ colors[dst * 3] = chunk.colors[i * 3];
62
+ colors[dst * 3 + 1] = chunk.colors[i * 3 + 1];
63
+ colors[dst * 3 + 2] = chunk.colors[i * 3 + 2];
64
+ }
65
+ if (intensities && chunk.intensities) {
66
+ intensities[dst] = chunk.intensities[i];
67
+ }
68
+ dst++;
69
+ }
70
+ return {
71
+ positions,
72
+ colors,
73
+ intensities,
74
+ pointCount: newCount,
75
+ bbox: chunk.bbox,
76
+ };
77
+ }
78
+ function abortIfAborted(signal) {
79
+ if (signal?.aborted) {
80
+ throw new DOMException('Aborted', 'AbortError');
81
+ }
82
+ }
83
+ //# sourceMappingURL=e57-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e57-source.js","sourceRoot":"","sources":["../../src/streaming/e57-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Host-side helper that drives a `StreamingPointSource` to completion,
3
+ * applies a memory-cap downsampling policy, and emits decoded chunks
4
+ * to a callback.
5
+ *
6
+ * Renderers consume this directly: pass `onChunk` as your "upload to
7
+ * GPU" callback and the host takes care of pacing, abort, and the
8
+ * end-of-stream `onComplete` notification.
9
+ */
10
+ import type { DecodedPointChunk, PointCloudBBox } from '../types.js';
11
+ import { type CreateDecodeWorkerSourceOptions, type DecodeWorkerFormat } from './worker-client.js';
12
+ import type { PointSourceInfo, StreamingPointSource } from './types.js';
13
+ export interface StreamPointCloudOptions {
14
+ /** Source format. */
15
+ format: DecodeWorkerFormat;
16
+ /** File or remote-fetched blob. */
17
+ blob: Blob;
18
+ /** Optional label (filename, URL) for diagnostics. */
19
+ label?: string;
20
+ /**
21
+ * Soft memory cap measured in points. When the source declares more
22
+ * than this, the host applies stride-based downsampling so the chunks
23
+ * fit. Default: 25 million (~600 MB GPU at the 24-byte/point format).
24
+ */
25
+ maxPointsInMemory?: number;
26
+ /** Hard size ceiling — if `blob.size` exceeds, the call rejects. */
27
+ maxFileSize?: number;
28
+ /** Points per chunk during streaming decode. Default: 200_000. */
29
+ chunkSize?: number;
30
+ /** Called once after the source's header parses. */
31
+ onOpen?: (info: PointSourceInfo & {
32
+ stride: number;
33
+ }) => void;
34
+ /** Called for each decoded chunk. */
35
+ onChunk: (chunk: DecodedPointChunk) => void;
36
+ /** Periodic progress signal in 0..1. */
37
+ onProgress?: (loaded: number, total: number) => void;
38
+ /** Called once with the aggregated bbox once the stream finishes. */
39
+ onComplete?: (bbox: PointCloudBBox, totalEmitted: number) => void;
40
+ /** Called if the source errors mid-stream. */
41
+ onError?: (err: Error) => void;
42
+ /** Abort signal for the whole stream. */
43
+ signal?: AbortSignal;
44
+ /** Override the source factory (used by tests). */
45
+ createSource?: (opts: CreateDecodeWorkerSourceOptions) => StreamingPointSource;
46
+ }
47
+ export interface StreamHandle {
48
+ /** Cancel pending and future decode work. */
49
+ cancel(): void;
50
+ /** Resolves once the stream finishes successfully or is cancelled. */
51
+ done: Promise<void>;
52
+ }
53
+ export declare function streamPointCloud(opts: StreamPointCloudOptions): StreamHandle;
54
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/streaming/host.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAEL,KAAK,+BAA+B,EACpC,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACtC,qBAAqB;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,mCAAmC;IACnC,IAAI,EAAE,IAAI,CAAC;IACX,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,oDAAoD;IACpD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9D,qCAAqC;IACrC,OAAO,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5C,wCAAwC;IACxC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAE/B,yCAAyC;IACzC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,mDAAmD;IACnD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,+BAA+B,KAAK,oBAAoB,CAAC;CAChF;AAMD,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,MAAM,IAAI,IAAI,CAAC;IACf,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,YAAY,CA2F5E"}