@lumiscaphe/viewer 4.2.2 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/index.js CHANGED
@@ -1,1778 +1,1688 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".ls-viewer-container{display:block;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;width:100%;height:100%}.ls-viewer-container-image,.ls-viewer-container-video{cursor:default;pointer-events:none}.ls-viewer-container-vrcube{cursor:pointer;cursor:grab}.ls-viewer-container-vrcube-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-vrobject{cursor:move;cursor:grab}.ls-viewer-container-vrobject-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-loading{cursor:progress}.ls-viewer-canvas{position:absolute;opacity:0;transition:opacity .5s}.ls-viewer-video{position:absolute}")),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
2
- import V from "debounce-promise";
3
- import * as M from "twgl.js";
4
- import { v3 as h, m4 as c } from "twgl.js";
5
- import U from "regression";
6
- class y {
7
- constructor(t, e) {
8
- this.width = t, this.height = e;
9
- }
10
- get aspect() {
11
- return this.width / this.height;
12
- }
13
- }
14
- const P = class P {
15
- constructor(t, e, i, s) {
16
- this.top = t, this.left = e, this.width = i, this.height = s;
17
- }
18
- static contains(t, e) {
19
- return e.x >= 0 && e.x < t.width && e.y >= 0 && e.y < t.height;
20
- }
21
- static fit(t, e, i) {
22
- const s = t.aspect, r = e.aspect;
23
- let a = 0, n = 0;
24
- switch (i) {
25
- case "contain":
26
- a = r < s ? e.width : e.height * s, n = r < s ? e.width / s : e.height;
27
- break;
28
- case "cover":
29
- default:
30
- a = r < s ? e.height * s : e.width, n = r < s ? e.height : e.width / s;
31
- break;
32
- case "fill":
33
- a = e.width, n = e.height;
34
- break;
35
- }
36
- const o = (e.height - n) / 2, u = (e.width - a) / 2;
37
- return new P(o, u, a, n);
38
- }
39
- static project(t, e, i, s) {
40
- const r = P.fit(t, e, i), a = r.width / t.width, n = r.height / t.height;
41
- return {
42
- x: Math.round(r.left + s.x * a),
43
- y: Math.round(r.top + s.y * n)
44
- };
45
- }
46
- static unproject(t, e, i, s) {
47
- const r = P.fit(t, e, i), a = r.width / t.width, n = r.height / t.height;
48
- return {
49
- x: Math.round((s.x - r.left) / a),
50
- y: Math.round((s.y - r.top) / n)
51
- };
52
- }
53
- static getStandardAspectRatio(t, e, i) {
54
- if (t === 0 || e === 0)
55
- return 0;
56
- if (i)
57
- return i;
58
- const s = t / e;
59
- return t < e ? s < P.PORTRAIT_ASPECT_BOUNDARY ? 9 / 16 : 3 / 4 : s < P.LANDSCAPE_ASPECT_BOUNDARY ? 4 / 3 : 16 / 9;
60
- }
61
- static getStandardResolution(t, e, i) {
62
- if (t === 0 || e === 0)
63
- return new y(0, 0);
64
- const s = P.getStandardAspectRatio(t, e, i);
65
- if (i) {
66
- const a = P.getStandardQuality(Math.min(t, e));
67
- return new y(Math.round(a * s), Math.round(a));
68
- }
69
- if (t < e) {
70
- const a = P.getStandardQuality(Math.max(e * s, t));
71
- return new y(Math.round(a), Math.round(a / s));
72
- }
73
- const r = P.getStandardQuality(Math.max(t / s, e));
74
- return new y(Math.round(r * s), Math.round(r));
75
- }
76
- static getStandardQuality(t) {
77
- return t <= 720 ? 720 : 1080;
78
- }
79
- };
80
- P.LANDSCAPE_ASPECT_BOUNDARY = Math.sqrt(4 / 3 * (16 / 9)), P.PORTRAIT_ASPECT_BOUNDARY = Math.sqrt(3 / 4 * (9 / 16));
81
- let b = P;
82
- class N {
83
- constructor(t) {
84
- this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = this.element.getContext("2d"), this.context.imageSmoothingQuality = "high", this.backCanvas = document.createElement("canvas"), this.backContext = this.backCanvas.getContext("2d"), this.backContext.imageSmoothingQuality = "high", this.fit = t;
85
- }
86
- destroy() {
87
- this.requestAnimationId && (cancelAnimationFrame(this.requestAnimationId), this.requestAnimationId = void 0);
88
- }
89
- show(t) {
90
- t ? this.element.style.display = "block" : this.element.style.opacity = "1";
91
- }
92
- hide(t) {
93
- t ? this.element.style.display = "none" : this.element.style.opacity = "0";
94
- }
95
- resize(t, e, i) {
96
- const s = Math.floor(t * i), r = Math.floor(e * i);
97
- this.element.style.width = `${t}px`, this.element.style.height = `${e}px`, !(this.element.width === s && this.element.height === r) && (this.element.width = s, this.element.height = r, this.context.imageSmoothingQuality = "high", this.backCanvas.width = s, this.backCanvas.height = r, this.backContext.imageSmoothingQuality = "high", this.image && this.draw(this.image, !1));
98
- }
99
- draw(t, e, i) {
100
- if (!t)
101
- return;
102
- this.requestAnimationId && (cancelAnimationFrame(this.requestAnimationId), this.requestAnimationId = void 0);
103
- const s = b.fit(new y(t.width, t.height), new y(this.element.width, this.element.height), this.fit);
104
- e ? (this.backContext.drawImage(this.element, 0, 0), this.context.globalAlpha = 0, this.fadeLoop(t, i || 0)) : (this.context.globalAlpha = 1, this.context.drawImage(t, s.left, s.top, s.width, s.height)), this.image = t;
105
- }
106
- fadeLoop(t, e) {
107
- if (this.context.globalAlpha >= 1) {
108
- cancelAnimationFrame(this.requestAnimationId), this.requestAnimationId = void 0;
109
- return;
110
- }
111
- const i = Math.min(this.context.globalAlpha + e, 1), s = b.fit(new y(t.width, t.height), new y(this.element.width, this.element.height), this.fit);
112
- this.context.clearRect(0, 0, this.element.width, this.element.height), this.context.globalAlpha = 1, this.context.drawImage(this.backCanvas, 0, 0), this.context.globalAlpha = i, this.context.drawImage(t, s.left, s.top, s.width, s.height), this.requestAnimationId = requestAnimationFrame(() => {
113
- this.fadeLoop(t, e);
114
- });
115
- }
116
- }
117
- class B {
118
- constructor() {
119
- this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = M.getContext(this.element, { preserveDrawingBuffer: !0 }), this.context && this.context.isContextLost() && (this.context = void 0), M.setDefaults({ textureColor: [1, 1, 1, 1] });
120
- }
121
- show() {
122
- this.element.style.opacity = "1";
123
- }
124
- hide() {
125
- this.element.style.opacity = "0";
126
- }
127
- resize(t, e, i) {
128
- this.element.width = t * i, this.element.height = e * i, this.element.style.width = `${t}px`, this.element.style.height = `${e}px`;
129
- }
130
- }
131
- class w {
132
- static accelerate(t, e) {
133
- const i = e || 1.5;
134
- return Math.abs(t) ** i * (t > 0 ? 1 : -1);
135
- }
136
- static clamp(t, e, i) {
137
- return Math.max(Math.min(t, i), e);
138
- }
139
- static degreesToRadians(t) {
140
- return t * (Math.PI / 180);
141
- }
142
- static radiansToDegrees(t) {
143
- return t * (180 / Math.PI);
144
- }
145
- static mod(t, e) {
146
- return t - e * Math.floor(t / e);
147
- }
148
- static perspectiveWithFovX(t, e, i, s, r) {
149
- const a = Math.tan(t / 2), n = a / e;
150
- return this.perspectiveWithLeft(-a, a, -n, n, i, s, r);
151
- }
152
- static perspectiveWithFovY(t, e, i, s, r) {
153
- const a = i * Math.tan(t / 2), n = a * e;
154
- return this.perspectiveWithLeft(-n, n, -a, a, i, s, r);
155
- }
156
- static perspectiveWithLeft(t, e, i, s, r, a, n) {
157
- n = n || new Float32Array(16);
158
- const o = e + t, u = e - t, l = s + i, p = s - i, d = a - r;
159
- return n[0] = 2 * r / u, n[1] = 0, n[2] = 0, n[3] = 0, n[4] = 0, n[5] = 2 * r / p, n[6] = 0, n[7] = 0, n[8] = o / u, n[9] = l / p, n[10] = -a / d, n[11] = -1, n[12] = 0, n[13] = 0, n[14] = -a * r / d, n[15] = 0, n;
160
- }
161
- }
162
- const O = class O {
163
- static initCubeFace(t, e, i) {
164
- let s = [0, 0, 0];
165
- const r = h.subtract(e, t), a = h.mulScalar([0, 1, 0], h.length(r)), n = h.mulScalar(h.normalize(h.cross(r, a)), h.length(r)), o = h.mulScalar(h.normalize(h.cross(a, n)), h.length(r));
166
- switch (i) {
167
- case "front":
168
- e = h.add(t, o), s = h.normalize(a);
169
- break;
170
- case "right":
171
- e = h.add(t, n), s = h.normalize(a);
172
- break;
173
- case "back":
174
- e = h.subtract(t, o), s = h.normalize(a);
175
- break;
176
- case "left":
177
- e = h.subtract(t, n), s = h.normalize(a);
178
- break;
179
- case "up":
180
- e = h.add(t, a), s = h.normalize(h.mulScalar(o, -1));
181
- break;
182
- case "down":
183
- e = h.subtract(t, a), s = h.normalize(o);
184
- break;
185
- }
186
- return new O(e, t, s);
187
- }
188
- constructor(t, e, i) {
189
- this.target = h.copy(t), this.eye = h.copy(e), this.up = h.copy(i);
190
- }
191
- get viewVector() {
192
- return h.subtract(this.target, this.eye);
193
- }
194
- get rightVector() {
195
- return h.normalize(h.cross(this.viewVector, this.up));
196
- }
197
- get viewMatrix() {
198
- return c.inverse(c.lookAt(this.eye, this.target, this.up));
199
- }
200
- clone() {
201
- return new O(h.copy(this.target), h.copy(this.eye), h.copy(this.up));
202
- }
203
- };
204
- O.default = new O([0, 0, 0], [2, 2, 2], [0, 1, 0]);
205
- let S = O;
206
- class X {
207
- constructor(t) {
208
- this.target = t.target;
209
- const e = h.normalize(h.subtract(t.eye, t.target)), i = h.dot(e, [1, 0, 0]), s = h.dot(e, [0, 1, 0]), r = h.dot(e, [0, 0, 1]);
210
- this.longitude = Math.atan2(i, r), this.latitude = Math.atan2(s, Math.sqrt(i * i + r * r)), h.dot(t.up, [0, 1, 0]) < 0 && (this.longitude = Math.PI + this.longitude, this.latitude = Math.PI - this.latitude), this.distance = h.length(h.subtract(t.target, t.eye));
211
- }
212
- get vector() {
213
- const t = Math.cos(this.latitude) * this.distance, e = Math.sin(this.latitude) * this.distance, i = Math.cos(this.longitude) * t, s = Math.sin(this.longitude) * t;
214
- return [i, e, s];
215
- }
216
- pointOfView(t) {
217
- const e = c.rotationY(this.longitude), i = c.rotationX(-this.latitude), s = c.rotationZ(0), r = c.multiply(e, c.multiply(i, s));
218
- let a = [0, 0, -1];
219
- a = c.transformPoint(r, a);
220
- let n = [0, 1, 0];
221
- n = c.transformPoint(r, n);
222
- const o = h.subtract(t, h.mulScalar(a, this.distance));
223
- return new S(t, o, n);
224
- }
225
- }
226
- class Y {
227
- constructor() {
228
- }
229
- async animation(t) {
230
- return t.scene;
231
- }
232
- async database(t) {
233
- throw new Error("Unavailable");
234
- }
235
- async image(t) {
236
- return t.scene;
237
- }
238
- async video(t) {
239
- return t.scene;
240
- }
241
- async vrCube(t) {
242
- return t.scene;
243
- }
244
- async vrObject(t) {
245
- return t.scene;
246
- }
247
- }
248
- class H {
249
- constructor(t) {
250
- this.xmlDoc = t;
251
- }
252
- get id() {
253
- return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id");
254
- }
255
- getCameraId(t, e) {
256
- return e ? this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id") : this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id");
257
- }
258
- getCameraById(t, e) {
259
- let i;
260
- return t && e ? i = this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`) : i = this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`), i ? this.mapElementToCamera(i) : null;
261
- }
262
- getCameraByName(t, e) {
263
- let i;
264
- return e && t ? i = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`) : i = this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`), i ? this.mapElementToCamera(i) : null;
265
- }
266
- getCameraGroupId(t) {
267
- return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id");
268
- }
269
- getCameraGroupById(t) {
270
- const e = this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);
271
- return e ? this.mapElementToCameraGroup(e) : null;
272
- }
273
- getCameraGroupByName(t) {
274
- const e = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);
275
- return e ? this.mapElementToCameraGroup(e) : null;
276
- }
277
- mapElementToCamera(t) {
278
- return {
279
- id: t.getAttribute("id"),
280
- name: t.getAttribute("name"),
281
- pointOfView: new S(
282
- [
283
- parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),
284
- //
285
- parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),
286
- parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))
287
- ],
288
- [
289
- parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),
290
- //
291
- parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),
292
- parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))
293
- ],
294
- [
295
- parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),
296
- //
297
- parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),
298
- parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))
299
- ]
300
- )
301
- };
302
- }
303
- mapElementToCameraGroup(t) {
304
- return {
305
- id: t.getAttribute("id"),
306
- name: t.getAttribute("name"),
307
- cameras: [...t.querySelectorAll("Camera")].map((e) => this.mapElementToCamera(e))
308
- };
309
- }
310
- }
311
- const g = class g {
312
- constructor(t) {
313
- this.server = t;
314
- }
315
- static buildQuery(t) {
316
- return Object.entries(t).filter(([e, i]) => i != null).map(([e, i]) => `${e}=${i}`).join("&");
317
- }
318
- static sceneParameters(t) {
319
- const e = t.scene, i = e.length > 1 ? e.find((a) => a.accessory) : null, s = e.length > 1 ? e.find((a) => a.decor) : null, r = e.find((a) => a !== i && a !== s);
320
- return {
321
- databaseId: r.database,
322
- configuration: r?.configuration,
323
- animations: r?.animations?.join("/"),
324
- accessoryDatabaseId: i?.database,
325
- decorDatabaseId: s?.database,
326
- decorDeltaAltitude: s?.translation?.y
327
- };
328
- }
329
- static renderParameters(t) {
330
- const { parameters: e, view: i } = t;
331
- return {
332
- background: i.background,
333
- width: e.width,
334
- height: e.height,
335
- softwareAntialiasing: e.antialiasing,
336
- superSampling: e.superSampling
337
- };
338
- }
339
- static encoderParameters(t) {
340
- const { encoder: e } = t;
341
- return {
342
- imageFormat: e.format,
343
- imageQuality: e.quality
344
- };
345
- }
346
- static async fetch(t) {
347
- return fetch(t).then((e) => e.text()).then((e) => {
348
- const s = e.replace(/&amp;/g, "&").match(this.xmlRegex);
349
- return s ? s.map((r) => r.replace(this.xmlRegex, "$1")) : Promise.reject();
350
- });
351
- }
352
- async animation(t) {
353
- const e = {
354
- ...g.sceneParameters(t),
355
- animation: t.view.animation,
356
- bookmarkSet: t.view.camera.split("/")[0],
357
- bookmark: t.view.camera.split("/")[1],
358
- frames: t.view.frames,
359
- loop: !!t.view.loop,
360
- ...g.renderParameters(t),
361
- ...g.encoderParameters(t)
362
- }, i = g.buildQuery(e);
363
- return g.fetch(`${this.server}/ImagesFromAnimation?${i}`);
364
- }
365
- async database(t) {
366
- return fetch(`${this.server}/Database?databaseId=${t}`).then((e) => e.text()).then((e) => {
367
- const i = new DOMParser().parseFromString(e, "application/xml");
368
- return new H(i);
369
- });
370
- }
371
- async image(t) {
372
- const e = {
373
- ...g.sceneParameters(t),
374
- bookmarkSet: t.view.camera.split("/")[0],
375
- bookmark: t.view.camera.split("/")[1],
376
- ...g.renderParameters(t),
377
- ...g.encoderParameters(t)
378
- }, i = g.buildQuery(e);
379
- return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`);
380
- }
381
- async video(t) {
382
- const e = {
383
- ...g.sceneParameters(t),
384
- animation: t.view.animation,
385
- bookmarkSet: t.view.camera.split("/")[0],
386
- bookmark: t.view.camera.split("/")[1],
387
- duration: t.view.duration,
388
- frames: t.view.frames,
389
- loop: !!t.view.loop,
390
- reverse: !!t.view.reverse,
391
- ...g.renderParameters(t),
392
- ...g.encoderParameters(t)
393
- }, i = g.buildQuery(e);
394
- return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`);
395
- }
396
- async vrCube(t) {
397
- const e = {
398
- ...g.sceneParameters(t),
399
- bookmarkSet: t.view.camera.split("/")[0],
400
- bookmark: t.view.camera.split("/")[1],
401
- ...g.renderParameters(t),
402
- ...g.encoderParameters(t)
403
- };
404
- e.width = Math.max(e.width, e.height), e.height = Math.max(e.width, e.height);
405
- const i = g.buildQuery(e);
406
- return g.fetch(`${this.server}/CubeFromBookmark?${i}`);
407
- }
408
- async vrObject(t) {
409
- const e = {
410
- ...g.sceneParameters(t),
411
- bookmarkSet: t.view.camera,
412
- ...g.renderParameters(t),
413
- ...g.encoderParameters(t)
414
- }, i = g.buildQuery(e);
415
- return g.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`);
416
- }
417
- };
418
- g.xmlRegex = /directUrl="([^"]*)"/g;
419
- let F = g;
420
- class m {
421
- constructor(t) {
422
- this.server = t;
423
- }
424
- static scene(t) {
425
- return t.scene.map((e) => {
426
- const { accessory: i, decor: s, ...r } = e;
427
- return r;
428
- });
429
- }
430
- static renderParameters(t) {
431
- return {
432
- ...t.parameters,
433
- superSampling: t.parameters.superSampling.toString()
434
- };
435
- }
436
- static encoder(t) {
437
- switch (t.encoder.format) {
438
- case "jpeg":
439
- return {
440
- jpeg: {
441
- quality: t.encoder.quality
442
- }
443
- };
444
- case "png":
445
- return {
446
- png: {
447
- compression: t.encoder.compression
448
- }
449
- };
450
- case "webp":
451
- return {
452
- webp: {
453
- quality: t.encoder.quality
454
- }
455
- };
456
- }
457
- return {
458
- jpeg: {
459
- quality: 80
460
- }
461
- };
462
- }
463
- static async fetchFrame(t, e) {
464
- return fetch(t, { method: "POST", body: JSON.stringify(e) }).then((i) => i.json()).then((i) => i.url);
465
- }
466
- static async fetchFrameArray(t, e) {
467
- return fetch(t, { method: "POST", body: JSON.stringify(e) }).then((i) => i.json()).then((i) => i.map((s) => s.url));
468
- }
469
- static async fetchHotspots(t, e) {
470
- return fetch(t, { method: "POST", body: JSON.stringify(e) }).then((i) => i.json());
471
- }
472
- static async fetchHotspotsArray(t, e) {
473
- return fetch(t, { method: "POST", body: JSON.stringify(e) }).then((i) => i.json());
474
- }
475
- static async fetchPick(t, e) {
476
- return fetch(t, { method: "POST", body: JSON.stringify(e) }).then((i) => i.json()).then((i) => i[0]);
477
- }
478
- async database(t) {
479
- return fetch(`${this.server}/Database?databaseId=${t}`).then((e) => e.text()).then((e) => {
480
- const i = new DOMParser().parseFromString(e, "application/xml");
481
- return new H(i);
482
- });
483
- }
484
- async image(t) {
485
- const e = {
486
- scene: m.scene(t),
487
- mode: {
488
- image: {
489
- camera: t.view.camera
490
- }
491
- },
492
- renderParameters: m.renderParameters(t),
493
- encoder: m.encoder(t)
494
- };
495
- return m.fetchFrame(`${this.server}/Snapshot`, e);
496
- }
497
- async vrCube(t) {
498
- const e = {
499
- scene: m.scene(t),
500
- mode: {
501
- vrCube: {
502
- camera: t.view.camera
503
- }
504
- },
505
- renderParameters: m.renderParameters(t),
506
- encoder: m.encoder(t)
507
- };
508
- return e.renderParameters.width = Math.max(e.renderParameters.width, e.renderParameters.height), e.renderParameters.height = Math.max(e.renderParameters.width, e.renderParameters.height), m.fetchFrameArray(`${this.server}/Snapshot`, e);
509
- }
510
- async vrObject(t) {
511
- let e;
512
- t.view.cameraGroup ? e = {
513
- images: {
514
- cameraGroup: t.view.cameraGroup
515
- }
516
- } : t.view.frames ? e = {
517
- vrObject: {
518
- camera: t.view.camera,
519
- frames: t.view.frames
520
- }
521
- } : e = {
522
- vrObject: {
523
- camera: t.view.camera,
524
- panFrames: t.view.panFrames || 1,
525
- panFrom: t.view.panFrom || 0,
526
- panTo: t.view.panTo || 0,
527
- panLoop: t.view.panLoop || !1,
528
- tiltFrames: t.view.tiltFrames || 1,
529
- tiltFrom: t.view.tiltFrom || 0,
530
- tiltTo: t.view.tiltTo || 0,
531
- tiltLoop: t.view.tiltLoop || !1
532
- }
533
- };
534
- const i = {
535
- scene: m.scene(t),
536
- mode: e,
537
- renderParameters: m.renderParameters(t),
538
- encoder: m.encoder(t)
539
- };
540
- return m.fetchFrameArray(`${this.server}/Snapshot`, i);
541
- }
542
- async animation(t) {
543
- const e = {
544
- scene: m.scene(t),
545
- mode: {
546
- animation: {
547
- id: t.view.animation,
548
- camera: t.view.camera,
549
- fps: t.view.fps
550
- }
551
- },
552
- renderParameters: m.renderParameters(t),
553
- encoder: m.encoder(t)
554
- };
555
- return m.fetchFrameArray(`${this.server}/Snapshot`, e);
556
- }
557
- async imageHotspots(t, e) {
558
- const i = {
559
- scene: m.scene(t),
560
- mode: {
561
- image: {
562
- camera: t.view.camera
563
- }
564
- },
565
- renderParameters: m.renderParameters(t),
566
- ...this.hotspotsBody(e)
567
- };
568
- return await m.fetchHotspots(`${this.server}/Hotspot`, i);
569
- }
570
- async imagePick(t, e) {
571
- const i = {
572
- scene: m.scene(t),
573
- camera: t.view.camera,
574
- renderParameters: m.renderParameters(t),
575
- positions: [e]
576
- };
577
- return await m.fetchPick(`${this.server}/Pick`, i);
578
- }
579
- async vrCubeHotspots(t, e) {
580
- const i = {
581
- scene: m.scene(t),
582
- mode: {
583
- vrCube: {
584
- camera: t.view.camera
585
- }
586
- },
587
- renderParameters: m.renderParameters(t),
588
- ...this.hotspotsBody(e)
589
- };
590
- return i.renderParameters.width = Math.max(i.renderParameters.width, i.renderParameters.height), i.renderParameters.height = Math.max(i.renderParameters.width, i.renderParameters.height), await m.fetchHotspotsArray(`${this.server}/Hotspot`, i);
591
- }
592
- async vrObjectHotspots(t, e) {
593
- let i;
594
- t.view.cameraGroup ? i = {
595
- images: {
596
- cameraGroup: t.view.cameraGroup
597
- }
598
- } : t.view.frames ? i = {
599
- vrObject: {
600
- camera: t.view.camera,
601
- frames: t.view.frames
602
- }
603
- } : i = {
604
- vrObject: {
605
- camera: t.view.camera,
606
- panFrames: t.view.panFrames || 1,
607
- panFrom: t.view.panFrom || 0,
608
- panTo: t.view.panTo || 0,
609
- panLoop: t.view.panLoop || !1,
610
- tiltFrames: t.view.tiltFrames || 1,
611
- tiltFrom: t.view.tiltFrom || 0,
612
- tiltTo: t.view.tiltTo || 0,
613
- tiltLoop: t.view.tiltLoop || !1
614
- }
615
- };
616
- const s = {
617
- scene: m.scene(t),
618
- mode: i,
619
- renderParameters: m.renderParameters(t),
620
- ...this.hotspotsBody(e)
621
- };
622
- return await m.fetchHotspotsArray(`${this.server}/Hotspot`, s);
623
- }
624
- hotspotsBody(t) {
625
- return {
626
- positions: t.every((e) => typeof e != "string") ? t : void 0,
627
- tags: t.every((e) => typeof e == "string") ? t : void 0
628
- };
629
- }
630
- }
631
- class D {
632
- constructor(t, e, i) {
633
- switch (e) {
634
- case "static":
635
- this.webrender = new Y();
636
- break;
637
- case "v1":
638
- this.webrender = new F(t), this.webrenderV2 = new m(t);
639
- break;
640
- case "v2":
641
- this.webrender = new m(t), this.webrenderV2 = new m(t);
642
- break;
643
- default:
644
- this.webrender = new F(t), this.webrenderV2 = new m(t);
645
- break;
646
- }
647
- this.delegate = i, this.loadingId = 0, this.loaded = 0, this.total = 0, this.databases = [], this.onLoadStart = i && i.onLoadStart ? i.onLoadStart : () => {
648
- }, this.onLoadProgress = i && i.onLoadProgress ? i.onLoadProgress : () => {
649
- }, this.onLoadEnd = i && i.onLoadEnd ? i.onLoadEnd : () => {
650
- };
651
- }
652
- get progress() {
653
- return this.total ? this.loaded / this.total : 0;
654
- }
655
- async loadImageSnapshot(t) {
656
- this.loadingId += 1, this.loaded = 0, this.total = 1, this.onLoadStart(this.progress);
657
- const { loadingId: e } = this;
658
- return this.webrender.image(t).then((i) => this.loadImage(i, e)).then((i) => (this.onLoadEnd(this.progress), i));
659
- }
660
- async loadVideoSnapshot(t, e) {
661
- this.loadingId += 1, this.loaded = 0, this.total = 1, this.onLoadStart(this.progress);
662
- const { loadingId: i } = this;
663
- return this.webrender.video(e).then((s) => this.loadVideo(t, s, !!e.view.loop, i)).then(() => (this.onLoadEnd(this.progress), t));
664
- }
665
- async loadVRCubeSnapshot(t) {
666
- this.loadingId += 1, this.loaded = 0, this.total = 0, this.onLoadStart(this.progress);
667
- const { loadingId: e } = this;
668
- return this.webrender.vrCube(t).then((i) => {
669
- this.total = i.length;
670
- const s = i.map((r) => this.loadImage(r, e));
671
- return Promise.all(s);
672
- }).then((i) => (this.onLoadEnd(this.progress), i));
673
- }
674
- async loadVRObjectSnapshot(t, e) {
675
- this.loadingId += 1, this.loaded = 0, this.total = 0, this.onLoadStart(this.progress);
676
- const { loadingId: i } = this;
677
- return t.view.animation ? t.encoder?.format === "mp4" ? this.webrender.video(t).then((s) => this.loadVideoFrames(s, t.view.frames, 30, i)) : this.webrender.animation(t).then((s) => this.loadImageFrames(s, t.view.loop, e, i)) : this.webrender.vrObject(t).then((s) => this.loadImageFrames(s, t.view.loop, e, i));
678
- }
679
- async loadImage(t, e) {
680
- const i = new Image();
681
- i.crossOrigin = location.protocol === "file:" && !D.isValidHttpUrl(t) ? null : "anonymous";
682
- const s = new Promise((r, a) => {
683
- i.addEventListener(
684
- "load",
685
- () => {
686
- e === this.loadingId && (this.loaded += 1, this.onLoadProgress(this.progress), r(i));
687
- },
688
- { once: !0 }
689
- ), i.addEventListener(
690
- "error",
691
- (n) => {
692
- e === this.loadingId && a(`${n.type} : ${t}`);
693
- },
694
- { once: !0 }
695
- );
696
- });
697
- return i.src = t, s;
698
- }
699
- loadImageFrames(t, e, i, s) {
700
- this.total = t.length;
701
- const r = new Array(t.length), a = i || 0;
702
- for (let n = 0, o = t.length; n < o; n += 1) {
703
- const u = Math.ceil(n / 2) * (n % 2 === 0 ? 1 : -1), l = e ? w.mod(a + u, o) : n;
704
- r[l] = this.loadImage(t[l], s);
705
- }
706
- return Promise.all(r).then(() => this.onLoadEnd(this.progress)).catch(() => {
707
- }), r;
708
- }
709
- async loadVideo(t, e, i, s) {
710
- t.loop = i;
711
- const r = new Promise((a, n) => {
712
- t.addEventListener(
713
- "canplaythrough",
714
- () => {
715
- s === this.loadingId && (this.loaded += 1, this.onLoadProgress(this.progress), a());
716
- },
717
- { once: !0 }
718
- ), t.addEventListener(
719
- "error",
720
- (o) => {
721
- s === this.loadingId && n(`${o.type} : ${e}`);
722
- },
723
- { once: !0 }
724
- );
725
- });
726
- return t.src = e, t.load(), r;
727
- }
728
- async loadVideoFrame(t, e, i, s, r) {
729
- let a = 0;
730
- return new Promise((n, o) => {
731
- const u = () => {
732
- if (r !== this.loadingId) return;
733
- if (a !== s) {
734
- a += 1;
735
- return;
736
- }
737
- t.removeEventListener("seeked", u);
738
- const l = document.createElement("canvas");
739
- l.width = t.videoWidth, l.height = t.videoHeight, l.getContext("2d").drawImage(t, 0, 0);
740
- const d = new Image();
741
- d.src = l.toDataURL(), n(d), this.loaded += 1, this.onLoadProgress(this.progress), s !== i - 1 && (t.currentTime += 1 / e);
742
- };
743
- t.addEventListener("seeked", u), t.addEventListener(
744
- "error",
745
- (l) => {
746
- r === this.loadingId && o(l);
747
- },
748
- { once: !0 }
749
- );
750
- });
751
- }
752
- loadVideoFrames(t, e, i, s) {
753
- this.total = e;
754
- const r = new Array(e), a = document.createElement("video");
755
- for (let n = 0, o = e; n < o; n += 1)
756
- r[n] = this.loadVideoFrame(a, i, e, n, s);
757
- return a.addEventListener(
758
- "canplaythrough",
759
- () => {
760
- s === this.loadingId && (a.currentTime = 1 / i / 2);
761
- },
762
- { once: !0 }
763
- ), a.src = t, a.load(), Promise.all(r).then(() => this.onLoadEnd(this.progress)).catch(() => {
764
- }), r;
765
- }
766
- async loadImageHotspots(t, e) {
767
- return this.webrenderV2 ? await this.webrenderV2.imageHotspots(await this.convert(t), e) : Promise.reject(new Error("Hotspots only available with api V2"));
768
- }
769
- async loadVRCubeHotspots(t, e) {
770
- return this.webrenderV2 ? await this.webrenderV2.vrCubeHotspots(await this.convert(t), e) : Promise.reject(new Error("Hotspots only available with api V2"));
771
- }
772
- async loadVRObjectHotspots(t, e) {
773
- return this.webrenderV2 ? await this.webrenderV2.vrObjectHotspots(await this.convert(t), e) : Promise.reject(new Error("Hotspots only available with api V2"));
774
- }
775
- async loadImagePick(t, e) {
776
- return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.convert(t), e) : Promise.reject(new Error("Picking only available with api V2"));
777
- }
778
- async loadVRObjectPick(t, e, i, s) {
779
- return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t, i, s), e) : Promise.reject(new Error("Picking only available with api V2"));
780
- }
781
- async loadVRCubePick(t, e, i) {
782
- return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t, i), e) : Promise.reject(new Error("Picking only available with api V2"));
783
- }
784
- async convert(t) {
785
- if (!this.webrenderV2 || this.webrender instanceof m || !t.view.camera)
786
- return t;
787
- const e = t.scene.find((o) => !o.decor && !o.accessory);
788
- if (!e)
789
- return t;
790
- let i = this.databases.find((o) => o.id === e.database);
791
- (!i || !i.xmlDoc) && (i = await this.webrender.database(e.database), this.databases.push(i));
792
- const s = t.view.camera.split("/"), r = s.length === 2 ? s[0] : void 0, a = s.length === 2 ? s[1] : s[0], n = i.getCameraId(a, r);
793
- if (n)
794
- return { ...t, view: { ...t.view, camera: n } };
795
- {
796
- const o = i.getCameraGroupId(a);
797
- return o ? { ...t, view: { ...t.view, cameraGroup: o } } : t;
798
- }
799
- }
800
- async vrObjectFrameSnapshot(t, e, i) {
801
- if (!this.webrenderV2)
802
- return t;
803
- const s = t.scene.find((a) => !a.decor && !a.accessory);
804
- if (!s)
805
- return t;
806
- let r = this.databases.find((a) => a.id === s.database);
807
- if (r || (r = await this.webrender.database(s.database), this.databases.push(r)), this.webrender instanceof F) {
808
- if (!t.view.camera)
809
- return t;
810
- const a = r.getCameraGroupId(t.view.camera);
811
- if (!a)
812
- return t;
813
- const n = r.getCameraGroupById(a);
814
- if (!n)
815
- return t;
816
- const o = n.cameras[e];
817
- return o ? { ...t, view: { ...t.view, camera: o.id } } : t;
818
- } else if (this.webrender instanceof m) {
819
- const a = typeof t.view.camera == "string" ? t.view.camera : t.view.camera?.id;
820
- if (a) {
821
- const n = r.getCameraById(a);
822
- if (!n)
823
- return t;
824
- const o = new X(n.pointOfView), u = 2 * Math.PI / i;
825
- o.longitude += e * u % (2 * Math.PI);
826
- const l = o.pointOfView(n.pointOfView.target);
827
- return {
828
- ...t,
829
- view: {
830
- ...t.view,
831
- camera: {
832
- id: n.id,
833
- pov: {
834
- target: {
835
- x: l.target[0],
836
- y: l.target[1],
837
- z: l.target[2]
838
- },
839
- eye: {
840
- x: l.eye[0],
841
- y: l.eye[1],
842
- z: l.eye[2]
843
- },
844
- up: {
845
- x: l.up[0],
846
- y: l.up[1],
847
- z: l.up[2]
848
- }
849
- }
850
- }
851
- }
852
- };
853
- } else if (t.view.cameraGroup) {
854
- const n = r.getCameraGroupById(t.view.cameraGroup);
855
- if (!n)
856
- return t;
857
- const o = n.cameras[e];
858
- return o ? { ...t, view: { ...t.view, camera: o.id } } : t;
859
- } else
860
- return t;
861
- } else
862
- return t;
863
- }
864
- async vrCubeFrameSnapshot(t, e) {
865
- const i = t.scene.find((o) => !o.decor && !o.accessory);
866
- if (!i)
867
- return t;
868
- let s = this.databases.find((o) => o.id === i.database);
869
- if (s || (s = await this.webrender.database(i.database), this.databases.push(s)), !t.view.camera)
870
- return t;
871
- let r;
872
- if (this.webrender instanceof F) {
873
- const o = t.view.camera.split("/"), u = o.length === 2 ? o[0] : void 0, l = o.length === 2 ? o[1] : o[0];
874
- r = s.getCameraId(l, u);
875
- } else this.webrender instanceof m && (r = typeof t.view.camera == "string" ? t.view.camera : t.view.camera.id);
876
- if (!r)
877
- return t;
878
- const a = s.getCameraById(r);
879
- if (!a)
880
- return t;
881
- const n = S.initCubeFace(a.pointOfView.eye, a.pointOfView.target, e);
882
- return {
883
- ...t,
884
- view: {
885
- ...t.view,
886
- camera: {
887
- id: a.id,
888
- pov: {
889
- target: {
890
- x: n.target[0],
891
- y: n.target[1],
892
- z: n.target[2]
893
- },
894
- eye: {
895
- x: n.eye[0],
896
- y: n.eye[1],
897
- z: n.eye[2]
898
- },
899
- up: {
900
- x: n.up[0],
901
- y: n.up[1],
902
- z: n.up[2]
903
- }
904
- },
905
- lens: {
906
- fov: 90
907
- }
908
- }
909
- },
910
- parameters: {
911
- ...t.parameters,
912
- width: Math.max(t.parameters.width, t.parameters.height),
913
- height: Math.max(t.parameters.width, t.parameters.height)
914
- }
915
- };
916
- }
917
- onLoadStart(t) {
918
- this.delegate && this.delegate.onLoadStart(t);
919
- }
920
- onLoadProgress(t) {
921
- this.delegate && this.delegate.onLoadProgress(t);
922
- }
923
- onLoadEnd(t) {
924
- this.delegate && this.delegate.onLoadEnd(t);
925
- }
926
- static isValidHttpUrl(t) {
927
- let e;
928
- try {
929
- e = new URL(t);
930
- } catch {
931
- return !1;
932
- }
933
- return e.protocol === "http:" || e.protocol === "https:";
934
- }
935
- }
936
- class Q {
937
- constructor() {
938
- this.element = document.createElement("video"), this.element.classList.add("ls-viewer-video"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.element.setAttribute("muted", ""), this.element.setAttribute("playsinline", ""), this.element.setAttribute("preload", "auto");
939
- }
940
- show() {
941
- this.element.style.opacity = "1";
942
- }
943
- hide() {
944
- this.element.style.opacity = "0";
945
- }
946
- resize(t, e, i, s) {
947
- const r = b.fit(i, new y(t, e), s);
948
- this.element.style.top = `${r.top}px`, this.element.style.left = `${r.left}px`, this.element.style.width = `${r.width}px`, this.element.style.height = `${r.height}px`, (i.width !== this.element.width || i.height !== this.element.height) && (this.element.width = i.width, this.element.height = i.height);
949
- }
950
- }
951
- class J {
952
- constructor(t, e, i) {
953
- this.container = t, this.canvas = e, this.loader = i, this.hotspotList = [];
954
- }
955
- destroy() {
956
- }
957
- show() {
958
- this.canvas.show(!1), this.container.classList.add("ls-viewer-container-image");
959
- }
960
- hide() {
961
- this.canvas.hide(!1), this.container.classList.remove("ls-viewer-container-image");
962
- }
963
- async load(t, e, i, s) {
964
- let r = Promise.resolve();
965
- const a = JSON.stringify(t);
966
- a === this.snapshotHash && this.image ? r = r.then(() => this.canvas.draw(this.image, s, 0.05)) : r = r.then(
967
- () => this.loader.loadImageSnapshot(t).then((o) => {
968
- this.canvas.draw(o, s, 0.05), this.image = o;
969
- })
970
- );
971
- const n = JSON.stringify(e);
972
- return (a !== this.snapshotHash || n !== this.hotspotsHash) && (e.length ? r = r.then(
973
- () => this.loader.loadImageHotspots(t, e).then((o) => {
974
- this.hotspotList = o;
975
- })
976
- ) : this.hotspotList = []), this.hotspotsHash = n, this.snapshotHash = a, r;
977
- }
978
- async pick(t, e) {
979
- const i = new y(t.parameters.width, t.parameters.height), s = b.unproject(i, this.canvas.resolution, this.canvas.fit, e);
980
- return this.loader.loadImagePick(t, s);
981
- }
982
- hotspots(t) {
983
- return this.hotspotList.map((e) => ({ ...e, position2D: b.project(t, this.canvas.resolution, this.canvas.fit, e.position2D) })).map((e) => ({ ...e, visibility: b.contains(this.canvas.resolution, e.position2D) ? e.visibility : "OutOfFrustum" }));
984
- }
985
- snapshot(t, e) {
986
- return this.canvas.element.toDataURL(t, e);
987
- }
988
- onMouseDown(t) {
989
- }
990
- onMouseMove(t) {
991
- }
992
- onMouseUp(t) {
993
- }
994
- onMouseEnter(t) {
995
- }
996
- onTouchStart(t) {
997
- }
998
- onTouchMove(t) {
999
- }
1000
- onTouchEnd(t) {
1001
- }
1002
- onDeviceOrientation(t) {
1003
- }
1004
- }
1005
- class L {
1006
- constructor(t, e) {
1007
- this.x = t, this.y = e;
1008
- }
1009
- clone() {
1010
- return new L(this.x, this.y);
1011
- }
1012
- }
1013
- class f {
1014
- static pointFromMouseEvent(t) {
1015
- return new L(t.screenX, t.screenY);
1016
- }
1017
- static pointFromTouchEvent(t) {
1018
- const e = t.targetTouches[0] || t.changedTouches[0];
1019
- return new L(e.screenX, e.screenY);
1020
- }
1021
- }
1022
- class j {
1023
- constructor(...t) {
1024
- t.length === 3 ? ({ 0: this.u, 1: this.v, 2: this.o } = t, this.w = h.cross(this.u, this.v)) : t.length === 4 ? { 0: this.u, 1: this.v, 2: this.w, 3: this.o } = t : (this.u = [1, 0, 0], this.v = [0, 1, 0], this.w = [0, 0, 1], this.o = [0, 0, 0]);
1025
- }
1026
- get localToGlobalMatrix() {
1027
- const t = [this.u[0], this.u[1], this.u[2], 0], e = [this.v[0], this.v[1], this.v[2], 0], i = [this.w[0], this.w[1], this.w[2], 0], s = [this.o[0], this.o[1], this.o[2], 1];
1028
- return [...t, ...e, ...i, ...s];
1029
- }
1030
- get globalToLocalMatrix() {
1031
- return c.inverse(this.localToGlobalMatrix);
1032
- }
1033
- }
1034
- class Z {
1035
- constructor(t, e, i) {
1036
- this.x = t, this.y = e, this.time = i;
1037
- }
1038
- }
1039
- class R {
1040
- constructor(t) {
1041
- this.points = [], this.onMotion = t, this.lastPoint = new L(0, 0), this.velocity = new L(0, 0), this.loop = this.loop.bind(this);
1042
- }
1043
- destroy() {
1044
- this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = void 0);
1045
- }
1046
- track(t) {
1047
- const e = Date.now();
1048
- this.points = this.points.filter((i) => e - i.time <= 100), this.points.push(new Z(t.x, t.y, e)), this.lastPoint = t;
1049
- }
1050
- start() {
1051
- if (this.points.length === 0)
1052
- return;
1053
- const t = this.points[0], e = this.points[this.points.length - 1], i = e.x - t.x, s = e.y - t.y, r = e.time - t.time;
1054
- this.velocity = new L(r === 0 ? 0 : i / (r / 15), r === 0 ? 0 : s / (r / 15)), this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = void 0), this.animationFrameId = requestAnimationFrame(this.loop);
1055
- }
1056
- stop() {
1057
- this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = void 0), this.points = [];
1058
- }
1059
- loop() {
1060
- if (Math.abs(this.velocity.x) < 1 && Math.abs(this.velocity.y) < 1) {
1061
- this.animationFrameId = void 0, this.points = [];
1062
- return;
1063
- }
1064
- this.lastPoint.x += this.velocity.x, this.lastPoint.y += this.velocity.y, this.velocity.x *= 0.9, this.velocity.y *= 0.9, this.onMotion(this.lastPoint.clone()), this.animationFrameId = requestAnimationFrame(this.loop);
1065
- }
1066
- }
1067
- class W {
1068
- constructor(t, e, i) {
1069
- this.isStarted = !1, this.pov = t, this.fov = w.degreesToRadians(e), this.orientationMatrix = c.identity(), this.inertia = new R(this.motion.bind(this)), this.onMotion = i, this.initPov = this.pov, this.initFov = this.fov, this.initOrientation = w.degreesToRadians(window.orientation) || 0, this.startPov = new S([0, 0, 1], [0, 0, 0], [0, 1, 0]), this.startSize = { width: 0, height: 0 }, this.previousPoint = new L(0, 0);
1070
- }
1071
- destroy() {
1072
- this.inertia.destroy();
1073
- }
1074
- get orientedPov() {
1075
- const t = h.normalize(h.cross(this.pov.up, this.pov.target)), e = new j(t, [0, 1, 0], this.pov.eye), i = c.identity();
1076
- c.multiply(i, e.localToGlobalMatrix, i), c.multiply(i, this.orientationMatrix, i), c.multiply(i, e.globalToLocalMatrix, i);
1077
- const s = c.transformDirection(i, this.pov.target), r = this.pov.eye, a = c.transformDirection(i, this.pov.up);
1078
- return new S(s, r, a);
1079
- }
1080
- reset() {
1081
- this.pov = this.initPov.clone(), this.fov = this.initFov;
1082
- }
1083
- start(t, e) {
1084
- this.isStarted = !0, this.startPov = this.pov, this.startSize = e, this.previousPoint = t, this.inertia.stop();
1085
- }
1086
- motion(t) {
1087
- this.isStarted && this.inertia.track(t);
1088
- const e = {
1089
- x: t.x - this.previousPoint.x,
1090
- y: t.y - this.previousPoint.y
1091
- }, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r = c.multiply(c.rotationY(i), c.rotationX(-s)), a = h.normalize(h.cross(this.pov.up, this.pov.target)), n = new j(a, [0, 1, 0], this.pov.eye), o = c.identity();
1092
- c.multiply(o, n.localToGlobalMatrix, o), c.multiply(o, r, o), c.multiply(o, n.globalToLocalMatrix, o);
1093
- const u = c.transformPoint(o, this.pov.target), l = c.transformDirection(o, this.pov.up);
1094
- h.cross(l, [0, 0, 1])[0] >= 0 && (this.pov.target = u, this.pov.up = l), this.previousPoint = t, this.onMotion();
1095
- }
1096
- end(t, e) {
1097
- this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
1098
- }
1099
- orientation(t, e, i) {
1100
- const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t), a = w.degreesToRadians(-e), n = w.degreesToRadians(-i), o = c.rotationX(w.degreesToRadians(90));
1101
- c.rotateZ(o, this.initOrientation, o), c.rotateZ(o, r, o), c.rotateX(o, a, o), c.rotateY(o, n, o), c.rotateZ(o, -s, o), this.orientationMatrix = o, this.onMotion();
1102
- }
1103
- }
1104
- var _ = `precision mediump float;
1105
-
1106
- uniform float u_mix;
1107
- uniform samplerCube u_texture;
1108
- uniform samplerCube u_texture_back;
1109
-
1110
- varying vec3 direction;
1111
-
1112
- void main() {
1113
- vec4 backColor = textureCube(u_texture_back, direction);
1114
- vec4 color = textureCube(u_texture, direction);
1115
- gl_FragColor = mix(backColor, color, u_mix);
1116
- }`, K = `attribute vec4 position;
1117
-
1118
- uniform mat4 u_mvpi;
1119
-
1120
- varying vec3 direction;
1121
-
1122
- void main() {
1123
- direction = (u_mvpi * position).xyz;
1124
- gl_Position = position;
1125
- }`;
1126
- class tt {
1127
- constructor(t, e, i, s, r) {
1128
- this.container = t, this.canvas = e, this.loader = i, this.aspectRatioOverride = r, this.images = [], this.hotspotsList = [[]];
1129
- const a = new S([0, 0, 1], [0, 0, 0], [0, 1, 0]), n = 60, o = c.rotationX(w.degreesToRadians(15));
1130
- c.transformDirection(o, a.target, a.target), c.transformDirection(o, a.up, a.up), this.interaction = new W(a, n, () => {
1131
- this.animationFrameId = requestAnimationFrame(this.render), this.onInteraction({
1132
- pov: this.interaction.pov.clone(),
1133
- fov: this.interaction.fov
1134
- });
1135
- }), this.onInteraction = s, this.gl = this.canvas.context, this.programInfo = M.createProgramInfo(this.gl, [`${K}
1136
- `, `${_}
1137
- `]), this.quad = M.primitives.createXYQuadBufferInfo(this.gl), this.uniforms = {
1138
- u_mvpi: c.identity(),
1139
- u_mix: 0,
1140
- u_texture_back: M.createTexture(this.gl, {
1141
- target: this.gl.TEXTURE_CUBE_MAP,
1142
- minMag: this.gl.LINEAR,
1143
- width: 1,
1144
- height: 1
1145
- }),
1146
- u_texture: M.createTexture(this.gl, {
1147
- target: this.gl.TEXTURE_CUBE_MAP,
1148
- minMag: this.gl.LINEAR,
1149
- width: 1,
1150
- height: 1
1151
- })
1152
- }, this.render = this.render.bind(this);
1153
- }
1154
- destroy() {
1155
- this.interaction.destroy(), this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = void 0);
1156
- }
1157
- show() {
1158
- this.canvas.show(), this.container.classList.add("ls-viewer-container-vrcube");
1159
- }
1160
- hide() {
1161
- this.canvas.hide(), this.container.classList.remove("ls-viewer-container-vrcube");
1162
- }
1163
- get pov() {
1164
- return this.interaction.pov;
1165
- }
1166
- set pov(t) {
1167
- this.interaction.pov.eye.every((e, i) => e === t.eye[i]) && this.interaction.pov.target.every((e, i) => e === t.target[i]) && this.interaction.pov.up.every((e, i) => e === t.up[i]) || (this.interaction.pov = t.clone(), this.animationFrameId = requestAnimationFrame(this.render));
1168
- }
1169
- get fov() {
1170
- return w.radiansToDegrees(this.interaction.fov);
1171
- }
1172
- set fov(t) {
1173
- this.interaction.fov !== t && (this.interaction.fov = w.degreesToRadians(t), this.animationFrameId = requestAnimationFrame(this.render));
1174
- }
1175
- async load(t, e, i, s) {
1176
- let r = Promise.resolve();
1177
- {
1178
- const o = this.gl.getExtension("WEBGL_debug_renderer_info");
1179
- o && navigator.platform === "MacIntel" && navigator.userAgent.includes("Chrome") && this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL") && (t.parameters.width = Math.min(t.parameters.width, 1812), t.parameters.height = Math.min(t.parameters.height, 1812));
1180
- }
1181
- const a = JSON.stringify(t);
1182
- a === this.snapshotHash ? r = r.then(() => (this.animationFrameId = requestAnimationFrame(this.render), Promise.resolve())) : (this.images = [], this.animationFrameId = requestAnimationFrame(this.render), r = r.then(
1183
- () => this.loader.loadVRCubeSnapshot(t).then((o) => {
1184
- this.images = o, M.createTexture(
1185
- this.gl,
1186
- {
1187
- target: this.gl.TEXTURE_CUBE_MAP,
1188
- min: this.gl.LINEAR_MIPMAP_LINEAR,
1189
- minMag: this.gl.LINEAR,
1190
- cubeFaceOrder: [
1191
- this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
1192
- //
1193
- this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,
1194
- this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,
1195
- this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
1196
- this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
1197
- this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y
1198
- ],
1199
- src: o
1200
- },
1201
- (u, l) => {
1202
- u || (i && this.interaction.reset(), this.uniforms.u_mix = s ? 0 : 1, this.uniforms.u_texture_back = this.uniforms.u_texture, this.uniforms.u_texture = l, this.animationFrameId = requestAnimationFrame(this.render));
1203
- }
1204
- );
1205
- })
1206
- ));
1207
- const n = JSON.stringify(e);
1208
- return (a !== this.snapshotHash || n !== this.hotspotsHash) && (e.length ? r = r.then(
1209
- () => this.loader.loadVRCubeHotspots(t, e).then((o) => {
1210
- this.hotspotsList = o;
1211
- })
1212
- ) : this.hotspotsList = [[]]), this.hotspotsHash = n, this.snapshotHash = a, r;
1213
- }
1214
- async pick(t, e) {
1215
- const i = this.canvas.element.clientWidth, s = this.canvas.element.clientHeight, r = e.x, a = s - e.y, n = 2 * r / i - 1, o = 2 * a / s - 1, u = [n, o, 0], l = this.modelViewProjectionMatrix, p = c.inverse(l), d = h.normalize(c.transformPoint(p, u)), C = Math.max(Math.abs(d[0]), Math.abs(d[1]), Math.abs(d[2]));
1216
- let A = "";
1217
- Math.abs(d[0]) === C ? A = d[0] > 0 ? "XPOS" : "XNEG" : Math.abs(d[1]) === C ? A = d[1] > 0 ? "YPOS" : "YNEG" : A = d[2] > 0 ? "ZPOS" : "ZNEG";
1218
- let x = 0, E = 0, I = "";
1219
- switch (A) {
1220
- case "XPOS":
1221
- x = (-d[2] / Math.abs(d[0]) + 1) / 2, E = (-d[1] / Math.abs(d[0]) + 1) / 2, I = "right";
1222
- break;
1223
- case "XNEG":
1224
- x = (d[2] / Math.abs(d[0]) + 1) / 2, E = (-d[1] / Math.abs(d[0]) + 1) / 2, I = "left";
1225
- break;
1226
- case "YPOS":
1227
- x = (d[0] / Math.abs(d[1]) + 1) / 2, E = (d[2] / Math.abs(d[1]) + 1) / 2, I = "up";
1228
- break;
1229
- case "YNEG":
1230
- x = (d[0] / Math.abs(d[1]) + 1) / 2, E = (-d[2] / Math.abs(d[1]) + 1) / 2, I = "down";
1231
- break;
1232
- case "ZPOS":
1233
- x = (d[0] / Math.abs(d[2]) + 1) / 2, E = (-d[1] / Math.abs(d[2]) + 1) / 2, I = "front";
1234
- break;
1235
- case "ZNEG":
1236
- x = (-d[0] / Math.abs(d[2]) + 1) / 2, E = (-d[1] / Math.abs(d[2]) + 1) / 2, I = "back";
1237
- break;
1238
- }
1239
- const T = {
1240
- x: Math.round(x * Math.max(t.parameters.width, t.parameters.height)),
1241
- y: Math.round(E * Math.max(t.parameters.width, t.parameters.height))
1242
- };
1243
- return this.loader.loadVRCubePick(t, T, I);
1244
- }
1245
- hotspots() {
1246
- const t = [];
1247
- if (this.hotspotsList.length === 0)
1248
- return [];
1249
- const e = this.hotspotsList[0]?.length ?? 0, i = this.modelViewProjectionMatrix;
1250
- for (let s = 0; s < e; s++) {
1251
- const r = this.hotspotsList.findIndex(($) => $[s].visibility !== "OutOfFrustum");
1252
- if (r === -1)
1253
- continue;
1254
- const a = { ...this.hotspotsList[r][s] }, n = a.position2D.x / this.images[0].width, o = a.position2D.y / this.images[0].height;
1255
- let u = 0, l = 0, p = 0;
1256
- switch (r) {
1257
- case 0:
1258
- this.pov.target[2] < 0 && (a.visibility = "OutOfFrustum"), u = 2 * n - 1, l = 1 - 2 * o, p = 1;
1259
- break;
1260
- case 1:
1261
- this.pov.target[0] > 0 && (a.visibility = "OutOfFrustum"), u = 1, l = 1 - 2 * o, p = 1 - 2 * n;
1262
- break;
1263
- case 2:
1264
- this.pov.target[2] > 0 && (a.visibility = "OutOfFrustum"), u = 1 - 2 * n, l = 1 - 2 * o, p = -1;
1265
- break;
1266
- case 3:
1267
- this.pov.target[0] < 0 && (a.visibility = "OutOfFrustum"), u = -1, l = 1 - 2 * o, p = 2 * n - 1;
1268
- break;
1269
- case 4:
1270
- this.pov.target[1] < 0 && (a.visibility = "OutOfFrustum"), u = 2 * n - 1, l = 1, p = 2 * o - 1;
1271
- break;
1272
- case 5:
1273
- this.pov.target[1] > 0 && (a.visibility = "OutOfFrustum"), u = 2 * n - 1, l = -1, p = 1 - 2 * o;
1274
- break;
1275
- }
1276
- const d = h.normalize([u, l, p]), C = c.transformPoint(i, d), A = this.canvas.element.clientWidth, x = this.canvas.element.clientHeight, E = 0.5 * A * (C[0] + 1), I = 0.5 * x * (C[1] + 1), T = {
1277
- x: Math.round(E),
1278
- y: Math.round(x - I)
1279
- }, G = new y(A, x), z = b.contains(G, T) ? a.visibility : "OutOfFrustum";
1280
- t.push({ ...a, position2D: T, visibility: z });
1281
- }
1282
- return t;
1283
- }
1284
- snapshot(t, e) {
1285
- return this.canvas.element.toDataURL(t, e);
1286
- }
1287
- get modelViewProjectionMatrix() {
1288
- const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = b.getStandardAspectRatio(t, e, this.aspectRatioOverride), r = this.interaction.fov * (s / i), a = c.setAxis(c.identity(), [-1, 0, 0], 0), n = t > e ? w.perspectiveWithFovY(r, t / e, 0.5, 100) : w.perspectiveWithFovX(r, t / e, 0.5, 100), o = this.interaction.orientedPov, u = c.inverse(c.lookAt(o.eye, o.target, o.up));
1289
- return c.multiply(c.multiply(n, u), a);
1290
- }
1291
- render() {
1292
- this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi = c.inverse(this.modelViewProjectionMatrix), this.gl.useProgram(this.programInfo.program), M.setBuffersAndAttributes(this.gl, this.programInfo, this.quad), M.setUniforms(this.programInfo, this.uniforms), M.drawBufferInfo(this.gl, this.quad), this.uniforms.u_mix < 1 && (this.uniforms.u_mix = Math.min(this.uniforms.u_mix + 0.05, 1), this.animationFrameId = requestAnimationFrame(this.render));
1293
- }
1294
- onMouseDown(t) {
1295
- this.container.classList.add("ls-viewer-container-vrcube-grabbing"), this.interaction.start(f.pointFromMouseEvent(t), {
1296
- width: this.gl.canvas.width,
1297
- height: this.gl.canvas.height
1298
- });
1299
- }
1300
- onMouseMove(t) {
1301
- this.interaction.isStarted && (this.interaction.motion(f.pointFromMouseEvent(t)), t.preventDefault());
1302
- }
1303
- onMouseUp(t) {
1304
- this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrcube-grabbing"), this.interaction.end(f.pointFromMouseEvent(t), !0));
1305
- }
1306
- onMouseEnter(t) {
1307
- this.interaction.isStarted && t.buttons === 0 && (this.container.classList.remove("ls-viewer-container-vrcube-grabbing"), this.interaction.end(f.pointFromMouseEvent(t), !1));
1308
- }
1309
- onTouchStart(t) {
1310
- this.container.classList.add("ls-viewer-container-vrcube-grabbing"), this.interaction.start(f.pointFromTouchEvent(t), {
1311
- width: this.gl.canvas.width,
1312
- height: this.gl.canvas.height
1313
- });
1314
- }
1315
- onTouchMove(t) {
1316
- this.interaction.isStarted && (this.interaction.motion(f.pointFromTouchEvent(t)), t.preventDefault());
1317
- }
1318
- onTouchEnd(t) {
1319
- this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrcube-grabbing"), this.interaction.end(f.pointFromTouchEvent(t), !0));
1320
- }
1321
- onDeviceOrientation(t) {
1322
- this.interaction.orientation(t.alpha, t.beta, t.gamma);
1323
- }
1324
- }
1325
- class et {
1326
- constructor(t, e, i, s, r) {
1327
- this.isStarted = !1, this.position = t, this.frames = e, this.rows = i, this.loop = s, this.onMotion = r, this.inertia = new R(this.motion.bind(this)), this.initPosition = { ...this.position }, this.startPosition = { x: 0, y: 0 }, this.startPoint = new L(0, 0), this.startSize = { width: 0, height: 0 }, this.lastPoints = [], this.lastPointsNumber = 20;
1328
- }
1329
- destroy() {
1330
- this.inertia.destroy();
1331
- }
1332
- reset() {
1333
- this.position = { ...this.initPosition };
1334
- }
1335
- get positionIndex() {
1336
- return this.frames * this.position.y + this.position.x;
1337
- }
1338
- set positionIndex(t) {
1339
- if (this.positionIndex === t)
1340
- return;
1341
- const e = this.loop ? w.mod(t, this.frames * this.rows) : Math.max(0, Math.min(t, this.frames * this.rows));
1342
- this.position.x = w.mod(e, this.frames), this.position.y = Math.floor(e / this.frames);
1343
- }
1344
- start(t, e) {
1345
- this.isStarted = !0, this.startPosition = { ...this.position }, this.startPoint = t, this.startSize = e, this.lastPoints = [], this.inertia.stop();
1346
- }
1347
- motion(t) {
1348
- this.isStarted && this.inertia.track(t), this.lastPoints.push({ x: t.x, y: t.y }), this.lastPoints.splice(0, this.lastPoints.length - this.lastPointsNumber);
1349
- const e = U.linear(this.lastPoints.map((s) => [s.x, s.y])), i = 25;
1350
- if (Math.abs(e.equation[0]) < 1) {
1351
- const s = w.accelerate(t.x - this.startPoint.x, 1.3) / this.startSize.width * (this.frames / 4);
1352
- let r = this.startPosition.x - Math.round(s);
1353
- r = this.loop ? w.mod(r, this.frames) : Math.max(0, Math.min(r, this.frames - 1)), r !== this.position.x && (this.position.x = r, this.onMotion());
1354
- const a = Math.min(...this.lastPoints.map((o) => o.x));
1355
- Math.max(...this.lastPoints.map((o) => o.x)) - a > i && (this.startPoint.y = t.y, this.startPosition.y = this.position.y);
1356
- } else {
1357
- const s = w.accelerate(t.y - this.startPoint.y, 1.7) / this.startSize.height * (this.rows / 4);
1358
- let r = this.startPosition.y + Math.round(s);
1359
- r = Math.max(0, Math.min(r, this.rows - 1)), r !== this.position.y && (this.position.y = r, this.onMotion());
1360
- const a = Math.min(...this.lastPoints.map((o) => o.y));
1361
- Math.max(...this.lastPoints.map((o) => o.y)) - a > i && (this.startPoint.x = t.x, this.startPosition.x = this.position.x);
1362
- }
1363
- }
1364
- end(t, e) {
1365
- this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
1366
- }
1367
- }
1368
- class k {
1369
- constructor(t, e, i, s) {
1370
- this.container = t, this.canvas = e, this.loader = i, this.images = [], this.frames = 24, this.hotspotsList = [[]], this.interaction = new et({ x: 0, y: 0 }, 1, 1, !1, () => {
1371
- this.canvas.draw(this.image, !0, 0.5), this.onInteraction({
1372
- position: this.interaction.positionIndex
1373
- });
1374
- }), this.onInteraction = s;
1375
- }
1376
- destroy() {
1377
- this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = void 0);
1378
- }
1379
- show() {
1380
- this.canvas.show(!1), this.container.classList.add("ls-viewer-container-vrobject");
1381
- }
1382
- hide() {
1383
- this.canvas.hide(!1), this.container.classList.remove("ls-viewer-container-vrobject");
1384
- }
1385
- async goto(t) {
1386
- return new Promise((e) => {
1387
- let i = this.interaction.positionIndex;
1388
- const s = () => {
1389
- if (this.interaction.positionIndex === t)
1390
- e();
1391
- else {
1392
- let r = i > t ? -1 : 1;
1393
- this.interaction.loop && this.interaction.frames - i + t < Math.abs(t - i) && (r *= -1), i += 0.5 * r, this.position = Math.floor(i), this.animationFrameId = requestAnimationFrame(s);
1394
- }
1395
- };
1396
- this.animationFrameId = requestAnimationFrame(s);
1397
- });
1398
- }
1399
- get position() {
1400
- return this.interaction.positionIndex;
1401
- }
1402
- set position(t) {
1403
- this.interaction.positionIndex = t, this.canvas.draw(this.image, !0, 0.5);
1404
- }
1405
- get image() {
1406
- return this.images[this.interaction.positionIndex];
1407
- }
1408
- async load(t, e, i, s) {
1409
- let r = Promise.resolve();
1410
- i && this.interaction.reset();
1411
- const a = JSON.stringify(t);
1412
- a === this.snapshotHash && this.image ? r = r.then(() => this.canvas.draw(this.image, s, 0.05)) : (this.images = [], r = r.then(
1413
- () => this.loader.loadVRObjectSnapshot(t, this.interaction.positionIndex).then((o) => {
1414
- const u = o.length;
1415
- return this.images = new Array(u), this.interaction.frames = t.view.frames ?? t.view.panFrames ?? this.frames, this.interaction.rows = u / this.interaction.frames, this.interaction.loop = !!t.view.loop, i && this.interaction.reset(), o.forEach((l, p) => {
1416
- l.then((d) => {
1417
- this.images[p] = d, d === this.image && this.canvas.draw(this.image, s, 0.05);
1418
- }).catch(() => {
1419
- });
1420
- }), o[this.interaction.positionIndex].then(() => Promise.resolve());
1421
- })
1422
- ));
1423
- const n = JSON.stringify(e);
1424
- return (a !== this.snapshotHash || n !== this.hotspotsHash) && (e.length ? r = r.then(
1425
- () => this.loader.loadVRObjectHotspots(t, e).then((o) => {
1426
- this.hotspotsList = o;
1427
- })
1428
- ) : this.hotspotsList = [[]]), this.hotspotsHash = n, this.snapshotHash = a, r;
1429
- }
1430
- async pick(t, e) {
1431
- const i = new y(t.parameters.width, t.parameters.height), s = b.unproject(i, this.canvas.resolution, this.canvas.fit, e);
1432
- return this.loader.loadVRObjectPick(t, s, this.position, this.frames);
1433
- }
1434
- hotspots(t) {
1435
- return (this.hotspotsList[this.interaction.positionIndex] || []).map((i) => ({ ...i, position2D: b.project(t, this.canvas.resolution, this.canvas.fit, i.position2D) })).map((i) => ({ ...i, visibility: b.contains(this.canvas.resolution, i.position2D) ? i.visibility : "OutOfFrustum" }));
1436
- }
1437
- snapshot(t, e) {
1438
- return this.canvas.element.toDataURL(t, e);
1439
- }
1440
- onMouseDown(t) {
1441
- this.container.classList.add("ls-viewer-container-vrobject-grabbing"), this.interaction.start(f.pointFromMouseEvent(t), {
1442
- width: this.canvas.element.width,
1443
- height: this.canvas.element.height
1444
- });
1445
- }
1446
- onMouseMove(t) {
1447
- this.interaction.isStarted && (this.interaction.motion(f.pointFromMouseEvent(t)), t.preventDefault());
1448
- }
1449
- onMouseUp(t) {
1450
- this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrobject-grabbing"), this.interaction.end(f.pointFromMouseEvent(t), !0));
1451
- }
1452
- onMouseEnter(t) {
1453
- this.interaction.isStarted && t.buttons === 0 && (this.container.classList.remove("ls-viewer-container-vrobject-grabbing"), this.interaction.end(f.pointFromMouseEvent(t), !1));
1454
- }
1455
- onTouchStart(t) {
1456
- this.container.classList.add("ls-viewer-container-vrobject-grabbing"), this.interaction.start(f.pointFromTouchEvent(t), {
1457
- width: this.canvas.element.width,
1458
- height: this.canvas.element.height
1459
- });
1460
- }
1461
- onTouchMove(t) {
1462
- this.interaction.isStarted && (this.interaction.motion(f.pointFromTouchEvent(t)), t.preventDefault());
1463
- }
1464
- onTouchEnd(t) {
1465
- this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrobject-grabbing"), this.interaction.end(f.pointFromTouchEvent(t), !0));
1466
- }
1467
- onDeviceOrientation(t) {
1468
- }
1469
- }
1470
- class it {
1471
- constructor(t, e, i) {
1472
- this.container = t, this.loader = i, this.video = e;
1473
- }
1474
- destroy() {
1475
- }
1476
- show() {
1477
- this.video.show(), this.container.classList.add("ls-viewer-container-video");
1478
- }
1479
- hide() {
1480
- this.video.hide(), this.container.classList.remove("ls-viewer-container-video");
1481
- }
1482
- async load(t) {
1483
- const e = JSON.stringify(t);
1484
- return e === this.hash ? (this.video.element.load(), Promise.resolve()) : (this.hash = e, this.loader.loadVideoSnapshot(this.video.element, t));
1485
- }
1486
- async pick(t, e) {
1487
- return Promise.reject();
1488
- }
1489
- hotspots(t) {
1490
- return [];
1491
- }
1492
- snapshot(t, e) {
1493
- return "data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
1494
- }
1495
- async play() {
1496
- return new Promise((t, e) => {
1497
- this.video.element.addEventListener(
1498
- "ended",
1499
- () => {
1500
- t();
1501
- },
1502
- { once: !0 }
1503
- ), this.video.element.play().catch(e), this.show();
1504
- });
1505
- }
1506
- onMouseDown(t) {
1507
- }
1508
- onMouseMove(t) {
1509
- }
1510
- onMouseUp(t) {
1511
- }
1512
- onMouseEnter(t) {
1513
- }
1514
- onTouchStart(t) {
1515
- }
1516
- onTouchMove(t) {
1517
- }
1518
- onTouchEnd(t) {
1519
- }
1520
- onDeviceOrientation(t) {
1521
- }
1522
- }
1523
- class nt {
1524
- constructor(t, e) {
1525
- this.onDeviceOrientation = this.onDeviceOrientation.bind(this), this.onResize = this.onResize.bind(this), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseMove = this.onMouseMove.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.onMouseEnter = this.onMouseEnter.bind(this), this.onTouchStart = this.onTouchStart.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onLoadStart = this.onLoadStart.bind(this), this.onLoadProgress = this.onLoadProgress.bind(this), this.onLoadEnd = this.onLoadEnd.bind(this), this.onLoadError = this.onLoadError.bind(this), this.onHotspotsChange = this.onHotspotsChange.bind(this), this.onVrcubeInteraction = this.onVrcubeInteraction.bind(this), this.onVrobjectInteraction = this.onVrobjectInteraction.bind(this), this.options = {
1526
- server: "localhost",
1527
- api: "v1",
1528
- autores: !0,
1529
- fit: "cover",
1530
- image: {},
1531
- video: {},
1532
- vrcube: {},
1533
- vrobject: {},
1534
- events: {},
1535
- ...e
1536
- }, this.options.events = {
1537
- onLoadStart: () => {
1538
- },
1539
- onLoadProgress: () => {
1540
- },
1541
- onLoadEnd: () => {
1542
- },
1543
- onLoadError: () => {
1544
- },
1545
- onInteraction: () => {
1546
- },
1547
- onVrcubeInteraction: () => {
1548
- },
1549
- onVrobjectInteraction: () => {
1550
- },
1551
- onHotspotsChange: () => {
1552
- },
1553
- ...e.events
1554
- }, this.options.events.onLoadError = V(this.options.events.onLoadError, 10), this.container = t, this.container.classList.add("ls-viewer-container"), this.canvas2D = new N(this.options.fit), this.container.prepend(this.canvas2D.element), this.canvas3D = new B(), this.container.prepend(this.canvas3D.element), this.video = new Q(), this.container.prepend(this.video.element), this.loader = new D(this.options.server, this.options.api, this), this.resolution = new y(0, 0), this.parameters = {
1555
- width: 0,
1556
- height: 0,
1557
- antialiasing: !1,
1558
- superSampling: 2
1559
- }, this.encoder = {
1560
- format: "jpeg",
1561
- quality: 80
1562
- }, this.hotspots = [], this.widgetImage = new J(t, this.canvas2D, this.loader), this.widgetVideo = new it(t, this.video, this.loader), this.widgetVRObject = new k(t, this.canvas2D, this.loader, this.onVrobjectInteraction), this.canvas3D.context && (this.widgetVRCube = new tt(t, this.canvas3D, this.loader, this.onVrcubeInteraction, this.aspectRatioOverride)), this.widget = this.widgetImage, this.container.addEventListener("mousedown", this.onMouseDown), this.container.addEventListener("mouseenter", this.onMouseEnter), this.container.addEventListener("touchstart", this.onTouchStart), document.addEventListener("mousemove", this.onMouseMove, { passive: !1 }), document.addEventListener("mouseup", this.onMouseUp), document.addEventListener("touchmove", this.onTouchMove, { passive: !1 }), document.addEventListener("touchend", this.onTouchEnd), this.loadWidget = V(this.loadWidget, 10), this.resizeObserver = new ResizeObserver(this.onResize), this.resizeObserver.observe(this.container);
1563
- }
1564
- destroy() {
1565
- this.resizeObserver.disconnect(), this.canvas2D.destroy(), this.container.removeEventListener("mousedown", this.onMouseDown), this.container.removeEventListener("mouseenter", this.onMouseEnter), this.container.removeEventListener("touchstart", this.onTouchStart), document.removeEventListener("mousemove", this.onMouseMove), document.removeEventListener("mouseup", this.onMouseUp), document.removeEventListener("touchmove", this.onTouchMove), document.removeEventListener("touchend", this.onTouchEnd);
1566
- }
1567
- async load(t, e) {
1568
- let i = Promise.resolve();
1569
- return e?.animation && (i = i.then(() => this.loadAnimation(e.animation))), this.view && e?.fromPosition !== void 0 && this.viewWidget instanceof k && (this.view.mode, i = i.then(() => this.viewWidget.goto(e.fromPosition))), e?.animation && (i = i.then(() => this.widgetVideo.play())), i = i.then(() => (this.scene = Array.isArray(t) ? [...t] : [t], this.loadWidget(!1, !(e && e.animation)))), i.catch((s) => {
1570
- this.onLoadError(s);
1571
- }), i;
1572
- }
1573
- async setEncoder(t) {
1574
- this.encoder = { ...t };
1575
- let e = Promise.resolve();
1576
- return e = e.then(() => this.loadWidget(!1, !0)), e.catch((i) => {
1577
- this.onLoadError(i);
1578
- }), e;
1579
- }
1580
- setParameters(t) {
1581
- if (t.width && t.height) {
1582
- this.resolution = new y(t.width, t.height);
1583
- const i = this.container.clientWidth, s = this.container.clientHeight;
1584
- this.canvas2D.resize(i, s, this.getCanvas2DPixelRatio(i, s));
1585
- }
1586
- this.parameters = { ...t }, this.parameters.width = this.resolution.width, this.parameters.height = this.resolution.height;
1587
- let e = Promise.resolve();
1588
- return e = e.then(() => this.loadWidget(!1, !0)), e.catch((i) => {
1589
- this.onLoadError(i);
1590
- }), e;
1591
- }
1592
- setHotspots(t) {
1593
- this.hotspots = t, this.loadWidget(!1, !1);
1594
- }
1595
- async setView(t, e) {
1596
- let i = Promise.resolve();
1597
- return e?.animation && (i = i.then(() => this.loadAnimation(e.animation))), this.view && e?.fromPosition !== void 0 && this.viewWidget instanceof k && (i = i.then(() => this.viewWidget.goto(e.fromPosition))), e?.animation && (i = i.then(() => this.widgetVideo.play())), i = i.then(() => {
1598
- let s = !0;
1599
- return this.view = { ...t }, this.view && this.viewWidget instanceof k && e?.toPosition !== void 0 && (s = !1, this.viewWidget.position = e.toPosition), this.loadWidget(s, !(e && e.animation));
1600
- }), i.catch((s) => {
1601
- this.onLoadError(s);
1602
- }), i;
1603
- }
1604
- setVrcube(t) {
1605
- this.widgetVRCube && Object.assign(this.widgetVRCube, t);
1606
- }
1607
- setVrobject(t) {
1608
- Object.assign(this.widgetVRObject, t);
1609
- }
1610
- async loadAnimation(t) {
1611
- const e = {
1612
- scene: this.scene,
1613
- view: {
1614
- animation: t.name,
1615
- camera: t.camera,
1616
- duration: t.duration,
1617
- loop: t.loop,
1618
- reverse: t.reverse
1619
- },
1620
- parameters: this.parameters,
1621
- encoder: {
1622
- format: "mp4"
1623
- }
1624
- };
1625
- return e.view?.background || (e.view.background = "product"), this.widgetVideo.load(e).then(() => Promise.resolve());
1626
- }
1627
- async playAnimation(t) {
1628
- return this.loadAnimation(t).then(() => this.widgetVideo.play()).catch((e) => {
1629
- this.onLoadError(e);
1630
- });
1631
- }
1632
- stopAnimation() {
1633
- this.widgetVideo.hide();
1634
- }
1635
- async pick(t) {
1636
- if (!this.scene)
1637
- throw new Error("No scene set");
1638
- if (!this.view)
1639
- throw new Error("No view set");
1640
- if (!this.view.camera && !this.view.cameraGroup)
1641
- throw new Error("No camera set");
1642
- const e = {
1643
- scene: this.scene,
1644
- view: this.view,
1645
- parameters: this.parameters,
1646
- encoder: this.encoder
1647
- };
1648
- return await this.viewWidget.pick(e, t);
1649
- }
1650
- async pickHotspot(t) {
1651
- const e = await this.pick(t), i = Object.values(e.point), s = h.normalize(Object.values(e.normal)), r = h.add(i, h.mulScalar(s, 0.01));
1652
- return e.point = { x: r[0], y: r[1], z: r[2] }, e;
1653
- }
1654
- snapshot(t, e) {
1655
- return this.viewWidget.snapshot(t, e);
1656
- }
1657
- async loadWidget(t, e) {
1658
- if (!this.scene || !this.view || !this.parameters.width || !this.parameters.height)
1659
- return Promise.resolve();
1660
- const i = this.viewWidget;
1661
- if (!i)
1662
- return Promise.reject(new Error("Unknown view mode"));
1663
- const s = {
1664
- scene: this.scene,
1665
- view: this.view,
1666
- parameters: this.parameters,
1667
- encoder: this.encoder
1668
- };
1669
- return s.view.background || (s.view.background = "product"), i.load(s, this.hotspots, t, e).then(() => {
1670
- this.widget.hide(), this.widget = i, this.widget.show(), this.widgetVideo.hide(), this.onHotspotsChange();
1671
- });
1672
- }
1673
- get aspectRatioOverride() {
1674
- switch (this.options.aspectRatio) {
1675
- case "4:3":
1676
- return 4 / 3;
1677
- case "16:9":
1678
- return 16 / 9;
1679
- default:
1680
- return;
1681
- }
1682
- }
1683
- get viewWidget() {
1684
- switch (this.view?.mode) {
1685
- case "image":
1686
- return this.widgetImage;
1687
- case "video":
1688
- return this.widgetVideo;
1689
- case "vrcube":
1690
- return this.widgetVRCube ?? this.widgetImage;
1691
- case "vrobject":
1692
- return this.widgetVRObject;
1693
- default:
1694
- return this.widgetImage;
1695
- }
1696
- }
1697
- onMouseDown(t) {
1698
- this.widget.onMouseDown(t);
1699
- }
1700
- onMouseEnter(t) {
1701
- this.widget.onMouseEnter(t);
1702
- }
1703
- onMouseMove(t) {
1704
- this.widget.onMouseMove(t);
1705
- }
1706
- onMouseUp(t) {
1707
- this.widget.onMouseUp(t);
1708
- }
1709
- onTouchStart(t) {
1710
- this.widget.onTouchStart(t);
1711
- }
1712
- onTouchMove(t) {
1713
- this.widget.onTouchMove(t);
1714
- }
1715
- onTouchEnd(t) {
1716
- this.widget.onTouchEnd(t);
1717
- }
1718
- onDeviceOrientation(t) {
1719
- this.widget.onDeviceOrientation(t);
1720
- }
1721
- // Cap per-axis so the canvas backing never exceeds the source resolution; otherwise
1722
- // drawImage upscales the JPEG and looks blurry on iOS / MacOS.
1723
- getCanvas2DPixelRatio(t, e) {
1724
- return t <= 0 || e <= 0 || this.resolution.width <= 0 || this.resolution.height <= 0 ? window.devicePixelRatio : Math.min(window.devicePixelRatio, this.resolution.width / t, this.resolution.height / e);
1725
- }
1726
- onResize() {
1727
- const t = this.container.clientWidth, e = this.container.clientHeight;
1728
- this.options.autores && (this.resolution = b.getStandardResolution(t * window.devicePixelRatio, e * window.devicePixelRatio, this.aspectRatioOverride), this.parameters.width = this.resolution.width, this.parameters.height = this.resolution.height), this.canvas2D.resize(t, e, this.getCanvas2DPixelRatio(t, e)), this.canvas3D.resize(t, e, window.devicePixelRatio), this.video.resize(t, e, this.resolution, this.options.fit), this.loadWidget(!1, !1).then(() => {
1729
- this.onHotspotsChange();
1730
- }).catch((i) => {
1731
- this.onLoadError(i);
1732
- });
1733
- }
1734
- onVrcubeInteraction(...t) {
1735
- this.onHotspotsChange(), this.options.events.onInteraction(...t), this.options.events.onVrcubeInteraction(...t);
1736
- }
1737
- onVrobjectInteraction(t) {
1738
- this.onHotspotsChange(), this.options.events.onInteraction(t.position), this.options.events.onVrobjectInteraction(t.position);
1739
- }
1740
- onHotspotsChange() {
1741
- const t = this.widget.hotspots(this.resolution);
1742
- t.length && this.options.events.onHotspotsChange(t);
1743
- }
1744
- onLoadStart(...t) {
1745
- this.container.classList.add("ls-viewer-container-loading"), this.options.events.onLoadStart(...t);
1746
- }
1747
- onLoadProgress(...t) {
1748
- this.options.events.onLoadProgress(...t);
1749
- }
1750
- onLoadEnd(...t) {
1751
- this.container.classList.remove("ls-viewer-container-loading"), this.options.events.onLoadEnd(...t);
1752
- }
1753
- onLoadError(...t) {
1754
- this.container.classList.remove("ls-viewer-container-loading"), this.options.events.onLoadError(...t);
1755
- }
1756
- }
1757
- var q;
1758
- ((v) => {
1759
- ((t) => {
1760
- t.Visible = "Visible", t.Occluded = "Occluded", t.Clipped = "Clipped", t.OutOfFrustum = "OutOfFrustum";
1761
- })(v.HotspotVisibility || (v.HotspotVisibility = {})), ((t) => {
1762
- t.VeryLow = "veryLow", t.Low = "low", t.Medium = "medium", t.Fine = "fine", t.Ultra = "ultra";
1763
- })(v.SunShadowQualityMode || (v.SunShadowQualityMode = {})), ((t) => {
1764
- t.None = "none", t.Weak = "weak", t.Normal = "normal", t.Fine = "fine", t.UltraFine = "ultraFine", t.Max = "max";
1765
- })(v.SunShadowSmoothnessMode || (v.SunShadowSmoothnessMode = {})), ((t) => {
1766
- t.Manual = "manual", t.TimeAndLoc = "timeAndLoc", t.ExtractedFromEnv = "extractedFromEnv";
1767
- })(v.SunUseCaseMode || (v.SunUseCaseMode = {})), ((t) => {
1768
- t.ShowOnly = "showOnly", t.HideOnly = "hideOnly";
1769
- })(v.SurfacesFilterMode || (v.SurfacesFilterMode = {}));
1770
- })(q || (q = {}));
1771
- export {
1772
- nt as Viewer,
1773
- q as WRAPIv2,
1774
- J as WidgetImage,
1775
- tt as WidgetVRCube,
1776
- k as WidgetVRObject,
1777
- it as WidgetVideo
1778
- };
1
+ (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`.ls-viewer-container{-webkit-user-select:none;user-select:none;width:100%;height:100%;display:block;position:relative;overflow:hidden}.ls-viewer-container-image,.ls-viewer-container-video{cursor:default;pointer-events:none}.ls-viewer-container-vrcube{cursor:pointer;cursor:grab;touch-action:none}.ls-viewer-container-vrcube-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-vrobject{cursor:move;cursor:grab;touch-action:none}.ls-viewer-container-vrobject-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-loading{cursor:progress}.ls-viewer-canvas{opacity:0;transition:opacity .5s;position:absolute}.ls-viewer-video{position:absolute}/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();
2
+ import e from "debounce-promise";
3
+ import * as t from "twgl.js";
4
+ import { m4 as n, v3 as r } from "twgl.js";
5
+ import i from "regression";
6
+ //#region src/lib/Resolution.ts
7
+ var a = class {
8
+ constructor(e, t) {
9
+ this.width = e, this.height = t;
10
+ }
11
+ get aspect() {
12
+ return this.width / this.height;
13
+ }
14
+ }, o = class e {
15
+ static {
16
+ this.LANDSCAPE_ASPECT_BOUNDARY = Math.sqrt(4 / 3 * (16 / 9));
17
+ }
18
+ static {
19
+ this.PORTRAIT_ASPECT_BOUNDARY = Math.sqrt(.421875);
20
+ }
21
+ constructor(e, t, n, r) {
22
+ this.top = e, this.left = t, this.width = n, this.height = r;
23
+ }
24
+ static contains(e, t) {
25
+ return t.x >= 0 && t.x < e.width && t.y >= 0 && t.y < e.height;
26
+ }
27
+ static fit(t, n, r) {
28
+ let i = t.aspect, a = n.aspect, o, s;
29
+ switch (r) {
30
+ case "contain":
31
+ o = a < i ? n.width : n.height * i, s = a < i ? n.width / i : n.height;
32
+ break;
33
+ case "cover":
34
+ default:
35
+ o = a < i ? n.height * i : n.width, s = a < i ? n.height : n.width / i;
36
+ break;
37
+ case "fill": o = n.width, s = n.height;
38
+ }
39
+ let c = (n.height - s) / 2, l = (n.width - o) / 2;
40
+ return new e(c, l, o, s);
41
+ }
42
+ static project(t, n, r, i) {
43
+ let a = e.fit(t, n, r), o = a.width / t.width, s = a.height / t.height;
44
+ return {
45
+ x: Math.round(a.left + i.x * o),
46
+ y: Math.round(a.top + i.y * s)
47
+ };
48
+ }
49
+ static unproject(t, n, r, i) {
50
+ let a = e.fit(t, n, r), o = a.width / t.width, s = a.height / t.height;
51
+ return {
52
+ x: Math.round((i.x - a.left) / o),
53
+ y: Math.round((i.y - a.top) / s)
54
+ };
55
+ }
56
+ static getStandardAspectRatio(t, n, r) {
57
+ if (t === 0 || n === 0) return 0;
58
+ if (r) return r;
59
+ let i = t / n;
60
+ return t < n ? i < e.PORTRAIT_ASPECT_BOUNDARY ? 9 / 16 : 3 / 4 : i < e.LANDSCAPE_ASPECT_BOUNDARY ? 4 / 3 : 16 / 9;
61
+ }
62
+ static getStandardResolution(t, n, r) {
63
+ if (t === 0 || n === 0) return new a(0, 0);
64
+ let i = e.getStandardAspectRatio(t, n, r);
65
+ if (r) {
66
+ let r = e.getStandardQuality(Math.min(t, n));
67
+ return new a(Math.round(r * i), Math.round(r));
68
+ }
69
+ if (t < n) {
70
+ let r = e.getStandardQuality(Math.max(n * i, t));
71
+ return new a(Math.round(r), Math.round(r / i));
72
+ }
73
+ let o = e.getStandardQuality(Math.max(t / i, n));
74
+ return new a(Math.round(o * i), Math.round(o));
75
+ }
76
+ static getStandardQuality(e) {
77
+ return e <= 720 ? 720 : 1080;
78
+ }
79
+ }, s = class {
80
+ constructor(e) {
81
+ this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = this.element.getContext("2d"), this.context.imageSmoothingQuality = "high", this.backCanvas = document.createElement("canvas"), this.backContext = this.backCanvas.getContext("2d"), this.backContext.imageSmoothingQuality = "high", this.fit = e;
82
+ }
83
+ destroy() {
84
+ this.requestAnimationId &&= (cancelAnimationFrame(this.requestAnimationId), void 0);
85
+ }
86
+ show(e) {
87
+ e ? this.element.style.display = "block" : this.element.style.opacity = "1";
88
+ }
89
+ hide(e) {
90
+ e ? this.element.style.display = "none" : this.element.style.opacity = "0";
91
+ }
92
+ get resolution() {
93
+ return new a(this.element.clientWidth, this.element.clientHeight);
94
+ }
95
+ resize(e, t, n) {
96
+ let r = Math.floor(e * n), i = Math.floor(t * n);
97
+ this.element.style.width = `${e}px`, this.element.style.height = `${t}px`, (this.element.width !== r || this.element.height !== i) && (this.element.width = r, this.element.height = i, this.context.imageSmoothingQuality = "high", this.backCanvas.width = r, this.backCanvas.height = i, this.backContext.imageSmoothingQuality = "high", this.image && this.draw(this.image, !1));
98
+ }
99
+ draw(e, t, n) {
100
+ if (!e) return;
101
+ this.requestAnimationId &&= (cancelAnimationFrame(this.requestAnimationId), void 0);
102
+ let r = o.fit(new a(e.width, e.height), new a(this.element.width, this.element.height), this.fit);
103
+ t ? (this.backContext.drawImage(this.element, 0, 0), this.context.globalAlpha = 0, this.fadeLoop(e, n || 0)) : (this.context.globalAlpha = 1, this.context.drawImage(e, r.left, r.top, r.width, r.height)), this.image = e;
104
+ }
105
+ fadeLoop(e, t) {
106
+ if (this.context.globalAlpha >= 1) {
107
+ cancelAnimationFrame(this.requestAnimationId), this.requestAnimationId = void 0;
108
+ return;
109
+ }
110
+ let n = Math.min(this.context.globalAlpha + t, 1), r = o.fit(new a(e.width, e.height), new a(this.element.width, this.element.height), this.fit);
111
+ this.context.clearRect(0, 0, this.element.width, this.element.height), this.context.globalAlpha = 1, this.context.drawImage(this.backCanvas, 0, 0), this.context.globalAlpha = n, this.context.drawImage(e, r.left, r.top, r.width, r.height), this.requestAnimationId = requestAnimationFrame(() => {
112
+ this.fadeLoop(e, t);
113
+ });
114
+ }
115
+ }, c = class {
116
+ constructor() {
117
+ this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = t.getContext(this.element, { preserveDrawingBuffer: !0 }), this.context && this.context.isContextLost() && (this.context = void 0), t.setDefaults({ textureColor: [
118
+ 1,
119
+ 1,
120
+ 1,
121
+ 1
122
+ ] });
123
+ }
124
+ show() {
125
+ this.element.style.opacity = "1";
126
+ }
127
+ hide() {
128
+ this.element.style.opacity = "0";
129
+ }
130
+ resize(e, t, n) {
131
+ this.element.width = e * n, this.element.height = t * n, this.element.style.width = `${e}px`, this.element.style.height = `${t}px`;
132
+ }
133
+ }, l = class {
134
+ static accelerate(e, t) {
135
+ return Math.abs(e) ** (t || 1.5) * (e > 0 ? 1 : -1);
136
+ }
137
+ static clamp(e, t, n) {
138
+ return Math.max(Math.min(e, n), t);
139
+ }
140
+ static degreesToRadians(e) {
141
+ return Math.PI / 180 * e;
142
+ }
143
+ static radiansToDegrees(e) {
144
+ return 180 / Math.PI * e;
145
+ }
146
+ static mod(e, t) {
147
+ return e - t * Math.floor(e / t);
148
+ }
149
+ static perspectiveWithFovX(e, t, n, r, i) {
150
+ let a = Math.tan(e / 2), o = a / t;
151
+ return this.perspectiveWithLeft(-a, a, -o, o, n, r, i);
152
+ }
153
+ static perspectiveWithFovY(e, t, n, r, i) {
154
+ let a = n * Math.tan(e / 2), o = a * t;
155
+ return this.perspectiveWithLeft(-o, o, -a, a, n, r, i);
156
+ }
157
+ static perspectiveWithLeft(e, t, n, r, i, a, o) {
158
+ o ||= /* @__PURE__ */ new Float32Array(16);
159
+ let s = t + e, c = t - e, l = r + n, u = r - n, d = a - i;
160
+ return o[0] = 2 * i / c, o[1] = 0, o[2] = 0, o[3] = 0, o[4] = 0, o[5] = 2 * i / u, o[6] = 0, o[7] = 0, o[8] = s / c, o[9] = l / u, o[10] = -a / d, o[11] = -1, o[12] = 0, o[13] = 0, o[14] = -a * i / d, o[15] = 0, o;
161
+ }
162
+ }, u = class e {
163
+ static {
164
+ this.default = new e([
165
+ 0,
166
+ 0,
167
+ 0
168
+ ], [
169
+ 2,
170
+ 2,
171
+ 2
172
+ ], [
173
+ 0,
174
+ 1,
175
+ 0
176
+ ]);
177
+ }
178
+ static initCubeFace(t, n, i) {
179
+ let a = [
180
+ 0,
181
+ 0,
182
+ 0
183
+ ], o = r.subtract(n, t), s = r.mulScalar([
184
+ 0,
185
+ 1,
186
+ 0
187
+ ], r.length(o)), c = r.mulScalar(r.normalize(r.cross(o, s)), r.length(o)), l = r.mulScalar(r.normalize(r.cross(s, c)), r.length(o));
188
+ switch (i) {
189
+ case "front":
190
+ n = r.add(t, l), a = r.normalize(s);
191
+ break;
192
+ case "right":
193
+ n = r.add(t, c), a = r.normalize(s);
194
+ break;
195
+ case "back":
196
+ n = r.subtract(t, l), a = r.normalize(s);
197
+ break;
198
+ case "left":
199
+ n = r.subtract(t, c), a = r.normalize(s);
200
+ break;
201
+ case "up":
202
+ n = r.add(t, s), a = r.normalize(r.mulScalar(l, -1));
203
+ break;
204
+ case "down": n = r.subtract(t, s), a = r.normalize(l);
205
+ }
206
+ return new e(n, t, a);
207
+ }
208
+ constructor(e, t, n) {
209
+ this.target = r.copy(e), this.eye = r.copy(t), this.up = r.copy(n);
210
+ }
211
+ get viewVector() {
212
+ return r.subtract(this.target, this.eye);
213
+ }
214
+ get rightVector() {
215
+ return r.normalize(r.cross(this.viewVector, this.up));
216
+ }
217
+ get viewMatrix() {
218
+ return n.inverse(n.lookAt(this.eye, this.target, this.up));
219
+ }
220
+ clone() {
221
+ return new e(r.copy(this.target), r.copy(this.eye), r.copy(this.up));
222
+ }
223
+ }, d = class {
224
+ constructor(e) {
225
+ this.target = e.target;
226
+ let t = r.normalize(r.subtract(e.eye, e.target)), n = r.dot(t, [
227
+ 1,
228
+ 0,
229
+ 0
230
+ ]), i = r.dot(t, [
231
+ 0,
232
+ 1,
233
+ 0
234
+ ]), a = r.dot(t, [
235
+ 0,
236
+ 0,
237
+ 1
238
+ ]);
239
+ this.longitude = Math.atan2(n, a), this.latitude = Math.atan2(i, Math.sqrt(n * n + a * a)), r.dot(e.up, [
240
+ 0,
241
+ 1,
242
+ 0
243
+ ]) < 0 && (this.longitude = Math.PI + this.longitude, this.latitude = Math.PI - this.latitude), this.distance = r.length(r.subtract(e.target, e.eye));
244
+ }
245
+ get vector() {
246
+ let e = Math.cos(this.latitude) * this.distance, t = Math.sin(this.latitude) * this.distance;
247
+ return [
248
+ Math.cos(this.longitude) * e,
249
+ t,
250
+ Math.sin(this.longitude) * e
251
+ ];
252
+ }
253
+ pointOfView(e) {
254
+ let t = n.rotationY(this.longitude), i = n.rotationX(-this.latitude), a = n.rotationZ(0), o = n.multiply(t, n.multiply(i, a)), s = [
255
+ 0,
256
+ 0,
257
+ -1
258
+ ];
259
+ s = n.transformPoint(o, s);
260
+ let c = [
261
+ 0,
262
+ 1,
263
+ 0
264
+ ];
265
+ return c = n.transformPoint(o, c), new u(e, r.subtract(e, r.mulScalar(s, this.distance)), c);
266
+ }
267
+ }, f = class {
268
+ constructor() {}
269
+ async animation(e, t) {
270
+ return e.scene;
271
+ }
272
+ async database(e) {
273
+ throw Error("Unavailable");
274
+ }
275
+ async image(e, t) {
276
+ return e.scene;
277
+ }
278
+ async video(e) {
279
+ return e.scene;
280
+ }
281
+ async vrCube(e, t) {
282
+ return e.scene;
283
+ }
284
+ async vrObject(e, t) {
285
+ return e.scene;
286
+ }
287
+ }, p = class {
288
+ constructor(e) {
289
+ this.xmlDoc = e;
290
+ }
291
+ get id() {
292
+ return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id");
293
+ }
294
+ getCameraId(e, t) {
295
+ return t ? this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"] Camera[name="${e}"]`)?.getAttribute("id") : this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${e}"]`)?.getAttribute("id");
296
+ }
297
+ getCameraById(e, t) {
298
+ let n;
299
+ return n = e && t ? this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"] Camera[id="${e}"]`) : this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${e}"]`), n ? this.mapElementToCamera(n) : null;
300
+ }
301
+ getCameraByName(e, t) {
302
+ let n;
303
+ return n = t && e ? this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"] Camera[name="${e}"]`) : this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${e}"]`), n ? this.mapElementToCamera(n) : null;
304
+ }
305
+ getCameraGroupId(e) {
306
+ return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"]`)?.getAttribute("id");
307
+ }
308
+ getCameraGroupById(e) {
309
+ let t = this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"]`);
310
+ return t ? this.mapElementToCameraGroup(t) : null;
311
+ }
312
+ getCameraGroupByName(e) {
313
+ let t = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"]`);
314
+ return t ? this.mapElementToCameraGroup(t) : null;
315
+ }
316
+ mapElementToCamera(e) {
317
+ return {
318
+ id: e.getAttribute("id"),
319
+ name: e.getAttribute("name"),
320
+ pointOfView: new u([
321
+ parseFloat(e.querySelector("PointOfView Target").getAttribute("x")),
322
+ parseFloat(e.querySelector("PointOfView Target").getAttribute("y")),
323
+ parseFloat(e.querySelector("PointOfView Target").getAttribute("z"))
324
+ ], [
325
+ parseFloat(e.querySelector("PointOfView Eye").getAttribute("x")),
326
+ parseFloat(e.querySelector("PointOfView Eye").getAttribute("y")),
327
+ parseFloat(e.querySelector("PointOfView Eye").getAttribute("z"))
328
+ ], [
329
+ parseFloat(e.querySelector("PointOfView Up").getAttribute("x")),
330
+ parseFloat(e.querySelector("PointOfView Up").getAttribute("y")),
331
+ parseFloat(e.querySelector("PointOfView Up").getAttribute("z"))
332
+ ])
333
+ };
334
+ }
335
+ mapElementToCameraGroup(e) {
336
+ return {
337
+ id: e.getAttribute("id"),
338
+ name: e.getAttribute("name"),
339
+ cameras: [...e.querySelectorAll("Camera")].map((e) => this.mapElementToCamera(e))
340
+ };
341
+ }
342
+ }, m = class e {
343
+ static {
344
+ this.xmlRegex = /directUrl="([^"]*)"/g;
345
+ }
346
+ constructor(e) {
347
+ this.server = e;
348
+ }
349
+ static buildQuery(e) {
350
+ return Object.entries(e).filter(([e, t]) => t != null).map(([e, t]) => `${e}=${t}`).join("&");
351
+ }
352
+ static sceneParameters(e) {
353
+ let t = e.scene, n = t.length > 1 ? t.find((e) => e.accessory) : null, r = t.length > 1 ? t.find((e) => e.decor) : null, i = t.find((e) => e !== n && e !== r);
354
+ return {
355
+ databaseId: i.database,
356
+ configuration: i?.configuration,
357
+ animations: i?.animations?.join("/"),
358
+ accessoryDatabaseId: n?.database,
359
+ decorDatabaseId: r?.database,
360
+ decorDeltaAltitude: r?.translation?.y
361
+ };
362
+ }
363
+ static renderParameters(e) {
364
+ let { parameters: t, view: n } = e;
365
+ return {
366
+ background: n.background,
367
+ width: t.width,
368
+ height: t.height,
369
+ softwareAntialiasing: t.antialiasing,
370
+ superSampling: t.superSampling
371
+ };
372
+ }
373
+ static encoderParameters(e) {
374
+ let { encoder: t } = e;
375
+ return {
376
+ imageFormat: t.format,
377
+ imageQuality: t.quality
378
+ };
379
+ }
380
+ static async fetch(e, t) {
381
+ return fetch(e, { signal: t }).then((e) => e.text()).then((e) => {
382
+ let t = e.replace(/&amp;/g, "&").match(this.xmlRegex);
383
+ return t ? t.map((e) => e.replace(this.xmlRegex, "$1")) : Promise.reject();
384
+ });
385
+ }
386
+ async animation(t, n) {
387
+ let r = {
388
+ ...e.sceneParameters(t),
389
+ animation: t.view.animation,
390
+ bookmarkSet: t.view.camera.split("/")[0],
391
+ bookmark: t.view.camera.split("/")[1],
392
+ frames: t.view.frames,
393
+ loop: !!t.view.loop,
394
+ ...e.renderParameters(t),
395
+ ...e.encoderParameters(t)
396
+ }, i = e.buildQuery(r);
397
+ return e.fetch(`${this.server}/ImagesFromAnimation?${i}`, n);
398
+ }
399
+ async database(e) {
400
+ return fetch(`${this.server}/Database?databaseId=${e}`).then((e) => e.text()).then((e) => new p(new DOMParser().parseFromString(e, "application/xml")));
401
+ }
402
+ async image(t, n) {
403
+ let r = {
404
+ ...e.sceneParameters(t),
405
+ bookmarkSet: t.view.camera.split("/")[0],
406
+ bookmark: t.view.camera.split("/")[1],
407
+ ...e.renderParameters(t),
408
+ ...e.encoderParameters(t)
409
+ }, i = e.buildQuery(r);
410
+ return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`);
411
+ }
412
+ async video(t) {
413
+ let n = {
414
+ ...e.sceneParameters(t),
415
+ animation: t.view.animation,
416
+ bookmarkSet: t.view.camera.split("/")[0],
417
+ bookmark: t.view.camera.split("/")[1],
418
+ duration: t.view.duration,
419
+ frames: t.view.frames,
420
+ loop: !!t.view.loop,
421
+ reverse: !!t.view.reverse,
422
+ ...e.renderParameters(t),
423
+ ...e.encoderParameters(t)
424
+ }, r = e.buildQuery(n);
425
+ return Promise.resolve(`${this.server}/ImagesFromAnimation?${r}`);
426
+ }
427
+ async vrCube(t, n) {
428
+ let r = {
429
+ ...e.sceneParameters(t),
430
+ bookmarkSet: t.view.camera.split("/")[0],
431
+ bookmark: t.view.camera.split("/")[1],
432
+ ...e.renderParameters(t),
433
+ ...e.encoderParameters(t)
434
+ };
435
+ r.width = Math.max(r.width, r.height), r.height = Math.max(r.width, r.height);
436
+ let i = e.buildQuery(r);
437
+ return e.fetch(`${this.server}/CubeFromBookmark?${i}`, n);
438
+ }
439
+ async vrObject(t, n) {
440
+ let r = {
441
+ ...e.sceneParameters(t),
442
+ bookmarkSet: t.view.camera,
443
+ ...e.renderParameters(t),
444
+ ...e.encoderParameters(t)
445
+ }, i = e.buildQuery(r);
446
+ return e.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`, n);
447
+ }
448
+ }, h = class e {
449
+ constructor(e) {
450
+ this.server = e;
451
+ }
452
+ static scene(e) {
453
+ return e.scene.map((e) => {
454
+ let { accessory: t, decor: n, ...r } = e;
455
+ return r;
456
+ });
457
+ }
458
+ static renderParameters(e) {
459
+ return {
460
+ ...e.parameters,
461
+ superSampling: e.parameters.superSampling.toString()
462
+ };
463
+ }
464
+ static encoder(e) {
465
+ switch (e.encoder.format) {
466
+ case "jpeg": return { jpeg: { quality: e.encoder.quality } };
467
+ case "png": return { png: { compression: e.encoder.compression } };
468
+ case "webp": return { webp: { quality: e.encoder.quality } };
469
+ }
470
+ return { jpeg: { quality: 80 } };
471
+ }
472
+ static async fetchFrame(e, t, n) {
473
+ return fetch(e, {
474
+ method: "POST",
475
+ body: JSON.stringify(t),
476
+ signal: n
477
+ }).then((e) => e.json()).then((e) => e.url);
478
+ }
479
+ static async fetchFrameArray(e, t, n) {
480
+ return fetch(e, {
481
+ method: "POST",
482
+ body: JSON.stringify(t),
483
+ signal: n
484
+ }).then((e) => e.json()).then((e) => e.map((e) => e.url));
485
+ }
486
+ static async fetchHotspots(e, t) {
487
+ return fetch(e, {
488
+ method: "POST",
489
+ body: JSON.stringify(t)
490
+ }).then((e) => e.json());
491
+ }
492
+ static async fetchHotspotsArray(e, t) {
493
+ return fetch(e, {
494
+ method: "POST",
495
+ body: JSON.stringify(t)
496
+ }).then((e) => e.json());
497
+ }
498
+ static async fetchPick(e, t) {
499
+ return fetch(e, {
500
+ method: "POST",
501
+ body: JSON.stringify(t)
502
+ }).then((e) => e.json()).then((e) => e[0]);
503
+ }
504
+ async database(e) {
505
+ return fetch(`${this.server}/Database?databaseId=${e}`).then((e) => e.text()).then((e) => new p(new DOMParser().parseFromString(e, "application/xml")));
506
+ }
507
+ async image(t, n) {
508
+ let r = {
509
+ scene: e.scene(t),
510
+ mode: { image: { camera: t.view.camera } },
511
+ renderParameters: e.renderParameters(t),
512
+ encoder: e.encoder(t)
513
+ };
514
+ return e.fetchFrame(`${this.server}/Snapshot`, r, n);
515
+ }
516
+ async vrCube(t, n) {
517
+ let r = {
518
+ scene: e.scene(t),
519
+ mode: { vrCube: { camera: t.view.camera } },
520
+ renderParameters: e.renderParameters(t),
521
+ encoder: e.encoder(t)
522
+ };
523
+ return r.renderParameters.width = Math.max(r.renderParameters.width, r.renderParameters.height), r.renderParameters.height = Math.max(r.renderParameters.width, r.renderParameters.height), e.fetchFrameArray(`${this.server}/Snapshot`, r, n);
524
+ }
525
+ async vrObject(t, n) {
526
+ let r;
527
+ r = t.view.cameraGroup ? { images: { cameraGroup: t.view.cameraGroup } } : t.view.frames ? { vrObject: {
528
+ camera: t.view.camera,
529
+ frames: t.view.frames
530
+ } } : { vrObject: {
531
+ camera: t.view.camera,
532
+ panFrames: t.view.panFrames || 1,
533
+ panFrom: t.view.panFrom || 0,
534
+ panTo: t.view.panTo || 0,
535
+ panLoop: t.view.panLoop || !1,
536
+ tiltFrames: t.view.tiltFrames || 1,
537
+ tiltFrom: t.view.tiltFrom || 0,
538
+ tiltTo: t.view.tiltTo || 0,
539
+ tiltLoop: t.view.tiltLoop || !1
540
+ } };
541
+ let i = {
542
+ scene: e.scene(t),
543
+ mode: r,
544
+ renderParameters: e.renderParameters(t),
545
+ encoder: e.encoder(t)
546
+ };
547
+ return e.fetchFrameArray(`${this.server}/Snapshot`, i, n);
548
+ }
549
+ async animation(t, n) {
550
+ let r = {
551
+ scene: e.scene(t),
552
+ mode: { animation: {
553
+ id: t.view.animation,
554
+ camera: t.view.camera,
555
+ fps: t.view.fps
556
+ } },
557
+ renderParameters: e.renderParameters(t),
558
+ encoder: e.encoder(t)
559
+ };
560
+ return e.fetchFrameArray(`${this.server}/Snapshot`, r, n);
561
+ }
562
+ async imageHotspots(t, n) {
563
+ let r = {
564
+ scene: e.scene(t),
565
+ mode: { image: { camera: t.view.camera } },
566
+ renderParameters: e.renderParameters(t),
567
+ ...this.hotspotsBody(n)
568
+ };
569
+ return await e.fetchHotspots(`${this.server}/Hotspot`, r);
570
+ }
571
+ async imagePick(t, n) {
572
+ let r = {
573
+ scene: e.scene(t),
574
+ camera: t.view.camera,
575
+ renderParameters: e.renderParameters(t),
576
+ positions: [n]
577
+ };
578
+ return await e.fetchPick(`${this.server}/Pick`, r);
579
+ }
580
+ async vrCubeHotspots(t, n) {
581
+ let r = {
582
+ scene: e.scene(t),
583
+ mode: { vrCube: { camera: t.view.camera } },
584
+ renderParameters: e.renderParameters(t),
585
+ ...this.hotspotsBody(n)
586
+ };
587
+ return r.renderParameters.width = Math.max(r.renderParameters.width, r.renderParameters.height), r.renderParameters.height = Math.max(r.renderParameters.width, r.renderParameters.height), await e.fetchHotspotsArray(`${this.server}/Hotspot`, r);
588
+ }
589
+ async vrObjectHotspots(t, n) {
590
+ let r;
591
+ r = t.view.cameraGroup ? { images: { cameraGroup: t.view.cameraGroup } } : t.view.frames ? { vrObject: {
592
+ camera: t.view.camera,
593
+ frames: t.view.frames
594
+ } } : { vrObject: {
595
+ camera: t.view.camera,
596
+ panFrames: t.view.panFrames || 1,
597
+ panFrom: t.view.panFrom || 0,
598
+ panTo: t.view.panTo || 0,
599
+ panLoop: t.view.panLoop || !1,
600
+ tiltFrames: t.view.tiltFrames || 1,
601
+ tiltFrom: t.view.tiltFrom || 0,
602
+ tiltTo: t.view.tiltTo || 0,
603
+ tiltLoop: t.view.tiltLoop || !1
604
+ } };
605
+ let i = {
606
+ scene: e.scene(t),
607
+ mode: r,
608
+ renderParameters: e.renderParameters(t),
609
+ ...this.hotspotsBody(n)
610
+ };
611
+ return await e.fetchHotspotsArray(`${this.server}/Hotspot`, i);
612
+ }
613
+ hotspotsBody(e) {
614
+ return {
615
+ positions: e.every((e) => typeof e != "string") ? e : void 0,
616
+ tags: e.every((e) => typeof e == "string") ? e : void 0
617
+ };
618
+ }
619
+ }, g = class e {
620
+ constructor(e, t, n) {
621
+ switch (t) {
622
+ case "static":
623
+ this.webrender = new f();
624
+ break;
625
+ case "v1":
626
+ this.webrender = new m(e), this.webrenderV2 = new h(e);
627
+ break;
628
+ case "v2":
629
+ this.webrender = new h(e), this.webrenderV2 = new h(e);
630
+ break;
631
+ default: this.webrender = new m(e), this.webrenderV2 = new h(e);
632
+ }
633
+ this.delegate = n, this.controller = new AbortController(), this.loaded = 0, this.total = 0, this.databases = [], this.onLoadStart = n && n.onLoadStart ? n.onLoadStart : () => {}, this.onLoadProgress = n && n.onLoadProgress ? n.onLoadProgress : () => {}, this.onLoadEnd = n && n.onLoadEnd ? n.onLoadEnd : () => {};
634
+ }
635
+ get progress() {
636
+ return this.total ? this.loaded / this.total : 0;
637
+ }
638
+ renew() {
639
+ return this.controller.abort(), this.controller = new AbortController(), this.controller.signal;
640
+ }
641
+ async loadImageSnapshot(e) {
642
+ let t = this.renew();
643
+ return this.loaded = 0, this.total = 1, this.onLoadStart(this.progress), this.webrender.image(e, t).then((e) => this.loadImage(e, t)).then((e) => (this.onLoadEnd(this.progress), e));
644
+ }
645
+ async loadVideoSnapshot(e, t) {
646
+ let n = this.renew();
647
+ return this.loaded = 0, this.total = 1, this.onLoadStart(this.progress), this.webrender.video(t).then((r) => this.loadVideo(e, r, !!t.view.loop, n)).then(() => (this.onLoadEnd(this.progress), e));
648
+ }
649
+ async loadVRCubeSnapshot(e) {
650
+ let t = this.renew();
651
+ return this.loaded = 0, this.total = 0, this.onLoadStart(this.progress), this.webrender.vrCube(e, t).then((e) => {
652
+ this.total = e.length;
653
+ let n = e.map((e) => this.loadImage(e, t));
654
+ return Promise.all(n);
655
+ }).then((e) => (this.onLoadEnd(this.progress), e));
656
+ }
657
+ async loadVRObjectSnapshot(e, t) {
658
+ let n = this.renew();
659
+ return this.loaded = 0, this.total = 0, this.onLoadStart(this.progress), e.view.animation ? e.encoder?.format === "mp4" ? this.webrender.video(e).then((t) => this.loadVideoFrames(t, e.view.frames, 30, n)) : this.webrender.animation(e, n).then((r) => this.loadImageFrames(r, e.view.loop, t, n)) : this.webrender.vrObject(e, n).then((r) => this.loadImageFrames(r, e.view.loop, t, n));
660
+ }
661
+ async loadImage(t, n) {
662
+ let r = new Image();
663
+ r.crossOrigin = location.protocol === "file:" && !e.isValidHttpUrl(t) ? null : "anonymous";
664
+ let i = new Promise((e, i) => {
665
+ let a = () => {
666
+ r.src = "", i(new DOMException("Image load aborted", "AbortError"));
667
+ };
668
+ if (n.aborted) {
669
+ a();
670
+ return;
671
+ }
672
+ r.addEventListener("load", () => {
673
+ n.removeEventListener("abort", a), this.loaded += 1, this.onLoadProgress(this.progress), e(r);
674
+ }, { once: !0 }), r.addEventListener("error", (e) => {
675
+ n.removeEventListener("abort", a), i(`${e.type} : ${t}`);
676
+ }, { once: !0 }), n.addEventListener("abort", a, { once: !0 });
677
+ });
678
+ return r.src = t, i;
679
+ }
680
+ loadImageFrames(e, t, n, r) {
681
+ this.total = e.length;
682
+ let i = Array(e.length), a = n || 0;
683
+ for (let n = 0, o = e.length; n < o; n += 1) {
684
+ let s = Math.ceil(n / 2) * (n % 2 == 0 ? 1 : -1), c = t ? l.mod(a + s, o) : n;
685
+ i[c] = this.loadImage(e[c], r);
686
+ }
687
+ return Promise.all(i).then(() => this.onLoadEnd(this.progress)).catch((e) => {
688
+ e instanceof DOMException && e.name === "AbortError" || this.onLoadEnd(this.progress);
689
+ }), i;
690
+ }
691
+ async loadVideo(e, t, n, r) {
692
+ e.loop = n;
693
+ let i = new Promise((n, i) => {
694
+ let a = () => {
695
+ e.removeAttribute("src"), e.load(), i(new DOMException("Video load aborted", "AbortError"));
696
+ };
697
+ if (r.aborted) {
698
+ a();
699
+ return;
700
+ }
701
+ e.addEventListener("canplaythrough", () => {
702
+ r.removeEventListener("abort", a), this.loaded += 1, this.onLoadProgress(this.progress), n();
703
+ }, { once: !0 }), e.addEventListener("error", (e) => {
704
+ r.removeEventListener("abort", a), i(`${e.type} : ${t}`);
705
+ }, { once: !0 }), r.addEventListener("abort", a, { once: !0 });
706
+ });
707
+ return e.src = t, e.load(), i;
708
+ }
709
+ async loadVideoFrame(e, t, n, r, i) {
710
+ let a = 0;
711
+ return new Promise((o, s) => {
712
+ let c = () => {
713
+ if (i.aborted) return;
714
+ if (a !== r) {
715
+ a += 1;
716
+ return;
717
+ }
718
+ e.removeEventListener("seeked", c), e.removeEventListener("error", l), i.removeEventListener("abort", u);
719
+ let s = document.createElement("canvas");
720
+ s.width = e.videoWidth, s.height = e.videoHeight, s.getContext("2d").drawImage(e, 0, 0);
721
+ let d = new Image();
722
+ d.src = s.toDataURL(), o(d), this.loaded += 1, this.onLoadProgress(this.progress), r !== n - 1 && (e.currentTime += 1 / t);
723
+ }, l = (e) => {
724
+ i.removeEventListener("abort", u), s(e);
725
+ }, u = () => {
726
+ e.removeEventListener("seeked", c), e.removeEventListener("error", l), s(new DOMException("Video frame load aborted", "AbortError"));
727
+ };
728
+ if (i.aborted) {
729
+ u();
730
+ return;
731
+ }
732
+ e.addEventListener("seeked", c), e.addEventListener("error", l, { once: !0 }), i.addEventListener("abort", u, { once: !0 });
733
+ });
734
+ }
735
+ loadVideoFrames(e, t, n, r) {
736
+ this.total = t;
737
+ let i = Array(t), a = document.createElement("video");
738
+ for (let e = 0, o = t; e < o; e += 1) i[e] = this.loadVideoFrame(a, n, t, e, r);
739
+ return a.addEventListener("canplaythrough", () => {
740
+ r.aborted || (a.currentTime = 1 / n / 2);
741
+ }, { once: !0 }), r.addEventListener("abort", () => {
742
+ a.removeAttribute("src"), a.load();
743
+ }, { once: !0 }), a.src = e, a.load(), Promise.all(i).then(() => this.onLoadEnd(this.progress)).catch((e) => {
744
+ e instanceof DOMException && e.name === "AbortError" || this.onLoadEnd(this.progress);
745
+ }), i;
746
+ }
747
+ async loadImageHotspots(e, t) {
748
+ return this.webrenderV2 ? await this.webrenderV2.imageHotspots(await this.convert(e), t) : Promise.reject(/* @__PURE__ */ Error("Hotspots only available with api V2"));
749
+ }
750
+ async loadVRCubeHotspots(e, t) {
751
+ return this.webrenderV2 ? await this.webrenderV2.vrCubeHotspots(await this.convert(e), t) : Promise.reject(/* @__PURE__ */ Error("Hotspots only available with api V2"));
752
+ }
753
+ async loadVRObjectHotspots(e, t) {
754
+ return this.webrenderV2 ? await this.webrenderV2.vrObjectHotspots(await this.convert(e), t) : Promise.reject(/* @__PURE__ */ Error("Hotspots only available with api V2"));
755
+ }
756
+ async loadImagePick(e, t) {
757
+ return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.convert(e), t) : Promise.reject(/* @__PURE__ */ Error("Picking only available with api V2"));
758
+ }
759
+ async loadVRObjectPick(e, t, n, r) {
760
+ return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(e, n, r), t) : Promise.reject(/* @__PURE__ */ Error("Picking only available with api V2"));
761
+ }
762
+ async loadVRCubePick(e, t, n) {
763
+ return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(e, n), t) : Promise.reject(/* @__PURE__ */ Error("Picking only available with api V2"));
764
+ }
765
+ async convert(e) {
766
+ if (!this.webrenderV2 || this.webrender instanceof h || !e.view.camera) return e;
767
+ let t = e.scene.find((e) => !e.decor && !e.accessory);
768
+ if (!t) return e;
769
+ let n = this.databases.find((e) => e.id === t.database);
770
+ (!n || !n.xmlDoc) && (n = await this.webrender.database(t.database), this.databases.push(n));
771
+ let r = e.view.camera.split("/"), i = r.length === 2 ? r[0] : void 0, a = r.length === 2 ? r[1] : r[0], o = n.getCameraId(a, i);
772
+ if (o) return {
773
+ ...e,
774
+ view: {
775
+ ...e.view,
776
+ camera: o
777
+ }
778
+ };
779
+ {
780
+ let t = n.getCameraGroupId(a);
781
+ return t ? {
782
+ ...e,
783
+ view: {
784
+ ...e.view,
785
+ cameraGroup: t
786
+ }
787
+ } : e;
788
+ }
789
+ }
790
+ async vrObjectFrameSnapshot(e, t, n) {
791
+ if (!this.webrenderV2) return e;
792
+ let r = e.scene.find((e) => !e.decor && !e.accessory);
793
+ if (!r) return e;
794
+ let i = this.databases.find((e) => e.id === r.database);
795
+ if (i || (i = await this.webrender.database(r.database), this.databases.push(i)), this.webrender instanceof m) {
796
+ if (!e.view.camera) return e;
797
+ let n = i.getCameraGroupId(e.view.camera);
798
+ if (!n) return e;
799
+ let r = i.getCameraGroupById(n);
800
+ if (!r) return e;
801
+ let a = r.cameras[t];
802
+ return a ? {
803
+ ...e,
804
+ view: {
805
+ ...e.view,
806
+ camera: a.id
807
+ }
808
+ } : e;
809
+ }
810
+ if (this.webrender instanceof h) {
811
+ let r = typeof e.view.camera == "string" ? e.view.camera : e.view.camera?.id;
812
+ if (r) {
813
+ let a = i.getCameraById(r);
814
+ if (!a) return e;
815
+ let o = new d(a.pointOfView), s = 2 * Math.PI / n;
816
+ o.longitude += t * s % (2 * Math.PI);
817
+ let c = o.pointOfView(a.pointOfView.target);
818
+ return {
819
+ ...e,
820
+ view: {
821
+ ...e.view,
822
+ camera: {
823
+ id: a.id,
824
+ pov: {
825
+ target: {
826
+ x: c.target[0],
827
+ y: c.target[1],
828
+ z: c.target[2]
829
+ },
830
+ eye: {
831
+ x: c.eye[0],
832
+ y: c.eye[1],
833
+ z: c.eye[2]
834
+ },
835
+ up: {
836
+ x: c.up[0],
837
+ y: c.up[1],
838
+ z: c.up[2]
839
+ }
840
+ }
841
+ }
842
+ }
843
+ };
844
+ }
845
+ if (e.view.cameraGroup) {
846
+ let n = i.getCameraGroupById(e.view.cameraGroup);
847
+ if (!n) return e;
848
+ let r = n.cameras[t];
849
+ return r ? {
850
+ ...e,
851
+ view: {
852
+ ...e.view,
853
+ camera: r.id
854
+ }
855
+ } : e;
856
+ }
857
+ return e;
858
+ }
859
+ return e;
860
+ }
861
+ async vrCubeFrameSnapshot(e, t) {
862
+ let n = e.scene.find((e) => !e.decor && !e.accessory);
863
+ if (!n) return e;
864
+ let r = this.databases.find((e) => e.id === n.database);
865
+ if (r || (r = await this.webrender.database(n.database), this.databases.push(r)), !e.view.camera) return e;
866
+ let i;
867
+ if (this.webrender instanceof m) {
868
+ let t = e.view.camera.split("/"), n = t.length === 2 ? t[0] : void 0, a = t.length === 2 ? t[1] : t[0];
869
+ i = r.getCameraId(a, n);
870
+ } else this.webrender instanceof h && (i = typeof e.view.camera == "string" ? e.view.camera : e.view.camera.id);
871
+ if (!i) return e;
872
+ let a = r.getCameraById(i);
873
+ if (!a) return e;
874
+ let o = u.initCubeFace(a.pointOfView.eye, a.pointOfView.target, t);
875
+ return {
876
+ ...e,
877
+ view: {
878
+ ...e.view,
879
+ camera: {
880
+ id: a.id,
881
+ pov: {
882
+ target: {
883
+ x: o.target[0],
884
+ y: o.target[1],
885
+ z: o.target[2]
886
+ },
887
+ eye: {
888
+ x: o.eye[0],
889
+ y: o.eye[1],
890
+ z: o.eye[2]
891
+ },
892
+ up: {
893
+ x: o.up[0],
894
+ y: o.up[1],
895
+ z: o.up[2]
896
+ }
897
+ },
898
+ lens: { fov: 90 }
899
+ }
900
+ },
901
+ parameters: {
902
+ ...e.parameters,
903
+ width: Math.max(e.parameters.width, e.parameters.height),
904
+ height: Math.max(e.parameters.width, e.parameters.height)
905
+ }
906
+ };
907
+ }
908
+ onLoadStart(e) {
909
+ this.delegate && this.delegate.onLoadStart(e);
910
+ }
911
+ onLoadProgress(e) {
912
+ this.delegate && this.delegate.onLoadProgress(e);
913
+ }
914
+ onLoadEnd(e) {
915
+ this.delegate && this.delegate.onLoadEnd(e);
916
+ }
917
+ static isValidHttpUrl(e) {
918
+ let t;
919
+ try {
920
+ t = new URL(e);
921
+ } catch {
922
+ return !1;
923
+ }
924
+ return t.protocol === "http:" || t.protocol === "https:";
925
+ }
926
+ }, _ = class {
927
+ constructor() {
928
+ this.element = document.createElement("video"), this.element.classList.add("ls-viewer-video"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.element.setAttribute("muted", ""), this.element.setAttribute("playsinline", ""), this.element.setAttribute("preload", "auto");
929
+ }
930
+ show() {
931
+ this.element.style.opacity = "1";
932
+ }
933
+ hide() {
934
+ this.element.style.opacity = "0";
935
+ }
936
+ resize(e, t, n, r) {
937
+ let i = o.fit(n, new a(e, t), r);
938
+ this.element.style.top = `${i.top}px`, this.element.style.left = `${i.left}px`, this.element.style.width = `${i.width}px`, this.element.style.height = `${i.height}px`, (n.width !== this.element.width || n.height !== this.element.height) && (this.element.width = n.width, this.element.height = n.height);
939
+ }
940
+ }, v = class {
941
+ constructor(e, t, n) {
942
+ this.container = e, this.canvas = t, this.loader = n, this.hotspotList = [];
943
+ }
944
+ destroy() {}
945
+ show() {
946
+ this.canvas.show(!1), this.container.classList.add("ls-viewer-container-image");
947
+ }
948
+ hide() {
949
+ this.canvas.hide(!1), this.container.classList.remove("ls-viewer-container-image");
950
+ }
951
+ async load(e, t, n, r) {
952
+ let i = Promise.resolve(), a = JSON.stringify(e);
953
+ i = a === this.snapshotHash && this.image ? i.then(() => this.canvas.draw(this.image, r, .05)) : i.then(() => this.loader.loadImageSnapshot(e).then((e) => {
954
+ this.canvas.draw(e, r, .05), this.image = e;
955
+ }));
956
+ let o = JSON.stringify(t);
957
+ return (a !== this.snapshotHash || o !== this.hotspotsHash) && (t.length ? i = i.then(() => this.loader.loadImageHotspots(e, t).then((e) => {
958
+ this.hotspotList = e;
959
+ })) : this.hotspotList = []), this.hotspotsHash = o, this.snapshotHash = a, i;
960
+ }
961
+ async pick(e, t) {
962
+ let n = new a(e.parameters.width, e.parameters.height), r = o.unproject(n, this.canvas.resolution, this.canvas.fit, t);
963
+ return this.loader.loadImagePick(e, r);
964
+ }
965
+ hotspots(e) {
966
+ return this.hotspotList.map((t) => ({
967
+ ...t,
968
+ position2D: o.project(e, this.canvas.resolution, this.canvas.fit, t.position2D)
969
+ })).map((e) => ({
970
+ ...e,
971
+ visibility: o.contains(this.canvas.resolution, e.position2D) ? e.visibility : "OutOfFrustum"
972
+ }));
973
+ }
974
+ snapshot(e, t) {
975
+ return this.canvas.element.toDataURL(e, t);
976
+ }
977
+ onPointerDown(e) {}
978
+ onPointerMove(e) {}
979
+ onPointerUp(e) {}
980
+ onPointerCancel(e) {}
981
+ onDeviceOrientation(e) {}
982
+ }, y = class {
983
+ constructor(...e) {
984
+ e.length === 3 ? ({0: this.u, 1: this.v, 2: this.o} = e, this.w = r.cross(this.u, this.v)) : e.length === 4 ? {0: this.u, 1: this.v, 2: this.w, 3: this.o} = e : (this.u = [
985
+ 1,
986
+ 0,
987
+ 0
988
+ ], this.v = [
989
+ 0,
990
+ 1,
991
+ 0
992
+ ], this.w = [
993
+ 0,
994
+ 0,
995
+ 1
996
+ ], this.o = [
997
+ 0,
998
+ 0,
999
+ 0
1000
+ ]);
1001
+ }
1002
+ get localToGlobalMatrix() {
1003
+ let e = [
1004
+ this.u[0],
1005
+ this.u[1],
1006
+ this.u[2],
1007
+ 0
1008
+ ], t = [
1009
+ this.v[0],
1010
+ this.v[1],
1011
+ this.v[2],
1012
+ 0
1013
+ ], n = [
1014
+ this.w[0],
1015
+ this.w[1],
1016
+ this.w[2],
1017
+ 0
1018
+ ], r = [
1019
+ this.o[0],
1020
+ this.o[1],
1021
+ this.o[2],
1022
+ 1
1023
+ ];
1024
+ return [
1025
+ ...e,
1026
+ ...t,
1027
+ ...n,
1028
+ ...r
1029
+ ];
1030
+ }
1031
+ get globalToLocalMatrix() {
1032
+ return n.inverse(this.localToGlobalMatrix);
1033
+ }
1034
+ }, b = class {
1035
+ constructor(e, t, n) {
1036
+ this.x = e, this.y = t, this.time = n;
1037
+ }
1038
+ }, x = class e {
1039
+ constructor(e, t) {
1040
+ this.x = e, this.y = t;
1041
+ }
1042
+ clone() {
1043
+ return new e(this.x, this.y);
1044
+ }
1045
+ }, S = class {
1046
+ constructor(e) {
1047
+ this.loop = () => {
1048
+ if (Math.abs(this.velocity.x) < 1 && Math.abs(this.velocity.y) < 1) {
1049
+ this.animationFrameId = void 0, this.points = [];
1050
+ return;
1051
+ }
1052
+ this.lastPoint.x += this.velocity.x, this.lastPoint.y += this.velocity.y, this.velocity.x *= .9, this.velocity.y *= .9, this.onMotion(this.lastPoint.clone()), this.animationFrameId = requestAnimationFrame(this.loop);
1053
+ }, this.points = [], this.onMotion = e, this.lastPoint = new x(0, 0), this.velocity = new x(0, 0);
1054
+ }
1055
+ destroy() {
1056
+ this.animationFrameId &&= (cancelAnimationFrame(this.animationFrameId), void 0);
1057
+ }
1058
+ track(e) {
1059
+ let t = Date.now();
1060
+ this.points = this.points.filter((e) => t - e.time <= 100), this.points.push(new b(e.x, e.y, t)), this.lastPoint = e;
1061
+ }
1062
+ start() {
1063
+ if (this.points.length === 0) return;
1064
+ let e = this.points[0], t = this.points[this.points.length - 1], n = t.x - e.x, r = t.y - e.y, i = t.time - e.time;
1065
+ this.velocity = new x(i === 0 ? 0 : n / (i / 15), i === 0 ? 0 : r / (i / 15)), this.animationFrameId &&= (cancelAnimationFrame(this.animationFrameId), void 0), this.animationFrameId = requestAnimationFrame(this.loop);
1066
+ }
1067
+ stop() {
1068
+ this.animationFrameId &&= (cancelAnimationFrame(this.animationFrameId), void 0), this.points = [];
1069
+ }
1070
+ }, C = class {
1071
+ constructor(e, t, i) {
1072
+ this.motion = (e) => {
1073
+ this.isStarted && this.inertia.track(e);
1074
+ let t = {
1075
+ x: e.x - this.previousPoint.x,
1076
+ y: e.y - this.previousPoint.y
1077
+ }, i = l.accelerate(t.x, 1.3) / this.startSize.width * .2 * Math.PI * 1.5, a = l.accelerate(t.y, 1.3) / this.startSize.height * .2 * Math.PI, o = n.multiply(n.rotationY(i), n.rotationX(-a)), s = new y(r.normalize(r.cross(this.pov.up, this.pov.target)), [
1078
+ 0,
1079
+ 1,
1080
+ 0
1081
+ ], this.pov.eye), c = n.identity();
1082
+ n.multiply(c, s.localToGlobalMatrix, c), n.multiply(c, o, c), n.multiply(c, s.globalToLocalMatrix, c);
1083
+ let u = n.transformPoint(c, this.pov.target), d = n.transformDirection(c, this.pov.up);
1084
+ r.cross(d, [
1085
+ 0,
1086
+ 0,
1087
+ 1
1088
+ ])[0] >= 0 && (this.pov.target = u, this.pov.up = d), this.previousPoint = e, this.onMotion();
1089
+ }, this.isStarted = !1, this.pov = e, this.fov = l.degreesToRadians(t), this.orientationMatrix = n.identity(), this.inertia = new S(this.motion), this.onMotion = i, this.initPov = this.pov, this.initFov = this.fov, this.initOrientation = l.degreesToRadians(window.orientation) || 0, this.startPov = new u([
1090
+ 0,
1091
+ 0,
1092
+ 1
1093
+ ], [
1094
+ 0,
1095
+ 0,
1096
+ 0
1097
+ ], [
1098
+ 0,
1099
+ 1,
1100
+ 0
1101
+ ]), this.startSize = {
1102
+ width: 0,
1103
+ height: 0
1104
+ }, this.previousPoint = new x(0, 0);
1105
+ }
1106
+ destroy() {
1107
+ this.inertia.destroy();
1108
+ }
1109
+ get orientedPov() {
1110
+ let e = new y(r.normalize(r.cross(this.pov.up, this.pov.target)), [
1111
+ 0,
1112
+ 1,
1113
+ 0
1114
+ ], this.pov.eye), t = n.identity();
1115
+ n.multiply(t, e.localToGlobalMatrix, t), n.multiply(t, this.orientationMatrix, t), n.multiply(t, e.globalToLocalMatrix, t);
1116
+ let i = n.transformDirection(t, this.pov.target), a = this.pov.eye;
1117
+ return new u(i, a, n.transformDirection(t, this.pov.up));
1118
+ }
1119
+ reset() {
1120
+ this.pov = this.initPov.clone(), this.fov = this.initFov;
1121
+ }
1122
+ start(e, t) {
1123
+ this.isStarted = !0, this.startPov = this.pov, this.startSize = t, this.previousPoint = e, this.inertia.stop();
1124
+ }
1125
+ end(e, t) {
1126
+ this.isStarted = !1, t && (this.inertia.track(e), this.inertia.start());
1127
+ }
1128
+ orientation(e, t, r) {
1129
+ let i = l.degreesToRadians(window.orientation) || 0, a = l.degreesToRadians(e), o = l.degreesToRadians(-t), s = l.degreesToRadians(-r), c = n.rotationX(l.degreesToRadians(90));
1130
+ n.rotateZ(c, this.initOrientation, c), n.rotateZ(c, a, c), n.rotateX(c, o, c), n.rotateY(c, s, c), n.rotateZ(c, -i, c), this.orientationMatrix = c, this.onMotion();
1131
+ }
1132
+ }, w = "precision mediump float;\n\nuniform float u_mix;\nuniform samplerCube u_texture;\nuniform samplerCube u_texture_back;\n\nvarying vec3 direction;\n\nvoid main() {\n vec4 backColor = textureCube(u_texture_back, direction);\n vec4 color = textureCube(u_texture, direction);\n gl_FragColor = mix(backColor, color, u_mix);\n}", T = "attribute vec4 position;\n\nuniform mat4 u_mvpi;\n\nvarying vec3 direction;\n\nvoid main() {\n direction = (u_mvpi * position).xyz;\n gl_Position = position;\n}", E = class {
1133
+ constructor(e, r, i, a, o) {
1134
+ this.render = () => {
1135
+ this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi = n.inverse(this.modelViewProjectionMatrix), this.gl.useProgram(this.programInfo.program), t.setBuffersAndAttributes(this.gl, this.programInfo, this.quad), t.setUniforms(this.programInfo, this.uniforms), t.drawBufferInfo(this.gl, this.quad), this.uniforms.u_mix < 1 && (this.uniforms.u_mix = Math.min(this.uniforms.u_mix + .05, 1), this.animationFrameId = requestAnimationFrame(this.render));
1136
+ }, this.container = e, this.canvas = r, this.loader = i, this.aspectRatioOverride = o, this.images = [], this.hotspotsList = [[]];
1137
+ let s = new u([
1138
+ 0,
1139
+ 0,
1140
+ 1
1141
+ ], [
1142
+ 0,
1143
+ 0,
1144
+ 0
1145
+ ], [
1146
+ 0,
1147
+ 1,
1148
+ 0
1149
+ ]), c = n.rotationX(l.degreesToRadians(15));
1150
+ n.transformDirection(c, s.target, s.target), n.transformDirection(c, s.up, s.up), this.interaction = new C(s, 60, () => {
1151
+ this.animationFrameId = requestAnimationFrame(this.render), this.onInteraction({
1152
+ pov: this.interaction.pov.clone(),
1153
+ fov: this.interaction.fov
1154
+ });
1155
+ }), this.onInteraction = a, this.gl = this.canvas.context, this.programInfo = t.createProgramInfo(this.gl, [`${T}\n`, `${w}\n`]), this.quad = t.primitives.createXYQuadBufferInfo(this.gl), this.uniforms = {
1156
+ u_mvpi: n.identity(),
1157
+ u_mix: 0,
1158
+ u_texture_back: t.createTexture(this.gl, {
1159
+ target: this.gl.TEXTURE_CUBE_MAP,
1160
+ minMag: this.gl.LINEAR,
1161
+ width: 1,
1162
+ height: 1
1163
+ }),
1164
+ u_texture: t.createTexture(this.gl, {
1165
+ target: this.gl.TEXTURE_CUBE_MAP,
1166
+ minMag: this.gl.LINEAR,
1167
+ width: 1,
1168
+ height: 1
1169
+ })
1170
+ };
1171
+ }
1172
+ destroy() {
1173
+ this.interaction.destroy(), this.animationFrameId &&= (cancelAnimationFrame(this.animationFrameId), void 0);
1174
+ }
1175
+ show() {
1176
+ this.canvas.show(), this.container.classList.add("ls-viewer-container-vrcube");
1177
+ }
1178
+ hide() {
1179
+ this.canvas.hide(), this.container.classList.remove("ls-viewer-container-vrcube");
1180
+ }
1181
+ get pov() {
1182
+ return this.interaction.pov;
1183
+ }
1184
+ set pov(e) {
1185
+ this.interaction.pov.eye.every((t, n) => t === e.eye[n]) && this.interaction.pov.target.every((t, n) => t === e.target[n]) && this.interaction.pov.up.every((t, n) => t === e.up[n]) || (this.interaction.pov = e.clone(), this.animationFrameId = requestAnimationFrame(this.render));
1186
+ }
1187
+ get fov() {
1188
+ return l.radiansToDegrees(this.interaction.fov);
1189
+ }
1190
+ set fov(e) {
1191
+ this.interaction.fov !== e && (this.interaction.fov = l.degreesToRadians(e), this.animationFrameId = requestAnimationFrame(this.render));
1192
+ }
1193
+ async load(e, n, r, i) {
1194
+ let a = Promise.resolve();
1195
+ {
1196
+ let t = this.gl.getExtension("WEBGL_debug_renderer_info");
1197
+ t && navigator.platform === "MacIntel" && navigator.userAgent.includes("Chrome") && this.gl.getParameter(t.UNMASKED_RENDERER_WEBGL).includes("OpenGL") && (e.parameters.width = Math.min(e.parameters.width, 1812), e.parameters.height = Math.min(e.parameters.height, 1812));
1198
+ }
1199
+ let o = JSON.stringify(e);
1200
+ o === this.snapshotHash ? a = a.then(() => (this.animationFrameId = requestAnimationFrame(this.render), Promise.resolve())) : (this.images = [], this.animationFrameId = requestAnimationFrame(this.render), a = a.then(() => this.loader.loadVRCubeSnapshot(e).then((e) => {
1201
+ this.images = e, t.createTexture(this.gl, {
1202
+ target: this.gl.TEXTURE_CUBE_MAP,
1203
+ min: this.gl.LINEAR_MIPMAP_LINEAR,
1204
+ minMag: this.gl.LINEAR,
1205
+ cubeFaceOrder: [
1206
+ this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
1207
+ this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,
1208
+ this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,
1209
+ this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
1210
+ this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
1211
+ this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y
1212
+ ],
1213
+ src: e
1214
+ }, (e, t) => {
1215
+ e || (r && this.interaction.reset(), this.uniforms.u_mix = +!i, this.uniforms.u_texture_back = this.uniforms.u_texture, this.uniforms.u_texture = t, this.animationFrameId = requestAnimationFrame(this.render));
1216
+ });
1217
+ })));
1218
+ let s = JSON.stringify(n);
1219
+ return (o !== this.snapshotHash || s !== this.hotspotsHash) && (n.length ? a = a.then(() => this.loader.loadVRCubeHotspots(e, n).then((e) => {
1220
+ this.hotspotsList = e;
1221
+ })) : this.hotspotsList = [[]]), this.hotspotsHash = s, this.snapshotHash = o, a;
1222
+ }
1223
+ async pick(e, t) {
1224
+ let i = this.canvas.element.clientWidth, a = this.canvas.element.clientHeight, o = t.x, s = a - t.y, c = [
1225
+ 2 * o / i - 1,
1226
+ 2 * s / a - 1,
1227
+ 0
1228
+ ], l = this.modelViewProjectionMatrix, u = n.inverse(l), d = r.normalize(n.transformPoint(u, c)), f = Math.max(Math.abs(d[0]), Math.abs(d[1]), Math.abs(d[2])), p;
1229
+ p = Math.abs(d[0]) === f ? d[0] > 0 ? "XPOS" : "XNEG" : Math.abs(d[1]) === f ? d[1] > 0 ? "YPOS" : "YNEG" : d[2] > 0 ? "ZPOS" : "ZNEG";
1230
+ let m = 0, h = 0, g = "";
1231
+ switch (p) {
1232
+ case "XPOS":
1233
+ m = (-d[2] / Math.abs(d[0]) + 1) / 2, h = (-d[1] / Math.abs(d[0]) + 1) / 2, g = "right";
1234
+ break;
1235
+ case "XNEG":
1236
+ m = (d[2] / Math.abs(d[0]) + 1) / 2, h = (-d[1] / Math.abs(d[0]) + 1) / 2, g = "left";
1237
+ break;
1238
+ case "YPOS":
1239
+ m = (d[0] / Math.abs(d[1]) + 1) / 2, h = (d[2] / Math.abs(d[1]) + 1) / 2, g = "up";
1240
+ break;
1241
+ case "YNEG":
1242
+ m = (d[0] / Math.abs(d[1]) + 1) / 2, h = (-d[2] / Math.abs(d[1]) + 1) / 2, g = "down";
1243
+ break;
1244
+ case "ZPOS":
1245
+ m = (d[0] / Math.abs(d[2]) + 1) / 2, h = (-d[1] / Math.abs(d[2]) + 1) / 2, g = "front";
1246
+ break;
1247
+ case "ZNEG": m = (-d[0] / Math.abs(d[2]) + 1) / 2, h = (-d[1] / Math.abs(d[2]) + 1) / 2, g = "back";
1248
+ }
1249
+ let _ = {
1250
+ x: Math.round(m * Math.max(e.parameters.width, e.parameters.height)),
1251
+ y: Math.round(h * Math.max(e.parameters.width, e.parameters.height))
1252
+ };
1253
+ return this.loader.loadVRCubePick(e, _, g);
1254
+ }
1255
+ hotspots() {
1256
+ let e = [];
1257
+ if (this.hotspotsList.length === 0) return [];
1258
+ let t = this.hotspotsList[0]?.length ?? 0, i = this.modelViewProjectionMatrix;
1259
+ for (let s = 0; s < t; s++) {
1260
+ let t = this.hotspotsList.findIndex((e) => e[s].visibility !== "OutOfFrustum");
1261
+ if (t === -1) continue;
1262
+ let c = { ...this.hotspotsList[t][s] }, l = c.position2D.x / this.images[0].width, u = c.position2D.y / this.images[0].height, d = 0, f = 0, p = 0;
1263
+ switch (t) {
1264
+ case 0:
1265
+ this.pov.target[2] < 0 && (c.visibility = "OutOfFrustum"), d = 2 * l - 1, f = 1 - 2 * u, p = 1;
1266
+ break;
1267
+ case 1:
1268
+ this.pov.target[0] > 0 && (c.visibility = "OutOfFrustum"), d = 1, f = 1 - 2 * u, p = 1 - 2 * l;
1269
+ break;
1270
+ case 2:
1271
+ this.pov.target[2] > 0 && (c.visibility = "OutOfFrustum"), d = 1 - 2 * l, f = 1 - 2 * u, p = -1;
1272
+ break;
1273
+ case 3:
1274
+ this.pov.target[0] < 0 && (c.visibility = "OutOfFrustum"), d = -1, f = 1 - 2 * u, p = 2 * l - 1;
1275
+ break;
1276
+ case 4:
1277
+ this.pov.target[1] < 0 && (c.visibility = "OutOfFrustum"), d = 2 * l - 1, f = 1, p = 2 * u - 1;
1278
+ break;
1279
+ case 5: this.pov.target[1] > 0 && (c.visibility = "OutOfFrustum"), d = 2 * l - 1, f = -1, p = 1 - 2 * u;
1280
+ }
1281
+ let m = r.normalize([
1282
+ d,
1283
+ f,
1284
+ p
1285
+ ]), h = n.transformPoint(i, m), g = this.canvas.element.clientWidth, _ = this.canvas.element.clientHeight, v = .5 * g * (h[0] + 1), y = .5 * _ * (h[1] + 1), b = {
1286
+ x: Math.round(v),
1287
+ y: Math.round(_ - y)
1288
+ }, x = new a(g, _), S = o.contains(x, b) ? c.visibility : "OutOfFrustum";
1289
+ e.push({
1290
+ ...c,
1291
+ position2D: b,
1292
+ visibility: S
1293
+ });
1294
+ }
1295
+ return e;
1296
+ }
1297
+ snapshot(e, t) {
1298
+ return this.canvas.element.toDataURL(e, t);
1299
+ }
1300
+ get modelViewProjectionMatrix() {
1301
+ let e = this.canvas.element.clientWidth, t = this.canvas.element.clientHeight, r = e > t ? e / t : t / e, i = o.getStandardAspectRatio(e, t, this.aspectRatioOverride), a = this.interaction.fov * (i / r), s = n.setAxis(n.identity(), [
1302
+ -1,
1303
+ 0,
1304
+ 0
1305
+ ], 0), c = e > t ? l.perspectiveWithFovY(a, e / t, .5, 100) : l.perspectiveWithFovX(a, e / t, .5, 100), u = this.interaction.orientedPov, d = n.inverse(n.lookAt(u.eye, u.target, u.up));
1306
+ return n.multiply(n.multiply(c, d), s);
1307
+ }
1308
+ onPointerDown(e) {
1309
+ this.container.setPointerCapture(e.pointerId), this.container.classList.add("ls-viewer-container-vrcube-grabbing"), this.interaction.start(new x(e.screenX, e.screenY), {
1310
+ width: this.gl.canvas.width,
1311
+ height: this.gl.canvas.height
1312
+ });
1313
+ }
1314
+ onPointerMove(e) {
1315
+ this.interaction.isStarted && (this.interaction.motion(new x(e.screenX, e.screenY)), e.preventDefault());
1316
+ }
1317
+ onPointerUp(e) {
1318
+ this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrcube-grabbing"), this.interaction.end(new x(e.screenX, e.screenY), !0));
1319
+ }
1320
+ onPointerCancel(e) {
1321
+ this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrcube-grabbing"), this.interaction.end(new x(e.screenX, e.screenY), !1));
1322
+ }
1323
+ onDeviceOrientation(e) {
1324
+ this.interaction.orientation(e.alpha, e.beta, e.gamma);
1325
+ }
1326
+ }, D = class {
1327
+ constructor(e, t, n, r, a) {
1328
+ this.motion = (e) => {
1329
+ this.isStarted && this.inertia.track(e), this.lastPoints.push({
1330
+ x: e.x,
1331
+ y: e.y
1332
+ }), this.lastPoints.splice(0, this.lastPoints.length - this.lastPointsNumber);
1333
+ let t = i.linear(this.lastPoints.map((e) => [e.x, e.y]));
1334
+ if (Math.abs(t.equation[0]) < 1) {
1335
+ let t = l.accelerate(e.x - this.startPoint.x, 1.3) / this.startSize.width * (this.frames / 4), n = this.startPosition.x - Math.round(t);
1336
+ n = this.loop ? l.mod(n, this.frames) : Math.max(0, Math.min(n, this.frames - 1)), n !== this.position.x && (this.position.x = n, this.onMotion());
1337
+ let r = Math.min(...this.lastPoints.map((e) => e.x));
1338
+ Math.max(...this.lastPoints.map((e) => e.x)) - r > 25 && (this.startPoint.y = e.y, this.startPosition.y = this.position.y);
1339
+ } else {
1340
+ let t = l.accelerate(e.y - this.startPoint.y, 1.7) / this.startSize.height * (this.rows / 4), n = this.startPosition.y + Math.round(t);
1341
+ n = Math.max(0, Math.min(n, this.rows - 1)), n !== this.position.y && (this.position.y = n, this.onMotion());
1342
+ let r = Math.min(...this.lastPoints.map((e) => e.y));
1343
+ Math.max(...this.lastPoints.map((e) => e.y)) - r > 25 && (this.startPoint.x = e.x, this.startPosition.x = this.position.x);
1344
+ }
1345
+ }, this.isStarted = !1, this.position = e, this.frames = t, this.rows = n, this.loop = r, this.onMotion = a, this.inertia = new S(this.motion), this.initPosition = { ...this.position }, this.startPosition = {
1346
+ x: 0,
1347
+ y: 0
1348
+ }, this.startPoint = new x(0, 0), this.startSize = {
1349
+ width: 0,
1350
+ height: 0
1351
+ }, this.lastPoints = [], this.lastPointsNumber = 20;
1352
+ }
1353
+ destroy() {
1354
+ this.inertia.destroy();
1355
+ }
1356
+ reset() {
1357
+ this.position = { ...this.initPosition };
1358
+ }
1359
+ get positionIndex() {
1360
+ return this.frames * this.position.y + this.position.x;
1361
+ }
1362
+ set positionIndex(e) {
1363
+ if (this.positionIndex === e) return;
1364
+ let t = this.loop ? l.mod(e, this.frames * this.rows) : Math.max(0, Math.min(e, this.frames * this.rows));
1365
+ this.position.x = l.mod(t, this.frames), this.position.y = Math.floor(t / this.frames);
1366
+ }
1367
+ start(e, t) {
1368
+ this.isStarted = !0, this.startPosition = { ...this.position }, this.startPoint = e, this.startSize = t, this.lastPoints = [], this.inertia.stop();
1369
+ }
1370
+ end(e, t) {
1371
+ this.isStarted = !1, t && (this.inertia.track(e), this.inertia.start());
1372
+ }
1373
+ }, O = class {
1374
+ constructor(e, t, n, r) {
1375
+ this.container = e, this.canvas = t, this.loader = n, this.images = [], this.frames = 24, this.hotspotsList = [[]], this.interaction = new D({
1376
+ x: 0,
1377
+ y: 0
1378
+ }, 1, 1, !1, () => {
1379
+ this.canvas.draw(this.image, !0, .5), this.onInteraction({ position: this.interaction.positionIndex });
1380
+ }), this.onInteraction = r;
1381
+ }
1382
+ destroy() {
1383
+ this.animationFrameId &&= (cancelAnimationFrame(this.animationFrameId), void 0);
1384
+ }
1385
+ show() {
1386
+ this.canvas.show(!1), this.container.classList.add("ls-viewer-container-vrobject");
1387
+ }
1388
+ hide() {
1389
+ this.canvas.hide(!1), this.container.classList.remove("ls-viewer-container-vrobject");
1390
+ }
1391
+ async goto(e) {
1392
+ return new Promise((t) => {
1393
+ let n = this.interaction.positionIndex, r = () => {
1394
+ if (this.interaction.positionIndex === e) t();
1395
+ else {
1396
+ let t = n > e ? -1 : 1;
1397
+ this.interaction.loop && this.interaction.frames - n + e < Math.abs(e - n) && (t *= -1), n += .5 * t, this.position = Math.floor(n), this.animationFrameId = requestAnimationFrame(r);
1398
+ }
1399
+ };
1400
+ this.animationFrameId = requestAnimationFrame(r);
1401
+ });
1402
+ }
1403
+ get position() {
1404
+ return this.interaction.positionIndex;
1405
+ }
1406
+ set position(e) {
1407
+ this.interaction.positionIndex = e, this.canvas.draw(this.image, !0, .5);
1408
+ }
1409
+ get image() {
1410
+ return this.images[this.interaction.positionIndex];
1411
+ }
1412
+ async load(e, t, n, r) {
1413
+ let i = Promise.resolve();
1414
+ n && this.interaction.reset();
1415
+ let a = JSON.stringify(e);
1416
+ a === this.snapshotHash && this.image ? i = i.then(() => this.canvas.draw(this.image, r, .05)) : (this.images = [], i = i.then(() => this.loader.loadVRObjectSnapshot(e, this.interaction.positionIndex).then((t) => {
1417
+ let i = t.length;
1418
+ return this.images = Array(i), this.interaction.frames = e.view.frames ?? e.view.panFrames ?? this.frames, this.interaction.rows = i / this.interaction.frames, this.interaction.loop = !!e.view.loop, n && this.interaction.reset(), t.forEach((e, t) => {
1419
+ e.then((e) => {
1420
+ this.images[t] = e, e === this.image && this.canvas.draw(this.image, r, .05);
1421
+ }).catch(() => {});
1422
+ }), t[this.interaction.positionIndex].then(() => Promise.resolve());
1423
+ })));
1424
+ let o = JSON.stringify(t);
1425
+ return (a !== this.snapshotHash || o !== this.hotspotsHash) && (t.length ? i = i.then(() => this.loader.loadVRObjectHotspots(e, t).then((e) => {
1426
+ this.hotspotsList = e;
1427
+ })) : this.hotspotsList = [[]]), this.hotspotsHash = o, this.snapshotHash = a, i;
1428
+ }
1429
+ async pick(e, t) {
1430
+ let n = new a(e.parameters.width, e.parameters.height), r = o.unproject(n, this.canvas.resolution, this.canvas.fit, t);
1431
+ return this.loader.loadVRObjectPick(e, r, this.position, this.frames);
1432
+ }
1433
+ hotspots(e) {
1434
+ return (this.hotspotsList[this.interaction.positionIndex] || []).map((t) => ({
1435
+ ...t,
1436
+ position2D: o.project(e, this.canvas.resolution, this.canvas.fit, t.position2D)
1437
+ })).map((e) => ({
1438
+ ...e,
1439
+ visibility: o.contains(this.canvas.resolution, e.position2D) ? e.visibility : "OutOfFrustum"
1440
+ }));
1441
+ }
1442
+ snapshot(e, t) {
1443
+ return this.canvas.element.toDataURL(e, t);
1444
+ }
1445
+ onPointerDown(e) {
1446
+ this.container.setPointerCapture(e.pointerId), this.container.classList.add("ls-viewer-container-vrobject-grabbing"), this.interaction.start(new x(e.screenX, e.screenY), {
1447
+ width: this.canvas.element.width,
1448
+ height: this.canvas.element.height
1449
+ });
1450
+ }
1451
+ onPointerMove(e) {
1452
+ this.interaction.isStarted && (this.interaction.motion(new x(e.screenX, e.screenY)), e.preventDefault());
1453
+ }
1454
+ onPointerUp(e) {
1455
+ this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrobject-grabbing"), this.interaction.end(new x(e.screenX, e.screenY), !0));
1456
+ }
1457
+ onPointerCancel(e) {
1458
+ this.interaction.isStarted && (this.container.classList.remove("ls-viewer-container-vrobject-grabbing"), this.interaction.end(new x(e.screenX, e.screenY), !1));
1459
+ }
1460
+ onDeviceOrientation(e) {}
1461
+ }, k = class {
1462
+ constructor(e, t, n) {
1463
+ this.container = e, this.loader = n, this.video = t;
1464
+ }
1465
+ destroy() {}
1466
+ show() {
1467
+ this.video.show(), this.container.classList.add("ls-viewer-container-video");
1468
+ }
1469
+ hide() {
1470
+ this.video.hide(), this.container.classList.remove("ls-viewer-container-video");
1471
+ }
1472
+ async load(e) {
1473
+ let t = JSON.stringify(e);
1474
+ return t === this.hash ? (this.video.element.load(), Promise.resolve()) : (this.hash = t, this.loader.loadVideoSnapshot(this.video.element, e));
1475
+ }
1476
+ async pick(e, t) {
1477
+ return Promise.reject();
1478
+ }
1479
+ hotspots(e) {
1480
+ return [];
1481
+ }
1482
+ snapshot(e, t) {
1483
+ return "data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
1484
+ }
1485
+ async play() {
1486
+ return new Promise((e, t) => {
1487
+ this.video.element.addEventListener("ended", () => {
1488
+ e();
1489
+ }, { once: !0 }), this.video.element.play().catch(t), this.show();
1490
+ });
1491
+ }
1492
+ onPointerDown(e) {}
1493
+ onPointerMove(e) {}
1494
+ onPointerUp(e) {}
1495
+ onPointerCancel(e) {}
1496
+ onDeviceOrientation(e) {}
1497
+ }, A = class {
1498
+ constructor(t, n) {
1499
+ this.onPointerDown = (e) => {
1500
+ this.container.addEventListener("pointermove", this.onPointerMove, { passive: !1 }), this.widget.onPointerDown(e);
1501
+ }, this.onPointerMove = (e) => {
1502
+ this.widget.onPointerMove(e);
1503
+ }, this.onPointerUp = (e) => {
1504
+ this.container.removeEventListener("pointermove", this.onPointerMove), this.widget.onPointerUp(e);
1505
+ }, this.onPointerCancel = (e) => {
1506
+ this.container.removeEventListener("pointermove", this.onPointerMove), this.widget.onPointerCancel(e);
1507
+ }, this.onDeviceOrientation = (e) => {
1508
+ this.widget.onDeviceOrientation(e);
1509
+ }, this.onResize = () => {
1510
+ let e = this.container.clientWidth, t = this.container.clientHeight;
1511
+ this.options.autores && (this.resolution = o.getStandardResolution(e * window.devicePixelRatio, t * window.devicePixelRatio, this.aspectRatioOverride), this.parameters.width = this.resolution.width, this.parameters.height = this.resolution.height), this.canvas2D.resize(e, t, this.getCanvas2DPixelRatio(e, t)), this.canvas3D.resize(e, t, window.devicePixelRatio), this.video.resize(e, t, this.resolution, this.options.fit), this.loadWidget(!1, !1).then(() => {
1512
+ this.onHotspotsChange();
1513
+ }).catch((e) => {
1514
+ this.onLoadError(e);
1515
+ });
1516
+ }, this.onVrcubeInteraction = (e) => {
1517
+ this.onHotspotsChange(), this.options.events.onInteraction?.(e), this.options.events.onVrcubeInteraction?.(e);
1518
+ }, this.onVrobjectInteraction = (e) => {
1519
+ this.onHotspotsChange(), this.options.events.onInteraction?.(e.position), this.options.events.onVrobjectInteraction?.(e.position);
1520
+ }, this.onHotspotsChange = () => {
1521
+ let e = this.widget.hotspots(this.resolution);
1522
+ e.length && this.options.events.onHotspotsChange?.(e);
1523
+ }, this.onLoadStart = (e) => {
1524
+ this.container.classList.add("ls-viewer-container-loading"), this.options.events.onLoadStart?.(e);
1525
+ }, this.onLoadProgress = (e) => {
1526
+ this.options.events.onLoadProgress?.(e);
1527
+ }, this.onLoadEnd = (e) => {
1528
+ this.container.classList.remove("ls-viewer-container-loading"), this.options.events.onLoadEnd?.(e);
1529
+ }, this.onLoadError = (e) => {
1530
+ e instanceof DOMException && e.name === "AbortError" || (this.container.classList.remove("ls-viewer-container-loading"), this.options.events.onLoadError?.(e));
1531
+ }, this.options = {
1532
+ server: "localhost",
1533
+ api: "v1",
1534
+ autores: !0,
1535
+ fit: "cover",
1536
+ ...n,
1537
+ events: { ...n.events }
1538
+ }, this.options.events.onLoadError && (this.options.events.onLoadError = e(this.options.events.onLoadError, 10)), this.container = t, this.container.classList.add("ls-viewer-container"), this.canvas2D = new s(this.options.fit), this.container.prepend(this.canvas2D.element), this.canvas3D = new c(), this.container.prepend(this.canvas3D.element), this.video = new _(), this.container.prepend(this.video.element), this.loader = new g(this.options.server, this.options.api, this), this.resolution = new a(0, 0), this.parameters = {
1539
+ width: 0,
1540
+ height: 0,
1541
+ antialiasing: !1,
1542
+ superSampling: 2
1543
+ }, this.encoder = {
1544
+ format: "jpeg",
1545
+ quality: 80
1546
+ }, this.hotspots = [], this.widgetImage = new v(t, this.canvas2D, this.loader), this.widgetVideo = new k(t, this.video, this.loader), this.widgetVRObject = new O(t, this.canvas2D, this.loader, this.onVrobjectInteraction), this.canvas3D.context && (this.widgetVRCube = new E(t, this.canvas3D, this.loader, this.onVrcubeInteraction, this.aspectRatioOverride)), this.widget = this.widgetImage, this.container.addEventListener("pointerdown", this.onPointerDown), this.container.addEventListener("pointerup", this.onPointerUp), this.container.addEventListener("pointercancel", this.onPointerCancel), this.loadWidget = e(this.loadWidget, 10), this.resizeObserver = new ResizeObserver(this.onResize), this.resizeObserver.observe(this.container);
1547
+ }
1548
+ destroy() {
1549
+ this.resizeObserver.disconnect(), this.canvas2D.destroy(), this.container.removeEventListener("pointerdown", this.onPointerDown), this.container.removeEventListener("pointerup", this.onPointerUp), this.container.removeEventListener("pointercancel", this.onPointerCancel), this.container.removeEventListener("pointermove", this.onPointerMove);
1550
+ }
1551
+ async load(e, t) {
1552
+ let n = Promise.resolve();
1553
+ return t?.animation && (n = n.then(() => this.loadAnimation(t.animation))), this.view && t?.fromPosition !== void 0 && this.viewWidget instanceof O && (this.view.mode, n = n.then(() => this.viewWidget.goto(t.fromPosition))), t?.animation && (n = n.then(() => this.widgetVideo.play())), n = n.then(() => (this.scene = Array.isArray(e) ? [...e] : [e], this.loadWidget(!1, !(t && t.animation)))), n.catch((e) => {
1554
+ this.onLoadError(e);
1555
+ }), n;
1556
+ }
1557
+ async setEncoder(e) {
1558
+ this.encoder = { ...e };
1559
+ let t = Promise.resolve();
1560
+ return t = t.then(() => this.loadWidget(!1, !0)), t.catch((e) => {
1561
+ this.onLoadError(e);
1562
+ }), t;
1563
+ }
1564
+ setParameters(e) {
1565
+ if (e.width && e.height) {
1566
+ this.resolution = new a(e.width, e.height);
1567
+ let t = this.container.clientWidth, n = this.container.clientHeight;
1568
+ this.canvas2D.resize(t, n, this.getCanvas2DPixelRatio(t, n));
1569
+ }
1570
+ this.parameters = { ...e }, this.parameters.width = this.resolution.width, this.parameters.height = this.resolution.height;
1571
+ let t = Promise.resolve();
1572
+ return t = t.then(() => this.loadWidget(!1, !0)), t.catch((e) => {
1573
+ this.onLoadError(e);
1574
+ }), t;
1575
+ }
1576
+ setHotspots(e) {
1577
+ this.hotspots = e, this.loadWidget(!1, !1);
1578
+ }
1579
+ async setView(e, t) {
1580
+ let n = Promise.resolve();
1581
+ return t?.animation && (n = n.then(() => this.loadAnimation(t.animation))), this.view && t?.fromPosition !== void 0 && this.viewWidget instanceof O && (n = n.then(() => this.viewWidget.goto(t.fromPosition))), t?.animation && (n = n.then(() => this.widgetVideo.play())), n = n.then(() => {
1582
+ let n = !0;
1583
+ return this.view = { ...e }, this.view && this.viewWidget instanceof O && t?.toPosition !== void 0 && (n = !1, this.viewWidget.position = t.toPosition), this.loadWidget(n, !(t && t.animation));
1584
+ }), n.catch((e) => {
1585
+ this.onLoadError(e);
1586
+ }), n;
1587
+ }
1588
+ setVrcube(e) {
1589
+ this.widgetVRCube && Object.assign(this.widgetVRCube, e);
1590
+ }
1591
+ setVrobject(e) {
1592
+ Object.assign(this.widgetVRObject, e);
1593
+ }
1594
+ async loadAnimation(e) {
1595
+ let t = {
1596
+ scene: this.scene,
1597
+ view: {
1598
+ animation: e.name,
1599
+ camera: e.camera,
1600
+ duration: e.duration,
1601
+ loop: e.loop,
1602
+ reverse: e.reverse
1603
+ },
1604
+ parameters: this.parameters,
1605
+ encoder: { format: "mp4" }
1606
+ };
1607
+ return t.view?.background || (t.view.background = "product"), this.widgetVideo.load(t).then(() => Promise.resolve());
1608
+ }
1609
+ async playAnimation(e) {
1610
+ return this.loadAnimation(e).then(() => this.widgetVideo.play()).catch((e) => {
1611
+ this.onLoadError(e);
1612
+ });
1613
+ }
1614
+ stopAnimation() {
1615
+ this.widgetVideo.hide();
1616
+ }
1617
+ async pick(e) {
1618
+ if (!this.scene) throw Error("No scene set");
1619
+ if (!this.view) throw Error("No view set");
1620
+ if (!this.view.camera && !this.view.cameraGroup) throw Error("No camera set");
1621
+ let t = {
1622
+ scene: this.scene,
1623
+ view: this.view,
1624
+ parameters: this.parameters,
1625
+ encoder: this.encoder
1626
+ };
1627
+ return await this.viewWidget.pick(t, e);
1628
+ }
1629
+ async pickHotspot(e) {
1630
+ let t = await this.pick(e), n = Object.values(t.point), i = r.normalize(Object.values(t.normal)), a = r.add(n, r.mulScalar(i, .01));
1631
+ return t.point = {
1632
+ x: a[0],
1633
+ y: a[1],
1634
+ z: a[2]
1635
+ }, t;
1636
+ }
1637
+ snapshot(e, t) {
1638
+ return this.viewWidget.snapshot(e, t);
1639
+ }
1640
+ async loadWidget(e, t) {
1641
+ if (!this.scene || !this.view || !this.parameters.width || !this.parameters.height) return Promise.resolve();
1642
+ let n = this.viewWidget;
1643
+ if (!n) return Promise.reject(/* @__PURE__ */ Error("Unknown view mode"));
1644
+ let r = {
1645
+ scene: this.scene,
1646
+ view: this.view,
1647
+ parameters: this.parameters,
1648
+ encoder: this.encoder
1649
+ };
1650
+ return r.view.background || (r.view.background = "product"), n.load(r, this.hotspots, e, t).then(() => {
1651
+ this.widget.hide(), this.widget = n, this.widget.show(), this.widgetVideo.hide(), this.onHotspotsChange();
1652
+ });
1653
+ }
1654
+ get aspectRatioOverride() {
1655
+ switch (this.options.aspectRatio) {
1656
+ case "4:3": return 4 / 3;
1657
+ case "16:9": return 16 / 9;
1658
+ default: return;
1659
+ }
1660
+ }
1661
+ get viewWidget() {
1662
+ switch (this.view?.mode) {
1663
+ case "image": return this.widgetImage;
1664
+ case "video": return this.widgetVideo;
1665
+ case "vrcube": return this.widgetVRCube ?? this.widgetImage;
1666
+ case "vrobject": return this.widgetVRObject;
1667
+ default: return this.widgetImage;
1668
+ }
1669
+ }
1670
+ getCanvas2DPixelRatio(e, t) {
1671
+ return e <= 0 || t <= 0 || this.resolution.width <= 0 || this.resolution.height <= 0 ? window.devicePixelRatio : Math.min(window.devicePixelRatio, this.resolution.width / e, this.resolution.height / t);
1672
+ }
1673
+ }, j;
1674
+ (function(e) {
1675
+ e.HotspotVisibility = /* @__PURE__ */ function(e) {
1676
+ return e.Visible = "Visible", e.Occluded = "Occluded", e.Clipped = "Clipped", e.OutOfFrustum = "OutOfFrustum", e;
1677
+ }({}), e.SunShadowQualityMode = /* @__PURE__ */ function(e) {
1678
+ return e.VeryLow = "veryLow", e.Low = "low", e.Medium = "medium", e.Fine = "fine", e.Ultra = "ultra", e;
1679
+ }({}), e.SunShadowSmoothnessMode = /* @__PURE__ */ function(e) {
1680
+ return e.None = "none", e.Weak = "weak", e.Normal = "normal", e.Fine = "fine", e.UltraFine = "ultraFine", e.Max = "max", e;
1681
+ }({}), e.SunUseCaseMode = /* @__PURE__ */ function(e) {
1682
+ return e.Manual = "manual", e.TimeAndLoc = "timeAndLoc", e.ExtractedFromEnv = "extractedFromEnv", e;
1683
+ }({}), e.SurfacesFilterMode = /* @__PURE__ */ function(e) {
1684
+ return e.ShowOnly = "showOnly", e.HideOnly = "hideOnly", e;
1685
+ }({});
1686
+ })(j ||= {});
1687
+ //#endregion
1688
+ export { A as Viewer, j as WRAPIv2, v as WidgetImage, E as WidgetVRCube, O as WidgetVRObject, k as WidgetVideo };