@xeokit/xeokit-sdk 2.0.16 → 2.0.17

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.
@@ -6790,7 +6790,7 @@ function isSameComponent(c1, c2) {
6790
6790
  @returns {boolean}
6791
6791
  @private
6792
6792
  */
6793
- function isFunction(value) {
6793
+ function isFunction$1(value) {
6794
6794
  return (typeof value === "function");
6795
6795
  }
6796
6796
 
@@ -6800,7 +6800,7 @@ function isFunction(value) {
6800
6800
  @returns {boolean}
6801
6801
  @private
6802
6802
  */
6803
- function isObject(value) {
6803
+ function isObject$1(value) {
6804
6804
  const objectConstructor = {}.constructor;
6805
6805
  return (!!value && value.constructor === objectConstructor);
6806
6806
  }
@@ -6935,8 +6935,8 @@ const utils = {
6935
6935
  isNumeric: isNumeric,
6936
6936
  isID: isID,
6937
6937
  isSameComponent: isSameComponent,
6938
- isFunction: isFunction,
6939
- isObject: isObject,
6938
+ isFunction: isFunction$1,
6939
+ isObject: isObject$1,
6940
6940
  copy: copy,
6941
6941
  apply: apply,
6942
6942
  apply2: apply2,
@@ -39406,6 +39406,8 @@ class DistanceMeasurementsPlugin extends Plugin {
39406
39406
  * {@link Viewer} plugin that improves interactivity by temporarily switching to fast and simple rendering while the
39407
39407
  * {@link Camera} is moving or the {@link Canvas} is resizing.
39408
39408
  *
39409
+ * [<img src="https://xeokit.io/img/docs/FastNavPlugin/FastNavPlugin.gif">](https://xeokit.github.io/xeokit-sdk/examples/#performance_FastNavPlugin)
39410
+ *
39409
39411
  * FastNavPlugin works by disabling specified rendering features, and optionally down-scaling the canvas, whenever we
39410
39412
  * move the Camera or resize the Canvas. Then, once the Camera or Canvas has been at rest after a certain time, FastNavPlugin
39411
39413
  * restores those rendering features and original canvas scale again.
@@ -39428,7 +39430,7 @@ class DistanceMeasurementsPlugin extends Plugin {
39428
39430
  * * disable physically-based materials (switching to non-PBR),
39429
39431
  * * hide transparent objects, and
39430
39432
  * * down-scale the canvas by 0.5, causing 75% less pixels to render.
39431
- *
39433
+ * <br><br>
39432
39434
  * We'll also configure a 0.5 second delay before we transition back to high-quality each time we stop moving, so that we're
39433
39435
  * not continually flipping between low and high quality as we interact.
39434
39436
  *
@@ -64977,7 +64979,21 @@ class PerformanceModel extends Component {
64977
64979
 
64978
64980
  let needNewBatchingLayers = false;
64979
64981
 
64980
- const origin = (cfg.origin || cfg.rtcCenter) ? math.addVec3(this._origin, cfg.origin || cfg.rtcCenter, tempVec3a$8) : null;
64982
+ const cellSize = 100000;
64983
+
64984
+ let origin = null;
64985
+
64986
+ if (cfg.origin || cfg.rtcCenter) {
64987
+ origin = math.addVec3(this._origin, cfg.origin || cfg.rtcCenter, tempVec3a$8);
64988
+ } else if (!cfg.positionsDecodeMatrix) { // TODO: Assumes we never quantize double-precision coordinates
64989
+ const rtcCenter = math.vec3();
64990
+ const rtcPositions = [];
64991
+ const rtcNeeded = worldToRTCPositions(positions, rtcPositions, rtcCenter, cellSize);
64992
+ if (rtcNeeded) {
64993
+ positions = rtcPositions;
64994
+ origin = math.addVec3(this._origin, rtcCenter, rtcCenter);
64995
+ }
64996
+ }
64981
64997
 
64982
64998
  if (origin) {
64983
64999
  if (!this._lastOrigin) {
@@ -75960,7 +75976,7 @@ class STLSceneGraphLoader {
75960
75976
  spinner.processes++;
75961
75977
 
75962
75978
  plugin.dataSource.getSTL(src, function (data) { // OK
75963
- parse(plugin, modelNode, data, options);
75979
+ parse$1(plugin, modelNode, data, options);
75964
75980
  try {
75965
75981
  const binData = ensureBinary(data);
75966
75982
  if (isBinary(binData)) {
@@ -76015,7 +76031,7 @@ class STLSceneGraphLoader {
76015
76031
  }
76016
76032
  }
76017
76033
 
76018
- function parse(plugin, modelNode, data, options) {
76034
+ function parse$1(plugin, modelNode, data, options) {
76019
76035
  try {
76020
76036
  const binData = ensureBinary(data);
76021
76037
  if (isBinary(binData)) {
@@ -130843,7 +130859,7 @@ class LocaleService {
130843
130859
  if (!localeMessages) {
130844
130860
  return null;
130845
130861
  }
130846
- const localeMessage = resolvePath(msg, localeMessages);
130862
+ const localeMessage = resolvePath$1(msg, localeMessages);
130847
130863
  if (localeMessage) {
130848
130864
  if (args) {
130849
130865
  return vsprintf(localeMessage, args);
@@ -130868,7 +130884,7 @@ class LocaleService {
130868
130884
  if (!localeMessages) {
130869
130885
  return null;
130870
130886
  }
130871
- let localeMessage = resolvePath(msg, localeMessages);
130887
+ let localeMessage = resolvePath$1(msg, localeMessages);
130872
130888
  count = parseInt("" + count, 10);
130873
130889
  if (count === 0) {
130874
130890
  localeMessage = localeMessage.zero;
@@ -130977,7 +130993,7 @@ class LocaleService {
130977
130993
  }
130978
130994
  }
130979
130995
 
130980
- function resolvePath(key, json) {
130996
+ function resolvePath$1(key, json) {
130981
130997
  if (json[key]) {
130982
130998
  return json[key];
130983
130999
  }
@@ -143080,4 +143096,2831 @@ class IFCLoaderPlugin extends Plugin {
143080
143096
  }
143081
143097
  }
143082
143098
 
143083
- export { AmbientLight, AngleMeasurementsPlugin, AnnotationsPlugin, AxisGizmoPlugin, BCFViewpointsPlugin, CameraMemento, CameraPath, CameraPathAnimation, Component, Configs, ContextMenu, CubicBezierCurve, Curve, DirLight, DistanceMeasurementsPlugin, EdgeMaterial, EmphasisMaterial, FastNavPlugin, Fresnel, GLTFDefaultDataSource, GLTFLoaderPlugin, IFCLoaderPlugin, ImagePlane, LambertMaterial, LightMap, LocaleService, Map$1 as Map, Marker, Mesh, MetallicMaterial, ModelMemento, NavCubePlugin, Node, OBJLoaderPlugin, ObjectsMemento, Path, PerformanceModel, PhongMaterial, Plugin, PointLight, QuadraticBezierCurve, Queue, ReadableGeometry, ReflectionMap, STLDefaultDataSource, STLLoaderPlugin, SectionPlane, SectionPlanesPlugin, Skybox, SkyboxesPlugin, SpecularMaterial, SplineCurve, SpriteMarker, StoreyViewsPlugin, Texture, TreeViewPlugin, VBOGeometry, ViewCullPlugin, Viewer, XKTDefaultDataSource, XKTLoaderPlugin, XML3DLoaderPlugin, buildBoxGeometry, buildBoxLinesGeometry, buildCylinderGeometry, buildGridGeometry, buildPlaneGeometry, buildSphereGeometry, buildTorusGeometry, buildVectorTextGeometry, load3DSGeometry, loadOBJGeometry, math, utils };
143099
+ /**
143100
+ * Default data access strategy for {@link LASLoaderPlugin}.
143101
+ */
143102
+ class LASDefaultDataSource {
143103
+
143104
+ constructor() {
143105
+ }
143106
+
143107
+ /**
143108
+ * Gets the contents of the given LAS file in an arraybuffer.
143109
+ *
143110
+ * @param {String|Number} src Path or ID of an LAS file.
143111
+ * @param {Function} ok Callback fired on success, argument is the LAS file in an arraybuffer.
143112
+ * @param {Function} error Callback fired on error.
143113
+ */
143114
+ getLAS(src, ok, error) {
143115
+ var defaultCallback = () => {
143116
+ };
143117
+ ok = ok || defaultCallback;
143118
+ error = error || defaultCallback;
143119
+ const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
143120
+ const dataUriRegexResult = src.match(dataUriRegex);
143121
+ if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest
143122
+ const isBase64 = !!dataUriRegexResult[2];
143123
+ var data = dataUriRegexResult[3];
143124
+ data = window.decodeURIComponent(data);
143125
+ if (isBase64) {
143126
+ data = window.atob(data);
143127
+ }
143128
+ try {
143129
+ const buffer = new ArrayBuffer(data.length);
143130
+ const view = new Uint8Array(buffer);
143131
+ for (var i = 0; i < data.length; i++) {
143132
+ view[i] = data.charCodeAt(i);
143133
+ }
143134
+ ok(buffer);
143135
+ } catch (errMsg) {
143136
+ error(errMsg);
143137
+ }
143138
+ } else {
143139
+ const request = new XMLHttpRequest();
143140
+ request.open('GET', src, true);
143141
+ request.responseType = 'arraybuffer';
143142
+ request.onreadystatechange = function () {
143143
+ if (request.readyState === 4) {
143144
+ if (request.status === 200) {
143145
+ ok(request.response);
143146
+ } else {
143147
+ error('getXKT error : ' + request.response);
143148
+ }
143149
+ }
143150
+ };
143151
+ request.send(null);
143152
+ }
143153
+ }
143154
+ }
143155
+
143156
+ function assert$2(condition, message) {
143157
+ if (!condition) {
143158
+ throw new Error(message || 'loader assertion failed.');
143159
+ }
143160
+ }
143161
+
143162
+ const globals$1 = {
143163
+ self: typeof self !== 'undefined' && self,
143164
+ window: typeof window !== 'undefined' && window,
143165
+ global: typeof global !== 'undefined' && global,
143166
+ document: typeof document !== 'undefined' && document
143167
+ };
143168
+ const global_ = globals$1.global || globals$1.self || globals$1.window || {};
143169
+ const isBrowser$2 = typeof process !== 'object' || String(process) !== '[object process]' || process.browser;
143170
+ const matches$1 = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version);
143171
+ matches$1 && parseFloat(matches$1[1]) || 0;
143172
+
143173
+ const VERSION$2 = "3.0.13" ;
143174
+
143175
+ function assert$1(condition, message) {
143176
+ if (!condition) {
143177
+ throw new Error(message || 'loaders.gl assertion failed.');
143178
+ }
143179
+ }
143180
+
143181
+ typeof process !== 'object' || String(process) !== '[object process]' || process.browser;
143182
+ const isMobile = typeof window !== 'undefined' && typeof window.orientation !== 'undefined';
143183
+ const matches = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version);
143184
+ matches && parseFloat(matches[1]) || 0;
143185
+
143186
+ function _defineProperty(obj, key, value) {
143187
+ if (key in obj) {
143188
+ Object.defineProperty(obj, key, {
143189
+ value: value,
143190
+ enumerable: true,
143191
+ configurable: true,
143192
+ writable: true
143193
+ });
143194
+ } else {
143195
+ obj[key] = value;
143196
+ }
143197
+
143198
+ return obj;
143199
+ }
143200
+
143201
+ class WorkerJob {
143202
+ constructor(jobName, workerThread) {
143203
+ _defineProperty(this, "name", void 0);
143204
+
143205
+ _defineProperty(this, "workerThread", void 0);
143206
+
143207
+ _defineProperty(this, "isRunning", void 0);
143208
+
143209
+ _defineProperty(this, "result", void 0);
143210
+
143211
+ _defineProperty(this, "_resolve", void 0);
143212
+
143213
+ _defineProperty(this, "_reject", void 0);
143214
+
143215
+ this.name = jobName;
143216
+ this.workerThread = workerThread;
143217
+ this.isRunning = true;
143218
+
143219
+ this._resolve = () => {};
143220
+
143221
+ this._reject = () => {};
143222
+
143223
+ this.result = new Promise((resolve, reject) => {
143224
+ this._resolve = resolve;
143225
+ this._reject = reject;
143226
+ });
143227
+ }
143228
+
143229
+ postMessage(type, payload) {
143230
+ this.workerThread.postMessage({
143231
+ source: 'loaders.gl',
143232
+ type,
143233
+ payload
143234
+ });
143235
+ }
143236
+
143237
+ done(value) {
143238
+ assert$1(this.isRunning);
143239
+ this.isRunning = false;
143240
+
143241
+ this._resolve(value);
143242
+ }
143243
+
143244
+ error(error) {
143245
+ assert$1(this.isRunning);
143246
+ this.isRunning = false;
143247
+
143248
+ this._reject(error);
143249
+ }
143250
+
143251
+ }
143252
+
143253
+ const workerURLCache = new Map();
143254
+ function getLoadableWorkerURL(props) {
143255
+ assert$1(props.source && !props.url || !props.source && props.url);
143256
+ let workerURL = workerURLCache.get(props.source || props.url);
143257
+
143258
+ if (!workerURL) {
143259
+ if (props.url) {
143260
+ workerURL = getLoadableWorkerURLFromURL(props.url);
143261
+ workerURLCache.set(props.url, workerURL);
143262
+ }
143263
+
143264
+ if (props.source) {
143265
+ workerURL = getLoadableWorkerURLFromSource(props.source);
143266
+ workerURLCache.set(props.source, workerURL);
143267
+ }
143268
+ }
143269
+
143270
+ assert$1(workerURL);
143271
+ return workerURL;
143272
+ }
143273
+
143274
+ function getLoadableWorkerURLFromURL(url) {
143275
+ if (!url.startsWith('http')) {
143276
+ return url;
143277
+ }
143278
+
143279
+ const workerSource = buildScriptSource(url);
143280
+ return getLoadableWorkerURLFromSource(workerSource);
143281
+ }
143282
+
143283
+ function getLoadableWorkerURLFromSource(workerSource) {
143284
+ const blob = new Blob([workerSource], {
143285
+ type: 'application/javascript'
143286
+ });
143287
+ return URL.createObjectURL(blob);
143288
+ }
143289
+
143290
+ function buildScriptSource(workerUrl) {
143291
+ return "try {\n importScripts('".concat(workerUrl, "');\n} catch (error) {\n console.error(error);\n throw error;\n}");
143292
+ }
143293
+
143294
+ function getTransferList(object, recursive = true, transfers) {
143295
+ const transfersSet = transfers || new Set();
143296
+
143297
+ if (!object) ; else if (isTransferable(object)) {
143298
+ transfersSet.add(object);
143299
+ } else if (isTransferable(object.buffer)) {
143300
+ transfersSet.add(object.buffer);
143301
+ } else if (ArrayBuffer.isView(object)) ; else if (recursive && typeof object === 'object') {
143302
+ for (const key in object) {
143303
+ getTransferList(object[key], recursive, transfersSet);
143304
+ }
143305
+ }
143306
+
143307
+ return transfers === undefined ? Array.from(transfersSet) : [];
143308
+ }
143309
+
143310
+ function isTransferable(object) {
143311
+ if (!object) {
143312
+ return false;
143313
+ }
143314
+
143315
+ if (object instanceof ArrayBuffer) {
143316
+ return true;
143317
+ }
143318
+
143319
+ if (typeof MessagePort !== 'undefined' && object instanceof MessagePort) {
143320
+ return true;
143321
+ }
143322
+
143323
+ if (typeof ImageBitmap !== 'undefined' && object instanceof ImageBitmap) {
143324
+ return true;
143325
+ }
143326
+
143327
+ if (typeof OffscreenCanvas !== 'undefined' && object instanceof OffscreenCanvas) {
143328
+ return true;
143329
+ }
143330
+
143331
+ return false;
143332
+ }
143333
+
143334
+ const NOOP = () => {};
143335
+
143336
+ class WorkerThread {
143337
+ static isSupported() {
143338
+ return typeof Worker !== 'undefined';
143339
+ }
143340
+
143341
+ constructor(props) {
143342
+ _defineProperty(this, "name", void 0);
143343
+
143344
+ _defineProperty(this, "source", void 0);
143345
+
143346
+ _defineProperty(this, "url", void 0);
143347
+
143348
+ _defineProperty(this, "terminated", false);
143349
+
143350
+ _defineProperty(this, "worker", void 0);
143351
+
143352
+ _defineProperty(this, "onMessage", void 0);
143353
+
143354
+ _defineProperty(this, "onError", void 0);
143355
+
143356
+ _defineProperty(this, "_loadableURL", '');
143357
+
143358
+ const {
143359
+ name,
143360
+ source,
143361
+ url
143362
+ } = props;
143363
+ assert$1(source || url);
143364
+ this.name = name;
143365
+ this.source = source;
143366
+ this.url = url;
143367
+ this.onMessage = NOOP;
143368
+
143369
+ this.onError = error => console.log(error);
143370
+
143371
+ this.worker = this._createBrowserWorker();
143372
+ }
143373
+
143374
+ destroy() {
143375
+ this.onMessage = NOOP;
143376
+ this.onError = NOOP;
143377
+ this.worker.terminate();
143378
+ this.terminated = true;
143379
+ }
143380
+
143381
+ get isRunning() {
143382
+ return Boolean(this.onMessage);
143383
+ }
143384
+
143385
+ postMessage(data, transferList) {
143386
+ transferList = transferList || getTransferList(data);
143387
+ this.worker.postMessage(data, transferList);
143388
+ }
143389
+
143390
+ _getErrorFromErrorEvent(event) {
143391
+ let message = 'Failed to load ';
143392
+ message += "worker ".concat(this.name, ". ");
143393
+
143394
+ if (event.message) {
143395
+ message += "".concat(event.message, " in ");
143396
+ }
143397
+
143398
+ if (event.lineno) {
143399
+ message += ":".concat(event.lineno, ":").concat(event.colno);
143400
+ }
143401
+
143402
+ return new Error(message);
143403
+ }
143404
+
143405
+ _createBrowserWorker() {
143406
+ this._loadableURL = getLoadableWorkerURL({
143407
+ source: this.source,
143408
+ url: this.url
143409
+ });
143410
+ const worker = new Worker(this._loadableURL, {
143411
+ name: this.name
143412
+ });
143413
+
143414
+ worker.onmessage = event => {
143415
+ if (!event.data) {
143416
+ this.onError(new Error('No data received'));
143417
+ } else {
143418
+ this.onMessage(event.data);
143419
+ }
143420
+ };
143421
+
143422
+ worker.onerror = error => {
143423
+ this.onError(this._getErrorFromErrorEvent(error));
143424
+ this.terminated = true;
143425
+ };
143426
+
143427
+ worker.onmessageerror = event => console.error(event);
143428
+
143429
+ return worker;
143430
+ }
143431
+
143432
+ }
143433
+
143434
+ class WorkerPool {
143435
+ constructor(props) {
143436
+ _defineProperty(this, "name", 'unnamed');
143437
+
143438
+ _defineProperty(this, "source", void 0);
143439
+
143440
+ _defineProperty(this, "url", void 0);
143441
+
143442
+ _defineProperty(this, "maxConcurrency", 1);
143443
+
143444
+ _defineProperty(this, "maxMobileConcurrency", 1);
143445
+
143446
+ _defineProperty(this, "onDebug", () => {});
143447
+
143448
+ _defineProperty(this, "reuseWorkers", true);
143449
+
143450
+ _defineProperty(this, "props", {});
143451
+
143452
+ _defineProperty(this, "jobQueue", []);
143453
+
143454
+ _defineProperty(this, "idleQueue", []);
143455
+
143456
+ _defineProperty(this, "count", 0);
143457
+
143458
+ _defineProperty(this, "isDestroyed", false);
143459
+
143460
+ this.source = props.source;
143461
+ this.url = props.url;
143462
+ this.setProps(props);
143463
+ }
143464
+
143465
+ destroy() {
143466
+ this.idleQueue.forEach(worker => worker.destroy());
143467
+ this.isDestroyed = true;
143468
+ }
143469
+
143470
+ setProps(props) {
143471
+ this.props = { ...this.props,
143472
+ ...props
143473
+ };
143474
+
143475
+ if (props.name !== undefined) {
143476
+ this.name = props.name;
143477
+ }
143478
+
143479
+ if (props.maxConcurrency !== undefined) {
143480
+ this.maxConcurrency = props.maxConcurrency;
143481
+ }
143482
+
143483
+ if (props.maxMobileConcurrency !== undefined) {
143484
+ this.maxMobileConcurrency = props.maxMobileConcurrency;
143485
+ }
143486
+
143487
+ if (props.reuseWorkers !== undefined) {
143488
+ this.reuseWorkers = props.reuseWorkers;
143489
+ }
143490
+
143491
+ if (props.onDebug !== undefined) {
143492
+ this.onDebug = props.onDebug;
143493
+ }
143494
+ }
143495
+
143496
+ async startJob(name, onMessage = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
143497
+ const startPromise = new Promise(onStart => {
143498
+ this.jobQueue.push({
143499
+ name,
143500
+ onMessage,
143501
+ onError,
143502
+ onStart
143503
+ });
143504
+ return this;
143505
+ });
143506
+
143507
+ this._startQueuedJob();
143508
+
143509
+ return await startPromise;
143510
+ }
143511
+
143512
+ async _startQueuedJob() {
143513
+ if (!this.jobQueue.length) {
143514
+ return;
143515
+ }
143516
+
143517
+ const workerThread = this._getAvailableWorker();
143518
+
143519
+ if (!workerThread) {
143520
+ return;
143521
+ }
143522
+
143523
+ const queuedJob = this.jobQueue.shift();
143524
+
143525
+ if (queuedJob) {
143526
+ this.onDebug({
143527
+ message: 'Starting job',
143528
+ name: queuedJob.name,
143529
+ workerThread,
143530
+ backlog: this.jobQueue.length
143531
+ });
143532
+ const job = new WorkerJob(queuedJob.name, workerThread);
143533
+
143534
+ workerThread.onMessage = data => queuedJob.onMessage(job, data.type, data.payload);
143535
+
143536
+ workerThread.onError = error => queuedJob.onError(job, error);
143537
+
143538
+ queuedJob.onStart(job);
143539
+
143540
+ try {
143541
+ await job.result;
143542
+ } finally {
143543
+ this.returnWorkerToQueue(workerThread);
143544
+ }
143545
+ }
143546
+ }
143547
+
143548
+ returnWorkerToQueue(worker) {
143549
+ const shouldDestroyWorker = this.isDestroyed || !this.reuseWorkers || this.count > this._getMaxConcurrency();
143550
+
143551
+ if (shouldDestroyWorker) {
143552
+ worker.destroy();
143553
+ this.count--;
143554
+ } else {
143555
+ this.idleQueue.push(worker);
143556
+ }
143557
+
143558
+ if (!this.isDestroyed) {
143559
+ this._startQueuedJob();
143560
+ }
143561
+ }
143562
+
143563
+ _getAvailableWorker() {
143564
+ if (this.idleQueue.length > 0) {
143565
+ return this.idleQueue.shift() || null;
143566
+ }
143567
+
143568
+ if (this.count < this._getMaxConcurrency()) {
143569
+ this.count++;
143570
+ const name = "".concat(this.name.toLowerCase(), " (#").concat(this.count, " of ").concat(this.maxConcurrency, ")");
143571
+ return new WorkerThread({
143572
+ name,
143573
+ source: this.source,
143574
+ url: this.url
143575
+ });
143576
+ }
143577
+
143578
+ return null;
143579
+ }
143580
+
143581
+ _getMaxConcurrency() {
143582
+ return isMobile ? this.maxMobileConcurrency : this.maxConcurrency;
143583
+ }
143584
+
143585
+ }
143586
+
143587
+ const DEFAULT_PROPS = {
143588
+ maxConcurrency: 3,
143589
+ maxMobileConcurrency: 1,
143590
+ onDebug: () => {},
143591
+ reuseWorkers: true
143592
+ };
143593
+ class WorkerFarm {
143594
+ static isSupported() {
143595
+ return WorkerThread.isSupported();
143596
+ }
143597
+
143598
+ static getWorkerFarm(props = {}) {
143599
+ WorkerFarm._workerFarm = WorkerFarm._workerFarm || new WorkerFarm({});
143600
+
143601
+ WorkerFarm._workerFarm.setProps(props);
143602
+
143603
+ return WorkerFarm._workerFarm;
143604
+ }
143605
+
143606
+ constructor(props) {
143607
+ _defineProperty(this, "props", void 0);
143608
+
143609
+ _defineProperty(this, "workerPools", new Map());
143610
+
143611
+ this.props = { ...DEFAULT_PROPS
143612
+ };
143613
+ this.setProps(props);
143614
+ this.workerPools = new Map();
143615
+ }
143616
+
143617
+ destroy() {
143618
+ for (const workerPool of this.workerPools.values()) {
143619
+ workerPool.destroy();
143620
+ }
143621
+ }
143622
+
143623
+ setProps(props) {
143624
+ this.props = { ...this.props,
143625
+ ...props
143626
+ };
143627
+
143628
+ for (const workerPool of this.workerPools.values()) {
143629
+ workerPool.setProps(this._getWorkerPoolProps());
143630
+ }
143631
+ }
143632
+
143633
+ getWorkerPool(options) {
143634
+ const {
143635
+ name,
143636
+ source,
143637
+ url
143638
+ } = options;
143639
+ let workerPool = this.workerPools.get(name);
143640
+
143641
+ if (!workerPool) {
143642
+ workerPool = new WorkerPool({
143643
+ name,
143644
+ source,
143645
+ url
143646
+ });
143647
+ workerPool.setProps(this._getWorkerPoolProps());
143648
+ this.workerPools.set(name, workerPool);
143649
+ }
143650
+
143651
+ return workerPool;
143652
+ }
143653
+
143654
+ _getWorkerPoolProps() {
143655
+ return {
143656
+ maxConcurrency: this.props.maxConcurrency,
143657
+ maxMobileConcurrency: this.props.maxMobileConcurrency,
143658
+ reuseWorkers: this.props.reuseWorkers,
143659
+ onDebug: this.props.onDebug
143660
+ };
143661
+ }
143662
+
143663
+ }
143664
+
143665
+ _defineProperty(WorkerFarm, "_workerFarm", void 0);
143666
+
143667
+ const NPM_TAG = 'latest';
143668
+ function getWorkerURL(worker, options = {}) {
143669
+ const workerOptions = options[worker.id] || {};
143670
+ const workerFile = "".concat(worker.id, "-worker.js");
143671
+ let url = workerOptions.workerUrl;
143672
+
143673
+ if (!url && worker.id === 'compression') {
143674
+ url = options.workerUrl;
143675
+ }
143676
+
143677
+ if (options._workerType === 'test') {
143678
+ url = "modules/".concat(worker.module, "/dist/").concat(workerFile);
143679
+ }
143680
+
143681
+ if (!url) {
143682
+ let version = worker.version;
143683
+
143684
+ if (version === 'latest') {
143685
+ version = NPM_TAG;
143686
+ }
143687
+
143688
+ const versionTag = version ? "@".concat(version) : '';
143689
+ url = "https://unpkg.com/@loaders.gl/".concat(worker.module).concat(versionTag, "/dist/").concat(workerFile);
143690
+ }
143691
+
143692
+ assert$1(url);
143693
+ return url;
143694
+ }
143695
+
143696
+ function validateWorkerVersion(worker, coreVersion = VERSION$2) {
143697
+ assert$1(worker, 'no worker provided');
143698
+ const workerVersion = worker.version;
143699
+
143700
+ if (!coreVersion || !workerVersion) {
143701
+ return false;
143702
+ }
143703
+
143704
+ return true;
143705
+ }
143706
+
143707
+ var makeNodeStream = {};
143708
+
143709
+ var node = /*#__PURE__*/Object.freeze({
143710
+ __proto__: null,
143711
+ 'default': makeNodeStream
143712
+ });
143713
+
143714
+ function canParseWithWorker(loader, options) {
143715
+ if (!WorkerFarm.isSupported()) {
143716
+ return false;
143717
+ }
143718
+
143719
+ return loader.worker && (options === null || options === void 0 ? void 0 : options.worker);
143720
+ }
143721
+ async function parseWithWorker(loader, data, options, context, parseOnMainThread) {
143722
+ const name = loader.id;
143723
+ const url = getWorkerURL(loader, options);
143724
+ const workerFarm = WorkerFarm.getWorkerFarm(options);
143725
+ const workerPool = workerFarm.getWorkerPool({
143726
+ name,
143727
+ url
143728
+ });
143729
+ options = JSON.parse(JSON.stringify(options));
143730
+ const job = await workerPool.startJob('process-on-worker', onMessage.bind(null, parseOnMainThread));
143731
+ job.postMessage('process', {
143732
+ input: data,
143733
+ options
143734
+ });
143735
+ const result = await job.result;
143736
+ return await result.result;
143737
+ }
143738
+
143739
+ async function onMessage(parseOnMainThread, job, type, payload) {
143740
+ switch (type) {
143741
+ case 'done':
143742
+ job.done(payload);
143743
+ break;
143744
+
143745
+ case 'error':
143746
+ job.error(payload.error);
143747
+ break;
143748
+
143749
+ case 'process':
143750
+ const {
143751
+ id,
143752
+ input,
143753
+ options
143754
+ } = payload;
143755
+
143756
+ try {
143757
+ const result = await parseOnMainThread(input, options);
143758
+ job.postMessage('done', {
143759
+ id,
143760
+ result
143761
+ });
143762
+ } catch (error) {
143763
+ const message = error instanceof Error ? error.message : 'unknown error';
143764
+ job.postMessage('error', {
143765
+ id,
143766
+ error: message
143767
+ });
143768
+ }
143769
+
143770
+ break;
143771
+
143772
+ default:
143773
+ console.warn("parse-with-worker unknown message ".concat(type));
143774
+ }
143775
+ }
143776
+
143777
+ function isBuffer$1(value) {
143778
+ return value && typeof value === 'object' && value.isBuffer;
143779
+ }
143780
+ function bufferToArrayBuffer(data) {
143781
+ if (undefined) {
143782
+ return undefined(data);
143783
+ }
143784
+
143785
+ return data;
143786
+ }
143787
+
143788
+ function toArrayBuffer(data) {
143789
+ if (isBuffer$1(data)) {
143790
+ data = bufferToArrayBuffer(data);
143791
+ }
143792
+
143793
+ if (data instanceof ArrayBuffer) {
143794
+ return data;
143795
+ }
143796
+
143797
+ if (ArrayBuffer.isView(data)) {
143798
+ if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
143799
+ return data.buffer;
143800
+ }
143801
+
143802
+ return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
143803
+ }
143804
+
143805
+ if (typeof data === 'string') {
143806
+ const text = data;
143807
+ const uint8Array = new TextEncoder().encode(text);
143808
+ return uint8Array.buffer;
143809
+ }
143810
+
143811
+ if (data && typeof data === 'object' && data._toArrayBuffer) {
143812
+ return data._toArrayBuffer();
143813
+ }
143814
+
143815
+ throw new Error('toArrayBuffer');
143816
+ }
143817
+ function compareArrayBuffers(arrayBuffer1, arrayBuffer2, byteLength) {
143818
+ byteLength = byteLength || arrayBuffer1.byteLength;
143819
+
143820
+ if (arrayBuffer1.byteLength < byteLength || arrayBuffer2.byteLength < byteLength) {
143821
+ return false;
143822
+ }
143823
+
143824
+ const array1 = new Uint8Array(arrayBuffer1);
143825
+ const array2 = new Uint8Array(arrayBuffer2);
143826
+
143827
+ for (let i = 0; i < array1.length; ++i) {
143828
+ if (array1[i] !== array2[i]) {
143829
+ return false;
143830
+ }
143831
+ }
143832
+
143833
+ return true;
143834
+ }
143835
+ function concatenateArrayBuffers(...sources) {
143836
+ const sourceArrays = sources.map(source2 => source2 instanceof ArrayBuffer ? new Uint8Array(source2) : source2);
143837
+ const byteLength = sourceArrays.reduce((length, typedArray) => length + typedArray.byteLength, 0);
143838
+ const result = new Uint8Array(byteLength);
143839
+ let offset = 0;
143840
+
143841
+ for (const sourceArray of sourceArrays) {
143842
+ result.set(sourceArray, offset);
143843
+ offset += sourceArray.byteLength;
143844
+ }
143845
+
143846
+ return result.buffer;
143847
+ }
143848
+
143849
+ async function concatenateArrayBuffersAsync(asyncIterator) {
143850
+ const arrayBuffers = [];
143851
+
143852
+ for await (const chunk of asyncIterator) {
143853
+ arrayBuffers.push(chunk);
143854
+ }
143855
+
143856
+ return concatenateArrayBuffers(...arrayBuffers);
143857
+ }
143858
+
143859
+ let pathPrefix = '';
143860
+ const fileAliases = {};
143861
+ function resolvePath(filename) {
143862
+ for (const alias in fileAliases) {
143863
+ if (filename.startsWith(alias)) {
143864
+ const replacement = fileAliases[alias];
143865
+ filename = filename.replace(alias, replacement);
143866
+ }
143867
+ }
143868
+
143869
+ if (!filename.startsWith('http://') && !filename.startsWith('https://')) {
143870
+ filename = "".concat(pathPrefix).concat(filename);
143871
+ }
143872
+
143873
+ return filename;
143874
+ }
143875
+
143876
+ const isBoolean = x => typeof x === 'boolean';
143877
+
143878
+ const isFunction = x => typeof x === 'function';
143879
+
143880
+ const isObject = x => x !== null && typeof x === 'object';
143881
+ const isPureObject = x => isObject(x) && x.constructor === {}.constructor;
143882
+ const isIterable = x => x && typeof x[Symbol.iterator] === 'function';
143883
+ const isAsyncIterable = x => x && typeof x[Symbol.asyncIterator] === 'function';
143884
+ const isResponse = x => typeof Response !== 'undefined' && x instanceof Response || x && x.arrayBuffer && x.text && x.json;
143885
+ const isBlob = x => typeof Blob !== 'undefined' && x instanceof Blob;
143886
+ const isReadableDOMStream = x => typeof ReadableStream !== 'undefined' && x instanceof ReadableStream || isObject(x) && isFunction(x.tee) && isFunction(x.cancel) && isFunction(x.getReader);
143887
+ const isBuffer = x => x && typeof x === 'object' && x.isBuffer;
143888
+ const isReadableNodeStream = x => isObject(x) && isFunction(x.read) && isFunction(x.pipe) && isBoolean(x.readable);
143889
+ const isReadableStream = x => isReadableDOMStream(x) || isReadableNodeStream(x);
143890
+
143891
+ const DATA_URL_PATTERN = /^data:([-\w.]+\/[-\w.+]+)(;|,)/;
143892
+ const MIME_TYPE_PATTERN = /^([-\w.]+\/[-\w.+]+)/;
143893
+ function parseMIMEType(mimeString) {
143894
+ const matches = MIME_TYPE_PATTERN.exec(mimeString);
143895
+
143896
+ if (matches) {
143897
+ return matches[1];
143898
+ }
143899
+
143900
+ return mimeString;
143901
+ }
143902
+ function parseMIMETypeFromURL(url) {
143903
+ const matches = DATA_URL_PATTERN.exec(url);
143904
+
143905
+ if (matches) {
143906
+ return matches[1];
143907
+ }
143908
+
143909
+ return '';
143910
+ }
143911
+
143912
+ const QUERY_STRING_PATTERN = /\?.*/;
143913
+ function getResourceUrlAndType(resource) {
143914
+ if (isResponse(resource)) {
143915
+ const url = stripQueryString(resource.url || '');
143916
+ const contentTypeHeader = resource.headers.get('content-type') || '';
143917
+ return {
143918
+ url,
143919
+ type: parseMIMEType(contentTypeHeader) || parseMIMETypeFromURL(url)
143920
+ };
143921
+ }
143922
+
143923
+ if (isBlob(resource)) {
143924
+ return {
143925
+ url: stripQueryString(resource.name || ''),
143926
+ type: resource.type || ''
143927
+ };
143928
+ }
143929
+
143930
+ if (typeof resource === 'string') {
143931
+ return {
143932
+ url: stripQueryString(resource),
143933
+ type: parseMIMETypeFromURL(resource)
143934
+ };
143935
+ }
143936
+
143937
+ return {
143938
+ url: '',
143939
+ type: ''
143940
+ };
143941
+ }
143942
+ function getResourceContentLength(resource) {
143943
+ if (isResponse(resource)) {
143944
+ return resource.headers['content-length'] || -1;
143945
+ }
143946
+
143947
+ if (isBlob(resource)) {
143948
+ return resource.size;
143949
+ }
143950
+
143951
+ if (typeof resource === 'string') {
143952
+ return resource.length;
143953
+ }
143954
+
143955
+ if (resource instanceof ArrayBuffer) {
143956
+ return resource.byteLength;
143957
+ }
143958
+
143959
+ if (ArrayBuffer.isView(resource)) {
143960
+ return resource.byteLength;
143961
+ }
143962
+
143963
+ return -1;
143964
+ }
143965
+
143966
+ function stripQueryString(url) {
143967
+ return url.replace(QUERY_STRING_PATTERN, '');
143968
+ }
143969
+
143970
+ async function makeResponse(resource) {
143971
+ if (isResponse(resource)) {
143972
+ return resource;
143973
+ }
143974
+
143975
+ const headers = {};
143976
+ const contentLength = getResourceContentLength(resource);
143977
+
143978
+ if (contentLength >= 0) {
143979
+ headers['content-length'] = String(contentLength);
143980
+ }
143981
+
143982
+ const {
143983
+ url,
143984
+ type
143985
+ } = getResourceUrlAndType(resource);
143986
+
143987
+ if (type) {
143988
+ headers['content-type'] = type;
143989
+ }
143990
+
143991
+ const initialDataUrl = await getInitialDataUrl(resource);
143992
+
143993
+ if (initialDataUrl) {
143994
+ headers['x-first-bytes'] = initialDataUrl;
143995
+ }
143996
+
143997
+ if (typeof resource === 'string') {
143998
+ resource = new TextEncoder().encode(resource);
143999
+ }
144000
+
144001
+ const response = new Response(resource, {
144002
+ headers
144003
+ });
144004
+ Object.defineProperty(response, 'url', {
144005
+ value: url
144006
+ });
144007
+ return response;
144008
+ }
144009
+ async function checkResponse(response) {
144010
+ if (!response.ok) {
144011
+ const message = await getResponseError(response);
144012
+ throw new Error(message);
144013
+ }
144014
+ }
144015
+
144016
+ async function getResponseError(response) {
144017
+ let message = "Failed to fetch resource ".concat(response.url, " (").concat(response.status, "): ");
144018
+
144019
+ try {
144020
+ const contentType = response.headers.get('Content-Type');
144021
+ let text = response.statusText;
144022
+
144023
+ if (contentType.includes('application/json')) {
144024
+ text += " ".concat(await response.text());
144025
+ }
144026
+
144027
+ message += text;
144028
+ message = message.length > 60 ? "".concat(message.slice(60), "...") : message;
144029
+ } catch (error) {}
144030
+
144031
+ return message;
144032
+ }
144033
+
144034
+ async function getInitialDataUrl(resource) {
144035
+ const INITIAL_DATA_LENGTH = 5;
144036
+
144037
+ if (typeof resource === 'string') {
144038
+ return "data:,".concat(resource.slice(0, INITIAL_DATA_LENGTH));
144039
+ }
144040
+
144041
+ if (resource instanceof Blob) {
144042
+ const blobSlice = resource.slice(0, 5);
144043
+ return await new Promise(resolve => {
144044
+ const reader = new FileReader();
144045
+
144046
+ reader.onload = event => {
144047
+ var _event$target;
144048
+
144049
+ return resolve(event === null || event === void 0 ? void 0 : (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result);
144050
+ };
144051
+
144052
+ reader.readAsDataURL(blobSlice);
144053
+ });
144054
+ }
144055
+
144056
+ if (resource instanceof ArrayBuffer) {
144057
+ const slice = resource.slice(0, INITIAL_DATA_LENGTH);
144058
+ const base64 = arrayBufferToBase64(slice);
144059
+ return "data:base64,".concat(base64);
144060
+ }
144061
+
144062
+ return null;
144063
+ }
144064
+
144065
+ function arrayBufferToBase64(buffer) {
144066
+ let binary = '';
144067
+ const bytes = new Uint8Array(buffer);
144068
+
144069
+ for (let i = 0; i < bytes.byteLength; i++) {
144070
+ binary += String.fromCharCode(bytes[i]);
144071
+ }
144072
+
144073
+ return btoa(binary);
144074
+ }
144075
+
144076
+ async function fetchFile(url, options) {
144077
+ if (typeof url === 'string') {
144078
+ url = resolvePath(url);
144079
+ let fetchOptions = options;
144080
+
144081
+ if (options !== null && options !== void 0 && options.fetch && typeof (options === null || options === void 0 ? void 0 : options.fetch) !== 'function') {
144082
+ fetchOptions = options.fetch;
144083
+ }
144084
+
144085
+ return await fetch(url, fetchOptions);
144086
+ }
144087
+
144088
+ return await makeResponse(url);
144089
+ }
144090
+
144091
+ function isElectron(mockUserAgent) {
144092
+ if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') {
144093
+ return true;
144094
+ }
144095
+
144096
+ if (typeof process !== 'undefined' && typeof process.versions === 'object' && Boolean(process.versions.electron)) {
144097
+ return true;
144098
+ }
144099
+
144100
+ const realUserAgent = typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent;
144101
+ const userAgent = mockUserAgent || realUserAgent;
144102
+
144103
+ if (userAgent && userAgent.indexOf('Electron') >= 0) {
144104
+ return true;
144105
+ }
144106
+
144107
+ return false;
144108
+ }
144109
+
144110
+ function isBrowser$1() {
144111
+ const isNode = typeof process === 'object' && String(process) === '[object process]' && !process.browser;
144112
+ return !isNode || isElectron();
144113
+ }
144114
+
144115
+ const globals = {
144116
+ self: typeof self !== 'undefined' && self,
144117
+ window: typeof window !== 'undefined' && window,
144118
+ global: typeof global !== 'undefined' && global,
144119
+ document: typeof document !== 'undefined' && document,
144120
+ process: typeof process === 'object' && process
144121
+ };
144122
+ const window_ = globals.window || globals.self || globals.global;
144123
+ const process_ = globals.process || {};
144124
+
144125
+ const VERSION$1 = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'untranspiled source';
144126
+ const isBrowser = isBrowser$1();
144127
+
144128
+ function getStorage(type) {
144129
+ try {
144130
+ const storage = window[type];
144131
+ const x = '__storage_test__';
144132
+ storage.setItem(x, x);
144133
+ storage.removeItem(x);
144134
+ return storage;
144135
+ } catch (e) {
144136
+ return null;
144137
+ }
144138
+ }
144139
+
144140
+ class LocalStorage {
144141
+ constructor(id, defaultSettings, type = 'sessionStorage') {
144142
+ this.storage = getStorage(type);
144143
+ this.id = id;
144144
+ this.config = {};
144145
+ Object.assign(this.config, defaultSettings);
144146
+
144147
+ this._loadConfiguration();
144148
+ }
144149
+
144150
+ getConfiguration() {
144151
+ return this.config;
144152
+ }
144153
+
144154
+ setConfiguration(configuration) {
144155
+ this.config = {};
144156
+ return this.updateConfiguration(configuration);
144157
+ }
144158
+
144159
+ updateConfiguration(configuration) {
144160
+ Object.assign(this.config, configuration);
144161
+
144162
+ if (this.storage) {
144163
+ const serialized = JSON.stringify(this.config);
144164
+ this.storage.setItem(this.id, serialized);
144165
+ }
144166
+
144167
+ return this;
144168
+ }
144169
+
144170
+ _loadConfiguration() {
144171
+ let configuration = {};
144172
+
144173
+ if (this.storage) {
144174
+ const serializedConfiguration = this.storage.getItem(this.id);
144175
+ configuration = serializedConfiguration ? JSON.parse(serializedConfiguration) : {};
144176
+ }
144177
+
144178
+ Object.assign(this.config, configuration);
144179
+ return this;
144180
+ }
144181
+
144182
+ }
144183
+
144184
+ function formatTime(ms) {
144185
+ let formatted;
144186
+
144187
+ if (ms < 10) {
144188
+ formatted = "".concat(ms.toFixed(2), "ms");
144189
+ } else if (ms < 100) {
144190
+ formatted = "".concat(ms.toFixed(1), "ms");
144191
+ } else if (ms < 1000) {
144192
+ formatted = "".concat(ms.toFixed(0), "ms");
144193
+ } else {
144194
+ formatted = "".concat((ms / 1000).toFixed(2), "s");
144195
+ }
144196
+
144197
+ return formatted;
144198
+ }
144199
+ function leftPad(string, length = 8) {
144200
+ const padLength = Math.max(length - string.length, 0);
144201
+ return "".concat(' '.repeat(padLength)).concat(string);
144202
+ }
144203
+
144204
+ function formatImage(image, message, scale, maxWidth = 600) {
144205
+ const imageUrl = image.src.replace(/\(/g, '%28').replace(/\)/g, '%29');
144206
+
144207
+ if (image.width > maxWidth) {
144208
+ scale = Math.min(scale, maxWidth / image.width);
144209
+ }
144210
+
144211
+ const width = image.width * scale;
144212
+ const height = image.height * scale;
144213
+ const style = ['font-size:1px;', "padding:".concat(Math.floor(height / 2), "px ").concat(Math.floor(width / 2), "px;"), "line-height:".concat(height, "px;"), "background:url(".concat(imageUrl, ");"), "background-size:".concat(width, "px ").concat(height, "px;"), 'color:transparent;'].join('');
144214
+ return ["".concat(message, " %c+"), style];
144215
+ }
144216
+
144217
+ const COLOR = {
144218
+ BLACK: 30,
144219
+ RED: 31,
144220
+ GREEN: 32,
144221
+ YELLOW: 33,
144222
+ BLUE: 34,
144223
+ MAGENTA: 35,
144224
+ CYAN: 36,
144225
+ WHITE: 37,
144226
+ BRIGHT_BLACK: 90,
144227
+ BRIGHT_RED: 91,
144228
+ BRIGHT_GREEN: 92,
144229
+ BRIGHT_YELLOW: 93,
144230
+ BRIGHT_BLUE: 94,
144231
+ BRIGHT_MAGENTA: 95,
144232
+ BRIGHT_CYAN: 96,
144233
+ BRIGHT_WHITE: 97
144234
+ };
144235
+
144236
+ function getColor(color) {
144237
+ return typeof color === 'string' ? COLOR[color.toUpperCase()] || COLOR.WHITE : color;
144238
+ }
144239
+
144240
+ function addColor(string, color, background) {
144241
+ if (!isBrowser && typeof string === 'string') {
144242
+ if (color) {
144243
+ color = getColor(color);
144244
+ string = "\x1B[".concat(color, "m").concat(string, "\x1B[39m");
144245
+ }
144246
+
144247
+ if (background) {
144248
+ color = getColor(background);
144249
+ string = "\x1B[".concat(background + 10, "m").concat(string, "\x1B[49m");
144250
+ }
144251
+ }
144252
+
144253
+ return string;
144254
+ }
144255
+
144256
+ function autobind(obj, predefined = ['constructor']) {
144257
+ const proto = Object.getPrototypeOf(obj);
144258
+ const propNames = Object.getOwnPropertyNames(proto);
144259
+
144260
+ for (const key of propNames) {
144261
+ if (typeof obj[key] === 'function') {
144262
+ if (!predefined.find(name => key === name)) {
144263
+ obj[key] = obj[key].bind(obj);
144264
+ }
144265
+ }
144266
+ }
144267
+ }
144268
+
144269
+ function assert(condition, message) {
144270
+ if (!condition) {
144271
+ throw new Error(message || 'Assertion failed');
144272
+ }
144273
+ }
144274
+
144275
+ function getHiResTimestamp() {
144276
+ let timestamp;
144277
+
144278
+ if (isBrowser && window_.performance) {
144279
+ timestamp = window_.performance.now();
144280
+ } else if (process_.hrtime) {
144281
+ const timeParts = process_.hrtime();
144282
+ timestamp = timeParts[0] * 1000 + timeParts[1] / 1e6;
144283
+ } else {
144284
+ timestamp = Date.now();
144285
+ }
144286
+
144287
+ return timestamp;
144288
+ }
144289
+
144290
+ const originalConsole = {
144291
+ debug: isBrowser ? console.debug || console.log : console.log,
144292
+ log: console.log,
144293
+ info: console.info,
144294
+ warn: console.warn,
144295
+ error: console.error
144296
+ };
144297
+ const DEFAULT_SETTINGS = {
144298
+ enabled: true,
144299
+ level: 0
144300
+ };
144301
+
144302
+ function noop() {}
144303
+
144304
+ const cache = {};
144305
+ const ONCE = {
144306
+ once: true
144307
+ };
144308
+
144309
+ function getTableHeader(table) {
144310
+ for (const key in table) {
144311
+ for (const title in table[key]) {
144312
+ return title || 'untitled';
144313
+ }
144314
+ }
144315
+
144316
+ return 'empty';
144317
+ }
144318
+
144319
+ class Log {
144320
+ constructor({
144321
+ id
144322
+ } = {
144323
+ id: ''
144324
+ }) {
144325
+ this.id = id;
144326
+ this.VERSION = VERSION$1;
144327
+ this._startTs = getHiResTimestamp();
144328
+ this._deltaTs = getHiResTimestamp();
144329
+ this.LOG_THROTTLE_TIMEOUT = 0;
144330
+ this._storage = new LocalStorage("__probe-".concat(this.id, "__"), DEFAULT_SETTINGS);
144331
+ this.userData = {};
144332
+ this.timeStamp("".concat(this.id, " started"));
144333
+ autobind(this);
144334
+ Object.seal(this);
144335
+ }
144336
+
144337
+ set level(newLevel) {
144338
+ this.setLevel(newLevel);
144339
+ }
144340
+
144341
+ get level() {
144342
+ return this.getLevel();
144343
+ }
144344
+
144345
+ isEnabled() {
144346
+ return this._storage.config.enabled;
144347
+ }
144348
+
144349
+ getLevel() {
144350
+ return this._storage.config.level;
144351
+ }
144352
+
144353
+ getTotal() {
144354
+ return Number((getHiResTimestamp() - this._startTs).toPrecision(10));
144355
+ }
144356
+
144357
+ getDelta() {
144358
+ return Number((getHiResTimestamp() - this._deltaTs).toPrecision(10));
144359
+ }
144360
+
144361
+ set priority(newPriority) {
144362
+ this.level = newPriority;
144363
+ }
144364
+
144365
+ get priority() {
144366
+ return this.level;
144367
+ }
144368
+
144369
+ getPriority() {
144370
+ return this.level;
144371
+ }
144372
+
144373
+ enable(enabled = true) {
144374
+ this._storage.updateConfiguration({
144375
+ enabled
144376
+ });
144377
+
144378
+ return this;
144379
+ }
144380
+
144381
+ setLevel(level) {
144382
+ this._storage.updateConfiguration({
144383
+ level
144384
+ });
144385
+
144386
+ return this;
144387
+ }
144388
+
144389
+ assert(condition, message) {
144390
+ assert(condition, message);
144391
+ }
144392
+
144393
+ warn(message) {
144394
+ return this._getLogFunction(0, message, originalConsole.warn, arguments, ONCE);
144395
+ }
144396
+
144397
+ error(message) {
144398
+ return this._getLogFunction(0, message, originalConsole.error, arguments);
144399
+ }
144400
+
144401
+ deprecated(oldUsage, newUsage) {
144402
+ return this.warn("`".concat(oldUsage, "` is deprecated and will be removed in a later version. Use `").concat(newUsage, "` instead"));
144403
+ }
144404
+
144405
+ removed(oldUsage, newUsage) {
144406
+ return this.error("`".concat(oldUsage, "` has been removed. Use `").concat(newUsage, "` instead"));
144407
+ }
144408
+
144409
+ probe(logLevel, message) {
144410
+ return this._getLogFunction(logLevel, message, originalConsole.log, arguments, {
144411
+ time: true,
144412
+ once: true
144413
+ });
144414
+ }
144415
+
144416
+ log(logLevel, message) {
144417
+ return this._getLogFunction(logLevel, message, originalConsole.debug, arguments);
144418
+ }
144419
+
144420
+ info(logLevel, message) {
144421
+ return this._getLogFunction(logLevel, message, console.info, arguments);
144422
+ }
144423
+
144424
+ once(logLevel, message) {
144425
+ return this._getLogFunction(logLevel, message, originalConsole.debug || originalConsole.info, arguments, ONCE);
144426
+ }
144427
+
144428
+ table(logLevel, table, columns) {
144429
+ if (table) {
144430
+ return this._getLogFunction(logLevel, table, console.table || noop, columns && [columns], {
144431
+ tag: getTableHeader(table)
144432
+ });
144433
+ }
144434
+
144435
+ return noop;
144436
+ }
144437
+
144438
+ image({
144439
+ logLevel,
144440
+ priority,
144441
+ image,
144442
+ message = '',
144443
+ scale = 1
144444
+ }) {
144445
+ if (!this._shouldLog(logLevel || priority)) {
144446
+ return noop;
144447
+ }
144448
+
144449
+ return isBrowser ? logImageInBrowser({
144450
+ image,
144451
+ message,
144452
+ scale
144453
+ }) : logImageInNode({
144454
+ image,
144455
+ message,
144456
+ scale
144457
+ });
144458
+ }
144459
+
144460
+ settings() {
144461
+ if (console.table) {
144462
+ console.table(this._storage.config);
144463
+ } else {
144464
+ console.log(this._storage.config);
144465
+ }
144466
+ }
144467
+
144468
+ get(setting) {
144469
+ return this._storage.config[setting];
144470
+ }
144471
+
144472
+ set(setting, value) {
144473
+ this._storage.updateConfiguration({
144474
+ [setting]: value
144475
+ });
144476
+ }
144477
+
144478
+ time(logLevel, message) {
144479
+ return this._getLogFunction(logLevel, message, console.time ? console.time : console.info);
144480
+ }
144481
+
144482
+ timeEnd(logLevel, message) {
144483
+ return this._getLogFunction(logLevel, message, console.timeEnd ? console.timeEnd : console.info);
144484
+ }
144485
+
144486
+ timeStamp(logLevel, message) {
144487
+ return this._getLogFunction(logLevel, message, console.timeStamp || noop);
144488
+ }
144489
+
144490
+ group(logLevel, message, opts = {
144491
+ collapsed: false
144492
+ }) {
144493
+ opts = normalizeArguments({
144494
+ logLevel,
144495
+ message,
144496
+ opts
144497
+ });
144498
+ const {
144499
+ collapsed
144500
+ } = opts;
144501
+ opts.method = (collapsed ? console.groupCollapsed : console.group) || console.info;
144502
+ return this._getLogFunction(opts);
144503
+ }
144504
+
144505
+ groupCollapsed(logLevel, message, opts = {}) {
144506
+ return this.group(logLevel, message, Object.assign({}, opts, {
144507
+ collapsed: true
144508
+ }));
144509
+ }
144510
+
144511
+ groupEnd(logLevel) {
144512
+ return this._getLogFunction(logLevel, '', console.groupEnd || noop);
144513
+ }
144514
+
144515
+ withGroup(logLevel, message, func) {
144516
+ this.group(logLevel, message)();
144517
+
144518
+ try {
144519
+ func();
144520
+ } finally {
144521
+ this.groupEnd(logLevel)();
144522
+ }
144523
+ }
144524
+
144525
+ trace() {
144526
+ if (console.trace) {
144527
+ console.trace();
144528
+ }
144529
+ }
144530
+
144531
+ _shouldLog(logLevel) {
144532
+ return this.isEnabled() && this.getLevel() >= normalizeLogLevel(logLevel);
144533
+ }
144534
+
144535
+ _getLogFunction(logLevel, message, method, args = [], opts) {
144536
+ if (this._shouldLog(logLevel)) {
144537
+ opts = normalizeArguments({
144538
+ logLevel,
144539
+ message,
144540
+ args,
144541
+ opts
144542
+ });
144543
+ method = method || opts.method;
144544
+ assert(method);
144545
+ opts.total = this.getTotal();
144546
+ opts.delta = this.getDelta();
144547
+ this._deltaTs = getHiResTimestamp();
144548
+ const tag = opts.tag || opts.message;
144549
+
144550
+ if (opts.once) {
144551
+ if (!cache[tag]) {
144552
+ cache[tag] = getHiResTimestamp();
144553
+ } else {
144554
+ return noop;
144555
+ }
144556
+ }
144557
+
144558
+ message = decorateMessage(this.id, opts.message, opts);
144559
+ return method.bind(console, message, ...opts.args);
144560
+ }
144561
+
144562
+ return noop;
144563
+ }
144564
+
144565
+ }
144566
+ Log.VERSION = VERSION$1;
144567
+
144568
+ function normalizeLogLevel(logLevel) {
144569
+ if (!logLevel) {
144570
+ return 0;
144571
+ }
144572
+
144573
+ let resolvedLevel;
144574
+
144575
+ switch (typeof logLevel) {
144576
+ case 'number':
144577
+ resolvedLevel = logLevel;
144578
+ break;
144579
+
144580
+ case 'object':
144581
+ resolvedLevel = logLevel.logLevel || logLevel.priority || 0;
144582
+ break;
144583
+
144584
+ default:
144585
+ return 0;
144586
+ }
144587
+
144588
+ assert(Number.isFinite(resolvedLevel) && resolvedLevel >= 0);
144589
+ return resolvedLevel;
144590
+ }
144591
+
144592
+ function normalizeArguments(opts) {
144593
+ const {
144594
+ logLevel,
144595
+ message
144596
+ } = opts;
144597
+ opts.logLevel = normalizeLogLevel(logLevel);
144598
+ const args = opts.args ? Array.from(opts.args) : [];
144599
+
144600
+ while (args.length && args.shift() !== message) {}
144601
+
144602
+ opts.args = args;
144603
+
144604
+ switch (typeof logLevel) {
144605
+ case 'string':
144606
+ case 'function':
144607
+ if (message !== undefined) {
144608
+ args.unshift(message);
144609
+ }
144610
+
144611
+ opts.message = logLevel;
144612
+ break;
144613
+
144614
+ case 'object':
144615
+ Object.assign(opts, logLevel);
144616
+ break;
144617
+ }
144618
+
144619
+ if (typeof opts.message === 'function') {
144620
+ opts.message = opts.message();
144621
+ }
144622
+
144623
+ const messageType = typeof opts.message;
144624
+ assert(messageType === 'string' || messageType === 'object');
144625
+ return Object.assign(opts, opts.opts);
144626
+ }
144627
+
144628
+ function decorateMessage(id, message, opts) {
144629
+ if (typeof message === 'string') {
144630
+ const time = opts.time ? leftPad(formatTime(opts.total)) : '';
144631
+ message = opts.time ? "".concat(id, ": ").concat(time, " ").concat(message) : "".concat(id, ": ").concat(message);
144632
+ message = addColor(message, opts.color, opts.background);
144633
+ }
144634
+
144635
+ return message;
144636
+ }
144637
+
144638
+ function logImageInNode({
144639
+ image,
144640
+ message = '',
144641
+ scale = 1
144642
+ }) {
144643
+ let asciify = null;
144644
+
144645
+ try {
144646
+ asciify = module.require('asciify-image');
144647
+ } catch (error) {}
144648
+
144649
+ if (asciify) {
144650
+ return () => asciify(image, {
144651
+ fit: 'box',
144652
+ width: "".concat(Math.round(80 * scale), "%")
144653
+ }).then(data => console.log(data));
144654
+ }
144655
+
144656
+ return noop;
144657
+ }
144658
+
144659
+ function logImageInBrowser({
144660
+ image,
144661
+ message = '',
144662
+ scale = 1
144663
+ }) {
144664
+ if (typeof image === 'string') {
144665
+ const img = new Image();
144666
+
144667
+ img.onload = () => {
144668
+ const args = formatImage(img, message, scale);
144669
+ console.log(...args);
144670
+ };
144671
+
144672
+ img.src = image;
144673
+ return noop;
144674
+ }
144675
+
144676
+ const element = image.nodeName || '';
144677
+
144678
+ if (element.toLowerCase() === 'img') {
144679
+ console.log(...formatImage(image, message, scale));
144680
+ return noop;
144681
+ }
144682
+
144683
+ if (element.toLowerCase() === 'canvas') {
144684
+ const img = new Image();
144685
+
144686
+ img.onload = () => console.log(...formatImage(img, message, scale));
144687
+
144688
+ img.src = image.toDataURL();
144689
+ return noop;
144690
+ }
144691
+
144692
+ return noop;
144693
+ }
144694
+
144695
+ const probeLog = new Log({
144696
+ id: 'loaders.gl'
144697
+ });
144698
+ class NullLog {
144699
+ log() {
144700
+ return () => {};
144701
+ }
144702
+
144703
+ info() {
144704
+ return () => {};
144705
+ }
144706
+
144707
+ warn() {
144708
+ return () => {};
144709
+ }
144710
+
144711
+ error() {
144712
+ return () => {};
144713
+ }
144714
+
144715
+ }
144716
+ class ConsoleLog {
144717
+ constructor() {
144718
+ _defineProperty(this, "console", void 0);
144719
+
144720
+ this.console = console;
144721
+ }
144722
+
144723
+ log(...args) {
144724
+ return this.console.log.bind(this.console, ...args);
144725
+ }
144726
+
144727
+ info(...args) {
144728
+ return this.console.info.bind(this.console, ...args);
144729
+ }
144730
+
144731
+ warn(...args) {
144732
+ return this.console.warn.bind(this.console, ...args);
144733
+ }
144734
+
144735
+ error(...args) {
144736
+ return this.console.error.bind(this.console, ...args);
144737
+ }
144738
+
144739
+ }
144740
+
144741
+ const DEFAULT_LOADER_OPTIONS = {
144742
+ fetch: null,
144743
+ mimeType: undefined,
144744
+ nothrow: false,
144745
+ log: new ConsoleLog(),
144746
+ CDN: 'https://unpkg.com/@loaders.gl',
144747
+ worker: true,
144748
+ maxConcurrency: 3,
144749
+ maxMobileConcurrency: 1,
144750
+ reuseWorkers: true,
144751
+ _workerType: '',
144752
+ limit: 0,
144753
+ _limitMB: 0,
144754
+ batchSize: 'auto',
144755
+ batchDebounceMs: 0,
144756
+ metadata: false,
144757
+ transforms: []
144758
+ };
144759
+ const REMOVED_LOADER_OPTIONS = {
144760
+ throws: 'nothrow',
144761
+ dataType: '(no longer used)',
144762
+ uri: 'baseUri',
144763
+ method: 'fetch.method',
144764
+ headers: 'fetch.headers',
144765
+ body: 'fetch.body',
144766
+ mode: 'fetch.mode',
144767
+ credentials: 'fetch.credentials',
144768
+ cache: 'fetch.cache',
144769
+ redirect: 'fetch.redirect',
144770
+ referrer: 'fetch.referrer',
144771
+ referrerPolicy: 'fetch.referrerPolicy',
144772
+ integrity: 'fetch.integrity',
144773
+ keepalive: 'fetch.keepalive',
144774
+ signal: 'fetch.signal'
144775
+ };
144776
+
144777
+ function getGlobalLoaderState() {
144778
+ global_.loaders = global_.loaders || {};
144779
+ const {
144780
+ loaders
144781
+ } = global_;
144782
+ loaders._state = loaders._state || {};
144783
+ return loaders._state;
144784
+ }
144785
+
144786
+ const getGlobalLoaderOptions = () => {
144787
+ const state = getGlobalLoaderState();
144788
+ state.globalOptions = state.globalOptions || { ...DEFAULT_LOADER_OPTIONS
144789
+ };
144790
+ return state.globalOptions;
144791
+ };
144792
+ function normalizeOptions(options, loader, loaders, url) {
144793
+ loaders = loaders || [];
144794
+ loaders = Array.isArray(loaders) ? loaders : [loaders];
144795
+ validateOptions(options, loaders);
144796
+ return normalizeOptionsInternal(loader, options, url);
144797
+ }
144798
+ function getFetchFunction(options, context) {
144799
+ const globalOptions = getGlobalLoaderOptions();
144800
+ const fetchOptions = options || globalOptions;
144801
+
144802
+ if (typeof fetchOptions.fetch === 'function') {
144803
+ return fetchOptions.fetch;
144804
+ }
144805
+
144806
+ if (isObject(fetchOptions.fetch)) {
144807
+ return url => fetchFile(url, fetchOptions);
144808
+ }
144809
+
144810
+ if (context !== null && context !== void 0 && context.fetch) {
144811
+ return context === null || context === void 0 ? void 0 : context.fetch;
144812
+ }
144813
+
144814
+ return fetchFile;
144815
+ }
144816
+
144817
+ function validateOptions(options, loaders) {
144818
+ validateOptionsObject(options, null, DEFAULT_LOADER_OPTIONS, REMOVED_LOADER_OPTIONS, loaders);
144819
+
144820
+ for (const loader of loaders) {
144821
+ const idOptions = options && options[loader.id] || {};
144822
+ const loaderOptions = loader.options && loader.options[loader.id] || {};
144823
+ const deprecatedOptions = loader.deprecatedOptions && loader.deprecatedOptions[loader.id] || {};
144824
+ validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders);
144825
+ }
144826
+ }
144827
+
144828
+ function validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) {
144829
+ const loaderName = id || 'Top level';
144830
+ const prefix = id ? "".concat(id, ".") : '';
144831
+
144832
+ for (const key in options) {
144833
+ const isSubOptions = !id && isObject(options[key]);
144834
+ const isBaseUriOption = key === 'baseUri' && !id;
144835
+ const isWorkerUrlOption = key === 'workerUrl' && id;
144836
+
144837
+ if (!(key in defaultOptions) && !isBaseUriOption && !isWorkerUrlOption) {
144838
+ if (key in deprecatedOptions) {
144839
+ probeLog.warn("".concat(loaderName, " loader option '").concat(prefix).concat(key, "' no longer supported, use '").concat(deprecatedOptions[key], "'"))();
144840
+ } else if (!isSubOptions) {
144841
+ const suggestion = findSimilarOption(key, loaders);
144842
+ probeLog.warn("".concat(loaderName, " loader option '").concat(prefix).concat(key, "' not recognized. ").concat(suggestion))();
144843
+ }
144844
+ }
144845
+ }
144846
+ }
144847
+
144848
+ function findSimilarOption(optionKey, loaders) {
144849
+ const lowerCaseOptionKey = optionKey.toLowerCase();
144850
+ let bestSuggestion = '';
144851
+
144852
+ for (const loader of loaders) {
144853
+ for (const key in loader.options) {
144854
+ if (optionKey === key) {
144855
+ return "Did you mean '".concat(loader.id, ".").concat(key, "'?");
144856
+ }
144857
+
144858
+ const lowerCaseKey = key.toLowerCase();
144859
+ const isPartialMatch = lowerCaseOptionKey.startsWith(lowerCaseKey) || lowerCaseKey.startsWith(lowerCaseOptionKey);
144860
+
144861
+ if (isPartialMatch) {
144862
+ bestSuggestion = bestSuggestion || "Did you mean '".concat(loader.id, ".").concat(key, "'?");
144863
+ }
144864
+ }
144865
+ }
144866
+
144867
+ return bestSuggestion;
144868
+ }
144869
+
144870
+ function normalizeOptionsInternal(loader, options, url) {
144871
+ const loaderDefaultOptions = loader.options || {};
144872
+ const mergedOptions = { ...loaderDefaultOptions
144873
+ };
144874
+ addUrlOptions(mergedOptions, url);
144875
+
144876
+ if (mergedOptions.log === null) {
144877
+ mergedOptions.log = new NullLog();
144878
+ }
144879
+
144880
+ mergeNestedFields(mergedOptions, getGlobalLoaderOptions());
144881
+ mergeNestedFields(mergedOptions, options);
144882
+ return mergedOptions;
144883
+ }
144884
+
144885
+ function mergeNestedFields(mergedOptions, options) {
144886
+ for (const key in options) {
144887
+ if (key in options) {
144888
+ const value = options[key];
144889
+
144890
+ if (isPureObject(value) && isPureObject(mergedOptions[key])) {
144891
+ mergedOptions[key] = { ...mergedOptions[key],
144892
+ ...options[key]
144893
+ };
144894
+ } else {
144895
+ mergedOptions[key] = options[key];
144896
+ }
144897
+ }
144898
+ }
144899
+ }
144900
+
144901
+ function addUrlOptions(options, url) {
144902
+ if (url && !('baseUri' in options)) {
144903
+ options.baseUri = url;
144904
+ }
144905
+ }
144906
+
144907
+ function isLoaderObject(loader) {
144908
+ var _loader;
144909
+
144910
+ if (!loader) {
144911
+ return false;
144912
+ }
144913
+
144914
+ if (Array.isArray(loader)) {
144915
+ loader = loader[0];
144916
+ }
144917
+
144918
+ const hasExtensions = Array.isArray((_loader = loader) === null || _loader === void 0 ? void 0 : _loader.extensions);
144919
+ return hasExtensions;
144920
+ }
144921
+ function normalizeLoader(loader) {
144922
+ var _loader2, _loader3;
144923
+
144924
+ assert$2(loader, 'null loader');
144925
+ assert$2(isLoaderObject(loader), 'invalid loader');
144926
+ let options;
144927
+
144928
+ if (Array.isArray(loader)) {
144929
+ options = loader[1];
144930
+ loader = loader[0];
144931
+ loader = { ...loader,
144932
+ options: { ...loader.options,
144933
+ ...options
144934
+ }
144935
+ };
144936
+ }
144937
+
144938
+ if ((_loader2 = loader) !== null && _loader2 !== void 0 && _loader2.parseTextSync || (_loader3 = loader) !== null && _loader3 !== void 0 && _loader3.parseText) {
144939
+ loader.text = true;
144940
+ }
144941
+
144942
+ if (!loader.text) {
144943
+ loader.binary = true;
144944
+ }
144945
+
144946
+ return loader;
144947
+ }
144948
+
144949
+ const getGlobalLoaderRegistry = () => {
144950
+ const state = getGlobalLoaderState();
144951
+ state.loaderRegistry = state.loaderRegistry || [];
144952
+ return state.loaderRegistry;
144953
+ };
144954
+ function getRegisteredLoaders() {
144955
+ return getGlobalLoaderRegistry();
144956
+ }
144957
+
144958
+ const EXT_PATTERN = /\.([^.]+)$/;
144959
+ async function selectLoader(data, loaders = [], options, context) {
144960
+ if (!validHTTPResponse(data)) {
144961
+ return null;
144962
+ }
144963
+
144964
+ let loader = selectLoaderSync(data, loaders, { ...options,
144965
+ nothrow: true
144966
+ }, context);
144967
+
144968
+ if (loader) {
144969
+ return loader;
144970
+ }
144971
+
144972
+ if (isBlob(data)) {
144973
+ data = await data.slice(0, 10).arrayBuffer();
144974
+ loader = selectLoaderSync(data, loaders, options, context);
144975
+ }
144976
+
144977
+ if (!loader && !(options !== null && options !== void 0 && options.nothrow)) {
144978
+ throw new Error(getNoValidLoaderMessage(data));
144979
+ }
144980
+
144981
+ return loader;
144982
+ }
144983
+ function selectLoaderSync(data, loaders = [], options, context) {
144984
+ if (!validHTTPResponse(data)) {
144985
+ return null;
144986
+ }
144987
+
144988
+ if (loaders && !Array.isArray(loaders)) {
144989
+ return normalizeLoader(loaders);
144990
+ }
144991
+
144992
+ let candidateLoaders = [];
144993
+
144994
+ if (loaders) {
144995
+ candidateLoaders = candidateLoaders.concat(loaders);
144996
+ }
144997
+
144998
+ if (!(options !== null && options !== void 0 && options.ignoreRegisteredLoaders)) {
144999
+ candidateLoaders.push(...getRegisteredLoaders());
145000
+ }
145001
+
145002
+ normalizeLoaders(candidateLoaders);
145003
+ const loader = selectLoaderInternal(data, candidateLoaders, options, context);
145004
+
145005
+ if (!loader && !(options !== null && options !== void 0 && options.nothrow)) {
145006
+ throw new Error(getNoValidLoaderMessage(data));
145007
+ }
145008
+
145009
+ return loader;
145010
+ }
145011
+
145012
+ function selectLoaderInternal(data, loaders, options, context) {
145013
+ const {
145014
+ url,
145015
+ type
145016
+ } = getResourceUrlAndType(data);
145017
+ const testUrl = url || (context === null || context === void 0 ? void 0 : context.url);
145018
+ let loader = null;
145019
+
145020
+ if (options !== null && options !== void 0 && options.mimeType) {
145021
+ loader = findLoaderByMIMEType(loaders, options === null || options === void 0 ? void 0 : options.mimeType);
145022
+ }
145023
+
145024
+ loader = loader || findLoaderByUrl(loaders, testUrl);
145025
+ loader = loader || findLoaderByMIMEType(loaders, type);
145026
+ loader = loader || findLoaderByInitialBytes(loaders, data);
145027
+ loader = loader || findLoaderByMIMEType(loaders, options === null || options === void 0 ? void 0 : options.fallbackMimeType);
145028
+ return loader;
145029
+ }
145030
+
145031
+ function validHTTPResponse(data) {
145032
+ if (data instanceof Response) {
145033
+ if (data.status === 204) {
145034
+ return false;
145035
+ }
145036
+ }
145037
+
145038
+ return true;
145039
+ }
145040
+
145041
+ function getNoValidLoaderMessage(data) {
145042
+ const {
145043
+ url,
145044
+ type
145045
+ } = getResourceUrlAndType(data);
145046
+ let message = 'No valid loader found';
145047
+
145048
+ if (data) {
145049
+ message += " data: \"".concat(getFirstCharacters(data), "\", contentType: \"").concat(type, "\"");
145050
+ }
145051
+
145052
+ if (url) {
145053
+ message += " url: ".concat(url);
145054
+ }
145055
+
145056
+ return message;
145057
+ }
145058
+
145059
+ function normalizeLoaders(loaders) {
145060
+ for (const loader of loaders) {
145061
+ normalizeLoader(loader);
145062
+ }
145063
+ }
145064
+
145065
+ function findLoaderByUrl(loaders, url) {
145066
+ const match = url && EXT_PATTERN.exec(url);
145067
+ const extension = match && match[1];
145068
+ return extension ? findLoaderByExtension(loaders, extension) : null;
145069
+ }
145070
+
145071
+ function findLoaderByExtension(loaders, extension) {
145072
+ extension = extension.toLowerCase();
145073
+
145074
+ for (const loader of loaders) {
145075
+ for (const loaderExtension of loader.extensions) {
145076
+ if (loaderExtension.toLowerCase() === extension) {
145077
+ return loader;
145078
+ }
145079
+ }
145080
+ }
145081
+
145082
+ return null;
145083
+ }
145084
+
145085
+ function findLoaderByMIMEType(loaders, mimeType) {
145086
+ for (const loader of loaders) {
145087
+ if (loader.mimeTypes && loader.mimeTypes.includes(mimeType)) {
145088
+ return loader;
145089
+ }
145090
+
145091
+ if (mimeType === "application/x.".concat(loader.id)) {
145092
+ return loader;
145093
+ }
145094
+ }
145095
+
145096
+ return null;
145097
+ }
145098
+
145099
+ function findLoaderByInitialBytes(loaders, data) {
145100
+ if (!data) {
145101
+ return null;
145102
+ }
145103
+
145104
+ for (const loader of loaders) {
145105
+ if (typeof data === 'string') {
145106
+ if (testDataAgainstText(data, loader)) {
145107
+ return loader;
145108
+ }
145109
+ } else if (ArrayBuffer.isView(data)) {
145110
+ if (testDataAgainstBinary(data.buffer, data.byteOffset, loader)) {
145111
+ return loader;
145112
+ }
145113
+ } else if (data instanceof ArrayBuffer) {
145114
+ const byteOffset = 0;
145115
+
145116
+ if (testDataAgainstBinary(data, byteOffset, loader)) {
145117
+ return loader;
145118
+ }
145119
+ }
145120
+ }
145121
+
145122
+ return null;
145123
+ }
145124
+
145125
+ function testDataAgainstText(data, loader) {
145126
+ if (loader.testText) {
145127
+ return loader.testText(data);
145128
+ }
145129
+
145130
+ const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests];
145131
+ return tests.some(test => data.startsWith(test));
145132
+ }
145133
+
145134
+ function testDataAgainstBinary(data, byteOffset, loader) {
145135
+ const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests];
145136
+ return tests.some(test => testBinary(data, byteOffset, loader, test));
145137
+ }
145138
+
145139
+ function testBinary(data, byteOffset, loader, test) {
145140
+ if (test instanceof ArrayBuffer) {
145141
+ return compareArrayBuffers(test, data, test.byteLength);
145142
+ }
145143
+
145144
+ switch (typeof test) {
145145
+ case 'function':
145146
+ return test(data, loader);
145147
+
145148
+ case 'string':
145149
+ const magic = getMagicString(data, byteOffset, test.length);
145150
+ return test === magic;
145151
+
145152
+ default:
145153
+ return false;
145154
+ }
145155
+ }
145156
+
145157
+ function getFirstCharacters(data, length = 5) {
145158
+ if (typeof data === 'string') {
145159
+ return data.slice(0, length);
145160
+ } else if (ArrayBuffer.isView(data)) {
145161
+ return getMagicString(data.buffer, data.byteOffset, length);
145162
+ } else if (data instanceof ArrayBuffer) {
145163
+ const byteOffset = 0;
145164
+ return getMagicString(data, byteOffset, length);
145165
+ }
145166
+
145167
+ return '';
145168
+ }
145169
+
145170
+ function getMagicString(arrayBuffer, byteOffset, length) {
145171
+ if (arrayBuffer.byteLength < byteOffset + length) {
145172
+ return '';
145173
+ }
145174
+
145175
+ const dataView = new DataView(arrayBuffer);
145176
+ let magic = '';
145177
+
145178
+ for (let i = 0; i < length; i++) {
145179
+ magic += String.fromCharCode(dataView.getUint8(byteOffset + i));
145180
+ }
145181
+
145182
+ return magic;
145183
+ }
145184
+
145185
+ const DEFAULT_CHUNK_SIZE$2 = 256 * 1024;
145186
+ function* makeStringIterator(string, options) {
145187
+ const chunkSize = (options === null || options === void 0 ? void 0 : options.chunkSize) || DEFAULT_CHUNK_SIZE$2;
145188
+ let offset = 0;
145189
+ const textEncoder = new TextEncoder();
145190
+
145191
+ while (offset < string.length) {
145192
+ const chunkLength = Math.min(string.length - offset, chunkSize);
145193
+ const chunk = string.slice(offset, offset + chunkLength);
145194
+ offset += chunkLength;
145195
+ yield textEncoder.encode(chunk);
145196
+ }
145197
+ }
145198
+
145199
+ const DEFAULT_CHUNK_SIZE$1 = 256 * 1024;
145200
+ function* makeArrayBufferIterator(arrayBuffer, options = {}) {
145201
+ const {
145202
+ chunkSize = DEFAULT_CHUNK_SIZE$1
145203
+ } = options;
145204
+ let byteOffset = 0;
145205
+
145206
+ while (byteOffset < arrayBuffer.byteLength) {
145207
+ const chunkByteLength = Math.min(arrayBuffer.byteLength - byteOffset, chunkSize);
145208
+ const chunk = new ArrayBuffer(chunkByteLength);
145209
+ const sourceArray = new Uint8Array(arrayBuffer, byteOffset, chunkByteLength);
145210
+ const chunkArray = new Uint8Array(chunk);
145211
+ chunkArray.set(sourceArray);
145212
+ byteOffset += chunkByteLength;
145213
+ yield chunk;
145214
+ }
145215
+ }
145216
+
145217
+ const DEFAULT_CHUNK_SIZE = 1024 * 1024;
145218
+ async function* makeBlobIterator(blob, options) {
145219
+ const chunkSize = (options === null || options === void 0 ? void 0 : options.chunkSize) || DEFAULT_CHUNK_SIZE;
145220
+ let offset = 0;
145221
+
145222
+ while (offset < blob.size) {
145223
+ const end = offset + chunkSize;
145224
+ const chunk = await blob.slice(offset, end).arrayBuffer();
145225
+ offset = end;
145226
+ yield chunk;
145227
+ }
145228
+ }
145229
+
145230
+ function makeStreamIterator(stream, options) {
145231
+ return isBrowser$2 ? makeBrowserStreamIterator(stream, options) : makeNodeStreamIterator(stream);
145232
+ }
145233
+
145234
+ async function* makeBrowserStreamIterator(stream, options) {
145235
+ const reader = stream.getReader();
145236
+ let nextBatchPromise;
145237
+
145238
+ try {
145239
+ while (true) {
145240
+ const currentBatchPromise = nextBatchPromise || reader.read();
145241
+
145242
+ if (options !== null && options !== void 0 && options._streamReadAhead) {
145243
+ nextBatchPromise = reader.read();
145244
+ }
145245
+
145246
+ const {
145247
+ done,
145248
+ value
145249
+ } = await currentBatchPromise;
145250
+
145251
+ if (done) {
145252
+ return;
145253
+ }
145254
+
145255
+ yield toArrayBuffer(value);
145256
+ }
145257
+ } catch (error) {
145258
+ reader.releaseLock();
145259
+ }
145260
+ }
145261
+
145262
+ async function* makeNodeStreamIterator(stream, options) {
145263
+ for await (const chunk of stream) {
145264
+ yield toArrayBuffer(chunk);
145265
+ }
145266
+ }
145267
+
145268
+ function makeIterator(data, options) {
145269
+ if (typeof data === 'string') {
145270
+ return makeStringIterator(data, options);
145271
+ }
145272
+
145273
+ if (data instanceof ArrayBuffer) {
145274
+ return makeArrayBufferIterator(data, options);
145275
+ }
145276
+
145277
+ if (isBlob(data)) {
145278
+ return makeBlobIterator(data, options);
145279
+ }
145280
+
145281
+ if (isReadableStream(data)) {
145282
+ return makeStreamIterator(data, options);
145283
+ }
145284
+
145285
+ if (isResponse(data)) {
145286
+ const response = data;
145287
+ return makeStreamIterator(response.body, options);
145288
+ }
145289
+
145290
+ throw new Error('makeIterator');
145291
+ }
145292
+
145293
+ const ERR_DATA = 'Cannot convert supplied data type';
145294
+ function getArrayBufferOrStringFromDataSync(data, loader, options) {
145295
+ if (loader.text && typeof data === 'string') {
145296
+ return data;
145297
+ }
145298
+
145299
+ if (isBuffer(data)) {
145300
+ data = data.buffer;
145301
+ }
145302
+
145303
+ if (data instanceof ArrayBuffer) {
145304
+ const arrayBuffer = data;
145305
+
145306
+ if (loader.text && !loader.binary) {
145307
+ const textDecoder = new TextDecoder('utf8');
145308
+ return textDecoder.decode(arrayBuffer);
145309
+ }
145310
+
145311
+ return arrayBuffer;
145312
+ }
145313
+
145314
+ if (ArrayBuffer.isView(data)) {
145315
+ if (loader.text && !loader.binary) {
145316
+ const textDecoder = new TextDecoder('utf8');
145317
+ return textDecoder.decode(data);
145318
+ }
145319
+
145320
+ let arrayBuffer = data.buffer;
145321
+ const byteLength = data.byteLength || data.length;
145322
+
145323
+ if (data.byteOffset !== 0 || byteLength !== arrayBuffer.byteLength) {
145324
+ arrayBuffer = arrayBuffer.slice(data.byteOffset, data.byteOffset + byteLength);
145325
+ }
145326
+
145327
+ return arrayBuffer;
145328
+ }
145329
+
145330
+ throw new Error(ERR_DATA);
145331
+ }
145332
+ async function getArrayBufferOrStringFromData(data, loader, options) {
145333
+ const isArrayBuffer = data instanceof ArrayBuffer || ArrayBuffer.isView(data);
145334
+
145335
+ if (typeof data === 'string' || isArrayBuffer) {
145336
+ return getArrayBufferOrStringFromDataSync(data, loader);
145337
+ }
145338
+
145339
+ if (isBlob(data)) {
145340
+ data = await makeResponse(data);
145341
+ }
145342
+
145343
+ if (isResponse(data)) {
145344
+ const response = data;
145345
+ await checkResponse(response);
145346
+ return loader.binary ? await response.arrayBuffer() : await response.text();
145347
+ }
145348
+
145349
+ if (isReadableStream(data)) {
145350
+ data = makeIterator(data, options);
145351
+ }
145352
+
145353
+ if (isIterable(data) || isAsyncIterable(data)) {
145354
+ return concatenateArrayBuffersAsync(data);
145355
+ }
145356
+
145357
+ throw new Error(ERR_DATA);
145358
+ }
145359
+
145360
+ function getLoaderContext(context, options, previousContext = null) {
145361
+ if (previousContext) {
145362
+ return previousContext;
145363
+ }
145364
+
145365
+ const resolvedContext = {
145366
+ fetch: getFetchFunction(options, context),
145367
+ ...context
145368
+ };
145369
+
145370
+ if (!Array.isArray(resolvedContext.loaders)) {
145371
+ resolvedContext.loaders = null;
145372
+ }
145373
+
145374
+ return resolvedContext;
145375
+ }
145376
+ function getLoadersFromContext(loaders, context) {
145377
+ if (!context && loaders && !Array.isArray(loaders)) {
145378
+ return loaders;
145379
+ }
145380
+
145381
+ let candidateLoaders;
145382
+
145383
+ if (loaders) {
145384
+ candidateLoaders = Array.isArray(loaders) ? loaders : [loaders];
145385
+ }
145386
+
145387
+ if (context && context.loaders) {
145388
+ const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders];
145389
+ candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders;
145390
+ }
145391
+
145392
+ return candidateLoaders && candidateLoaders.length ? candidateLoaders : null;
145393
+ }
145394
+
145395
+ async function parse(data, loaders, options, context) {
145396
+ assert$1(!context || typeof context === 'object');
145397
+
145398
+ if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {
145399
+ context = undefined;
145400
+ options = loaders;
145401
+ loaders = undefined;
145402
+ }
145403
+
145404
+ data = await data;
145405
+ options = options || {};
145406
+ const {
145407
+ url
145408
+ } = getResourceUrlAndType(data);
145409
+ const typedLoaders = loaders;
145410
+ const candidateLoaders = getLoadersFromContext(typedLoaders, context);
145411
+ const loader = await selectLoader(data, candidateLoaders, options);
145412
+
145413
+ if (!loader) {
145414
+ return null;
145415
+ }
145416
+
145417
+ options = normalizeOptions(options, loader, candidateLoaders, url);
145418
+ context = getLoaderContext({
145419
+ url,
145420
+ parse,
145421
+ loaders: candidateLoaders
145422
+ }, options, context);
145423
+ return await parseWithLoader(loader, data, options, context);
145424
+ }
145425
+
145426
+ async function parseWithLoader(loader, data, options, context) {
145427
+ validateWorkerVersion(loader);
145428
+ data = await getArrayBufferOrStringFromData(data, loader, options);
145429
+
145430
+ if (loader.parseTextSync && typeof data === 'string') {
145431
+ options.dataType = 'text';
145432
+ return loader.parseTextSync(data, options, context, loader);
145433
+ }
145434
+
145435
+ if (canParseWithWorker(loader, options)) {
145436
+ return await parseWithWorker(loader, data, options, context, parse);
145437
+ }
145438
+
145439
+ if (loader.parseText && typeof data === 'string') {
145440
+ return await loader.parseText(data, options, context, loader);
145441
+ }
145442
+
145443
+ if (loader.parse) {
145444
+ return await loader.parse(data, options, context, loader);
145445
+ }
145446
+
145447
+ assert$1(!loader.parseSync);
145448
+ throw new Error("".concat(loader.id, " loader - no parser found and worker is disabled"));
145449
+ }
145450
+
145451
+ const VERSION = "3.0.13" ;
145452
+ const DEFAULT_LAS_OPTIONS = {
145453
+ las: {
145454
+ fp64: false,
145455
+ skip: 1,
145456
+ colorDepth: 8
145457
+ }
145458
+ };
145459
+ const LASLoader = {
145460
+ name: 'LAS',
145461
+ id: 'las',
145462
+ module: 'las',
145463
+ version: VERSION,
145464
+ worker: true,
145465
+ extensions: ['las', 'laz'],
145466
+ mimeTypes: ['application/octet-stream'],
145467
+ text: true,
145468
+ binary: true,
145469
+ tests: ['LAS'],
145470
+ options: DEFAULT_LAS_OPTIONS
145471
+ };
145472
+
145473
+ /**
145474
+ * {@link Viewer} plugin that loads lidar point cloud geometry from LAS files.
145475
+ *
145476
+ * <a href="/examples/#loading_LASLoaderPlugin_Autzen"><img src="/assets/images/autzen.png"></a>
145477
+ *
145478
+ * [[Run this example](/examples/#loading_LASLoaderPlugin_Autzen)]
145479
+ *
145480
+ * ## Summary
145481
+ *
145482
+ * * Loads [LAS 1.4 Format](https://www.asprs.org/divisions-committees/lidar-division/laser-las-file-format-exchange-activities) from both *.las* and *.laz* files.
145483
+ * * Loads lidar point cloud positions, colors and intensities.
145484
+ * * Supports 32 and 64-bit positions.
145485
+ * * Supports 8 and 16-bit color depths.
145486
+ * * Option to load every *n* points.
145487
+ * * Does not (yet) load [point classifications](https://www.usna.edu/Users/oceano/pguth/md_help/html/las_format_classification_codes.htm).
145488
+ *
145489
+ * ## Performance
145490
+ *
145491
+ * If you need faster loading, consider pre-converting your LAS files to XKT format using [xeokit-convert](https://github.com/xeokit/xeokit-convert), then loading them
145492
+ * with {@link XKTLoaderPlugin}.
145493
+ *
145494
+ * ## Scene and metadata representation
145495
+ *
145496
+ * When LASLoaderPlugin loads a LAS file, it creates two {@link Entity}s, a {@link MetaModel} and a {@link MetaObject}.
145497
+ *
145498
+ * The first Entity represents the file as a model within the Viewer's {@link Scene}. To indicate that it represents a model,
145499
+ * this Entity will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.
145500
+ *
145501
+ * The second Entity represents the the point cloud itself, as an object within the Scene. To indicate that it
145502
+ * represents an object, this Entity will have {@link Entity#isObject} set ````true```` and will be registered
145503
+ * by {@link Entity#id} in {@link Scene#objects}.
145504
+ *
145505
+ * The MetaModel registers the LAS file as a model within the Viewer's {@link MetaScene}. The MetaModel will be registered
145506
+ * by {@link MetaModel#id} in {@link MetaScene#metaModels} .
145507
+ *
145508
+ * Finally, the MetaObject registers the point cloud as an object within the {@link MetaScene}. The MetaObject will be registered
145509
+ * by {@link MetaObject#id} in {@link MetaScene#metaObjects}.
145510
+ *
145511
+ * ## Usage
145512
+ *
145513
+ * In the example below we'll load the Autzen model from
145514
+ * a [LAS file](https://github.com/xeokit/xeokit-sdk/tree/master/examples/models/las/Duplex.las). Once the model has
145515
+ * loaded, we'll then find its {@link MetaModel}, and the {@link MetaObject} and {@link Entity} that represent its point cloud.
145516
+ *
145517
+ * * [[Run this example](/examples/#loading_LASLoaderPlugin_Autzen)]
145518
+ *
145519
+ * ````javascript
145520
+ * import {Viewer, LASLoaderPlugin} from "xeokit-sdk.es.js";
145521
+ *
145522
+ * const viewer = new Viewer({
145523
+ * canvasId: "myCanvas",
145524
+ * transparent: true
145525
+ * });
145526
+ *
145527
+ * viewer.camera.eye = [-2.56, 8.38, 8.27];
145528
+ * viewer.camera.look = [13.44, 3.31, -14.83];
145529
+ * viewer.camera.up = [0.10, 0.98, -0.14];
145530
+ *
145531
+ * const lasLoader = new LASLoaderPlugin(viewer, {
145532
+ * colorDepth: 8, // Default
145533
+ * fp64: false, // Default
145534
+ * skip: 1 // Default
145535
+ * });
145536
+ *
145537
+ * const modelEntity = lasLoader.load({
145538
+ * id: "myModel",
145539
+ * src: "../assets/models/las/autzen.laz"
145540
+ * });
145541
+ *
145542
+ * modelEntity.on("loaded", () => {
145543
+ *
145544
+ * const metaModel = viewer.metaScene.metaModels[modelEntity.id];
145545
+ * const pointCloudMetaObject = metaModel.rootMetaObject;
145546
+ *
145547
+ * const pointCloudEntity = viewer.scene.objects[pointCloudMetaObject.id];
145548
+ *
145549
+ * //...
145550
+ * });
145551
+ * ````
145552
+ *
145553
+ * ## Transforming
145554
+ *
145555
+ * We have the option to rotate, scale and translate each LAS model as we load it.
145556
+ *
145557
+ * In the example below, we'll scale our model to half its size, rotate it 90 degrees about its local X-axis, then
145558
+ * translate it 100 units along its X axis.
145559
+ *
145560
+ * ````javascript
145561
+ * const modelEntity = lasLoader.load({
145562
+ * id: "myModel",
145563
+ * src: "../assets/models/las/autzen.laz"
145564
+ * rotation: [90,0,0],
145565
+ * scale: [0.5, 0.5, 0.5],
145566
+ * origin: [100, 0, 0]
145567
+ * });
145568
+ * ````
145569
+ *
145570
+ * ## Configuring a custom data source
145571
+ *
145572
+ * By default, LASLoaderPlugin will load LAS files over HTTP.
145573
+ *
145574
+ * In the example below, we'll customize the way LASLoaderPlugin loads the files by configuring it with our own data source
145575
+ * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.
145576
+ *
145577
+ * ````javascript
145578
+ * import {utils} from "xeokit-sdk.es.js";
145579
+ *
145580
+ * class MyDataSource {
145581
+ *
145582
+ * constructor() {
145583
+ * }
145584
+ *
145585
+ * // Gets the contents of the given LAS file in an arraybuffer
145586
+ * getLAS(src, ok, error) {
145587
+ * utils.loadArraybuffer(src,
145588
+ * (arraybuffer) => {
145589
+ * ok(arraybuffer);
145590
+ * },
145591
+ * (errMsg) => {
145592
+ * error(errMsg);
145593
+ * });
145594
+ * }
145595
+ * }
145596
+ *
145597
+ * const lasLoader = new LASLoaderPlugin(viewer, {
145598
+ * dataSource: new MyDataSource()
145599
+ * });
145600
+ *
145601
+ * const modelEntity = lasLoader.load({
145602
+ * id: "myModel",
145603
+ * src: "../assets/models/las/autzen.laz"
145604
+ * });
145605
+ * ````
145606
+ *
145607
+ * @class LASLoaderPlugin
145608
+ * @since 2.0.13
145609
+ */
145610
+ class LASLoaderPlugin extends Plugin {
145611
+
145612
+ /**
145613
+ * @constructor
145614
+ *
145615
+ * @param {Viewer} viewer The Viewer.
145616
+ * @param {Object} cfg Plugin configuration.
145617
+ * @param {String} [cfg.id="lasLoader"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
145618
+ * @param {Object} [cfg.dataSource] A custom data source through which the LASLoaderPlugin can load model and metadata files. Defaults to an instance of {@link LASDefaultDataSource}, which loads uover HTTP.
145619
+ * @param {Number} [cfg.skip=1] Configures LASLoaderPlugin to load every **n** points.
145620
+ * @param {Number} [cfg.fp64=false] Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.
145621
+ * @param {Number} [cfg.colorDepth=8] Configures whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits. Accepted values are 8, 16 an "auto".
145622
+ */
145623
+ constructor(viewer, cfg = {}) {
145624
+
145625
+ super("lasLoader", viewer, cfg);
145626
+
145627
+ this.dataSource = cfg.dataSource;
145628
+ this.skip = cfg.skip;
145629
+ this.fp64 = cfg.fp64;
145630
+ this.colorDepth = cfg.colorDepth;
145631
+ }
145632
+
145633
+ /**
145634
+ * Gets the custom data source through which the LASLoaderPlugin can load LAS files.
145635
+ *
145636
+ * Default value is {@link LASDefaultDataSource}, which loads via HTTP.
145637
+ *
145638
+ * @type {Object}
145639
+ */
145640
+ get dataSource() {
145641
+ return this._dataSource;
145642
+ }
145643
+
145644
+ /**
145645
+ * Sets a custom data source through which the LASLoaderPlugin can load LAS files.
145646
+ *
145647
+ * Default value is {@link LASDefaultDataSource}, which loads via HTTP.
145648
+ *
145649
+ * @type {Object}
145650
+ */
145651
+ set dataSource(value) {
145652
+ this._dataSource = value || new LASDefaultDataSource();
145653
+ }
145654
+
145655
+ /**
145656
+ * When LASLoaderPlugin is configured to load every **n** points, returns the value of **n**.
145657
+ *
145658
+ * Default value is ````1````.
145659
+ *
145660
+ * @returns {Number} The **n**th point that LASLoaderPlugin will read.
145661
+ */
145662
+ get skip() {
145663
+ return this._skip;
145664
+ }
145665
+
145666
+ /**
145667
+ * Configures LASLoaderPlugin to load every **n** points.
145668
+ *
145669
+ * Default value is ````1````.
145670
+ *
145671
+ * @param {Number} value The **n**th point that LASLoaderPlugin will read.
145672
+ */
145673
+ set skip(value) {
145674
+ this._skip = value || 1;
145675
+ }
145676
+
145677
+ /**
145678
+ * Gets if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.
145679
+ *
145680
+ * Default value is ````false````.
145681
+ *
145682
+ * @returns {Boolean} True if LASLoaderPlugin assumes that positions are stored in 64-bit floats instead of 32-bit.
145683
+ */
145684
+ get fp64() {
145685
+ return this._fp64;
145686
+ }
145687
+
145688
+ /**
145689
+ * Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.
145690
+ *
145691
+ * Default value is ````false````.
145692
+ *
145693
+ * @param {Boolean} value True if LASLoaderPlugin assumes that positions are stored in 64-bit floats instead of 32-bit.
145694
+ */
145695
+ set fp64(value) {
145696
+ this._fp64 = !!value;
145697
+ }
145698
+
145699
+ /**
145700
+ * Gets whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits.
145701
+ *
145702
+ * Default value is ````8````.
145703
+ *
145704
+ * Note: LAS specification recommends 16 bits.
145705
+ *
145706
+ * @returns {Number|String} Possible returned values are 8, 16 and "auto".
145707
+ */
145708
+ get colorDepth() {
145709
+ return this._colorDepth;
145710
+ }
145711
+
145712
+ /**
145713
+ * Configures whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits.
145714
+ *
145715
+ * Default value is ````8````.
145716
+ *
145717
+ * Note: LAS specification recommends 16 bits.
145718
+ *
145719
+ * @param {Number|String} value Valid values are 8, 16 and "auto".
145720
+ */
145721
+ set colorDepth(value) {
145722
+ this._colorDepth = !!value;
145723
+ }
145724
+
145725
+ /**
145726
+ * Loads an ````LAS```` model into this LASLoaderPlugin's {@link Viewer}.
145727
+ *
145728
+ * @param {*} params Loading parameters.
145729
+ * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.
145730
+ * @param {String} [params.src] Path to a LAS file, as an alternative to the ````las```` parameter.
145731
+ * @param {ArrayBuffer} [params.las] The LAS file data, as an alternative to the ````src```` parameter.
145732
+ * @param {Number[]} [params.position=[0,0,0]] The model World-space 3D position.
145733
+ * @param {Number[]} [params.scale=[1,1,1]] The model's World-space scale.
145734
+ * @param {Number[]} [params.rotation=[0,0,0]] The model's World-space rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.
145735
+ * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters.
145736
+ * @param {Object} [params.stats] Collects model statistics.
145737
+ * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.
145738
+ */
145739
+ load(params = {}) {
145740
+
145741
+ if (params.id && this.viewer.scene.components[params.id]) {
145742
+ this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
145743
+ delete params.id;
145744
+ }
145745
+
145746
+ const performanceModel = new PerformanceModel(this.viewer.scene, utils.apply(params, {
145747
+ isModel: true,
145748
+ maxGeometryBatchSize: this._maxGeometryBatchSize
145749
+ }));
145750
+
145751
+ if (!params.src && !params.las) {
145752
+ this.error("load() param expected: src or las");
145753
+ return performanceModel; // Return new empty model
145754
+ }
145755
+
145756
+ const options = {
145757
+ skip: this._skip,
145758
+ fp64: this._fp64,
145759
+ colorDepth: this._colorDepth
145760
+ };
145761
+
145762
+ if (params.src) {
145763
+ this._loadModel(params.src, params, options, performanceModel);
145764
+ } else {
145765
+ const spinner = this.viewer.scene.canvas.spinner;
145766
+ spinner.processes++;
145767
+ this._parseModel(params.las, params, options, performanceModel).then(() => {
145768
+ spinner.processes--;
145769
+ }, (errMsg) => {
145770
+ spinner.processes--;
145771
+ this.error(errMsg);
145772
+ performanceModel.fire("error", errMsg);
145773
+ });
145774
+ }
145775
+
145776
+ return performanceModel;
145777
+ }
145778
+
145779
+ _loadModel(src, params, options, performanceModel) {
145780
+ const spinner = this.viewer.scene.canvas.spinner;
145781
+ spinner.processes++;
145782
+ this._dataSource.getLAS(params.src, (arrayBuffer) => {
145783
+ this._parseModel(arrayBuffer, params, options, performanceModel).then(() => {
145784
+ spinner.processes--;
145785
+ }, (errMsg) => {
145786
+ spinner.processes--;
145787
+ this.error(errMsg);
145788
+ performanceModel.fire("error", errMsg);
145789
+ });
145790
+ },
145791
+ (errMsg) => {
145792
+ spinner.processes--;
145793
+ this.error(errMsg);
145794
+ performanceModel.fire("error", errMsg);
145795
+ });
145796
+ }
145797
+
145798
+ _parseModel(arrayBuffer, params, options, performanceModel) {
145799
+
145800
+ return new Promise((resolve, reject) => {
145801
+
145802
+ if (performanceModel.destroyed) {
145803
+ reject();
145804
+ return;
145805
+ }
145806
+
145807
+ const stats = params.stats || {};
145808
+ stats.sourceFormat = "LAS";
145809
+ stats.schemaVersion = "";
145810
+ stats.title = "";
145811
+ stats.author = "";
145812
+ stats.created = "";
145813
+ stats.numMetaObjects = 0;
145814
+ stats.numPropertySets = 0;
145815
+ stats.numObjects = 0;
145816
+ stats.numGeometries = 0;
145817
+ stats.numTriangles = 0;
145818
+ stats.numVertices = 0;
145819
+
145820
+ try {
145821
+ parse(arrayBuffer, LASLoader, options).then((parsedData) => {
145822
+
145823
+ const attributes = parsedData.attributes;
145824
+ const attributesPosition = attributes.POSITION;
145825
+ const attributesColor = attributes.COLOR_0;
145826
+ // const attributesColor_0 = attributes.COLOR_0;
145827
+ const attributesIntensity = attributes.intensity;
145828
+ const attributesClassification = attributes.classification;
145829
+
145830
+ if (!attributesPosition) {
145831
+ performanceModel.finalize();
145832
+ reject("No positions found in file");
145833
+ return;
145834
+ }
145835
+
145836
+ const positionsValue = attributesPosition.value;
145837
+
145838
+ if (params.rotateX) {
145839
+ if (positionsValue) {
145840
+ for (let i = 0, len = positionsValue.length; i < len; i += 3) {
145841
+ const temp = positionsValue[i + 1];
145842
+ positionsValue[i + 1] = positionsValue[i + 2];
145843
+ positionsValue[i + 2] = temp;
145844
+ }
145845
+ }
145846
+ }
145847
+
145848
+ let colorsCompressed = null;
145849
+
145850
+ if (attributesColor) {
145851
+ colorsCompressed = attributesColor.value;
145852
+ } else {
145853
+
145854
+ }
145855
+
145856
+ if (attributesIntensity) {
145857
+ const intensities = attributesIntensity.value;
145858
+ colorsCompressed = new Uint8Array(intensities.length * 4);
145859
+
145860
+ if (attributesColor) { // Intensities with colors
145861
+ const colors = attributesColor.value;
145862
+ const colorsSize = attributesColor.size;
145863
+ for (let i = 0, j = 0, len = intensities.length; i < len; i++, j += 4) {
145864
+ const intensity = Math.round((intensities[i] / 65536) * 255); // FIXME: Precision loss converting intensity from 16 to 8 bits
145865
+ colorsCompressed[j + 0] = colors[i * colorsSize];
145866
+ colorsCompressed[j + 1] = colors[i * colorsSize + 1];
145867
+ colorsCompressed[j + 2] = colors[i * colorsSize + 2];
145868
+ colorsCompressed[j + 3] = intensity;
145869
+ }
145870
+ } else { // Intensities without colors
145871
+ for (let i = 0, j = 0, len = intensities.length; i < len; i++, j += 4) {
145872
+ const intensity = Math.round((intensities[i] / 65536) * 255);
145873
+ colorsCompressed[j + 0] = 125; // Gray
145874
+ colorsCompressed[j + 1] = 125;
145875
+ colorsCompressed[j + 2] = 125;
145876
+ colorsCompressed[j + 3] = intensity;
145877
+ }
145878
+ }
145879
+ } else if (attributesColor) { // Colors without intensities
145880
+ const colors = attributesColor.value;
145881
+ const colorsSize = attributesColor.size;
145882
+ for (let i = 0, j = 0, len = colors.length / colorsSize; i < len; i++, j += 4) {
145883
+ colorsCompressed[j + 0] = colors[i * colorsSize];
145884
+ colorsCompressed[j + 1] = colors[i * colorsSize + 1];
145885
+ colorsCompressed[j + 2] = colors[i * colorsSize + 2];
145886
+ colorsCompressed[j + 3] = (colorsSize === 4) ? colors[i * colorsSize + 3] : 255;
145887
+ }
145888
+ }
145889
+
145890
+ performanceModel.createMesh({
145891
+ id: "pointsMesh",
145892
+ primitive: "points",
145893
+ positions: positionsValue,
145894
+ colorsCompressed
145895
+ });
145896
+
145897
+ performanceModel.createEntity({
145898
+ id: math.createUUID(),
145899
+ meshIds: ["pointsMesh"],
145900
+ isObject: true
145901
+ });
145902
+
145903
+ performanceModel.finalize();
145904
+
145905
+ // TODO: Create metamodel
145906
+
145907
+
145908
+ performanceModel.scene.once("tick", () => {
145909
+ if (performanceModel.destroyed) {
145910
+ return;
145911
+ }
145912
+ performanceModel.scene.fire("modelLoaded", performanceModel.id); // FIXME: Assumes listeners know order of these two events
145913
+ performanceModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
145914
+ });
145915
+
145916
+ resolve();
145917
+ });
145918
+ } catch (e) {
145919
+ performanceModel.finalize();
145920
+ reject(e);
145921
+ }
145922
+ });
145923
+ }
145924
+ }
145925
+
145926
+ export { AmbientLight, AngleMeasurementsPlugin, AnnotationsPlugin, AxisGizmoPlugin, BCFViewpointsPlugin, CameraMemento, CameraPath, CameraPathAnimation, Component, Configs, ContextMenu, CubicBezierCurve, Curve, DirLight, DistanceMeasurementsPlugin, EdgeMaterial, EmphasisMaterial, FastNavPlugin, Fresnel, GLTFDefaultDataSource, GLTFLoaderPlugin, IFCLoaderPlugin, ImagePlane, LASLoaderPlugin, LambertMaterial, LightMap, LocaleService, Map$1 as Map, Marker, Mesh, MetallicMaterial, ModelMemento, NavCubePlugin, Node, OBJLoaderPlugin, ObjectsMemento, Path, PerformanceModel, PhongMaterial, Plugin, PointLight, QuadraticBezierCurve, Queue, ReadableGeometry, ReflectionMap, STLDefaultDataSource, STLLoaderPlugin, SectionPlane, SectionPlanesPlugin, Skybox, SkyboxesPlugin, SpecularMaterial, SplineCurve, SpriteMarker, StoreyViewsPlugin, Texture, TreeViewPlugin, VBOGeometry, ViewCullPlugin, Viewer, XKTDefaultDataSource, XKTLoaderPlugin, XML3DLoaderPlugin, buildBoxGeometry, buildBoxLinesGeometry, buildCylinderGeometry, buildGridGeometry, buildPlaneGeometry, buildSphereGeometry, buildTorusGeometry, buildVectorTextGeometry, load3DSGeometry, loadOBJGeometry, math, utils };