@virtualdisplay.io/client 4.0.0-alpha.23 → 4.0.0-alpha.25

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.
@@ -14,70 +14,75 @@ const c = {
14
14
  FOCUS: "focus",
15
15
  PRICING: "pricing",
16
16
  QR_SHOWN: "qr_shown",
17
- SYNC: "sync"
18
- }, Q = {
17
+ SYNC: "sync",
18
+ SELECTABLE: "selectable"
19
+ }, tt = {
19
20
  FOCUS: "focus",
20
21
  UNFOCUS: "unfocus"
21
- }, kt = {
22
+ }, Tt = {
22
23
  FOCUSED: "focused"
23
- }, At = {
24
+ }, Rt = {
24
25
  /** Behaves exactly like an unpriced combination: no price, no button. */
25
26
  HIDDEN: "hidden"
26
- }, Et = new Set(Object.values(c));
27
- function xt(n) {
27
+ }, It = new Set(Object.values(c));
28
+ function Lt(n) {
28
29
  if (typeof n != "object" || n === null)
29
30
  return !1;
30
31
  const t = n;
31
- return typeof t.target == "string" ? !1 : typeof t.type == "string" && Et.has(t.type);
32
+ return typeof t.target == "string" ? !1 : typeof t.type == "string" && It.has(t.type);
32
33
  }
