@loaders.gl/las 4.4.0-alpha.1 → 4.4.0-alpha.10

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 (83) hide show
  1. package/dist/dist.dev.js +1022 -77
  2. package/dist/dist.min.js +21 -21
  3. package/dist/index.cjs +1024 -79
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +4 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +7 -1
  8. package/dist/index.js.map +1 -0
  9. package/dist/las-arrow-loader.d.ts +10 -8
  10. package/dist/las-arrow-loader.d.ts.map +1 -1
  11. package/dist/las-arrow-loader.js +5 -4
  12. package/dist/las-arrow-loader.js.map +1 -0
  13. package/dist/las-format.d.ts +2 -2
  14. package/dist/las-format.js +3 -2
  15. package/dist/las-format.js.map +1 -0
  16. package/dist/las-loader.d.ts +2 -31
  17. package/dist/las-loader.d.ts.map +1 -1
  18. package/dist/las-loader.js +2 -20
  19. package/dist/las-loader.js.map +1 -0
  20. package/dist/las-worker.js +65 -71
  21. package/dist/laz-rs-loader.d.ts +29 -0
  22. package/dist/laz-rs-loader.d.ts.map +1 -0
  23. package/dist/laz-rs-loader.js +17 -0
  24. package/dist/laz-rs-loader.js.map +1 -0
  25. package/dist/lazperf-loader.d.ts +31 -0
  26. package/dist/lazperf-loader.d.ts.map +1 -0
  27. package/dist/lazperf-loader.js +15 -0
  28. package/dist/lazperf-loader.js.map +1 -0
  29. package/dist/lib/get-las-schema.d.ts +1 -1
  30. package/dist/lib/get-las-schema.js +2 -1
  31. package/dist/lib/get-las-schema.js.map +1 -0
  32. package/dist/lib/las-types.d.ts +1 -0
  33. package/dist/lib/las-types.d.ts.map +1 -1
  34. package/dist/lib/las-types.js +1 -0
  35. package/dist/lib/las-types.js.map +1 -0
  36. package/dist/lib/{laslaz-decoder.d.ts → laz-perf/laslaz-decoder.d.ts} +1 -1
  37. package/dist/lib/laz-perf/laslaz-decoder.d.ts.map +1 -0
  38. package/dist/lib/{laslaz-decoder.js → laz-perf/laslaz-decoder.js} +4 -2
  39. package/dist/lib/laz-perf/laslaz-decoder.js.map +1 -0
  40. package/dist/lib/{parse-las.d.ts → laz-perf/parse-las.d.ts} +3 -3
  41. package/dist/lib/laz-perf/parse-las.d.ts.map +1 -0
  42. package/dist/lib/{parse-las.js → laz-perf/parse-las.js} +6 -6
  43. package/dist/lib/laz-perf/parse-las.js.map +1 -0
  44. package/dist/lib/laz-rs-wasm/laslaz-decoder.d.ts +134 -0
  45. package/dist/lib/laz-rs-wasm/laslaz-decoder.d.ts.map +1 -0
  46. package/dist/lib/laz-rs-wasm/laslaz-decoder.js +446 -0
  47. package/dist/lib/laz-rs-wasm/laslaz-decoder.js.map +1 -0
  48. package/dist/lib/laz-rs-wasm/parse-las.d.ts +18 -0
  49. package/dist/lib/laz-rs-wasm/parse-las.d.ts.map +1 -0
  50. package/dist/lib/laz-rs-wasm/parse-las.js +188 -0
  51. package/dist/lib/laz-rs-wasm/parse-las.js.map +1 -0
  52. package/dist/libs/laz-perf/laz-perf.d.ts.map +1 -0
  53. package/dist/{lib/libs → libs/laz-perf}/laz-perf.js +1 -0
  54. package/dist/libs/laz-perf/laz-perf.js.map +1 -0
  55. package/dist/libs/laz-rs-wasm/laz_rs_wasm.d.ts +95 -0
  56. package/dist/libs/laz-rs-wasm/laz_rs_wasm.d.ts.map +1 -0
  57. package/dist/libs/laz-rs-wasm/laz_rs_wasm.js +425 -0
  58. package/dist/libs/laz-rs-wasm/laz_rs_wasm.js.map +1 -0
  59. package/dist/workers/las-worker.js +1 -0
  60. package/dist/workers/las-worker.js.map +1 -0
  61. package/package.json +9 -6
  62. package/src/index.ts +8 -1
  63. package/src/las-arrow-loader.ts +6 -5
  64. package/src/las-format.ts +2 -2
  65. package/src/las-loader.ts +1 -23
  66. package/src/laz-rs-loader.ts +22 -0
  67. package/src/lazperf-loader.ts +22 -0
  68. package/src/lib/get-las-schema.ts +1 -1
  69. package/src/lib/las-types.ts +1 -0
  70. package/src/lib/{laslaz-decoder.ts → laz-perf/laslaz-decoder.ts} +4 -3
  71. package/src/lib/{parse-las.ts → laz-perf/parse-las.ts} +7 -10
  72. package/src/lib/laz-rs-wasm/laslaz-decoder.ts +528 -0
  73. package/src/lib/laz-rs-wasm/parse-las.ts +232 -0
  74. package/src/libs/laz-rs-wasm/laz_rs_wasm.d.ts +80 -0
  75. package/src/libs/laz-rs-wasm/laz_rs_wasm.js +477 -0
  76. package/src/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm +0 -0
  77. package/src/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm.d.ts +31 -0
  78. package/src/libs/laz-rs-wasm/package.json +19 -0
  79. package/dist/lib/laslaz-decoder.d.ts.map +0 -1
  80. package/dist/lib/libs/laz-perf.d.ts.map +0 -1
  81. package/dist/lib/parse-las.d.ts.map +0 -1
  82. /package/dist/{lib/libs → libs/laz-perf}/laz-perf.d.ts +0 -0
  83. /package/src/{lib/libs → libs/laz-perf}/laz-perf.ts +0 -0
