@virtualdisplay.io/client 4.0.0-alpha.7 → 4.0.0-alpha.9

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.
@@ -1,4 +1,4 @@
1
- import { n as e } from "./chunk-efA98nb6.js";
1
+ import { n as e } from "./chunk-C_CI6nMA.js";
2
2
  //#region src/client/error.ts
3
3
  var t = {
4
4
  NO_MAPPING: "NO_MAPPING",
@@ -66,7 +66,7 @@ var t = {
66
66
  }
67
67
  buildUrl() {
68
68
  let e = this.getServerUrl(), t = new URL(e);
69
- return t.searchParams.set("license", this.options.license), t.searchParams.set("model", this.options.model), this.options.language !== void 0 && t.searchParams.set("language", this.options.language), this.options.debug === !0 && t.searchParams.set("debug", "true"), t.toString();
69
+ return t.searchParams.set("license", this.options.license), t.searchParams.set("model", this.options.model), this.options.language !== void 0 && t.searchParams.set("language", this.options.language), this.options.debug === !0 && t.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && t.searchParams.set("traceparent", this.options.traceparent), t.toString();
70
70
  }
71
71
  getServerUrl() {
72
72
  return this.defaultServer;
@@ -101,28 +101,48 @@ function o(e, t) {
101
101
  e.level === "error" ? console.error(n) : e.level === "warn" ? console.warn(n) : console.log(n);
102
102
  }
103
103
  //#endregion
104
+ //#region ../logger/src/serialise.ts
105
+ function s(e, t = 0) {
106
+ let n = {
107
+ name: e.name,
108
+ message: e.message
109
+ };
110
+ e.stack !== void 0 && (n.stack = e.stack);
111
+ for (let t of Object.getOwnPropertyNames(e)) {
112
+ if (t === "name" || t === "message" || t === "stack" || t === "cause") continue;
113
+ let r = e[t];
114
+ r !== void 0 && (n[t] = r);
115
+ }
116
+ return e.cause !== void 0 && e.cause !== null && (n.cause = e.cause instanceof Error && t < 5 ? s(e.cause, t + 1) : String(e.cause)), n;
117
+ }
118
+ function c(e) {
119
+ let t = {};
120
+ for (let [n, r] of Object.entries(e)) t[n] = r instanceof Error ? s(r) : r;
121
+ return t;
122
+ }
123
+ //#endregion
104
124
  //#region ../utils/src/date.ts
105
- function s() {
125
+ function l() {
106
126
  return /* @__PURE__ */ new Date();
107
127
  }
108
- function c(e) {
128
+ function u(e) {
109
129
  return e.toISOString();
110
130
  }
111
131
  //#endregion
112
132
  //#region ../logger/src/logger.ts
113
- var l = class e {
133
+ var d = class e {
114
134
  constructor(e) {
115
135
  this.config = e;
116
136
  }
117
137
  log(e, t, n = {}) {
118
138
  let r = this.config.traceProvider?.() ?? {};
119
139
  o({
120
- timestamp: c(s()),
140
+ timestamp: u(l()),
121
141
  level: e,
122
142
  msg: t,
123
143
  service: this.config.service,
124
144
  ...r,
125
- ...n
145
+ ...c(n)
126
146
  }, this.config.isDev);
127
147
  }
128
148
  debug(e, t) {
@@ -147,8 +167,8 @@ var l = class e {
147
167
  }).bind(this), n;
148
168
  }
149
169
  };
150
- function u(e, t) {
151
- return new l({
170
+ function f(e, t) {
171
+ return new d({
152
172
  service: e,
153
173
  isDev: t?.isDev === void 0 ? typeof process < "u" ? process.env.NODE_ENV !== "production" : !0 : t.isDev,
154
174
  traceProvider: t?.traceProvider
@@ -156,34 +176,34 @@ function u(e, t) {
156
176
  }
157
177
  //#endregion
158
178
  //#region src/utils/logger.ts
159
- function d(e) {
179
+ function p(e) {
160
180
  if (e !== void 0) return typeof e == "object" && e && !Array.isArray(e) && !(e instanceof Error) ? e : e instanceof Error ? { error: e.message } : { value: e };
161
181
  }
162
- function f(e) {
182
+ function m(e) {
163
183
  return {
164
- debug: (t, n) => e.debug(t, d(n)),
165
- info: (t, n) => e.info(t, d(n)),
166
- warn: (t, n) => e.warn(t, d(n)),
167
- error: (t, n) => e.error(t, d(n))
184
+ debug: (t, n) => e.debug(t, p(n)),
185
+ info: (t, n) => e.info(t, p(n)),
186
+ warn: (t, n) => e.warn(t, p(n)),
187
+ error: (t, n) => e.error(t, p(n))
168
188
  };
169
189
  }
170
- var p = !1, m = f(u("client", { isDev: !1 }));
171
- function h() {
172
- p = !0, m = f(u("client", { isDev: !0 }));
190
+ var h = !1, g = m(f("client", { isDev: !1 }));
191
+ function _() {
192
+ h = !0, g = m(f("client", { isDev: !0 }));
173
193
  }
174
- function g() {
175
- return p;
194
+ function ee() {
195
+ return h;
176
196
  }
177
197
  //#endregion
178
198
  //#region src/client/ready-state-tracker.ts
179
- var _ = class {
199
+ var te = class {
180
200
  ready = !1;
181
201
  onReady;
182
202
  constructor(e) {
183
203
  this.onReady = e;
184
204
  }
185
205
  handleMappingReceived() {
186
- this.ready || (this.ready = !0, m.info("Mapping received from server, client is now ready"), this.onReady?.());
206
+ this.ready || (this.ready = !0, g.info("Mapping received from server, client is now ready"), this.onReady?.());
187
207
  }
188
208
  get isReady() {
189
209
  return this.ready;
@@ -191,102 +211,7 @@ var _ = class {
191
211
  clear() {
192
212
  this.ready = !1;
193
213
  }
194
- }, v = class {
195
- isSelectedValue = !1;
196
- constructor(e, t) {
197
- this.value = e, this.attribute = t;
198
- }
199
- get isSelected() {
200
- return this.isSelectedValue;
201
- }
202
- setSelected(e) {
203
- this.isSelectedValue = e;
204
- }
205
- }, ee = class {
206
- name;
207
- defaultValue;
208
- values;
209
- onSelect;
210
- onChangeCallback;
211
- constructor(e) {
212
- this.name = e.name, this.defaultValue = e.defaultValue, this.onSelect = e.onSelect, this.values = this.createValues(e.values);
213
- }
214
- select(e) {
215
- if (!this.values.has(e)) throw n.valueNotFound(this.name, e);
216
- this.onSelect(this.name, e);
217
- }
218
- getValues() {
219
- return Array.from(this.values.values());
220
- }
221
- getValue(e) {
222
- return this.values.get(e);
223
- }
224
- onChange(e) {
225
- this.onChangeCallback = e;
226
- }
227
- handleResult(e) {
228
- let t;
229
- for (let n of this.values.values()) {
230
- let r = n.value === e;
231
- n.setSelected(r), r && (t = n);
232
- }
233
- t !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(t);
234
- }
235
- createValues(e) {
236
- let t = /* @__PURE__ */ new Map();
237
- for (let n of e) {
238
- let e = new v(n, this.name);
239
- n === this.defaultValue && e.setSelected(!0), t.set(n, e);
240
- }
241
- return t;
242
- }
243
- }, te = class {
244
- attributes = /* @__PURE__ */ new Map();
245
- constructor(e, t, n) {
246
- for (let n of e) {
247
- let e = this.buildOptions(n, t);
248
- this.attributes.set(n.name, new ee(e));
249
- }
250
- this.onMutationFailed = n;
251
- }
252
- onMutationFailed;
253
- get(e) {
254
- return this.attributes.get(e);
255
- }
256
- defaults() {
257
- let e = [];
258
- for (let t of this.attributes.values()) t.defaultValue !== void 0 && e.push({
259
- name: t.name,
260
- value: t.defaultValue
261
- });
262
- return e;
263
- }
264
- handleResults(e) {
265
- for (let t of e) {
266
- if (!t.success) {
267
- this.onMutationFailed?.(t.name, t.value);
268
- continue;
269
- }
270
- this.get(t.name)?.handleResult(t.value);
271
- }
272
- }
273
- buildOptions(e, t) {
274
- let n = {
275
- name: e.name,
276
- values: e.values,
277
- onSelect: (e, n) => {
278
- t([{
279
- name: e,
280
- value: n
281
- }], !1);
282
- }
283
- };
284
- return e.defaultValue === void 0 ? n : {
285
- ...n,
286
- defaultValue: e.defaultValue
287
- };
288
- }
289
- }, y = {
214
+ }, v = {
290
215
  HANDSHAKE: "handshake",
291
216
  MUTATION: "mutation",
292
217
  STATE: "state",
@@ -296,47 +221,54 @@ var _ = class {
296
221
  MAPPING: "mapping",
297
222
  AR_ACTIVATE: "ar_activate",
298
223
  CONFIG: "config",
299
- INTERACTION: "interaction"
300
- }, ne = new Set(Object.values(y));
224
+ INTERACTION: "interaction",
225
+ ANNOTATION_PLACE_MODE: "annotation_place_mode",
226
+ ANNOTATION_PLACED: "annotation_placed",
227
+ ANNOTATION_TOGGLE: "annotation_toggle"
228
+ }, ne = new Set(Object.values(v));
301
229
  function re(e) {
302
230
  if (typeof e != "object" || !e) return !1;
303
231
  let t = e;
304
232
  return typeof t.target == "string" ? !1 : typeof t.type == "string" && ne.has(t.type);
305
233
  }
306
234
  function ie(e) {
307
- let t = b(e);
308
- return t !== null && t.type === y.HANDSHAKE;
235
+ let t = y(e);
236
+ return t !== null && t.type === v.HANDSHAKE;
309
237
  }
310
238
  function ae(e) {
311
- let t = b(e);
312
- return t !== null && t.type === y.MUTATION && Array.isArray(t.results);
239
+ let t = y(e);
240
+ return t !== null && t.type === v.MUTATION && Array.isArray(t.results);
313
241
  }
314
242
  function oe(e) {
315
- let t = b(e);
316
- return t !== null && t.type === y.SNAPSHOT && ("data" in t || "error" in t);
243
+ let t = y(e);
244
+ return t !== null && t.type === v.SNAPSHOT && ("data" in t || "error" in t);
317
245
  }
318
246
  function se(e) {
319
- let t = b(e);
320
- return t !== null && t.type === y.CAMERA && Array.isArray(t.transforms);
247
+ let t = y(e);
248
+ return t !== null && t.type === v.CAMERA && Array.isArray(t.transforms);
321
249
  }
322
250
  function ce(e) {
323
- let t = b(e);
324
- return t !== null && t.type === y.MAPPING && Array.isArray(t.attributes);
251
+ let t = y(e);
252
+ return t !== null && t.type === v.MAPPING && Array.isArray(t.attributes);
325
253
  }
326
254
  function le(e) {
327
- let t = b(e);
328
- return t !== null && t.type === y.LOADING_INDICATOR && typeof t.progress == "number";
255
+ let t = y(e);
256
+ return t !== null && t.type === v.LOADING_INDICATOR && typeof t.progress == "number";
329
257
  }
330
258
  function ue(e) {
331
- let t = b(e);
332
- return t !== null && t.type === y.CONFIG && typeof t.viewerSettings == "object";
259
+ let t = y(e);
260
+ return t !== null && t.type === v.CONFIG && typeof t.viewerSettings == "object";
261
+ }
262
+ function de(e) {
263
+ let t = y(e);
264
+ return t !== null && t.type === v.ANNOTATION_PLACED && typeof t.position == "object" && t.position !== null;
333
265
  }
334
- function b(e) {
266
+ function y(e) {
335
267
  return typeof e != "object" || !e ? null : e;
336
268
  }
337
269
  //#endregion
338
270
  //#region ../messaging/src/queue.ts
339
- var de = class {
271
+ var b = class {
340
272
  pending = [];
341
273
  isReady = !1;
342
274
  constructor(e) {
@@ -374,8 +306,9 @@ var de = class {
374
306
  shouldBuffer;
375
307
  listener = null;
376
308
  sourceId;
309
+ targetOrigin;
377
310
  constructor(e, t) {
378
- this.getTarget = e, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.publisher = new de((e) => this.post(e)), this.consumer = new de((e) => this.routeToHandler(e)), this.shouldBuffer = t?.shouldBuffer ?? null, t?.bufferIncoming !== !0 && this.consumer.markReady();
311
+ this.getTarget = e, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = t?.targetOrigin ?? "*", this.publisher = new b((e) => this.post(e)), this.consumer = new b((e) => this.routeToHandler(e)), this.shouldBuffer = t?.shouldBuffer ?? null, t?.bufferIncoming !== !0 && this.consumer.markReady();
379
312
  }
380
313
  on(e, t) {
381
314
  this.handlers.set(e, t);
@@ -383,6 +316,9 @@ var de = class {
383
316
  off(e) {
384
317
  this.handlers.delete(e);
385
318
  }
319
+ setTargetOrigin(e) {
320
+ this.targetOrigin = e;
321
+ }
386
322
  send(e) {
387
323
  this.publisher.enqueue(e);
388
324
  }
@@ -399,12 +335,14 @@ var de = class {
399
335
  this.listener === null && (this.listener = (e) => {
400
336
  let { data: t } = e;
401
337
  if (!re(t) || t._source === this.sourceId) return;
402
- let n = t;
403
- if (this.shouldBuffer !== null && !this.shouldBuffer(n)) {
404
- this.routeToHandler(n);
338
+ let n = this.getTarget();
339
+ if (n !== null && e.source !== null && e.source !== n) return;
340
+ let r = t;
341
+ if (this.shouldBuffer !== null && !this.shouldBuffer(r)) {
342
+ this.routeToHandler(r);
405
343
  return;
406
344
  }
407
- this.consumer.enqueue(n);
345
+ this.consumer.enqueue(r);
408
346
  }, window.addEventListener("message", this.listener));
409
347
  }
410
348
  destroy() {
@@ -421,7 +359,7 @@ var de = class {
421
359
  t !== null && t.postMessage({
422
360
  ...e,
423
361
  _source: this.sourceId
424
- }, "*");
362
+ }, this.targetOrigin);
425
363
  }
426
364
  routeToHandler(e) {
427
365
  let t = this.handlers.get(e.type);
@@ -433,17 +371,141 @@ var de = class {
433
371
  });
434
372
  }
435
373
  };
436
- new Set([y.CAMERA]);
374
+ new Set([v.CAMERA]);
437
375
  //#endregion
438
- //#region src/attributes/attributes.ts
376
+ //#region src/annotations/annotations.ts
439
377
  var pe = class {
378
+ placedCallbacks = [];
379
+ constructor(e) {
380
+ this.send = e;
381
+ }
382
+ setEnabled(e) {
383
+ this.send({
384
+ type: v.ANNOTATION_TOGGLE,
385
+ enabled: e
386
+ });
387
+ }
388
+ startPlacing() {
389
+ this.send({
390
+ type: v.ANNOTATION_PLACE_MODE,
391
+ enabled: !0
392
+ });
393
+ }
394
+ stopPlacing() {
395
+ this.send({
396
+ type: v.ANNOTATION_PLACE_MODE,
397
+ enabled: !1
398
+ });
399
+ }
400
+ onPlaced(e) {
401
+ this.placedCallbacks.push(e);
402
+ }
403
+ handlePlaced(e) {
404
+ for (let t of this.placedCallbacks) t(e);
405
+ }
406
+ }, me = class {
407
+ isSelectedValue = !1;
408
+ constructor(e, t) {
409
+ this.value = e, this.attribute = t;
410
+ }
411
+ get isSelected() {
412
+ return this.isSelectedValue;
413
+ }
414
+ setSelected(e) {
415
+ this.isSelectedValue = e;
416
+ }
417
+ }, x = class {
418
+ name;
419
+ defaultValue;
420
+ values;
421
+ onSelect;
422
+ onChangeCallback;
423
+ constructor(e) {
424
+ this.name = e.name, this.defaultValue = e.defaultValue, this.onSelect = e.onSelect, this.values = this.createValues(e.values);
425
+ }
426
+ select(e) {
427
+ if (!this.values.has(e)) throw n.valueNotFound(this.name, e);
428
+ this.onSelect(this.name, e);
429
+ }
430
+ getValues() {
431
+ return Array.from(this.values.values());
432
+ }
433
+ getValue(e) {
434
+ return this.values.get(e);
435
+ }
436
+ onChange(e) {
437
+ this.onChangeCallback = e;
438
+ }
439
+ handleResult(e) {
440
+ let t;
441
+ for (let n of this.values.values()) {
442
+ let r = n.value === e;
443
+ n.setSelected(r), r && (t = n);
444
+ }
445
+ t !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(t);
446
+ }
447
+ createValues(e) {
448
+ let t = /* @__PURE__ */ new Map();
449
+ for (let n of e) {
450
+ let e = new me(n, this.name);
451
+ n === this.defaultValue && e.setSelected(!0), t.set(n, e);
452
+ }
453
+ return t;
454
+ }
455
+ }, he = class {
456
+ attributes = /* @__PURE__ */ new Map();
457
+ constructor(e, t, n) {
458
+ for (let n of e) {
459
+ let e = this.buildOptions(n, t);
460
+ this.attributes.set(n.name, new x(e));
461
+ }
462
+ this.onMutationFailed = n;
463
+ }
464
+ onMutationFailed;
465
+ get(e) {
466
+ return this.attributes.get(e);
467
+ }
468
+ defaults() {
469
+ let e = [];
470
+ for (let t of this.attributes.values()) t.defaultValue !== void 0 && e.push({
471
+ name: t.name,
472
+ value: t.defaultValue
473
+ });
474
+ return e;
475
+ }
476
+ handleResults(e) {
477
+ for (let t of e) {
478
+ if (!t.success) {
479
+ this.onMutationFailed?.(t.name, t.value);
480
+ continue;
481
+ }
482
+ this.get(t.name)?.handleResult(t.value);
483
+ }
484
+ }
485
+ buildOptions(e, t) {
486
+ let n = {
487
+ name: e.name,
488
+ values: e.values,
489
+ onSelect: (e, n) => {
490
+ t([{
491
+ name: e,
492
+ value: n
493
+ }], !1);
494
+ }
495
+ };
496
+ return e.defaultValue === void 0 ? n : {
497
+ ...n,
498
+ defaultValue: e.defaultValue
499
+ };
500
+ }
501
+ }, ge = class {
440
502
  registry;
441
503
  pendingCallbacks = [];
442
504
  constructor(e, t) {
443
505
  this.send = e, this.onMutationFailed = t;
444
506
  }
445
507
  handleMappingReceived(e) {
446
- m.debug("Initializing from server mapping", { attributeCount: e.attributes.length }), this.registry = new te(e.attributes, (e, t) => this.sendMutation(e, t), this.onMutationFailed), this.replayPendingCallbacks();
508
+ g.debug("Initializing from server mapping", { attributeCount: e.attributes.length }), this.registry = new he(e.attributes, (e, t) => this.sendMutation(e, t), this.onMutationFailed), this.replayPendingCallbacks();
447
509
  }
448
510
  handleMutationResult(e) {
449
511
  this.registry?.handleResults(e.results);
@@ -470,7 +532,7 @@ var pe = class {
470
532
  }
471
533
  let n = this.registry.get(e);
472
534
  if (n === void 0) {
473
- m.warn(`onChange: attribute "${e}" not found — callback will not fire`);
535
+ g.warn(`onChange: attribute "${e}" not found — callback will not fire`);
474
536
  return;
475
537
  }
476
538
  n.onChange(t);
@@ -483,7 +545,7 @@ var pe = class {
483
545
  }
484
546
  sendMutation(e, t) {
485
547
  let n = {
486
- type: y.MUTATION,
548
+ type: v.MUTATION,
487
549
  mutations: e,
488
550
  isInitial: t
489
551
  };
@@ -492,11 +554,11 @@ var pe = class {
492
554
  replayPendingCallbacks() {
493
555
  for (let { name: e, callback: t } of this.pendingCallbacks) {
494
556
  let n = this.registry?.get(e);
495
- n === void 0 && m.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`), n?.onChange(t);
557
+ n === void 0 && g.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`), n?.onChange(t);
496
558
  }
497
559
  this.pendingCallbacks.length = 0;
498
560
  }
499
- }, x = class {
561
+ }, _e = class {
500
562
  commands = [];
501
563
  constructor(e) {
502
564
  this.send = e;
@@ -522,7 +584,7 @@ var pe = class {
522
584
  set() {
523
585
  if (this.commands.length === 0) throw n.invalidParameter("No camera commands to execute. Call rotate(), tilt(), or zoom() before set().");
524
586
  let e = {
525
- type: y.CAMERA,
587
+ type: v.CAMERA,
526
588
  commands: this.commands
527
589
  };
528
590
  this.send(e), this.commands = [];
@@ -532,12 +594,12 @@ var pe = class {
532
594
  }
533
595
  reset() {
534
596
  let e = {
535
- type: y.CAMERA,
597
+ type: v.CAMERA,
536
598
  commands: [{ action: "reset" }]
537
599
  };
538
600
  this.send(e);
539
601
  }
540
- }, me = class {
602
+ }, ve = class {
541
603
  state;
542
604
  limitsState;
543
605
  changeCallbacks = [];
@@ -598,7 +660,7 @@ var pe = class {
598
660
  for (let t of this.changeCallbacks) t(e);
599
661
  }
600
662
  }
601
- }, S = class {
663
+ }, ye = class {
602
664
  developedCallbacks = /* @__PURE__ */ new Set();
603
665
  errorCallbacks = /* @__PURE__ */ new Set();
604
666
  developed = !1;
@@ -626,24 +688,24 @@ var pe = class {
626
688
  t(e);
627
689
  }), this.developedCallbacks.clear(), this.errorCallbacks.clear());
628
690
  }
629
- }, C = class {
691
+ }, S = class {
630
692
  validExtensions = [".png"];
631
693
  pendingPhotos = /* @__PURE__ */ new Map();
632
694
  constructor(e) {
633
695
  this.send = e;
634
696
  }
635
697
  take(e) {
636
- this.validateFilename(e), m.debug("Taking snapshot", { filename: e });
637
- let t = new S(e);
698
+ this.validateFilename(e), g.debug("Taking snapshot", { filename: e });
699
+ let t = new ye(e);
638
700
  return this.pendingPhotos.set(t.getFilename(), t), this.send({
639
- type: y.SNAPSHOT,
701
+ type: v.SNAPSHOT,
640
702
  filename: e
641
703
  }), t;
642
704
  }
643
705
  handleSnapshotResult(e) {
644
706
  let r = this.pendingPhotos.get(e.filename);
645
707
  if (r === void 0) {
646
- m.warn("No pending photo found for filename", {
708
+ g.warn("No pending photo found for filename", {
647
709
  filename: e.filename,
648
710
  pendingFilenames: Array.from(this.pendingPhotos.keys())
649
711
  });
@@ -663,7 +725,7 @@ var pe = class {
663
725
  if (!this.validExtensions.some((t) => e.toLowerCase().endsWith(t))) throw new n(`Invalid filename: "${e}". Filename must end with one of: ${this.validExtensions.join(", ")}`, t.INVALID_PARAMETER);
664
726
  if (e.includes("..") || e.includes("/") || e.includes("\\")) throw new n("Filename cannot contain path separators or \"..\"", t.INVALID_PARAMETER);
665
727
  }
666
- }, he = class {
728
+ }, be = class {
667
729
  container = null;
668
730
  attach(e) {
669
731
  this.container = e;
@@ -689,70 +751,70 @@ var pe = class {
689
751
  this.container?.removeEventListener(e, n);
690
752
  };
691
753
  }
692
- }, ge = {}, w = [
754
+ }, xe = {}, C = [
693
755
  "en",
694
756
  "nl",
695
757
  "de"
696
- ], T = ["baseLocale"], _e = [], ve, ye;
697
- function be(e) {
698
- if (_e.length === 0) return;
758
+ ], w = ["baseLocale"], T = [], E, D;
759
+ function Se(e) {
760
+ if (T.length === 0) return;
699
761
  let t = typeof e == "string" ? e : e.href;
700
- if (ve === t) return ye;
762
+ if (E === t) return D;
701
763
  let n = new URL(t, "http://dummy.com"), r;
702
- for (let e of _e) if (new ge(e.match, n.href).exec(n.href)) {
764
+ for (let e of T) if (new xe(e.match, n.href).exec(n.href)) {
703
765
  r = e;
704
766
  break;
705
767
  }
706
- return ve = t, ye = r, r;
768
+ return E = t, D = r, r;
707
769
  }
708
- function E(e) {
709
- let t = be(e);
710
- return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : T;
770
+ function O(e) {
771
+ let t = Se(e);
772
+ return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : w;
711
773
  }
712
- var D = void 0, O = typeof window > "u";
774
+ var k = void 0, A = typeof window > "u";
713
775
  globalThis.__paraglide = globalThis.__paraglide ?? {}, globalThis.__paraglide.ssr = globalThis.__paraglide.ssr ?? {};
714
- var k = !1, A = () => {
715
- if (D) {
716
- let e = D?.getStore()?.locale;
776
+ var j = !1, M = () => {
777
+ if (k) {
778
+ let e = k?.getStore()?.locale;
717
779
  if (e) return e;
718
780
  }
719
- let e = T;
720
- !O && typeof window < "u" && window.location?.href && (e = E(window.location.href));
721
- let t = xe(e, typeof window < "u" ? window.location?.href : void 0);
722
- if (t) return k || (k = !0, j(t, { reload: !1 })), t;
781
+ let e = w;
782
+ !A && typeof window < "u" && window.location?.href && (e = O(window.location.href));
783
+ let t = Ce(e, typeof window < "u" ? window.location?.href : void 0);
784
+ if (t) return j || (j = !0, N(t, { reload: !1 })), t;
723
785
  throw Error("No locale found. Read the docs https://inlang.com/m/gerre34r/library-inlang-paraglideJs/errors#no-locale-found");
724
786
  };
725
- function xe(e, t) {
787
+ function Ce(e, t) {
726
788
  let n;
727
789
  for (let t of e) {
728
790
  if (t === "baseLocale") n = "en";
729
- else if (we(t) && N.has(t)) {
730
- let e = N.get(t);
791
+ else if (Ee(t) && F.has(t)) {
792
+ let e = F.get(t);
731
793
  if (e) {
732
794
  let t = e.getLocale();
733
795
  if (t instanceof Promise) continue;
734
- if (t !== void 0) return Ce(t);
796
+ if (t !== void 0) return Te(t);
735
797
  }
736
798
  }
737
- let e = M(n);
799
+ let e = P(n);
738
800
  if (e) return e;
739
801
  }
740
802
  }
741
- var Se = (e) => {
803
+ var we = (e) => {
742
804
  e ? window.location.href = e : window.location.reload();
743
- }, j = (e, t) => {
805
+ }, N = (e, t) => {
744
806
  let n = {
745
807
  reload: !0,
746
808
  ...t
747
809
  }, r;
748
810
  try {
749
- r = A();
811
+ r = M();
750
812
  } catch {}
751
- let i = [], a = T;
752
- !O && typeof window < "u" && window.location?.href && (a = E(window.location.href));
813
+ let i = [], a = w;
814
+ !A && typeof window < "u" && window.location?.href && (a = O(window.location.href));
753
815
  for (let t of a) if (t === "baseLocale") continue;
754
- else if (we(t) && N.has(t)) {
755
- let n = N.get(t);
816
+ else if (Ee(t) && F.has(t)) {
817
+ let n = F.get(t);
756
818
  if (n) {
757
819
  let r = n.setLocale(e);
758
820
  r instanceof Promise && (r = r.catch((e) => {
@@ -761,78 +823,78 @@ var Se = (e) => {
761
823
  }
762
824
  }
763
825
  let o = () => {
764
- !O && n.reload && window.location && e !== r && Se(void 0);
826
+ !A && n.reload && window.location && e !== r && we(void 0);
765
827
  };
766
828
  if (i.length) return Promise.all(i).then(() => {
767
829
  o();
768
830
  });
769
831
  o();
770
832
  };
771
- function M(e) {
833
+ function P(e) {
772
834
  if (typeof e != "string") return;
773
835
  let t = e.toLowerCase();
774
- for (let e of w) if (e.toLowerCase() === t) return e;
836
+ for (let e of C) if (e.toLowerCase() === t) return e;
775
837
  }
776
- function Ce(e) {
777
- let t = M(e);
838
+ function Te(e) {
839
+ let t = P(e);
778
840
  if (t) return t;
779
- throw Error(`Invalid locale: ${e}. Expected one of: ${w.join(", ")}`);
841
+ throw Error(`Invalid locale: ${e}. Expected one of: ${C.join(", ")}`);
780
842
  }
781
- var N = /* @__PURE__ */ new Map();
782
- function we(e) {
843
+ var F = /* @__PURE__ */ new Map();
844
+ function Ee(e) {
783
845
  return typeof e == "string" && /^custom-[A-Za-z0-9_-]+$/.test(e);
784
846
  }
785
847
  //#endregion
786
848
  //#region ../i18n/src/paraglide-viewer/messages/controls_ar_buttonlabel1.js
787
- var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivieren", Oe = ((e = {}, t = {}) => {
788
- let n = t.locale ?? A();
789
- return n === "en" ? Te(e) : n === "nl" ? Ee(e) : De(e);
790
- }), ke = () => "Scan to view in AR", Ae = () => "Scan om in AR te bekijken", je = () => "Scannen für AR-Ansicht", Me = ((e = {}, t = {}) => {
791
- let n = t.locale ?? A();
792
- return n === "en" ? ke(e) : n === "nl" ? Ae(e) : je(e);
793
- }), Ne = () => "Use your smartphone camera to scan this QR code", Pe = () => "Gebruik de camera van uw smartphone om deze QR-code te scannen", Fe = () => "Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen", Ie = ((e = {}, t = {}) => {
794
- let n = t.locale ?? A();
795
- return n === "en" ? Ne(e) : n === "nl" ? Pe(e) : Fe(e);
796
- }), Le = () => "The 3D model will open in your phone's AR mode", Re = () => "Het 3D-model wordt geopend in de AR-modus van uw telefoon", ze = () => "Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet", Be = ((e = {}, t = {}) => {
797
- let n = t.locale ?? A();
798
- return n === "en" ? Le(e) : n === "nl" ? Re(e) : ze(e);
799
- }), Ve = () => "Close", He = () => "Sluiten", Ue = () => "Schließen", We = ((e = {}, t = {}) => {
800
- let n = t.locale ?? A();
801
- return n === "en" ? Ve(e) : n === "nl" ? He(e) : Ue(e);
802
- }), Ge = () => "Toggle fullscreen", Ke = () => "Volledig scherm", qe = () => "Vollbild umschalten", Je = ((e = {}, t = {}) => {
803
- let n = t.locale ?? A();
804
- return n === "en" ? Ge(e) : n === "nl" ? Ke(e) : qe(e);
805
- }), Ye = () => "Downloading", Xe = () => "Downloaden", Ze = () => "Herunterladen", Qe = ((e = {}, t = {}) => {
806
- let n = t.locale ?? A();
807
- return n === "en" ? Ye(e) : n === "nl" ? Xe(e) : Ze(e);
808
- }), $e = () => "Rendering", et = () => "Renderen", tt = () => "Rendern", nt = ((e = {}, t = {}) => {
809
- let n = t.locale ?? A();
810
- return n === "en" ? $e(e) : n === "nl" ? et(e) : tt(e);
811
- }), rt = () => "Screenshot", it = () => "Screenshot", at = () => "Screenshot", ot = ((e = {}, t = {}) => {
812
- let n = t.locale ?? A();
813
- return n === "en" ? rt(e) : n === "nl" ? it(e) : at(e);
814
- }), st = () => "Reset camera", ct = () => "Camera resetten", lt = () => "Kamera zurücksetzen", ut = ((e = {}, t = {}) => {
815
- let n = t.locale ?? A();
816
- return n === "en" ? st(e) : n === "nl" ? ct(e) : lt(e);
817
- }), dt = () => "Zoom in", ft = () => "Inzoomen", pt = () => "Hineinzoomen", mt = ((e = {}, t = {}) => {
818
- let n = t.locale ?? A();
819
- return n === "en" ? dt(e) : n === "nl" ? ft(e) : pt(e);
820
- }), ht = () => "Zoom out", gt = () => "Uitzoomen", _t = () => "Herauszoomen", vt = ((e = {}, t = {}) => {
821
- let n = t.locale ?? A();
822
- return n === "en" ? ht(e) : n === "nl" ? gt(e) : _t(e);
823
- }), yt = () => "Rotate left", bt = () => "Naar links draaien", xt = () => "Nach links drehen", St = ((e = {}, t = {}) => {
824
- let n = t.locale ?? A();
825
- return n === "en" ? yt(e) : n === "nl" ? bt(e) : xt(e);
826
- }), Ct = () => "Rotate right", wt = () => "Naar rechts draaien", Tt = () => "Nach rechts drehen", Et = ((e = {}, t = {}) => {
827
- let n = t.locale ?? A();
828
- return n === "en" ? Ct(e) : n === "nl" ? wt(e) : Tt(e);
829
- }), Dt = () => "Tilt up", Ot = () => "Omhoog kantelen", kt = () => "Nach oben kippen", At = ((e = {}, t = {}) => {
830
- let n = t.locale ?? A();
831
- return n === "en" ? Dt(e) : n === "nl" ? Ot(e) : kt(e);
832
- }), jt = () => "Tilt down", Mt = () => "Omlaag kantelen", Nt = () => "Nach unten kippen", Pt = ((e = {}, t = {}) => {
833
- let n = t.locale ?? A();
834
- return n === "en" ? jt(e) : n === "nl" ? Mt(e) : Nt(e);
835
- }), Ft = {
849
+ var De = () => "Activate AR", Oe = () => "AR activeren", ke = () => "AR aktivieren", Ae = ((e = {}, t = {}) => {
850
+ let n = t.locale ?? M();
851
+ return n === "en" ? De(e) : n === "nl" ? Oe(e) : ke(e);
852
+ }), je = () => "Scan to view in AR", Me = () => "Scan om in AR te bekijken", Ne = () => "Scannen für AR-Ansicht", Pe = ((e = {}, t = {}) => {
853
+ let n = t.locale ?? M();
854
+ return n === "en" ? je(e) : n === "nl" ? Me(e) : Ne(e);
855
+ }), Fe = () => "Use your smartphone camera to scan this QR code", Ie = () => "Gebruik de camera van je smartphone om deze QR-code te scannen", Le = () => "Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen", Re = ((e = {}, t = {}) => {
856
+ let n = t.locale ?? M();
857
+ return n === "en" ? Fe(e) : n === "nl" ? Ie(e) : Le(e);
858
+ }), ze = () => "The 3D model will open in your phone's AR mode", Be = () => "Het 3D-model wordt geopend in de AR-modus van je telefoon", Ve = () => "Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet", He = ((e = {}, t = {}) => {
859
+ let n = t.locale ?? M();
860
+ return n === "en" ? ze(e) : n === "nl" ? Be(e) : Ve(e);
861
+ }), Ue = () => "Close", We = () => "Sluiten", Ge = () => "Schließen", Ke = ((e = {}, t = {}) => {
862
+ let n = t.locale ?? M();
863
+ return n === "en" ? Ue(e) : n === "nl" ? We(e) : Ge(e);
864
+ }), qe = () => "Toggle fullscreen", Je = () => "Volledig scherm", Ye = () => "Vollbild umschalten", Xe = ((e = {}, t = {}) => {
865
+ let n = t.locale ?? M();
866
+ return n === "en" ? qe(e) : n === "nl" ? Je(e) : Ye(e);
867
+ }), Ze = () => "Downloading", Qe = () => "Downloaden", $e = () => "Herunterladen", et = ((e = {}, t = {}) => {
868
+ let n = t.locale ?? M();
869
+ return n === "en" ? Ze(e) : n === "nl" ? Qe(e) : $e(e);
870
+ }), tt = () => "Rendering", nt = () => "Renderen", rt = () => "Rendern", it = ((e = {}, t = {}) => {
871
+ let n = t.locale ?? M();
872
+ return n === "en" ? tt(e) : n === "nl" ? nt(e) : rt(e);
873
+ }), at = () => "Screenshot", ot = () => "Screenshot", st = () => "Screenshot", ct = ((e = {}, t = {}) => {
874
+ let n = t.locale ?? M();
875
+ return n === "en" ? at(e) : n === "nl" ? ot(e) : st(e);
876
+ }), lt = () => "Reset camera", ut = () => "Camera resetten", dt = () => "Kamera zurücksetzen", ft = ((e = {}, t = {}) => {
877
+ let n = t.locale ?? M();
878
+ return n === "en" ? lt(e) : n === "nl" ? ut(e) : dt(e);
879
+ }), pt = () => "Zoom in", mt = () => "Inzoomen", ht = () => "Hineinzoomen", gt = ((e = {}, t = {}) => {
880
+ let n = t.locale ?? M();
881
+ return n === "en" ? pt(e) : n === "nl" ? mt(e) : ht(e);
882
+ }), _t = () => "Zoom out", vt = () => "Uitzoomen", yt = () => "Herauszoomen", bt = ((e = {}, t = {}) => {
883
+ let n = t.locale ?? M();
884
+ return n === "en" ? _t(e) : n === "nl" ? vt(e) : yt(e);
885
+ }), xt = () => "Rotate left", St = () => "Naar links draaien", Ct = () => "Nach links drehen", wt = ((e = {}, t = {}) => {
886
+ let n = t.locale ?? M();
887
+ return n === "en" ? xt(e) : n === "nl" ? St(e) : Ct(e);
888
+ }), Tt = () => "Rotate right", Et = () => "Naar rechts draaien", Dt = () => "Nach rechts drehen", Ot = ((e = {}, t = {}) => {
889
+ let n = t.locale ?? M();
890
+ return n === "en" ? Tt(e) : n === "nl" ? Et(e) : Dt(e);
891
+ }), kt = () => "Tilt up", At = () => "Omhoog kantelen", jt = () => "Nach oben kippen", Mt = ((e = {}, t = {}) => {
892
+ let n = t.locale ?? M();
893
+ return n === "en" ? kt(e) : n === "nl" ? At(e) : jt(e);
894
+ }), Nt = () => "Tilt down", Pt = () => "Omlaag kantelen", Ft = () => "Nach unten kippen", It = ((e = {}, t = {}) => {
895
+ let n = t.locale ?? M();
896
+ return n === "en" ? Nt(e) : n === "nl" ? Pt(e) : Ft(e);
897
+ }), Lt = {
836
898
  xmlns: "http://www.w3.org/2000/svg",
837
899
  width: 24,
838
900
  height: 24,
@@ -842,40 +904,40 @@ var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivier
842
904
  "stroke-width": 2,
843
905
  "stroke-linecap": "round",
844
906
  "stroke-linejoin": "round"
845
- }, It = ([e, t, n]) => {
907
+ }, Rt = ([e, t, n]) => {
846
908
  let r = document.createElementNS("http://www.w3.org/2000/svg", e);
847
909
  return Object.keys(t).forEach((e) => {
848
910
  r.setAttribute(e, String(t[e]));
849
911
  }), n?.length && n.forEach((e) => {
850
- let t = It(e);
912
+ let t = Rt(e);
851
913
  r.appendChild(t);
852
914
  }), r;
853
- }, Lt = (e, t = {}) => It([
915
+ }, zt = (e, t = {}) => Rt([
854
916
  "svg",
855
917
  {
856
- ...Ft,
918
+ ...Lt,
857
919
  ...t
858
920
  },
859
921
  e
860
- ]), Rt = [
922
+ ]), Bt = [
861
923
  ["path", { d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" }],
862
924
  ["path", { d: "m3.3 7 8.7 5 8.7-5" }],
863
925
  ["path", { d: "M12 22V12" }]
864
- ], zt = [["path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }], ["circle", {
926
+ ], Vt = [["path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }], ["circle", {
865
927
  cx: "12",
866
928
  cy: "13",
867
929
  r: "3"
868
- }]], Bt = [["path", { d: "m6 9 6 6 6-6" }]], Vt = [["path", { d: "m15 18-6-6 6-6" }]], Ht = [["path", { d: "m9 18 6-6-6-6" }]], Ut = [["path", { d: "m18 15-6-6-6 6" }]], Wt = [
930
+ }]], Ht = [["path", { d: "m6 9 6 6 6-6" }]], Ut = [["path", { d: "m15 18-6-6 6-6" }]], Wt = [["path", { d: "m9 18 6-6-6-6" }]], Gt = [["path", { d: "m18 15-6-6-6 6" }]], Kt = [
869
931
  ["path", { d: "M15 3h6v6" }],
870
932
  ["path", { d: "m21 3-7 7" }],
871
933
  ["path", { d: "m3 21 7-7" }],
872
934
  ["path", { d: "M9 21H3v-6" }]
873
- ], Gt = [
935
+ ], qt = [
874
936
  ["path", { d: "m14 10 7-7" }],
875
937
  ["path", { d: "M20 10h-6V4" }],
876
938
  ["path", { d: "m3 21 7-7" }],
877
939
  ["path", { d: "M4 14h6v6" }]
878
- ], Kt = [["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { d: "M3 3v5h5" }]], qt = [
940
+ ], Jt = [["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { d: "M3 3v5h5" }]], Yt = [
879
941
  ["circle", {
880
942
  cx: "11",
881
943
  cy: "11",
@@ -899,7 +961,7 @@ var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivier
899
961
  y1: "11",
900
962
  y2: "11"
901
963
  }]
902
- ], Jt = [
964
+ ], Xt = [
903
965
  ["circle", {
904
966
  cx: "11",
905
967
  cy: "11",
@@ -920,26 +982,26 @@ var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivier
920
982
  ];
921
983
  //#endregion
922
984
  //#region ../ui/src/icons.ts
923
- function P(e, { size: t = 20, strokeWidth: n = 1.75 } = {}) {
924
- return Lt(e, {
985
+ function I(e, { size: t = 20, strokeWidth: n = 1.75 } = {}) {
986
+ return zt(e, {
925
987
  width: t,
926
988
  height: t,
927
989
  "stroke-width": n
928
990
  });
929
991
  }
930
- var F = {
931
- ar: (e) => P(Rt, e),
932
- fullscreen: (e) => P(Wt, e),
933
- exitFullscreen: (e) => P(Gt, e),
934
- screenshot: (e) => P(zt, e),
935
- tiltUp: (e) => P(Ut, e),
936
- tiltDown: (e) => P(Bt, e),
937
- rotateLeft: (e) => P(Vt, e),
938
- rotateRight: (e) => P(Ht, e),
939
- zoomIn: (e) => P(qt, e),
940
- zoomOut: (e) => P(Jt, e),
941
- reset: (e) => P(Kt, e)
942
- }, I = class {
992
+ var L = {
993
+ ar: (e) => I(Bt, e),
994
+ fullscreen: (e) => I(Kt, e),
995
+ exitFullscreen: (e) => I(qt, e),
996
+ screenshot: (e) => I(Vt, e),
997
+ tiltUp: (e) => I(Gt, e),
998
+ tiltDown: (e) => I(Ht, e),
999
+ rotateLeft: (e) => I(Ut, e),
1000
+ rotateRight: (e) => I(Wt, e),
1001
+ zoomIn: (e) => I(Yt, e),
1002
+ zoomOut: (e) => I(Xt, e),
1003
+ reset: (e) => I(Jt, e)
1004
+ }, R = class {
943
1005
  element;
944
1006
  constructor({ variant: e = "default", size: t = "default", label: n, icon: r, onClick: i, disabled: a = !1 } = {}) {
945
1007
  this.element = document.createElement("button"), this.element.className = `ui-btn ui-btn--${e} ui-btn--size-${t}`, n !== void 0 && (this.element.setAttribute("aria-label", n), this.element.title = n), r === void 0 ? n !== void 0 && (this.element.textContent = n) : this.element.appendChild(r), i && this.element.addEventListener("click", i), this.element.disabled = a;
@@ -948,7 +1010,7 @@ var F = {
948
1010
  let t = this.element.querySelector("svg");
949
1011
  t === null ? this.element.appendChild(e) : t.replaceWith(e);
950
1012
  }
951
- }, L = {
1013
+ }, z = {
952
1014
  brand: {
953
1015
  DEFAULT: "#171717",
954
1016
  primary: "#171717",
@@ -987,7 +1049,7 @@ var F = {
987
1049
  },
988
1050
  white: "#ffffff",
989
1051
  black: "#000000"
990
- }, R = {
1052
+ }, B = {
991
1053
  px: "1px",
992
1054
  0: "0",
993
1055
  .5: "0.125rem",
@@ -1010,27 +1072,27 @@ var F = {
1010
1072
  20: "5rem",
1011
1073
  24: "6rem"
1012
1074
  };
1013
- R[1], R[2], R[4], R[6], R[8], R[12];
1075
+ B[1], B[2], B[4], B[6], B[8], B[12];
1014
1076
  //#endregion
1015
1077
  //#region ../ui/src/vanilla/components/card/index.ts
1016
- var Yt = class {
1078
+ var Zt = class {
1017
1079
  element;
1018
1080
  constructor() {
1019
1081
  this.element = document.createElement("div"), Object.assign(this.element.style, {
1020
- background: L.white,
1021
- borderRadius: R[3],
1022
- padding: R[6],
1023
- boxShadow: `0 ${R[2]} ${R[8]} oklch(0% 0 0 / 20%)`,
1082
+ background: z.white,
1083
+ borderRadius: B[3],
1084
+ padding: B[6],
1085
+ boxShadow: `0 ${B[2]} ${B[8]} oklch(0% 0 0 / 20%)`,
1024
1086
  maxWidth: "20rem",
1025
1087
  width: "100%"
1026
1088
  });
1027
1089
  }
1028
- }, Xt = class {
1090
+ }, Qt = class {
1029
1091
  card;
1030
1092
  backdrop;
1031
1093
  keyHandler = null;
1032
1094
  constructor(e = {}) {
1033
- this.options = e, this.card = new Yt(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1095
+ this.options = e, this.card = new Zt(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1034
1096
  }
1035
1097
  open() {
1036
1098
  document.body.appendChild(this.backdrop), this.keyHandler = (e) => {
@@ -1044,7 +1106,7 @@ var Yt = class {
1044
1106
  let e = document.createElement("div");
1045
1107
  return Object.assign(e.style, {
1046
1108
  position: "fixed",
1047
- inset: R[0],
1109
+ inset: B[0],
1048
1110
  background: "oklch(0% 0 0 / 50%)",
1049
1111
  zIndex: "9999",
1050
1112
  display: "flex",
@@ -1054,7 +1116,7 @@ var Yt = class {
1054
1116
  t.target === e && this.close();
1055
1117
  }), e;
1056
1118
  }
1057
- }, Zt = class {
1119
+ }, $t = class {
1058
1120
  element;
1059
1121
  selectCallback = null;
1060
1122
  constructor(e, t, n) {
@@ -1072,7 +1134,7 @@ var Yt = class {
1072
1134
  onSelect(e) {
1073
1135
  this.selectCallback = e;
1074
1136
  }
1075
- }, Qt = class {
1137
+ }, en = class {
1076
1138
  element;
1077
1139
  select;
1078
1140
  constructor(e, t, n, r, i) {
@@ -1085,7 +1147,7 @@ var Yt = class {
1085
1147
  a.value = n, a.textContent = i?.[e] ?? n, n === r && (a.selected = !0, o = !0), this.select.appendChild(a);
1086
1148
  }
1087
1149
  o || (a.selected = !0);
1088
- let s = Lt(Bt, {
1150
+ let s = zt(Ht, {
1089
1151
  width: 16,
1090
1152
  height: 16,
1091
1153
  "stroke-width": 2
@@ -1100,7 +1162,7 @@ var Yt = class {
1100
1162
  e(this.select.value);
1101
1163
  });
1102
1164
  }
1103
- }, z = {
1165
+ }, V = {
1104
1166
  fontFamily: {
1105
1167
  sans: [
1106
1168
  "Mona Sans",
@@ -1139,42 +1201,42 @@ var Yt = class {
1139
1201
  normal: "1.5",
1140
1202
  relaxed: "1.75"
1141
1203
  }
1142
- }, $t = z.fontFamily.sans.join(", "), en = class {
1204
+ }, tn = V.fontFamily.sans.join(", "), nn = class {
1143
1205
  qrLib = null;
1144
1206
  dialog = null;
1145
1207
  async show(t) {
1146
- this.hide(), this.qrLib ??= await import("./browser-DbgxVbZp.js").then((t) => /* @__PURE__ */ e(t.default, 1));
1208
+ this.hide(), this.qrLib ??= await import("./browser-DxtIwHNu.js").then((t) => /* @__PURE__ */ e(t.default, 1));
1147
1209
  let n = await this.qrLib.toDataURL(t, {
1148
1210
  width: 256,
1149
1211
  margin: 4,
1150
1212
  errorCorrectionLevel: "M",
1151
1213
  color: {
1152
- dark: L.black,
1153
- light: L.white
1214
+ dark: z.black,
1215
+ light: z.white
1154
1216
  }
1155
1217
  });
1156
- this.dialog = new Xt({ onClose: () => {
1218
+ this.dialog = new Qt({ onClose: () => {
1157
1219
  this.dialog = null;
1158
1220
  } }), Object.assign(this.dialog.card.element.style, {
1159
1221
  display: "flex",
1160
1222
  flexDirection: "column",
1161
1223
  alignItems: "center",
1162
- gap: R[3],
1163
- fontFamily: $t
1164
- }), this.dialog.card.element.appendChild(this.createText(Me(), {
1165
- fontSize: z.fontSize.base,
1166
- fontWeight: z.fontWeight.semibold,
1167
- color: L.neutral[900]
1168
- })), this.dialog.card.element.appendChild(this.createText(Ie(), {
1169
- fontSize: z.fontSize.sm,
1170
- color: L.neutral[600]
1171
- })), this.dialog.card.element.appendChild(this.createQrImage(n)), this.dialog.card.element.appendChild(this.createText(Be(), {
1172
- fontSize: z.fontSize.xs,
1173
- color: L.neutral[500]
1224
+ gap: B[3],
1225
+ fontFamily: tn
1226
+ }), this.dialog.card.element.appendChild(this.createText(Pe(), {
1227
+ fontSize: V.fontSize.base,
1228
+ fontWeight: V.fontWeight.semibold,
1229
+ color: z.neutral[900]
1230
+ })), this.dialog.card.element.appendChild(this.createText(Re(), {
1231
+ fontSize: V.fontSize.sm,
1232
+ color: z.neutral[600]
1233
+ })), this.dialog.card.element.appendChild(this.createQrImage(n)), this.dialog.card.element.appendChild(this.createText(He(), {
1234
+ fontSize: V.fontSize.xs,
1235
+ color: z.neutral[500]
1174
1236
  }));
1175
- let r = new I({
1237
+ let r = new R({
1176
1238
  variant: "outline",
1177
- label: We(),
1239
+ label: Ke(),
1178
1240
  onClick: () => {
1179
1241
  this.hide();
1180
1242
  }
@@ -1195,12 +1257,12 @@ var Yt = class {
1195
1257
  createQrImage(e) {
1196
1258
  let t = document.createElement("img");
1197
1259
  return t.src = e, t.alt = "QR code", Object.assign(t.style, {
1198
- width: R[24],
1199
- height: R[24],
1200
- borderRadius: R[1]
1260
+ width: B[24],
1261
+ height: B[24],
1262
+ borderRadius: B[1]
1201
1263
  }), t;
1202
1264
  }
1203
- }, B = z.fontFamily.sans.join(", "), tn = `
1265
+ }, H = V.fontFamily.sans.join(", "), rn = `
1204
1266
  :root {
1205
1267
  --primary: oklch(5% 0 0);
1206
1268
  --primary-foreground: oklch(100% 0 0);
@@ -1224,7 +1286,7 @@ var Yt = class {
1224
1286
  gap: 0.5rem;
1225
1287
  border: 1px solid transparent;
1226
1288
  border-radius: var(--radius);
1227
- font-family: ${B};
1289
+ font-family: ${H};
1228
1290
  font-size: 0.875rem;
1229
1291
  font-weight: 600;
1230
1292
  white-space: nowrap;
@@ -1281,7 +1343,7 @@ var Yt = class {
1281
1343
  border-radius: var(--radius);
1282
1344
  background: var(--background);
1283
1345
  color: var(--foreground);
1284
- font-family: ${B};
1346
+ font-family: ${H};
1285
1347
  font-size: 0.875rem;
1286
1348
  font-weight: 600;
1287
1349
  cursor: pointer;
@@ -1315,7 +1377,7 @@ var Yt = class {
1315
1377
  background: var(--background);
1316
1378
  appearance: none;
1317
1379
  color: var(--foreground);
1318
- font-family: ${B};
1380
+ font-family: ${H};
1319
1381
  font-size: 0.875rem;
1320
1382
  font-weight: 400;
1321
1383
  cursor: pointer;
@@ -1337,20 +1399,95 @@ var Yt = class {
1337
1399
  color: var(--muted-foreground);
1338
1400
  pointer-events: none;
1339
1401
  }
1340
- `, V = !1;
1341
- function nn() {
1342
- if (V || typeof document > "u") return;
1343
- V = !0;
1402
+
1403
+ /* ── Annotation layer ───────────────────────────────────── */
1404
+ .vd-annotations-layer {
1405
+ position: absolute;
1406
+ inset-block-start: 0;
1407
+ inset-inline-start: 0;
1408
+ inline-size: 100%;
1409
+ block-size: 100%;
1410
+ pointer-events: none;
1411
+ overflow: visible !important; /* override CSS2DRenderer inline style */
1412
+ }
1413
+
1414
+ .vd-annotation-marker {
1415
+ display: flex;
1416
+ align-items: center;
1417
+ justify-content: center;
1418
+ inline-size: 1.75rem;
1419
+ block-size: 1.75rem;
1420
+ border-radius: 50%;
1421
+ border: 2px solid oklch(100% 0 0);
1422
+ background: var(--primary);
1423
+ color: var(--primary-foreground);
1424
+ font-family: ${H};
1425
+ font-size: 0.8125rem;
1426
+ font-weight: 600;
1427
+ cursor: pointer;
1428
+ pointer-events: auto;
1429
+ box-shadow: 0 2px 8px oklch(5% 0 0 / 20%);
1430
+ transition: transform 100ms ease;
1431
+ position: relative;
1432
+ }
1433
+ .vd-annotation-marker:hover { transform: scale(1.1); }
1434
+
1435
+ .vd-annotation-popup {
1436
+ position: absolute;
1437
+ inset-block-end: calc(100% + 0.5rem);
1438
+ inset-inline-start: 50%;
1439
+ transform: translateX(-50%);
1440
+ background: var(--background);
1441
+ color: var(--foreground);
1442
+ border: 1px solid var(--border);
1443
+ border-radius: var(--radius);
1444
+ padding: 0.75rem 1rem;
1445
+ max-inline-size: 15rem;
1446
+ box-shadow: 0 4px 6px oklch(5% 0 0 / 8%), 0 2px 4px oklch(5% 0 0 / 6%);
1447
+ pointer-events: auto;
1448
+ white-space: normal;
1449
+ }
1450
+
1451
+ @media (prefers-reduced-motion: no-preference) {
1452
+ .vd-annotation-popup {
1453
+ animation: vd-popup-in 150ms ease;
1454
+ }
1455
+ }
1456
+
1457
+ @keyframes vd-popup-in {
1458
+ from { opacity: 0; transform: translateX(-50%) translateY(4px); }
1459
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
1460
+ }
1461
+
1462
+ .vd-annotation-popup-title {
1463
+ font-family: ${H};
1464
+ font-size: 0.875rem;
1465
+ font-weight: 600;
1466
+ line-height: 1.25rem;
1467
+ }
1468
+
1469
+ .vd-annotation-popup-description {
1470
+ font-family: ${H};
1471
+ font-size: 0.8125rem;
1472
+ font-weight: 400;
1473
+ line-height: 1.125rem;
1474
+ color: var(--muted-foreground);
1475
+ margin-block-start: 0.25rem;
1476
+ }
1477
+ `, an = !1;
1478
+ function on() {
1479
+ if (an || typeof document > "u") return;
1480
+ an = !0;
1344
1481
  let e = document.createElement("style");
1345
- e.id = "vd-ui-vanilla", e.textContent = tn, document.head.appendChild(e);
1482
+ e.id = "vd-ui-vanilla", e.textContent = rn, document.head.appendChild(e);
1346
1483
  }
1347
1484
  //#endregion
1348
1485
  //#region src/ui/loading.ts
1349
- function H(e) {
1486
+ function sn(e) {
1350
1487
  let t = Math.max(0, Math.min(1, e));
1351
1488
  return t * t * (3 - 2 * t);
1352
1489
  }
1353
- function rn(e, t, n, r, i, a) {
1490
+ function cn(e, t, n, r, i, a) {
1354
1491
  let [o, s, c] = e, l = Math.cos(t), u = Math.sin(t), d = l * o + u * c, f = -u * o + l * c, p = Math.cos(n), m = Math.sin(n), h = p * s - m * f, g = m * s + p * f, _ = .55;
1355
1492
  return [
1356
1493
  r + d * a * _,
@@ -1358,12 +1495,12 @@ function rn(e, t, n, r, i, a) {
1358
1495
  g
1359
1496
  ];
1360
1497
  }
1361
- function an(e, t, n) {
1498
+ function ln(e, t, n) {
1362
1499
  e.beginPath(), e.moveTo(t[0], t[1]), e.lineTo(n[0], n[1]), e.strokeStyle = "#000", e.lineWidth = 2, e.stroke();
1363
1500
  }
1364
- function on(e, t, n, r, i) {
1501
+ function un(e, t, n, r, i) {
1365
1502
  let a = t(n), o = t(r);
1366
- an(e, a, [
1503
+ ln(e, a, [
1367
1504
  a[0] + (o[0] - a[0]) * i,
1368
1505
  a[1] + (o[1] - a[1]) * i,
1369
1506
  a[2]
@@ -1401,7 +1538,7 @@ var U = [
1401
1538
  -1,
1402
1539
  1,
1403
1540
  -1
1404
- ], sn = [
1541
+ ], dn = [
1405
1542
  [U, W],
1406
1543
  [W, G],
1407
1544
  [G, K],
@@ -1414,8 +1551,8 @@ var U = [
1414
1551
  [J, Y],
1415
1552
  [Y, X],
1416
1553
  [X, q]
1417
- ], cn = 400, ln = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif";
1418
- function un() {
1554
+ ], fn = 400, pn = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif";
1555
+ function mn() {
1419
1556
  let e = document.createElement("div");
1420
1557
  Object.assign(e.style, {
1421
1558
  position: "absolute",
@@ -1451,21 +1588,21 @@ function un() {
1451
1588
  fontWeight: "400",
1452
1589
  color: "#000",
1453
1590
  fontVariantNumeric: "tabular-nums",
1454
- fontFamily: ln
1591
+ fontFamily: pn
1455
1592
  });
1456
1593
  let i = document.createElement("span");
1457
1594
  return Object.assign(i.style, {
1458
1595
  fontSize: "13px",
1459
1596
  color: "#000",
1460
- fontFamily: ln
1461
- }), i.textContent = Qe(), n.appendChild(r), n.appendChild(i), e.appendChild(t), e.appendChild(n), {
1597
+ fontFamily: pn
1598
+ }), i.textContent = et(), n.appendChild(r), n.appendChild(i), e.appendChild(t), e.appendChild(n), {
1462
1599
  overlay: e,
1463
1600
  canvas: t,
1464
1601
  pctEl: r,
1465
1602
  phaseEl: i
1466
1603
  };
1467
1604
  }
1468
- var dn = class {
1605
+ var hn = class {
1469
1606
  overlay;
1470
1607
  canvas;
1471
1608
  ctx;
@@ -1478,17 +1615,17 @@ var dn = class {
1478
1615
  visible = !1;
1479
1616
  constructor(e, t = {}) {
1480
1617
  this.startTime = performance.now();
1481
- let n = un();
1618
+ let n = mn();
1482
1619
  this.overlay = n.overlay, this.canvas = n.canvas, this.pctEl = n.pctEl, this.phaseEl = n.phaseEl, e.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
1483
- let r = t.showDelay ?? cn;
1620
+ let r = t.showDelay ?? fn;
1484
1621
  this.showTimerId = setTimeout(() => {
1485
1622
  this.reveal();
1486
1623
  }, r);
1487
1624
  }
1488
1625
  get loadingTexts() {
1489
1626
  return {
1490
- downloading: Qe(),
1491
- rendering: nt()
1627
+ downloading: et(),
1628
+ rendering: it()
1492
1629
  };
1493
1630
  }
1494
1631
  updateProgress(e, t) {
@@ -1535,26 +1672,29 @@ var dn = class {
1535
1672
  if (this.ctx === null) return;
1536
1673
  let e = this.canvas.width / Math.min(devicePixelRatio, 2), t = this.canvas.height / Math.min(devicePixelRatio, 2), n = (performance.now() - this.startTime) / 1e3;
1537
1674
  this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, e, t);
1538
- let r = e / 2, i = t * .44, a = Math.min(e, t) * .08, o = (e) => rn(e, .785, .615, r, i, a), s = n % 6 / 6, c = sn.length, l;
1539
- l = s < .35 ? H(s / .35) * c : s < .55 ? c : s < .9 ? (1 - H((s - .55) / .35)) * c : 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
1675
+ let r = e / 2, i = t * .44, a = Math.min(e, t) * .08, o = (e) => cn(e, .785, .615, r, i, a), s = n % 6 / 6, c = dn.length, l;
1676
+ l = s < .35 ? sn(s / .35) * c : s < .55 ? c : s < .9 ? (1 - sn((s - .55) / .35)) * c : 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
1540
1677
  for (let e = 0; e < c && !(e >= l); e++) {
1541
- let t = sn[e];
1678
+ let t = dn[e];
1542
1679
  if (t === void 0) continue;
1543
1680
  let n = Math.min(1, l - e);
1544
- on(this.ctx, o, t[0], t[1], n);
1681
+ un(this.ctx, o, t[0], t[1], n);
1545
1682
  }
1546
1683
  this.ctx.shadowBlur = 0;
1547
1684
  }
1548
- }, fn = class {
1685
+ }, gn = class {
1549
1686
  element;
1550
1687
  arBtn = null;
1551
1688
  fullscreenBtn = null;
1552
1689
  onFullscreenChange;
1553
1690
  constructor(e) {
1554
- this.options = e, this.element = document.createElement("div"), this.onFullscreenChange = () => {
1691
+ this.options = e, this.element = document.createElement("div"), Object.assign(this.element.style, {
1692
+ display: "flex",
1693
+ gap: "0.375rem"
1694
+ }), this.onFullscreenChange = () => {
1555
1695
  if (this.fullscreenBtn === null) return;
1556
1696
  let e = document.fullscreenElement !== null;
1557
- this.fullscreenBtn.setIcon(e ? F.exitFullscreen() : F.fullscreen());
1697
+ this.fullscreenBtn.setIcon(e ? L.exitFullscreen() : L.fullscreen());
1558
1698
  }, document.addEventListener("fullscreenchange", this.onFullscreenChange);
1559
1699
  }
1560
1700
  syncButton(e, t, n) {
@@ -1565,19 +1705,19 @@ var dn = class {
1565
1705
  return !t && e !== null ? (e.element.remove(), null) : e;
1566
1706
  }
1567
1707
  applySettings(e) {
1568
- this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new I({
1708
+ this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new R({
1569
1709
  variant: "outline",
1570
1710
  size: "icon",
1571
- label: Oe(),
1572
- icon: F.ar(),
1711
+ label: Ae(),
1712
+ icon: L.ar(),
1573
1713
  onClick: () => {
1574
1714
  this.options.onAr?.();
1575
1715
  }
1576
- })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new I({
1716
+ })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new R({
1577
1717
  variant: "outline",
1578
1718
  size: "icon",
1579
- label: Je(),
1580
- icon: F.fullscreen(),
1719
+ label: Xe(),
1720
+ icon: L.fullscreen(),
1581
1721
  onClick: () => {
1582
1722
  this.options.onFullscreen?.();
1583
1723
  }
@@ -1586,112 +1726,133 @@ var dn = class {
1586
1726
  destroy() {
1587
1727
  document.removeEventListener("fullscreenchange", this.onFullscreenChange);
1588
1728
  }
1589
- }, Z = .5, pn = class e {
1729
+ }, Z = .5, _n = class e {
1590
1730
  element;
1591
1731
  constructor(t, n) {
1592
1732
  this.element = Object.assign(document.createElement("div"), { className: "vd-camera-controls" });
1593
- let r = n.rotation, i = n.tilt, a = n.zoom, o = 0, s = (e) => Math.max(n.limits?.minZoom ?? 1, Math.min(n.limits?.maxZoom ?? Infinity, e)), c = (e) => {
1594
- let t = n.limits?.minRotate, r = n.limits?.maxRotate;
1595
- return t !== void 0 || r !== void 0 ? Math.max(t ?? -Infinity, Math.min(r ?? Infinity, e)) : e;
1596
- }, l = (e) => {
1597
- let a = n.limits?.minTilt, s = n.limits?.maxTilt;
1598
- if (a !== void 0 || s !== void 0) {
1599
- i = Math.max(a ?? 0, Math.min(s ?? 180, i + e)), t.tilt(i).set();
1600
- return;
1601
- }
1602
- let c = i + e;
1603
- c > 180 || c < 0 ? (i = c > 180 ? 360 - c : -c, o = (o + 180) % 360, t.tilt(i).rotate(r + o).set()) : (i = c, t.tilt(i).set());
1604
- }, u = new I({
1733
+ let r = {
1734
+ targetRotation: n.rotation,
1735
+ targetTilt: n.tilt,
1736
+ targetZoom: n.zoom,
1737
+ thetaOffset: 0
1738
+ }, i = vn(t, n, r);
1739
+ n.onChange((e) => {
1740
+ r.targetRotation = e.rotation - r.thetaOffset, r.targetTilt = e.tilt, r.targetZoom = e.zoom, yn(i, n, e);
1741
+ }), this.element.appendChild(e.buildZoom(i.zoomOut, i.zoomIn)), this.element.appendChild(e.buildDpad(i.tiltUp, i.rotateLeft, i.reset, i.rotateRight, i.tiltDown));
1742
+ }
1743
+ static buildZoom(e, t) {
1744
+ let n = document.createElement("div");
1745
+ return n.className = "vd-zoom", n.appendChild(e.element), n.appendChild(t.element), n;
1746
+ }
1747
+ static buildDpad(e, t, n, r, i) {
1748
+ let a = document.createElement("div");
1749
+ a.className = "vd-dpad";
1750
+ for (let [o, s] of [
1751
+ [e, "up"],
1752
+ [t, "left"],
1753
+ [n, "center"],
1754
+ [r, "right"],
1755
+ [i, "down"]
1756
+ ]) o.element.classList.add(`vd-dpad-${s}`), a.appendChild(o.element);
1757
+ return a;
1758
+ }
1759
+ };
1760
+ function vn(e, t, n) {
1761
+ let r = (e) => Math.max(t.limits?.minZoom ?? 1, Math.min(t.limits?.maxZoom ?? Infinity, e)), i = (e) => {
1762
+ let n = t.limits?.minRotate, r = t.limits?.maxRotate;
1763
+ return n !== void 0 || r !== void 0 ? Math.max(n ?? -Infinity, Math.min(r ?? Infinity, e)) : e;
1764
+ }, a = (r) => {
1765
+ let i = t.limits?.minTilt, a = t.limits?.maxTilt;
1766
+ if (i !== void 0 || a !== void 0) {
1767
+ n.targetTilt = Math.max(i ?? 0, Math.min(a ?? 180, n.targetTilt + r)), e.tilt(n.targetTilt).set();
1768
+ return;
1769
+ }
1770
+ let o = n.targetTilt + r;
1771
+ o > 180 || o < 0 ? (n.targetTilt = o > 180 ? 360 - o : -o, n.thetaOffset = (n.thetaOffset + 180) % 360, e.tilt(n.targetTilt).rotate(n.targetRotation + n.thetaOffset).set()) : (n.targetTilt = o, e.tilt(n.targetTilt).set());
1772
+ };
1773
+ return {
1774
+ zoomOut: new R({
1605
1775
  variant: "outline",
1606
1776
  size: "icon",
1607
- label: vt(),
1608
- icon: F.zoomOut(),
1777
+ label: bt(),
1778
+ icon: L.zoomOut(),
1609
1779
  onClick: () => {
1610
- a = s(a - 10), t.zoom(a).set();
1780
+ n.targetZoom = r(n.targetZoom - 10), e.zoom(n.targetZoom).set();
1611
1781
  }
1612
- }), d = new I({
1782
+ }),
1783
+ zoomIn: new R({
1613
1784
  variant: "outline",
1614
1785
  size: "icon",
1615
- label: mt(),
1616
- icon: F.zoomIn(),
1786
+ label: gt(),
1787
+ icon: L.zoomIn(),
1617
1788
  onClick: () => {
1618
- a = s(a + 10), t.zoom(a).set();
1789
+ n.targetZoom = r(n.targetZoom + 10), e.zoom(n.targetZoom).set();
1619
1790
  }
1620
- }), f = new I({
1791
+ }),
1792
+ tiltUp: new R({
1621
1793
  variant: "outline",
1622
1794
  size: "icon",
1623
- label: At(),
1624
- icon: F.tiltUp(),
1795
+ label: Mt(),
1796
+ icon: L.tiltUp(),
1625
1797
  onClick: () => {
1626
- l(-15);
1798
+ a(-15);
1627
1799
  }
1628
- }), p = new I({
1800
+ }),
1801
+ rotateLeft: new R({
1629
1802
  variant: "outline",
1630
1803
  size: "icon",
1631
- label: St(),
1632
- icon: F.rotateLeft(),
1804
+ label: wt(),
1805
+ icon: L.rotateLeft(),
1633
1806
  onClick: () => {
1634
- r = c(r - 15), t.rotate(r + o).set();
1807
+ n.targetRotation = i(n.targetRotation - 15), e.rotate(n.targetRotation + n.thetaOffset).set();
1635
1808
  }
1636
- }), m = new I({
1809
+ }),
1810
+ reset: new R({
1637
1811
  variant: "outline",
1638
1812
  size: "icon",
1639
- label: ut(),
1640
- icon: F.reset(),
1813
+ label: ft(),
1814
+ icon: L.reset(),
1641
1815
  onClick: () => {
1642
- o = 0, t.reset();
1816
+ n.thetaOffset = 0, e.reset();
1643
1817
  }
1644
- }), h = new I({
1818
+ }),
1819
+ rotateRight: new R({
1645
1820
  variant: "outline",
1646
1821
  size: "icon",
1647
- label: Et(),
1648
- icon: F.rotateRight(),
1822
+ label: Ot(),
1823
+ icon: L.rotateRight(),
1649
1824
  onClick: () => {
1650
- r = c(r + 15), t.rotate(r + o).set();
1825
+ n.targetRotation = i(n.targetRotation + 15), e.rotate(n.targetRotation + n.thetaOffset).set();
1651
1826
  }
1652
- }), g = new I({
1827
+ }),
1828
+ tiltDown: new R({
1653
1829
  variant: "outline",
1654
1830
  size: "icon",
1655
- label: Pt(),
1656
- icon: F.tiltDown(),
1831
+ label: It(),
1832
+ icon: L.tiltDown(),
1657
1833
  onClick: () => {
1658
- l(15);
1834
+ a(15);
1659
1835
  }
1660
- }), _ = (e) => {
1661
- let t = n.limits;
1662
- t !== void 0 && (u.element.disabled = t.minZoom !== void 0 && e.zoom <= t.minZoom + Z, d.element.disabled = t.maxZoom !== void 0 && e.zoom >= t.maxZoom - Z, f.element.disabled = t.minTilt !== void 0 && e.tilt <= t.minTilt + Z, g.element.disabled = t.maxTilt !== void 0 && e.tilt >= t.maxTilt - Z, p.element.disabled = t.minRotate !== void 0 && e.rotation <= t.minRotate + Z, h.element.disabled = t.maxRotate !== void 0 && e.rotation >= t.maxRotate - Z);
1663
- };
1664
- n.onChange((e) => {
1665
- r = e.rotation - o, i = e.tilt, a = e.zoom, _(e);
1666
- }), this.element.appendChild(e.buildZoom(u, d)), this.element.appendChild(e.buildDpad(f, p, m, h, g));
1667
- }
1668
- static buildZoom(e, t) {
1669
- let n = document.createElement("div");
1670
- return n.className = "vd-zoom", n.appendChild(e.element), n.appendChild(t.element), n;
1671
- }
1672
- static buildDpad(e, t, n, r, i) {
1673
- let a = document.createElement("div");
1674
- a.className = "vd-dpad";
1675
- for (let [o, s] of [
1676
- [e, "up"],
1677
- [t, "left"],
1678
- [n, "center"],
1679
- [r, "right"],
1680
- [i, "down"]
1681
- ]) o.element.classList.add(`vd-dpad-${s}`), a.appendChild(o.element);
1682
- return a;
1683
- }
1684
- }, mn = 5;
1836
+ })
1837
+ };
1838
+ }
1839
+ function yn(e, t, n) {
1840
+ let r = t.limits;
1841
+ r !== void 0 && (e.zoomOut.element.disabled = r.minZoom !== void 0 && n.zoom <= r.minZoom + Z, e.zoomIn.element.disabled = r.maxZoom !== void 0 && n.zoom >= r.maxZoom - Z, e.tiltUp.element.disabled = r.minTilt !== void 0 && n.tilt <= r.minTilt + Z, e.tiltDown.element.disabled = r.maxTilt !== void 0 && n.tilt >= r.maxTilt - Z, e.rotateLeft.element.disabled = r.minRotate !== void 0 && n.rotation <= r.minRotate + Z, e.rotateRight.element.disabled = r.maxRotate !== void 0 && n.rotation >= r.maxRotate - Z);
1842
+ }
1843
+ //#endregion
1844
+ //#region src/ui/controls/attribute-group.ts
1845
+ var bn = 5;
1685
1846
  function Q(e) {
1686
1847
  let t = e.replace(/([A-Z])/g, " $1").trim();
1687
1848
  return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
1688
1849
  }
1689
- function hn(e, t, n, r, i) {
1850
+ function xn(e, t, n, r, i) {
1690
1851
  let a = document.createElement("div");
1691
1852
  a.className = "vd-attribute", a.dataset.name = e.name;
1692
1853
  let o = document.createElement("span");
1693
1854
  o.className = "vd-attribute-label", o.textContent = Q(e.name), a.appendChild(o);
1694
- let s = e.values.find((n) => t.getValue(e.name, n)?.isSelected === !0), c = e.values.map(Q), l = e.values.length <= mn ? new Zt(e.values, s, c) : new Qt(e.name, e.values, Q(e.name), s, c);
1855
+ let s = e.values.find((n) => t.getValue(e.name, n)?.isSelected === !0), c = e.values.map(Q), l = e.values.length <= bn ? new $t(e.values, s, c) : new en(e.name, e.values, Q(e.name), s, c);
1695
1856
  return l.onSelect((t) => {
1696
1857
  n.dispatch("ui:select", {
1697
1858
  attribute: e.name,
@@ -1706,7 +1867,7 @@ function hn(e, t, n, r, i) {
1706
1867
  }
1707
1868
  //#endregion
1708
1869
  //#region src/ui/styles.ts
1709
- var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display: flex;\n z-index: 10;\n", _n = `
1870
+ var Sn = V.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display: flex;\n z-index: 10;\n", Cn = `
1710
1871
  /* Override browser's default black fullscreen backdrop */
1711
1872
  .vd-container:fullscreen {
1712
1873
  background: oklch(100% 0 0);
@@ -1715,51 +1876,51 @@ var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display:
1715
1876
  /* Layout slots — four corners */
1716
1877
  .vd-slot-top-right {
1717
1878
  ${$}
1718
- inset-block-start: ${R[3]};
1719
- inset-inline-end: ${R[3]};
1879
+ inset-block-start: ${B[3]};
1880
+ inset-inline-end: ${B[3]};
1720
1881
  flex-direction: column;
1721
1882
  align-items: flex-end;
1722
- gap: ${R[1.5]};
1883
+ gap: ${B[1.5]};
1723
1884
  }
1724
1885
 
1725
1886
  .vd-slot-bottom-left {
1726
1887
  ${$}
1727
- inset-block-end: ${R[3]};
1728
- inset-inline-start: ${R[3]};
1888
+ inset-block-end: ${B[3]};
1889
+ inset-inline-start: ${B[3]};
1729
1890
  flex-direction: column;
1730
1891
  align-items: flex-start;
1731
- gap: ${R[1.5]};
1892
+ gap: ${B[1.5]};
1732
1893
  }
1733
1894
 
1734
1895
  .vd-slot-bottom-right {
1735
1896
  ${$}
1736
- inset-block-end: ${R[3]};
1737
- inset-inline-end: ${R[3]};
1897
+ inset-block-end: ${B[3]};
1898
+ inset-inline-end: ${B[3]};
1738
1899
  flex-direction: row;
1739
- gap: ${R[1.5]};
1900
+ gap: ${B[1.5]};
1740
1901
  }
1741
1902
 
1742
1903
  /* Component styles — no positioning */
1743
1904
  .vd-camera-controls {
1744
1905
  display: flex;
1745
1906
  flex-direction: column;
1746
- gap: ${R[1]};
1747
- background: color-mix(in oklch, ${L.white} 85%, transparent);
1907
+ gap: ${B[1]};
1908
+ background: color-mix(in oklch, ${z.white} 85%, transparent);
1748
1909
  backdrop-filter: blur(8px);
1749
- border-radius: ${R[2]};
1750
- padding: ${R[2]};
1910
+ border-radius: ${B[2]};
1911
+ padding: ${B[2]};
1751
1912
  }
1752
1913
 
1753
1914
  .vd-zoom {
1754
1915
  display: flex;
1755
- gap: ${R[.5]};
1916
+ gap: ${B[.5]};
1756
1917
  }
1757
1918
 
1758
1919
  .vd-dpad {
1759
1920
  display: grid;
1760
- grid-template-columns: repeat(3, ${R[9]});
1761
- grid-template-rows: repeat(3, ${R[9]});
1762
- gap: ${R[.5]};
1921
+ grid-template-columns: repeat(3, ${B[9]});
1922
+ grid-template-rows: repeat(3, ${B[9]});
1923
+ gap: ${B[.5]};
1763
1924
  }
1764
1925
 
1765
1926
  .vd-dpad-up { grid-column: 2; grid-row: 1; }
@@ -1771,40 +1932,40 @@ var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display:
1771
1932
  .vd-attributes {
1772
1933
  display: flex;
1773
1934
  flex-direction: column;
1774
- gap: ${R[2]};
1775
- background: color-mix(in oklch, ${L.white} 85%, transparent);
1935
+ gap: ${B[2]};
1936
+ background: color-mix(in oklch, ${z.white} 85%, transparent);
1776
1937
  backdrop-filter: blur(8px);
1777
- border-radius: ${R[2]};
1778
- padding: ${R[2]};
1779
- font-family: ${gn};
1938
+ border-radius: ${B[2]};
1939
+ padding: ${B[2]};
1940
+ font-family: ${Sn};
1780
1941
  }
1781
1942
 
1782
1943
  .vd-attribute {
1783
1944
  display: flex;
1784
1945
  flex-direction: column;
1785
- gap: ${R[1]};
1946
+ gap: ${B[1]};
1786
1947
  }
1787
1948
 
1788
1949
  .vd-attribute-label {
1789
- font-size: ${z.fontSize.xs};
1790
- font-weight: ${z.fontWeight.medium};
1791
- color: ${L.neutral[900]};
1792
- font-family: ${gn};
1950
+ font-size: ${V.fontSize.xs};
1951
+ font-weight: ${V.fontWeight.medium};
1952
+ color: ${z.neutral[900]};
1953
+ font-family: ${Sn};
1793
1954
  }
1794
1955
 
1795
1956
  `;
1796
- function vn() {
1797
- if (nn(), document.getElementById("vd-styles") !== null) return;
1957
+ function wn() {
1958
+ if (on(), document.getElementById("vd-styles") !== null) return;
1798
1959
  let e = document.createElement("style");
1799
- e.id = "vd-styles", e.textContent = _n, document.head.appendChild(e);
1960
+ e.id = "vd-styles", e.textContent = Cn, document.head.appendChild(e);
1800
1961
  }
1801
1962
  //#endregion
1802
1963
  //#region src/ui/standard-interface.ts
1803
- function yn(e, t) {
1964
+ function Tn(e, t) {
1804
1965
  let n = document.createElement("a");
1805
1966
  n.href = `data:image/png;base64,${e}`, n.download = t, n.click();
1806
1967
  }
1807
- var bn = class {
1968
+ var En = class {
1808
1969
  options;
1809
1970
  settings = {};
1810
1971
  container = null;
@@ -1822,15 +1983,18 @@ var bn = class {
1822
1983
  this.options = e;
1823
1984
  }
1824
1985
  attach(e) {
1825
- vn(), this.container = e, this.loading = new dn(e), this.slots.topRight = this.createSlot(e, "vd-slot-top-right"), this.slots.bottomLeft = this.createSlot(e, "vd-slot-bottom-left"), this.slots.bottomRight = this.createSlot(e, "vd-slot-bottom-right"), this.actionBar = new fn({
1986
+ wn(), this.container = e, this.loading = new hn(e), this.slots.topRight = this.createSlot(e, "vd-slot-top-right"), this.slots.bottomLeft = this.createSlot(e, "vd-slot-bottom-left"), this.slots.bottomRight = this.createSlot(e, "vd-slot-bottom-right");
1987
+ }
1988
+ onReady() {
1989
+ this.loading?.hide(), this.loading = null, this.mountToolbar(), this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.attributes !== null && (this.attributes.style.display = "flex");
1990
+ }
1991
+ mountToolbar() {
1992
+ this.actionBar !== null || this.slots.bottomRight === null || (this.actionBar = new gn({
1826
1993
  onAr: this.options.onAr,
1827
1994
  onFullscreen: () => {
1828
1995
  document.fullscreenElement === null ? this.container?.requestFullscreen() : document.exitFullscreen();
1829
1996
  }
1830
- }), this.actionBar.applySettings(this.settings), this.slots.bottomRight.appendChild(this.actionBar.element), this.syncScreenshotButton(), this.placeScreenshotButton();
1831
- }
1832
- onReady() {
1833
- this.loading?.hide(), this.loading = null, this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.attributes !== null && (this.attributes.style.display = "flex");
1997
+ }), this.actionBar.applySettings(this.settings), this.slots.bottomRight.appendChild(this.actionBar.element), this.syncScreenshotButton(), this.placeScreenshotButton());
1834
1998
  }
1835
1999
  updateProgress(e, t) {
1836
2000
  this.loading?.updateProgress(e, t);
@@ -1839,12 +2003,12 @@ var bn = class {
1839
2003
  this.loading?.showError(e);
1840
2004
  }
1841
2005
  applyViewerSettings(e) {
1842
- this.settings = e, e.language !== void 0 && j(e.language), this.syncScreenshotButton(), this.actionBar?.applySettings(e), this.cameraControls !== null && (this.cameraControls.element.style.display = e.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
2006
+ this.settings = e, e.language !== void 0 && N(e.language, { reload: !1 }), this.syncScreenshotButton(), this.actionBar?.applySettings(e), this.cameraControls !== null && (this.cameraControls.element.style.display = e.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
1843
2007
  }
1844
2008
  renderAttributeControls(e, t) {
1845
- if (!(this.container === null || this.slots.topRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.attributes?.remove(), this.attributes = null, this.settings.cameraControls === !0 && (this.cameraControls = new pn(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), t.length !== 0)) {
2009
+ if (!(this.container === null || this.slots.topRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.attributes?.remove(), this.attributes = null, this.settings.cameraControls === !0 && (this.cameraControls = new _n(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), !(t.length === 0 || this.settings.attributeControls === !1))) {
1846
2010
  this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes", this.attributes.style.display = "none";
1847
- for (let n of t) this.attributes.appendChild(hn(n, e, this.options.eventBus, this.options.onSelect, this.options.onSubscribe));
2011
+ for (let n of t) this.attributes.appendChild(xn(n, e, this.options.eventBus, this.options.onSelect, this.options.onSubscribe));
1848
2012
  this.slots.bottomLeft.appendChild(this.attributes);
1849
2013
  }
1850
2014
  }
@@ -1862,14 +2026,14 @@ var bn = class {
1862
2026
  }
1863
2027
  syncScreenshotButton() {
1864
2028
  let e = this.settings.screenshot === !0;
1865
- e && this.screenshotBtn === null && (this.screenshotBtn = new I({
2029
+ e && this.screenshotBtn === null && (this.screenshotBtn = new R({
1866
2030
  variant: "outline",
1867
2031
  size: "icon",
1868
- label: ot(),
1869
- icon: F.screenshot(),
2032
+ label: ct(),
2033
+ icon: L.screenshot(),
1870
2034
  onClick: () => {
1871
2035
  this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: t }) => {
1872
- yn(e, t);
2036
+ Tn(e, t);
1873
2037
  });
1874
2038
  }
1875
2039
  })), !e && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
@@ -1877,13 +2041,14 @@ var bn = class {
1877
2041
  placeScreenshotButton() {
1878
2042
  this.screenshotBtn === null || this.slots.topRight === null || (this.cameraControls === null ? this.slots.topRight.appendChild(this.screenshotBtn.element) : this.cameraControls.element.appendChild(this.screenshotBtn.element));
1879
2043
  }
1880
- }, xn = class {
2044
+ }, Dn = class {
1881
2045
  attributes;
1882
2046
  readyStateTracker;
1883
2047
  messenger;
1884
2048
  cameraApi;
1885
2049
  cameraPositionApi;
1886
2050
  snapshotApi;
2051
+ annotationsApi;
1887
2052
  eventBus;
1888
2053
  ui;
1889
2054
  qrModal;
@@ -1897,17 +2062,17 @@ var bn = class {
1897
2062
  let t = (e) => {
1898
2063
  this.messenger.send(e);
1899
2064
  };
1900
- this.attributes = new pe(t, (e, t) => {
2065
+ this.attributes = new ge(t, (e, t) => {
1901
2066
  for (let n of this.mutationFailedCallbacks) n({
1902
2067
  attribute: e,
1903
2068
  value: t
1904
2069
  });
1905
- }), this.snapshotApi = new C(t), this.cameraApi = new x(t), this.cameraPositionApi = new me(), this.eventBus = new he(), this.qrModal = new en(), this.readyStateTracker = new _(() => {
2070
+ }), this.snapshotApi = new S(t), this.annotationsApi = new pe(t), this.cameraApi = new _e(t), this.cameraPositionApi = new ve(), this.eventBus = new be(), this.qrModal = new nn(), this.readyStateTracker = new te(() => {
1906
2071
  let e = this.readyCallbacks;
1907
2072
  this.readyCallbacks = [];
1908
2073
  for (let t of e) t(this);
1909
2074
  this.ui.onReady();
1910
- }), this.ui = new bn({
2075
+ }), this.ui = new En({
1911
2076
  snapshotApi: this.snapshotApi,
1912
2077
  cameraApi: this.cameraApi,
1913
2078
  cameraPositionApi: this.cameraPositionApi,
@@ -1920,28 +2085,49 @@ var bn = class {
1920
2085
  }), this.registerHandlers(), this.messenger.start(), this.createAndConnectIframe();
1921
2086
  }
1922
2087
  registerHandlers() {
1923
- this.messenger.on(y.HANDSHAKE, (e) => {
1924
- ie(e) && (m.info("Server handshake received, flushing publisher queue"), this.messenger.markReady());
1925
- }), this.messenger.on(y.MUTATION, (e) => {
2088
+ this.messenger.on(v.HANDSHAKE, (e) => {
2089
+ ie(e) && (g.info("Server handshake received, flushing publisher queue"), this.messenger.markReady());
2090
+ }), this.messenger.on(v.MUTATION, (e) => {
1926
2091
  ae(e) && this.attributes.handleMutationResult(e);
1927
- }), this.messenger.on(y.SNAPSHOT, (e) => {
2092
+ }), this.messenger.on(v.SNAPSHOT, (e) => {
1928
2093
  oe(e) && this.snapshotApi.handleSnapshotResult(e);
1929
- }), this.messenger.on(y.CAMERA, (e) => {
2094
+ }), this.messenger.on(v.CAMERA, (e) => {
1930
2095
  se(e) && this.cameraPositionApi.handlePositionUpdate(e);
1931
- }), this.messenger.on(y.LOADING_INDICATOR, (e) => {
2096
+ }), this.messenger.on(v.LOADING_INDICATOR, (e) => {
1932
2097
  le(e) && (e.error === void 0 ? this.ui.updateProgress(e.progress, e.phase) : this.ui.showError(e.error));
1933
- }), this.messenger.on(y.CONFIG, (e) => {
1934
- ue(e) && (e.viewerSettings !== void 0 && this.ui.applyViewerSettings(e.viewerSettings), this.cameraPositionApi.applyLimits(e.cameraLimits));
1935
- }), this.messenger.on(y.MAPPING, (e) => {
2098
+ }), this.messenger.on(v.CONFIG, (e) => {
2099
+ ue(e) && this.handleConfig(e);
2100
+ }), this.messenger.on(v.ANNOTATION_PLACED, (e) => {
2101
+ de(e) && this.annotationsApi.handlePlaced(e.position);
2102
+ }), this.messenger.on(v.MAPPING, (e) => {
1936
2103
  ce(e) && (this.attributes.handleMappingReceived(e), this.ui.renderAttributeControls(this.attributes, e.attributes), this.readyStateTracker.handleMappingReceived());
1937
2104
  });
1938
2105
  }
2106
+ handleConfig(e) {
2107
+ let t = e.viewerSettings, n = this.options.viewerSettings;
2108
+ if (t !== void 0 || n !== void 0) {
2109
+ let e = n === void 0 ? t : {
2110
+ ...t ?? {},
2111
+ ...n
2112
+ };
2113
+ if (n !== void 0 && t !== void 0) {
2114
+ let e = Object.entries(n).filter(([e, n]) => t[e] !== n).map(([e, n]) => `${e} (metadata: ${t[e] ?? "undefined"}, override: ${n})`);
2115
+ e.length > 0 && g.warn(`Viewer settings override active: ${e.join(", ")}`);
2116
+ }
2117
+ this.ui.applyViewerSettings(e), this.annotationsApi.setEnabled(e.annotations !== !1);
2118
+ }
2119
+ this.cameraPositionApi.applyLimits(e.cameraLimits);
2120
+ }
1939
2121
  initializeLogging() {
1940
- this.options.debug === !0 && h(), m.info("Initializing Virtualdisplay client", { model: this.options.model });
2122
+ this.options.debug === !0 && _(), g.info("Initializing Virtualdisplay client", { model: this.options.model });
1941
2123
  }
1942
2124
  createAndConnectIframe() {
1943
2125
  let e = new r(this.options).create();
1944
2126
  this.container = e.container, this.iframe = e.iframe, this.eventBus.attach(this.container), this.ui.attach(this.container);
2127
+ try {
2128
+ let e = new URL(this.iframe.src).origin;
2129
+ this.messenger.setTargetOrigin(e);
2130
+ } catch {}
1945
2131
  }
1946
2132
  select(e, t) {
1947
2133
  this.attributes.select(e, t);
@@ -1974,6 +2160,9 @@ var bn = class {
1974
2160
  on(e, t) {
1975
2161
  this.eventBus.on(e, t);
1976
2162
  }
2163
+ get annotations() {
2164
+ return this.annotationsApi;
2165
+ }
1977
2166
  get camera() {
1978
2167
  return this.cameraApi;
1979
2168
  }
@@ -1991,4 +2180,4 @@ var bn = class {
1991
2180
  }
1992
2181
  };
1993
2182
  //#endregion
1994
- export { ee as Attribute, v as AttributeValue, x as Camera, t as ERROR_CODES, S as Photo, C as Snapshot, xn as VirtualdisplayClient, n as VirtualdisplayError, h as enableDebugMode, g as isDebugMode, m as logger };
2183
+ export { pe as Annotations, x as Attribute, me as AttributeValue, _e as Camera, t as ERROR_CODES, ye as Photo, S as Snapshot, Dn as VirtualdisplayClient, n as VirtualdisplayError, _ as enableDebugMode, ee as isDebugMode, g as logger };