33
- function Tt(n) {
34
- const t = C(n);
34
+ function Ot(n) {
35
+ const t = S(n);
35
36
  return t !== null && t.type === c.HANDSHAKE;
36
37
  }
37
- function Rt(n) {
38
- const t = C(n);
38
+ function Nt(n) {
39
+ const t = S(n);
39
40
  return t !== null && t.type === c.SESSION && typeof t.sessionId == "string";
40
41
  }
41
- function It(n) {
42
- const t = C(n);
42
+ function Mt(n) {
43
+ const t = S(n);
43
44
  return t !== null && t.type === c.MUTATION && Array.isArray(t.results);
44
45
  }
45
- function Ot(n) {
46
- const t = C(n);
46
+ function zt(n) {
47
+ const t = S(n);
47
48
  return t !== null && t.type === c.SNAPSHOT && ("data" in t || "error" in t);
48
49
  }
49
- function Nt(n) {
50
- const t = C(n);
50
+ function Pt(n) {
51
+ const t = S(n);
51
52
  return t !== null && t.type === c.CAMERA && Array.isArray(t.transforms);
52
53
  }
53
- function Mt(n) {
54
- const t = C(n);
54
+ function Ft(n) {
55
+ const t = S(n);
55
56
  return t !== null && t.type === c.MAPPING && Array.isArray(t.attributes);
56
57
  }
57
- function Lt(n) {
58
- const t = C(n);
58
+ function $t(n) {
59
+ const t = S(n);
59
60
  return t !== null && t.type === c.LOADING_INDICATOR && typeof t.progress == "number";
60
61
  }
61
- function zt(n) {
62
- const t = C(n);
62
+ function Dt(n) {
63
+ const t = S(n);
63
64
  return t !== null && t.type === c.SYNC && typeof t.connected == "boolean";
64
65
  }
65
- function Pt(n) {
66
- const t = C(n);
66
+ function Bt(n) {
67
+ const t = S(n);
68
+ return t !== null && t.type === c.SELECTABLE && Array.isArray(t.attributes);
69
+ }
70
+ function Ut(n) {
71
+ const t = S(n);
67
72
  return t !== null && t.type === c.CONFIG && typeof t.viewerSettings == "object";
68
73
  }
69
- function Ft(n) {
70
- const t = C(n);
74
+ function Vt(n) {
75
+ const t = S(n);
71
76
  return t !== null && t.type === c.FOCUS && typeof t.state == "string";
72
77
  }
73
- function $t(n) {
74
- const t = C(n);
78
+ function jt(n) {
79
+ const t = S(n);
75
80
  return t !== null && t.type === c.PRICING && typeof t.pricing == "object" && t.pricing !== null;
76
81
  }
77
- function C(n) {
82
+ function S(n) {
78
83
  return typeof n != "object" || n === null ? null : n;
79
84
  }
80
- class Y {
85
+ class et {
81
86
  constructor(t) {
82
87
  this.processor = t;
83
88
  }
@@ -124,15 +129,14 @@ class Y {
124
129
  this.pending.length = 0;
125
130
  }
126
131
  }
127
- class Dt {
132
+ class Ht {
128
133
  constructor(t, e) {
129
- this.getTarget = t, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = e?.targetOrigin ?? "*", this.isValid = e?.isValid ?? xt, this.publisher = new Y((i) => this.post(i)), this.consumer = new Y((i) => this.routeToHandler(i)), this.shouldBuffer = e?.shouldBuffer ?? null, e?.bufferIncoming !== !0 && this.consumer.markReady();
134
+ this.getTarget = t, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = "*", this.isValid = e?.isValid ?? Lt, this.publisher = new et((i) => this.post(i)), this.consumer = new et((i) => this.routeToHandler(i)), e?.bufferIncoming !== !0 && this.consumer.markReady();
130
135
  }
131
136
  getTarget;
132
137
  handlers = /* @__PURE__ */ new Map();
133
138
  publisher;
134
139
  consumer;
135
- shouldBuffer;
136
140
  listener = null;
137
141
  sourceId;
138
142
  targetOrigin;
@@ -143,12 +147,6 @@ class Dt {
143
147
  on(t, e) {
144
148
  this.handlers.set(t, e);
145
149
  }
146
- /**
147
- * Remove a handler for a specific message type
148
- */
149
- off(t) {
150
- this.handlers.delete(t);
151
- }
152
150
  /**
153
151
  * Update the target origin for outgoing postMessage calls.
154
152
  * Use when the target origin is discovered at runtime (e.g. from the first incoming message).
@@ -166,20 +164,14 @@ class Dt {
166
164
  /**
167
165
  * Feed a message through the same routing path as one that just arrived via
168
166
  * postMessage, without an actual postMessage round-trip: still validated
169
- * against `isValid`, and still respects the consumer queue's buffering and
170
- * the `shouldBuffer` bypass. For a transport that delivers messages some
167
+ * against `isValid`, and still respects the consumer queue's buffering. For
168
+ * a transport that delivers messages some
171
169
  * other way than the iframe channel this messenger already listens on (the
172
170
  * viewer engine's SSE-sourced live sync channel, ar-session-handoff) and
173
171
  * needs them to land exactly where a postMessage would.
174
172
  */
175
173
  receive(t) {
176
- if (this.isValid(t)) {
177
- if (this.shouldBuffer !== null && !this.shouldBuffer(t)) {
178
- this.routeToHandler(t);
179
- return;
180
- }
181
- this.consumer.enqueue(t);
182
- }
174
+ this.isValid(t) && this.consumer.enqueue(t);
183
175
  }
184
176
  /**
185
177
  * Enable sending and flush queued outgoing messages
@@ -212,10 +204,6 @@ class Dt {
212
204
  if (i !== null && t.source !== null && t.source !== i)
213
205
  return;
214
206
  const o = e;
215
- if (this.shouldBuffer !== null && !this.shouldBuffer(o)) {
216
- this.routeToHandler(o);
217
- return;
218
- }
219
207
  this.consumer.enqueue(o);
220
208
  }, window.addEventListener("message", this.listener));
221
209
  }
@@ -252,7 +240,7 @@ class Dt {
252
240
  });
253
241
  }
254
242
  }
255
- class Bt {
243
+ class qt {
256
244
  constructor(t) {
257
245
  this.send = t;
258
246
  }
@@ -264,7 +252,7 @@ class Bt {
264
252
  });
265
253
  }
266
254
  }
267
- class Ut {
255
+ class Gt {
268
256
  constructor(t, e) {
269
257
  this.value = t, this.attribute = e;
270
258
  }
@@ -307,7 +295,7 @@ class f extends Error {
307
295
  return new f(t, A.INVALID_PARAMETER);
308
296
  }
309
297
  }
310
- class Vt {
298
+ class Zt {
311
299
  name;
312
300
  defaultValue;
313
301
  values;
@@ -359,18 +347,18 @@ class Vt {
359
347
  createValues(t) {
360
348
  const e = /* @__PURE__ */ new Map();
361
349
  for (const i of t) {
362
- const o = new Ut(i, this.name);
350
+ const o = new Gt(i, this.name);
363
351
  i === this.defaultValue && o.setSelected(!0), e.set(i, o);
364
352
  }
365
353
  return e;
366
354
  }
367
355
  }
368
- class jt {
356
+ class Wt {
369
357
  attributes = /* @__PURE__ */ new Map();
370
358
  constructor(t, e, i) {
371
359
  for (const o of t) {
372
360
  const s = this.buildOptions(o, e);
373
- this.attributes.set(o.name, new Vt(s));
361
+ this.attributes.set(o.name, new Zt(s));
374
362
  }
375
363
  this.onMutationFailed = i;
376
364
  }
@@ -407,18 +395,55 @@ class jt {
407
395
  return t.defaultValue !== void 0 ? { ...i, defaultValue: t.defaultValue } : i;
408
396
  }
409
397
  }
410
- function Ht(n) {
411
- const t = new Date(n.timestamp).toLocaleTimeString("en-GB", { hour12: !1 }), e = n.level.toUpperCase().padEnd(5), i = n.trace_id?.slice(0, 8) ?? "--------", o = n.msg, s = ["timestamp", "level", "msg", "service", "trace_id", "span_id"], r = Object.entries(n).filter(([l]) => !s.includes(l)).map(([l, d]) => `${l}=${JSON.stringify(d)}`).join(" ");
412
- return `${t} ${e} [${i}] ${o}${r ? " " + r : ""}`;
398
+ const N = 4096, F = 16384, Yt = [1024, 256, 64], Qt = 20, Y = ["timestamp", "level", "msg", "service", "trace_id", "span_id"];
399
+ function Kt(n) {
400
+ const t = new Date(n.timestamp).toLocaleTimeString("en-GB", { hour12: !1 }), e = n.level.toUpperCase().padEnd(5), i = n.trace_id?.slice(0, 8) ?? "--------", o = n.msg, s = Object.entries(n).filter(([r]) => !Y.includes(r)).map(([r, a]) => `${r}=${I(a, N).line}`).join(" ");
401
+ return `${t} ${e} [${i}] ${o}${s ? " " + s : ""}`;
413
402
  }
414
- function qt(n) {
415
- return JSON.stringify(n);
416
- }
417
- function Gt(n, t) {
418
- const e = t ? Ht(n) : qt(n);
403
+ function Xt(n) {
404
+ for (const o of [N, ...Yt]) {
405
+ const { line: s, truncated: r } = I(n, o);
406
+ if (!r) {
407
+ if (s.length <= F)
408
+ return s;
409
+ continue;
410
+ }
411
+ const { line: a } = I({ ...n, log_truncated: !0 }, o);
412
+ if (a.length <= F)
413
+ return a;
414
+ }
415
+ const t = Object.keys(n).filter((o) => !Y.includes(o)), e = { ...te(n, Y), log_truncated: !0, log_dropped_count: t.length }, i = I({ ...e, log_dropped_attrs: t.slice(0, Qt) }, N);
416
+ return i.line.length <= F ? i.line : I(e, N).line;
417
+ }
418
+ function I(n, t) {
419
+ const e = [];
420
+ let i = !1;
421
+ return { line: JSON.stringify(n, function(r, a) {
422
+ if (typeof a == "string")
423
+ return a.length > t && (i = !0), Jt(a, t);
424
+ if (typeof a == "bigint")
425
+ return a.toString();
426
+ if (typeof a != "object" || a === null)
427
+ return a;
428
+ for (; e.length > 0 && e.at(-1) !== this; )
429
+ e.pop();
430
+ return e.includes(a) ? "[Circular]" : (e.push(a), a);
431
+ }), truncated: i };
432
+ }
433
+ function Jt(n, t) {
434
+ return n.length <= t ? n : `${n.slice(0, t)}...[truncated ${n.length - t} chars]`;
435
+ }
436
+ function te(n, t) {
437
+ const e = {};
438
+ for (const i of t)
439
+ n[i] !== void 0 && (e[i] = n[i]);
440
+ return e;
441
+ }
442
+ function ee(n, t) {
443
+ const e = t ? Kt(n) : Xt(n);
419
444
  n.level === "error" ? console.error(e) : n.level === "warn" ? console.warn(e) : console.log(e);
420
445
  }
421
- function lt(n, t = 0) {
446
+ function mt(n, t = 0) {
422
447
  const e = {
423
448
  name: n.name,
424
449
  message: n.message
@@ -430,36 +455,36 @@ function lt(n, t = 0) {
430
455
  const o = n[i];
431
456
  o !== void 0 && (e[i] = o);
432
457
  }
433
- return n.cause !== void 0 && n.cause !== null && (e.cause = n.cause instanceof Error && t < 5 ? lt(n.cause, t + 1) : String(n.cause)), e;
458
+ return n.cause !== void 0 && n.cause !== null && (e.cause = n.cause instanceof Error && t < 5 ? mt(n.cause, t + 1) : String(n.cause)), e;
434
459
  }
435
- function Zt(n) {
460
+ function ne(n) {
436
461
  const t = {};
437
462
  for (const [e, i] of Object.entries(n))
438
- t[e] = i instanceof Error ? lt(i) : i;
463
+ t[e] = i instanceof Error ? mt(i) : i;
439
464
  return t;
440
465
  }
441
- function Wt() {
466
+ function ie() {
442
467
  return /* @__PURE__ */ new Date();
443
468
  }
444
- function Qt(n) {
469
+ function oe(n) {
445
470
  return n.toISOString();
446
471
  }
447
- function ct() {
472
+ function pt() {
448
473
  return typeof navigator > "u" ? "" : navigator.userAgent;
449
474
  }
450
- function Yt() {
475
+ function se() {
451
476
  return typeof navigator > "u" ? !1 : navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
452
477
  }
453
- function Kt() {
454
- return /iPhone|iPad|iPod/i.test(ct()) || Yt();
478
+ function re() {
479
+ return /iPhone|iPad|iPod/i.test(pt()) || se();
455
480
  }
456
- function Xt() {
457
- return /Android/i.test(ct());
481
+ function ae() {
482
+ return /Android/i.test(pt());
458
483
  }
459
- function Jt() {
460
- return Kt() || Xt();
484
+ function le() {
485
+ return re() || ae();
461
486
  }
462
- class te {
487
+ class ce {
463
488
  constructor(t) {
464
489
  this.config = t;
465
490
  }
@@ -469,14 +494,14 @@ class te {
469
494
  */
470
495
  log(t, e, i = {}) {
471
496
  const o = this.config.traceProvider?.() ?? {}, s = {
472
- timestamp: Qt(Wt()),
497
+ timestamp: oe(ie()),
473
498
  level: t,
474
499
  msg: e,
475
500
  service: this.config.service,
476
501
  ...o,
477
- ...Zt(i)
502
+ ...ne(i)
478
503
  };
479
- Gt(s, this.config.isDev);
504
+ ee(s, this.config.isDev);
480
505
  }
481
506
  /**
482
507
  * Log at DEBUG level (development only).
@@ -503,15 +528,15 @@ class te {
503
528
  this.log("error", t, e);
504
529
  }
505
530
  }
506
- function ut(n, t) {
531
+ function ft(n, t) {
507
532
  const e = t?.isDev !== void 0 ? t.isDev : typeof process < "u" ? process.env.NODE_ENV !== "production" : !0;
508
- return new te({ service: n, isDev: e, traceProvider: t?.traceProvider });
533
+ return new ce({ service: n, isDev: e, traceProvider: t?.traceProvider });
509
534
  }
510
535
  function O(n) {
511
536
  if (n !== void 0)
512
537
  return typeof n == "object" && n !== null && !Array.isArray(n) && !(n instanceof Error) ? n : n instanceof Error ? { error: n.message } : { value: n };
513
538
  }
514
- function dt(n) {
539
+ function gt(n) {
515
540
  return {
516
541
  debug: (t, e) => n.debug(t, O(e)),
517
542
  info: (t, e) => n.info(t, O(e)),
@@ -519,14 +544,14 @@ function dt(n) {
519
544
  error: (t, e) => n.error(t, O(e))
520
545
  };
521
546
  }
522
- let ht = !1, _ = dt(ut("client", { isDev: !1 }));
523
- function ee() {
524
- ht = !0, _ = dt(ut("client", { isDev: !0 }));
547
+ let bt = !1, _ = gt(ft("client", { isDev: !1 }));
548
+ function de() {
549
+ bt = !0, _ = gt(ft("client", { isDev: !0 }));
525
550
  }
526
- function Ki() {
527
- return ht;
551
+ function uo() {
552
+ return bt;
528
553
  }
529
- class ne {
554
+ class ue {
530
555
  constructor(t, e) {
531
556
  this.send = t, this.onMutationFailed = e;
532
557
  }
@@ -540,7 +565,7 @@ class ne {
540
565
  handleMappingReceived(t) {
541
566
  _.debug("Initializing from server mapping", {
542
567
  attributeCount: t.attributes.length
543
- }), this.registry = new jt(
568
+ }), this.registry = new Wt(
544
569
  t.attributes,
545
570
  (e, i) => this.sendMutation(e, i),
546
571
  this.onMutationFailed
@@ -605,7 +630,27 @@ class ne {
605
630
  this.pendingCallbacks.length = 0;
606
631
  }
607
632
  }
608
- let ie = class {
633
+ class he {
634
+ snapshot;
635
+ callbacks = [];
636
+ handleSnapshot(t) {
637
+ this.snapshot = t.attributes;
638
+ for (const e of this.callbacks)
639
+ e(t.attributes);
640
+ }
641
+ onChange(t) {
642
+ this.callbacks.push(t), this.snapshot !== void 0 && t(this.snapshot);
643
+ }
644
+ /** The selectable values for one attribute, or null when unrestricted. */
645
+ selectableFor(t) {
646
+ return this.snapshot?.find((i) => i.name === t)?.selectable ?? null;
647
+ }
648
+ /** The latest snapshot; empty before the viewer has reported anything. */
649
+ get current() {
650
+ return this.snapshot ?? [];
651
+ }
652
+ }
653
+ let me = class {
609
654
  constructor(t) {
610
655
  this.send = t;
611
656
  }
@@ -668,7 +713,7 @@ let ie = class {
668
713
  this.send(t);
669
714
  }
670
715
  };
671
- class oe {
716
+ class pe {
672
717
  state;
673
718
  limitsState;
674
719
  changeCallbacks = [];
@@ -756,20 +801,20 @@ class oe {
756
801
  }
757
802
  }
758
803
  }
759
- function se(n, t) {
760
- const e = n.filter((s) => re(s, t));
804
+ function fe(n, t) {
805
+ const e = n.filter((s) => ge(s, t));
761
806
  if (e.length === 0)
762
807
  return;
763
- const i = Math.max(...e.map(K)), o = e.filter((s) => K(s) === i);
808
+ const i = Math.max(...e.map(nt)), o = e.filter((s) => nt(s) === i);
764
809
  return o.length === 1 ? o[0] : void 0;
765
810
  }
766
- function re(n, t) {
811
+ function ge(n, t) {
767
812
  return Object.entries(n.attributes).every(([e, i]) => t[e] === i);
768
813
  }
769
- function K(n) {
814
+ function nt(n) {
770
815
  return Object.keys(n.attributes).length;
771
816
  }
772
- class ae {
817
+ class be {
773
818
  constructor(t, e) {
774
819
  this.dispatchChange = t, this.dispatchSubmit = e;
775
820
  }
@@ -879,8 +924,8 @@ class ae {
879
924
  resolve() {
880
925
  if (this.pricing === void 0)
881
926
  return;
882
- const t = se(this.pricing.rules, this.selection);
883
- if (!(t === void 0 || t.availability === At.HIDDEN))
927
+ const t = fe(this.pricing.rules, this.selection);
928
+ if (!(t === void 0 || t.availability === Rt.HIDDEN))
884
929
  return {
885
930
  attributes: { ...this.selection },
886
931
  reference: t.reference,
@@ -890,7 +935,7 @@ class ae {
890
935
  };
891
936
  }
892
937
  }
893
- class le {
938
+ class ve {
894
939
  constructor(t, e) {
895
940
  this.send = t, this.dispatch = e;
896
941
  }
@@ -912,11 +957,11 @@ class le {
912
957
  throw f.invalidParameter(
913
958
  `set() requires a non-empty component name, got ${String(t)}`
914
959
  );
915
- this.send({ type: c.FOCUS, action: Q.FOCUS, component: t });
960
+ this.send({ type: c.FOCUS, action: tt.FOCUS, component: t });
916
961
  }
917
962
  /** Return to the overview — unfocus the current component. */
918
963
  clear() {
919
- this.send({ type: c.FOCUS, action: Q.UNFOCUS });
964
+ this.send({ type: c.FOCUS, action: tt.UNFOCUS });
920
965
  }
921
966
  /**
922
967
  * Subscribe to focus changes. The callback fires with the focus state when a
@@ -927,14 +972,14 @@ class le {
927
972
  }
928
973
  /** Called by the client when a FocusStateMessage is received from the viewer. */
929
974
  handleStateReceived(t) {
930
- t.state === kt.FOCUSED && t.component !== void 0 ? (this.focused = t.component, this.attributes = t.attributes ?? []) : (this.focused = null, this.attributes = []);
975
+ t.state === Tt.FOCUSED && t.component !== void 0 ? (this.focused = t.component, this.attributes = t.attributes ?? []) : (this.focused = null, this.attributes = []);
931
976
  const e = this.focused !== null ? { component: this.focused, attributes: this.attributes } : null;
932
977
  for (const i of this.changeCallbacks)
933
978
  i(e);
934
979
  this.dispatch(e);
935
980
  }
936
981
  }
937
- class ce {
982
+ class ye {
938
983
  constructor(t) {
939
984
  this.filename = t;
940
985
  }
@@ -987,8 +1032,8 @@ class ce {
987
1032
  }), this.developedCallbacks.clear(), this.errorCallbacks.clear());
988
1033
  }
989
1034
  }
990
- const X = 3e4;
991
- class ue {
1035
+ const it = 3e4;
1036
+ class we {
992
1037
  constructor(t) {
993
1038
  this.send = t;
994
1039
  }
@@ -1004,12 +1049,12 @@ class ue {
1004
1049
  */
1005
1050
  take(t) {
1006
1051
  this.validateFilename(t), _.debug("Taking snapshot", { filename: t });
1007
- const e = new ce(t), i = setTimeout(() => {
1052
+ const e = new ye(t), i = setTimeout(() => {
1008
1053
  this.pendingPhotos.delete(t), _.warn("Snapshot timed out", { filename: t }), e.fail(new f(
1009
- `Snapshot timed out: the viewer did not respond within ${X}ms`,
1054
+ `Snapshot timed out: the viewer did not respond within ${it}ms`,
1010
1055
  A.SNAPSHOT_FAILED
1011
1056
  ));
1012
- }, X);
1057
+ }, it);
1013
1058
  return this.pendingPhotos.set(t, { photo: e, timeout: i }), this.send({
1014
1059
  type: c.SNAPSHOT,
1015
1060
  filename: t
@@ -1075,7 +1120,7 @@ class ue {
1075
1120
  );
1076
1121
  }
1077
1122
  }
1078
- class de {
1123
+ class Se {
1079
1124
  container = null;
1080
1125
  attach(t) {
1081
1126
  this.container = t;
@@ -1096,626 +1141,636 @@ class de {
1096
1141
  };
1097
1142
  }
1098
1143
  }
1099
- const he = {}, me = "en", mt = (
1144
+ const _e = {}, Ce = "en", vt = (
1100
1145
  /** @type {const} */
1101
1146
  ["en", "nl", "de"]
1102
- ), Z = [
1147
+ ), K = [
1103
1148
  "baseLocale"
1104
- ], J = [];
1105
- let tt, et;
1106
- function pe(n) {
1107
- if (J.length === 0)
1108
- return;
1109
- const t = typeof n == "string" ? n : n.href;
1110
- if (tt === t)
1111
- return et;
1112
- const e = new URL(t, "http://dummy.com");
1113
- let i;
1114
- for (const o of J)
1115
- if (new he(o.match, e.href).exec(e.href)) {
1116
- i = o;
1117
- break;
1118
- }
1119
- return tt = t, et = i, i;
1120
- }
1121
- function pt(n) {
1122
- const t = pe(n);
1123
- return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : Z;
1124
- }
1125
- const G = typeof window > "u";
1149
+ ], ot = [], Q = typeof window > "u";
1126
1150
  globalThis.__paraglide = /** @type {any} */
1127
1151
  globalThis.__paraglide ?? {};
1128
1152
  globalThis.__paraglide.ssr = /** @type {any} */
1129
1153
  globalThis.__paraglide.ssr ?? {};
1130
- let nt = !1, h = () => {
1131
- let n = Z;
1132
- !G && typeof window < "u" && window.location?.href && (n = pt(window.location.href));
1133
- const t = fe(n);
1154
+ let st = !1, u = () => {
1155
+ let n = K;
1156
+ !Q && typeof window < "u" && window.location?.href && (n = wt(window.location.href));
1157
+ const t = ke(n);
1134
1158
  if (t)
1135
- return nt || (nt = !0, ft(t, { reload: !1 })), t;
1159
+ return st || (st = !0, yt(t, { reload: !1 })), t;
1136
1160
  throw new Error("No locale found. Read the docs https://paraglidejs.com/errors#no-locale-found");
1137
1161
  };
1138
- function fe(n, t) {
1162
+ function ke(n, t) {
1139
1163
  let e;
1140
1164
  for (const i of n) {
1141
1165
  if (i === "baseLocale")
1142
- e = me;
1143
- else if (bt(i) && N.has(i)) {
1144
- const s = N.get(i);
1166
+ e = Ce;
1167
+ else if (St(i) && M.has(i)) {
1168
+ const s = M.get(i);
1145
1169
  if (s) {
1146
1170
  const r = s.getLocale();
1147
1171
  if (r instanceof Promise)
1148
1172
  continue;
1149
1173
  if (r !== void 0)
1150
- return be(r);
1174
+ return xe(r);
1151
1175
  }
1152
1176
  }
1153
- const o = gt(e);
1177
+ const o = X(e);
1154
1178
  if (o)
1155
1179
  return o;
1156
1180
  }
1157
1181
  }
1158
- const ge = (n) => {
1182
+ const Ae = (n) => {
1159
1183
  window.location.reload();
1160
1184
  };
1161
- let ft = (n, t) => {
1185
+ let yt = (n, t) => {
1162
1186
  const e = {
1163
1187
  reload: !0,
1164
1188
  ...t
1165
1189
  };
1166
1190
  let i;
1167
1191
  try {
1168
- i = h();
1192
+ i = u();
1169
1193
  } catch {
1170
1194
  }
1171
1195
  const o = [];
1172
- let s = Z;
1173
- !G && typeof window < "u" && window.location?.href && (s = pt(window.location.href));
1174
- for (const l of s)
1175
- if (l !== "baseLocale" && bt(l) && N.has(l)) {
1176
- const d = N.get(l);
1177
- if (d) {
1178
- let u = d.setLocale(n);
1179
- u instanceof Promise && (u = u.catch((p) => {
1180
- throw new Error(`Custom strategy "${l}" setLocale failed.`, {
1181
- cause: p
1196
+ let s = K;
1197
+ !Q && typeof window < "u" && window.location?.href && (s = wt(window.location.href));
1198
+ for (const a of s)
1199
+ if (a !== "baseLocale" && St(a) && M.has(a)) {
1200
+ const h = M.get(a);
1201
+ if (h) {
1202
+ let d = h.setLocale(n);
1203
+ d instanceof Promise && (d = d.catch((m) => {
1204
+ throw new Error(`Custom strategy "${a}" setLocale failed.`, {
1205
+ cause: m
1182
1206
  });
1183
- }), o.push(u));
1207
+ }), o.push(d));
1184
1208
  }
1185
1209
  }
1186
1210
  const r = () => {
1187
- !G && e.reload && window.location && n !== i && ge();
1211
+ !Q && e.reload && window.location && n !== i && Ae();
1188
1212
  };
1189
1213
  if (o.length)
1190
1214
  return Promise.all(o).then(() => {
1191
1215
  r();
1192
1216
  });
1193
1217
  r();
1194
- };
1195
- function gt(n) {
1218
+ }, Ee = () => typeof window < "u" ? window.location.origin : "http://fallback.com";
1219
+ function X(n) {
1196
1220
  if (typeof n != "string")
1197
1221
  return;
1198
1222
  const t = n.toLowerCase();
1199
- for (const e of mt)
1223
+ for (const e of vt)
1200
1224
  if (e.toLowerCase() === t)
1201
1225
  return e;
1202
1226
  }
1203
- function be(n) {
1204
- const t = gt(n);
1227
+ function xe(n) {
1228
+ const t = X(n);
1205
1229
  if (t)
1206
1230
  return t;
1207
- throw new Error(`Invalid locale: ${n}. Expected one of: ${mt.join(", ")}`);
1231
+ throw new Error(`Invalid locale: ${n}. Expected one of: ${vt.join(", ")}`);
1232
+ }
1233
+ function Te(n) {
1234
+ return Re(n);
1235
+ }
1236
+ function Re(n) {
1237
+ const t = typeof n == "string" ? new URL(n, Ee()) : new URL(n), e = t.pathname.split("/").filter(Boolean);
1238
+ return e.length > 0 && X(e[0]) && (t.pathname = "/" + e.slice(1).join("/")), t;
1239
+ }
1240
+ let rt, at;
1241
+ function Ie(n) {
1242
+ if (ot.length === 0)
1243
+ return;
1244
+ const t = typeof n == "string" ? n : n.href;
1245
+ if (rt === t)
1246
+ return at;
1247
+ const e = new URL(t, "http://example.com"), i = Te(e), o = i.href === e.href ? [e] : [e, i];
1248
+ let s;
1249
+ for (const r of o) {
1250
+ for (const a of ot)
1251
+ if (new _e(a.match, r.href).exec(r.href)) {
1252
+ s = a;
1253
+ break;
1254
+ }
1255
+ if (s)
1256
+ break;
1257
+ }
1258
+ return rt = t, at = s, s;
1208
1259
  }
1209
- const N = /* @__PURE__ */ new Map();
1210
- function bt(n) {
1260
+ function wt(n) {
1261
+ const t = Ie(n);
1262
+ return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : K;
1263
+ }
1264
+ const M = /* @__PURE__ */ new Map();
1265
+ function St(n) {
1211
1266
  return typeof n == "string" && /^custom-[A-Za-z0-9_-]+$/.test(n);
1212
1267
  }
1213
- const ve = (
1268
+ const Le = (
1214
1269
  /** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
1215
1270
  () => (
1216
1271
  /** @type {LocalizedString} */
1217
1272
  "Activate AR"
1218
1273
  )
1219
- ), ye = (
1274
+ ), Oe = (
1220
1275
  /** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
1221
1276
  () => (
1222
1277
  /** @type {LocalizedString} */
1223
1278
  "AR activeren"
1224
1279
  )
1225
- ), we = (
1280
+ ), Ne = (
1226
1281
  /** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
1227
1282
  () => (
1228
1283
  /** @type {LocalizedString} */
1229
1284
  "AR aktivieren"
1230
1285
  )
1231
- ), _e = (
1286
+ ), Me = (
1232
1287
  /** @type {((inputs?: Controls_Ar_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Ar_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1233
1288
  ((n = {}, t = {}) => {
1234
- const e = t.locale ?? h();
1235
- return e === "en" ? ve() : e === "nl" ? ye() : we();
1289
+ const e = t.locale ?? u();
1290
+ return e === "nl" ? Oe() : e === "de" ? Ne() : Le();
1236
1291
  })
1237
- ), Ce = (
1292
+ ), ze = (
1238
1293
  /** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
1239
1294
  () => (
1240
1295
  /** @type {LocalizedString} */
1241
1296
  "Scan to view in AR"
1242
1297
  )
1243
- ), Se = (
1298
+ ), Pe = (
1244
1299
  /** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
1245
1300
  () => (
1246
1301
  /** @type {LocalizedString} */
1247
1302
  "Scan om in AR te bekijken"
1248
1303
  )
1249
- ), ke = (
1304
+ ), Fe = (
1250
1305
  /** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
1251
1306
  () => (
1252
1307
  /** @type {LocalizedString} */
1253
1308
  "Scannen für AR-Ansicht"
1254
1309
  )
1255
- ), Ae = (
1310
+ ), $e = (
1256
1311
  /** @type {((inputs?: Controls_Qr_Modaltitle1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modaltitle1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1257
1312
  ((n = {}, t = {}) => {
1258
- const e = t.locale ?? h();
1259
- return e === "en" ? Ce() : e === "nl" ? Se() : ke();
1313
+ const e = t.locale ?? u();
1314
+ return e === "nl" ? Pe() : e === "de" ? Fe() : ze();
1260
1315
  })
1261
- ), Ee = (
1316
+ ), De = (
1262
1317
  /** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
1263
1318
  () => (
1264
1319
  /** @type {LocalizedString} */
1265
1320
  "Use your smartphone camera to scan this QR code"
1266
1321
  )
1267
- ), xe = (
1322
+ ), Be = (
1268
1323
  /** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
1269
1324
  () => (
1270
1325
  /** @type {LocalizedString} */
1271
1326
  "Gebruik de camera van je smartphone om deze QR-code te scannen"
1272
1327
  )
1273
- ), Te = (
1328
+ ), Ue = (
1274
1329
  /** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
1275
1330
  () => (
1276
1331
  /** @type {LocalizedString} */
1277
1332
  "Verwende die Kamera deines Smartphones, um diesen QR-Code zu scannen"
1278
1333
  )
1279
- ), Re = (
1334
+ ), Ve = (
1280
1335
  /** @type {((inputs?: Controls_Qr_Modaldescription1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modaldescription1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1281
1336
  ((n = {}, t = {}) => {
1282
- const e = t.locale ?? h();
1283
- return e === "en" ? Ee() : e === "nl" ? xe() : Te();
1337
+ const e = t.locale ?? u();
1338
+ return e === "nl" ? Be() : e === "de" ? Ue() : De();
1284
1339
  })
1285
- ), Ie = (
1340
+ ), je = (
1286
1341
  /** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
1287
1342
  () => (
1288
1343
  /** @type {LocalizedString} */
1289
1344
  "Your phone will open the 3D model in AR mode."
1290
1345
  )
1291
- ), Oe = (
1346
+ ), He = (
1292
1347
  /** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
1293
1348
  () => (
1294
1349
  /** @type {LocalizedString} */
1295
1350
  "Je telefoon opent het 3D-model in AR-modus."
1296
1351
  )
1297
- ), Ne = (
1352
+ ), qe = (
1298
1353
  /** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
1299
1354
  () => (
1300
1355
  /** @type {LocalizedString} */
1301
1356
  "Dein Telefon öffnet das 3D-Modell im AR-Modus."
1302
1357
  )
1303
- ), Me = (
1358
+ ), Ge = (
1304
1359
  /** @type {((inputs?: Controls_Qr_Modalinstructions1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modalinstructions1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1305
1360
  ((n = {}, t = {}) => {
1306
- const e = t.locale ?? h();
1307
- return e === "en" ? Ie() : e === "nl" ? Oe() : Ne();
1361
+ const e = t.locale ?? u();
1362
+ return e === "nl" ? He() : e === "de" ? qe() : je();
1308
1363
  })
1309
- ), Le = (
1364
+ ), Ze = (
1310
1365
  /** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
1311
1366
  () => (
1312
1367
  /** @type {LocalizedString} */
1313
1368
  "Close"
1314
1369
  )
1315
- ), ze = (
1370
+ ), We = (
1316
1371
  /** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
1317
1372
  () => (
1318
1373
  /** @type {LocalizedString} */
1319
1374
  "Sluiten"
1320
1375
  )
1321
- ), Pe = (
1376
+ ), Ye = (
1322
1377
  /** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
1323
1378
  () => (
1324
1379
  /** @type {LocalizedString} */
1325
1380
  "Schließen"
1326
1381
  )
1327
- ), Fe = (
1382
+ ), Qe = (
1328
1383
  /** @type {((inputs?: Controls_Qr_Closebutton1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Closebutton1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1329
1384
  ((n = {}, t = {}) => {
1330
- const e = t.locale ?? h();
1331
- return e === "en" ? Le() : e === "nl" ? ze() : Pe();
1385
+ const e = t.locale ?? u();
1386
+ return e === "nl" ? We() : e === "de" ? Ye() : Ze();
1332
1387
  })
1333
- ), $e = (
1388
+ ), Ke = (
1334
1389
  /** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
1335
1390
  () => (
1336
1391
  /** @type {LocalizedString} */
1337
1392
  "Fullscreen"
1338
1393
  )
1339
- ), De = (
1394
+ ), Xe = (
1340
1395
  /** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
1341
1396
  () => (
1342
1397
  /** @type {LocalizedString} */
1343
1398
  "Volledig scherm"
1344
1399
  )
1345
- ), Be = (
1400
+ ), Je = (
1346
1401
  /** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
1347
1402
  () => (
1348
1403
  /** @type {LocalizedString} */
1349
1404
  "Vollbild"
1350
1405
  )
1351
- ), Ue = (
1406
+ ), tn = (
1352
1407
  /** @type {((inputs?: Controls_Fullscreen_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Fullscreen_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1353
1408
  ((n = {}, t = {}) => {
1354
- const e = t.locale ?? h();
1355
- return e === "en" ? $e() : e === "nl" ? De() : Be();
1409
+ const e = t.locale ?? u();
1410
+ return e === "nl" ? Xe() : e === "de" ? Je() : Ke();
1356
1411
  })
1357
- ), Ve = (
1412
+ ), en = (
1358
1413
  /** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
1359
1414
  () => (
1360
1415
  /** @type {LocalizedString} */
1361
1416
  "Downloading"
1362
1417
  )
1363
- ), je = (
1418
+ ), nn = (
1364
1419
  /** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
1365
1420
  () => (
1366
1421
  /** @type {LocalizedString} */
1367
1422
  "Downloaden"
1368
1423
  )
1369
- ), He = (
1424
+ ), on = (
1370
1425
  /** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
1371
1426
  () => (
1372
1427
  /** @type {LocalizedString} */
1373
1428
  "Herunterladen"
1374
1429
  )
1375
- ), vt = (
1430
+ ), _t = (
1376
1431
  /** @type {((inputs?: Loading_Downloadingshort1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_Downloadingshort1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1377
1432
  ((n = {}, t = {}) => {
1378
- const e = t.locale ?? h();
1379
- return e === "en" ? Ve() : e === "nl" ? je() : He();
1433
+ const e = t.locale ?? u();
1434
+ return e === "nl" ? nn() : e === "de" ? on() : en();
1380
1435
  })
1381
- ), qe = (
1436
+ ), sn = (
1382
1437
  /** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
1383
1438
  () => (
1384
1439
  /** @type {LocalizedString} */
1385
1440
  "Rendering"
1386
1441
  )
1387
- ), Ge = (
1442
+ ), rn = (
1388
1443
  /** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
1389
1444
  () => (
1390
1445
  /** @type {LocalizedString} */
1391
1446
  "Renderen"
1392
1447
  )
1393
- ), Ze = (
1448
+ ), an = (
1394
1449
  /** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
1395
1450
  () => (
1396
1451
  /** @type {LocalizedString} */
1397
1452
  "Rendern"
1398
1453
  )
1399
- ), We = (
1454
+ ), ln = (
1400
1455
  /** @type {((inputs?: Loading_RenderingInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_RenderingInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1401
1456
  ((n = {}, t = {}) => {
1402
- const e = t.locale ?? h();
1403
- return e === "en" ? qe() : e === "nl" ? Ge() : Ze();
1457
+ const e = t.locale ?? u();
1458
+ return e === "nl" ? rn() : e === "de" ? an() : sn();
1404
1459
  })
1405
- ), Qe = (
1460
+ ), cn = (
1406
1461
  /** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
1407
1462
  () => (
1408
1463
  /** @type {LocalizedString} */
1409
1464
  "Screenshot"
1410
1465
  )
1411
- ), Ye = (
1466
+ ), dn = (
1412
1467
  /** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
1413
1468
  () => (
1414
1469
  /** @type {LocalizedString} */
1415
1470
  "Screenshot"
1416
1471
  )
1417
- ), Ke = (
1472
+ ), un = (
1418
1473
  /** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
1419
1474
  () => (
1420
1475
  /** @type {LocalizedString} */
1421
1476
  "Screenshot"
1422
1477
  )
1423
- ), Xe = (
1478
+ ), hn = (
1424
1479
  /** @type {((inputs?: Controls_Screenshot_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Screenshot_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1425
1480
  ((n = {}, t = {}) => {
1426
- const e = t.locale ?? h();
1427
- return e === "en" ? Qe() : e === "nl" ? Ye() : Ke();
1481
+ const e = t.locale ?? u();
1482
+ return e === "nl" ? dn() : e === "de" ? un() : cn();
1428
1483
  })
1429
- ), Je = (
1484
+ ), mn = (
1430
1485
  /** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
1431
1486
  () => (
1432
1487
  /** @type {LocalizedString} */
1433
1488
  "Configure"
1434
1489
  )
1435
- ), tn = (
1490
+ ), pn = (
1436
1491
  /** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
1437
1492
  () => (
1438
1493
  /** @type {LocalizedString} */
1439
1494
  "Configureren"
1440
1495
  )
1441
- ), en = (
1496
+ ), fn = (
1442
1497
  /** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
1443
1498
  () => (
1444
1499
  /** @type {LocalizedString} */
1445
1500
  "Konfigurieren"
1446
1501
  )
1447
- ), nn = (
1502
+ ), gn = (
1448
1503
  /** @type {((inputs?: Controls_Configurator_OpenInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Configurator_OpenInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1449
1504
  ((n = {}, t = {}) => {
1450
- const e = t.locale ?? h();
1451
- return e === "en" ? Je() : e === "nl" ? tn() : en();
1505
+ const e = t.locale ?? u();
1506
+ return e === "nl" ? pn() : e === "de" ? fn() : mn();
1452
1507
  })
1453
- ), on = (
1508
+ ), bn = (
1454
1509
  /** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
1455
1510
  () => (
1456
1511
  /** @type {LocalizedString} */
1457
1512
  "Close"
1458
1513
  )
1459
- ), sn = (
1514
+ ), vn = (
1460
1515
  /** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
1461
1516
  () => (
1462
1517
  /** @type {LocalizedString} */
1463
1518
  "Sluiten"
1464
1519
  )
1465
- ), rn = (
1520
+ ), yn = (
1466
1521
  /** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
1467
1522
  () => (
1468
1523
  /** @type {LocalizedString} */
1469
1524
  "Schließen"
1470
1525
  )
1471
- ), an = (
1526
+ ), wn = (
1472
1527
  /** @type {((inputs?: Controls_Configurator_CloseInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Configurator_CloseInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1473
1528
  ((n = {}, t = {}) => {
1474
- const e = t.locale ?? h();
1475
- return e === "en" ? on() : e === "nl" ? sn() : rn();
1529
+ const e = t.locale ?? u();
1530
+ return e === "nl" ? vn() : e === "de" ? yn() : bn();
1476
1531
  })
1477
- ), ln = (
1532
+ ), Sn = (
1478
1533
  /** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
1479
1534
  () => (
1480
1535
  /** @type {LocalizedString} */
1481
1536
  "Reset camera"
1482
1537
  )
1483
- ), cn = (
1538
+ ), _n = (
1484
1539
  /** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
1485
1540
  () => (
1486
1541
  /** @type {LocalizedString} */
1487
1542
  "Camera resetten"
1488
1543
  )
1489
- ), un = (
1544
+ ), Cn = (
1490
1545
  /** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
1491
1546
  () => (
1492
1547
  /** @type {LocalizedString} */
1493
1548
  "Kamera zurücksetzen"
1494
1549
  )
1495
- ), dn = (
1550
+ ), kn = (
1496
1551
  /** @type {((inputs?: Controls_Camera_ResetInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_ResetInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1497
1552
  ((n = {}, t = {}) => {
1498
- const e = t.locale ?? h();
1499
- return e === "en" ? ln() : e === "nl" ? cn() : un();
1553
+ const e = t.locale ?? u();
1554
+ return e === "nl" ? _n() : e === "de" ? Cn() : Sn();
1500
1555
  })
1501
- ), hn = (
1556
+ ), An = (
1502
1557
  /** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
1503
1558
  () => (
1504
1559
  /** @type {LocalizedString} */
1505
1560
  "Zoom in"
1506
1561
  )
1507
- ), mn = (
1562
+ ), En = (
1508
1563
  /** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
1509
1564
  () => (
1510
1565
  /** @type {LocalizedString} */
1511
1566
  "Inzoomen"
1512
1567
  )
1513
- ), pn = (
1568
+ ), xn = (
1514
1569
  /** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
1515
1570
  () => (
1516
1571
  /** @type {LocalizedString} */
1517
1572
  "Hineinzoomen"
1518
1573
  )
1519
- ), fn = (
1574
+ ), Tn = (
1520
1575
  /** @type {((inputs?: Controls_Camera_Zoomin1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Zoomin1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1521
1576
  ((n = {}, t = {}) => {
1522
- const e = t.locale ?? h();
1523
- return e === "en" ? hn() : e === "nl" ? mn() : pn();
1577
+ const e = t.locale ?? u();
1578
+ return e === "nl" ? En() : e === "de" ? xn() : An();
1524
1579
  })
1525
- ), gn = (
1580
+ ), Rn = (
1526
1581
  /** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
1527
1582
  () => (
1528
1583
  /** @type {LocalizedString} */
1529
1584
  "Zoom out"
1530
1585
  )
1531
- ), bn = (
1586
+ ), In = (
1532
1587
  /** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
1533
1588
  () => (
1534
1589
  /** @type {LocalizedString} */
1535
1590
  "Uitzoomen"
1536
1591
  )
1537
- ), vn = (
1592
+ ), Ln = (
1538
1593
  /** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
1539
1594
  () => (
1540
1595
  /** @type {LocalizedString} */
1541
1596
  "Herauszoomen"
1542
1597
  )
1543
- ), yn = (
1598
+ ), On = (
1544
1599
  /** @type {((inputs?: Controls_Camera_Zoomout1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Zoomout1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1545
1600
  ((n = {}, t = {}) => {
1546
- const e = t.locale ?? h();
1547
- return e === "en" ? gn() : e === "nl" ? bn() : vn();
1601
+ const e = t.locale ?? u();
1602
+ return e === "nl" ? In() : e === "de" ? Ln() : Rn();
1548
1603
  })
1549
- ), wn = (
1604
+ ), Nn = (
1550
1605
  /** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
1551
1606
  () => (
1552
1607
  /** @type {LocalizedString} */
1553
1608
  "Rotate left"
1554
1609
  )
1555
- ), _n = (
1610
+ ), Mn = (
1556
1611
  /** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
1557
1612
  () => (
1558
1613
  /** @type {LocalizedString} */
1559
1614
  "Naar links draaien"
1560
1615
  )
1561
- ), Cn = (
1616
+ ), zn = (
1562
1617
  /** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
1563
1618
  () => (
1564
1619
  /** @type {LocalizedString} */
1565
1620
  "Nach links drehen"
1566
1621
  )
1567
- ), Sn = (
1622
+ ), Pn = (
1568
1623
  /** @type {((inputs?: Controls_Camera_Rotateleft1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Rotateleft1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1569
1624
  ((n = {}, t = {}) => {
1570
- const e = t.locale ?? h();
1571
- return e === "en" ? wn() : e === "nl" ? _n() : Cn();
1625
+ const e = t.locale ?? u();
1626
+ return e === "nl" ? Mn() : e === "de" ? zn() : Nn();
1572
1627
  })
1573
- ), kn = (
1628
+ ), Fn = (
1574
1629
  /** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
1575
1630
  () => (
1576
1631
  /** @type {LocalizedString} */
1577
1632
  "Rotate right"
1578
1633
  )
1579
- ), An = (
1634
+ ), $n = (
1580
1635
  /** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
1581
1636
  () => (
1582
1637
  /** @type {LocalizedString} */
1583
1638
  "Naar rechts draaien"
1584
1639
  )
1585
- ), En = (
1640
+ ), Dn = (
1586
1641
  /** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
1587
1642
  () => (
1588
1643
  /** @type {LocalizedString} */
1589
1644
  "Nach rechts drehen"
1590
1645
  )
1591
- ), xn = (
1646
+ ), Bn = (
1592
1647
  /** @type {((inputs?: Controls_Camera_Rotateright1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Rotateright1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1593
1648
  ((n = {}, t = {}) => {
1594
- const e = t.locale ?? h();
1595
- return e === "en" ? kn() : e === "nl" ? An() : En();
1649
+ const e = t.locale ?? u();
1650
+ return e === "nl" ? $n() : e === "de" ? Dn() : Fn();
1596
1651
  })
1597
- ), Tn = (
1652
+ ), Un = (
1598
1653
  /** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
1599
1654
  () => (
1600
1655
  /** @type {LocalizedString} */
1601
1656
  "Tilt up"
1602
1657
  )
1603
- ), Rn = (
1658
+ ), Vn = (
1604
1659
  /** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
1605
1660
  () => (
1606
1661
  /** @type {LocalizedString} */
1607
1662
  "Omhoog kantelen"
1608
1663
  )
1609
- ), In = (
1664
+ ), jn = (
1610
1665
  /** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
1611
1666
  () => (
1612
1667
  /** @type {LocalizedString} */
1613
1668
  "Nach oben kippen"
1614
1669
  )
1615
- ), On = (
1670
+ ), Hn = (
1616
1671
  /** @type {((inputs?: Controls_Camera_Tiltup1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Tiltup1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1617
1672
  ((n = {}, t = {}) => {
1618
- const e = t.locale ?? h();
1619
- return e === "en" ? Tn() : e === "nl" ? Rn() : In();
1673
+ const e = t.locale ?? u();
1674
+ return e === "nl" ? Vn() : e === "de" ? jn() : Un();
1620
1675
  })
1621
- ), Nn = (
1676
+ ), qn = (
1622
1677
  /** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
1623
1678
  () => (
1624
1679
  /** @type {LocalizedString} */
1625
1680
  "Tilt down"
1626
1681
  )