@@ -0,0 +1,528 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /*
6
+ Modified from Uday Verma and Howard Butler's plasio
7
+ https://github.com/verma/plasio/
8
+ MIT License
9
+ */
10
+ // laslaz.js - treat as compiled code
11
+ import type {LASHeader} from '../las-types';
12
+ import {WasmLasZipDecompressor} from '../../libs/laz-rs-wasm/laz_rs_wasm';
13
+
14
+ type LASPoint = {
15
+ position: [number, number, number];
16
+ intensity: number;
17
+ classification: number;
18
+ color?: [number, number, number];
19
+ };
20
+
21
+ type LASReader = (dv: DataView) => LASPoint;
22
+
23
+ type LASReaders = {
24
+ [key: number]: LASReader;
25
+ };
26
+
27
+ type LASData = {
28
+ buffer: ArrayBuffer;
29
+ count: number;
30
+ hasMoreData: boolean;
31
+ };
32
+
33
+ const POINT_FORMAT_READERS: LASReaders = {
34
+ 0: (dv) => {
35
+ return {
36
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
37
+ intensity: dv.getUint16(12, true),
38
+ classification: dv.getUint8(15)
39
+ };
40
+ },
41
+ 1: (dv) => {
42
+ return {
43
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
44
+ intensity: dv.getUint16(12, true),
45
+ classification: dv.getUint8(15)
46
+ };
47
+ },
48
+ 2: (dv) => {
49
+ return {
50
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
51
+ intensity: dv.getUint16(12, true),
52
+ classification: dv.getUint8(15),
53
+ color: [dv.getUint16(20, true), dv.getUint16(22, true), dv.getUint16(24, true)]
54
+ };
55
+ },
56
+ 3: (dv) => {
57
+ return {
58
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
59
+ intensity: dv.getUint16(12, true),
60
+ classification: dv.getUint8(15),
61
+ color: [dv.getUint16(28, true), dv.getUint16(30, true), dv.getUint16(32, true)]
62
+ };
63
+ },
64
+ 4: (dv) => {
65
+ return {
66
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
67
+ intensity: dv.getUint16(12, true),
68
+ classification: dv.getUint8(15)
69
+ };
70
+ },
71
+ 5: (dv) => {
72
+ return {
73
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
74
+ intensity: dv.getUint16(12, true),
75
+ classification: dv.getUint8(15),
76
+ color: [dv.getUint16(28, true), dv.getUint16(30, true), dv.getUint16(32, true)]
77
+ };
78
+ },
79
+ 6: (dv) => {
80
+ return {
81
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
82
+ intensity: dv.getUint16(12, true),
83
+ classification: dv.getUint8(16)
84
+ };
85
+ },
86
+ 7: (dv) => {
87
+ return {
88
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
89
+ intensity: dv.getUint16(12, true),
90
+ classification: dv.getUint8(16),
91
+ color: [dv.getUint16(30, true), dv.getUint16(32, true), dv.getUint16(34, true)]
92
+ };
93
+ },
94
+ 8: (dv) => {
95
+ return {
96
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
97
+ intensity: dv.getUint16(12, true),
98
+ classification: dv.getUint8(16),
99
+ color: [dv.getUint16(30, true), dv.getUint16(32, true), dv.getUint16(34, true)]
100
+ };
101
+ },
102
+ 9: (dv) => {
103
+ return {
104
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
105
+ intensity: dv.getUint16(12, true),
106
+ classification: dv.getUint8(16)
107
+ };
108
+ },
109
+ 10: (dv) => {
110
+ return {
111
+ position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
112
+ intensity: dv.getUint16(12, true),
113
+ classification: dv.getUint8(16),
114
+ color: [dv.getUint16(30, true), dv.getUint16(32, true), dv.getUint16(34, true)]
115
+ };
116
+ }
117
+ };
118
+
119
+ /**
120
+ * Reads incoming binary data depends on the Type parameter
121
+ * @param buf
122
+ * @param Type
123
+ * @param offset
124
+ * @param count
125
+ * @returns number | number[] from incoming binary data
126
+ */
127
+ function readAs(buf: ArrayBuffer, Type: any = {}, offset: number, count?: number) {
128
+ count = count === undefined || count === 0 ? 1 : count;
129
+ const sub = buf.slice(offset, offset + Type.BYTES_PER_ELEMENT * count);
130
+
131
+ const r = new Type(sub);
132
+ if (count === 1) {
133
+ return r[0];
134
+ }
135
+
136
+ const ret: number[] = [];
137
+ for (let i = 0; i < count; i++) {
138
+ ret.push(r[i]);
139
+ }
140
+
141
+ return ret;
142
+ }
143
+
144
+ /**
145
+ * Parsing of header's attributes
146
+ * @param arraybuffer
147
+ * @returns header as LASHeader
148
+ */
149
+ function parseLASHeader(arraybuffer: ArrayBuffer): LASHeader {
150
+ const ver = new Uint8Array(arraybuffer, 24, 2);
151
+ const version = ver[0] * 10 + ver[1];
152
+ const versionAsString = `${ver[0]}.${ver[1]}`;
153
+
154
+ const rawPointsFormatId = readAs(arraybuffer, Uint8Array, 32 * 3 + 8);
155
+ const bit7 = (rawPointsFormatId & 0x80) >> 7;
156
+ const bit6 = (rawPointsFormatId & 0x40) >> 6;
157
+
158
+ const isCompressed = bit7 === 1 || bit6 === 1;
159
+ const pointsFormatId = rawPointsFormatId & 0x3f;
160
+ const o: Partial<LASHeader> = {
161
+ pointsOffset: readAs(arraybuffer, Uint32Array, 32 * 3),
162
+ pointsFormatId,
163
+ pointsStructSize: readAs(arraybuffer, Uint16Array, 32 * 3 + 8 + 1),
164
+ pointsCount: readAs(arraybuffer, Uint32Array, 32 * 3 + 11),
165
+ versionAsString,
166
+ isCompressed
167
+ };
168
+
169
+ let start = 32 * 3 + 35;
170
+
171
+ o.scale = readAs(arraybuffer, Float64Array, start, 3);
172
+ start += 24; // 8*3
173
+ o.offset = readAs(arraybuffer, Float64Array, start, 3);
174
+ start += 24;
175
+
176
+ const bounds = readAs(arraybuffer, Float64Array, start, 6);
177
+ start += 48; // 8*6
178
+ o.maxs = [bounds[0], bounds[2], bounds[4]];
179
+ o.mins = [bounds[1], bounds[3], bounds[5]];
180
+
181
+ start += 20; // 8*20
182
+
183
+ if (version === 14) {
184
+ o.pointsCount = Number(readAs(arraybuffer, BigUint64Array, start));
185
+ }
186
+
187
+ const colorPointFormats = new Set([2, 3, 5, 7, 8, 10]);
188
+ o.hasColor = colorPointFormats.has(pointsFormatId);
189
+ // @ts-expect-error Caused when restoring lazperf
190
+ return o;
191
+ }
192
+
193
+ // LAS Loader
194
+ // Loads uncompressed files
195
+ //
196
+ class LASLoader {
197
+ arraybuffer: ArrayBuffer;
198
+ readOffset: number = 0;
199
+ header: LASHeader | null = null;
200
+
201
+ constructor(arraybuffer: ArrayBuffer) {
202
+ this.arraybuffer = arraybuffer;
203
+ }
204
+
205
+ /**
206
+ * @returns boolean
207
+ */
208
+ open() {
209
+ // Nothing needs to be done to open this
210
+ return true;
211
+ }
212
+ /**
213
+ * Parsing of incoming binary
214
+ * @returns LASHeader
215
+ */
216
+ getHeader() {
217
+ this.header = parseLASHeader(this.arraybuffer);
218
+ return this.header;
219
+ }
220
+
221
+ /**
222
+ * Reading data
223
+ * @param count
224
+ * @param skip
225
+ * @returns LasData
226
+ */
227
+ readData(count: number, skip: number): LASData {
228
+ const {header, arraybuffer} = this;
229
+ if (!header) {
230
+ throw new Error('Cannot start reading data till a header request is issued');
231
+ }
232
+
233
+ let {readOffset} = this;
234
+ let start: number;
235
+
236
+ if (skip <= 1) {
237
+ count = Math.min(count, header.pointsCount - readOffset);
238
+ start = header.pointsOffset + readOffset * header.pointsStructSize;
239
+ const end = start + count * header.pointsStructSize;
240
+ readOffset += count;
241
+ this.readOffset = readOffset;
242
+ return {
243
+ buffer: arraybuffer.slice(start, end),
244
+ count,
245
+ hasMoreData: readOffset < header.pointsCount
246
+ };
247
+ }
248
+
249
+ const pointsToRead = Math.min(count * skip, header.pointsCount - readOffset);
250
+ const bufferSize = Math.ceil(pointsToRead / skip);
251
+ let pointsRead = 0;
252
+
253
+ const buf = new Uint8Array(bufferSize * header.pointsStructSize);
254
+ for (let i = 0; i < pointsToRead; i++) {
255
+ if (i % skip === 0) {
256
+ start = header.pointsOffset + readOffset * header.pointsStructSize;
257
+ const src = new Uint8Array(arraybuffer, start, header.pointsStructSize);
258
+
259
+ buf.set(src, pointsRead * header.pointsStructSize);
260
+ pointsRead++;
261
+ }
262
+
263
+ readOffset++;
264
+ }
265
+ this.readOffset = readOffset;
266
+
267
+ return {
268
+ buffer: buf.buffer,
269
+ count: pointsRead,
270
+ hasMoreData: readOffset < header.pointsCount
271
+ };
272
+ }
273
+ /**
274
+ * Method which brings data to null to close the file
275
+ * @returns
276
+ */
277
+ close() {
278
+ // @ts-ignore Possibly null
279
+ this.arraybuffer = null;
280
+ return true;
281
+ }
282
+ }
283
+
284
+ /**
285
+ * LAZ Loader
286
+ * Uses NaCL module to load LAZ files
287
+ */
288
+ class LAZLoader {
289
+ arraybuffer: ArrayBuffer;
290
+ readOffset: number = 0;
291
+ instance: WasmLasZipDecompressor | null = null;
292
+ header: LASHeader | null = null;
293
+
294
+ constructor(arraybuffer: ArrayBuffer) {
295
+ this.arraybuffer = arraybuffer;
296
+ }
297
+
298
+ /**
299
+ * Opens the file
300
+ * @returns boolean
301
+ */
302
+ open(): boolean {
303
+ try {
304
+ const abInt = new Uint8Array(this.arraybuffer);
305
+ this.instance = new WasmLasZipDecompressor(abInt);
306
+
307
+ return true;
308
+ } catch (error) {
309
+ throw new Error(`Failed to open file: ${(error as Error).message}`);
310
+ }
311
+ }
312
+
313
+ getHeader(): LASHeader {
314
+ try {
315
+ this.header = parseLASHeader(this.arraybuffer);
316
+ return this.header;
317
+ } catch (error) {
318
+ throw new Error(`Failed to get header: ${(error as Error).message}`);
319
+ }
320
+ }
321
+
322
+ /**
323
+ * @param count
324
+ * @param offset
325
+ * @param skip
326
+ * @returns LASData
327
+ */
328
+ readData(count: number, skip: number): LASData {
329
+ if (!this.instance) {
330
+ throw new Error('You need to open the file before trying to read stuff');
331
+ }
332
+
333
+ const {header, instance} = this;
334
+
335
+ if (!header) {
336
+ throw new Error(
337
+ 'You need to query header before reading, I maintain state that way, sorry :('
338
+ );
339
+ }
340
+
341
+ try {
342
+ const pointsToRead = Math.min(count * skip, header.pointsCount - this.readOffset);
343
+ const bufferSize = Math.ceil(pointsToRead / skip);
344
+ let pointsRead = 0;
345
+
346
+ const buf = new Uint8Array(bufferSize * header.pointsStructSize);
347
+
348
+ const bufRead = new Uint8Array(header.pointsStructSize);
349
+ for (let i = 0; i < pointsToRead; i++) {
350
+ instance.decompress_many(bufRead);
351
+
352
+ if (i % skip === 0) {
353
+ buf.set(bufRead, pointsRead * header.pointsStructSize);
354
+ pointsRead++;
355
+ }
356
+
357
+ this.readOffset++;
358
+ }
359
+ return {
360
+ buffer: buf.buffer,
361
+ count: pointsRead,
362
+ hasMoreData: this.readOffset < header.pointsCount
363
+ };
364
+ } catch (error) {
365
+ throw new Error(`Failed to read data: ${(error as Error).message}`);
366
+ }
367
+ }
368
+
369
+ /**
370
+ * Deletes the instance
371
+ * @returns boolean
372
+ */
373
+ close(): boolean {
374
+ try {
375
+ if (this.instance !== null) {
376
+ this.instance.free();
377
+ this.instance = null;
378
+ }
379
+ // @ts-ignore Possibly null
380
+ this.arraybuffer = null;
381
+ return true;
382
+ } catch (error) {
383
+ throw new Error(`Failed to close file: ${(error as Error).message}`);
384
+ }
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Helper class: Decodes LAS records into points
390
+ */
391
+ class LASDecoder {
392
+ arrayb: ArrayBuffer;
393
+ decoder: (dv: DataView) => LASPoint;
394
+ pointsCount: number;
395
+ pointSize: number;
396
+
397
+ constructor(buffer: ArrayBuffer, len: number, header: LASHeader) {
398
+ this.arrayb = buffer;
399
+ this.decoder = POINT_FORMAT_READERS[header.pointsFormatId];
400
+ this.pointsCount = len;
401
+ this.pointSize = header.pointsStructSize;
402
+ }
403
+
404
+ /**
405
+ * Decodes data depends on this point size
406
+ * @param index
407
+ * @returns New object
408
+ */
409
+ getPoint(index: number): LASPoint {
410
+ if (index < 0 || index >= this.pointsCount) {
411
+ throw new Error('Point index out of range');
412
+ }
413
+
414
+ const dv = new DataView(this.arrayb, index * this.pointSize, this.pointSize);
415
+ return this.decoder(dv);
416
+ }
417
+ }
418
+
419
+ /**
420
+ * A single consistent interface for loading LAS/LAZ files
421
+ */
422
+ export class LASFile {
423
+ arraybuffer: ArrayBuffer;
424
+ formatId: number = 0;
425
+ loader: LASLoader | LAZLoader;
426
+ isCompressed: boolean = true;
427
+ isOpen: boolean = false;
428
+ version: number = 0;
429
+ versionAsString: string = '';
430
+
431
+ constructor(arraybuffer: ArrayBuffer) {
432
+ this.arraybuffer = arraybuffer;
433
+
434
+ this.validate();
435
+
436
+ this.loader = this.isCompressed
437
+ ? new LAZLoader(this.arraybuffer)
438
+ : new LASLoader(this.arraybuffer);
439
+ }
440
+
441
+ validate(): void {
442
+ const signature = readAs(this.arraybuffer, Uint8Array, 0, 4);
443
+ const check = String.fromCharCode(...signature);
444
+ if (check !== 'LASF') {
445
+ throw new Error('Invalid LAS file');
446
+ }
447
+
448
+ if (this.determineVersion() > 14) {
449
+ throw new Error('Only file versions <= 1.4 are supported');
450
+ }
451
+
452
+ this.determineFormat();
453
+ if (POINT_FORMAT_READERS[this.formatId] === undefined) {
454
+ throw new Error('The point format ID is not supported');
455
+ }
456
+ }
457
+
458
+ /**
459
+ * Determines format in parameters of LASHeader
460
+ */
461
+ determineFormat(): void {
462
+ const formatId = readAs(this.arraybuffer, Uint8Array, 32 * 3 + 8);
463
+ const bit7 = (formatId & 0x80) >> 7;
464
+ const bit6 = (formatId & 0x40) >> 6;
465
+
466
+ if (bit7 === 1 && bit6 === 1) {
467
+ throw new Error('Old style compression not supported');
468
+ }
469
+
470
+ this.formatId = formatId & 0x3f;
471
+ this.isCompressed = bit7 === 1 || bit6 === 1;
472
+ }
473
+
474
+ /**
475
+ * Determines version
476
+ * @returns version
477
+ */
478
+ determineVersion(): number {
479
+ const ver = new Uint8Array(this.arraybuffer, 24, 2);
480
+ this.version = ver[0] * 10 + ver[1];
481
+ this.versionAsString = `${ver[0]}.${ver[1]}`;
482
+ return this.version;
483
+ }
484
+
485
+ /**
486
+ * Reads if the file is open
487
+ * @returns boolean
488
+ */
489
+ open(): void {
490
+ if (this.loader.open()) {
491
+ this.isOpen = true;
492
+ }
493
+ }
494
+ /**
495
+ * Gets the header
496
+ * @returns Header
497
+ */
498
+ getHeader(): LASHeader {
499
+ return this.loader.getHeader();
500
+ }
501
+
502
+ /**
503
+ * @param count
504
+ * @param start
505
+ * @param skip
506
+ * @returns LASData
507
+ */
508
+ readData(count: number, skip: number): LASData {
509
+ return this.loader.readData(count, skip);
510
+ }
511
+
512
+ /**
513
+ * Closes the file
514
+ */
515
+ close(): void {
516
+ if (this.loader.close()) {
517
+ this.isOpen = false;
518
+ }
519
+ }
520
+ /**
521
+ */
522
+ getUnpacker(): typeof LASDecoder {
523
+ return LASDecoder;
524
+ }
525
+ }
526
+
527
+ /* eslint no-use-before-define: 2 */
528
+ // export const LASModuleWasLoaded = false;