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

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.
@@ -496,7 +496,7 @@ var pe = class {
496
496
  }
497
497
  this.pendingCallbacks.length = 0;
498
498
  }
499
- }, me = class {
499
+ }, x = class {
500
500
  commands = [];
501
501
  constructor(e) {
502
502
  this.send = e;
@@ -537,7 +537,7 @@ var pe = class {
537
537
  };
538
538
  this.send(e);
539
539
  }
540
- }, he = class {
540
+ }, me = class {
541
541
  state;
542
542
  limitsState;
543
543
  changeCallbacks = [];
@@ -598,7 +598,7 @@ var pe = class {
598
598
  for (let t of this.changeCallbacks) t(e);
599
599
  }
600
600
  }
601
- }, ge = class {
601
+ }, S = class {
602
602
  developedCallbacks = /* @__PURE__ */ new Set();
603
603
  errorCallbacks = /* @__PURE__ */ new Set();
604
604
  developed = !1;
@@ -626,7 +626,7 @@ var pe = class {
626
626
  t(e);
627
627
  }), this.developedCallbacks.clear(), this.errorCallbacks.clear());
628
628
  }
629
- }, _e = class {
629
+ }, C = class {
630
630
  validExtensions = [".png"];
631
631
  pendingPhotos = /* @__PURE__ */ new Map();
632
632
  constructor(e) {
@@ -634,7 +634,7 @@ var pe = class {
634
634
  }
635
635
  take(e) {
636
636
  this.validateFilename(e), m.debug("Taking snapshot", { filename: e });
637
- let t = new ge(e);
637
+ let t = new S(e);
638
638
  return this.pendingPhotos.set(t.getFilename(), t), this.send({
639
639
  type: y.SNAPSHOT,
640
640
  filename: e
@@ -663,7 +663,7 @@ var pe = class {
663
663
  if (!this.validExtensions.some((t) => e.toLowerCase().endsWith(t))) throw new n(`Invalid filename: "${e}". Filename must end with one of: ${this.validExtensions.join(", ")}`, t.INVALID_PARAMETER);
664
664
  if (e.includes("..") || e.includes("/") || e.includes("\\")) throw new n("Filename cannot contain path separators or \"..\"", t.INVALID_PARAMETER);
665
665
  }
666
- }, ve = class {
666
+ }, he = class {
667
667
  container = null;
668
668
  attach(e) {
669
669
  this.container = e;
@@ -689,70 +689,70 @@ var pe = class {
689
689
  this.container?.removeEventListener(e, n);
690
690
  };
691
691
  }
692
- }, ye = {}, be = [
692
+ }, ge = {}, w = [
693
693
  "en",
694
694
  "nl",
695
695
  "de"
696
- ], x = ["baseLocale"], S = [], C, w;
697
- function xe(e) {
698
- if (S.length === 0) return;
696
+ ], T = ["baseLocale"], _e = [], ve, ye;
697
+ function be(e) {
698
+ if (_e.length === 0) return;
699
699
  let t = typeof e == "string" ? e : e.href;
700
- if (C === t) return w;
700
+ if (ve === t) return ye;
701
701
  let n = new URL(t, "http://dummy.com"), r;
702
- for (let e of S) if (new ye(e.match, n.href).exec(n.href)) {
702
+ for (let e of _e) if (new ge(e.match, n.href).exec(n.href)) {
703
703
  r = e;
704
704
  break;
705
705
  }
706
- return C = t, w = r, r;
706
+ return ve = t, ye = r, r;
707
707
  }
708
- function T(e) {
709
- let t = xe(e);
710
- return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : x;
708
+ function E(e) {
709
+ let t = be(e);
710
+ return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : T;
711
711
  }
712
- var E = void 0, D = typeof window > "u";
712
+ var D = void 0, O = typeof window > "u";
713
713
  globalThis.__paraglide = globalThis.__paraglide ?? {}, globalThis.__paraglide.ssr = globalThis.__paraglide.ssr ?? {};
714
- var O = !1, k = () => {
715
- if (E) {
716
- let e = E?.getStore()?.locale;
714
+ var k = !1, A = () => {
715
+ if (D) {
716
+ let e = D?.getStore()?.locale;
717
717
  if (e) return e;
718
718
  }
719
- let e = x;
720
- !D && typeof window < "u" && window.location?.href && (e = T(window.location.href));
721
- let t = Se(e, typeof window < "u" ? window.location?.href : void 0);
722
- if (t) return O || (O = !0, A(t, { reload: !1 })), t;
719
+ let e = T;
720
+ !O && typeof window < "u" && window.location?.href && (e = E(window.location.href));
721
+ let t = xe(e, typeof window < "u" ? window.location?.href : void 0);
722
+ if (t) return k || (k = !0, j(t, { reload: !1 })), t;
723
723
  throw Error("No locale found. Read the docs https://inlang.com/m/gerre34r/library-inlang-paraglideJs/errors#no-locale-found");
724
724
  };
725
- function Se(e, t) {
725
+ function xe(e, t) {
726
726
  let n;
727
727
  for (let t of e) {
728
728
  if (t === "baseLocale") n = "en";
729
- else if (N(t) && M.has(t)) {
730
- let e = M.get(t);
729
+ else if (we(t) && N.has(t)) {
730
+ let e = N.get(t);
731
731
  if (e) {
732
732
  let t = e.getLocale();
733
733
  if (t instanceof Promise) continue;
734
- if (t !== void 0) return we(t);
734
+ if (t !== void 0) return Ce(t);
735
735
  }
736
736
  }
737
- let e = j(n);
737
+ let e = M(n);
738
738
  if (e) return e;
739
739
  }
740
740
  }
741
- var Ce = (e) => {
741
+ var Se = (e) => {
742
742
  e ? window.location.href = e : window.location.reload();
743
- }, A = (e, t) => {
743
+ }, j = (e, t) => {
744
744
  let n = {
745
745
  reload: !0,
746
746
  ...t
747
747
  }, r;
748
748
  try {
749
- r = k();
749
+ r = A();
750
750
  } catch {}
751
- let i = [], a = x;
752
- !D && typeof window < "u" && window.location?.href && (a = T(window.location.href));
751
+ let i = [], a = T;
752
+ !O && typeof window < "u" && window.location?.href && (a = E(window.location.href));
753
753
  for (let t of a) if (t === "baseLocale") continue;
754
- else if (N(t) && M.has(t)) {
755
- let n = M.get(t);
754
+ else if (we(t) && N.has(t)) {
755
+ let n = N.get(t);
756
756
  if (n) {
757
757
  let r = n.setLocale(e);
758
758
  r instanceof Promise && (r = r.catch((e) => {
@@ -761,280 +761,78 @@ var Ce = (e) => {
761
761
  }
762
762
  }
763
763
  let o = () => {
764
- !D && n.reload && window.location && e !== r && Ce(void 0);
764
+ !O && n.reload && window.location && e !== r && Se(void 0);
765
765
  };
766
766
  if (i.length) return Promise.all(i).then(() => {
767
767
  o();
768
768
  });
769
769
  o();
770
770
  };
771
- function j(e) {
771
+ function M(e) {
772
772
  if (typeof e != "string") return;
773
773
  let t = e.toLowerCase();
774
- for (let e of be) if (e.toLowerCase() === t) return e;
774
+ for (let e of w) if (e.toLowerCase() === t) return e;
775
775
  }
776
- function we(e) {
777
- let t = j(e);
776
+ function Ce(e) {
777
+ let t = M(e);
778
778
  if (t) return t;
779
- throw Error(`Invalid locale: ${e}. Expected one of: ${be.join(", ")}`);
779
+ throw Error(`Invalid locale: ${e}. Expected one of: ${w.join(", ")}`);
780
780
  }
781
- var M = /* @__PURE__ */ new Map();
782
- function N(e) {
781
+ var N = /* @__PURE__ */ new Map();
782
+ function we(e) {
783
783
  return typeof e == "string" && /^custom-[A-Za-z0-9_-]+$/.test(e);
784
784
  }
785
785
  //#endregion
786
786
  //#region ../i18n/src/paraglide-viewer/messages/controls_ar_buttonlabel1.js
787
787
  var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivieren", Oe = ((e = {}, t = {}) => {
788
- let n = t.locale ?? k();
788
+ let n = t.locale ?? A();
789
789
  return n === "en" ? Te(e) : n === "nl" ? Ee(e) : De(e);
790
790
  }), ke = () => "Scan to view in AR", Ae = () => "Scan om in AR te bekijken", je = () => "Scannen für AR-Ansicht", Me = ((e = {}, t = {}) => {
791
- let n = t.locale ?? k();
791
+ let n = t.locale ?? A();
792
792
  return n === "en" ? ke(e) : n === "nl" ? Ae(e) : je(e);
793
793
  }), Ne = () => "Use your smartphone camera to scan this QR code", Pe = () => "Gebruik de camera van uw smartphone om deze QR-code te scannen", Fe = () => "Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen", Ie = ((e = {}, t = {}) => {
794
- let n = t.locale ?? k();
794
+ let n = t.locale ?? A();
795
795
  return n === "en" ? Ne(e) : n === "nl" ? Pe(e) : Fe(e);
796
796
  }), Le = () => "The 3D model will open in your phone's AR mode", Re = () => "Het 3D-model wordt geopend in de AR-modus van uw telefoon", ze = () => "Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet", Be = ((e = {}, t = {}) => {
797
- let n = t.locale ?? k();
797
+ let n = t.locale ?? A();
798
798
  return n === "en" ? Le(e) : n === "nl" ? Re(e) : ze(e);
799
799
  }), Ve = () => "Close", He = () => "Sluiten", Ue = () => "Schließen", We = ((e = {}, t = {}) => {
800
- let n = t.locale ?? k();
800
+ let n = t.locale ?? A();
801
801
  return n === "en" ? Ve(e) : n === "nl" ? He(e) : Ue(e);
802
802
  }), Ge = () => "Toggle fullscreen", Ke = () => "Volledig scherm", qe = () => "Vollbild umschalten", Je = ((e = {}, t = {}) => {
803
- let n = t.locale ?? k();
803
+ let n = t.locale ?? A();
804
804
  return n === "en" ? Ge(e) : n === "nl" ? Ke(e) : qe(e);
805
- }), Ye = () => "Downloading", Xe = () => "Downloaden", Ze = () => "Herunterladen", P = ((e = {}, t = {}) => {
806
- let n = t.locale ?? k();
805
+ }), Ye = () => "Downloading", Xe = () => "Downloaden", Ze = () => "Herunterladen", Qe = ((e = {}, t = {}) => {
806
+ let n = t.locale ?? A();
807
807
  return n === "en" ? Ye(e) : n === "nl" ? Xe(e) : Ze(e);
808
- }), Qe = () => "Rendering", $e = () => "Renderen", et = () => "Rendern", tt = ((e = {}, t = {}) => {
809
- let n = t.locale ?? k();
810
- return n === "en" ? Qe(e) : n === "nl" ? $e(e) : et(e);
811
- }), nt = () => "Screenshot", rt = () => "Screenshot", it = () => "Screenshot", at = ((e = {}, t = {}) => {
812
- let n = t.locale ?? k();
813
- return n === "en" ? nt(e) : n === "nl" ? rt(e) : it(e);
814
- }), ot = () => "Reset camera", st = () => "Camera resetten", ct = () => "Kamera zurücksetzen", lt = ((e = {}, t = {}) => {
815
- let n = t.locale ?? k();
816
- return n === "en" ? ot(e) : n === "nl" ? st(e) : ct(e);
817
- }), ut = () => "Zoom in", dt = () => "Inzoomen", ft = () => "Hineinzoomen", pt = ((e = {}, t = {}) => {
818
- let n = t.locale ?? k();
819
- return n === "en" ? ut(e) : n === "nl" ? dt(e) : ft(e);
820
- }), mt = () => "Zoom out", ht = () => "Uitzoomen", gt = () => "Herauszoomen", _t = ((e = {}, t = {}) => {
821
- let n = t.locale ?? k();
822
- return n === "en" ? mt(e) : n === "nl" ? ht(e) : gt(e);
823
- }), vt = () => "Rotate left", yt = () => "Naar links draaien", bt = () => "Nach links drehen", xt = ((e = {}, t = {}) => {
824
- let n = t.locale ?? k();
825
- return n === "en" ? vt(e) : n === "nl" ? yt(e) : bt(e);
826
- }), St = () => "Rotate right", Ct = () => "Naar rechts draaien", wt = () => "Nach rechts drehen", Tt = ((e = {}, t = {}) => {
827
- let n = t.locale ?? k();
828
- return n === "en" ? St(e) : n === "nl" ? Ct(e) : wt(e);
829
- }), Et = () => "Tilt up", Dt = () => "Omhoog kantelen", Ot = () => "Nach oben kippen", kt = ((e = {}, t = {}) => {
830
- let n = t.locale ?? k();
831
- return n === "en" ? Et(e) : n === "nl" ? Dt(e) : Ot(e);
832
- }), At = () => "Tilt down", jt = () => "Omlaag kantelen", Mt = () => "Nach unten kippen", Nt = ((e = {}, t = {}) => {
833
- let n = t.locale ?? k();
834
- return n === "en" ? At(e) : n === "nl" ? jt(e) : Mt(e);
835
- });
836
- //#endregion
837
- //#region src/ui/loading.ts
838
- function F(e) {
839
- let t = Math.max(0, Math.min(1, e));
840
- return t * t * (3 - 2 * t);
841
- }
842
- function Pt(e, t, n, r, i, a) {
843
- let [o, s, c] = e, l = Math.cos(t), u = Math.sin(t), d = l * o + u * c, f = -u * o + l * c, p = Math.cos(n), m = Math.sin(n), h = p * s - m * f, g = m * s + p * f, _ = .55;
844
- return [
845
- r + d * a * _,
846
- i - h * a * _,
847
- g
848
- ];
849
- }
850
- function Ft(e, t, n) {
851
- e.beginPath(), e.moveTo(t[0], t[1]), e.lineTo(n[0], n[1]), e.strokeStyle = "#000", e.lineWidth = 2, e.stroke();
852
- }
853
- function It(e, t, n, r, i) {
854
- let a = t(n), o = t(r);
855
- Ft(e, a, [
856
- a[0] + (o[0] - a[0]) * i,
857
- a[1] + (o[1] - a[1]) * i,
858
- a[2]
859
- ]);
860
- }
861
- var I = [
862
- -1,
863
- -1,
864
- 1
865
- ], L = [
866
- 1,
867
- -1,
868
- 1
869
- ], R = [
870
- 1,
871
- -1,
872
- -1
873
- ], z = [
874
- -1,
875
- -1,
876
- -1
877
- ], B = [
878
- -1,
879
- 1,
880
- 1
881
- ], V = [
882
- 1,
883
- 1,
884
- 1
885
- ], H = [
886
- 1,
887
- 1,
888
- -1
889
- ], U = [
890
- -1,
891
- 1,
892
- -1
893
- ], Lt = [
894
- [I, L],
895
- [L, R],
896
- [R, z],
897
- [z, I],
898
- [I, B],
899
- [L, V],
900
- [R, H],
901
- [z, U],
902
- [B, V],
903
- [V, H],
904
- [H, U],
905
- [U, B]
906
- ], Rt = 400, zt = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif";
907
- function Bt() {
908
- let e = document.createElement("div");
909
- Object.assign(e.style, {
910
- position: "absolute",
911
- inset: "0",
912
- display: "flex",
913
- flexDirection: "column",
914
- alignItems: "center",
915
- justifyContent: "center",
916
- background: "#fff",
917
- zIndex: "20",
918
- opacity: "0",
919
- transition: "opacity 0.3s ease-in-out"
920
- });
921
- let t = document.createElement("canvas");
922
- Object.assign(t.style, {
923
- width: "100%",
924
- height: "100%",
925
- position: "absolute",
926
- inset: "0"
927
- });
928
- let n = document.createElement("div");
929
- Object.assign(n.style, {
930
- position: "absolute",
931
- top: "56%",
932
- left: "0",
933
- right: "0",
934
- textAlign: "center",
935
- pointerEvents: "none"
936
- });
937
- let r = document.createElement("span");
938
- Object.assign(r.style, {
939
- fontSize: "13px",
940
- fontWeight: "400",
941
- color: "#000",
942
- fontVariantNumeric: "tabular-nums",
943
- fontFamily: zt
944
- });
945
- let i = document.createElement("span");
946
- return Object.assign(i.style, {
947
- fontSize: "13px",
948
- color: "#000",
949
- fontFamily: zt
950
- }), i.textContent = P(), n.appendChild(r), n.appendChild(i), e.appendChild(t), e.appendChild(n), {
951
- overlay: e,
952
- canvas: t,
953
- pctEl: r,
954
- phaseEl: i
955
- };
956
- }
957
- var Vt = class {
958
- overlay;
959
- canvas;
960
- ctx;
961
- pctEl;
962
- phaseEl;
963
- animationId = null;
964
- showTimerId = null;
965
- startTime;
966
- hidden = !1;
967
- visible = !1;
968
- constructor(e, t = {}) {
969
- this.startTime = performance.now();
970
- let n = Bt();
971
- this.overlay = n.overlay, this.canvas = n.canvas, this.pctEl = n.pctEl, this.phaseEl = n.phaseEl, e.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
972
- let r = t.showDelay ?? Rt;
973
- this.showTimerId = setTimeout(() => {
974
- this.reveal();
975
- }, r);
976
- }
977
- get loadingTexts() {
978
- return {
979
- downloading: P(),
980
- rendering: tt()
981
- };
982
- }
983
- updateProgress(e, t) {
984
- this.hidden || (this.pctEl.textContent = `${Math.round(e)}%`, this.phaseEl.textContent = t === "" ? "" : ` \u00B7 ${t}`);
985
- }
986
- showError(e) {
987
- if (this.hidden = !1, this.animationId !== null && (cancelAnimationFrame(this.animationId), this.animationId = null), this.ctx !== null) {
988
- let e = Math.min(devicePixelRatio, 2), t = this.canvas.width / e, n = this.canvas.height / e;
989
- this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, t * e, n * e);
990
- }
991
- this.pctEl.textContent = "", this.phaseEl.textContent = e, this.phaseEl.style.color = "#b91c1c", this.reveal();
992
- }
993
- hide() {
994
- if (!this.hidden) {
995
- if (this.hidden = !0, this.cancelShowTimer(), !this.visible) {
996
- this.destroy();
997
- return;
998
- }
999
- this.overlay.style.opacity = "0", this.overlay.addEventListener("transitionend", () => {
1000
- this.destroy();
1001
- }, { once: !0 }), setTimeout(() => {
1002
- this.destroy();
1003
- }, 500);
1004
- }
1005
- }
1006
- destroy() {
1007
- this.cancelShowTimer(), this.animationId !== null && (cancelAnimationFrame(this.animationId), this.animationId = null), this.overlay.remove();
1008
- }
1009
- reveal() {
1010
- this.hidden || this.visible || (this.visible = !0, this.overlay.style.opacity = "1");
1011
- }
1012
- cancelShowTimer() {
1013
- this.showTimerId !== null && (clearTimeout(this.showTimerId), this.showTimerId = null);
1014
- }
1015
- sizeCanvas() {
1016
- if (this.ctx === null) return;
1017
- let e = Math.min(devicePixelRatio, 2), t = this.overlay.clientWidth || 440, n = this.overlay.clientHeight || 360;
1018
- this.canvas.width = t * e, this.canvas.height = n * e, this.ctx.scale(e, e), this.ctx.lineCap = "round", this.ctx.lineJoin = "round";
1019
- }
1020
- tick = () => {
1021
- this.hidden || (this.drawFrame(), this.animationId = requestAnimationFrame(this.tick));
1022
- };
1023
- drawFrame() {
1024
- if (this.ctx === null) return;
1025
- let e = this.canvas.width / Math.min(devicePixelRatio, 2), t = this.canvas.height / Math.min(devicePixelRatio, 2), n = (performance.now() - this.startTime) / 1e3;
1026
- this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, e, t);
1027
- let r = e / 2, i = t * .44, a = Math.min(e, t) * .08, o = (e) => Pt(e, .785, .615, r, i, a), s = n % 6 / 6, c = Lt.length, l;
1028
- l = s < .35 ? F(s / .35) * c : s < .55 ? c : s < .9 ? (1 - F((s - .55) / .35)) * c : 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
1029
- for (let e = 0; e < c && !(e >= l); e++) {
1030
- let t = Lt[e];
1031
- if (t === void 0) continue;
1032
- let n = Math.min(1, l - e);
1033
- It(this.ctx, o, t[0], t[1], n);
1034
- }
1035
- this.ctx.shadowBlur = 0;
1036
- }
1037
- }, Ht = {
808
+ }), $e = () => "Rendering", et = () => "Renderen", tt = () => "Rendern", nt = ((e = {}, t = {}) => {
809
+ let n = t.locale ?? A();
810
+ return n === "en" ? $e(e) : n === "nl" ? et(e) : tt(e);
811
+ }), rt = () => "Screenshot", it = () => "Screenshot", at = () => "Screenshot", ot = ((e = {}, t = {}) => {
812
+ let n = t.locale ?? A();
813
+ return n === "en" ? rt(e) : n === "nl" ? it(e) : at(e);
814
+ }), st = () => "Reset camera", ct = () => "Camera resetten", lt = () => "Kamera zurücksetzen", ut = ((e = {}, t = {}) => {
815
+ let n = t.locale ?? A();
816
+ return n === "en" ? st(e) : n === "nl" ? ct(e) : lt(e);
817
+ }), dt = () => "Zoom in", ft = () => "Inzoomen", pt = () => "Hineinzoomen", mt = ((e = {}, t = {}) => {
818
+ let n = t.locale ?? A();
819
+ return n === "en" ? dt(e) : n === "nl" ? ft(e) : pt(e);
820
+ }), ht = () => "Zoom out", gt = () => "Uitzoomen", _t = () => "Herauszoomen", vt = ((e = {}, t = {}) => {
821
+ let n = t.locale ?? A();
822
+ return n === "en" ? ht(e) : n === "nl" ? gt(e) : _t(e);
823
+ }), yt = () => "Rotate left", bt = () => "Naar links draaien", xt = () => "Nach links drehen", St = ((e = {}, t = {}) => {
824
+ let n = t.locale ?? A();
825
+ return n === "en" ? yt(e) : n === "nl" ? bt(e) : xt(e);
826
+ }), Ct = () => "Rotate right", wt = () => "Naar rechts draaien", Tt = () => "Nach rechts drehen", Et = ((e = {}, t = {}) => {
827
+ let n = t.locale ?? A();
828
+ return n === "en" ? Ct(e) : n === "nl" ? wt(e) : Tt(e);
829
+ }), Dt = () => "Tilt up", Ot = () => "Omhoog kantelen", kt = () => "Nach oben kippen", At = ((e = {}, t = {}) => {
830
+ let n = t.locale ?? A();
831
+ return n === "en" ? Dt(e) : n === "nl" ? Ot(e) : kt(e);
832
+ }), jt = () => "Tilt down", Mt = () => "Omlaag kantelen", Nt = () => "Nach unten kippen", Pt = ((e = {}, t = {}) => {
833
+ let n = t.locale ?? A();
834
+ return n === "en" ? jt(e) : n === "nl" ? Mt(e) : Nt(e);
835
+ }), Ft = {
1038
836
  xmlns: "http://www.w3.org/2000/svg",
1039
837
  width: 24,
1040
838
  height: 24,
@@ -1044,40 +842,40 @@ var Vt = class {
1044
842
  "stroke-width": 2,
1045
843
  "stroke-linecap": "round",
1046
844
  "stroke-linejoin": "round"
1047
- }, Ut = ([e, t, n]) => {
845
+ }, It = ([e, t, n]) => {
1048
846
  let r = document.createElementNS("http://www.w3.org/2000/svg", e);
1049
847
  return Object.keys(t).forEach((e) => {
1050
848
  r.setAttribute(e, String(t[e]));
1051
849
  }), n?.length && n.forEach((e) => {
1052
- let t = Ut(e);
850
+ let t = It(e);
1053
851
  r.appendChild(t);
1054
852
  }), r;
1055
- }, Wt = (e, t = {}) => Ut([
853
+ }, Lt = (e, t = {}) => It([
1056
854
  "svg",
1057
855
  {
1058
- ...Ht,
856
+ ...Ft,
1059
857
  ...t
1060
858
  },
1061
859
  e
1062
- ]), Gt = [
860
+ ]), Rt = [
1063
861
  ["path", { d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" }],
1064
862
  ["path", { d: "m3.3 7 8.7 5 8.7-5" }],
1065
863
  ["path", { d: "M12 22V12" }]
1066
- ], Kt = [["path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }], ["circle", {
864
+ ], zt = [["path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }], ["circle", {
1067
865
  cx: "12",
1068
866
  cy: "13",
1069
867
  r: "3"
1070
- }]], qt = [["path", { d: "m6 9 6 6 6-6" }]], Jt = [["path", { d: "m15 18-6-6 6-6" }]], Yt = [["path", { d: "m9 18 6-6-6-6" }]], Xt = [["path", { d: "m18 15-6-6-6 6" }]], Zt = [
868
+ }]], Bt = [["path", { d: "m6 9 6 6 6-6" }]], Vt = [["path", { d: "m15 18-6-6 6-6" }]], Ht = [["path", { d: "m9 18 6-6-6-6" }]], Ut = [["path", { d: "m18 15-6-6-6 6" }]], Wt = [
1071
869
  ["path", { d: "M15 3h6v6" }],
1072
870
  ["path", { d: "m21 3-7 7" }],
1073
871
  ["path", { d: "m3 21 7-7" }],
1074
872
  ["path", { d: "M9 21H3v-6" }]
1075
- ], Qt = [
873
+ ], Gt = [
1076
874
  ["path", { d: "m14 10 7-7" }],
1077
875
  ["path", { d: "M20 10h-6V4" }],
1078
876
  ["path", { d: "m3 21 7-7" }],
1079
877
  ["path", { d: "M4 14h6v6" }]
1080
- ], $t = [["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { d: "M3 3v5h5" }]], en = [
878
+ ], Kt = [["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { d: "M3 3v5h5" }]], qt = [
1081
879
  ["circle", {
1082
880
  cx: "11",
1083
881
  cy: "11",
@@ -1101,7 +899,7 @@ var Vt = class {
1101
899
  y1: "11",
1102
900
  y2: "11"
1103
901
  }]
1104
- ], tn = [
902
+ ], Jt = [
1105
903
  ["circle", {
1106
904
  cx: "11",
1107
905
  cy: "11",
@@ -1122,26 +920,26 @@ var Vt = class {
1122
920
  ];
1123
921
  //#endregion
1124
922
  //#region ../ui/src/icons.ts
1125
- function W(e, { size: t = 20, strokeWidth: n = 1.75 } = {}) {
1126
- return Wt(e, {
923
+ function P(e, { size: t = 20, strokeWidth: n = 1.75 } = {}) {
924
+ return Lt(e, {
1127
925
  width: t,
1128
926
  height: t,
1129
927
  "stroke-width": n
1130
928
  });
1131
929
  }
1132
- var G = {
1133
- ar: (e) => W(Gt, e),
1134
- fullscreen: (e) => W(Zt, e),
1135
- exitFullscreen: (e) => W(Qt, e),
1136
- screenshot: (e) => W(Kt, e),
1137
- tiltUp: (e) => W(Xt, e),
1138
- tiltDown: (e) => W(qt, e),
1139
- rotateLeft: (e) => W(Jt, e),
1140
- rotateRight: (e) => W(Yt, e),
1141
- zoomIn: (e) => W(en, e),
1142
- zoomOut: (e) => W(tn, e),
1143
- reset: (e) => W($t, e)
1144
- }, K = class {
930
+ var F = {
931
+ ar: (e) => P(Rt, e),
932
+ fullscreen: (e) => P(Wt, e),
933
+ exitFullscreen: (e) => P(Gt, e),
934
+ screenshot: (e) => P(zt, e),
935
+ tiltUp: (e) => P(Ut, e),
936
+ tiltDown: (e) => P(Bt, e),
937
+ rotateLeft: (e) => P(Vt, e),
938
+ rotateRight: (e) => P(Ht, e),
939
+ zoomIn: (e) => P(qt, e),
940
+ zoomOut: (e) => P(Jt, e),
941
+ reset: (e) => P(Kt, e)
942
+ }, I = class {
1145
943
  element;
1146
944
  constructor({ variant: e = "default", size: t = "default", label: n, icon: r, onClick: i, disabled: a = !1 } = {}) {
1147
945
  this.element = document.createElement("button"), this.element.className = `ui-btn ui-btn--${e} ui-btn--size-${t}`, n !== void 0 && (this.element.setAttribute("aria-label", n), this.element.title = n), r === void 0 ? n !== void 0 && (this.element.textContent = n) : this.element.appendChild(r), i && this.element.addEventListener("click", i), this.element.disabled = a;
@@ -1150,7 +948,7 @@ var G = {
1150
948
  let t = this.element.querySelector("svg");
1151
949
  t === null ? this.element.appendChild(e) : t.replaceWith(e);
1152
950
  }
1153
- }, q = {
951
+ }, L = {
1154
952
  brand: {
1155
953
  DEFAULT: "#171717",
1156
954
  primary: "#171717",
@@ -1189,7 +987,7 @@ var G = {
1189
987
  },
1190
988
  white: "#ffffff",
1191
989
  black: "#000000"
1192
- }, J = {
990
+ }, R = {
1193
991
  px: "1px",
1194
992
  0: "0",
1195
993
  .5: "0.125rem",
@@ -1212,27 +1010,27 @@ var G = {
1212
1010
  20: "5rem",
1213
1011
  24: "6rem"
1214
1012
  };
1215
- J[1], J[2], J[4], J[6], J[8], J[12];
1013
+ R[1], R[2], R[4], R[6], R[8], R[12];
1216
1014
  //#endregion
1217
1015
  //#region ../ui/src/vanilla/components/card/index.ts
1218
- var nn = class {
1016
+ var Yt = class {
1219
1017
  element;
1220
1018
  constructor() {
1221
1019
  this.element = document.createElement("div"), Object.assign(this.element.style, {
1222
- background: q.white,
1223
- borderRadius: J[3],
1224
- padding: J[6],
1225
- boxShadow: `0 ${J[2]} ${J[8]} oklch(0% 0 0 / 20%)`,
1020
+ background: L.white,
1021
+ borderRadius: R[3],
1022
+ padding: R[6],
1023
+ boxShadow: `0 ${R[2]} ${R[8]} oklch(0% 0 0 / 20%)`,
1226
1024
  maxWidth: "20rem",
1227
1025
  width: "100%"
1228
1026
  });
1229
1027
  }
1230
- }, rn = class {
1028
+ }, Xt = class {
1231
1029
  card;
1232
1030
  backdrop;
1233
1031
  keyHandler = null;
1234
1032
  constructor(e = {}) {
1235
- this.options = e, this.card = new nn(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1033
+ this.options = e, this.card = new Yt(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1236
1034
  }
1237
1035
  open() {
1238
1036
  document.body.appendChild(this.backdrop), this.keyHandler = (e) => {
@@ -1246,7 +1044,7 @@ var nn = class {
1246
1044
  let e = document.createElement("div");
1247
1045
  return Object.assign(e.style, {
1248
1046
  position: "fixed",
1249
- inset: J[0],
1047
+ inset: R[0],
1250
1048
  background: "oklch(0% 0 0 / 50%)",
1251
1049
  zIndex: "9999",
1252
1050
  display: "flex",
@@ -1256,7 +1054,7 @@ var nn = class {
1256
1054
  t.target === e && this.close();
1257
1055
  }), e;
1258
1056
  }
1259
- }, an = class {
1057
+ }, Zt = class {
1260
1058
  element;
1261
1059
  selectCallback = null;
1262
1060
  constructor(e, t, n) {
@@ -1274,7 +1072,7 @@ var nn = class {
1274
1072
  onSelect(e) {
1275
1073
  this.selectCallback = e;
1276
1074
  }
1277
- }, on = class {
1075
+ }, Qt = class {
1278
1076
  element;
1279
1077
  select;
1280
1078
  constructor(e, t, n, r, i) {
@@ -1287,7 +1085,7 @@ var nn = class {
1287
1085
  a.value = n, a.textContent = i?.[e] ?? n, n === r && (a.selected = !0, o = !0), this.select.appendChild(a);
1288
1086
  }
1289
1087
  o || (a.selected = !0);
1290
- let s = Wt(qt, {
1088
+ let s = Lt(Bt, {
1291
1089
  width: 16,
1292
1090
  height: 16,
1293
1091
  "stroke-width": 2
@@ -1302,7 +1100,7 @@ var nn = class {
1302
1100
  e(this.select.value);
1303
1101
  });
1304
1102
  }
1305
- }, Y = {
1103
+ }, z = {
1306
1104
  fontFamily: {
1307
1105
  sans: [
1308
1106
  "Mona Sans",
@@ -1341,7 +1139,7 @@ var nn = class {
1341
1139
  normal: "1.5",
1342
1140
  relaxed: "1.75"
1343
1141
  }
1344
- }, sn = Y.fontFamily.sans.join(", "), cn = class {
1142
+ }, $t = z.fontFamily.sans.join(", "), en = class {
1345
1143
  qrLib = null;
1346
1144
  dialog = null;
1347
1145
  async show(t) {
@@ -1351,30 +1149,30 @@ var nn = class {
1351
1149
  margin: 4,
1352
1150
  errorCorrectionLevel: "M",
1353
1151
  color: {
1354
- dark: q.black,
1355
- light: q.white
1152
+ dark: L.black,
1153
+ light: L.white
1356
1154
  }
1357
1155
  });
1358
- this.dialog = new rn({ onClose: () => {
1156
+ this.dialog = new Xt({ onClose: () => {
1359
1157
  this.dialog = null;
1360
1158
  } }), Object.assign(this.dialog.card.element.style, {
1361
1159
  display: "flex",
1362
1160
  flexDirection: "column",
1363
1161
  alignItems: "center",
1364
- gap: J[3],
1365
- fontFamily: sn
1162
+ gap: R[3],
1163
+ fontFamily: $t
1366
1164
  }), this.dialog.card.element.appendChild(this.createText(Me(), {
1367
- fontSize: Y.fontSize.base,
1368
- fontWeight: Y.fontWeight.semibold,
1369
- color: q.neutral[900]
1165
+ fontSize: z.fontSize.base,
1166
+ fontWeight: z.fontWeight.semibold,
1167
+ color: L.neutral[900]
1370
1168
  })), this.dialog.card.element.appendChild(this.createText(Ie(), {
1371
- fontSize: Y.fontSize.sm,
1372
- color: q.neutral[600]
1169
+ fontSize: z.fontSize.sm,
1170
+ color: L.neutral[600]
1373
1171
  })), this.dialog.card.element.appendChild(this.createQrImage(n)), this.dialog.card.element.appendChild(this.createText(Be(), {
1374
- fontSize: Y.fontSize.xs,
1375
- color: q.neutral[500]
1172
+ fontSize: z.fontSize.xs,
1173
+ color: L.neutral[500]
1376
1174
  }));
1377
- let r = new K({
1175
+ let r = new I({
1378
1176
  variant: "outline",
1379
1177
  label: We(),
1380
1178
  onClick: () => {
@@ -1397,12 +1195,12 @@ var nn = class {
1397
1195
  createQrImage(e) {
1398
1196
  let t = document.createElement("img");
1399
1197
  return t.src = e, t.alt = "QR code", Object.assign(t.style, {
1400
- width: J[24],
1401
- height: J[24],
1402
- borderRadius: J[1]
1198
+ width: R[24],
1199
+ height: R[24],
1200
+ borderRadius: R[1]
1403
1201
  }), t;
1404
1202
  }
1405
- }, X = Y.fontFamily.sans.join(", "), ln = `
1203
+ }, B = z.fontFamily.sans.join(", "), tn = `
1406
1204
  :root {
1407
1205
  --primary: oklch(5% 0 0);
1408
1206
  --primary-foreground: oklch(100% 0 0);
@@ -1426,7 +1224,7 @@ var nn = class {
1426
1224
  gap: 0.5rem;
1427
1225
  border: 1px solid transparent;
1428
1226
  border-radius: var(--radius);
1429
- font-family: ${X};
1227
+ font-family: ${B};
1430
1228
  font-size: 0.875rem;
1431
1229
  font-weight: 600;
1432
1230
  white-space: nowrap;
@@ -1483,7 +1281,7 @@ var nn = class {
1483
1281
  border-radius: var(--radius);
1484
1282
  background: var(--background);
1485
1283
  color: var(--foreground);
1486
- font-family: ${X};
1284
+ font-family: ${B};
1487
1285
  font-size: 0.875rem;
1488
1286
  font-weight: 600;
1489
1287
  cursor: pointer;
@@ -1517,7 +1315,7 @@ var nn = class {
1517
1315
  background: var(--background);
1518
1316
  appearance: none;
1519
1317
  color: var(--foreground);
1520
- font-family: ${X};
1318
+ font-family: ${B};
1521
1319
  font-size: 0.875rem;
1522
1320
  font-weight: 400;
1523
1321
  cursor: pointer;
@@ -1539,55 +1337,224 @@ var nn = class {
1539
1337
  color: var(--muted-foreground);
1540
1338
  pointer-events: none;
1541
1339
  }
1542
- `, Z = !1;
1543
- function un() {
1544
- if (Z || typeof document > "u") return;
1545
- Z = !0;
1340
+ `, V = !1;
1341
+ function nn() {
1342
+ if (V || typeof document > "u") return;
1343
+ V = !0;
1546
1344
  let e = document.createElement("style");
1547
- e.id = "vd-ui-vanilla", e.textContent = ln, document.head.appendChild(e);
1345
+ e.id = "vd-ui-vanilla", e.textContent = tn, document.head.appendChild(e);
1548
1346
  }
1549
1347
  //#endregion
1550
- //#region src/ui/toolbar.ts
1551
- function dn(e, t) {
1552
- let n = document.createElement("a");
1553
- n.href = `data:image/png;base64,${e}`, n.download = t, n.click();
1348
+ //#region src/ui/loading.ts
1349
+ function H(e) {
1350
+ let t = Math.max(0, Math.min(1, e));
1351
+ return t * t * (3 - 2 * t);
1554
1352
  }
1555
- var fn = class {
1556
- element;
1557
- screenshotBtn = null;
1558
- constructor(e) {
1559
- this.options = e, this.element = document.createElement("div"), this.element.className = "vd-toolbar";
1353
+ function rn(e, t, n, r, i, a) {
1354
+ let [o, s, c] = e, l = Math.cos(t), u = Math.sin(t), d = l * o + u * c, f = -u * o + l * c, p = Math.cos(n), m = Math.sin(n), h = p * s - m * f, g = m * s + p * f, _ = .55;
1355
+ return [
1356
+ r + d * a * _,
1357
+ i - h * a * _,
1358
+ g
1359
+ ];
1360
+ }
1361
+ function an(e, t, n) {
1362
+ e.beginPath(), e.moveTo(t[0], t[1]), e.lineTo(n[0], n[1]), e.strokeStyle = "#000", e.lineWidth = 2, e.stroke();
1363
+ }
1364
+ function on(e, t, n, r, i) {
1365
+ let a = t(n), o = t(r);
1366
+ an(e, a, [
1367
+ a[0] + (o[0] - a[0]) * i,
1368
+ a[1] + (o[1] - a[1]) * i,
1369
+ a[2]
1370
+ ]);
1371
+ }
1372
+ var U = [
1373
+ -1,
1374
+ -1,
1375
+ 1
1376
+ ], W = [
1377
+ 1,
1378
+ -1,
1379
+ 1
1380
+ ], G = [
1381
+ 1,
1382
+ -1,
1383
+ -1
1384
+ ], K = [
1385
+ -1,
1386
+ -1,
1387
+ -1
1388
+ ], q = [
1389
+ -1,
1390
+ 1,
1391
+ 1
1392
+ ], J = [
1393
+ 1,
1394
+ 1,
1395
+ 1
1396
+ ], Y = [
1397
+ 1,
1398
+ 1,
1399
+ -1
1400
+ ], X = [
1401
+ -1,
1402
+ 1,
1403
+ -1
1404
+ ], sn = [
1405
+ [U, W],
1406
+ [W, G],
1407
+ [G, K],
1408
+ [K, U],
1409
+ [U, q],
1410
+ [W, J],
1411
+ [G, Y],
1412
+ [K, X],
1413
+ [q, J],
1414
+ [J, Y],
1415
+ [Y, X],
1416
+ [X, q]
1417
+ ], cn = 400, ln = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif";
1418
+ function un() {
1419
+ let e = document.createElement("div");
1420
+ Object.assign(e.style, {
1421
+ position: "absolute",
1422
+ inset: "0",
1423
+ display: "flex",
1424
+ flexDirection: "column",
1425
+ alignItems: "center",
1426
+ justifyContent: "center",
1427
+ background: "#fff",
1428
+ zIndex: "20",
1429
+ opacity: "0",
1430
+ transition: "opacity 0.3s ease-in-out"
1431
+ });
1432
+ let t = document.createElement("canvas");
1433
+ Object.assign(t.style, {
1434
+ width: "100%",
1435
+ height: "100%",
1436
+ position: "absolute",
1437
+ inset: "0"
1438
+ });
1439
+ let n = document.createElement("div");
1440
+ Object.assign(n.style, {
1441
+ position: "absolute",
1442
+ top: "56%",
1443
+ left: "0",
1444
+ right: "0",
1445
+ textAlign: "center",
1446
+ pointerEvents: "none"
1447
+ });
1448
+ let r = document.createElement("span");
1449
+ Object.assign(r.style, {
1450
+ fontSize: "13px",
1451
+ fontWeight: "400",
1452
+ color: "#000",
1453
+ fontVariantNumeric: "tabular-nums",
1454
+ fontFamily: ln
1455
+ });
1456
+ let i = document.createElement("span");
1457
+ return Object.assign(i.style, {
1458
+ fontSize: "13px",
1459
+ color: "#000",
1460
+ fontFamily: ln
1461
+ }), i.textContent = Qe(), n.appendChild(r), n.appendChild(i), e.appendChild(t), e.appendChild(n), {
1462
+ overlay: e,
1463
+ canvas: t,
1464
+ pctEl: r,
1465
+ phaseEl: i
1466
+ };
1467
+ }
1468
+ var dn = class {
1469
+ overlay;
1470
+ canvas;
1471
+ ctx;
1472
+ pctEl;
1473
+ phaseEl;
1474
+ animationId = null;
1475
+ showTimerId = null;
1476
+ startTime;
1477
+ hidden = !1;
1478
+ visible = !1;
1479
+ constructor(e, t = {}) {
1480
+ this.startTime = performance.now();
1481
+ let n = un();
1482
+ this.overlay = n.overlay, this.canvas = n.canvas, this.pctEl = n.pctEl, this.phaseEl = n.phaseEl, e.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
1483
+ let r = t.showDelay ?? cn;
1484
+ this.showTimerId = setTimeout(() => {
1485
+ this.reveal();
1486
+ }, r);
1560
1487
  }
1561
- syncButton(e, t, n) {
1562
- if (t && e === null) {
1563
- let e = n();
1564
- return this.element.appendChild(e.element), e;
1488
+ get loadingTexts() {
1489
+ return {
1490
+ downloading: Qe(),
1491
+ rendering: nt()
1492
+ };
1493
+ }
1494
+ updateProgress(e, t) {
1495
+ this.hidden || (this.pctEl.textContent = `${Math.round(e)}%`, this.phaseEl.textContent = t === "" ? "" : ` \u00B7 ${t}`);
1496
+ }
1497
+ showError(e) {
1498
+ if (this.hidden = !1, this.animationId !== null && (cancelAnimationFrame(this.animationId), this.animationId = null), this.ctx !== null) {
1499
+ let e = Math.min(devicePixelRatio, 2), t = this.canvas.width / e, n = this.canvas.height / e;
1500
+ this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, t * e, n * e);
1565
1501
  }
1566
- return !t && e !== null ? (e.element.remove(), null) : e;
1502
+ this.pctEl.textContent = "", this.phaseEl.textContent = e, this.phaseEl.style.color = "#b91c1c", this.reveal();
1567
1503
  }
1568
- applySettings(e) {
1569
- this.screenshotBtn = this.syncButton(this.screenshotBtn, e.screenshot === !0, () => new K({
1570
- variant: "outline",
1571
- size: "icon",
1572
- label: at(),
1573
- icon: G.screenshot(),
1574
- onClick: () => {
1575
- this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: t }) => {
1576
- dn(e, t);
1577
- });
1504
+ hide() {
1505
+ if (!this.hidden) {
1506
+ if (this.hidden = !0, this.cancelShowTimer(), !this.visible) {
1507
+ this.destroy();
1508
+ return;
1578
1509
  }
1579
- }));
1510
+ this.overlay.style.opacity = "0", this.overlay.addEventListener("transitionend", () => {
1511
+ this.destroy();
1512
+ }, { once: !0 }), setTimeout(() => {
1513
+ this.destroy();
1514
+ }, 500);
1515
+ }
1516
+ }
1517
+ destroy() {
1518
+ this.cancelShowTimer(), this.animationId !== null && (cancelAnimationFrame(this.animationId), this.animationId = null), this.overlay.remove();
1519
+ }
1520
+ reveal() {
1521
+ this.hidden || this.visible || (this.visible = !0, this.overlay.style.opacity = "1");
1522
+ }
1523
+ cancelShowTimer() {
1524
+ this.showTimerId !== null && (clearTimeout(this.showTimerId), this.showTimerId = null);
1525
+ }
1526
+ sizeCanvas() {
1527
+ if (this.ctx === null) return;
1528
+ let e = Math.min(devicePixelRatio, 2), t = this.overlay.clientWidth || 440, n = this.overlay.clientHeight || 360;
1529
+ this.canvas.width = t * e, this.canvas.height = n * e, this.ctx.scale(e, e), this.ctx.lineCap = "round", this.ctx.lineJoin = "round";
1580
1530
  }
1581
- }, pn = class {
1531
+ tick = () => {
1532
+ this.hidden || (this.drawFrame(), this.animationId = requestAnimationFrame(this.tick));
1533
+ };
1534
+ drawFrame() {
1535
+ if (this.ctx === null) return;
1536
+ let e = this.canvas.width / Math.min(devicePixelRatio, 2), t = this.canvas.height / Math.min(devicePixelRatio, 2), n = (performance.now() - this.startTime) / 1e3;
1537
+ this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, e, t);
1538
+ let r = e / 2, i = t * .44, a = Math.min(e, t) * .08, o = (e) => rn(e, .785, .615, r, i, a), s = n % 6 / 6, c = sn.length, l;
1539
+ l = s < .35 ? H(s / .35) * c : s < .55 ? c : s < .9 ? (1 - H((s - .55) / .35)) * c : 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
1540
+ for (let e = 0; e < c && !(e >= l); e++) {
1541
+ let t = sn[e];
1542
+ if (t === void 0) continue;
1543
+ let n = Math.min(1, l - e);
1544
+ on(this.ctx, o, t[0], t[1], n);
1545
+ }
1546
+ this.ctx.shadowBlur = 0;
1547
+ }
1548
+ }, fn = class {
1582
1549
  element;
1583
1550
  arBtn = null;
1584
1551
  fullscreenBtn = null;
1585
1552
  onFullscreenChange;
1586
1553
  constructor(e) {
1587
- this.options = e, this.element = document.createElement("div"), this.element.className = "vd-action-bar", this.onFullscreenChange = () => {
1554
+ this.options = e, this.element = document.createElement("div"), this.onFullscreenChange = () => {
1588
1555
  if (this.fullscreenBtn === null) return;
1589
1556
  let e = document.fullscreenElement !== null;
1590
- this.fullscreenBtn.setIcon(e ? G.exitFullscreen() : G.fullscreen());
1557
+ this.fullscreenBtn.setIcon(e ? F.exitFullscreen() : F.fullscreen());
1591
1558
  }, document.addEventListener("fullscreenchange", this.onFullscreenChange);
1592
1559
  }
1593
1560
  syncButton(e, t, n) {
@@ -1598,19 +1565,19 @@ var fn = class {
1598
1565
  return !t && e !== null ? (e.element.remove(), null) : e;
1599
1566
  }
1600
1567
  applySettings(e) {
1601
- this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new K({
1568
+ this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new I({
1602
1569
  variant: "outline",
1603
1570
  size: "icon",
1604
1571
  label: Oe(),
1605
- icon: G.ar(),
1572
+ icon: F.ar(),
1606
1573
  onClick: () => {
1607
1574
  this.options.onAr?.();
1608
1575
  }
1609
- })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new K({
1576
+ })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new I({
1610
1577
  variant: "outline",
1611
1578
  size: "icon",
1612
1579
  label: Je(),
1613
- icon: G.fullscreen(),
1580
+ icon: F.fullscreen(),
1614
1581
  onClick: () => {
1615
1582
  this.options.onFullscreen?.();
1616
1583
  }
@@ -1619,7 +1586,7 @@ var fn = class {
1619
1586
  destroy() {
1620
1587
  document.removeEventListener("fullscreenchange", this.onFullscreenChange);
1621
1588
  }
1622
- }, Q = .5, mn = class e {
1589
+ }, Z = .5, pn = class e {
1623
1590
  element;
1624
1591
  constructor(t, n) {
1625
1592
  this.element = Object.assign(document.createElement("div"), { className: "vd-camera-controls" });
@@ -1634,65 +1601,65 @@ var fn = class {
1634
1601
  }
1635
1602
  let c = i + e;
1636
1603
  c > 180 || c < 0 ? (i = c > 180 ? 360 - c : -c, o = (o + 180) % 360, t.tilt(i).rotate(r + o).set()) : (i = c, t.tilt(i).set());
1637
- }, u = new K({
1604
+ }, u = new I({
1638
1605
  variant: "outline",
1639
1606
  size: "icon",
1640
- label: _t(),
1641
- icon: G.zoomOut(),
1607
+ label: vt(),
1608
+ icon: F.zoomOut(),
1642
1609
  onClick: () => {
1643
1610
  a = s(a - 10), t.zoom(a).set();
1644
1611
  }
1645
- }), d = new K({
1612
+ }), d = new I({
1646
1613
  variant: "outline",
1647
1614
  size: "icon",
1648
- label: pt(),
1649
- icon: G.zoomIn(),
1615
+ label: mt(),
1616
+ icon: F.zoomIn(),
1650
1617
  onClick: () => {
1651
1618
  a = s(a + 10), t.zoom(a).set();
1652
1619
  }
1653
- }), f = new K({
1620
+ }), f = new I({
1654
1621
  variant: "outline",
1655
1622
  size: "icon",
1656
- label: kt(),
1657
- icon: G.tiltUp(),
1623
+ label: At(),
1624
+ icon: F.tiltUp(),
1658
1625
  onClick: () => {
1659
1626
  l(-15);
1660
1627
  }
1661
- }), p = new K({
1628
+ }), p = new I({
1662
1629
  variant: "outline",
1663
1630
  size: "icon",
1664
- label: xt(),
1665
- icon: G.rotateLeft(),
1631
+ label: St(),
1632
+ icon: F.rotateLeft(),
1666
1633
  onClick: () => {
1667
1634
  r = c(r - 15), t.rotate(r + o).set();
1668
1635
  }
1669
- }), m = new K({
1636
+ }), m = new I({
1670
1637
  variant: "outline",
1671
1638
  size: "icon",
1672
- label: lt(),
1673
- icon: G.reset(),
1639
+ label: ut(),
1640
+ icon: F.reset(),
1674
1641
  onClick: () => {
1675
1642
  o = 0, t.reset();
1676
1643
  }
1677
- }), h = new K({
1644
+ }), h = new I({
1678
1645
  variant: "outline",
1679
1646
  size: "icon",
1680
- label: Tt(),
1681
- icon: G.rotateRight(),
1647
+ label: Et(),
1648
+ icon: F.rotateRight(),
1682
1649
  onClick: () => {
1683
1650
  r = c(r + 15), t.rotate(r + o).set();
1684
1651
  }
1685
- }), g = new K({
1652
+ }), g = new I({
1686
1653
  variant: "outline",
1687
1654
  size: "icon",
1688
- label: Nt(),
1689
- icon: G.tiltDown(),
1655
+ label: Pt(),
1656
+ icon: F.tiltDown(),
1690
1657
  onClick: () => {
1691
1658
  l(15);
1692
1659
  }
1693
1660
  }), _ = (e) => {
1694
1661
  let t = n.limits;
1695
- t !== void 0 && (u.element.disabled = t.minZoom !== void 0 && e.zoom <= t.minZoom + Q, d.element.disabled = t.maxZoom !== void 0 && e.zoom >= t.maxZoom - Q, f.element.disabled = t.minTilt !== void 0 && e.tilt <= t.minTilt + Q, g.element.disabled = t.maxTilt !== void 0 && e.tilt >= t.maxTilt - Q, p.element.disabled = t.minRotate !== void 0 && e.rotation <= t.minRotate + Q, h.element.disabled = t.maxRotate !== void 0 && e.rotation >= t.maxRotate - Q);
1662
+ t !== void 0 && (u.element.disabled = t.minZoom !== void 0 && e.zoom <= t.minZoom + Z, d.element.disabled = t.maxZoom !== void 0 && e.zoom >= t.maxZoom - Z, f.element.disabled = t.minTilt !== void 0 && e.tilt <= t.minTilt + Z, g.element.disabled = t.maxTilt !== void 0 && e.tilt >= t.maxTilt - Z, p.element.disabled = t.minRotate !== void 0 && e.rotation <= t.minRotate + Z, h.element.disabled = t.maxRotate !== void 0 && e.rotation >= t.maxRotate - Z);
1696
1663
  };
1697
1664
  n.onChange((e) => {
1698
1665
  r = e.rotation - o, i = e.tilt, a = e.zoom, _(e);
@@ -1714,17 +1681,17 @@ var fn = class {
1714
1681
  ]) o.element.classList.add(`vd-dpad-${s}`), a.appendChild(o.element);
1715
1682
  return a;
1716
1683
  }
1717
- }, hn = 5;
1718
- function $(e) {
1684
+ }, mn = 5;
1685
+ function Q(e) {
1719
1686
  let t = e.replace(/([A-Z])/g, " $1").trim();
1720
1687
  return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
1721
1688
  }
1722
- function gn(e, t, n, r, i) {
1689
+ function hn(e, t, n, r, i) {
1723
1690
  let a = document.createElement("div");
1724
1691
  a.className = "vd-attribute", a.dataset.name = e.name;
1725
1692
  let o = document.createElement("span");
1726
- o.className = "vd-attribute-label", o.textContent = $(e.name), a.appendChild(o);
1727
- let s = e.values.find((n) => t.getValue(e.name, n)?.isSelected === !0), c = e.values.map($), l = e.values.length <= hn ? new an(e.values, s, c) : new on(e.name, e.values, $(e.name), s, c);
1693
+ o.className = "vd-attribute-label", o.textContent = Q(e.name), a.appendChild(o);
1694
+ let s = e.values.find((n) => t.getValue(e.name, n)?.isSelected === !0), c = e.values.map(Q), l = e.values.length <= mn ? new Zt(e.values, s, c) : new Qt(e.name, e.values, Q(e.name), s, c);
1728
1695
  return l.onSelect((t) => {
1729
1696
  n.dispatch("ui:select", {
1730
1697
  attribute: e.name,
@@ -1739,56 +1706,60 @@ function gn(e, t, n, r, i) {
1739
1706
  }
1740
1707
  //#endregion
1741
1708
  //#region src/ui/styles.ts
1742
- var _n = Y.fontFamily.sans.join(", "), vn = `
1709
+ var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display: flex;\n z-index: 10;\n", _n = `
1743
1710
  /* Override browser's default black fullscreen backdrop */
1744
1711
  .vd-container:fullscreen {
1745
1712
  background: oklch(100% 0 0);
1746
1713
  }
1747
1714
 
1748
- /* Top-right: screenshot + camera controls */
1749
- .vd-toolbar {
1750
- position: absolute;
1751
- inset-block-start: ${J[3]};
1752
- inset-inline-end: ${J[3]};
1753
- display: flex;
1715
+ /* Layout slots — four corners */
1716
+ .vd-slot-top-right {
1717
+ ${$}
1718
+ inset-block-start: ${R[3]};
1719
+ inset-inline-end: ${R[3]};
1754
1720
  flex-direction: column;
1755
1721
  align-items: flex-end;
1756
- gap: ${J[1.5]};
1757
- z-index: 10;
1722
+ gap: ${R[1.5]};
1758
1723
  }
1759
1724
 
1760
- /* Bottom-right: AR + fullscreen */
1761
- .vd-action-bar {
1762
- position: absolute;
1763
- inset-block-end: ${J[3]};
1764
- inset-inline-end: ${J[3]};
1765
- display: flex;
1725
+ .vd-slot-bottom-left {
1726
+ ${$}
1727
+ inset-block-end: ${R[3]};
1728
+ inset-inline-start: ${R[3]};
1729
+ flex-direction: column;
1730
+ align-items: flex-start;
1731
+ gap: ${R[1.5]};
1732
+ }
1733
+
1734
+ .vd-slot-bottom-right {
1735
+ ${$}
1736
+ inset-block-end: ${R[3]};
1737
+ inset-inline-end: ${R[3]};
1766
1738
  flex-direction: row;
1767
- gap: ${J[1.5]};
1768
- z-index: 10;
1739
+ gap: ${R[1.5]};
1769
1740
  }
1770
1741
 
1771
- /* Camera controls card inside .vd-toolbar */
1742
+ /* Component styles — no positioning */
1772
1743
  .vd-camera-controls {
1773
1744
  display: flex;
1774
1745
  flex-direction: column;
1775
- gap: ${J[1]};
1776
- background: color-mix(in oklch, ${q.white} 85%, transparent);
1746
+ gap: ${R[1]};
1747
+ background: color-mix(in oklch, ${L.white} 85%, transparent);
1777
1748
  backdrop-filter: blur(8px);
1778
- border-radius: ${J[2]};
1779
- padding: ${J[2]};
1749
+ border-radius: ${R[2]};
1750
+ padding: ${R[2]};
1780
1751
  }
1781
1752
 
1782
1753
  .vd-zoom {
1783
1754
  display: flex;
1784
- gap: ${J[.5]};
1755
+ gap: ${R[.5]};
1785
1756
  }
1786
1757
 
1787
1758
  .vd-dpad {
1788
1759
  display: grid;
1789
- grid-template-columns: repeat(3, ${J[9]});
1790
- grid-template-rows: repeat(3, ${J[9]});
1791
- gap: ${J[.5]};
1760
+ grid-template-columns: repeat(3, ${R[9]});
1761
+ grid-template-rows: repeat(3, ${R[9]});
1762
+ gap: ${R[.5]};
1792
1763
  }
1793
1764
 
1794
1765
  .vd-dpad-up { grid-column: 2; grid-row: 1; }
@@ -1797,49 +1768,53 @@ var _n = Y.fontFamily.sans.join(", "), vn = `
1797
1768
  .vd-dpad-right { grid-column: 3; grid-row: 2; }
1798
1769
  .vd-dpad-down { grid-column: 2; grid-row: 3; }
1799
1770
 
1800
- /* Bottom-left: attribute selectors */
1801
1771
  .vd-attributes {
1802
- position: absolute;
1803
- inset-block-end: ${J[3]};
1804
- inset-inline-start: ${J[3]};
1805
1772
  display: flex;
1806
1773
  flex-direction: column;
1807
- gap: ${J[2]};
1808
- background: color-mix(in oklch, ${q.white} 85%, transparent);
1774
+ gap: ${R[2]};
1775
+ background: color-mix(in oklch, ${L.white} 85%, transparent);
1809
1776
  backdrop-filter: blur(8px);
1810
- border-radius: ${J[2]};
1811
- padding: ${J[2]};
1812
- font-family: ${_n};
1813
- z-index: 10;
1777
+ border-radius: ${R[2]};
1778
+ padding: ${R[2]};
1779
+ font-family: ${gn};
1814
1780
  }
1815
1781
 
1816
1782
  .vd-attribute {
1817
1783
  display: flex;
1818
1784
  flex-direction: column;
1819
- gap: ${J[1]};
1785
+ gap: ${R[1]};
1820
1786
  }
1821
1787
 
1822
1788
  .vd-attribute-label {
1823
- font-size: ${Y.fontSize.xs};
1824
- font-weight: ${Y.fontWeight.medium};
1825
- color: ${q.neutral[900]};
1826
- font-family: ${_n};
1789
+ font-size: ${z.fontSize.xs};
1790
+ font-weight: ${z.fontWeight.medium};
1791
+ color: ${L.neutral[900]};
1792
+ font-family: ${gn};
1827
1793
  }
1828
1794
 
1829
1795
  `;
1830
- function yn() {
1831
- if (un(), document.getElementById("vd-styles") !== null) return;
1796
+ function vn() {
1797
+ if (nn(), document.getElementById("vd-styles") !== null) return;
1832
1798
  let e = document.createElement("style");
1833
- e.id = "vd-styles", e.textContent = vn, document.head.appendChild(e);
1799
+ e.id = "vd-styles", e.textContent = _n, document.head.appendChild(e);
1834
1800
  }
1835
1801
  //#endregion
1836
1802
  //#region src/ui/standard-interface.ts
1803
+ function yn(e, t) {
1804
+ let n = document.createElement("a");
1805
+ n.href = `data:image/png;base64,${e}`, n.download = t, n.click();
1806
+ }
1837
1807
  var bn = class {
1838
1808
  options;
1839
1809
  settings = {};
1840
1810
  container = null;
1841
1811
  loading = null;
1842
- toolbar = null;
1812
+ slots = {
1813
+ topRight: null,
1814
+ bottomLeft: null,
1815
+ bottomRight: null
1816
+ };
1817
+ screenshotBtn = null;
1843
1818
  actionBar = null;
1844
1819
  cameraControls = null;
1845
1820
  attributes = null;
@@ -1847,12 +1822,12 @@ var bn = class {
1847
1822
  this.options = e;
1848
1823
  }
1849
1824
  attach(e) {
1850
- yn(), this.container = e, this.loading = new Vt(e), this.toolbar = new fn({ snapshotApi: this.options.snapshotApi }), this.toolbar.applySettings(this.settings), e.appendChild(this.toolbar.element), this.actionBar = new pn({
1825
+ vn(), this.container = e, this.loading = new dn(e), this.slots.topRight = this.createSlot(e, "vd-slot-top-right"), this.slots.bottomLeft = this.createSlot(e, "vd-slot-bottom-left"), this.slots.bottomRight = this.createSlot(e, "vd-slot-bottom-right"), this.actionBar = new fn({
1851
1826
  onAr: this.options.onAr,
1852
1827
  onFullscreen: () => {
1853
1828
  document.fullscreenElement === null ? this.container?.requestFullscreen() : document.exitFullscreen();
1854
1829
  }
1855
- }), this.actionBar.applySettings(this.settings), e.appendChild(this.actionBar.element);
1830
+ }), this.actionBar.applySettings(this.settings), this.slots.bottomRight.appendChild(this.actionBar.element), this.syncScreenshotButton(), this.placeScreenshotButton();
1856
1831
  }
1857
1832
  onReady() {
1858
1833
  this.loading?.hide(), this.loading = null, this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.attributes !== null && (this.attributes.style.display = "flex");
@@ -1864,20 +1839,43 @@ var bn = class {
1864
1839
  this.loading?.showError(e);
1865
1840
  }
1866
1841
  applyViewerSettings(e) {
1867
- this.settings = e, e.language !== void 0 && A(e.language), this.toolbar?.applySettings(e), this.actionBar?.applySettings(e), this.cameraControls !== null && (this.cameraControls.element.style.display = e.cameraControls === !0 ? "flex" : "none");
1842
+ this.settings = e, e.language !== void 0 && j(e.language), this.syncScreenshotButton(), this.actionBar?.applySettings(e), this.cameraControls !== null && (this.cameraControls.element.style.display = e.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
1868
1843
  }
1869
1844
  renderAttributeControls(e, t) {
1870
- if (!(this.container === null || this.toolbar === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.attributes?.remove(), this.attributes = null, this.settings.cameraControls === !0 && (this.cameraControls = new mn(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.toolbar.element.appendChild(this.cameraControls.element)), t.length !== 0)) {
1845
+ if (!(this.container === null || this.slots.topRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.attributes?.remove(), this.attributes = null, this.settings.cameraControls === !0 && (this.cameraControls = new pn(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), t.length !== 0)) {
1871
1846
  this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes", this.attributes.style.display = "none";
1872
- for (let n of t) this.attributes.appendChild(gn(n, e, this.options.eventBus, this.options.onSelect, this.options.onSubscribe));
1873
- this.container.appendChild(this.attributes);
1847
+ for (let n of t) this.attributes.appendChild(hn(n, e, this.options.eventBus, this.options.onSelect, this.options.onSubscribe));
1848
+ this.slots.bottomLeft.appendChild(this.attributes);
1874
1849
  }
1875
1850
  }
1876
1851
  get viewerSettings() {
1877
1852
  return this.settings;
1878
1853
  }
1879
1854
  destroy() {
1880
- this.loading?.destroy(), this.toolbar?.element.remove(), this.actionBar?.destroy(), this.actionBar?.element.remove(), this.cameraControls?.element.remove(), this.attributes?.remove(), this.container = null;
1855
+ this.loading?.destroy(), this.screenshotBtn?.element.remove(), this.actionBar?.destroy(), this.actionBar?.element.remove(), this.cameraControls?.element.remove(), this.attributes?.remove();
1856
+ for (let e of Object.values(this.slots)) e?.remove();
1857
+ this.container = null;
1858
+ }
1859
+ createSlot(e, t) {
1860
+ let n = document.createElement("div");
1861
+ return n.className = t, e.appendChild(n), n;
1862
+ }
1863
+ syncScreenshotButton() {
1864
+ let e = this.settings.screenshot === !0;
1865
+ e && this.screenshotBtn === null && (this.screenshotBtn = new I({
1866
+ variant: "outline",
1867
+ size: "icon",
1868
+ label: ot(),
1869
+ icon: F.screenshot(),
1870
+ onClick: () => {
1871
+ this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: t }) => {
1872
+ yn(e, t);
1873
+ });
1874
+ }
1875
+ })), !e && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
1876
+ }
1877
+ placeScreenshotButton() {
1878
+ this.screenshotBtn === null || this.slots.topRight === null || (this.cameraControls === null ? this.slots.topRight.appendChild(this.screenshotBtn.element) : this.cameraControls.element.appendChild(this.screenshotBtn.element));
1881
1879
  }
1882
1880
  }, xn = class {
1883
1881
  attributes;
@@ -1904,7 +1902,7 @@ var bn = class {
1904
1902
  attribute: e,
1905
1903
  value: t
1906
1904
  });
1907
- }), this.snapshotApi = new _e(t), this.cameraApi = new me(t), this.cameraPositionApi = new he(), this.eventBus = new ve(), this.qrModal = new cn(), this.readyStateTracker = new _(() => {
1905
+ }), this.snapshotApi = new C(t), this.cameraApi = new x(t), this.cameraPositionApi = new me(), this.eventBus = new he(), this.qrModal = new en(), this.readyStateTracker = new _(() => {
1908
1906
  let e = this.readyCallbacks;
1909
1907
  this.readyCallbacks = [];
1910
1908
  for (let t of e) t(this);
@@ -1993,4 +1991,4 @@ var bn = class {
1993
1991
  }
1994
1992
  };
1995
1993
  //#endregion
1996
- export { ee as Attribute, v as AttributeValue, me as Camera, t as ERROR_CODES, ge as Photo, _e as Snapshot, xn as VirtualdisplayClient, n as VirtualdisplayError, h as enableDebugMode, g as isDebugMode, m as logger };
1994
+ export { ee as Attribute, v as AttributeValue, x as Camera, t as ERROR_CODES, S as Photo, C as Snapshot, xn as VirtualdisplayClient, n as VirtualdisplayError, h as enableDebugMode, g as isDebugMode, m as logger };