1627
- ), Mn = (
1682
+ ), Gn = (
1628
1683
  /** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
1629
1684
  () => (
1630
1685
  /** @type {LocalizedString} */
1631
1686
  "Omlaag kantelen"
1632
1687
  )
1633
- ), Ln = (
1688
+ ), Zn = (
1634
1689
  /** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
1635
1690
  () => (
1636
1691
  /** @type {LocalizedString} */
1637
1692
  "Nach unten kippen"
1638
1693
  )
1639
- ), zn = (
1694
+ ), Wn = (
1640
1695
  /** @type {((inputs?: Controls_Camera_Tiltdown1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Tiltdown1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1641
1696
  ((n = {}, t = {}) => {
1642
- const e = t.locale ?? h();
1643
- return e === "en" ? Nn() : e === "nl" ? Mn() : Ln();
1697
+ const e = t.locale ?? u();
1698
+ return e === "nl" ? Gn() : e === "de" ? Zn() : qn();
1644
1699
  })
1645
- ), Pn = (
1700
+ ), Yn = (
1646
1701
  /** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
1647
1702
  () => (
1648
1703
  /** @type {LocalizedString} */
1649
1704
  "Working…"
1650
1705
  )
1651
- ), Fn = (
1706
+ ), Qn = (
1652
1707
  /** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
1653
1708
  () => (
1654
1709
  /** @type {LocalizedString} */
1655
1710
  "Bezig…"
1656
1711
  )
