@oddin-gg/havik-player 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -142,7 +142,7 @@ function ae(e, t) {
142
142
  t?.addEventListener("abort", a, { once: !0 });
143
143
  });
144
144
  }
145
- async function oe(e, t, r) {
145
+ async function v(e, t, r) {
146
146
  let i = ee(t), a = Date.now(), s = i.timeoutMs == null ? Infinity : a + i.timeoutMs, c = 0, l;
147
147
  for (;;) {
148
148
  if (r?.aborted) throw new n("ABORTED", 0, "wait-for-live aborted");
@@ -168,21 +168,21 @@ async function oe(e, t, r) {
168
168
  }
169
169
  //#endregion
170
170
  //#region src/core/resolve.ts
171
- async function v(e) {
171
+ async function y(e) {
172
172
  if (!e.matchUrn || typeof e.matchUrn != "string") throw new n("INVALID_URN", 0, "resolveStream: a non-empty matchUrn is required");
173
173
  let t = await u(c(e.baseUrl, `/v1/playback/${encodeURIComponent(e.matchUrn)}`), {
174
174
  credential: e.credential,
175
175
  signal: e.signal,
176
176
  apiHeaders: e.apiHeaders
177
177
  });
178
- if (!t.ok) throw await se(t);
179
- return le(await t.json(), e.matchUrn);
178
+ if (!t.ok) throw await oe(t);
179
+ return ce(await t.json(), e.matchUrn);
180
180
  }
181
- function y(e) {
182
- let t = () => v(e);
183
- return e.waitForLive ? oe(t, e.waitForLive, e.signal) : t();
181
+ function b(e) {
182
+ let t = () => y(e);
183
+ return e.waitForLive ? v(t, e.waitForLive, e.signal) : t();
184
184
  }
185
- async function se(e) {
185
+ async function oe(e) {
186
186
  let t = l(e.headers.get("retry-after")), i = e.headers.get("x-request-id") ?? e.headers.get("x-amzn-requestid") ?? void 0, a = e.statusText || `HTTP ${e.status}`, o, s;
187
187
  try {
188
188
  let t = await e.json();
@@ -198,7 +198,7 @@ async function se(e) {
198
198
  liveStartsAtMs: s
199
199
  });
200
200
  }
201
- var ce = /* @__PURE__ */ new Set([
201
+ var se = /* @__PURE__ */ new Set([
202
202
  "matchUrn",
203
203
  "protocol",
204
204
  "drmEnabled",
@@ -209,7 +209,7 @@ var ce = /* @__PURE__ */ new Set([
209
209
  "expiresAt",
210
210
  "analytics"
211
211
  ]);
212
- function b(e, t) {
212
+ function x(e, t) {
213
213
  let r;
214
214
  try {
215
215
  r = new URL(t);
@@ -219,36 +219,36 @@ function b(e, t) {
219
219
  if (r.protocol !== "https:" && r.protocol !== "http:") throw new n("INTERNAL", 0, `playback ${e} has a disallowed scheme: ${r.protocol}`);
220
220
  return t;
221
221
  }
222
- function le(e, t) {
222
+ function ce(e, t) {
223
223
  if (!e.manifestUrl) throw new n("INTERNAL", 0, "playback response is missing manifestUrl");
224
224
  let r = e.drmEnabled ?? !!e.drm, i = {
225
225
  matchUrn: e.matchUrn ?? t,
226
226
  protocol: "hls",
227
227
  drmEnabled: r,
228
- manifestUrl: b("manifestUrl", e.manifestUrl),
228
+ manifestUrl: x("manifestUrl", e.manifestUrl),
229
229
  serverTime: e.serverTime ?? ""
230
230
  };
231
231
  if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid && (i.analytics = { sid: e.analytics.sid }), r && e.drm) {
232
232
  let t = {};
233
- e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: b("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
234
- licenseUrl: b("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
235
- certificateUrl: b("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
233
+ e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: x("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
234
+ licenseUrl: x("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
235
+ certificateUrl: x("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
236
236
  }), (t.widevine || t.fairplay) && (i.drm = t);
237
237
  }
238
238
  let a = {};
239
- for (let [t, n] of Object.entries(e)) ce.has(t) || (a[t] = n);
239
+ for (let [t, n] of Object.entries(e)) se.has(t) || (a[t] = n);
240
240
  return Object.keys(a).length > 0 && (i.extensions = a), i;
241
241
  }
242
242
  //#endregion
243
243
  //#region src/core/fullscreen.ts
244
- function x(e) {
244
+ function S(e) {
245
245
  return e.ownerDocument ?? document;
246
246
  }
247
- function S(e) {
247
+ function le(e) {
248
248
  return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
249
249
  }
250
250
  function C(e, t) {
251
- let n = S(x(e));
251
+ let n = le(S(e));
252
252
  return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
253
253
  }
254
254
  async function w(e, t) {
@@ -264,7 +264,7 @@ async function T(e, t) {
264
264
  n.webkitExitFullscreen?.();
265
265
  return;
266
266
  }
267
- let r = x(e), i = S(r);
267
+ let r = S(e), i = le(r);
268
268
  i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
269
269
  }
270
270
  //#endregion
@@ -551,7 +551,7 @@ var N = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
551
551
  function xe(e) {
552
552
  return e.startsWith("com.widevine");
553
553
  }
554
- function Se(e, t) {
554
+ function P(e, t) {
555
555
  if (!xe(e)) return t;
556
556
  let n = (e, t) => {
557
557
  let n = e.videoCapabilities;
@@ -568,8 +568,8 @@ function Se(e, t) {
568
568
  })));
569
569
  return [...t, ...r];
570
570
  }
571
- function Ce(e) {
572
- return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, Se(t, n)).then((t) => ({
571
+ function Se(e) {
572
+ return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, P(t, n)).then((t) => ({
573
573
  keySystem: t.keySystem,
574
574
  getConfiguration: () => t.getConfiguration(),
575
575
  createMediaKeys: () => be(e, t)
@@ -577,11 +577,11 @@ function Ce(e) {
577
577
  }
578
578
  //#endregion
579
579
  //#region src/core/drm/support.ts
580
- var we = 5e3, Te = "video/mp4; codecs=\"avc1.42E01E\"", P = "audio/mp4; codecs=\"mp4a.40.2\"", Ee = {
580
+ var Ce = 5e3, F = "video/mp4; codecs=\"avc1.42E01E\"", I = "audio/mp4; codecs=\"mp4a.40.2\"", we = {
581
581
  widevine: ["com.widevine.alpha"],
582
582
  fairplay: ["com.apple.fps"]
583
583
  };
584
- function De(e) {
584
+ function Te(e) {
585
585
  return e === "fairplay" ? [{
586
586
  initDataTypes: [
587
587
  "sinf",
@@ -589,30 +589,30 @@ function De(e) {
589
589
  "cenc"
590
590
  ],
591
591
  videoCapabilities: [{
592
- contentType: Te,
592
+ contentType: F,
593
593
  robustness: "",
594
594
  encryptionScheme: "cbcs"
595
595
  }],
596
596
  audioCapabilities: [{
597
- contentType: P,
597
+ contentType: I,
598
598
  robustness: "",
599
599
  encryptionScheme: "cbcs"
600
600
  }]
601
- }] : Se("com.widevine.alpha", [{
601
+ }] : P("com.widevine.alpha", [{
602
602
  initDataTypes: ["cenc"],
603
603
  videoCapabilities: [{
604
- contentType: Te,
604
+ contentType: F,
605
605
  robustness: "SW_SECURE_DECODE",
606
606
  encryptionScheme: "cbcs"
607
607
  }],
608
608
  audioCapabilities: [{
609
- contentType: P,
609
+ contentType: I,
610
610
  robustness: "SW_SECURE_CRYPTO",
611
611
  encryptionScheme: "cbcs"
612
612
  }]
613
613
  }]);
614
614
  }
615
- function F(e, t) {
615
+ function L(e, t) {
616
616
  return new Promise((n, r) => {
617
617
  let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
618
618
  e.then((e) => {
@@ -622,8 +622,8 @@ function F(e, t) {
622
622
  });
623
623
  });
624
624
  }
625
- async function Oe(e = {}) {
626
- let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? we, r = {};
625
+ async function Ee(e = {}) {
626
+ let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ce, r = {};
627
627
  if (typeof window < "u" && window.isSecureContext === !1) return {
628
628
  verdict: "insecure-context",
629
629
  detail: r
@@ -635,7 +635,7 @@ async function Oe(e = {}) {
635
635
  };
636
636
  let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
637
637
  for (let e of t) {
638
- let t = Ee[e];
638
+ let t = we[e];
639
639
  if (!t) {
640
640
  r[e] = "unknown system";
641
641
  continue;
@@ -646,7 +646,7 @@ async function Oe(e = {}) {
646
646
  break;
647
647
  }
648
648
  try {
649
- return await F((await F(i(n, De(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
649
+ return await L((await L(i(n, Te(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
650
650
  verdict: "supported",
651
651
  system: e,
652
652
  detail: r
@@ -670,38 +670,49 @@ async function Oe(e = {}) {
670
670
  }
671
671
  //#endregion
672
672
  //#region src/core/manifest.ts
673
- var ke = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
674
- function Ae(e) {
675
- return ke.test(e);
673
+ var De = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
674
+ function Oe(e) {
675
+ return De.test(e);
676
+ }
677
+ //#endregion
678
+ //#region src/core/env.ts
679
+ var R = {
680
+ integration: "https://feed-dev.oddin-video.gg",
681
+ production: "https://feed.oddin-video.gg"
682
+ };
683
+ function z(e) {
684
+ let t = Object.prototype.hasOwnProperty.call(R, e) ? R[e] : void 0;
685
+ if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
686
+ return t;
676
687
  }
677
688
  //#endregion
678
689
  //#region src/core/stats.ts
679
- var I = { droppedFrames: 0 };
680
- function L(e) {
690
+ var B = { droppedFrames: 0 };
691
+ function V(e) {
681
692
  try {
682
693
  return new URL(e).host;
683
694
  } catch {
684
695
  return "";
685
696
  }
686
697
  }
687
- var je = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
688
- function Me(e) {
698
+ var ke = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
699
+ function Ae(e) {
689
700
  if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
690
701
  let t = "", n = -1, r = performance.getEntriesByType("resource");
691
- for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || je.test(i.name)) && i.startTime >= n) {
692
- let e = L(i.name);
702
+ for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || ke.test(i.name)) && i.startTime >= n) {
703
+ let e = V(i.name);
693
704
  e && (t = e, n = i.startTime);
694
705
  }
695
706
  return t;
696
707
  }
697
- function R(e) {
708
+ function H(e) {
698
709
  let t = e.getVideoPlaybackQuality?.();
699
710
  return {
700
711
  dropped: t?.droppedVideoFrames ?? 0,
701
712
  totalFrames: t?.totalVideoFrames ?? 0
702
713
  };
703
714
  }
704
- function Ne(e, t) {
715
+ function je(e, t) {
705
716
  let n = [
706
717
  ["playing", () => t("playing")],
707
718
  ["waiting", () => t("buffering")],
@@ -718,7 +729,7 @@ function Ne(e, t) {
718
729
  }
719
730
  //#endregion
720
731
  //#region src/core/engine/native.ts
721
- function Pe(e) {
732
+ function Me(e) {
722
733
  try {
723
734
  let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
724
735
  return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
@@ -726,15 +737,15 @@ function Pe(e) {
726
737
  return;
727
738
  }
728
739
  }
729
- function z(e) {
740
+ function U(e) {
730
741
  return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
731
742
  }
732
- function B() {
743
+ function W() {
733
744
  if (typeof window > "u") return !1;
734
745
  let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
735
746
  return e || t;
736
747
  }
737
- var V = class {
748
+ var G = class {
738
749
  name = "native";
739
750
  deps;
740
751
  onLoaded;
@@ -770,7 +781,7 @@ var V = class {
770
781
  type: "error",
771
782
  error: new n("INTERNAL", 0, "native HLS playback error"),
772
783
  fatal: !0
773
- }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Fe(t.manifestUrl, t.analytics?.sid), e.load();
784
+ }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Ne(t.manifestUrl, t.analytics?.sid), e.load();
774
785
  }
775
786
  startLoad() {
776
787
  this.loadStarted || (this.loadStarted = !0, this.restorePreload());
@@ -792,7 +803,7 @@ var V = class {
792
803
  });
793
804
  this.onEncrypted = (n) => {
794
805
  let i = n;
795
- i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Pe(i.initData), (async () => {
806
+ i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Me(i.initData), (async () => {
796
807
  try {
797
808
  let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
798
809
  initDataTypes: [i.initDataType],
@@ -887,11 +898,11 @@ var V = class {
887
898
  e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
888
899
  }
889
900
  getStats() {
890
- let e = this.deps.video, t = R(e), n = {
901
+ let e = this.deps.video, t = H(e), n = {
891
902
  droppedFrames: t.dropped,
892
903
  decodedFrames: t.totalFrames
893
904
  };
894
- return this.cdnHost ||= Me(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity && (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)), n;
905
+ return this.cdnHost ||= Ae(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity && (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)), n;
895
906
  }
896
907
  stop() {
897
908
  try {
@@ -910,29 +921,29 @@ var V = class {
910
921
  } catch {}
911
922
  }
912
923
  };
913
- function Fe(e, t) {
924
+ function Ne(e, t) {
914
925
  return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
915
926
  }
916
927
  //#endregion
917
928
  //#region src/core/engine/hls.ts
918
- function Ie() {
929
+ function Pe() {
919
930
  return e.isSupported();
920
931
  }
921
- var Le = 3, Re = 5, ze = 3, Be = 3e4, Ve = 12e3, He = 3e3, H = 6e3, Ue = 5e3, We = 4e3, Ge = 2, Ke = 5, qe = 2, Je = 2, Ye = 2e3, Xe = 3e4, Ze = 2, Qe = 9, $e = .5, et = 64;
922
- function tt(e) {
932
+ var Fe = 3, Ie = 5, Le = 3, Re = 3e4, ze = 12e3, Be = 3e3, K = 6e3, Ve = 5e3, He = 4e3, Ue = 2, We = 5, Ge = 2, Ke = 2, qe = 2e3, Je = 3e4, Ye = 2, Xe = 9, Ze = .5, Qe = 64;
933
+ function $e(e) {
923
934
  if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
924
935
  delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
925
936
  return;
926
937
  }
927
- e.liveSyncDuration ??= Ze;
928
- let t = Math.max(12, e.liveSyncDuration + Qe);
929
- (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), nt(e, e.liveSyncDuration);
938
+ e.liveSyncDuration ??= Ye;
939
+ let t = Math.max(12, e.liveSyncDuration + Xe);
940
+ (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), et(e, e.liveSyncDuration);
930
941
  }
931
- function nt(e, t) {
942
+ function et(e, t) {
932
943
  let n = (e, t, n) => Math.min(n, Math.max(t, e));
933
944
  e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
934
945
  }
935
- var U = class {
946
+ var q = class {
936
947
  name = "hls";
937
948
  hls = null;
938
949
  deps;
@@ -991,7 +1002,7 @@ var U = class {
991
1002
  this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
992
1003
  }
993
1004
  async load() {
994
- let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = z(r) && B(), o = !!e.drm?.widevine?.licenseUrl && !a;
1005
+ let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = U(r) && W(), o = !!e.drm?.widevine?.licenseUrl && !a;
995
1006
  if (e.drmEnabled && !o) {
996
1007
  i({
997
1008
  type: "error",
@@ -1023,7 +1034,7 @@ var U = class {
1023
1034
  }
1024
1035
  this.loadSuspended = !0;
1025
1036
  }
1026
- }, Ue));
1037
+ }, Ve));
1027
1038
  }
1028
1039
  resumeLoading() {
1029
1040
  if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
@@ -1055,7 +1066,7 @@ var U = class {
1055
1066
  let t = e.liveSyncPosition;
1056
1067
  if (typeof t != "number" || !Number.isFinite(t)) return;
1057
1068
  let { video: n } = this.deps;
1058
- n.currentTime <= t + $e || (n.currentTime = t);
1069
+ n.currentTime <= t + Ze || (n.currentTime = t);
1059
1070
  }
1060
1071
  startHls() {
1061
1072
  let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
@@ -1079,7 +1090,7 @@ var U = class {
1079
1090
  videoEncryptionScheme: "cbcs",
1080
1091
  audioEncryptionScheme: "cbcs"
1081
1092
  },
1082
- ...M() ? { requestMediaKeySystemAccessFunc: Ce(t) } : {},
1093
+ ...M() ? { requestMediaKeySystemAccessFunc: Se(t) } : {},
1083
1094
  licenseXhrSetup: (e, t) => {
1084
1095
  e.open("POST", this.licenseUrl ?? t, !0), e.setRequestHeader("x-api-key", r.apiKey), e.setRequestHeader("X-Match-Urn", n.matchUrn), e.setRequestHeader("X-Device-Id", i), a && e.setRequestHeader("X-User-Id", a), this.licenseRequested = !0;
1085
1096
  let o = performance.now();
@@ -1095,7 +1106,7 @@ var U = class {
1095
1106
  } } : {},
1096
1107
  ...c
1097
1108
  };
1098
- tt(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
1109
+ $e(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
1099
1110
  let f = new e(d);
1100
1111
  this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
1101
1112
  this.mediaRecoveries = 0, this.networkRecoveries = 0;
@@ -1104,17 +1115,17 @@ var U = class {
1104
1115
  }), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
1105
1116
  t?.frag?.type === "main" && (this.kickPending = !1, this.kickTicks = 0, (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
1106
1117
  this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
1107
- }, Be)));
1118
+ }, Re)));
1108
1119
  }), f.on(e.Events.FRAG_LOADING, (e, t) => {
1109
1120
  t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
1110
1121
  }), f.on(e.Events.FRAG_LOADED, (e, t) => {
1111
1122
  let n = t?.frag?.stats, r = n?.loaded;
1112
1123
  typeof r == "number" && (this.bytesLoaded += r);
1113
1124
  let i = n?.loading;
1114
- i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > et && this.requestTimesMs.shift());
1125
+ i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Qe && this.requestTimesMs.shift());
1115
1126
  let a = t?.frag?.url;
1116
1127
  if (a) {
1117
- let e = L(a);
1128
+ let e = V(a);
1118
1129
  e && (this.cdnHost = e);
1119
1130
  }
1120
1131
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => {
@@ -1127,7 +1138,7 @@ var U = class {
1127
1138
  }));
1128
1139
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
1129
1140
  this.checkEndStale(), this.checkStarvation();
1130
- }, He), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1141
+ }, Be), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1131
1142
  this.renditionSwitches += 1;
1132
1143
  let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
1133
1144
  n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
@@ -1191,7 +1202,7 @@ var U = class {
1191
1202
  return;
1192
1203
  }
1193
1204
  this.capTimer && clearTimeout(this.capTimer);
1194
- let t = e > this.sizeCapLevel ? Ye : Xe;
1205
+ let t = e > this.sizeCapLevel ? qe : Je;
1195
1206
  this.capTimer = setTimeout(() => {
1196
1207
  this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
1197
1208
  }, t);
@@ -1238,7 +1249,7 @@ var U = class {
1238
1249
  e.widevine && (this.licenseUrl = e.widevine);
1239
1250
  }
1240
1251
  getStats() {
1241
- let e = this.hls, t = R(this.deps.video), n = {
1252
+ let e = this.hls, t = H(this.deps.video), n = {
1242
1253
  droppedFrames: t.dropped,
1243
1254
  decodedFrames: t.totalFrames,
1244
1255
  lowLatency: this.detectedLowLatency,
@@ -1284,7 +1295,7 @@ var U = class {
1284
1295
  return;
1285
1296
  }
1286
1297
  let e = Date.now() - this.lastAdvanceMs;
1287
- !this.chaseSuspended && e > H && this.suspendChasing(), e > Ve && this.emitEnded("stalled");
1298
+ !this.chaseSuspended && e > K && this.suspendChasing(), e > ze && this.emitEnded("stalled");
1288
1299
  }
1289
1300
  checkStarvation() {
1290
1301
  let e = this.hls, { video: t } = this.deps;
@@ -1293,17 +1304,17 @@ var U = class {
1293
1304
  this.starvedTicks = 0;
1294
1305
  return;
1295
1306
  }
1296
- let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < H, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > We;
1307
+ let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < K, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > He;
1297
1308
  if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
1298
1309
  this.starvedTicks = 0;
1299
1310
  return;
1300
1311
  }
1301
- if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < Ge)) {
1302
- if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= qe && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < Je)) {
1312
+ if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < Ue)) {
1313
+ if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= Ge && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < Ke)) {
1303
1314
  this.starvationRebuilds += 1, console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
1304
1315
  return;
1305
1316
  }
1306
- if (!(this.starvationKicks >= Ke)) {
1317
+ if (!(this.starvationKicks >= We)) {
1307
1318
  this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, console.warn("havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
1308
1319
  try {
1309
1320
  e.stopLoad(), e.startLoad(-1);
@@ -1353,7 +1364,7 @@ var U = class {
1353
1364
  scheduleLicenseRetry(t) {
1354
1365
  if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
1355
1366
  let n = t.response?.code ?? 0;
1356
- if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= ze) return !1;
1367
+ if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Le) return !1;
1357
1368
  this.licenseRecoveries += 1;
1358
1369
  let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
1359
1370
  return this.licenseRetryTimer = setTimeout(() => {
@@ -1385,7 +1396,7 @@ var U = class {
1385
1396
  return;
1386
1397
  }
1387
1398
  if (t.type === e.ErrorTypes.NETWORK_ERROR) {
1388
- if (this.networkRecoveries < Re) {
1399
+ if (this.networkRecoveries < Ie) {
1389
1400
  this.networkRecoveries += 1;
1390
1401
  let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
1391
1402
  this.networkRetryTimer = setTimeout(() => {
@@ -1402,7 +1413,7 @@ var U = class {
1402
1413
  return;
1403
1414
  }
1404
1415
  if (t.type === e.ErrorTypes.MEDIA_ERROR) {
1405
- if (this.mediaRecoveries < Le) {
1416
+ if (this.mediaRecoveries < Fe) {
1406
1417
  this.mediaRecoveries += 1, n.recoverMediaError();
1407
1418
  return;
1408
1419
  }
@@ -1426,16 +1437,16 @@ var U = class {
1426
1437
  let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
1427
1438
  return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
1428
1439
  }
1429
- }, rt = 15e3, it = 6e5, at = 3e5, ot = 100, W = 1, st = 1e3, G = 3e4, ct = 1e3, lt = {
1440
+ }, tt = 15e3, nt = 6e5, rt = 3e5, it = 100, J = 1, at = 1e3, ot = 3e4, st = 1e3, ct = {
1430
1441
  inline: "PRESENTATION_INLINE",
1431
1442
  fullscreen: "PRESENTATION_FULLSCREEN",
1432
1443
  pip: "PRESENTATION_PIP"
1433
- }, ut = {
1444
+ }, lt = {
1434
1445
  widevine: "KEY_SYSTEM_WIDEVINE",
1435
1446
  fairplay: "KEY_SYSTEM_FAIRPLAY",
1436
1447
  none: "KEY_SYSTEM_NONE"
1437
1448
  };
1438
- function K(e, t) {
1449
+ function ut(e, t) {
1439
1450
  return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
1440
1451
  }
1441
1452
  var dt = /* @__PURE__ */ new Set([
@@ -1448,7 +1459,7 @@ var dt = /* @__PURE__ */ new Set([
1448
1459
  "FORBIDDEN",
1449
1460
  "RATE_LIMITED",
1450
1461
  "TIMEOUT"
1451
- ]), q = {
1462
+ ]), Y = {
1452
1463
  idle: "PLAYER_STATE_IDLE",
1453
1464
  waiting: "PLAYER_STATE_WAITING",
1454
1465
  loading: "PLAYER_STATE_LOADING",
@@ -1544,8 +1555,8 @@ var pt = class {
1544
1555
  constructor(e) {
1545
1556
  this.opts = {
1546
1557
  ...e,
1547
- heartbeatMs: e.heartbeatMs ?? rt,
1548
- idleMs: e.idleMs ?? it
1558
+ heartbeatMs: e.heartbeatMs ?? tt,
1559
+ idleMs: e.idleMs ?? nt
1549
1560
  }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs, this.startupAnchorMs = this.bornMs;
1550
1561
  }
1551
1562
  start() {
@@ -1555,11 +1566,11 @@ var pt = class {
1555
1566
  sdkVersion: this.opts.sdkVersion,
1556
1567
  ...this.opts.environment
1557
1568
  };
1558
- this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), st), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.onVisibility());
1569
+ this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), at), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.onVisibility());
1559
1570
  }
1560
1571
  checkSuspension(e) {
1561
1572
  if (this.endedFlag || !this.opts.idleMs) return !1;
1562
- let t = Math.max(this.opts.idleMs, at);
1573
+ let t = Math.max(this.opts.idleMs, rt);
1563
1574
  return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
1564
1575
  }
1565
1576
  syncIdle(e) {
@@ -1573,21 +1584,21 @@ var pt = class {
1573
1584
  noteStateChange(e, t, n, r) {
1574
1585
  if (this.endedFlag || e === t) return;
1575
1586
  let i = this.now();
1576
- if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(W, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(W, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
1587
+ if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(J, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(J, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
1577
1588
  this.stallIsSeekInduced = this.seekInduced(i);
1578
1589
  let e = !this.isHidden && !this.stallIsSeekInduced;
1579
- e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(W, Math.round(this.playingTotalMs)));
1590
+ e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(J, Math.round(this.playingTotalMs)));
1580
1591
  } else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
1581
1592
  this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
1582
1593
  let a = {
1583
- fromState: q[e] ?? "PLAYER_STATE_UNSPECIFIED",
1584
- toState: q[t] ?? "PLAYER_STATE_UNSPECIFIED",
1585
- presentation: lt[this.presentation]
1594
+ fromState: Y[e] ?? "PLAYER_STATE_UNSPECIFIED",
1595
+ toState: Y[t] ?? "PLAYER_STATE_UNSPECIFIED",
1596
+ presentation: ct[this.presentation]
1586
1597
  }, o = this.causeOf(e, t, i);
1587
1598
  o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
1588
1599
  }
1589
1600
  seekInduced(e) {
1590
- return this.lastSeekMs >= 0 && e - this.lastSeekMs < ct;
1601
+ return this.lastSeekMs >= 0 && e - this.lastSeekMs < st;
1591
1602
  }
1592
1603
  causeOf(e, t, n) {
1593
1604
  if (t === "error") return "TRANSITION_CAUSE_ERROR";
@@ -1624,19 +1635,19 @@ var pt = class {
1624
1635
  }
1625
1636
  this.muteChanges += 1;
1626
1637
  let r = this.now();
1627
- n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(W, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
1638
+ n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(J, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
1628
1639
  }
1629
1640
  notePresentation(e) {
1630
1641
  this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
1631
1642
  }
1632
1643
  notePlayIntent() {
1633
- this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = W), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = W));
1644
+ this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = J), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = J));
1634
1645
  }
1635
1646
  noteReady() {
1636
- this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(W, this.now() - this.startupAnchorMs));
1647
+ this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
1637
1648
  }
1638
1649
  noteFirstBytes() {
1639
- this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(W, this.now() - this.startupAnchorMs));
1650
+ this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
1640
1651
  }
1641
1652
  noteSeek() {
1642
1653
  this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
@@ -1687,7 +1698,7 @@ var pt = class {
1687
1698
  let l = t.droppedFrames ?? 0;
1688
1699
  l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
1689
1700
  let u = t.renditionSwitches ?? 0;
1690
- u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = q[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
1701
+ u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = Y[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
1691
1702
  let d = this.mutedTotalMs;
1692
1703
  this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
1693
1704
  let f = t.upshifts ?? 0;
@@ -1702,14 +1713,14 @@ var pt = class {
1702
1713
  if (this.lastRequestCount = g, _ > 0) {
1703
1714
  o.requestCountDelta = _;
1704
1715
  let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
1705
- n.length > 0 && (o.requestTimeP50Ms = K(n, 50), o.requestTimeP95Ms = K(n, 95));
1716
+ n.length > 0 && (o.requestTimeP50Ms = ut(n, 50), o.requestTimeP95Ms = ut(n, 95));
1706
1717
  }
1707
1718
  typeof t.latencySeconds == "number" && typeof t.targetLatencySeconds == "number" && (o.driftMs = Math.round((t.latencySeconds - t.targetLatencySeconds) * 1e3)), typeof t.playbackRate == "number" && t.playbackRate > 0 && (o.playbackRate = t.playbackRate), t.qualityPinned === !0 && (o.qualityPinned = !0), t.cdnHost && (o.cdnHost = t.cdnHost), this.maybeEmitMediaInfo(t), this.enqueue({ heartbeat: o }), this.flush(), s > 0 && this.noteFirstBytes();
1708
1719
  }
1709
1720
  maybeEmitMediaInfo(e) {
1710
1721
  if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
1711
1722
  let t = {};
1712
- e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = ut[e.keySystem]), e.drmSecurityLevel && (t.drmSecurityLevel = e.drmSecurityLevel), e.ladderHeights?.length && (t.ladderHeights = e.ladderHeights), e.ladderTopBitrateKbps && (t.ladderTopBitrateKbps = e.ladderTopBitrateKbps), e.lowLatency && (t.lowLatency = !0);
1723
+ e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = lt[e.keySystem]), e.drmSecurityLevel && (t.drmSecurityLevel = e.drmSecurityLevel), e.ladderHeights?.length && (t.ladderHeights = e.ladderHeights), e.ladderTopBitrateKbps && (t.ladderTopBitrateKbps = e.ladderTopBitrateKbps), e.lowLatency && (t.lowLatency = !0);
1713
1724
  let n = JSON.stringify(t);
1714
1725
  n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
1715
1726
  }
@@ -1729,7 +1740,7 @@ var pt = class {
1729
1740
  let c = r?.positionMs ?? 0;
1730
1741
  c > 0 && (i.exitPositionMs = Math.round(c)), this.activeTotalMs > 0 && (i.activeWatchTimeMs = Math.round(this.activeTotalMs)), this.mutedTotalMs > 0 && (i.mutedTimeMs = Math.round(this.mutedTotalMs));
1731
1742
  let l = e !== "END_REASON_ENDED";
1732
- l && this.lastStallMs > 0 && n - this.lastStallMs <= G && (i.abandonAfterStallMs = Math.max(W, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= G && (i.abandonAfterErrorMs = Math.max(W, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
1743
+ l && this.lastStallMs > 0 && n - this.lastStallMs <= ot && (i.abandonAfterStallMs = Math.max(J, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= ot && (i.abandonAfterErrorMs = Math.max(J, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
1733
1744
  let u = r?.decodedFrames ?? this.lastDecoded;
1734
1745
  u > 0 && (i.decodedFramesTotal = u), this.startupTimeMs === 0 && (i.failedStage = this.lastErrorStage ?? (this.manifestLoadMs === 0 ? "ERROR_STAGE_MANIFEST" : this.firstFragLoadMs === 0 ? "ERROR_STAGE_FIRST_SEGMENT" : "ERROR_STAGE_OTHER")), this.pending.push(this.wrap({ sessionEnd: i })), this.flush(e === "END_REASON_PAGEHIDE");
1735
1746
  }
@@ -1749,7 +1760,7 @@ var pt = class {
1749
1760
  };
1750
1761
  }
1751
1762
  enqueue(e) {
1752
- for (this.pending.push(this.wrap(e)); this.pending.length > ot;) {
1763
+ for (this.pending.push(this.wrap(e)); this.pending.length > it;) {
1753
1764
  let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
1754
1765
  this.pending.splice(e >= 0 ? e : 0, 1);
1755
1766
  }
@@ -1845,7 +1856,7 @@ async function vt() {
1845
1856
  }
1846
1857
  //#endregion
1847
1858
  //#region src/core/version.ts
1848
- var yt = "2.7.0", J = {
1859
+ var yt = "2.8.0", bt = {
1849
1860
  accent: "#E1B600",
1850
1861
  accentText: "#1B1C23",
1851
1862
  background: "#0e0f13",
@@ -1856,7 +1867,7 @@ var yt = "2.7.0", J = {
1856
1867
  border: "rgba(255, 255, 255, 0.1)",
1857
1868
  radius: "8px",
1858
1869
  fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
1859
- }, Y = {
1870
+ }, xt = {
1860
1871
  accent: "--havik-accent",
1861
1872
  accentText: "--havik-accent-text",
1862
1873
  background: "--havik-bg",
@@ -1868,25 +1879,25 @@ var yt = "2.7.0", J = {
1868
1879
  radius: "--havik-radius",
1869
1880
  fontFamily: "--havik-font"
1870
1881
  };
1871
- function X(e, t) {
1882
+ function St(e, t) {
1872
1883
  let n = {
1873
- ...J,
1884
+ ...bt,
1874
1885
  ...t
1875
1886
  };
1876
- for (let t of Object.keys(Y)) e.style.setProperty(Y[t], n[t]);
1887
+ for (let t of Object.keys(xt)) e.style.setProperty(xt[t], n[t]);
1877
1888
  n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
1878
1889
  }
1879
1890
  //#endregion
1880
1891
  //#region src/ui/styles.ts
1881
- var Z = "havik-player-styles", bt = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n.havik-spinner{width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n";
1882
- function xt(e = document) {
1883
- if (e.getElementById(Z)) return;
1892
+ var Ct = "havik-player-styles", wt = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n.havik-spinner{width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n";
1893
+ function Tt(e = document) {
1894
+ if (e.getElementById(Ct)) return;
1884
1895
  let t = e.createElement("style");
1885
- t.id = Z, t.textContent = bt, e.head.appendChild(t);
1896
+ t.id = Ct, t.textContent = wt, e.head.appendChild(t);
1886
1897
  }
1887
1898
  //#endregion
1888
1899
  //#region src/ui/icons.ts
1889
- var St = {
1900
+ var Et = {
1890
1901
  play: "<path d=\"M8 5v14l11-7z\"/>",
1891
1902
  pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
1892
1903
  volumeHigh: "<path d=\"M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4zm-2.5-9v2.06A7 7 0 0 1 14 19v2a9 9 0 0 0 0-18z\"/>",
@@ -1899,21 +1910,21 @@ var St = {
1899
1910
  liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
1900
1911
  retry: "<path d=\"M17.65 6.35A8 8 0 1 0 19.73 13h-2.08A6 6 0 1 1 12 6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\"/>"
1901
1912
  };
1902
- function Q(e) {
1903
- return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${St[e]}</svg>`;
1913
+ function X(e) {
1914
+ return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Et[e]}</svg>`;
1904
1915
  }
1905
1916
  //#endregion
1906
1917
  //#region src/ui/controls.ts
1907
- var Ct = 3e3, wt = /* @__PURE__ */ new Set([
1918
+ var Dt = 3e3, Ot = /* @__PURE__ */ new Set([
1908
1919
  "GONE",
1909
1920
  "NOT_FOUND",
1910
1921
  "INVALID_URN",
1911
1922
  "UNAUTHORIZED"
1912
1923
  ]);
1913
- function Tt(e) {
1914
- return new Et(e);
1924
+ function kt(e) {
1925
+ return new At(e);
1915
1926
  }
1916
- var Et = class {
1927
+ var At = class {
1917
1928
  root;
1918
1929
  video;
1919
1930
  player;
@@ -1955,7 +1966,7 @@ var Et = class {
1955
1966
  scrubbing = !1;
1956
1967
  offFns = [];
1957
1968
  constructor(e) {
1958
- this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Ct, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, xt(this.doc), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
1969
+ this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Dt, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, Tt(this.doc), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
1959
1970
  let t = (e, t, n) => {
1960
1971
  let r = this.doc.createElement(e);
1961
1972
  if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
@@ -1966,12 +1977,12 @@ var Et = class {
1966
1977
  "aria-label": r,
1967
1978
  title: r
1968
1979
  });
1969
- return i.innerHTML = Q(n), i;
1980
+ return i.innerHTML = X(n), i;
1970
1981
  };
1971
1982
  this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
1972
1983
  type: "button",
1973
1984
  "aria-label": "Play"
1974
- }), this.center.innerHTML = Q("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
1985
+ }), this.center.innerHTML = X("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
1975
1986
  role: "slider",
1976
1987
  "aria-label": "Seek",
1977
1988
  "aria-valuemin": "0",
@@ -1989,7 +2000,7 @@ var Et = class {
1989
2000
  "aria-label": "Volume"
1990
2001
  });
1991
2002
  let a = t("div", "havik-vol");
1992
- a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
2003
+ a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = X("liveDot");
1993
2004
  let o = this.doc.createElement("span");
1994
2005
  o.textContent = "LIVE", this.liveGo = t("button", "havik-live__go", { type: "button" }), this.liveGo.textContent = "Go live", this.live.append(o, this.liveGo), this.time = t("div", "havik-time"), this.time.textContent = "0:00", this.time.style.display = "none";
1995
2006
  let s = t("div", "havik-spacer");
@@ -2043,12 +2054,12 @@ var Et = class {
2043
2054
  }
2044
2055
  if (e === "preplay") {
2045
2056
  let e = this.doc.createElement("button");
2046
- e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Q("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
2057
+ e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = X("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
2047
2058
  } else {
2048
2059
  let r = this.doc.createElement("div");
2049
- if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !wt.has(this.lastError.code)) {
2060
+ if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Ot.has(this.lastError.code)) {
2050
2061
  let e = this.doc.createElement("button");
2051
- e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Q("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
2062
+ e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${X("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
2052
2063
  }
2053
2064
  }
2054
2065
  this.root.append(n), this.statusBox = n, this.show();
@@ -2087,7 +2098,7 @@ var Et = class {
2087
2098
  let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
2088
2099
  this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
2089
2100
  }
2090
- !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Dt(this.video.currentTime)} / ${Dt(this.video.duration)}`);
2101
+ !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${jt(this.video.currentTime)} / ${jt(this.video.duration)}`);
2091
2102
  }
2092
2103
  syncLive() {
2093
2104
  let e = this.player.getStats(), t = e.isLive !== !1;
@@ -2137,17 +2148,17 @@ var Et = class {
2137
2148
  renderQualityMenu() {
2138
2149
  let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
2139
2150
  n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
2140
- for (let n of e) this.menu.append(this.menuItem(Ot(n), t === n.index, () => this.player.setQuality(n.index)));
2151
+ for (let n of e) this.menu.append(this.menuItem(Mt(n), t === n.index, () => this.player.setQuality(n.index)));
2141
2152
  }
2142
2153
  renderAudioMenu() {
2143
2154
  let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
2144
2155
  t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
2145
- for (let t of e) this.menu.append(this.menuItem(kt(t), t.default, () => this.player.setAudioTrack(t.id)));
2156
+ for (let t of e) this.menu.append(this.menuItem(Nt(t), t.default, () => this.player.setAudioTrack(t.id)));
2146
2157
  }
2147
2158
  renderCcMenu() {
2148
2159
  let e = this.player.getTextTracks(), t = this.doc.createElement("div");
2149
2160
  t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
2150
- for (let t of e) this.menu.append(this.menuItem(At(t), !1, () => this.player.setTextTrack(t.id)));
2161
+ for (let t of e) this.menu.append(this.menuItem(Pt(t), !1, () => this.player.setTextTrack(t.id)));
2151
2162
  }
2152
2163
  onTracksChanged() {
2153
2164
  this.openMenu && this.renderMenu(this.openMenu);
@@ -2230,7 +2241,7 @@ var Et = class {
2230
2241
  }
2231
2242
  }
2232
2243
  setIcon(e, t) {
2233
- e.innerHTML = Q(t);
2244
+ e.innerHTML = X(t);
2234
2245
  }
2235
2246
  destroy() {
2236
2247
  this.hideTimer && clearTimeout(this.hideTimer);
@@ -2247,32 +2258,41 @@ var Et = class {
2247
2258
  this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
2248
2259
  }
2249
2260
  };
2250
- function Dt(e) {
2261
+ function jt(e) {
2251
2262
  (!Number.isFinite(e) || e < 0) && (e = 0);
2252
2263
  let t = Math.floor(e % 60), n = Math.floor(e / 60 % 60), r = Math.floor(e / 3600), i = r > 0 ? String(n).padStart(2, "0") : String(n), a = String(t).padStart(2, "0");
2253
2264
  return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
2254
2265
  }
2255
- function Ot(e) {
2266
+ function Mt(e) {
2256
2267
  return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
2257
2268
  }
2258
- function kt(e) {
2269
+ function Nt(e) {
2259
2270
  return e.name || e.lang || `Track ${e.id}`;
2260
2271
  }
2261
- function At(e) {
2272
+ function Pt(e) {
2262
2273
  return e.name || e.lang || `Track ${e.id}`;
2263
2274
  }
2264
2275
  //#endregion
2265
2276
  //#region src/managed/index.ts
2266
- var jt = 6e3, Mt = 45e3, Nt = 2e3, Pt = 3, Ft = 2e3, It = 48e4;
2267
- async function Lt(e) {
2277
+ var Ft = 6e3, Z = 45e3, It = 2e3, Lt = 3, Rt = 2e3, zt = 48e4;
2278
+ function Bt(e) {
2279
+ if (e.env !== void 0 && e.baseUrl !== void 0) throw new n("INTERNAL", 0, `createPlayer: pass env OR baseUrl, not both (got env=${JSON.stringify(e.env)} and baseUrl=${JSON.stringify(e.baseUrl)})`);
2280
+ if (e.env !== void 0) return z(e.env);
2281
+ if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
2282
+ return e.baseUrl;
2283
+ }
2284
+ async function Q(e) {
2268
2285
  if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
2269
- if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: baseUrl is required");
2286
+ let t = Bt(e);
2270
2287
  if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
2271
2288
  if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
2272
- let t = new Rt(e);
2273
- return await t.start(), t;
2289
+ let r = new Vt({
2290
+ ...e,
2291
+ baseUrl: t
2292
+ });
2293
+ return await r.start(), r;
2274
2294
  }
2275
- var Rt = class {
2295
+ var Vt = class {
2276
2296
  opts;
2277
2297
  abort = new AbortController();
2278
2298
  listeners = {};
@@ -2316,7 +2336,7 @@ var Rt = class {
2316
2336
  this.opts.muted && (this.opts.video.muted = !0), this.opts.poster && (this.opts.video.poster = this.opts.poster), this.mountControls(), this.attachPipListeners(), this.setState("loading");
2317
2337
  let e = ++this.loadGen, t = this.resolveOptions();
2318
2338
  try {
2319
- let n = await v(t);
2339
+ let n = await y(t);
2320
2340
  if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
2321
2341
  let e = this._lastError;
2322
2342
  throw this.destroy(), e;
@@ -2343,7 +2363,7 @@ var Rt = class {
2343
2363
  r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
2344
2364
  }
2345
2365
  beginArmingByPolling(e) {
2346
- y({
2366
+ b({
2347
2367
  ...this.resolveOptions(),
2348
2368
  signal: this.abort.signal,
2349
2369
  waitForLive: this.buildWaitConfig(e)
@@ -2360,7 +2380,7 @@ var Rt = class {
2360
2380
  setTimeout(() => {
2361
2381
  a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
2362
2382
  phase: i ? "unavailable" : "tooEarly",
2363
- retryInMs: Mt,
2383
+ retryInMs: Z,
2364
2384
  attempt: 1,
2365
2385
  elapsedMs: 0,
2366
2386
  ...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
@@ -2377,7 +2397,7 @@ var Rt = class {
2377
2397
  }
2378
2398
  }
2379
2399
  }, h = () => {
2380
- a || s || p() || (s = !0, y({
2400
+ a || s || p() || (s = !0, b({
2381
2401
  ...this.resolveOptions(),
2382
2402
  signal: c.signal,
2383
2403
  waitForLive: this.buildWaitConfig(e)
@@ -2385,7 +2405,7 @@ var Rt = class {
2385
2405
  a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
2386
2406
  }));
2387
2407
  }, g = () => {
2388
- a || p() || v(this.resolveOptions()).then((e) => m(e)).catch((e) => {
2408
+ a || p() || y(this.resolveOptions()).then((e) => m(e)).catch((e) => {
2389
2409
  if (!(a || p())) {
2390
2410
  if (e instanceof n && o(e.code)) {
2391
2411
  h();
@@ -2399,13 +2419,13 @@ var Rt = class {
2399
2419
  !a && !p() && h();
2400
2420
  }, e);
2401
2421
  };
2402
- _(jt), this.armingSub = E({
2422
+ _(Ft), this.armingSub = E({
2403
2423
  eventsBaseUrl: t,
2404
2424
  matchUrn: this.opts.matchUrn,
2405
2425
  credential: this.opts.credential,
2406
- onAlive: () => _(Mt),
2426
+ onAlive: () => _(Z),
2407
2427
  onState: (e) => {
2408
- a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Nt);
2428
+ a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * It);
2409
2429
  },
2410
2430
  onError: () => h()
2411
2431
  });
@@ -2428,7 +2448,7 @@ var Rt = class {
2428
2448
  let n = await s(this.opts.credential);
2429
2449
  if (this.destroyed || t !== this.loadGen) return;
2430
2450
  this.setState("loading");
2431
- let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Ne(this.opts.video, (e) => {
2451
+ let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = je(this.opts.video, (e) => {
2432
2452
  this._state !== "ended" && this._state !== "error" && this.setState(e);
2433
2453
  });
2434
2454
  if (await i.load(), this.destroyed || t !== this.loadGen) {
@@ -2461,7 +2481,7 @@ var Rt = class {
2461
2481
  idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
2462
2482
  onIdle: () => this.onAnalyticsIdle(t),
2463
2483
  sample: () => {
2464
- let e = this.engine?.getStats() ?? I, t = i.buffered.length ? Math.max(0, i.buffered.end(i.buffered.length - 1) - i.currentTime) : 0;
2484
+ let e = this.engine?.getStats() ?? B, t = i.buffered.length ? Math.max(0, i.buffered.end(i.buffered.length - 1) - i.currentTime) : 0;
2465
2485
  return {
2466
2486
  ...e,
2467
2487
  bufferedMs: Math.round(t * 1e3),
@@ -2499,11 +2519,11 @@ var Rt = class {
2499
2519
  hlsConfig: i,
2500
2520
  emit: (e) => this.onEngineEvent(e)
2501
2521
  }, o = this.opts.engine ?? "auto";
2502
- if (o === "native") return new V(a);
2503
- if (o === "hls") return new U(a);
2504
- if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && z(this.opts.video) && B()) return new V(a);
2505
- if (Ie()) return new U(a);
2506
- if (z(this.opts.video)) return new V(a);
2522
+ if (o === "native") return new G(a);
2523
+ if (o === "hls") return new q(a);
2524
+ if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && U(this.opts.video) && W()) return new G(a);
2525
+ if (Pe()) return new q(a);
2526
+ if (U(this.opts.video)) return new G(a);
2507
2527
  throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
2508
2528
  }
2509
2529
  onEngineEvent(e) {
@@ -2546,7 +2566,7 @@ var Rt = class {
2546
2566
  r = 0, i = !1;
2547
2567
  },
2548
2568
  onError: () => {
2549
- this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Pt && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))));
2569
+ this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Lt && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))));
2550
2570
  }
2551
2571
  });
2552
2572
  }
@@ -2568,7 +2588,7 @@ var Rt = class {
2568
2588
  scheduleRejoin(e) {
2569
2589
  this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
2570
2590
  this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
2571
- }, Math.random() * Nt));
2591
+ }, Math.random() * It));
2572
2592
  }
2573
2593
  cancelRejoin() {
2574
2594
  this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
@@ -2592,7 +2612,7 @@ var Rt = class {
2592
2612
  }
2593
2613
  t.controls = !1;
2594
2614
  let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
2595
- r && r.insertBefore(n, t), n.appendChild(t), X(n, this.opts.theme), this.container = n, this.controlBar = Tt({
2615
+ r && r.insertBefore(n, t), n.appendChild(t), St(n, this.opts.theme), this.container = n, this.controlBar = kt({
2596
2616
  root: n,
2597
2617
  video: t,
2598
2618
  player: this,
@@ -2622,7 +2642,7 @@ var Rt = class {
2622
2642
  }
2623
2643
  startStats() {
2624
2644
  this.stopStats();
2625
- let e = Math.max(500, this.opts.statsIntervalMs ?? Ft);
2645
+ let e = Math.max(500, this.opts.statsIntervalMs ?? Rt);
2626
2646
  this.statsTimer = setInterval(() => {
2627
2647
  if (!this.engine) return;
2628
2648
  let e = this.engine.getStats();
@@ -2634,7 +2654,7 @@ var Rt = class {
2634
2654
  }
2635
2655
  scheduleLicenseRefresh() {
2636
2656
  this.stopRefresh();
2637
- let e = this.opts.licenseRefreshMs ?? It;
2657
+ let e = this.opts.licenseRefreshMs ?? zt;
2638
2658
  e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
2639
2659
  }
2640
2660
  stopRefresh() {
@@ -2643,7 +2663,7 @@ var Rt = class {
2643
2663
  async refreshLicense() {
2644
2664
  let e = this.engine;
2645
2665
  if (!this.destroyed && e) try {
2646
- let t = await v(this.resolveOptions());
2666
+ let t = await y(this.resolveOptions());
2647
2667
  if (this.destroyed || this.engine !== e) return;
2648
2668
  let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
2649
2669
  (n || r) && (e.setLicenseUrls({
@@ -2679,7 +2699,7 @@ var Rt = class {
2679
2699
  this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
2680
2700
  }
2681
2701
  getStats() {
2682
- return this.engine?.getStats() ?? I;
2702
+ return this.engine?.getStats() ?? B;
2683
2703
  }
2684
2704
  getQualityLevels() {
2685
2705
  return this.engine?.getQualityLevels() ?? [];
@@ -2731,7 +2751,7 @@ var Rt = class {
2731
2751
  let e = ++this.loadGen;
2732
2752
  this.teardownPlayback();
2733
2753
  try {
2734
- let t = await y({
2754
+ let t = await b({
2735
2755
  ...this.resolveOptions(),
2736
2756
  waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
2737
2757
  });
@@ -2789,7 +2809,7 @@ function $(e) {
2789
2809
  }
2790
2810
  //#endregion
2791
2811
  //#region src/embed/host.ts
2792
- function zt(e) {
2812
+ function Ht(e) {
2793
2813
  if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
2794
2814
  if (!e.src) throw Error("mountEmbed: opts.src is required");
2795
2815
  if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
@@ -2848,8 +2868,8 @@ function zt(e) {
2848
2868
  }
2849
2869
  //#endregion
2850
2870
  //#region src/embed/page.ts
2851
- var Bt = /^[A-Za-z0-9:_.-]{1,128}$/;
2852
- function Vt() {
2871
+ var Ut = /^[A-Za-z0-9:_.-]{1,128}$/;
2872
+ function Wt() {
2853
2873
  let e = window.HAVIK_EMBED_CONFIG;
2854
2874
  if (e) return {
2855
2875
  baseUrl: e.baseUrl ?? "",
@@ -2871,9 +2891,9 @@ function Vt() {
2871
2891
  waitForLive: !0
2872
2892
  };
2873
2893
  }
2874
- async function Ht() {
2875
- let e = Vt();
2876
- Wt();
2894
+ async function Gt() {
2895
+ let e = Wt();
2896
+ qt();
2877
2897
  let t = document.createElement("video");
2878
2898
  t.setAttribute("playsinline", ""), t.muted = e.muted ?? !0, t.style.cssText = "width:100%;height:100%;object-fit:contain;background:#000;aspect-ratio:auto", document.body.appendChild(t);
2879
2899
  let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
@@ -2928,12 +2948,12 @@ async function Ht() {
2928
2948
  code: e.code,
2929
2949
  message: e.message
2930
2950
  })), e.on("autoplayblocked", () => {
2931
- i({ type: "oddin:autoplayblocked" }), Ut(t, e);
2951
+ i({ type: "oddin:autoplayblocked" }), Kt(t, e);
2932
2952
  });
2933
2953
  }, s = async (r) => {
2934
2954
  a?.destroy(), a = null;
2935
2955
  try {
2936
- let n = await Lt({
2956
+ let n = await Q({
2937
2957
  video: t,
2938
2958
  baseUrl: e.baseUrl,
2939
2959
  matchUrn: r,
@@ -2994,7 +3014,7 @@ async function Ht() {
2994
3014
  a?.retry();
2995
3015
  break;
2996
3016
  case "oddin:load":
2997
- typeof e.matchUrn == "string" && Bt.test(e.matchUrn) && s(e.matchUrn);
3017
+ typeof e.matchUrn == "string" && Ut.test(e.matchUrn) && s(e.matchUrn);
2998
3018
  break;
2999
3019
  case "oddin:destroy": c();
3000
3020
  }
@@ -3006,18 +3026,18 @@ async function Ht() {
3006
3026
  protocol: 1
3007
3027
  });
3008
3028
  }
3009
- function Ut(e, t) {
3029
+ function Kt(e, t) {
3010
3030
  if (document.getElementById("havik-tap")) return;
3011
3031
  let n = document.createElement("button");
3012
3032
  n.id = "havik-tap", n.textContent = "▶ Tap to play", n.style.cssText = "position:fixed;inset:0;width:100%;height:100%;border:0;background:rgba(0,0,0,.55);color:#fff;font:600 18px system-ui,sans-serif;cursor:pointer;z-index:9", n.addEventListener("click", () => {
3013
3033
  n.remove(), t.play();
3014
3034
  }), document.body.appendChild(n);
3015
3035
  }
3016
- function Wt() {
3036
+ function qt() {
3017
3037
  let e = document.createElement("style");
3018
3038
  e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
3019
3039
  }
3020
3040
  //#endregion
3021
- export { J as ODDIN_THEME, n as PlaybackError, X as applyTheme, Ht as bootEmbed, _e as clearDeviceId, Lt as createPlayer, D as deriveEventsBaseUrl, Oe as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, Ae as isLowLatencyManifest, $ as isOddinMessage, ye as licenseRequestHeaders, zt as mountEmbed, oe as pollToLive, y as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
3041
+ export { bt as ODDIN_THEME, n as PlaybackError, St as applyTheme, z as baseUrlForEnv, Gt as bootEmbed, _e as clearDeviceId, Q as createPlayer, D as deriveEventsBaseUrl, Ee as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, Oe as isLowLatencyManifest, $ as isOddinMessage, ye as licenseRequestHeaders, Ht as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
3022
3042
 
3023
3043
  //# sourceMappingURL=index.js.map