1657
- ), $n = (
1712
+ ), Kn = (
1658
1713
  /** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
1659
1714
  () => (
1660
1715
  /** @type {LocalizedString} */
1661
1716
  "Läuft…"
1662
1717
  )
1663
- ), Dn = (
1718
+ ), Xn = (
1664
1719
  /** @type {((inputs?: Commerce_Submit_BusyInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_BusyInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1665
1720
  ((n = {}, t = {}) => {
1666
- const e = t.locale ?? h();
1667
- return e === "en" ? Pn() : e === "nl" ? Fn() : $n();
1721
+ const e = t.locale ?? u();
1722
+ return e === "nl" ? Qn() : e === "de" ? Kn() : Yn();
1668
1723
  })
1669
- ), Bn = (
1724
+ ), Jn = (
1670
1725
  /** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
1671
1726
  () => (
1672
1727
  /** @type {LocalizedString} */
1673
1728
  "Done"
1674
1729
  )
1675
- ), Un = (
1730
+ ), ti = (
1676
1731
  /** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
1677
1732
  () => (
1678
1733
  /** @type {LocalizedString} */
1679
1734
  "Gelukt"
1680
1735
  )
1681
- ), Vn = (
1736
+ ), ei = (
1682
1737
  /** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
1683
1738
  () => (
1684
1739
  /** @type {LocalizedString} */
1685
1740
  "Fertig"
1686
1741
  )
1687
- ), jn = (
1742
+ ), ni = (
1688
1743
  /** @type {((inputs?: Commerce_Submit_SuccessInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_SuccessInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1689
1744
  ((n = {}, t = {}) => {
1690
- const e = t.locale ?? h();
1691
- return e === "en" ? Bn() : e === "nl" ? Un() : Vn();
1745
+ const e = t.locale ?? u();
1746
+ return e === "nl" ? ti() : e === "de" ? ei() : Jn();
1692
1747
  })
1693
- ), Hn = (
1748
+ ), ii = (
1694
1749
  /** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
1695
1750
  () => (
1696
1751
  /** @type {LocalizedString} */
1697
1752
  "Failed"
1698
1753
  )
1699
- ), qn = (
1754
+ ), oi = (
1700
1755
  /** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
1701
1756
  () => (
1702
1757
  /** @type {LocalizedString} */
1703
1758
  "Mislukt"
1704
1759
  )
1705
- ), Gn = (
1760
+ ), si = (
1706
1761
  /** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
1707
1762
  () => (
1708
1763
  /** @type {LocalizedString} */
1709
1764
  "Fehlgeschlagen"
1710
1765
  )
1711
- ), Zn = (
1766
+ ), ri = (
1712
1767
  /** @type {((inputs?: Commerce_Submit_FailedInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_FailedInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1713
1768
  ((n = {}, t = {}) => {
1714
- const e = t.locale ?? h();
1715
- return e === "en" ? Hn() : e === "nl" ? qn() : Gn();
1769
+ const e = t.locale ?? u();
1770
+ return e === "nl" ? oi() : e === "de" ? si() : ii();
1716
1771
  })
1717
1772
  );
1718
- const Wn = {
1773
+ const ai = {
1719
1774
  xmlns: "http://www.w3.org/2000/svg",
1720
1775
  width: 24,
1721
1776
  height: 24,
@@ -1726,22 +1781,22 @@ const Wn = {
1726
1781
  "stroke-linecap": "round",
1727
1782
  "stroke-linejoin": "round"
1728
1783
  };
1729
- const yt = ([n, t, e]) => {
1784
+ const Ct = ([n, t, e]) => {
1730
1785
  const i = document.createElementNS("http://www.w3.org/2000/svg", n);
1731
1786
  return Object.keys(t).forEach((o) => {
1732
1787
  i.setAttribute(o, String(t[o]));
1733
1788
  }), e?.length && e.forEach((o) => {
1734
- const s = yt(o);
1789
+ const s = Ct(o);
1735
1790
  i.appendChild(s);
1736
1791
  }), i;
1737
- }, wt = (n, t = {}) => {
1792
+ }, kt = (n, t = {}) => {
1738
1793
  const i = {
1739
- ...Wn,
1794
+ ...ai,
1740
1795
  ...t
1741
1796
  };
1742
- return yt(["svg", i, n]);
1797
+ return Ct(["svg", i, n]);
1743
1798
  };
1744
- const Qn = [
1799
+ const li = [
1745
1800
  [
1746
1801
  "path",
1747
1802
  {
@@ -1751,7 +1806,7 @@ const Qn = [
1751
1806
  ["path", { d: "m3.3 7 8.7 5 8.7-5" }],
1752
1807
  ["path", { d: "M12 22V12" }]
1753
1808
  ];
1754
- const Yn = [
1809
+ const ci = [
1755
1810
  [
1756
1811
  "path",
1757
1812
  {
@@ -1760,27 +1815,27 @@ const Yn = [
1760
1815
  ],
1761
1816
  ["circle", { cx: "12", cy: "13", r: "3" }]
1762
1817
  ];
1763
- const _t = [["path", { d: "m6 9 6 6 6-6" }]];
1764
- const Kn = [["path", { d: "m15 18-6-6 6-6" }]];
1765
- const Xn = [["path", { d: "m9 18 6-6-6-6" }]];
1766
- const Jn = [["path", { d: "m18 15-6-6-6 6" }]];
1767
- const ti = [
1818
+ const At = [["path", { d: "m6 9 6 6 6-6" }]];
1819
+ const di = [["path", { d: "m15 18-6-6 6-6" }]];
1820
+ const ui = [["path", { d: "m9 18 6-6-6-6" }]];
1821
+ const hi = [["path", { d: "m18 15-6-6-6 6" }]];
1822
+ const mi = [
1768
1823
  ["path", { d: "M15 3h6v6" }],
1769
1824
  ["path", { d: "m21 3-7 7" }],
1770
1825
  ["path", { d: "m3 21 7-7" }],
1771
1826
  ["path", { d: "M9 21H3v-6" }]
1772
1827
  ];
1773
- const ei = [
1828
+ const pi = [
1774
1829
  ["path", { d: "m14 10 7-7" }],
1775
1830
  ["path", { d: "M20 10h-6V4" }],
1776
1831
  ["path", { d: "m3 21 7-7" }],
1777
1832
  ["path", { d: "M4 14h6v6" }]
1778
1833
  ];
1779
- const ni = [
1834
+ const fi = [
1780
1835
  ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }],
1781
1836
  ["path", { d: "M3 3v5h5" }]
1782
1837
  ];
1783
- const ii = [
1838
+ const gi = [
1784
1839
  ["path", { d: "M10 5H3" }],
1785
1840
  ["path", { d: "M12 19H3" }],
1786
1841
  ["path", { d: "M14 3v4" }],
@@ -1791,38 +1846,38 @@ const ii = [
1791
1846
  ["path", { d: "M8 10v4" }],
1792
1847
  ["path", { d: "M8 12H3" }]
1793
1848
  ];
1794
- const oi = [
1849
+ const bi = [
1795
1850
  ["path", { d: "M18 6 6 18" }],
1796
1851
  ["path", { d: "m6 6 12 12" }]
1797
1852
  ];
1798
- const si = [
1853
+ const vi = [
1799
1854
  ["circle", { cx: "11", cy: "11", r: "8" }],
1800
1855
  ["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
1801
- ["line", { x1: "11", x2: "11", y1: "8", y2: "14" }],
1802
1856
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
1803
1857
  ];
1804
- const ri = [
1858
+ const yi = [
1805
1859
  ["circle", { cx: "11", cy: "11", r: "8" }],
1806
1860
  ["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
1861
+ ["line", { x1: "11", x2: "11", y1: "8", y2: "14" }],
1807
1862
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
1808
1863
  ];
1809
1864
  function y(n, { size: t = 20, strokeWidth: e = 1.75 } = {}) {
1810
- return wt(n, { width: t, height: t, "stroke-width": e });
1865
+ return kt(n, { width: t, height: t, "stroke-width": e });
1811
1866
  }
1812
1867
  const g = {
1813
- ar: (n) => y(Qn, n),
1814
- fullscreen: (n) => y(ti, n),
1815
- exitFullscreen: (n) => y(ei, n),
1816
- screenshot: (n) => y(Yn, n),
1817
- tiltUp: (n) => y(Jn, n),
1818
- tiltDown: (n) => y(_t, n),
1819
- rotateLeft: (n) => y(Kn, n),
1820
- rotateRight: (n) => y(Xn, n),
1821
- zoomIn: (n) => y(si, n),
1822
- zoomOut: (n) => y(ri, n),
1823
- reset: (n) => y(ni, n),
1824
- configurator: (n) => y(ii, n),
1825
- close: (n) => y(oi, n)
1868
+ ar: (n) => y(li, n),
1869
+ fullscreen: (n) => y(mi, n),
1870
+ exitFullscreen: (n) => y(pi, n),
1871
+ screenshot: (n) => y(ci, n),
1872
+ tiltUp: (n) => y(hi, n),
1873
+ tiltDown: (n) => y(At, n),
1874
+ rotateLeft: (n) => y(di, n),
1875
+ rotateRight: (n) => y(ui, n),
1876
+ zoomIn: (n) => y(yi, n),
1877
+ zoomOut: (n) => y(vi, n),
1878
+ reset: (n) => y(fi, n),
1879
+ configurator: (n) => y(gi, n),
1880
+ close: (n) => y(bi, n)
1826
1881
  };
1827
1882
  class b {
1828
1883
  element;
@@ -1834,7 +1889,7 @@ class b {
1834
1889
  e !== null ? e.replaceWith(t) : this.element.appendChild(t);
1835
1890
  }
1836
1891
  }
1837
- const m = {
1892
+ const p = {
1838
1893
  semantic: {
1839
1894
  // eslint-disable-next-line vd-custom/enforce-error-codes -- This is a hex color, not an error code
1840
1895
  error: "#dc2626"
@@ -1846,7 +1901,7 @@ const m = {
1846
1901
  },
1847
1902
  white: "#ffffff",
1848
1903
  black: "#000000"
1849
- }, a = {
1904
+ }, l = {
1850
1905
  0: "0",
1851
1906
  0.5: "0.125rem",
1852
1907
  // 2px
@@ -1868,22 +1923,22 @@ const m = {
1868
1923
  // 32px
1869
1924
  9: "2.25rem"
1870
1925
  };
1871
- class ai {
1926
+ class wi {
1872
1927
  element;
1873
1928
  constructor() {
1874
1929
  this.element = document.createElement("div"), Object.assign(this.element.style, {
1875
- background: m.white,
1876
- borderRadius: a[3],
1877
- padding: a[6],
1878
- boxShadow: `0 ${a[2]} ${a[8]} oklch(0% 0 0 / 20%)`,
1930
+ background: p.white,
1931
+ borderRadius: l[3],
1932
+ padding: l[6],
1933
+ boxShadow: `0 ${l[2]} ${l[8]} oklch(0% 0 0 / 20%)`,
1879
1934
  maxWidth: "20rem",
1880
1935
  width: "100%"
1881
1936
  });
1882
1937
  }
1883
1938
  }
1884
- class li {
1939
+ class Si {
1885
1940
  constructor(t = {}) {
1886
- this.options = t, this.card = new ai(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1941
+ this.options = t, this.card = new wi(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1887
1942
  }
1888
1943
  options;
1889
1944
  card;
@@ -1901,7 +1956,7 @@ class li {
1901
1956
  const t = document.createElement("div");
1902
1957
  return Object.assign(t.style, {
1903
1958
  position: "fixed",
1904
- inset: a[0],
1959
+ inset: l[0],
1905
1960
  background: "oklch(0% 0 0 / 50%)",
1906
1961
  zIndex: "9999",
1907
1962
  display: "flex",
@@ -1912,7 +1967,7 @@ class li {
1912
1967
  }), t;
1913
1968
  }
1914
1969
  }
1915
- class ci {
1970
+ class _i {
1916
1971
  element;
1917
1972
  selectCallback = null;
1918
1973
  constructor(t, e, i) {
@@ -1933,22 +1988,33 @@ class ci {
1933
1988
  onSelect(t) {
1934
1989
  this.selectCallback = t;
1935
1990
  }
1991
+ /**
1992
+ * Enable only the given values; null lifts every restriction. A disabled
1993
+ * value stays visible (the buyer sees the option exists) but cannot be
1994
+ * picked: the selectable snapshot's "not in the list = grey".
1995
+ */
1996
+ setEnabled(t) {
1997
+ for (const e of this.element.querySelectorAll(".ui-toggle-group-item")) {
1998
+ const i = t === null || t.includes(e.dataset.value ?? "");
1999
+ e.disabled = !i, e.setAttribute("aria-disabled", i ? "false" : "true");
2000
+ }
2001
+ }
1936
2002
  }
1937
- class ui {
2003
+ class Ci {
1938
2004
  element;
1939
2005
  select;
1940
2006
  constructor(t, e, i, o, s) {
1941
2007
  this.select = document.createElement("select"), this.select.className = "ui-native-select", this.select.dataset.name = t, this.select.setAttribute("aria-label", i);
1942
2008
  const r = document.createElement("option");
1943
2009
  r.value = "", r.disabled = !0, r.textContent = i, this.select.appendChild(r);
1944
- let l = !1;
1945
- for (let u = 0; u < e.length; u++) {
1946
- const p = e[u], v = document.createElement("option");
1947
- v.value = p, v.textContent = s?.[u] ?? p, p === o && (v.selected = !0, l = !0), this.select.appendChild(v);
2010
+ let a = !1;
2011
+ for (let d = 0; d < e.length; d++) {
2012
+ const m = e[d], v = document.createElement("option");
2013
+ v.value = m, v.textContent = s?.[d] ?? m, m === o && (v.selected = !0, a = !0), this.select.appendChild(v);
1948
2014
  }
1949
- l || (r.selected = !0);
1950
- const d = wt(_t, { width: 16, height: 16, "stroke-width": 2 });
1951
- d.classList.add("ui-native-select-icon"), this.element = document.createElement("div"), this.element.className = "ui-native-select-wrap", this.element.appendChild(this.select), this.element.appendChild(d);
2015
+ a || (r.selected = !0);
2016
+ const h = kt(At, { width: 16, height: 16, "stroke-width": 2 });
2017
+ h.classList.add("ui-native-select-icon"), this.element = document.createElement("div"), this.element.className = "ui-native-select-wrap", this.element.appendChild(this.select), this.element.appendChild(h);
1952
2018
  }
1953
2019
  setSelected(t) {
1954
2020
  this.select.value = t;
@@ -1958,6 +2024,11 @@ class ui {
1958
2024
  t(this.select.value);
1959
2025
  });
1960
2026
  }
2027
+ /** Enable only the given values; null lifts every restriction (see ToggleGroup.setEnabled). */
2028
+ setEnabled(t) {
2029
+ for (const e of this.select.options)
2030
+ e.value !== "" && (e.disabled = t !== null && !t.includes(e.value));
2031
+ }
1961
2032
  }
1962
2033
  const w = {
1963
2034
  fontFamily: {
@@ -1976,7 +2047,7 @@ const w = {
1976
2047
  medium: "500",
1977
2048
  semibold: "600"
1978
2049
  }
1979
- }, x = w.fontFamily.sans.join(", "), di = `
2050
+ }, x = w.fontFamily.sans.join(", "), ki = `
1980
2051
  --primary: oklch(5% 0 0);
1981
2052
  --primary-foreground: oklch(100% 0 0);
1982
2053
  --secondary: oklch(92% 0 0);
@@ -1989,8 +2060,8 @@ const w = {
1989
2060
  --accent: oklch(92% 0 0);
1990
2061
  --accent-foreground: oklch(5% 0 0);
1991
2062
  --muted-foreground: oklch(44% 0 0);
1992
- `, hi = `
1993
- :root { ${di} }
2063
+ `, Ai = `
2064
+ :root { ${ki} }
1994
2065
 
1995
2066
  /* ── Button ──────────────────────────────────────────────── */
1996
2067
  .ui-btn {
@@ -2066,6 +2137,8 @@ const w = {
2066
2137
  box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
2067
2138
  }
2068
2139
  .ui-toggle-group-item:hover { background: var(--accent); border-color: oklch(85% 0 0); }
2140
+ .ui-toggle-group-item:disabled { opacity: 0.4; cursor: not-allowed; }
2141
+ .ui-toggle-group-item:disabled:hover { background: var(--background); border-color: var(--border); }
2069
2142
  .ui-toggle-group-item:active { transform: scale(0.98); }
2070
2143
  .ui-toggle-group-item:focus-visible {
2071
2144
  outline: none;
@@ -2267,43 +2340,43 @@ const w = {
2267
2340
  50% { opacity: 0.55; }
2268
2341
  }
2269
2342
  `;
2270
- let it = !1;
2271
- function Ct() {
2272
- if (it || typeof document > "u")
2343
+ let lt = !1;
2344
+ function Et() {
2345
+ if (lt || typeof document > "u")
2273
2346
  return;
2274
- it = !0;
2347
+ lt = !0;
2275
2348
  const n = document.createElement("style");
2276
- n.id = "vd-ui-vanilla", n.textContent = hi, document.head.appendChild(n);
2349
+ n.id = "vd-ui-vanilla", n.textContent = Ai, document.head.appendChild(n);
2277
2350
  }
2278
- const mi = w.fontFamily.sans.join(", ");
2279
- class pi {
2351
+ const Ei = w.fontFamily.sans.join(", ");
2352
+ class xi {
2280
2353
  qrLib = null;
2281
2354
  dialog = null;
2282
2355
  qrSlot = null;
2283
2356
  /** Open the modal immediately, with a loading placeholder in the QR slot. */
2284
2357
  show() {
2285
- this.hide(), Ct(), this.dialog = new li({ onClose: () => {
2358
+ this.hide(), Et(), this.dialog = new Si({ onClose: () => {
2286
2359
  this.dialog = null, this.qrSlot = null;
2287
2360
  } }), Object.assign(this.dialog.card.element.style, {
2288
2361
  display: "flex",
2289
2362
  flexDirection: "column",
2290
2363
  alignItems: "center",
2291
- gap: a[3],
2292
- fontFamily: mi
2293
- }), this.dialog.card.element.appendChild(this.createText(Ae(), {
2364
+ gap: l[3],
2365
+ fontFamily: Ei
2366
+ }), this.dialog.card.element.appendChild(this.createText($e(), {
2294
2367
  fontSize: w.fontSize.base,
2295
2368
  fontWeight: w.fontWeight.semibold,
2296
- color: m.neutral[900]
2297
- })), this.dialog.card.element.appendChild(this.createText(Re(), {
2369
+ color: p.neutral[900]
2370
+ })), this.dialog.card.element.appendChild(this.createText(Ve(), {
2298
2371
  fontSize: w.fontSize.sm,
2299
- color: m.neutral[600]
2300
- })), this.qrSlot = this.createQrSlot(), this.dialog.card.element.appendChild(this.qrSlot), this.dialog.card.element.appendChild(this.createText(Me(), {
2372
+ color: p.neutral[600]
2373
+ })), this.qrSlot = this.createQrSlot(), this.dialog.card.element.appendChild(this.qrSlot), this.dialog.card.element.appendChild(this.createText(Ge(), {
2301
2374
  fontSize: w.fontSize.xs,
2302
- color: m.neutral[500]
2375
+ color: p.neutral[500]
2303
2376
  }));
2304
2377
  const t = new b({
2305
2378
  variant: "outline",
2306
- label: Fe(),
2379
+ label: Qe(),
2307
2380
  onClick: () => {
2308
2381
  this.hide();
2309
2382
  }
@@ -2321,7 +2394,7 @@ class pi {
2321
2394
  width: 256,
2322
2395
  margin: 4,
2323
2396
  errorCorrectionLevel: "M",
2324
- color: { dark: m.black, light: m.white }
2397
+ color: { dark: p.black, light: p.white }
2325
2398
  });
2326
2399
  return this.qrSlot === null ? !1 : (this.qrSlot.classList.remove("ui-qr-slot--loading"), this.qrSlot.replaceChildren(this.createQrImage(e)), !0);
2327
2400
  }
@@ -2341,40 +2414,40 @@ class pi {
2341
2414
  return e.src = t, e.alt = "QR code", e;
2342
2415
  }
2343
2416
  }
2344
- function ot(n) {
2417
+ function ct(n) {
2345
2418
  const t = Math.max(0, Math.min(1, n));
2346
2419
  return t * t * (3 - 2 * t);
2347
2420
  }
2348
- function fi(n, t, e, i, o, s) {
2349
- const [r, l, d] = n, u = Math.cos(t), p = Math.sin(t), v = u * r + p * d, E = -p * r + u * d, k = Math.cos(e), S = Math.sin(e), R = k * l - S * E, L = S * l + k * E, W = 0.55;
2350
- return [i + v * s * W, o - R * s * W, L];
2421
+ function Ti(n, t, e, i, o, s) {
2422
+ const [r, a, h] = n, d = Math.cos(t), m = Math.sin(t), v = d * r + m * h, E = -m * r + d * h, k = Math.cos(e), C = Math.sin(e), R = k * a - C * E, P = C * a + k * E, J = 0.55;
2423
+ return [i + v * s * J, o - R * s * J, P];
2351
2424
  }
2352
- function gi(n, t, e) {
2425
+ function Ri(n, t, e) {
2353
2426
  n.beginPath(), n.moveTo(t[0], t[1]), n.lineTo(e[0], e[1]), n.strokeStyle = "#000", n.lineWidth = 2, n.stroke();
2354
2427
  }
2355
- function bi(n, t, e, i, o) {
2356
- const s = t(e), r = t(i), l = [
2428
+ function Ii(n, t, e, i, o) {
2429
+ const s = t(e), r = t(i), a = [
2357
2430
  s[0] + (r[0] - s[0]) * o,
2358
2431
  s[1] + (r[1] - s[1]) * o,
2359
2432
  s[2]
2360
2433
  ];
2361
- gi(n, s, l);
2362
- }
2363
- const z = [-1, -1, 1], P = [1, -1, 1], F = [1, -1, -1], $ = [-1, -1, -1], D = [-1, 1, 1], B = [1, 1, 1], U = [1, 1, -1], V = [-1, 1, -1], st = [
2364
- [z, P],
2365
- [P, F],
2366
- [F, $],
2367
- [$, z],
2368
- [z, D],
2369
- [P, B],
2370
- [F, U],
2371
- [$, V],
2434
+ Ri(n, s, a);
2435
+ }
2436
+ const $ = [-1, -1, 1], D = [1, -1, 1], B = [1, -1, -1], U = [-1, -1, -1], V = [-1, 1, 1], j = [1, 1, 1], H = [1, 1, -1], q = [-1, 1, -1], dt = [
2437
+ [$, D],
2372
2438
  [D, B],
2373
2439
  [B, U],
2374
- [U, V],
2375
- [V, D]
2376
- ], vi = 400, rt = '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
2377
- function yi() {
2440
+ [U, $],
2441
+ [$, V],
2442
+ [D, j],
2443
+ [B, H],
2444
+ [U, q],
2445
+ [V, j],
2446
+ [j, H],
2447
+ [H, q],
2448
+ [q, V]
2449
+ ], Li = 400, ut = '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
2450
+ function Oi() {
2378
2451
  const n = document.createElement("div");
2379
2452
  Object.assign(n.style, {
2380
2453
  position: "absolute",
@@ -2410,16 +2483,16 @@ function yi() {
2410
2483
  fontWeight: "400",
2411
2484
  color: "#000",
2412
2485
  fontVariantNumeric: "tabular-nums",
2413
- fontFamily: rt
2486
+ fontFamily: ut
2414
2487
  });
2415
2488
  const o = document.createElement("span");
2416
2489
  return Object.assign(o.style, {
2417
2490
  fontSize: "13px",
2418
2491
  color: "#000",
2419
- fontFamily: rt
2420
- }), o.textContent = vt(), e.appendChild(i), e.appendChild(o), n.appendChild(t), n.appendChild(e), { overlay: n, canvas: t, pctEl: i, phaseEl: o };
2492
+ fontFamily: ut
2493
+ }), o.textContent = _t(), e.appendChild(i), e.appendChild(o), n.appendChild(t), n.appendChild(e), { overlay: n, canvas: t, pctEl: i, phaseEl: o };
2421
2494
  }
2422
- class wi {
2495
+ class Ni {
2423
2496
  overlay;
2424
2497
  canvas;
2425
2498
  ctx;
@@ -2432,17 +2505,17 @@ class wi {
2432
2505
  visible = !1;
2433
2506
  constructor(t, e = {}) {
2434
2507
  this.startTime = performance.now();
2435
- const i = yi();
2508
+ const i = Oi();
2436
2509
  this.overlay = i.overlay, this.canvas = i.canvas, this.pctEl = i.pctEl, this.phaseEl = i.phaseEl, t.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
2437
- const o = e.showDelay ?? vi;
2510
+ const o = e.showDelay ?? Li;
2438
2511
  this.showTimerId = setTimeout(() => {
2439
2512
  this.reveal();
2440
2513
  }, o);
2441
2514
  }
2442
2515
  get loadingTexts() {
2443
2516
  return {
2444
- downloading: vt(),
2445
- rendering: We()
2517
+ downloading: _t(),
2518
+ rendering: ln()
2446
2519
  };
2447
2520
  }
2448
2521
  updateProgress(t, e) {
@@ -2495,20 +2568,20 @@ class wi {
2495
2568
  return;
2496
2569
  const t = this.canvas.width / Math.min(devicePixelRatio, 2), e = this.canvas.height / Math.min(devicePixelRatio, 2), i = (performance.now() - this.startTime) / 1e3;
2497
2570
  this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, t, e);
2498
- const o = t / 2, s = e * 0.44, r = Math.min(t, e) * 0.08, l = 0.785, d = 0.615, u = (S) => fi(S, l, d, o, s, r), p = 6, v = i % p / p, E = st.length;
2571
+ const o = t / 2, s = e * 0.44, r = Math.min(t, e) * 0.08, a = 0.785, h = 0.615, d = (C) => Ti(C, a, h, o, s, r), m = 6, v = i % m / m, E = dt.length;
2499
2572
  let k;
2500
- v < 0.35 ? k = ot(v / 0.35) * E : v < 0.55 ? k = E : v < 0.9 ? k = (1 - ot((v - 0.55) / 0.35)) * E : k = 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
2501
- for (let S = 0; S < E && !(S >= k); S++) {
2502
- const R = st[S];
2573
+ v < 0.35 ? k = ct(v / 0.35) * E : v < 0.55 ? k = E : v < 0.9 ? k = (1 - ct((v - 0.55) / 0.35)) * E : k = 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
2574
+ for (let C = 0; C < E && !(C >= k); C++) {
2575
+ const R = dt[C];
2503
2576
  if (R === void 0)
2504
2577
  continue;
2505
- const L = Math.min(1, k - S);
2506
- bi(this.ctx, u, R[0], R[1], L);
2578
+ const P = Math.min(1, k - C);
2579
+ Ii(this.ctx, d, R[0], R[1], P);
2507
2580
  }
2508
2581
  this.ctx.shadowBlur = 0;
2509
2582
  }
2510
2583
  }
2511
- class _i {
2584
+ class Mi {
2512
2585
  constructor(t) {
2513
2586
  this.options = t, this.element = document.createElement("div"), Object.assign(this.element.style, { display: "flex", gap: "0.375rem" }), this.onFullscreenChange = () => {
2514
2587
  this.setFullscreenIcon(document.fullscreenElement !== null);
@@ -2533,7 +2606,7 @@ class _i {
2533
2606
  this.arBtn = this.syncButton(this.arBtn, t.ar !== !1 && this.options.onAr !== void 0, () => new b({
2534
2607
  variant: "outline",
2535
2608
  size: "icon",
2536
- label: _e(),
2609
+ label: Me(),
2537
2610
  icon: g.ar(),
2538
2611
  onClick: () => {
2539
2612
  this.options.onAr?.();
@@ -2541,7 +2614,7 @@ class _i {
2541
2614
  })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, t.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new b({
2542
2615
  variant: "outline",
2543
2616
  size: "icon",
2544
- label: Ue(),
2617
+ label: tn(),
2545
2618
  icon: g.fullscreen(),
2546
2619
  onClick: () => {
2547
2620
  this.options.onFullscreen?.();
@@ -2553,7 +2626,7 @@ class _i {
2553
2626
  }
2554
2627
  }
2555
2628
  const T = 0.5;
2556
- class M {
2629
+ class z {
2557
2630
  element;
2558
2631
  constructor(t, e) {
2559
2632
  this.element = Object.assign(document.createElement("div"), { className: "vd-camera-controls" });
@@ -2562,10 +2635,10 @@ class M {
2562
2635
  targetTilt: e.tilt,
2563
2636
  targetZoom: e.zoom,
2564
2637
  thetaOffset: 0
2565
- }, o = Ci(t, e, i);
2638
+ }, o = zi(t, e, i);
2566
2639
  e.onChange((s) => {
2567
- i.targetRotation = s.rotation - i.thetaOffset, i.targetTilt = s.tilt, i.targetZoom = s.zoom, Si(o, e, s);
2568
- }), this.element.appendChild(M.buildZoom(o.zoomOut, o.zoomIn)), this.element.appendChild(M.buildDpad(o.tiltUp, o.rotateLeft, o.reset, o.rotateRight, o.tiltDown));
2640
+ i.targetRotation = s.rotation - i.thetaOffset, i.targetTilt = s.tilt, i.targetZoom = s.zoom, Pi(o, e, s);
2641
+ }), this.element.appendChild(z.buildZoom(o.zoomOut, o.zoomIn)), this.element.appendChild(z.buildDpad(o.tiltUp, o.rotateLeft, o.reset, o.rotateRight, o.tiltDown));
2569
2642
  }
2570
2643
  static buildZoom(t, e) {
2571
2644
  const i = document.createElement("div");
@@ -2574,59 +2647,59 @@ class M {
2574
2647
  static buildDpad(t, e, i, o, s) {
2575
2648
  const r = document.createElement("div");
2576
2649
  r.className = "vd-dpad";
2577
- for (const [l, d] of [
2650
+ for (const [a, h] of [
2578
2651
  [t, "up"],
2579
2652
  [e, "left"],
2580
2653
  [i, "center"],
2581
2654
  [o, "right"],
2582
2655
  [s, "down"]
2583
2656
  ])
2584
- l.element.classList.add(`vd-dpad-${d}`), r.appendChild(l.element);
2657
+ a.element.classList.add(`vd-dpad-${h}`), r.appendChild(a.element);
2585
2658
  return r;
2586
2659
  }
2587
2660
  }
2588
- function Ci(n, t, e) {
2661
+ function zi(n, t, e) {
2589
2662
  const i = (r) => Math.max(t.limits?.minZoom ?? 1, Math.min(t.limits?.maxZoom ?? 1 / 0, r)), o = (r) => {
2590
- const l = t.limits?.minRotate, d = t.limits?.maxRotate;
2591
- return l !== void 0 || d !== void 0 ? Math.max(l ?? -1 / 0, Math.min(d ?? 1 / 0, r)) : r;
2663
+ const a = t.limits?.minRotate, h = t.limits?.maxRotate;
2664
+ return a !== void 0 || h !== void 0 ? Math.max(a ?? -1 / 0, Math.min(h ?? 1 / 0, r)) : r;
2592
2665
  }, s = (r) => {
2593
- const l = t.limits?.minTilt, d = t.limits?.maxTilt;
2594
- if (l !== void 0 || d !== void 0) {
2595
- e.targetTilt = Math.max(l ?? 0, Math.min(d ?? 180, e.targetTilt + r)), n.tilt(e.targetTilt).set();
2666
+ const a = t.limits?.minTilt, h = t.limits?.maxTilt;
2667
+ if (a !== void 0 || h !== void 0) {
2668
+ e.targetTilt = Math.max(a ?? 0, Math.min(h ?? 180, e.targetTilt + r)), n.tilt(e.targetTilt).set();
2596
2669
  return;
2597
2670
  }
2598
- const u = e.targetTilt + r;
2599
- u > 180 || u < 0 ? (e.targetTilt = u > 180 ? 360 - u : -u, e.thetaOffset = (e.thetaOffset + 180) % 360, n.tilt(e.targetTilt).rotate(e.targetRotation + e.thetaOffset).set()) : (e.targetTilt = u, n.tilt(e.targetTilt).set());
2671
+ const d = e.targetTilt + r;
2672
+ d > 180 || d < 0 ? (e.targetTilt = d > 180 ? 360 - d : -d, e.thetaOffset = (e.thetaOffset + 180) % 360, n.tilt(e.targetTilt).rotate(e.targetRotation + e.thetaOffset).set()) : (e.targetTilt = d, n.tilt(e.targetTilt).set());
2600
2673
  };
2601
2674
  return {
2602
- zoomOut: new b({ variant: "outline", size: "icon", label: yn(), icon: g.zoomOut(), onClick: () => {
2675
+ zoomOut: new b({ variant: "outline", size: "icon", label: On(), icon: g.zoomOut(), onClick: () => {
2603
2676
  e.targetZoom = i(e.targetZoom - 10), n.zoom(e.targetZoom).set();
2604
2677
  } }),
2605
- zoomIn: new b({ variant: "outline", size: "icon", label: fn(), icon: g.zoomIn(), onClick: () => {
2678
+ zoomIn: new b({ variant: "outline", size: "icon", label: Tn(), icon: g.zoomIn(), onClick: () => {
2606
2679
  e.targetZoom = i(e.targetZoom + 10), n.zoom(e.targetZoom).set();
2607
2680
  } }),
2608
- tiltUp: new b({ variant: "outline", size: "icon", label: On(), icon: g.tiltUp(), onClick: () => {
2681
+ tiltUp: new b({ variant: "outline", size: "icon", label: Hn(), icon: g.tiltUp(), onClick: () => {
2609
2682
  s(-15);
2610
2683
  } }),
2611
- rotateLeft: new b({ variant: "outline", size: "icon", label: Sn(), icon: g.rotateLeft(), onClick: () => {
2684
+ rotateLeft: new b({ variant: "outline", size: "icon", label: Pn(), icon: g.rotateLeft(), onClick: () => {
2612
2685
  e.targetRotation = o(e.targetRotation - 15), n.rotate(e.targetRotation + e.thetaOffset).set();
2613
2686
  } }),
2614
- reset: new b({ variant: "outline", size: "icon", label: dn(), icon: g.reset(), onClick: () => {
2687
+ reset: new b({ variant: "outline", size: "icon", label: kn(), icon: g.reset(), onClick: () => {
2615
2688
  e.thetaOffset = 0, n.reset();
2616
2689
  } }),
2617
- rotateRight: new b({ variant: "outline", size: "icon", label: xn(), icon: g.rotateRight(), onClick: () => {
2690
+ rotateRight: new b({ variant: "outline", size: "icon", label: Bn(), icon: g.rotateRight(), onClick: () => {
2618
2691
  e.targetRotation = o(e.targetRotation + 15), n.rotate(e.targetRotation + e.thetaOffset).set();
2619
2692
  } }),
2620
- tiltDown: new b({ variant: "outline", size: "icon", label: zn(), icon: g.tiltDown(), onClick: () => {
2693
+ tiltDown: new b({ variant: "outline", size: "icon", label: Wn(), icon: g.tiltDown(), onClick: () => {
2621
2694
  s(15);
2622
2695
  } })
2623
2696
  };
2624
2697
  }
2625
- function Si(n, t, e) {
2698
+ function Pi(n, t, e) {
2626
2699
  const i = t.limits;
2627
2700
  i !== void 0 && (n.zoomOut.element.disabled = i.minZoom !== void 0 && e.zoom <= i.minZoom + T, n.zoomIn.element.disabled = i.maxZoom !== void 0 && e.zoom >= i.maxZoom - T, n.tiltUp.element.disabled = i.minTilt !== void 0 && e.tilt <= i.minTilt + T, n.tiltDown.element.disabled = i.maxTilt !== void 0 && e.tilt >= i.maxTilt - T, n.rotateLeft.element.disabled = i.minRotate !== void 0 && e.rotation <= i.minRotate + T, n.rotateRight.element.disabled = i.maxRotate !== void 0 && e.rotation >= i.maxRotate - T);
2628
2701
  }
2629
- const I = {
2702
+ const L = {
2630
2703
  /** Attribute selection requested (cancelable). `detail`: `{ attribute, value }`. */
2631
2704
  SELECT: "ui:select",
2632
2705
  /** Attribute selection applied. `detail`: `{ attribute, value }`. */
@@ -2637,27 +2710,29 @@ const I = {
2637
2710
  CONFIGURATION_CHANGE: "vd:configuration-change",
2638
2711
  /** Configuration submitted (bubbles). `detail`: the resolved configuration handed to the host. */
2639
2712
  CONFIGURATION_SUBMIT: "vd:configuration-submit"
2640
- }, ki = 5;
2641
- let Ai = 0;
2642
- function j(n) {
2713
+ }, Fi = 5;
2714
+ let $i = 0;
2715
+ function G(n) {
2643
2716
  const t = n.replace(/([A-Z])/g, " $1").trim();
2644
2717
  return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
2645
2718
  }
2646
- function Ei(n, t, e, i, o) {
2719
+ function Di(n, t, e, i, o) {
2647
2720
  const s = document.createElement("div");
2648
2721
  s.className = "vd-attribute", s.dataset.name = n.name;
2649
2722
  const r = document.createElement("span");
2650
- r.className = "vd-attribute-label", r.textContent = j(n.name), r.id = `vd-attribute-label-${Ai++}`, s.appendChild(r), s.setAttribute("role", "group"), s.setAttribute("aria-labelledby", r.id);
2651
- const l = n.values.find((p) => t.getValue(n.name, p)?.isSelected === !0), d = n.values.map(j), u = n.values.length <= ki ? new ci(n.values, l, d) : new ui(n.name, n.values, j(n.name), l, d);
2652
- return u.onSelect((p) => {
2653
- e.dispatch(I.SELECT, { attribute: n.name, value: p }, !0).defaultPrevented || i(n.name, p);
2654
- }), o(n.name, (p) => {
2655
- u.setSelected(p.value), e.dispatch(I.SELECTED, { attribute: n.name, value: p.value });
2656
- }), s.appendChild(u.element), s;
2657
- }
2658
- const xi = 80, Ti = 2500;
2659
- class Ri {
2660
- constructor(t, e = Ti) {
2723
+ r.className = "vd-attribute-label", r.textContent = G(n.name), r.id = `vd-attribute-label-${$i++}`, s.appendChild(r), s.setAttribute("role", "group"), s.setAttribute("aria-labelledby", r.id);
2724
+ const a = n.values.find((m) => t.getValue(n.name, m)?.isSelected === !0), h = n.values.map(G), d = n.values.length <= Fi ? new _i(n.values, a, h) : new Ci(n.name, n.values, G(n.name), a, h);
2725
+ return d.onSelect((m) => {
2726
+ e.dispatch(L.SELECT, { attribute: n.name, value: m }, !0).defaultPrevented || i(n.name, m);
2727
+ }), o(n.name, (m) => {
2728
+ d.setSelected(m.value), e.dispatch(L.SELECTED, { attribute: n.name, value: m.value });
2729
+ }), s.appendChild(d.element), { element: s, setSelectable: (m) => {
2730
+ d.setEnabled(m);
2731
+ } };
2732
+ }
2733
+ const Bi = 80, Ui = 2500;
2734
+ class Vi {
2735
+ constructor(t, e = Ui) {
2661
2736
  this.configuration = t, this.resetMs = e, this.element = document.createElement("div"), this.element.className = "vd-commerce vd-hidden";
2662
2737
  const i = document.createElement("div");
2663
2738
  i.className = "vd-commerce-price", this.priceEl = document.createElement("span"), this.priceEl.className = "vd-price", this.vatEl = document.createElement("span"), this.vatEl.className = "vd-vat", i.append(this.priceEl, this.vatEl), this.button = new b({ variant: "default", onClick: () => {
@@ -2689,19 +2764,19 @@ class Ri {
2689
2764
  this.priceEl.textContent = "", this.vatEl.textContent = "";
2690
2765
  return;
2691
2766
  }
2692
- this.priceEl.textContent = Ii(t.price, t.currency), this.vatEl.textContent = at(this.configuration.vatDisplay);
2767
+ this.priceEl.textContent = ji(t.price, t.currency), this.vatEl.textContent = ht(this.configuration.vatDisplay);
2693
2768
  }
2694
2769
  renderButton() {
2695
2770
  const t = this.configuration.submitEnabled;
2696
- this.button.element.classList.toggle("vd-hidden", !t), t && this.state === "idle" && this.setButtonText(at(this.configuration.buttonLabel));
2771
+ this.button.element.classList.toggle("vd-hidden", !t), t && this.state === "idle" && this.setButtonText(ht(this.configuration.buttonLabel));
2697
2772
  }
2698
2773
  async handleSubmit() {
2699
2774
  if (this.state !== "busy") {
2700
- this.setState("busy", Dn());
2775
+ this.setState("busy", Xn());
2701
2776
  try {
2702
- await this.configuration.submit(), this.setState("success", jn());
2777
+ await this.configuration.submit(), this.setState("success", ni());
2703
2778
  } catch {
2704
- this.setState("failed", Zn());
2779
+ this.setState("failed", ri());
2705
2780
  }
2706
2781
  this.scheduleReset();
2707
2782
  }
@@ -2718,18 +2793,18 @@ class Ri {
2718
2793
  this.button.element.textContent = t, this.button.element.setAttribute("aria-label", t);
2719
2794
  }
2720
2795
  }
2721
- function at(n) {
2722
- return (n ?? "").slice(0, xi);
2796
+ function ht(n) {
2797
+ return (n ?? "").slice(0, Bi);
2723
2798
  }
2724
- function Ii(n, t) {
2799
+ function ji(n, t) {
2725
2800
  try {
2726
- const e = new Intl.NumberFormat(h(), { style: "currency", currency: t }), i = e.resolvedOptions().maximumFractionDigits ?? 2;
2801
+ const e = new Intl.NumberFormat(u(), { style: "currency", currency: t }), i = e.resolvedOptions().maximumFractionDigits ?? 2;
2727
2802
  return e.format(n / 10 ** i);
2728
2803
  } catch {
2729
2804
  return `${t} ${(n / 100).toFixed(2)}`;
2730
2805
  }
2731
2806
  }
2732
- class St {
2807
+ class xt {
2733
2808
  slot = null;
2734
2809
  panel = null;
2735
2810
  attach(t, e) {
@@ -2742,8 +2817,8 @@ class St {
2742
2817
  this.slot?.remove(), this.slot = null, this.panel = null;
2743
2818
  }
2744
2819
  }
2745
- const Oi = 572;
2746
- class Ni {
2820
+ const Hi = 572;
2821
+ class qi {
2747
2822
  /** @param actionBarSlot The shared corner slot the AR/fullscreen buttons live in — the
2748
2823
  * "open configurator" toggle joins them there instead of floating as its own overlay. */
2749
2824
  constructor(t) {
@@ -2763,7 +2838,7 @@ class Ni {
2763
2838
  this.container = t, e.classList.add("vd-attributes-sidebar"), this.closeButton = new b({
2764
2839
  variant: "ghost",
2765
2840
  size: "icon-sm",
2766
- label: an(),
2841
+ label: wn(),
2767
2842
  icon: g.close({ size: 18 }),
2768
2843
  onClick: () => {
2769
2844
  this.expanded = !1, this.render();
@@ -2773,7 +2848,7 @@ class Ni {
2773
2848
  i.className = "vd-sidebar-header", i.appendChild(this.closeButton.element), this.body = document.createElement("div"), this.body.className = "vd-sidebar-body", this.body.appendChild(e), this.element = document.createElement("div"), this.element.className = "vd-sidebar vd-hidden", this.element.append(i, this.body), t.appendChild(this.element), this.openButton = new b({
2774
2849
  variant: "outline",
2775
2850
  size: "icon",
2776
- label: nn(),
2851
+ label: gn(),
2777
2852
  icon: g.configurator({ size: 18 }),
2778
2853
  onClick: () => {
2779
2854
  this.expanded = !0, this.render();
@@ -2789,7 +2864,7 @@ class Ni {
2789
2864
  observe() {
2790
2865
  typeof ResizeObserver > "u" || this.container === null || (this.observer = new ResizeObserver((t) => {
2791
2866
  const e = t[0]?.contentRect.width ?? 0;
2792
- this.setCollapsible(e > 0 && e < Oi);
2867
+ this.setCollapsible(e > 0 && e < Hi);
2793
2868
  }), this.observer.observe(this.container));
2794
2869
  }
2795
2870
  setCollapsible(t) {
@@ -2802,7 +2877,7 @@ class Ni {
2802
2877
  this.element.classList.toggle("vd-hidden", !this.visible), this.element.classList.toggle("vd-sidebar-collapsed", e), this.openButton.element.classList.toggle("vd-hidden", !e), this.closeButton.element.style.display = this.collapsible ? "" : "none", this.container.classList.toggle("vd-layout-sidebar-right", t), this.container.classList.toggle("vd-layout-sidebar-permanent", t && !this.collapsible);
2803
2878
  }
2804
2879
  }
2805
- class Mi {
2880
+ class Gi {
2806
2881
  attach(t, e) {
2807
2882
  }
2808
2883
  setVisible(t) {
@@ -2810,20 +2885,20 @@ class Mi {
2810
2885
  destroy() {
2811
2886
  }
2812
2887
  }
2813
- const Li = {
2814
- "inframe-bottom-left": () => new St(),
2815
- "sidebar-right": (n) => new Ni(n),
2816
- hidden: () => new Mi()
2888
+ const Zi = {
2889
+ "inframe-bottom-left": () => new xt(),
2890
+ "sidebar-right": (n) => new qi(n),
2891
+ hidden: () => new Gi()
2817
2892
  };
2818
- function zi(n, t) {
2819
- return (Li[n ?? ""] ?? (() => new St()))(t);
2893
+ function Wi(n, t) {
2894
+ return (Zi[n ?? ""] ?? (() => new xt()))(t);
2820
2895
  }
2821
- const H = w.fontFamily.sans.join(", "), q = `
2896
+ const Z = w.fontFamily.sans.join(", "), W = `
2822
2897
  position: absolute;
2823
2898
  display: flex;
2824
2899
  z-index: 10;
2825
2900
  transition: inset-inline-end 0.18s ease;
2826
- `, Pi = `
2901
+ `, Yi = `
2827
2902
  /* Override browser's default black fullscreen backdrop */
2828
2903
  .vd-container:fullscreen {
2829
2904
  background: oklch(100% 0 0);
@@ -2831,52 +2906,52 @@ const H = w.fontFamily.sans.join(", "), q = `
2831
2906
 
2832
2907
  /* Layout slots — four corners */
2833
2908
  .vd-slot-top-right {
2834
- ${q}
2835
- inset-block-start: ${a[3]};
2836
- inset-inline-end: ${a[3]};
2909
+ ${W}
2910
+ inset-block-start: ${l[3]};
2911
+ inset-inline-end: ${l[3]};
2837
2912
  flex-direction: column;
2838
2913
  align-items: flex-end;
2839
- gap: ${a[1.5]};
2914
+ gap: ${l[1.5]};
2840
2915
  }
2841
2916
 
2842
2917
  .vd-slot-bottom-left {
2843
- ${q}
2844
- inset-block-end: ${a[3]};
2845
- inset-inline-start: ${a[3]};
2918
+ ${W}
2919
+ inset-block-end: ${l[3]};
2920
+ inset-inline-start: ${l[3]};
2846
2921
  flex-direction: column;
2847
2922
  align-items: flex-start;
2848
- gap: ${a[1.5]};
2923
+ gap: ${l[1.5]};
2849
2924
  }
2850
2925
 
2851
2926
  .vd-slot-bottom-right {
2852
- ${q}
2853
- inset-block-end: ${a[3]};
2854
- inset-inline-end: ${a[3]};
2927
+ ${W}
2928
+ inset-block-end: ${l[3]};
2929
+ inset-inline-end: ${l[3]};
2855
2930
  flex-direction: row;
2856
- gap: ${a[1.5]};
2931
+ gap: ${l[1.5]};
2857
2932
  }
2858
2933
 
2859
2934
  /* Component styles — no positioning */
2860
2935
  .vd-camera-controls {
2861
2936
  display: flex;
2862
2937
  flex-direction: column;
2863
- gap: ${a[1]};
2864
- background: color-mix(in oklch, ${m.white} 85%, transparent);
2938
+ gap: ${l[1]};
2939
+ background: color-mix(in oklch, ${p.white} 85%, transparent);
2865
2940
  backdrop-filter: blur(8px);
2866
- border-radius: ${a[2]};
2867
- padding: ${a[2]};
2941
+ border-radius: ${l[2]};
2942
+ padding: ${l[2]};
2868
2943
  }
2869
2944
 
2870
2945
  .vd-zoom {
2871
2946
  display: flex;
2872
- gap: ${a[0.5]};
2947
+ gap: ${l[0.5]};
2873
2948
  }
2874
2949
 
2875
2950
  .vd-dpad {
2876
2951
  display: grid;
2877
- grid-template-columns: repeat(3, ${a[9]});
2878
- grid-template-rows: repeat(3, ${a[9]});
2879
- gap: ${a[0.5]};
2952
+ grid-template-columns: repeat(3, ${l[9]});
2953
+ grid-template-rows: repeat(3, ${l[9]});
2954
+ gap: ${l[0.5]};
2880
2955
  }
2881
2956
 
2882
2957
  .vd-dpad-up { grid-column: 2; grid-row: 1; }
@@ -2888,30 +2963,30 @@ const H = w.fontFamily.sans.join(", "), q = `
2888
2963
  .vd-attributes {
2889
2964
  display: flex;
2890
2965
  flex-direction: column;
2891
- gap: ${a[3]};
2892
- background: color-mix(in oklch, ${m.white} 85%, transparent);
2966
+ gap: ${l[3]};
2967
+ background: color-mix(in oklch, ${p.white} 85%, transparent);
2893
2968
  backdrop-filter: blur(8px);
2894
- border: 1px solid color-mix(in oklch, ${m.neutral[900]} 8%, transparent);
2895
- border-radius: ${a[3]};
2896
- padding: ${a[3]};
2897
- box-shadow: 0 ${a[1]} ${a[4]} color-mix(in oklch, ${m.neutral[900]} 6%, transparent);
2898
- font-family: ${H};
2969
+ border: 1px solid color-mix(in oklch, ${p.neutral[900]} 8%, transparent);
2970
+ border-radius: ${l[3]};
2971
+ padding: ${l[3]};
2972
+ box-shadow: 0 ${l[1]} ${l[4]} color-mix(in oklch, ${p.neutral[900]} 6%, transparent);
2973
+ font-family: ${Z};
2899
2974
  }
2900
2975
 
2901
2976
  .vd-attribute {
2902
2977
  display: flex;
2903
2978
  flex-direction: column;
2904
- gap: ${a[1.5]};
2979
+ gap: ${l[1.5]};
2905
2980
  }
2906
2981
 
2907
2982
  /* Micro-label: recedes so the controls lead. */
2908
2983
  .vd-attribute-label {
2909
2984
  font-size: ${w.fontSize.xs};
2910
2985
  font-weight: ${w.fontWeight.medium};
2911
- color: ${m.neutral[500]};
2986
+ color: ${p.neutral[500]};
2912
2987
  text-transform: uppercase;
2913
2988
  letter-spacing: 0.05em;
2914
- font-family: ${H};
2989
+ font-family: ${Z};
2915
2990
  }
2916
2991
 
2917
2992
  /* sidebar-right layout — a docked, full-height right panel */
@@ -2947,10 +3022,10 @@ const H = w.fontFamily.sans.join(", "), q = `
2947
3022
  z-index: 11;
2948
3023
  display: flex;
2949
3024
  flex-direction: column;
2950
- background: color-mix(in oklch, ${m.white} 90%, transparent);
3025
+ background: color-mix(in oklch, ${p.white} 90%, transparent);
2951
3026
  backdrop-filter: blur(10px);
2952
- border-inline-start: 1px solid color-mix(in oklch, ${m.neutral[900]} 8%, transparent);
2953
- box-shadow: -${a[1]} 0 ${a[4]} color-mix(in oklch, ${m.neutral[900]} 5%, transparent);
3027
+ border-inline-start: 1px solid color-mix(in oklch, ${p.neutral[900]} 8%, transparent);
3028
+ box-shadow: -${l[1]} 0 ${l[4]} color-mix(in oklch, ${p.neutral[900]} 5%, transparent);
2954
3029
  }
2955
3030
 
2956
3031
  @media (prefers-reduced-motion: no-preference) {
@@ -2962,13 +3037,13 @@ const H = w.fontFamily.sans.join(", "), q = `
2962
3037
  .vd-sidebar-header {
2963
3038
  display: flex;
2964
3039
  justify-content: flex-end;
2965
- padding: ${a[1.5]} ${a[1.5]} 0;
3040
+ padding: ${l[1.5]} ${l[1.5]} 0;
2966
3041
  }
2967
3042
 
2968
3043
  .vd-sidebar-body {
2969
3044
  flex: 1;
2970
3045
  overflow-y: auto;
2971
- padding: ${a[4]};
3046
+ padding: ${l[4]};
2972
3047
  }
2973
3048
 
2974
3049
  /* attributes inside the sidebar: flat and full-width — the panel provides the frosting */
@@ -2979,38 +3054,38 @@ const H = w.fontFamily.sans.join(", "), q = `
2979
3054
  border-radius: 0;
2980
3055
  padding: 0;
2981
3056
  box-shadow: none;
2982
- gap: ${a[5]};
3057
+ gap: ${l[5]};
2983
3058
  }
2984
3059
 
2985
3060
  /* while the panel is open, keep the corner controls clear of it */
2986
- .vd-layout-sidebar-right .vd-slot-top-right { inset-inline-end: calc(var(--vd-sidebar-width) + ${a[3]}); }
2987
- .vd-layout-sidebar-right .vd-slot-bottom-right { inset-inline-end: calc(var(--vd-sidebar-width) + ${a[3]}); }
3061
+ .vd-layout-sidebar-right .vd-slot-top-right { inset-inline-end: calc(var(--vd-sidebar-width) + ${l[3]}); }
3062
+ .vd-layout-sidebar-right .vd-slot-bottom-right { inset-inline-end: calc(var(--vd-sidebar-width) + ${l[3]}); }
2988
3063
 
2989
3064
  /* Price + CTA — sit under the attribute controls, separated by a hairline */
2990
3065
  .vd-commerce {
2991
3066
  display: flex;
2992
3067
  flex-direction: column;
2993
- gap: ${a[2]};
2994
- padding-block-start: ${a[3]};
2995
- border-block-start: 1px solid color-mix(in oklch, ${m.neutral[900]} 8%, transparent);
2996
- font-family: ${H};
3068
+ gap: ${l[2]};
3069
+ padding-block-start: ${l[3]};
3070
+ border-block-start: 1px solid color-mix(in oklch, ${p.neutral[900]} 8%, transparent);
3071
+ font-family: ${Z};
2997
3072
  }
2998
3073
 
2999
3074
  .vd-commerce-price {
3000
3075
  display: flex;
3001
3076
  align-items: baseline;
3002
- gap: ${a[1.5]};
3077
+ gap: ${l[1.5]};
3003
3078
  }
3004
3079
 
3005
3080
  .vd-price {
3006
3081
  font-size: ${w.fontSize.lg};
3007
3082
  font-weight: ${w.fontWeight.semibold};
3008
- color: ${m.neutral[900]};
3083
+ color: ${p.neutral[900]};
3009
3084
  }
3010
3085
 
3011
3086
  .vd-vat {
3012
3087
  font-size: ${w.fontSize.xs};
3013
- color: ${m.neutral[500]};
3088
+ color: ${p.neutral[500]};
3014
3089
  }
3015
3090
 
3016
3091
  .vd-cta {
@@ -3020,23 +3095,23 @@ const H = w.fontFamily.sans.join(", "), q = `
3020
3095
 
3021
3096
  /* Failed submit is the one place red belongs: a clear, recoverable error state. */
3022
3097
  .vd-commerce[data-submit="failed"] .vd-cta {
3023
- background: ${m.semantic.error};
3024
- border-color: ${m.semantic.error};
3025
- color: ${m.white};
3098
+ background: ${p.semantic.error};
3099
+ border-color: ${p.semantic.error};
3100
+ color: ${p.white};
3026
3101
  }
3027
3102
 
3028
3103
  `;
3029
- function Fi() {
3030
- if (Ct(), document.getElementById("vd-styles") !== null)
3104
+ function Qi() {
3105
+ if (Et(), document.getElementById("vd-styles") !== null)
3031
3106
  return;
3032
3107
  const n = document.createElement("style");
3033
- n.id = "vd-styles", n.textContent = Pi, document.head.appendChild(n);
3108
+ n.id = "vd-styles", n.textContent = Yi, document.head.appendChild(n);
3034
3109
  }
3035
- function $i(n, t) {
3110
+ function Ki(n, t) {
3036
3111
  const e = document.createElement("a");
3037
3112
  e.href = `data:image/png;base64,${n}`, e.download = t, e.click();
3038
3113
  }
3039
- class Di {
3114
+ class Xi {
3040
3115
  options;
3041
3116
  settings = {};
3042
3117
  container = null;
@@ -3046,13 +3121,17 @@ class Di {
3046
3121
  actionBar = null;
3047
3122
  cameraControls = null;
3048
3123
  attributes = null;
3124
+ /** Rendered attribute groups by name, so a selectable snapshot can reach their controls. */
3125
+ groupHandles = /* @__PURE__ */ new Map();
3126
+ /** The latest selectable snapshot, re-applied when the controls re-render. */
3127
+ lastSelectable = null;
3049
3128
  layout = null;
3050
3129
  commerce = null;
3051
3130
  constructor(t) {
3052
3131
  this.options = t;
3053
3132
  }
3054
3133
  attach(t) {
3055
- Fi(), this.container = t, this.loading = new wi(t), this.slots.topRight = this.createSlot(t, "vd-slot-top-right"), this.slots.bottomRight = this.createSlot(t, "vd-slot-bottom-right");
3134
+ Qi(), this.container = t, this.loading = new Ni(t), this.slots.topRight = this.createSlot(t, "vd-slot-top-right"), this.slots.bottomRight = this.createSlot(t, "vd-slot-bottom-right");
3056
3135
  }
3057
3136
  onReady() {
3058
3137
  this.loading?.hide(), this.loading = null, this.mountToolbar(), this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.layout?.setVisible(!0);
@@ -3061,7 +3140,7 @@ class Di {
3061
3140
  if (this.actionBar !== null || this.slots.bottomRight === null || this.container === null)
3062
3141
  return;
3063
3142
  const t = typeof this.container.requestFullscreen == "function";
3064
- this.actionBar = new _i({
3143
+ this.actionBar = new Mi({
3065
3144
  onAr: this.options.onAr,
3066
3145
  onFullscreen: t ? () => {
3067
3146
  this.toggleFullscreen();
@@ -3078,20 +3157,35 @@ class Di {
3078
3157
  this.loading?.showError(t);
3079
3158
  }
3080
3159
  applyViewerSettings(t) {
3081
- this.settings = t, t.language !== void 0 && ft(t.language, { reload: !1 }), this.syncScreenshotButton(), this.actionBar?.applySettings(t), this.cameraControls !== null && (this.cameraControls.element.style.display = t.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
3160
+ this.settings = t, t.language !== void 0 && yt(t.language, { reload: !1 }), this.syncScreenshotButton(), this.actionBar?.applySettings(t), this.cameraControls !== null && (this.cameraControls.element.style.display = t.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
3082
3161
  }
3083
3162
  renderAttributeControls(t, e) {
3084
- if (!(this.container === null || this.slots.topRight === null || this.slots.bottomRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.teardownConfigurator(), this.settings.cameraControls === !0 && (this.cameraControls = new M(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), e.length !== 0)) {
3085
- this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes";
3086
- for (const i of e)
3087
- this.attributes.appendChild(Ei(
3163
+ if (!(this.container === null || this.slots.topRight === null || this.slots.bottomRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.teardownConfigurator(), this.settings.cameraControls === !0 && (this.cameraControls = new z(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), e.length !== 0)) {
3164
+ this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes", this.groupHandles = /* @__PURE__ */ new Map();
3165
+ for (const i of e) {
3166
+ const o = Di(
3088
3167
  i,
3089
3168
  t,
3090
3169
  this.options.eventBus,
3091
3170
  this.options.onSelect,
3092
3171
  this.options.onSubscribe
3093
- ));
3094
- this.commerce = new Ri(this.options.configuration), this.attributes.appendChild(this.commerce.element), this.layout = zi(this.settings.configuratorLayout, this.slots.bottomRight), this.layout.attach(this.container, this.attributes);
3172
+ );
3173
+ this.groupHandles.set(i.name, o), this.attributes.appendChild(o.element);
3174
+ }
3175
+ this.commerce = new Vi(this.options.configuration), this.attributes.appendChild(this.commerce.element), this.layout = Wi(this.settings.configuratorLayout, this.slots.bottomRight), this.layout.attach(this.container, this.attributes), this.lastSelectable !== null && this.applySelectable(this.lastSelectable);
3176
+ }
3177
+ }
3178
+ /**
3179
+ * Grey out what the viewer reports as not pickable: per attribute in the
3180
+ * snapshot only the listed values stay enabled; attributes the snapshot
3181
+ * does not name are unrestricted. The interface renders, it never knows
3182
+ * the exclusion rules (kiesbaarheid live, binding-studio task 17).
3183
+ */
3184
+ applySelectable(t) {
3185
+ this.lastSelectable = t;
3186
+ for (const [e, i] of this.groupHandles) {
3187
+ const o = t.find((s) => s.name === e);
3188
+ i.setSelectable(o?.selectable ?? null);
3095
3189
  }
3096
3190
  }
3097
3191
  get viewerSettings() {
@@ -3099,7 +3193,7 @@ class Di {
3099
3193
  }
3100
3194
  /** Tear down the configurator panel: price + CTA, attribute controls, layout. */
3101
3195
  teardownConfigurator() {
3102
- this.commerce?.destroy(), this.commerce = null, this.attributes?.remove(), this.attributes = null, this.layout?.destroy(), this.layout = null;
3196
+ this.commerce?.destroy(), this.commerce = null, this.attributes?.remove(), this.attributes = null, this.groupHandles = /* @__PURE__ */ new Map(), this.layout?.destroy(), this.layout = null;
3103
3197
  }
3104
3198
  destroy() {
3105
3199
  this.loading?.destroy(), this.screenshotBtn?.element.remove(), this.actionBar?.destroy(), this.actionBar?.element.remove(), this.cameraControls?.element.remove(), this.teardownConfigurator();
@@ -3116,11 +3210,11 @@ class Di {
3116
3210
  t && this.screenshotBtn === null && (this.screenshotBtn = new b({
3117
3211
  variant: "outline",
3118
3212
  size: "icon",
3119
- label: Xe(),
3213
+ label: hn(),
3120
3214
  icon: g.screenshot(),
3121
3215
  onClick: () => {
3122
3216
  this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: i }) => {
3123
- $i(e, i);
3217
+ Ki(e, i);
3124
3218
  });
3125
3219
  }
3126
3220
  })), !t && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
@@ -3129,13 +3223,14 @@ class Di {
3129
3223
  this.screenshotBtn === null || this.slots.topRight === null || (this.cameraControls !== null ? this.cameraControls.element.appendChild(this.screenshotBtn.element) : this.slots.topRight.appendChild(this.screenshotBtn.element));
3130
3224
  }
3131
3225
  }
3132
- const Bi = {};
3133
- class Ui {
3226
+ const Ji = {};
3227
+ class to {
3134
3228
  defaultServer = "https://server.virtualdisplay.io";
3135
3229
  options;
3136
3230
  serverHost;
3137
- constructor(t, e) {
3138
- this.options = t, this.serverHost = e;
3231
+ extraParams;
3232
+ constructor(t, e, i) {
3233
+ this.options = t, this.serverHost = e, this.extraParams = i;
3139
3234
  }
3140
3235
  /**
3141
3236
  * Create container and iframe, attach to parent element
@@ -3162,12 +3257,15 @@ class Ui {
3162
3257
  }
3163
3258
  buildUrl() {
3164
3259
  const t = this.getServerUrl(), e = new URL(t);
3165
- return e.searchParams.set("license", this.options.license), e.searchParams.set("model", this.options.model), this.options.language !== void 0 && e.searchParams.set("language", this.options.language), this.options.session !== void 0 && e.searchParams.set("session", this.options.session), this.options.debug === !0 && e.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && e.searchParams.set("traceparent", this.options.traceparent), e.toString();
3260
+ e.searchParams.set("license", this.options.license), e.searchParams.set("model", this.options.model), this.options.language !== void 0 && e.searchParams.set("language", this.options.language), this.options.session !== void 0 && e.searchParams.set("session", this.options.session), this.options.debug === !0 && e.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && e.searchParams.set("traceparent", this.options.traceparent);
3261
+ for (const [i, o] of Object.entries(this.extraParams ?? {}))
3262
+ e.searchParams.set(i, o);
3263
+ return e.toString();
3166
3264
  }
3167
3265
  getServerUrl() {
3168
3266
  if (this.serverHost !== void 0)
3169
3267
  return this.serverHost;
3170
- if (Bi?.VITE_VIRTUALDISPLAY_SERVER_HOST === void 0)
3268
+ if (Ji?.VITE_VIRTUALDISPLAY_SERVER_HOST === void 0)
3171
3269
  return this.defaultServer;
3172
3270
  }
3173
3271
  getParentElement() {
@@ -3179,37 +3277,39 @@ class Ui {
3179
3277
  return t;
3180
3278
  }
3181
3279
  }
3182
- function Vi(n) {
3280
+ function eo(n) {
3183
3281
  const { messenger: t } = n;
3184
3282
  t.on(c.HANDSHAKE, (e) => {
3185
- Tt(e) && (_.info("Server handshake received, flushing publisher queue"), t.markReady());
3283
+ Ot(e) && (_.info("Server handshake received, flushing publisher queue"), t.markReady());
3186
3284
  }), t.on(c.SESSION, (e) => {
3187
- Rt(e) && n.onSession(e.sessionId);
3285
+ Nt(e) && n.onSession(e.sessionId);
3188
3286
  }), t.on(c.MUTATION, (e) => {
3189
- It(e) && (n.attributes.handleMutationResult(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()));
3287
+ Mt(e) && (n.attributes.handleMutationResult(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()));
3190
3288
  }), t.on(c.SNAPSHOT, (e) => {
3191
- Ot(e) && n.snapshot.handleSnapshotResult(e);
3289
+ zt(e) && n.snapshot.handleSnapshotResult(e);
3192
3290
  }), t.on(c.CAMERA, (e) => {
3193
- Nt(e) && n.cameraPosition.handlePositionUpdate(e);
3291
+ Pt(e) && n.cameraPosition.handlePositionUpdate(e);
3194
3292
  }), t.on(c.LOADING_INDICATOR, (e) => {
3195
- Lt(e) && (e.error !== void 0 ? n.ui.showError(e.error) : n.ui.updateProgress(e.progress, e.phase));
3293
+ $t(e) && (e.error !== void 0 ? n.ui.showError(e.error) : n.ui.updateProgress(e.progress, e.phase));
3196
3294
  }), t.on(c.CONFIG, (e) => {
3197
- Pt(e) && n.applyConfig(e);
3295
+ Ut(e) && n.applyConfig(e);
3198
3296
  }), t.on(c.MAPPING, (e) => {
3199
- Mt(e) && (n.attributes.handleMappingReceived(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()), n.ui.renderAttributeControls(n.attributes, e.attributes), n.readyStateTracker.handleMappingReceived());
3200
- }), ji(n);
3297
+ Ft(e) && (n.attributes.handleMappingReceived(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()), n.ui.renderAttributeControls(n.attributes, e.attributes), n.readyStateTracker.handleMappingReceived());
3298
+ }), no(n);
3201
3299
  }
3202
- function ji(n) {
3300
+ function no(n) {
3203
3301
  const { messenger: t } = n;
3204
3302
  t.on(c.FOCUS, (e) => {
3205
- Ft(e) && n.focus.handleStateReceived(e);
3303
+ Vt(e) && n.focus.handleStateReceived(e);
3206
3304
  }), t.on(c.PRICING, (e) => {
3207
- $t(e) && n.configuration.handlePricingReceived(e.pricing);
3305
+ jt(e) && n.configuration.handlePricingReceived(e.pricing);
3208
3306
  }), t.on(c.SYNC, (e) => {
3209
- zt(e) && n.onSync(e.connected);
3307
+ Dt(e) && n.onSync(e.connected);
3308
+ }), t.on(c.SELECTABLE, (e) => {
3309
+ Bt(e) && (n.selectable.handleSnapshot(e), n.ui.applySelectable(e.attributes));
3210
3310
  });
3211
3311
  }
3212
- class Hi {
3312
+ class io {
3213
3313
  ready = !1;
3214
3314
  onReady;
3215
3315
  constructor(t) {
@@ -3225,8 +3325,9 @@ class Hi {
3225
3325
  this.ready = !1;
3226
3326
  }
3227
3327
  }
3228
- class qi {
3328
+ class oo {
3229
3329
  attributes;
3330
+ selectableState;
3230
3331
  readyStateTracker;
3231
3332
  messenger;
3232
3333
  cameraApi;
@@ -3239,6 +3340,7 @@ class qi {
3239
3340
  ui;
3240
3341
  options;
3241
3342
  serverHost;
3343
+ iframeParams;
3242
3344
  /** The composed AR flow, or undefined in builds without one (the studio). */
3243
3345
  arActivation;
3244
3346
  /** The composed sync tracker, or undefined in builds without one (the studio). */
@@ -3250,49 +3352,52 @@ class qi {
3250
3352
  /** The viewer's tracking session id, once the server announces it (SESSION). */
3251
3353
  viewerSessionId;
3252
3354
  constructor(t, e) {
3253
- this.options = t, this.serverHost = e?.serverHost, this.initializeLogging(), this.messenger = new Dt(
3355
+ this.options = t;
3356
+ const i = e ?? {};
3357
+ this.serverHost = i.serverHost, this.iframeParams = i.iframeParams, this.initializeLogging(), this.messenger = new Ht(
3254
3358
  () => this.iframe?.contentWindow ?? null,
3255
- e?.messengerOptions
3359
+ i.messengerOptions
3256
3360
  );
3257
- const i = (s) => {
3258
- this.messenger.send(s);
3361
+ const o = (r) => {
3362
+ this.messenger.send(r);
3259
3363
  };
3260
- this.attributes = new ne(i, (s, r) => {
3261
- this.notifyMutationFailed(s, r);
3262
- }), this.snapshotApi = new ue(i), this.annotationsApi = new Bt(i), this.cameraApi = new ie(i), this.cameraPositionApi = new oe(), this.focusApi = new le(i, (s) => {
3263
- this.dispatchFocusChange(s);
3264
- }), this.configurationApi = new ae(
3265
- (s) => {
3266
- this.dispatchConfigurationChange(s);
3364
+ this.attributes = new ue(o, (r, a) => {
3365
+ this.notifyMutationFailed(r, a);
3366
+ }), this.selectableState = new he(), this.snapshotApi = new we(o), this.annotationsApi = new qt(o), this.cameraApi = new me(o), this.cameraPositionApi = new pe(), this.focusApi = new ve(o, (r) => {
3367
+ this.dispatchFocusChange(r);
3368
+ }), this.configurationApi = new be(
3369
+ (r) => {
3370
+ this.dispatchConfigurationChange(r);
3267
3371
  },
3268
- (s) => {
3269
- this.dispatchConfigurationSubmit(s);
3372
+ (r) => {
3373
+ this.dispatchConfigurationSubmit(r);
3270
3374
  }
3271
- ), this.eventBus = new de(), this.arActivation = e?.createArActivation?.(i), this.syncTracker = e?.createSyncTracker?.(), this.readyStateTracker = new Hi(() => {
3375
+ ), this.eventBus = new Se(), this.arActivation = i.createArActivation?.(o), this.syncTracker = i.createSyncTracker?.(), this.readyStateTracker = new io(() => {
3272
3376
  this.notifyReady();
3273
3377
  });
3274
- const o = this.arActivation;
3275
- this.ui = new Di({
3378
+ const s = this.arActivation;
3379
+ this.ui = new Xi({
3276
3380
  snapshotApi: this.snapshotApi,
3277
3381
  cameraApi: this.cameraApi,
3278
3382
  cameraPositionApi: this.cameraPositionApi,
3279
3383
  eventBus: this.eventBus,
3280
3384
  configuration: this.configurationApi,
3281
- onSelect: (s, r) => this.attributes.select(s, r),
3282
- onSubscribe: (s, r) => this.attributes.onChange(s, r),
3283
- ...o !== void 0 && { onAr: () => {
3284
- o.activate();
3385
+ onSelect: (r, a) => this.attributes.select(r, a),
3386
+ onSubscribe: (r, a) => this.attributes.onChange(r, a),
3387
+ ...s !== void 0 && { onAr: () => {
3388
+ s.activate();
3285
3389
  } },
3286
3390
  onFullscreenEnter: () => {
3287
3391
  this.trackFullscreen();
3288
3392
  }
3289
- }), this.wireIncomingMessages(), e?.registerHandlers?.(this.messenger, i), this.messenger.start(), this.createAndConnectIframe();
3393
+ }), this.wireIncomingMessages(), i.registerHandlers?.(this.messenger, o), this.messenger.start(), this.createAndConnectIframe();
3290
3394
  }
3291
3395
  /** Wire the inbound viewer protocol to the facades. */
3292
3396
  wireIncomingMessages() {
3293
- Vi({
3397
+ eo({
3294
3398
  messenger: this.messenger,
3295
3399
  attributes: this.attributes,
3400
+ selectable: this.selectableState,
3296
3401
  configuration: this.configurationApi,
3297
3402
  snapshot: this.snapshotApi,
3298
3403
  cameraPosition: this.cameraPositionApi,
@@ -3333,7 +3438,7 @@ class qi {
3333
3438
  */
3334
3439
  dispatchFocusChange(t) {
3335
3440
  this.container?.dispatchEvent(
3336
- new CustomEvent(I.FOCUS_CHANGE, { detail: t, bubbles: !0 })
3441
+ new CustomEvent(L.FOCUS_CHANGE, { detail: t, bubbles: !0 })
3337
3442
  );
3338
3443
  }
3339
3444
  /**
@@ -3342,13 +3447,13 @@ class qi {
3342
3447
  */
3343
3448
  dispatchConfigurationChange(t) {
3344
3449
  this.container?.dispatchEvent(
3345
- new CustomEvent(I.CONFIGURATION_CHANGE, { detail: t ?? null, bubbles: !0 })
3450
+ new CustomEvent(L.CONFIGURATION_CHANGE, { detail: t ?? null, bubbles: !0 })
3346
3451
  );
3347
3452
  }
3348
3453
  /** Dispatch a bubbling `vd:configuration-submit` event when the CTA is used. */
3349
3454
  dispatchConfigurationSubmit(t) {
3350
3455
  this.container?.dispatchEvent(
3351
- new CustomEvent(I.CONFIGURATION_SUBMIT, { detail: t, bubbles: !0 })
3456
+ new CustomEvent(L.CONFIGURATION_SUBMIT, { detail: t, bubbles: !0 })
3352
3457
  );
3353
3458
  }
3354
3459
  handleConfig(t) {
@@ -3356,7 +3461,7 @@ class qi {
3356
3461
  if (e !== void 0 || i !== void 0) {
3357
3462
  const o = i !== void 0 ? { ...e ?? {}, ...i } : e;
3358
3463
  if (i !== void 0 && e !== void 0) {
3359
- const s = Object.entries(i).filter(([r, l]) => e[r] !== l).map(([r, l]) => `${r} (metadata: ${e[r] ?? "undefined"}, override: ${l})`);
3464
+ const s = Object.entries(i).filter(([r, a]) => e[r] !== a).map(([r, a]) => `${r} (metadata: ${e[r] ?? "undefined"}, override: ${a})`);
3360
3465
  s.length > 0 && _.warn(`Viewer settings override active: ${s.join(", ")}`);
3361
3466
  }
3362
3467
  this.ui.applyViewerSettings(o), this.annotationsApi.setEnabled(o.annotations !== !1);
@@ -3368,10 +3473,10 @@ class qi {
3368
3473
  this.messenger.send({ type: c.FULLSCREEN });
3369
3474
  }
3370
3475
  initializeLogging() {
3371
- this.options.debug === !0 && ee(), _.info("Initializing Virtualdisplay client", { model: this.options.model });
3476
+ this.options.debug === !0 && de(), _.info("Initializing Virtualdisplay client", { model: this.options.model });
3372
3477
  }
3373
3478
  createAndConnectIframe() {
3374
- const e = new Ui(this.options, this.serverHost).create();
3479
+ const e = new to(this.options, this.serverHost, this.iframeParams).create();
3375
3480
  this.container = e.container, this.iframe = e.iframe, this.eventBus.attach(this.container), this.ui.attach(this.container);
3376
3481
  try {
3377
3482
  const i = new URL(this.iframe.src).origin;
@@ -3407,6 +3512,20 @@ class qi {
3407
3512
  onMutationFailed(t) {
3408
3513
  this.mutationFailedCallbacks.push(t);
3409
3514
  }
3515
+ /**
3516
+ * Subscribe to the viewer's selectability snapshots (kiesbaarheid live):
3517
+ * per attribute, which values the buyer can pick right now. Fires with the
3518
+ * current snapshot immediately when one already arrived. A model without
3519
+ * exclusions never sends one: everything stays selectable and this never
3520
+ * fires.
3521
+ */
3522
+ onSelectableChange(t) {
3523
+ this.selectableState.onChange(t);
3524
+ }
3525
+ /** The selectable values for one attribute right now, or null when unrestricted. */
3526
+ getSelectable(t) {
3527
+ return this.selectableState.selectableFor(t);
3528
+ }
3410
3529
  /**
3411
3530
  * Trigger the composed AR flow directly (ar-session-handoff task 035): a host
3412
3531
  * page that hides the built-in corner button (`viewerSettings.ar = false`,
@@ -3449,15 +3568,15 @@ class qi {
3449
3568
  this.readyStateTracker.clear(), this.readyCallbacks = [], this.mutationFailedCallbacks.length = 0, this.snapshotApi.clear(), this.messenger.destroy(), this.arActivation?.destroy(), this.ui.destroy(), this.container?.parentElement !== null && this.container?.parentElement !== void 0 && this.container.parentElement.removeChild(this.container), this.container = void 0, this.iframe = void 0;
3450
3569
  }
3451
3570
  }
3452
- const Gi = "ar.virtualdisplay.io";
3453
- function Zi(n) {
3454
- const t = new URL(`https://${Gi}/go`);
3571
+ const so = "ar.virtualdisplay.io";
3572
+ function ro(n) {
3573
+ const t = new URL(`https://${so}/go`);
3455
3574
  return n.sessionId !== void 0 ? t.searchParams.set("session", n.sessionId) : (t.searchParams.set("license", n.license), t.searchParams.set("model", n.model)), t.toString();
3456
3575
  }
3457
- const Wi = 1500;
3458
- class Qi {
3576
+ const ao = 1500;
3577
+ class lo {
3459
3578
  options;
3460
- qrModal = new pi();
3579
+ qrModal = new xi();
3461
3580
  /** The viewer's tracking session id, once the engine announces it (SESSION). */
3462
3581
  sessionId;
3463
3582
  /** Callbacks waiting on the SESSION message, resolved (or timed out) exactly once each. */
@@ -3479,7 +3598,7 @@ class Qi {
3479
3598
  }
3480
3599
  /** The AR button handler: mobile activates AR in the engine, desktop shows the hand-off QR. */
3481
3600
  activate() {
3482
- if (Jt()) {
3601
+ if (le()) {
3483
3602
  this.options.send({ type: c.AR_ACTIVATE });
3484
3603
  return;
3485
3604
  }
@@ -3503,7 +3622,7 @@ class Qi {
3503
3622
  const t = await this.waitForSessionId();
3504
3623
  if (this.destroyed)
3505
3624
  return;
3506
- const e = Zi({
3625
+ const e = ro({
3507
3626
  sessionId: t,
3508
3627
  license: this.options.license,
3509
3628
  model: this.options.model
@@ -3524,14 +3643,14 @@ class Qi {
3524
3643
  return this.sessionId !== void 0 ? Promise.resolve(this.sessionId) : new Promise((t) => {
3525
3644
  const e = setTimeout(() => {
3526
3645
  this.pendingTimers.delete(e), t(void 0);
3527
- }, Wi);
3646
+ }, ao);
3528
3647
  this.pendingTimers.add(e), this.waiters.push((i) => {
3529
3648
  this.pendingTimers.delete(e), clearTimeout(e), t(i);
3530
3649
  });
3531
3650
  });
3532
3651
  }
3533
3652
  }
3534
- class Yi {
3653
+ class co {
3535
3654
  callbacks = [];
3536
3655
  lastKnown;
3537
3656
  handleSync(t) {
@@ -3543,12 +3662,12 @@ class Yi {
3543
3662
  this.callbacks.push(t), this.lastKnown !== void 0 && t(this.lastKnown);
3544
3663
  }
3545
3664
  }
3546
- class Ji extends qi {
3665
+ class mo extends oo {
3547
3666
  syncStatusTracker;
3548
3667
  constructor(t) {
3549
- const e = new Yi();
3668
+ const e = new co();
3550
3669
  super(t, {
3551
- createArActivation: (i) => new Qi({
3670
+ createArActivation: (i) => new lo({
3552
3671
  license: t.license,
3553
3672
  model: t.model,
3554
3673
  send: i
@@ -3562,19 +3681,19 @@ class Ji extends qi {
3562
3681
  }
3563
3682
  }
3564
3683
  export {
3565
- Bt as Annotations,
3566
- Vt as Attribute,
3567
- Ut as AttributeValue,
3568
- ie as Camera,
3569
- ae as Configuration,
3684
+ qt as Annotations,
3685
+ Zt as Attribute,
3686
+ Gt as AttributeValue,
3687
+ me as Camera,
3688
+ be as Configuration,
3570
3689
  A as ERROR_CODES,
3571
- le as Focus,
3572
- ce as Photo,
3573
- ue as Snapshot,
3574
- I as VD_EVENTS,
3575
- Ji as VirtualdisplayClient,
3690
+ ve as Focus,
3691
+ ye as Photo,
3692
+ we as Snapshot,
3693
+ L as VD_EVENTS,
3694
+ mo as VirtualdisplayClient,
3576
3695
  f as VirtualdisplayError,
3577
- ee as enableDebugMode,
3578
- Ki as isDebugMode,
3696
+ de as enableDebugMode,
3697
+ uo as isDebugMode,
3579
3698
  _ as logger
3580
3699
  };