@oddin-gg/havik-player 2.25.0 → 2.26.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
@@ -309,42 +309,42 @@ function ge(e, t) {
309
309
  }
310
310
  //#endregion
311
311
  //#region src/core/fullscreen.ts
312
- function _e(e) {
312
+ function x(e) {
313
313
  return e.ownerDocument ?? document;
314
314
  }
315
- function ve(e) {
315
+ function _e(e) {
316
316
  return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
317
317
  }
318
- function ye(e, t) {
319
- let n = ve(_e(e));
318
+ function S(e, t) {
319
+ let n = _e(x(e));
320
320
  return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
321
321
  }
322
- function x(e, t) {
323
- let n = t ?? e, r = _e(e);
322
+ function C(e, t) {
323
+ let n = t ?? e, r = x(e);
324
324
  if (typeof n.requestFullscreen == "function") return r.fullscreenEnabled !== !1;
325
325
  if (typeof n.webkitRequestFullscreen == "function") return r.webkitFullscreenEnabled !== !1;
326
326
  let i = e;
327
327
  return i.webkitSupportsFullscreen === !0 && typeof i.webkitEnterFullscreen == "function" || e.readyState < 1;
328
328
  }
329
- async function S(e, t) {
329
+ async function w(e, t) {
330
330
  let n = t ?? e;
331
331
  if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
332
332
  if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
333
333
  let r = e;
334
334
  return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
335
335
  }
336
- async function C(e, t) {
336
+ async function T(e, t) {
337
337
  let n = e;
338
338
  if (n.webkitDisplayingFullscreen) {
339
339
  n.webkitExitFullscreen?.();
340
340
  return;
341
341
  }
342
- let r = _e(e), i = ve(r);
342
+ let r = x(e), i = _e(r);
343
343
  i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
344
344
  }
345
345
  //#endregion
346
346
  //#region src/core/catalog.ts
347
- async function be(e) {
347
+ async function ve(e) {
348
348
  let t = new URLSearchParams();
349
349
  e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
350
350
  let i = t.toString(), a = f(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
@@ -362,12 +362,12 @@ async function be(e) {
362
362
  };
363
363
  if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
364
364
  return {
365
- tournaments: xe(await s.json()),
365
+ tournaments: ye(await s.json()),
366
366
  etag: s.headers.get("etag") ?? void 0,
367
367
  notModified: !1
368
368
  };
369
369
  }
370
- function xe(e) {
370
+ function ye(e) {
371
371
  return (e.tournaments ?? []).map((e) => {
372
372
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
373
373
  return {
@@ -389,7 +389,7 @@ function xe(e) {
389
389
  };
390
390
  });
391
391
  }
392
- async function Se(e) {
392
+ async function be(e) {
393
393
  let t = f(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
394
394
  e.etag && i.set("If-None-Match", e.etag);
395
395
  let a = await m(t, {
@@ -409,13 +409,13 @@ async function Se(e) {
409
409
  };
410
410
  if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
411
411
  return {
412
- tournament: Ce(await a.json()),
412
+ tournament: xe(await a.json()),
413
413
  etag: a.headers.get("etag") ?? void 0,
414
414
  notModified: !1,
415
415
  notFound: !1
416
416
  };
417
417
  }
418
- function Ce(e) {
418
+ function xe(e) {
419
419
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
420
420
  return {
421
421
  urn: t,
@@ -435,18 +435,18 @@ function Ce(e) {
435
435
  }))
436
436
  };
437
437
  }
438
- function we(e) {
438
+ function Se(e) {
439
439
  return e.tournaments.flatMap((e) => e.matches);
440
440
  }
441
441
  //#endregion
442
442
  //#region src/core/poll.ts
443
- var Te = /* @__PURE__ */ new Set([
443
+ var Ce = /* @__PURE__ */ new Set([
444
444
  "NOT_FOUND",
445
445
  "GEO_DENIED",
446
446
  "GONE",
447
447
  "INVALID_URN"
448
448
  ]);
449
- function Ee(e) {
449
+ function we(e) {
450
450
  let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, c = !1, d = () => {
451
451
  c || (a = setTimeout(p, t));
452
452
  }, p = async () => {
@@ -479,7 +479,7 @@ function Ee(e) {
479
479
  } catch (t) {
480
480
  if (!i.signal.aborted) {
481
481
  let r = t instanceof n ? t : new n("NETWORK", 0, String(t));
482
- Te.has(r.code) && (c = !0), e.onError?.(r);
482
+ Ce.has(r.code) && (c = !0), e.onError?.(r);
483
483
  }
484
484
  } finally {
485
485
  d();
@@ -491,16 +491,16 @@ function Ee(e) {
491
491
  }
492
492
  //#endregion
493
493
  //#region src/core/events.ts
494
- var De = 45e3, w = class extends Error {
494
+ var Te = 45e3, E = class extends Error {
495
495
  status;
496
496
  terminal;
497
497
  constructor(e) {
498
498
  let t = e === 410;
499
499
  super(t ? `live-state subscribe failed: HTTP ${e} — match is gone, not retrying` : e === 404 ? `live-state subscribe failed: HTTP ${e} — match not in the catalog, retrying slowly` : `live-state subscribe failed: HTTP ${e}`), this.name = "LiveStateHttpError", this.status = e, this.terminal = t;
500
500
  }
501
- }, Oe = 3e5;
502
- function T(e) {
503
- let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? Oe), i = e.idleTimeoutMs ?? De, a = Number.isFinite(i) && i > 0 ? i : 0, o = new AbortController(), s = !1, l = (e) => new Promise((t) => {
501
+ }, Ee = 3e5;
502
+ function D(e) {
503
+ let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? Ee), i = e.idleTimeoutMs ?? Te, a = Number.isFinite(i) && i > 0 ? i : 0, o = new AbortController(), s = !1, l = (e) => new Promise((t) => {
504
504
  if (o.signal.aborted) return t();
505
505
  let n = setTimeout(t, e);
506
506
  o.signal.addEventListener("abort", () => {
@@ -567,7 +567,7 @@ function T(e) {
567
567
  });
568
568
  if (clearTimeout(_), s) return;
569
569
  if (!o.ok || !o.body) {
570
- let t = new w(o.status);
570
+ let t = new E(o.status);
571
571
  h = t.terminal, g = o.status === 404, e.onError?.(t);
572
572
  } else await p(o.body, () => {
573
573
  i = t;
@@ -585,7 +585,7 @@ function T(e) {
585
585
  s || (s = !0, o.abort());
586
586
  } };
587
587
  }
588
- function E(e) {
588
+ function O(e) {
589
589
  try {
590
590
  let t = new URL(e);
591
591
  return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
@@ -595,24 +595,24 @@ function E(e) {
595
595
  }
596
596
  //#endregion
597
597
  //#region src/core/drm/deviceId.ts
598
- var D = "havik.player.deviceId", O;
599
- function k() {
600
- if (O) return O;
598
+ var De = "havik.player.deviceId", k;
599
+ function Oe() {
600
+ if (k) return k;
601
601
  try {
602
- let e = globalThis.localStorage?.getItem(D);
603
- if (e) return O = e, e;
602
+ let e = globalThis.localStorage?.getItem(De);
603
+ if (e) return k = e, e;
604
604
  } catch {}
605
605
  let e = Ae();
606
- O = e;
606
+ k = e;
607
607
  try {
608
- globalThis.localStorage?.setItem(D, e);
608
+ globalThis.localStorage?.setItem(De, e);
609
609
  } catch {}
610
610
  return e;
611
611
  }
612
612
  function ke() {
613
- O = void 0;
613
+ k = void 0;
614
614
  try {
615
- globalThis.localStorage?.removeItem(D);
615
+ globalThis.localStorage?.removeItem(De);
616
616
  } catch {}
617
617
  }
618
618
  function Ae() {
@@ -631,28 +631,28 @@ function je(e, t, n = {}) {
631
631
  let r = {
632
632
  "x-api-key": t.apiKey,
633
633
  "X-Match-Urn": e.matchUrn,
634
- "X-Device-Id": n.deviceId ?? k(),
634
+ "X-Device-Id": n.deviceId ?? Oe(),
635
635
  "Content-Type": "application/octet-stream"
636
636
  };
637
637
  return n.userId && (r["X-User-Id"] = n.userId), r;
638
638
  }
639
639
  //#endregion
640
640
  //#region src/core/bandwidthMemory.ts
641
- var A = "havik.player.bandwidth", Me = .8, Ne = 2e7, Pe = 3e5;
642
- function Fe() {
641
+ var Me = "havik.player.bandwidth", Ne = .8, Pe = 2e7, Fe = 3e5;
642
+ function Ie() {
643
643
  return globalThis.navigator?.connection;
644
644
  }
645
- function Ie() {
646
- let e = Fe()?.type;
645
+ function Le() {
646
+ let e = Ie()?.type;
647
647
  return typeof e == "string" && e !== "" && e !== "unknown" ? e : "any";
648
648
  }
649
- function Le() {
650
- let e = Fe()?.downlink;
649
+ function Re() {
650
+ let e = Ie()?.downlink;
651
651
  return typeof e == "number" && Number.isFinite(e) && e > 0 ? e * 1e6 : void 0;
652
652
  }
653
- function Re() {
653
+ function ze() {
654
654
  try {
655
- let e = globalThis.localStorage?.getItem(A);
655
+ let e = globalThis.localStorage?.getItem(Me);
656
656
  if (!e) return {};
657
657
  let t = JSON.parse(e);
658
658
  return t && typeof t == "object" && !Array.isArray(t) ? t : {};
@@ -660,36 +660,36 @@ function Re() {
660
660
  return {};
661
661
  }
662
662
  }
663
- function ze(e = Date.now()) {
664
- let t = Re()[Ie()];
663
+ function Be(e = Date.now()) {
664
+ let t = ze()[Le()];
665
665
  if (!t || typeof t.bps != "number" || typeof t.at != "number" || !Number.isFinite(t.bps) || t.bps <= 0) return;
666
666
  let n = e - t.at;
667
667
  if (n < 0 || n > 2592e5) return;
668
- let r = Le(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
669
- return Math.round(Math.min(Ne, Math.max(Pe, i * Me)));
668
+ let r = Re(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
669
+ return Math.round(Math.min(Pe, Math.max(Fe, i * Ne)));
670
670
  }
671
- function Be(e, t = Date.now()) {
671
+ function Ve(e, t = Date.now()) {
672
672
  if (!Number.isFinite(e) || e <= 0) return;
673
- let n = Re();
674
- n[Ie()] = {
673
+ let n = ze();
674
+ n[Le()] = {
675
675
  bps: Math.round(e),
676
676
  at: t
677
677
  };
678
678
  try {
679
- globalThis.localStorage?.setItem(A, JSON.stringify(n));
679
+ globalThis.localStorage?.setItem(Me, JSON.stringify(n));
680
680
  } catch {}
681
681
  }
682
- function Ve() {
682
+ function He() {
683
683
  try {
684
- globalThis.localStorage?.removeItem(A);
684
+ globalThis.localStorage?.removeItem(Me);
685
685
  } catch {}
686
686
  }
687
687
  //#endregion
688
688
  //#region src/core/drm/cdm.ts
689
- var He = /* @__PURE__ */ new WeakMap();
690
- function Ue(e, t) {
691
- let n = He.get(e);
692
- n || (n = /* @__PURE__ */ new Map(), He.set(e, n));
689
+ var Ue = /* @__PURE__ */ new WeakMap();
690
+ function We(e, t) {
691
+ let n = Ue.get(e);
692
+ n || (n = /* @__PURE__ */ new Map(), Ue.set(e, n));
693
693
  let r = n.get(t.keySystem);
694
694
  if (r) return r;
695
695
  let i = t.createMediaKeys().catch((e) => {
@@ -697,22 +697,22 @@ function Ue(e, t) {
697
697
  });
698
698
  return n.set(t.keySystem, i), i;
699
699
  }
700
- function j() {
700
+ function A() {
701
701
  return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
702
702
  }
703
- var M = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
704
- function We(e) {
703
+ var j = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
704
+ function Ge(e) {
705
705
  return e.startsWith("com.widevine");
706
706
  }
707
- function N(e, t) {
708
- if (!We(e)) return t;
707
+ function M(e, t) {
708
+ if (!Ge(e)) return t;
709
709
  let n = (e, t) => {
710
710
  let n = e.videoCapabilities;
711
711
  return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
712
- let n = M.indexOf(e.robustness);
713
- return n === -1 || M.indexOf(t) > n;
712
+ let n = j.indexOf(e.robustness);
713
+ return n === -1 || j.indexOf(t) > n;
714
714
  });
715
- }, r = M.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
715
+ }, r = j.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
716
716
  ...t,
717
717
  videoCapabilities: t.videoCapabilities?.map((t) => ({
718
718
  ...t,
@@ -721,53 +721,53 @@ function N(e, t) {
721
721
  })));
722
722
  return [...t, ...r];
723
723
  }
724
- function Ge(e) {
725
- return (t, n) => j() ? navigator.requestMediaKeySystemAccess(t, N(t, n)).then((t) => ({
724
+ function Ke(e) {
725
+ return (t, n) => A() ? navigator.requestMediaKeySystemAccess(t, M(t, n)).then((t) => ({
726
726
  keySystem: t.keySystem,
727
727
  getConfiguration: () => t.getConfiguration(),
728
- createMediaKeys: () => Ue(e, t)
728
+ createMediaKeys: () => We(e, t)
729
729
  })) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
730
730
  }
731
- var P = {
731
+ var N = {
732
732
  video: "SW_SECURE_DECODE",
733
733
  audio: "SW_SECURE_CRYPTO",
734
734
  scheme: "cbcs"
735
735
  };
736
- function Ke(e) {
737
- if (!j()) return;
736
+ function qe(e) {
737
+ if (!A()) return;
738
738
  let t = (e, t) => ({
739
739
  contentType: e,
740
740
  robustness: t,
741
- encryptionScheme: P.scheme
741
+ encryptionScheme: N.scheme
742
742
  });
743
- Ge(e)("com.widevine.alpha", [{
743
+ Ke(e)("com.widevine.alpha", [{
744
744
  initDataTypes: ["cenc"],
745
745
  distinctiveIdentifier: "optional",
746
746
  persistentState: "optional",
747
747
  sessionTypes: ["temporary"],
748
- audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", P.audio)],
749
- videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", P.video)]
748
+ audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", N.audio)],
749
+ videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", N.video)]
750
750
  }]).then((e) => e.createMediaKeys()).catch(() => {});
751
751
  }
752
- function F(e) {
753
- let t = I(e);
752
+ function P(e) {
753
+ let t = F(e);
754
754
  if (/^avc[13]/.test(t)) return "avc";
755
755
  if (/^(hvc1|hev1)/.test(t)) return "hevc";
756
756
  if (/^(dvh1|dvhe)/.test(t)) return "dv";
757
757
  if (t.startsWith("av01")) return "av1";
758
758
  if (/^vp0?9/.test(t)) return "vp9";
759
759
  }
760
- function I(e) {
760
+ function F(e) {
761
761
  return (e ?? "").trim().toLowerCase();
762
762
  }
763
- var qe = {
763
+ var Je = {
764
764
  hevc: "hvc1.1.6.L93.90",
765
765
  dv: "dvh1.05.06",
766
766
  av1: "av01.0.05M.08",
767
767
  vp9: "vp09.00.10.08"
768
- }, Je = /* @__PURE__ */ new Map(), L = /* @__PURE__ */ new Map();
769
- function Ye(e) {
770
- let t = I(e), n = Je.get(t);
768
+ }, Ye = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new Map();
769
+ function Xe(e) {
770
+ let t = F(e), n = Ye.get(t);
771
771
  if (n) return n;
772
772
  let r = {
773
773
  initDataTypes: ["cenc"],
@@ -776,32 +776,32 @@ function Ye(e) {
776
776
  sessionTypes: ["temporary"],
777
777
  videoCapabilities: [{
778
778
  contentType: `video/mp4; codecs="${e.trim()}"`,
779
- robustness: P.video,
780
- encryptionScheme: P.scheme
779
+ robustness: N.video,
780
+ encryptionScheme: N.scheme
781
781
  }]
782
782
  }, i = (async () => {
783
783
  try {
784
- return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", N("com.widevine.alpha", [r])), !0;
784
+ return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", M("com.widevine.alpha", [r])), !0;
785
785
  } catch {
786
786
  return !1;
787
787
  }
788
- })().then((e) => (L.set(t, e), e));
789
- return Je.set(t, i), i;
788
+ })().then((e) => (I.set(t, e), e));
789
+ return Ye.set(t, i), i;
790
790
  }
791
- function Xe() {
792
- if (j()) for (let e of Object.values(qe)) Ye(e);
791
+ function Ze() {
792
+ if (A()) for (let e of Object.values(Je)) Xe(e);
793
793
  }
794
- function Ze(e) {
795
- let t = F(e);
796
- if (t) return t === "avc" ? !0 : L.get(I(e)) ?? L.get(I(qe[t]));
794
+ function Qe(e) {
795
+ let t = P(e);
796
+ if (t) return t === "avc" ? !0 : I.get(F(e)) ?? I.get(F(Je[t]));
797
797
  }
798
798
  //#endregion
799
799
  //#region src/core/drm/support.ts
800
- var Qe = 5e3, $e = "video/mp4; codecs=\"avc1.42E01E\"", et = "audio/mp4; codecs=\"mp4a.40.2\"", tt = {
800
+ var $e = 5e3, et = "video/mp4; codecs=\"avc1.42E01E\"", tt = "audio/mp4; codecs=\"mp4a.40.2\"", nt = {
801
801
  widevine: ["com.widevine.alpha"],
802
802
  fairplay: ["com.apple.fps"]
803
803
  };
804
- function nt(e) {
804
+ function rt(e) {
805
805
  return e === "fairplay" ? [{
806
806
  initDataTypes: [
807
807
  "sinf",
@@ -809,30 +809,30 @@ function nt(e) {
809
809
  "cenc"
810
810
  ],
811
811
  videoCapabilities: [{
812
- contentType: $e,
812
+ contentType: et,
813
813
  robustness: "",
814
814
  encryptionScheme: "cbcs"
815
815
  }],
816
816
  audioCapabilities: [{
817
- contentType: et,
817
+ contentType: tt,
818
818
  robustness: "",
819
819
  encryptionScheme: "cbcs"
820
820
  }]
821
- }] : N("com.widevine.alpha", [{
821
+ }] : M("com.widevine.alpha", [{
822
822
  initDataTypes: ["cenc"],
823
823
  videoCapabilities: [{
824
- contentType: $e,
825
- robustness: P.video,
826
- encryptionScheme: P.scheme
824
+ contentType: et,
825
+ robustness: N.video,
826
+ encryptionScheme: N.scheme
827
827
  }],
828
828
  audioCapabilities: [{
829
- contentType: et,
830
- robustness: P.audio,
831
- encryptionScheme: P.scheme
829
+ contentType: tt,
830
+ robustness: N.audio,
831
+ encryptionScheme: N.scheme
832
832
  }]
833
833
  }]);
834
834
  }
835
- function rt(e, t) {
835
+ function it(e, t) {
836
836
  return new Promise((n, r) => {
837
837
  let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
838
838
  e.then((e) => {
@@ -842,8 +842,8 @@ function rt(e, t) {
842
842
  });
843
843
  });
844
844
  }
845
- async function it(e = {}) {
846
- let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Qe, r = {};
845
+ async function at(e = {}) {
846
+ let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? $e, r = {};
847
847
  if (typeof window < "u" && window.isSecureContext === !1) return {
848
848
  verdict: "insecure-context",
849
849
  detail: r
@@ -855,7 +855,7 @@ async function it(e = {}) {
855
855
  };
856
856
  let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
857
857
  for (let e of t) {
858
- let t = tt[e];
858
+ let t = nt[e];
859
859
  if (!t) {
860
860
  r[e] = "unknown system";
861
861
  continue;
@@ -866,7 +866,7 @@ async function it(e = {}) {
866
866
  break;
867
867
  }
868
868
  try {
869
- return await rt((await rt(i(n, nt(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
869
+ return await it((await it(i(n, rt(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
870
870
  verdict: "supported",
871
871
  system: e,
872
872
  detail: r
@@ -890,32 +890,32 @@ async function it(e = {}) {
890
890
  }
891
891
  //#endregion
892
892
  //#region src/core/manifest.ts
893
- var at = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
894
- function ot(e) {
895
- return at.test(e);
893
+ var ot = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
894
+ function st(e) {
895
+ return ot.test(e);
896
896
  }
897
897
  //#endregion
898
898
  //#region src/core/env.ts
899
- var st = {
899
+ var ct = {
900
900
  integration: "https://feed-dev.oddin-video.gg",
901
901
  production: "https://feed.oddin-video.gg"
902
902
  };
903
- function ct(e) {
904
- let t = Object.prototype.hasOwnProperty.call(st, e) ? st[e] : void 0;
903
+ function lt(e) {
904
+ let t = Object.prototype.hasOwnProperty.call(ct, e) ? ct[e] : void 0;
905
905
  if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
906
906
  return t;
907
907
  }
908
908
  //#endregion
909
909
  //#region src/core/connectivity.ts
910
- function R() {
910
+ function L() {
911
911
  return typeof navigator > "u" || navigator.onLine !== !1;
912
912
  }
913
- function lt() {
913
+ function ut() {
914
914
  let e = /* @__PURE__ */ new Set(), t = (t) => {
915
915
  for (let n of Array.from(e)) n(t);
916
916
  }, n = () => t(!0), r = () => t(!1), i = typeof window < "u" && typeof window.addEventListener == "function";
917
917
  return i && (window.addEventListener("online", n), window.addEventListener("offline", r)), {
918
- isOnline: R,
918
+ isOnline: L,
919
919
  onChange(t) {
920
920
  return e.add(t), () => {
921
921
  e.delete(t);
@@ -928,32 +928,32 @@ function lt() {
928
928
  }
929
929
  //#endregion
930
930
  //#region src/core/stats.ts
931
- var ut = { droppedFrames: 0 };
932
- function dt(e) {
931
+ var dt = { droppedFrames: 0 };
932
+ function ft(e) {
933
933
  try {
934
934
  return new URL(e).host;
935
935
  } catch {
936
936
  return "";
937
937
  }
938
938
  }
939
- var ft = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
940
- function pt(e) {
939
+ var pt = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
940
+ function mt(e) {
941
941
  if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
942
942
  let t = "", n = -1, r = performance.getEntriesByType("resource");
943
- for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || ft.test(i.name)) && i.startTime >= n) {
944
- let e = dt(i.name);
943
+ for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || pt.test(i.name)) && i.startTime >= n) {
944
+ let e = ft(i.name);
945
945
  e && (t = e, n = i.startTime);
946
946
  }
947
947
  return t;
948
948
  }
949
- function z(e) {
949
+ function R(e) {
950
950
  let t = e.getVideoPlaybackQuality?.();
951
951
  return {
952
952
  dropped: t?.droppedVideoFrames ?? 0,
953
953
  totalFrames: t?.totalVideoFrames ?? 0
954
954
  };
955
955
  }
956
- var mt = class {
956
+ var ht = class {
957
957
  video;
958
958
  baseFrames = 0;
959
959
  baseDropped = 0;
@@ -963,7 +963,7 @@ var mt = class {
963
963
  this.video = e;
964
964
  }
965
965
  read() {
966
- let e = z(this.video);
966
+ let e = R(this.video);
967
967
  return e.totalFrames < this.lastFrames && (this.baseFrames += this.lastFrames), e.dropped < this.lastDropped && (this.baseDropped += this.lastDropped), this.lastFrames = e.totalFrames, this.lastDropped = e.dropped, {
968
968
  dropped: this.baseDropped + e.dropped,
969
969
  totalFrames: this.baseFrames + e.totalFrames
@@ -976,7 +976,7 @@ var mt = class {
976
976
  };
977
977
  }
978
978
  };
979
- function ht(e, t) {
979
+ function gt(e, t) {
980
980
  let n = [
981
981
  ["playing", () => t("playing")],
982
982
  ["waiting", () => t("buffering")],
@@ -993,8 +993,8 @@ function ht(e, t) {
993
993
  }
994
994
  //#endregion
995
995
  //#region src/core/engine/native.ts
996
- var gt = 2e3, _t = 3, B = 500, vt = 6e3, yt = .25, bt = 250, xt = .05, St = 4, Ct = 12e3, wt = .25, Tt = 1e3;
997
- function Et(e) {
996
+ var _t = 2e3, vt = 3, z = 500, yt = 6e3, bt = .25, xt = 250, St = .05, Ct = 4, wt = 12e3, Tt = .25, Et = 1e3;
997
+ function Dt(e) {
998
998
  try {
999
999
  let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
1000
1000
  return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
@@ -1002,20 +1002,20 @@ function Et(e) {
1002
1002
  return;
1003
1003
  }
1004
1004
  }
1005
- function V(e) {
1005
+ function B(e) {
1006
1006
  return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
1007
1007
  }
1008
- function H() {
1008
+ function V() {
1009
1009
  if (typeof window > "u") return !1;
1010
1010
  let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
1011
1011
  return e || t;
1012
1012
  }
1013
- function Dt() {
1014
- if (typeof navigator > "u" || !H()) return !1;
1013
+ function Ot() {
1014
+ if (typeof navigator > "u" || !V()) return !1;
1015
1015
  let e = navigator.userAgent ?? "";
1016
1016
  return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
1017
1017
  }
1018
- var U = class {
1018
+ var H = class {
1019
1019
  name = "native";
1020
1020
  deps;
1021
1021
  onLoaded;
@@ -1045,7 +1045,7 @@ var U = class {
1045
1045
  frameCounter;
1046
1046
  detachFrames = null;
1047
1047
  constructor(e) {
1048
- this.deps = e, this.frameCounter = new mt(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
1048
+ this.deps = e, this.frameCounter = new ht(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
1049
1049
  }
1050
1050
  async load() {
1051
1051
  this.detachFrames ??= this.frameCounter.attach();
@@ -1064,9 +1064,9 @@ var U = class {
1064
1064
  let i = !this.loadStarted;
1065
1065
  this.onLoaded = i ? void 0 : () => r({ type: "ready" }), this.onError = () => r({
1066
1066
  type: "error",
1067
- error: R() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
1067
+ error: L() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
1068
1068
  fatal: !0
1069
- }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = kt(t.manifestUrl, t.analytics?.sid), e.load();
1069
+ }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = At(t.manifestUrl, t.analytics?.sid), e.load();
1070
1070
  }
1071
1071
  startLoad() {
1072
1072
  this.loadStarted || (this.loadStarted = !0, this.restorePreload());
@@ -1094,7 +1094,7 @@ var U = class {
1094
1094
  };
1095
1095
  this.onEncrypted = (n) => {
1096
1096
  let a = n;
1097
- a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Et(a.initData), (async () => {
1097
+ a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Dt(a.initData), (async () => {
1098
1098
  try {
1099
1099
  let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
1100
1100
  initDataTypes: [a.initDataType],
@@ -1194,10 +1194,10 @@ var U = class {
1194
1194
  droppedFrames: t.dropped,
1195
1195
  decodedFrames: t.totalFrames
1196
1196
  };
1197
- if (this.cdnHost ||= pt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1197
+ if (this.cdnHost ||= mt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1198
1198
  n.isLive = !0;
1199
1199
  let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
1200
- Number.isFinite(r) && (n.atLiveEdge = r <= St, !e.paused && r >= 0 && (n.latencySeconds = r));
1200
+ Number.isFinite(r) && (n.atLiveEdge = r <= Ct, !e.paused && r >= 0 && (n.latencySeconds = r));
1201
1201
  } else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
1202
1202
  return n;
1203
1203
  }
@@ -1209,30 +1209,30 @@ var U = class {
1209
1209
  }
1210
1210
  watchRefocus() {
1211
1211
  this.deps.snapToLiveOnRefocus === !1 || typeof document > "u" || this.onVisibility || (this.onVisibility = () => {
1212
- let e = W();
1212
+ let e = U();
1213
1213
  if (document.visibilityState === "hidden") {
1214
1214
  this.hiddenSince = e, this.cancelRefocus();
1215
1215
  return;
1216
1216
  }
1217
1217
  let t = this.hiddenSince;
1218
- this.hiddenSince = null, t != null && e - t >= gt && this.armRefocus();
1218
+ this.hiddenSince = null, t != null && e - t >= _t && this.armRefocus();
1219
1219
  }, this.onPageShow = (e) => {
1220
1220
  e.persisted && this.armRefocus();
1221
1221
  }, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
1222
1222
  }
1223
1223
  armRefocus() {
1224
1224
  if (this.cancelRefocus(), Number.isFinite(this.deps.video.duration)) return;
1225
- let e = this.liveEnd(), t = W, n = t(), r = 0, i = () => {
1225
+ let e = this.liveEnd(), t = U, n = t(), r = 0, i = () => {
1226
1226
  if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
1227
- r += B;
1228
- let a = this.liveEnd(), o = a != null && (e == null || a >= e + yt), s = Math.max(r, t() - n) >= vt;
1227
+ r += z;
1228
+ let a = this.liveEnd(), o = a != null && (e == null || a >= e + bt), s = Math.max(r, t() - n) >= yt;
1229
1229
  if (o || s && a != null) {
1230
1230
  this.snapToLive();
1231
1231
  return;
1232
1232
  }
1233
- this.refocusTimer = setTimeout(i, B);
1233
+ this.refocusTimer = setTimeout(i, z);
1234
1234
  };
1235
- this.refocusTimer = setTimeout(i, B);
1235
+ this.refocusTimer = setTimeout(i, z);
1236
1236
  }
1237
1237
  cancelRefocus() {
1238
1238
  this.refocusTimer != null && clearTimeout(this.refocusTimer), this.refocusTimer = null;
@@ -1245,24 +1245,24 @@ var U = class {
1245
1245
  }, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
1246
1246
  if (e.duration !== Infinity) return;
1247
1247
  this.checkEndStale();
1248
- let t = Ot(e, e.currentTime);
1249
- t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= xt) && (this.bufferedAdvancedAt = W()), this.lastBufferedEnd = t);
1250
- }, bt);
1248
+ let t = kt(e, e.currentTime);
1249
+ t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= St) && (this.bufferedAdvancedAt = U()), this.lastBufferedEnd = t);
1250
+ }, xt);
1251
1251
  }
1252
1252
  checkEndStale() {
1253
1253
  if (this.endedEmitted) return;
1254
- let e = W(), t = this.lastTickAt == null ? 0 : e - this.lastTickAt;
1254
+ let e = U(), t = this.lastTickAt == null ? 0 : e - this.lastTickAt;
1255
1255
  this.lastTickAt = e;
1256
1256
  let n = this.liveEnd();
1257
1257
  if (n == null) return;
1258
- let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= wt;
1258
+ let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= Tt;
1259
1259
  this.lastSeekableEnd = n;
1260
1260
  let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
1261
- if (r || t > Tt || a || i.paused) {
1261
+ if (r || t > Et || a || i.paused) {
1262
1262
  this.edgeStampedAt = e;
1263
1263
  return;
1264
1264
  }
1265
- e - (this.edgeStampedAt ?? e) > Ct && (this.endedEmitted = !0, this.deps.emit({
1265
+ e - (this.edgeStampedAt ?? e) > wt && (this.endedEmitted = !0, this.deps.emit({
1266
1266
  type: "ended",
1267
1267
  reason: "stalled"
1268
1268
  }));
@@ -1276,9 +1276,9 @@ var U = class {
1276
1276
  liveEdgeEstimate() {
1277
1277
  let e = this.deps.video;
1278
1278
  if (e.duration !== Infinity) return null;
1279
- let t = this.liveEnd(), n = Ot(e, e.currentTime) ?? this.lastBufferedEnd;
1279
+ let t = this.liveEnd(), n = kt(e, e.currentTime) ?? this.lastBufferedEnd;
1280
1280
  if (n != null) {
1281
- let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (W() - e) / 1e3));
1281
+ let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (U() - e) / 1e3));
1282
1282
  (t == null || r > t) && (t = r);
1283
1283
  }
1284
1284
  return t != null && Number.isFinite(t) ? t : null;
@@ -1292,7 +1292,7 @@ var U = class {
1292
1292
  snapToLive() {
1293
1293
  let e = this.deps.video, t = this.liveEnd();
1294
1294
  if (t == null) return;
1295
- let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - _t, r);
1295
+ let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - vt, r);
1296
1296
  try {
1297
1297
  e.currentTime = i;
1298
1298
  } catch {}
@@ -1310,10 +1310,10 @@ var U = class {
1310
1310
  } catch {}
1311
1311
  }
1312
1312
  };
1313
- function W() {
1313
+ function U() {
1314
1314
  return typeof performance < "u" ? performance.now() : Date.now();
1315
1315
  }
1316
- function Ot(e, t) {
1316
+ function kt(e, t) {
1317
1317
  let n = e.buffered;
1318
1318
  if (!n || !Number.isFinite(t)) return null;
1319
1319
  for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
@@ -1322,12 +1322,12 @@ function Ot(e, t) {
1322
1322
  }
1323
1323
  return null;
1324
1324
  }
1325
- function kt(e, t) {
1325
+ function At(e, t) {
1326
1326
  return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
1327
1327
  }
1328
1328
  //#endregion
1329
1329
  //#region src/core/drm/signedUrl.ts
1330
- function G(e, t = Date.now()) {
1330
+ function W(e, t = Date.now()) {
1331
1331
  if (!e) return !1;
1332
1332
  let n;
1333
1333
  try {
@@ -1339,13 +1339,13 @@ function G(e, t = Date.now()) {
1339
1339
  }
1340
1340
  //#endregion
1341
1341
  //#region src/core/drm/xhrBody.ts
1342
- var At = 4096;
1343
- function jt(e) {
1342
+ var jt = 4096;
1343
+ function Mt(e) {
1344
1344
  if (!e || typeof e != "object") return;
1345
1345
  let { response: t } = e;
1346
1346
  if (typeof t == "string") return t;
1347
1347
  let n;
1348
- if (Object.prototype.toString.call(t) === "[object ArrayBuffer]" ? n = new Uint8Array(t) : ArrayBuffer.isView(t) && (n = new Uint8Array(t.buffer, t.byteOffset, t.byteLength)), !(!n || n.byteLength === 0 || n.byteLength > At)) try {
1348
+ if (Object.prototype.toString.call(t) === "[object ArrayBuffer]" ? n = new Uint8Array(t) : ArrayBuffer.isView(t) && (n = new Uint8Array(t.buffer, t.byteOffset, t.byteLength)), !(!n || n.byteLength === 0 || n.byteLength > jt)) try {
1349
1349
  return new TextDecoder().decode(n);
1350
1350
  } catch {
1351
1351
  return;
@@ -1353,8 +1353,8 @@ function jt(e) {
1353
1353
  }
1354
1354
  //#endregion
1355
1355
  //#region src/core/engine/prefetch.ts
1356
- var Mt = 15e3, Nt = 5e3, Pt = 6, Ft = 4e3, It = 2;
1357
- function K(e) {
1356
+ var Nt = 15e3, Pt = 5e3, Ft = 6, It = 4e3, Lt = 2;
1357
+ function G(e) {
1358
1358
  try {
1359
1359
  let t = new URL(e);
1360
1360
  return t.searchParams.delete("CMCD"), t.toString();
@@ -1362,7 +1362,7 @@ function K(e) {
1362
1362
  return e;
1363
1363
  }
1364
1364
  }
1365
- var Lt = class {
1365
+ var Rt = class {
1366
1366
  cmcd;
1367
1367
  entries = /* @__PURE__ */ new Map();
1368
1368
  keyed = /* @__PURE__ */ new Set();
@@ -1391,20 +1391,20 @@ var Lt = class {
1391
1391
  }
1392
1392
  prefetch(e, t, n) {
1393
1393
  if (!this.isActive(t)) return;
1394
- let r = K(e);
1394
+ let r = G(e);
1395
1395
  if (this.entries.has(r)) return;
1396
1396
  let i = this.perTrack.get(t) ?? 0;
1397
- i >= Pt || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Mt), this.stats.started += 1);
1397
+ i >= Ft || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Nt), this.stats.started += 1);
1398
1398
  }
1399
1399
  prefetchHint(e, t) {
1400
- let n = K(e);
1400
+ let n = G(e);
1401
1401
  if (this.entries.has(n)) return;
1402
1402
  let r = this.hints.get(t) ?? [];
1403
- for (; r.length >= It;) {
1403
+ for (; r.length >= Lt;) {
1404
1404
  let e = r.shift();
1405
1405
  e !== void 0 && this.drop(e) && (this.stats.hintDropped += 1);
1406
1406
  }
1407
- r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, Ft), this.stats.hintStarted += 1;
1407
+ r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, It), this.stats.hintStarted += 1;
1408
1408
  }
1409
1409
  dropHints(e) {
1410
1410
  for (let t of this.hints.get(e) ?? []) this.drop(t) && (this.stats.hintDropped += 1);
@@ -1437,7 +1437,7 @@ var Lt = class {
1437
1437
  }, r);
1438
1438
  }
1439
1439
  take(e) {
1440
- let t = K(e), n = this.entries.get(t);
1440
+ let t = G(e), n = this.entries.get(t);
1441
1441
  return n && this.entries.delete(t), n;
1442
1442
  }
1443
1443
  destroy() {
@@ -1457,14 +1457,14 @@ var Lt = class {
1457
1457
  }
1458
1458
  }
1459
1459
  };
1460
- function Rt(t) {
1461
- let n = e.DefaultConfig?.loader;
1462
- if (typeof n != "function") return;
1463
- class r extends n {
1460
+ function zt(t, n) {
1461
+ let r = typeof n == "function" ? n : e.DefaultConfig?.loader;
1462
+ if (typeof r != "function") return;
1463
+ class i extends r {
1464
1464
  served = !1;
1465
1465
  cancelled = !1;
1466
1466
  entry;
1467
- stats = zt();
1467
+ stats = Bt();
1468
1468
  load(e, n, r) {
1469
1469
  let i = e.rangeEnd ? void 0 : t.take(e.url);
1470
1470
  if (!i) {
@@ -1476,7 +1476,7 @@ function Rt(t) {
1476
1476
  i.hint ? t.stats.hintFailed += 1 : t.stats.failed += 1;
1477
1477
  }, s = () => {
1478
1478
  !this.cancelled && this.served && (i.abort.abort(), o(), this.served = !1, this.entry = void 0, super.load(e, n, r));
1479
- }, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || Nt, u = setTimeout(s, l);
1479
+ }, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || Pt, u = setTimeout(s, l);
1480
1480
  i.headers.then(() => {
1481
1481
  clearTimeout(u);
1482
1482
  let e = c?.maxLoadTimeMs;
@@ -1507,9 +1507,9 @@ function Rt(t) {
1507
1507
  super.abort();
1508
1508
  }
1509
1509
  }
1510
- return r;
1510
+ return i;
1511
1511
  }
1512
- function zt() {
1512
+ function Bt() {
1513
1513
  return {
1514
1514
  aborted: !1,
1515
1515
  loaded: 0,
@@ -1533,10 +1533,10 @@ function zt() {
1533
1533
  }
1534
1534
  };
1535
1535
  }
1536
- function Bt(e) {
1536
+ function Vt(e) {
1537
1537
  return e === "audio" ? "audio" : "main";
1538
1538
  }
1539
- function Vt(e, t) {
1539
+ function Ht(e, t) {
1540
1540
  let n = [];
1541
1541
  t.initSegment?.url && !t.initSegment.data && n.push({
1542
1542
  url: t.initSegment.url,
@@ -1553,7 +1553,7 @@ function Vt(e, t) {
1553
1553
  });
1554
1554
  return n;
1555
1555
  }
1556
- function Ht(e) {
1556
+ function Ut(e) {
1557
1557
  let t = e, n = t?.preloadHint;
1558
1558
  if (!n || !t?.url || n.TYPE !== "PART" || n["BYTERANGE-START"] !== void 0 || n["BYTERANGE-LENGTH"] !== void 0) return null;
1559
1559
  let r = n.URI;
@@ -1566,16 +1566,16 @@ function Ht(e) {
1566
1566
  }
1567
1567
  //#endregion
1568
1568
  //#region src/core/percentile.ts
1569
- function q(e, t) {
1569
+ function K(e, t) {
1570
1570
  return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
1571
1571
  }
1572
1572
  //#endregion
1573
1573
  //#region src/core/engine/hls.ts
1574
- function Ut() {
1574
+ function Wt() {
1575
1575
  return e.isSupported();
1576
1576
  }
1577
- var Wt = 3, Gt = 1e6, Kt = 20, qt = 1e4, Jt = 3, Yt = 5, Xt = 3, Zt = 1e4, Qt = 3e4, $t = 12e3, en = 3e3, tn = .02, nn = 6e3, rn = .5, an = 3, on = .5, sn = 1.1, cn = .25, ln = 5e3, un = 4e3, dn = 2, fn = 5, pn = 2, mn = 2, hn = 4, gn = 4, _n = 2e3, vn = 3e4, yn = 1, bn = 2;
1578
- function xn(e, t, n) {
1577
+ var Gt = 3, Kt = 1e6, qt = 20, Jt = 1e4, Yt = 3, Xt = 5, Zt = 3, Qt = 1e4, $t = 3e4, en = 12e3, tn = 3e3, nn = .02, rn = 6e3, an = .5, on = 3, sn = .5, cn = 1.1, ln = .25, un = 5e3, dn = 4e3, fn = 2, pn = 5, mn = 2, hn = 2, gn = 4, _n = 4, vn = 2e3, yn = 3e4, bn = 1, xn = 2, Sn = .5, Cn = .6, wn = 2, Tn = 1.5, En = 1e4, q = 8, Dn = 12e4, On = 6e4;
1578
+ function J(e, t, n) {
1579
1579
  if (n <= 0 || t < 0 || t >= e.length) return t;
1580
1580
  let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
1581
1581
  for (; t + 1 < e.length && r(t + 1, t);) t++;
@@ -1584,11 +1584,14 @@ function xn(e, t, n) {
1584
1584
  for (let t = 0; t < n && a + 1 < e.length; t++) a = i(a + 1);
1585
1585
  return a;
1586
1586
  }
1587
- var Sn = .2, Cn = 30, wn = 2, Tn = 2, En = 2, Dn = 9, On = .5, kn = 64, An = 1e4, jn = 8, Mn = .6, Nn = .4, Pn = .4, Fn = 2, In = 6e4, J = .5, Ln = 3.5, Rn = 300;
1588
- function zn(e) {
1587
+ function Y() {
1588
+ return typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1;
1589
+ }
1590
+ var kn = .2, An = 30, jn = 2, Mn = 2, Nn = 2, Pn = 9, Fn = .5, In = 64, Ln = 1e4, Rn = 8, zn = .6, Bn = .4, Vn = .4, Hn = 2, Un = 6e4, X = .5, Wn = 3.5, Gn = 300;
1591
+ function Kn(e) {
1589
1592
  return (e?.part ?? e?.frag)?.stats;
1590
1593
  }
1591
- function Bn() {
1594
+ function qn() {
1592
1595
  if (typeof navigator > "u") return 0;
1593
1596
  try {
1594
1597
  let e = navigator.connection?.rtt;
@@ -1597,20 +1600,20 @@ function Bn() {
1597
1600
  return 0;
1598
1601
  }
1599
1602
  }
1600
- function Vn(e) {
1603
+ function Jn(e) {
1601
1604
  if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
1602
1605
  delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
1603
1606
  return;
1604
1607
  }
1605
- e.liveSyncDuration ??= En;
1606
- let t = Math.max(12, e.liveSyncDuration + Dn);
1607
- (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Hn(e, e.liveSyncDuration);
1608
+ e.liveSyncDuration ??= Nn;
1609
+ let t = Math.max(12, e.liveSyncDuration + Pn);
1610
+ (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Yn(e, e.liveSyncDuration);
1608
1611
  }
1609
- function Hn(e, t) {
1612
+ function Yn(e, t) {
1610
1613
  let n = (e, t, n) => Math.min(n, Math.max(t, e));
1611
1614
  e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
1612
1615
  }
1613
- var Un = class {
1616
+ var Xn = class {
1614
1617
  name = "hls";
1615
1618
  hls = null;
1616
1619
  deps;
@@ -1641,6 +1644,7 @@ var Un = class {
1641
1644
  networkRetryTimer = null;
1642
1645
  licenseRetryTimer = null;
1643
1646
  offlineHold = !1;
1647
+ onOffline = null;
1644
1648
  onOnline = null;
1645
1649
  onVisibility = null;
1646
1650
  onSeeking = null;
@@ -1678,6 +1682,12 @@ var Un = class {
1678
1682
  liveRetargets = 0;
1679
1683
  holdBackEnabled;
1680
1684
  holdBackSamples = [];
1685
+ headroomSamples = [];
1686
+ headroomGranted = !1;
1687
+ lastStallAt = 0;
1688
+ headroomRegrantAt = 0;
1689
+ headroomUngated = !1;
1690
+ playingSince = 0;
1681
1691
  holdBackBase = -1;
1682
1692
  holdBackStepCount = 0;
1683
1693
  holdBackApplied = 0;
@@ -1706,11 +1716,11 @@ var Un = class {
1706
1716
  frameCounter;
1707
1717
  detachFrames = null;
1708
1718
  constructor(e) {
1709
- this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new mt(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
1719
+ this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new ht(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
1710
1720
  }
1711
1721
  async load() {
1712
1722
  this.detachFrames ??= this.frameCounter.attach();
1713
- let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = V(r) && H(), o = !!e.drm?.widevine?.licenseUrl && !a;
1723
+ let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = B(r) && V(), o = !!e.drm?.widevine?.licenseUrl && !a;
1714
1724
  if (e.drmEnabled && !o) {
1715
1725
  i({
1716
1726
  type: "error",
@@ -1719,21 +1729,23 @@ var Un = class {
1719
1729
  });
1720
1730
  return;
1721
1731
  }
1722
- e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ke(r), Xe()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1732
+ e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (qe(r), Ze()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1723
1733
  let e = this.hls;
1724
1734
  if (document.visibilityState !== "visible" || !e) return;
1725
1735
  let t = e.liveSyncPosition;
1726
1736
  if (typeof t != "number") return;
1727
1737
  let n = typeof e.targetLatency == "number" && e.targetLatency > 0 ? e.targetLatency : 3;
1728
1738
  t - r.currentTime > Math.max(n * 3, 8) && (r.currentTime = t);
1729
- }, document.addEventListener("visibilitychange", this.onVisibility)), typeof window < "u" && (this.onOnline = () => {
1730
- if (this.offlineHold && (this.offlineHold = !1, this.networkRecoveries = 0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), !this.stopped && this.hls)) {
1739
+ }, document.addEventListener("visibilitychange", this.onVisibility)), typeof window < "u" && (this.onOffline = () => {
1740
+ this.offlineHold = !0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.lastAdvanceMs = this.lastAdvanceMs ? Date.now() : 0, this.resetStarvationWindow(), this.clearKick();
1741
+ }, this.onOnline = () => {
1742
+ if (this.offlineHold && (this.offlineHold = !1, this.networkRecoveries = 0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), !this.stopped && this.hls && this.loadStarted && !this.loadSuspended)) {
1731
1743
  this.lastAdvanceMs = Date.now(), this.lastFragLoadingMs = 0, this.resetStarvationWindow(), this.resetChaseWindow(), this.clearKick();
1732
1744
  try {
1733
- this.hls.startLoad();
1745
+ this.hls.startLoad(-1);
1734
1746
  } catch {}
1735
1747
  }
1736
- }, window.addEventListener("online", this.onOnline)), this.onSeeking = () => {
1748
+ }, window.addEventListener("offline", this.onOffline), window.addEventListener("online", this.onOnline), L() || this.onOffline()), this.onSeeking = () => {
1737
1749
  this.clampOverSeek(), this.loadSuspended && (this.resumeLoading(), this.schedulePauseSuspend());
1738
1750
  }, r.addEventListener("seeking", this.onSeeking), this.onTimeUpdate = () => this.updateCatchUpBand(), r.addEventListener("timeupdate", this.onTimeUpdate), this.onPause = () => this.schedulePauseSuspend(), this.onPlay = () => this.resumeLoading(), r.addEventListener("pause", this.onPause), r.addEventListener("play", this.onPlay), this.sizeCapManaged && typeof ResizeObserver < "u" && (this.capObserver = new ResizeObserver(() => this.onMediaResize()), this.capObserver.observe(r), this.watchDprChanges());
1739
1751
  }
@@ -1749,7 +1761,7 @@ var Un = class {
1749
1761
  }
1750
1762
  this.loadSuspended = !0;
1751
1763
  }
1752
- }, ln));
1764
+ }, un));
1753
1765
  }
1754
1766
  resumeLoading() {
1755
1767
  if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
@@ -1765,7 +1777,7 @@ var Un = class {
1765
1777
  watchDprChanges() {
1766
1778
  if (typeof matchMedia != "function") return;
1767
1779
  this.unwatchDprChanges();
1768
- let e = typeof self < "u" && self.devicePixelRatio || 1, t = matchMedia(`(resolution: ${e}dppx)`);
1780
+ let e = Y(), t = matchMedia(`(resolution: ${e}dppx)`);
1769
1781
  if (typeof t.addEventListener != "function") return;
1770
1782
  let n = () => {
1771
1783
  this.onMediaResize(), this.watchDprChanges();
@@ -1781,7 +1793,7 @@ var Un = class {
1781
1793
  let t = e.liveSyncPosition;
1782
1794
  if (typeof t != "number" || !Number.isFinite(t)) return;
1783
1795
  let { video: n } = this.deps;
1784
- n.currentTime <= t + On || (n.currentTime = t);
1796
+ n.currentTime <= t + Fn || (n.currentTime = t);
1785
1797
  }
1786
1798
  reanchorPartTimeline(e, t) {
1787
1799
  let { frag: n, part: r } = t;
@@ -1793,7 +1805,7 @@ var Un = class {
1793
1805
  let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
1794
1806
  if (!s) return;
1795
1807
  let c = a.startPTS - s.start;
1796
- if (!(!Number.isFinite(c) || Math.abs(c) < tn)) {
1808
+ if (!(!Number.isFinite(c) || Math.abs(c) < nn)) {
1797
1809
  for (let e of i.fragments) e && e.setStart(e.start + c);
1798
1810
  i.fragmentHint?.setStart(i.fragmentHint.start + c), this.deps.debug === !0 && console.info(`havik-player: LL-HLS timeline re-anchored by ${c >= 0 ? "+" : ""}${c.toFixed(3)}s at sn ${n.sn} (level ${n.level})`);
1799
1811
  }
@@ -1801,7 +1813,7 @@ var Un = class {
1801
1813
  startHls() {
1802
1814
  let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
1803
1815
  this.clearKick(), this.resetStarvationWindow(), this.resetChaseWindow(), this.resetFrameDropWindow(), this.lastFragLoadingMs = 0, this.lastEndSN = -1, this.lastAdvanceMs = 0;
1804
- let u = n.drmEnabled && !!(n.drm?.widevine?.licenseUrl || n.drm?.fairplay?.licenseUrl), d = V(this.deps.video) && H(), f = {
1816
+ let u = n.drmEnabled && !!(n.drm?.widevine?.licenseUrl || n.drm?.fairplay?.licenseUrl), d = B(this.deps.video) && V(), f = {
1805
1817
  debug: s === !0,
1806
1818
  enableWorker: !o,
1807
1819
  lowLatencyMode: o,
@@ -1816,24 +1828,24 @@ var Un = class {
1816
1828
  emeEnabled: !0,
1817
1829
  drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
1818
1830
  drmSystemOptions: {
1819
- videoRobustness: P.video,
1820
- audioRobustness: P.audio,
1821
- videoEncryptionScheme: P.scheme,
1822
- audioEncryptionScheme: P.scheme
1831
+ videoRobustness: N.video,
1832
+ audioRobustness: N.audio,
1833
+ videoEncryptionScheme: N.scheme,
1834
+ audioEncryptionScheme: N.scheme
1823
1835
  },
1824
- ...j() ? { requestMediaKeySystemAccessFunc: Ge(t) } : {},
1836
+ ...A() ? { requestMediaKeySystemAccessFunc: Ke(t) } : {},
1825
1837
  licenseXhrSetup: (e, t) => {
1826
1838
  let o = performance.now(), s = () => {
1827
1839
  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, e.addEventListener("loadend", () => {
1828
1840
  this.licenseTimeMs === 0 && (this.licenseTimeMs = Math.max(1, Math.round(performance.now() - o)));
1829
1841
  });
1830
1842
  }, { freshLicenseUrl: c } = this.deps;
1831
- if (!c || !G(this.licenseUrl)) {
1843
+ if (!c || !W(this.licenseUrl)) {
1832
1844
  s();
1833
1845
  return;
1834
1846
  }
1835
1847
  let l = this.hls, u, d = new Promise((e) => {
1836
- u = setTimeout(() => e(void 0), Zt);
1848
+ u = setTimeout(() => e(void 0), Qt);
1837
1849
  });
1838
1850
  return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
1839
1851
  if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
@@ -1849,51 +1861,51 @@ var Un = class {
1849
1861
  ...c
1850
1862
  };
1851
1863
  this.prefetch?.destroy(), this.prefetch = null;
1852
- let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints === !0;
1864
+ let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints !== !1;
1853
1865
  if ((h || g) && !f.fLoader) {
1854
- let e = new Lt({
1866
+ let e = new Rt({
1855
1867
  sessionId: n.analytics?.sid,
1856
1868
  contentId: n.matchUrn
1857
- }), t = Rt(e);
1869
+ }), t = zt(e, f.loader);
1858
1870
  t && (this.prefetch = e, p = h, m = g, f.fLoader = t);
1859
1871
  }
1860
- Vn(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
1872
+ Jn(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
1861
1873
  let _ = new e(f);
1862
1874
  if (this.hls = _, this.armHoldBack(_, f), _.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(_, t)), _.on(e.Events.MANIFEST_PARSED, () => {
1863
1875
  this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(_), this.measureLadder(_), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
1864
1876
  }), _.on(e.Events.FRAG_BUFFERED, (e, t) => {
1865
1877
  t?.frag?.type === "main" && (this.kickKind !== "dead" && this.clearKick(), (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
1866
1878
  this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
1867
- }, Qt)));
1879
+ }, $t)));
1868
1880
  }), _.on(e.Events.FRAG_LOADING, (e, t) => {
1869
1881
  t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
1870
1882
  }), _.on(e.Events.FRAG_LOADED, (e, t) => {
1871
1883
  t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
1872
- let n = t?.frag, r = zn(t), i = r?.loaded;
1884
+ let n = t?.frag, r = Kn(t), i = r?.loaded;
1873
1885
  typeof i == "number" && (this.bytesLoaded += i), !this.reportedFirstBytes && typeof i == "number" && i > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
1874
1886
  let a = r?.loading;
1875
- a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length > kn && this.requestTimesMs.shift()), this.sampleHoldBack(t);
1887
+ a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length > In && this.requestTimesMs.shift()), this.sampleHoldBack(t), this.sampleHeadroom(t);
1876
1888
  let o = n?.url;
1877
1889
  if (o) {
1878
- let e = dt(o);
1890
+ let e = ft(o);
1879
1891
  e && (this.cdnHost = e);
1880
1892
  }
1881
1893
  }), _.on(e.Events.LEVEL_LOADED, (e, t) => {
1882
1894
  let n = t?.stats?.loaded;
1883
1895
  if (typeof n == "number" && (this.playlistBytesLoaded += n), this.reportedFirstPlaylist || (this.reportedFirstPlaylist = !0, l({ type: "firstPlaylist" })), this.detectedLowLatency) return;
1884
1896
  let r = t.details;
1885
- (r?.partList?.length || (r?.partTarget ?? 0) > 0) && (this.detectedLowLatency = !0, l({
1897
+ r?.partList?.length || (r?.partTarget ?? 0) > 0 ? (this.detectedLowLatency = !0, l({
1886
1898
  type: "lowLatencyDetected",
1887
1899
  value: !0
1888
- }));
1900
+ }), this.headroomUngated && (this.headroomUngated = !1, this.applySizeCapUnlessPending())) : r && !this.headroomUngated && (this.headroomUngated = !0, this.applySizeCapUnlessPending());
1889
1901
  }), _.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch && m) {
1890
1902
  let t = this.prefetch, n = this.deps.video, r = (e, r) => {
1891
1903
  if (n.paused) return;
1892
1904
  let i = e;
1893
1905
  if (!i?.live || !i.partList?.length || typeof i.edge != "number") return;
1894
1906
  let a = n.buffered, o = a.length ? a.end(a.length - 1) : 0;
1895
- if (i.edge - o > Wt * (i.partTarget || .5)) return;
1896
- let s = Ht(e);
1907
+ if (i.edge - o > Gt * (i.partTarget || .5)) return;
1908
+ let s = Ut(e);
1897
1909
  s && t.prefetchHint(s, r);
1898
1910
  };
1899
1911
  _.on(e.Events.LEVEL_LOADED, (e, t) => {
@@ -1905,15 +1917,15 @@ var Un = class {
1905
1917
  if (this.prefetch && p) {
1906
1918
  let t = this.prefetch;
1907
1919
  _.on(e.Events.KEY_LOADING, (e, n) => {
1908
- let r = n?.frag, i = Bt(r?.type);
1909
- if (r && t.isActive(i)) for (let e of Vt(_, r)) t.prefetch(e.url, i, e.kind);
1910
- }), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Bt(n?.frag?.type)));
1920
+ let r = n?.frag, i = Vt(r?.type);
1921
+ if (r && t.isActive(i)) for (let e of Ht(_, r)) t.prefetch(e.url, i, e.kind);
1922
+ }), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Vt(n?.frag?.type)));
1911
1923
  }
1912
1924
  _.on(e.Events.KEY_LOADED, () => {
1913
1925
  u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
1914
1926
  }), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
1915
- this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.checkFrameDrops();
1916
- }, en), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1927
+ this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.checkFrameDrops();
1928
+ }, tn), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1917
1929
  this.renditionSwitches += 1;
1918
1930
  let n = this.lastLevelIndex >= 0 ? _.levels[this.lastLevelIndex] : void 0, r = _.levels[t.level];
1919
1931
  n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, this.armFrameDropGrace(), l({
@@ -1956,17 +1968,28 @@ var Un = class {
1956
1968
  this.pushCap();
1957
1969
  }
1958
1970
  }
1959
- computeSizeCapTarget() {
1971
+ sizeCapCover() {
1960
1972
  let e = this.hls;
1961
1973
  if (!e || e.levels.length === 0) return null;
1962
1974
  let { video: n } = this.deps, r = n.getBoundingClientRect(), i = r.width, a = r.height;
1963
1975
  if (!i && !a && (i = n.width || 0, a = n.height || 0), !(i > 0) || !(a > 0)) return null;
1964
- let o = e.config ?? {}, s = typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1, c = o.ignoreDevicePixelRatio ? 1 : s;
1965
- c = Math.min(c, o.maxDevicePixelRatio ?? Infinity);
1966
- let l = t.getMaxLevelByMediaSize(e.levels, i * c, a * c), u = this.deps.sizeCapHeadroom;
1967
- if (u == null && s >= bn) return l;
1968
- let d = u ?? yn, f = Number.isNaN(d) ? yn : d === Infinity ? e.levels.length : Math.max(0, Math.floor(d));
1969
- return xn(e.levels, l, f);
1976
+ let o = e.config ?? {}, s = Y(), c = o.ignoreDevicePixelRatio ? 1 : s;
1977
+ return c = Math.min(c, o.maxDevicePixelRatio ?? Infinity), {
1978
+ cover: t.getMaxLevelByMediaSize(e.levels, i * c, a * c),
1979
+ deviceRatio: s
1980
+ };
1981
+ }
1982
+ sizeCapCoverLevel() {
1983
+ return this.sizeCapCover()?.cover ?? null;
1984
+ }
1985
+ computeSizeCapTarget() {
1986
+ let e = this.hls, t = this.sizeCapCover();
1987
+ if (!e || !t) return null;
1988
+ let { cover: n, deviceRatio: r } = t, i = this.deps.sizeCapHeadroom, a = i == null || Number.isNaN(i);
1989
+ if (a && r >= xn) return n;
1990
+ if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n, bn) : n;
1991
+ let o = i === Infinity ? e.levels.length : Math.max(0, Math.floor(i));
1992
+ return J(e.levels, n, o);
1970
1993
  }
1971
1994
  onMediaResize() {
1972
1995
  if (!this.sizeCapManaged) return;
@@ -1981,9 +2004,11 @@ var Un = class {
1981
2004
  return;
1982
2005
  }
1983
2006
  this.capTimer && clearTimeout(this.capTimer);
1984
- let t = e > this.sizeCapLevel ? _n : vn;
2007
+ let t = e > this.sizeCapLevel ? vn : yn;
1985
2008
  this.capTimer = setTimeout(() => {
1986
- this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
2009
+ this.capTimer = null;
2010
+ let n = this.computeSizeCapTarget();
2011
+ n === e || t === yn && n != null && n < e ? this.applySizeCap() : this.onMediaResize();
1987
2012
  }, t);
1988
2013
  }
1989
2014
  measureLadder(e) {
@@ -1991,9 +2016,9 @@ var Un = class {
1991
2016
  this.ladderHeights = t.length ? [...new Set(t)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = e.levels.length ? Math.round(Math.max(...e.levels.map((e) => e.bitrate)) / 1e3) : 0;
1992
2017
  }
1993
2018
  dropLevelsWidevineCannotPlay(e) {
1994
- this.removeLevelsWhere(e, (e) => Ze(e) !== !0);
1995
- let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && F(e) !== "avc" && !!F(e)));
1996
- for (let n of t) Ye(n).then((t) => {
2019
+ this.removeLevelsWhere(e, (e) => Qe(e) !== !0);
2020
+ let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && P(e) !== "avc" && !!P(e)));
2021
+ for (let n of t) Xe(n).then((t) => {
1997
2022
  t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
1998
2023
  });
1999
2024
  }
@@ -2001,13 +2026,69 @@ var Un = class {
2001
2026
  let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
2002
2027
  if (n.forEach((e, n) => {
2003
2028
  let a = e.videoCodec;
2004
- a && F(a) && t(a) && (r.push(n), i.add(a));
2029
+ a && P(a) && t(a) && (r.push(n), i.add(a));
2005
2030
  }), !r.length) return !1;
2006
2031
  let a = [...i].join(", ");
2007
- if (!n.some((e, t) => r.includes(t) ? !1 : !F(e.videoCodec) || Ze(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
2032
+ if (!n.some((e, t) => r.includes(t) ? !1 : !P(e.videoCodec) || Qe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
2008
2033
  for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
2009
2034
  return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
2010
2035
  }
2036
+ defaultHeadroomApplies() {
2037
+ let e = this.deps.sizeCapHeadroom;
2038
+ return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() < xn;
2039
+ }
2040
+ applySizeCapUnlessPending() {
2041
+ this.capTimer || this.applySizeCap();
2042
+ }
2043
+ sampleHeadroom(e) {
2044
+ if (!this.sizeCapManaged || !this.defaultHeadroomApplies() || e.frag?.type !== "main" || typeof e.frag.level != "number" || typeof document < "u" && document.hidden) return;
2045
+ let t = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag.duration;
2046
+ if (typeof t != "number" || !(t > 0)) return;
2047
+ let n = Kn(e)?.loading;
2048
+ if (!n || !(n.start > 0) || !(n.end >= n.start)) return;
2049
+ let r = this.hls?.levels?.[e.frag.level]?.bitrate;
2050
+ if (!(typeof r == "number" && r > 0)) return;
2051
+ let i = (n.end - n.start) / (t * 1e3);
2052
+ this.headroomSamples.push({
2053
+ t: Date.now(),
2054
+ ratio: i,
2055
+ bitrate: r
2056
+ }), this.headroomSamples.length > 256 && this.headroomSamples.shift();
2057
+ }
2058
+ onPlaybackStall() {
2059
+ let e = Date.now();
2060
+ this.deps.video.seeking || !this.playingSince || e - this.playingSince < En || (this.lastStallAt = e, this.headroomGranted && (this.headroomGranted = !1, this.applySizeCapUnlessPending()));
2061
+ }
2062
+ reviewSizeCapHeadroom() {
2063
+ let e = Date.now(), { video: t } = this.deps;
2064
+ !t.paused && !t.seeking && t.readyState >= 3 ? this.playingSince ||= e : this.playingSince = 0;
2065
+ let n = this.hls;
2066
+ if (!n || !this.sizeCapManaged) return;
2067
+ if (!this.defaultHeadroomApplies()) {
2068
+ this.headroomGranted = !1, this.headroomSamples = [];
2069
+ return;
2070
+ }
2071
+ this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e - Ln);
2072
+ let r = this.headroomEarned(n, e);
2073
+ r !== this.headroomGranted && (r || (this.headroomRegrantAt = e + On), this.headroomGranted = r, this.applySizeCapUnlessPending());
2074
+ }
2075
+ headroomEarned(e, t) {
2076
+ if (t - this.lastStallAt < Dn || !this.headroomGranted && t < this.headroomRegrantAt || !this.headroomGranted && this.headroomSamples.length < q) return !1;
2077
+ let n = e.levels, r = this.sizeCapCoverLevel();
2078
+ if (r == null) return this.headroomGranted;
2079
+ let i = J(n, r, bn);
2080
+ if (i === r) return this.headroomGranted;
2081
+ let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ? Tn : wn;
2082
+ if (!(a > 0) || !(o >= s * a)) return !1;
2083
+ let c = (e) => K([...e].sort((e, t) => e - t), 90);
2084
+ if (this.headroomGranted) {
2085
+ let e = this.headroomSamples.filter((e) => e.bitrate >= a).map((e) => e.ratio);
2086
+ return e.length < q || c(e) <= Cn;
2087
+ }
2088
+ let l = [];
2089
+ for (let e of this.headroomSamples) e.bitrate < a && l.push(e.ratio * (a / e.bitrate));
2090
+ return l.length >= q && c(l) <= Sn;
2091
+ }
2011
2092
  applySizeCap() {
2012
2093
  if (!this.sizeCapManaged) return;
2013
2094
  this.capTimer &&= (clearTimeout(this.capTimer), null);
@@ -2107,12 +2188,12 @@ var Un = class {
2107
2188
  this.lastAdvanceMs = Date.now();
2108
2189
  return;
2109
2190
  }
2110
- if (this.loadSuspended || this.offlineHold) {
2191
+ if (this.loadSuspended || this.offlineHold || !L()) {
2111
2192
  this.lastAdvanceMs = Date.now();
2112
2193
  return;
2113
2194
  }
2114
2195
  let e = Date.now() - this.lastAdvanceMs;
2115
- !this.chaseSuspended && e > nn && this.suspendChasing(), e > $t && this.emitEnded("stalled");
2196
+ !this.chaseSuspended && e > rn && this.suspendChasing(), e > en && this.emitEnded("stalled");
2116
2197
  }
2117
2198
  resetStarvationWindow() {
2118
2199
  this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
@@ -2123,11 +2204,11 @@ var Un = class {
2123
2204
  checkStarvation() {
2124
2205
  let e = this.hls, { video: t } = this.deps;
2125
2206
  if (!e || this.endedEmitted || !this.sawLive || this.chaseSuspended) return;
2126
- if (typeof document < "u" && document.hidden || this.loadSuspended || this.offlineHold) {
2207
+ if (typeof document < "u" && document.hidden || this.loadSuspended || this.offlineHold || !L()) {
2127
2208
  this.resetStarvationWindow();
2128
2209
  return;
2129
2210
  }
2130
- let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < nn, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > un, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = z(t), c = o - s, l = c !== this.starvedFrames;
2211
+ let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < rn, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > dn, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = R(t), c = o - s, l = c !== this.starvedFrames;
2131
2212
  if (this.starvedFrames = c, !a || l) {
2132
2213
  (t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
2133
2214
  return;
@@ -2136,12 +2217,12 @@ var Un = class {
2136
2217
  this.resetStarvationWindow();
2137
2218
  return;
2138
2219
  }
2139
- if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > hn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= pn && (this.clearKick(), this.starvationRebuilds < mn)) {
2220
+ if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > gn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= mn && (this.clearKick(), this.starvationRebuilds < hn)) {
2140
2221
  this.starvationRebuilds += 1, this.resetStarvationWindow(), this.clearRecoveryReset(), 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");
2141
2222
  return;
2142
2223
  }
2143
- let u = i && this.starvedTicks >= dn, d = !i && this.deadTicks >= hn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= gn;
2144
- if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= fn))) {
2224
+ let u = i && this.starvedTicks >= fn, d = !i && this.deadTicks >= gn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= _n;
2225
+ if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= pn))) {
2145
2226
  this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, this.kickKind = d ? "dead" : "quiet", this.clearRecoveryReset(), console.warn(d ? "havik-player: video starved while hls.js keeps loading media it never plays (dead pipeline at the live edge) — restarting the load" : "havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
2146
2227
  try {
2147
2228
  e.stopLoad(), e.startLoad(-1);
@@ -2156,7 +2237,7 @@ var Un = class {
2156
2237
  let t = e.latency, n = e.targetLatency;
2157
2238
  if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
2158
2239
  let r = t - n;
2159
- !this.catchUpEngaged && r > rn ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= rn && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
2240
+ !this.catchUpEngaged && r > an ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= an && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
2160
2241
  let i = this.catchUpEngaged ? this.catchUpRate : 1;
2161
2242
  e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
2162
2243
  }
@@ -2169,7 +2250,7 @@ var Un = class {
2169
2250
  }), n < 0 ? 0 : n;
2170
2251
  }
2171
2252
  armFrameDropGrace() {
2172
- this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Tn, this.fpsBadTicks = 0);
2253
+ this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Mn, this.fpsBadTicks = 0);
2173
2254
  }
2174
2255
  resetFrameDropWindow() {
2175
2256
  this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
@@ -2180,8 +2261,8 @@ var Un = class {
2180
2261
  this.resetFrameDropWindow();
2181
2262
  return;
2182
2263
  }
2183
- let { totalFrames: n, dropped: r } = z(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
2184
- if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Cn || o < 0) {
2264
+ let { totalFrames: n, dropped: r } = R(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
2265
+ if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < An || o < 0) {
2185
2266
  this.fpsBadTicks = 0;
2186
2267
  return;
2187
2268
  }
@@ -2189,11 +2270,11 @@ var Un = class {
2189
2270
  --this.fpsGraceTicks, this.fpsBadTicks = 0;
2190
2271
  return;
2191
2272
  }
2192
- if (o <= Sn * a) {
2273
+ if (o <= kn * a) {
2193
2274
  this.fpsBadTicks = 0;
2194
2275
  return;
2195
2276
  }
2196
- if (this.fpsBadTicks += 1, this.fpsBadTicks < wn) return;
2277
+ if (this.fpsBadTicks += 1, this.fpsBadTicks < jn) return;
2197
2278
  this.fpsBadTicks = 0;
2198
2279
  let s = e.levels, c = s[e.currentLevel];
2199
2280
  if (!c) return;
@@ -2210,22 +2291,22 @@ var Un = class {
2210
2291
  return;
2211
2292
  }
2212
2293
  let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
2213
- if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(sn, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
2294
+ if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(cn, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
2214
2295
  this.resetChaseWindow();
2215
2296
  return;
2216
2297
  }
2217
- if (this.chaseLatency < 0 || this.chaseLatency - n >= on) {
2298
+ if (this.chaseLatency < 0 || this.chaseLatency - n >= sn) {
2218
2299
  this.chaseLatency = n, this.chaseTicks = 0;
2219
2300
  return;
2220
2301
  }
2221
- if (this.chaseTicks += 1, this.chaseTicks < an) return;
2302
+ if (this.chaseTicks += 1, this.chaseTicks < on) return;
2222
2303
  this.resetChaseWindow();
2223
2304
  let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
2224
2305
  if (!(a > 1)) return;
2225
2306
  let o = e.targetLatency;
2226
2307
  if (typeof o != "number" || !(o > 0)) return;
2227
2308
  let s = Math.min(n, a - 1);
2228
- s < o + cn || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s, this.deps.emit({
2309
+ s < o + ln || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s, this.deps.emit({
2229
2310
  type: "livetargetchange",
2230
2311
  change: {
2231
2312
  targetSeconds: s,
@@ -2235,20 +2316,20 @@ var Un = class {
2235
2316
  }));
2236
2317
  }
2237
2318
  armHoldBack(e, t) {
2238
- this.holdBackEnabled && (this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [], this.holdBackBase < 0 && typeof t.liveSyncDuration == "number" && (this.holdBackBase = t.liveSyncDuration), this.holdBackApplied > 0 && (e.targetLatency = this.holdBackApplied));
2319
+ this.headroomSamples = [], this.headroomGranted = !1, this.holdBackEnabled && (this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [], this.holdBackBase < 0 && typeof t.liveSyncDuration == "number" && (this.holdBackBase = t.liveSyncDuration), this.holdBackApplied > 0 && (e.targetLatency = this.holdBackApplied));
2239
2320
  }
2240
2321
  applyHoldBackPrior() {
2241
2322
  let e = this.hls;
2242
2323
  if (!this.holdBackEnabled || this.holdBackPriorChecked || !e || (this.holdBackPriorChecked = !0, this.holdBackApplied > 0 || this.holdBackStepCount > 0)) return;
2243
2324
  let t = e.targetLatency;
2244
2325
  if (this.holdBackBase < 0 && typeof t == "number" && t > 0 && (this.holdBackBase = t), this.holdBackBase < 0) return;
2245
- let n = Bn();
2246
- if (!(n >= Rn)) return;
2247
- let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + J);
2326
+ let n = qn();
2327
+ if (!(n >= Gn)) return;
2328
+ let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + X);
2248
2329
  i > r && (this.holdBackStepCount = 1, this.moveHoldBack(e, r, i, "connection-rtt", `connection rtt ${n} ms`));
2249
2330
  }
2250
2331
  holdBackCeiling(e) {
2251
- let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Ln, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
2332
+ let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Wn, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
2252
2333
  return r > 1 ? Math.min(n, r - 1) : n;
2253
2334
  }
2254
2335
  sampleHoldBack(e) {
@@ -2257,7 +2338,7 @@ var Un = class {
2257
2338
  if (t !== "main" && t !== "audio") return;
2258
2339
  let n = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag?.duration;
2259
2340
  if (typeof n != "number" || !(n > 0)) return;
2260
- let r = zn(e)?.loading;
2341
+ let r = Kn(e)?.loading;
2261
2342
  if (!r || !(r.start > 0) || !(r.end > 0)) return;
2262
2343
  let i = r.first > r.start ? r.first : r.end, a = Math.max(0, i - r.start) / (n * 1e3);
2263
2344
  this.holdBackSamples.push({
@@ -2272,30 +2353,30 @@ var Un = class {
2272
2353
  this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [];
2273
2354
  return;
2274
2355
  }
2275
- let t = Date.now(), n = t - An, r = this.holdBackSamples, i = 0;
2356
+ let t = Date.now(), n = t - Ln, r = this.holdBackSamples, i = 0;
2276
2357
  for (; i < r.length && r[i].t < n;) i += 1;
2277
2358
  i > 0 && r.splice(0, i);
2278
2359
  let a = e.targetLatency;
2279
2360
  if (typeof a != "number" || !(a > 0)) return;
2280
2361
  this.holdBackBase < 0 && (this.holdBackBase = a);
2281
2362
  let o = this.holdBackBase, s = this.holdBackCeiling(e);
2282
- if (r.length < jn) {
2363
+ if (r.length < Rn) {
2283
2364
  this.holdBackSlowTicks = 0;
2284
2365
  return;
2285
2366
  }
2286
- let c = r.map((e) => e.ratio).sort((e, t) => e - t), l = q(c, 95), u = q(c, 50), d = Math.round(l * 1e3);
2287
- if (l >= Mn && u >= Nn) {
2288
- if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Fn) return;
2367
+ let c = r.map((e) => e.ratio).sort((e, t) => e - t), l = K(c, 95), u = K(c, 50), d = Math.round(l * 1e3);
2368
+ if (l >= zn && u >= Bn) {
2369
+ if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Hn) return;
2289
2370
  this.holdBackSlowTicks = 0;
2290
- let t = Math.ceil((s - o) / J), n = Math.ceil((a - o) / J - 1e-9);
2371
+ let t = Math.ceil((s - o) / X), n = Math.ceil((a - o) / X - 1e-9);
2291
2372
  if (n > this.holdBackStepCount && (this.holdBackStepCount = n), this.holdBackStepCount >= t) return;
2292
2373
  this.holdBackStepCount += 1;
2293
- let r = Math.min(s, o + this.holdBackStepCount * J);
2374
+ let r = Math.min(s, o + this.holdBackStepCount * X);
2294
2375
  if (r <= a) return;
2295
2376
  this.moveHoldBack(e, a, r, "slow-fetches", `part fetches slow (first byte p50 ${Math.round(u * 1e3)} / p95 ${d} ms per 1 s of media)`);
2296
2377
  return;
2297
2378
  }
2298
- if (this.holdBackSlowTicks = 0, l >= Pn) {
2379
+ if (this.holdBackSlowTicks = 0, l >= Vn) {
2299
2380
  this.holdBackFastSince = 0;
2300
2381
  return;
2301
2382
  }
@@ -2303,9 +2384,9 @@ var Un = class {
2303
2384
  this.holdBackFastSince = t;
2304
2385
  return;
2305
2386
  }
2306
- if (t - this.holdBackFastSince < In || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
2387
+ if (t - this.holdBackFastSince < Un || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
2307
2388
  --this.holdBackStepCount;
2308
- let f = Math.max(o, o + this.holdBackStepCount * J);
2389
+ let f = Math.max(o, o + this.holdBackStepCount * X);
2309
2390
  f >= a || this.moveHoldBack(e, a, f, "fast-fetches", `part fetches fast again (p95 first byte ${d} ms per 1 s of media)`);
2310
2391
  }
2311
2392
  moveHoldBack(e, t, n, r, i) {
@@ -2346,17 +2427,17 @@ var Un = class {
2346
2427
  } catch {}
2347
2428
  }
2348
2429
  startEstimate() {
2349
- return this.deps.rememberBandwidth === !1 ? Gt : ze() ?? Gt;
2430
+ return this.deps.rememberBandwidth === !1 ? Kt : Be() ?? Kt;
2350
2431
  }
2351
2432
  maybeRememberBandwidth(e) {
2352
- if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < Kt) return;
2433
+ if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < qt) return;
2353
2434
  let t = Date.now();
2354
- if (!e && t - this.bwSavedAt < qt) return;
2435
+ if (!e && t - this.bwSavedAt < Jt) return;
2355
2436
  let n = this.hls?.bandwidthEstimate;
2356
- typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Be(n));
2437
+ typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Ve(n));
2357
2438
  }
2358
2439
  destroy() {
2359
- if (this.maybeRememberBandwidth(!0), this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onOnline && typeof window < "u" && (window.removeEventListener("online", this.onOnline), this.onOnline = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
2440
+ if (this.maybeRememberBandwidth(!0), this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onOffline && typeof window < "u" && (window.removeEventListener("offline", this.onOffline), this.onOffline = null), this.onOnline && typeof window < "u" && (window.removeEventListener("online", this.onOnline), this.onOnline = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
2360
2441
  try {
2361
2442
  this.hls.destroy();
2362
2443
  } catch (e) {
@@ -2371,7 +2452,7 @@ var Un = class {
2371
2452
  scheduleLicenseRetry(t) {
2372
2453
  if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
2373
2454
  let n = t.response?.code ?? 0;
2374
- if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Xt) return !1;
2455
+ if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Zt) return !1;
2375
2456
  this.licenseRecoveries += 1;
2376
2457
  let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
2377
2458
  return this.licenseRetryTimer = setTimeout(() => {
@@ -2389,7 +2470,7 @@ var Un = class {
2389
2470
  }
2390
2471
  }
2391
2472
  onError(t) {
2392
- if (t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
2473
+ if (t.details === e.ErrorDetails.BUFFER_STALLED_ERROR && this.onPlaybackStall(), t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
2393
2474
  let n = this.hls;
2394
2475
  if (n) {
2395
2476
  if (this.clearRecoveryReset(), t.type === e.ErrorTypes.KEY_SYSTEM_ERROR) {
@@ -2403,11 +2484,11 @@ var Un = class {
2403
2484
  return;
2404
2485
  }
2405
2486
  if (t.type === e.ErrorTypes.NETWORK_ERROR) {
2406
- if (!R() && (t.response?.code ?? 0) === 0) {
2487
+ if (!L() && (t.response?.code ?? 0) === 0) {
2407
2488
  this.offlineHold = !0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null);
2408
2489
  return;
2409
2490
  }
2410
- if (this.networkRecoveries < Yt) {
2491
+ if (this.networkRecoveries < Xt) {
2411
2492
  this.networkRecoveries += 1;
2412
2493
  let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
2413
2494
  this.networkRetryTimer = setTimeout(() => {
@@ -2424,7 +2505,7 @@ var Un = class {
2424
2505
  return;
2425
2506
  }
2426
2507
  if (t.type === e.ErrorTypes.MEDIA_ERROR) {
2427
- if (this.mediaRecoveries < Jt) {
2508
+ if (this.mediaRecoveries < Yt) {
2428
2509
  this.mediaRecoveries += 1, n.recoverMediaError();
2429
2510
  return;
2430
2511
  }
@@ -2445,18 +2526,18 @@ var Un = class {
2445
2526
  }
2446
2527
  }
2447
2528
  toError(t, r = "PLAYBACK") {
2448
- let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(jt(t.networkDetails)) : void 0;
2529
+ let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(Mt(t.networkDetails)) : void 0;
2449
2530
  return new n(r === "DRM" ? a(o, l) : r === "NETWORK" && o === 0 ? "NETWORK" : o === 401 ? "UNAUTHORIZED" : o === 403 ? "FORBIDDEN" : "INTERNAL", o, `${r} error: ${s}${c ? ` (${c})` : ""}`, l ? { serverCode: l } : void 0);
2450
2531
  }
2451
- }, Wn = 15e3, Gn = 6e5, Kn = 3e5, qn = 100, Y = 1, Jn = 1e3, Yn = 3e4, Xn = 1e3, Zn = {
2532
+ }, Zn = 15e3, Qn = 6e5, $n = 3e5, er = 100, Z = 1, tr = 1e3, nr = 3e4, rr = 1e3, ir = {
2452
2533
  inline: "PRESENTATION_INLINE",
2453
2534
  fullscreen: "PRESENTATION_FULLSCREEN",
2454
2535
  pip: "PRESENTATION_PIP"
2455
- }, Qn = {
2536
+ }, ar = {
2456
2537
  widevine: "KEY_SYSTEM_WIDEVINE",
2457
2538
  fairplay: "KEY_SYSTEM_FAIRPLAY",
2458
2539
  none: "KEY_SYSTEM_NONE"
2459
- }, $n = /* @__PURE__ */ new Set([
2540
+ }, or = /* @__PURE__ */ new Set([
2460
2541
  "INVALID_URN",
2461
2542
  "NOT_FOUND",
2462
2543
  "GEO_DENIED",
@@ -2467,7 +2548,7 @@ var Un = class {
2467
2548
  "FORBIDDEN",
2468
2549
  "RATE_LIMITED",
2469
2550
  "TIMEOUT"
2470
- ]), X = {
2551
+ ]), sr = {
2471
2552
  idle: "PLAYER_STATE_IDLE",
2472
2553
  waiting: "PLAYER_STATE_WAITING",
2473
2554
  loading: "PLAYER_STATE_LOADING",
@@ -2477,7 +2558,7 @@ var Un = class {
2477
2558
  ended: "PLAYER_STATE_ENDED",
2478
2559
  error: "PLAYER_STATE_ERROR"
2479
2560
  };
2480
- function er(e) {
2561
+ function cr(e) {
2481
2562
  try {
2482
2563
  let t = new URL(e), [n, ...r] = t.hostname.split(".");
2483
2564
  return !n || r.length === 0 || n !== "feed" && !n.startsWith("feed-") ? void 0 : (t.hostname = [n.replace(/^feed/, "beacons"), ...r].join("."), t.pathname = "", t.search = "", t.origin);
@@ -2485,8 +2566,8 @@ function er(e) {
2485
2566
  return;
2486
2567
  }
2487
2568
  }
2488
- var tr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), nr = /* @__PURE__ */ new Set(), Z = /* @__PURE__ */ new Set(), Q = /* @__PURE__ */ new Set(), rr = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
2489
- function ir(e) {
2569
+ var lr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), ur = /* @__PURE__ */ new Set(), dr = /* @__PURE__ */ new Set(), fr = /* @__PURE__ */ new Set(), pr = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
2570
+ function mr(e) {
2490
2571
  if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
2491
2572
  let t;
2492
2573
  try {
@@ -2495,19 +2576,19 @@ function ir(e) {
2495
2576
  } catch {
2496
2577
  return;
2497
2578
  }
2498
- if (nr.has(t) && !Z.has(t)) {
2499
- Z.add(t), _(rr(new URL(t).origin));
2500
- for (let e of Q) e.noteCspBlocked();
2579
+ if (ur.has(t) && !dr.has(t)) {
2580
+ dr.add(t), _(pr(new URL(t).origin));
2581
+ for (let e of fr) e.noteCspBlocked();
2501
2582
  }
2502
2583
  }
2503
- function ar(e, t) {
2584
+ function hr(e, t) {
2504
2585
  return _(t, e), { disabledReason: t };
2505
2586
  }
2506
- function or(e, t, n) {
2507
- if (n) return t && !tr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
2587
+ function gr(e, t, n) {
2588
+ if (n) return t && !lr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
2508
2589
  if (t) return { endpoint: t };
2509
- if (t !== void 0) return ar("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
2510
- let r = er(e);
2590
+ if (t !== void 0) return hr("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
2591
+ let r = cr(e);
2511
2592
  if (r) return { endpoint: r };
2512
2593
  let i;
2513
2594
  try {
@@ -2515,9 +2596,9 @@ function or(e, t, n) {
2515
2596
  } catch {
2516
2597
  i = e;
2517
2598
  }
2518
- return ar(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
2599
+ return hr(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
2519
2600
  }
2520
- var sr = class {
2601
+ var _r = class {
2521
2602
  opts;
2522
2603
  url;
2523
2604
  cspKey;
@@ -2599,8 +2680,8 @@ var sr = class {
2599
2680
  constructor(e) {
2600
2681
  this.opts = {
2601
2682
  ...e,
2602
- heartbeatMs: e.heartbeatMs ?? Wn,
2603
- idleMs: e.idleMs ?? Gn
2683
+ heartbeatMs: e.heartbeatMs ?? Zn,
2684
+ idleMs: e.idleMs ?? Qn
2604
2685
  }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
2605
2686
  try {
2606
2687
  let e = new URL(this.url);
@@ -2617,11 +2698,11 @@ var sr = class {
2617
2698
  sdkVersion: this.opts.sdkVersion,
2618
2699
  ...this.opts.environment
2619
2700
  };
2620
- this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Jn), 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.cspKey && nr.add(this.cspKey), document.addEventListener("securitypolicyviolation", ir), Q.add(this), this.noteCspBlocked(), this.onVisibility());
2701
+ this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), tr), 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.cspKey && ur.add(this.cspKey), document.addEventListener("securitypolicyviolation", mr), fr.add(this), this.noteCspBlocked(), this.onVisibility());
2621
2702
  }
2622
2703
  checkSuspension(e) {
2623
2704
  if (this.endedFlag || !this.opts.idleMs) return !1;
2624
- let t = Math.max(this.opts.idleMs, Kn);
2705
+ let t = Math.max(this.opts.idleMs, $n);
2625
2706
  return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
2626
2707
  }
2627
2708
  syncIdle(e) {
@@ -2635,21 +2716,21 @@ var sr = class {
2635
2716
  noteStateChange(e, t, n, r) {
2636
2717
  if (this.endedFlag || e === t) return;
2637
2718
  let i = this.now();
2638
- if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Y, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Y, 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") {
2719
+ if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Z, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Z, 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") {
2639
2720
  this.stallIsSeekInduced = this.seekInduced(i);
2640
2721
  let e = !this.isHidden && !this.stallIsSeekInduced;
2641
- e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Y, Math.round(this.playingTotalMs)));
2722
+ e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Z, Math.round(this.playingTotalMs)));
2642
2723
  } else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
2643
2724
  this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
2644
2725
  let a = {
2645
- fromState: X[e] ?? "PLAYER_STATE_UNSPECIFIED",
2646
- toState: X[t] ?? "PLAYER_STATE_UNSPECIFIED",
2647
- presentation: Zn[this.presentation]
2726
+ fromState: sr[e] ?? "PLAYER_STATE_UNSPECIFIED",
2727
+ toState: sr[t] ?? "PLAYER_STATE_UNSPECIFIED",
2728
+ presentation: ir[this.presentation]
2648
2729
  }, o = this.causeOf(e, t, i);
2649
2730
  o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
2650
2731
  }
2651
2732
  seekInduced(e) {
2652
- return this.lastSeekMs >= 0 && e - this.lastSeekMs < Xn;
2733
+ return this.lastSeekMs >= 0 && e - this.lastSeekMs < rr;
2653
2734
  }
2654
2735
  causeOf(e, t, n) {
2655
2736
  if (t === "error") return "TRANSITION_CAUSE_ERROR";
@@ -2686,25 +2767,25 @@ var sr = class {
2686
2767
  }
2687
2768
  this.muteChanges += 1;
2688
2769
  let r = this.now();
2689
- 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(Y, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
2770
+ 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(Z, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
2690
2771
  }
2691
2772
  notePresentation(e) {
2692
2773
  this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
2693
2774
  }
2694
2775
  notePlayIntent() {
2695
- this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Y), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Y), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Y), this.drmSetupMs > 0 && (this.drmSetupMs = Y));
2776
+ this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Z), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Z), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Z), this.drmSetupMs > 0 && (this.drmSetupMs = Z));
2696
2777
  }
2697
2778
  noteReady() {
2698
- this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Y, this.now() - this.startupAnchorMs));
2779
+ this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
2699
2780
  }
2700
2781
  noteFirstPlaylist() {
2701
- this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Y, this.now() - this.startupAnchorMs));
2782
+ this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Z, this.now() - this.startupAnchorMs));
2702
2783
  }
2703
2784
  noteDrmReady() {
2704
- this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Y, this.now() - this.startupAnchorMs));
2785
+ this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Z, this.now() - this.startupAnchorMs));
2705
2786
  }
2706
2787
  noteFirstBytes() {
2707
- this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Y, this.now() - this.startupAnchorMs));
2788
+ this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
2708
2789
  }
2709
2790
  noteSeek() {
2710
2791
  this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
@@ -2723,7 +2804,7 @@ var sr = class {
2723
2804
  let r = n ?? "";
2724
2805
  if (r !== "") return /^fragLoad/i.test(r) ? this.sawFirstBytes ? "ERROR_STAGE_SEGMENT" : "ERROR_STAGE_FIRST_SEGMENT" : /^(manifest|level|audioTrack|subtitleTrack)/i.test(r) ? "ERROR_STAGE_MANIFEST" : /key|licen[cs]e/i.test(r) ? "ERROR_STAGE_DRM" : /parsing|append|buffer|remux|decrypt|media/i.test(r) ? "ERROR_STAGE_DECODE" : "ERROR_STAGE_OTHER";
2725
2806
  if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
2726
- if ($n.has(e)) return "ERROR_STAGE_RESOLVE";
2807
+ if (or.has(e)) return "ERROR_STAGE_RESOLVE";
2727
2808
  let i = t ?? "";
2728
2809
  return /frag|segment/i.test(i) ? this.sawFirstBytes ? "ERROR_STAGE_SEGMENT" : "ERROR_STAGE_FIRST_SEGMENT" : /manifest|level|playlist/i.test(i) ? "ERROR_STAGE_MANIFEST" : /key|licen[cs]e/i.test(i) ? "ERROR_STAGE_DRM" : /buffer|decode|media|append/i.test(i) ? "ERROR_STAGE_DECODE" : "ERROR_STAGE_OTHER";
2729
2810
  }
@@ -2755,7 +2836,7 @@ var sr = class {
2755
2836
  let l = t.droppedFrames ?? 0;
2756
2837
  l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
2757
2838
  let u = t.renditionSwitches ?? 0;
2758
- 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 = X[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
2839
+ 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 = sr[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
2759
2840
  let d = this.mutedTotalMs;
2760
2841
  this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
2761
2842
  let f = t.upshifts ?? 0;
@@ -2770,20 +2851,20 @@ var sr = class {
2770
2851
  if (this.lastRequestCount = g, _ > 0) {
2771
2852
  o.requestCountDelta = _;
2772
2853
  let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
2773
- n.length > 0 && (o.requestTimeP50Ms = q(n, 50), o.requestTimeP95Ms = q(n, 95));
2854
+ n.length > 0 && (o.requestTimeP50Ms = K(n, 50), o.requestTimeP95Ms = K(n, 95));
2774
2855
  }
2775
2856
  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();
2776
2857
  }
2777
2858
  maybeEmitMediaInfo(e) {
2778
2859
  if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
2779
2860
  let t = {};
2780
- e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Qn[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);
2861
+ e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = ar[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);
2781
2862
  let n = JSON.stringify(t);
2782
2863
  n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
2783
2864
  }
2784
2865
  end(e, t) {
2785
2866
  if (this.endedFlag) return;
2786
- this.endedFlag = !0, Q.delete(this);
2867
+ this.endedFlag = !0, fr.delete(this);
2787
2868
  let n = t ?? this.now();
2788
2869
  this.playingSinceMs !== null && (this.playingTotalMs += n - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += n - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += n - this.bufferingSinceMs, this.bufferingSinceMs = null), this.mutedSinceMs !== null && (this.mutedTotalMs += n - this.mutedSinceMs, this.mutedSinceMs = null), this.waitingSinceMs !== null && (this.waitingTotalMs += n - this.waitingSinceMs, this.waitingSinceMs = null), this.isPlaying = !1, this.syncActive(n), this.closePresentation(n), this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.timer &&= (clearInterval(this.timer), null), this.idleTimer &&= (clearTimeout(this.idleTimer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), document.removeEventListener("freeze", this.onFreeze), document.removeEventListener("resume", this.onResume));
2789
2870
  let r = this.safeSample();
@@ -2797,7 +2878,7 @@ var sr = class {
2797
2878
  let c = r?.positionMs ?? 0;
2798
2879
  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));
2799
2880
  let l = e !== "END_REASON_ENDED";
2800
- l && this.lastStallMs > 0 && n - this.lastStallMs <= Yn && (i.abandonAfterStallMs = Math.max(Y, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Yn && (i.abandonAfterErrorMs = Math.max(Y, 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);
2881
+ l && this.lastStallMs > 0 && n - this.lastStallMs <= nr && (i.abandonAfterStallMs = Math.max(Z, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= nr && (i.abandonAfterErrorMs = Math.max(Z, 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);
2801
2882
  let u = r?.decodedFrames ?? this.lastDecoded;
2802
2883
  u > 0 && (i.decodedFramesTotal = u), e === "END_REASON_STOPPED" && this.startupTimeMs === 0 && this.lastErrorStage === null && (e = "END_REASON_ABORTED", i.reason = e), this.startupTimeMs === 0 && e !== "END_REASON_ABORTED" && (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");
2803
2884
  }
@@ -2817,13 +2898,13 @@ var sr = class {
2817
2898
  };
2818
2899
  }
2819
2900
  noteCspBlocked() {
2820
- this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(rr(new URL(this.url).origin)));
2901
+ this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(pr(new URL(this.url).origin)));
2821
2902
  }
2822
2903
  cspBlocked() {
2823
- return !!this.cspKey && Z.has(this.cspKey);
2904
+ return !!this.cspKey && dr.has(this.cspKey);
2824
2905
  }
2825
2906
  enqueue(e) {
2826
- if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > qn;) {
2907
+ if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > er;) {
2827
2908
  let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
2828
2909
  this.pending.splice(e >= 0 ? e : 0, 1);
2829
2910
  }
@@ -2850,7 +2931,7 @@ var sr = class {
2850
2931
  };
2851
2932
  //#endregion
2852
2933
  //#region src/core/environment.ts
2853
- function cr() {
2934
+ function vr() {
2854
2935
  if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
2855
2936
  let e;
2856
2937
  try {
@@ -2875,14 +2956,14 @@ function cr() {
2875
2956
  integration: "INTEGRATION_KIND_IFRAME"
2876
2957
  };
2877
2958
  }
2878
- function lr() {
2959
+ function yr() {
2879
2960
  if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
2880
2961
  let e = navigator.userAgentData, t = e?.platform ?? "";
2881
2962
  if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
2882
2963
  let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
2883
2964
  return e?.mobile ?? (typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1 && n > 0 && n < 900) ? n >= 600 ? "DEVICE_CLASS_TABLET" : "DEVICE_CLASS_PHONE" : e || n >= 900 || /mac|win|linux|chrome os/i.test(t) ? "DEVICE_CLASS_DESKTOP" : "DEVICE_CLASS_OTHER";
2884
2965
  }
2885
- function ur() {
2966
+ function br() {
2886
2967
  let e = typeof navigator < "u" ? navigator.connection : void 0;
2887
2968
  if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
2888
2969
  let t = {
@@ -2901,17 +2982,17 @@ function ur() {
2901
2982
  }
2902
2983
  return typeof e.downlink == "number" && e.downlink > 0 && (i.downlinkKbps = Math.round(e.downlink * 1e3)), typeof e.rtt == "number" && e.rtt > 0 && (i.rttMs = Math.round(e.rtt)), e.saveData && (i.saveData = !0), i;
2903
2984
  }
2904
- function dr(e) {
2905
- let t = cr(), n = {
2906
- deviceClass: lr(),
2985
+ function xr(e) {
2986
+ let t = vr(), n = {
2987
+ deviceClass: yr(),
2907
2988
  integration: t.integration,
2908
- ...ur()
2989
+ ...br()
2909
2990
  };
2910
2991
  t.host && (n.host = t.host), typeof screen < "u" && screen.width > 0 && (n.screenWidth = screen.width, n.screenHeight = screen.height), typeof window < "u" && window.devicePixelRatio > 0 && (n.devicePixelRatio = Math.round(window.devicePixelRatio * 100) / 100);
2911
2992
  let r = e.getBoundingClientRect?.();
2912
2993
  return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
2913
2994
  }
2914
- async function fr() {
2995
+ async function Sr() {
2915
2996
  let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
2916
2997
  if (!e?.getHighEntropyValues) return {};
2917
2998
  try {
@@ -2923,7 +3004,7 @@ async function fr() {
2923
3004
  }
2924
3005
  //#endregion
2925
3006
  //#region src/core/version.ts
2926
- var pr = "2.25.0", mr = {
3007
+ var Cr = "2.26.0", wr = {
2927
3008
  accent: "#E1B600",
2928
3009
  accentText: "#1B1C23",
2929
3010
  background: "#0e0f13",
@@ -2934,7 +3015,7 @@ var pr = "2.25.0", mr = {
2934
3015
  border: "rgba(255, 255, 255, 0.1)",
2935
3016
  radius: "8px",
2936
3017
  fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
2937
- }, hr = {
3018
+ }, Tr = {
2938
3019
  accent: "--havik-accent",
2939
3020
  accentText: "--havik-accent-text",
2940
3021
  background: "--havik-bg",
@@ -2946,26 +3027,26 @@ var pr = "2.25.0", mr = {
2946
3027
  radius: "--havik-radius",
2947
3028
  fontFamily: "--havik-font"
2948
3029
  };
2949
- function gr(e, t) {
3030
+ function Er(e, t) {
2950
3031
  let n = {
2951
- ...mr,
3032
+ ...wr,
2952
3033
  ...t
2953
3034
  };
2954
- for (let t of Object.keys(hr)) e.style.setProperty(hr[t], n[t]);
3035
+ for (let t of Object.keys(Tr)) e.style.setProperty(Tr[t], n[t]);
2955
3036
  n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
2956
3037
  }
2957
3038
  //#endregion
2958
3039
  //#region src/ui/styles.ts
2959
- var _r = "havik-player-styles", vr = "\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 touch-action:manipulation}\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/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;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", yr = /* @__PURE__ */ new WeakMap();
2960
- function br(e = document, t) {
2961
- let n = e.querySelector(`style#${_r}`);
2962
- if (n && (!t || yr.get(n) === t)) return;
3040
+ var Dr = "havik-player-styles", Or = "\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 touch-action:manipulation}\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/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;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", kr = /* @__PURE__ */ new WeakMap();
3041
+ function Ar(e = document, t) {
3042
+ let n = e.querySelector(`style#${Dr}`);
3043
+ if (n && (!t || kr.get(n) === t)) return;
2963
3044
  let r = e.createElement("style");
2964
- r.id = _r, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = vr, yr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
3045
+ r.id = Dr, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Or, kr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
2965
3046
  }
2966
3047
  //#endregion
2967
3048
  //#region src/ui/icons.ts
2968
- var xr = {
3049
+ var jr = {
2969
3050
  play: "<path d=\"M8 5v14l11-7z\"/>",
2970
3051
  pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
2971
3052
  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\"/>",
@@ -2978,12 +3059,12 @@ var xr = {
2978
3059
  liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
2979
3060
  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\"/>"
2980
3061
  };
2981
- function $(e) {
2982
- return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${xr[e]}</svg>`;
3062
+ function Q(e) {
3063
+ return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${jr[e]}</svg>`;
2983
3064
  }
2984
3065
  //#endregion
2985
3066
  //#region src/ui/controls.ts
2986
- var Sr = 3e3, Cr = 250, wr = /* @__PURE__ */ new Set([
3067
+ var Mr = 3e3, Nr = 250, Pr = /* @__PURE__ */ new Set([
2987
3068
  "GONE",
2988
3069
  "NOT_FOUND",
2989
3070
  "GEO_DENIED",
@@ -2991,15 +3072,15 @@ var Sr = 3e3, Cr = 250, wr = /* @__PURE__ */ new Set([
2991
3072
  "UNAUTHORIZED",
2992
3073
  "DRM_DEVICE_REVOKED"
2993
3074
  ]);
2994
- function Tr(e) {
3075
+ function Fr(e) {
2995
3076
  let t = "This match isn't available in your country";
2996
3077
  return e ? `${t} (${e})` : t;
2997
3078
  }
2998
- var Er = "This device can't play protected video";
2999
- function Dr(e) {
3000
- return new Or(e);
3079
+ var Ir = "This device can't play protected video";
3080
+ function Lr(e) {
3081
+ return new Rr(e);
3001
3082
  }
3002
- var Or = class {
3083
+ var Rr = class {
3003
3084
  root;
3004
3085
  video;
3005
3086
  player;
@@ -3048,7 +3129,7 @@ var Or = class {
3048
3129
  scrubbing = !1;
3049
3130
  offFns = [];
3050
3131
  constructor(e) {
3051
- this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Sr, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, this.offlineMessage = e.offlineMessage ?? "No internet connection — waiting to reconnect", br(this.doc, e.cspNonce), 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");
3132
+ this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Mr, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, this.offlineMessage = e.offlineMessage ?? "No internet connection — waiting to reconnect", Ar(this.doc, e.cspNonce), 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");
3052
3133
  let t = (e, t, n) => {
3053
3134
  let r = this.doc.createElement(e);
3054
3135
  if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
@@ -3059,12 +3140,12 @@ var Or = class {
3059
3140
  "aria-label": r,
3060
3141
  title: r
3061
3142
  });
3062
- return i.innerHTML = $(n), i;
3143
+ return i.innerHTML = Q(n), i;
3063
3144
  };
3064
3145
  this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
3065
3146
  type: "button",
3066
3147
  "aria-label": "Play"
3067
- }), this.center.innerHTML = $("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", {
3148
+ }), 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", {
3068
3149
  role: "slider",
3069
3150
  "aria-label": "Seek",
3070
3151
  "aria-valuemin": "0",
@@ -3082,7 +3163,7 @@ var Or = class {
3082
3163
  "aria-label": "Volume"
3083
3164
  });
3084
3165
  let a = t("div", "havik-vol");
3085
- a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = $("liveDot");
3166
+ a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
3086
3167
  let o = this.doc.createElement("span");
3087
3168
  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";
3088
3169
  let s = t("div", "havik-spacer");
@@ -3134,7 +3215,7 @@ var Or = class {
3134
3215
  let t = this.surfaceWasHidden;
3135
3216
  this.tapTimer = setTimeout(() => {
3136
3217
  this.tapTimer = void 0, this.toggleBar(t);
3137
- }, Cr);
3218
+ }, Nr);
3138
3219
  }
3139
3220
  toggleBar(e) {
3140
3221
  e ? this.poke() : this.hideIfIdle();
@@ -3158,7 +3239,7 @@ var Or = class {
3158
3239
  this.renderStatus(t);
3159
3240
  }
3160
3241
  statusMessageFor(e) {
3161
- return e === "ended" ? this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? Tr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Er : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
3242
+ return e === "ended" ? this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? Fr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Ir : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
3162
3243
  }
3163
3244
  renderStatus(e) {
3164
3245
  let t = this.statusMessageFor(e);
@@ -3170,12 +3251,12 @@ var Or = class {
3170
3251
  }
3171
3252
  if (e === "preplay") {
3172
3253
  let e = this.doc.createElement("button");
3173
- e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = $("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
3254
+ 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);
3174
3255
  } else {
3175
3256
  let r = this.doc.createElement("div");
3176
- if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !wr.has(this.lastError.code)) {
3257
+ if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Pr.has(this.lastError.code)) {
3177
3258
  let e = this.doc.createElement("button");
3178
- e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${$("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
3259
+ 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);
3179
3260
  }
3180
3261
  }
3181
3262
  this.root.append(n), this.statusBox = n, this.show();
@@ -3214,7 +3295,7 @@ var Or = class {
3214
3295
  let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
3215
3296
  this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
3216
3297
  }
3217
- !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${kr(this.video.currentTime)} / ${kr(this.video.duration)}`);
3298
+ !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${zr(this.video.currentTime)} / ${zr(this.video.duration)}`);
3218
3299
  }
3219
3300
  syncLive() {
3220
3301
  let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended", r = !t && !this.streamEnded();
@@ -3264,17 +3345,17 @@ var Or = class {
3264
3345
  renderQualityMenu() {
3265
3346
  let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
3266
3347
  n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
3267
- for (let n of e) this.menu.append(this.menuItem(Ar(n), t === n.index, () => this.player.setQuality(n.index)));
3348
+ for (let n of e) this.menu.append(this.menuItem(Br(n), t === n.index, () => this.player.setQuality(n.index)));
3268
3349
  }
3269
3350
  renderAudioMenu() {
3270
3351
  let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
3271
3352
  t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
3272
- for (let t of e) this.menu.append(this.menuItem(jr(t), t.default, () => this.player.setAudioTrack(t.id)));
3353
+ for (let t of e) this.menu.append(this.menuItem(Vr(t), t.default, () => this.player.setAudioTrack(t.id)));
3273
3354
  }
3274
3355
  renderCcMenu() {
3275
3356
  let e = this.player.getTextTracks(), t = this.doc.createElement("div");
3276
3357
  t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
3277
- for (let t of e) this.menu.append(this.menuItem(Mr(t), !1, () => this.player.setTextTrack(t.id)));
3358
+ for (let t of e) this.menu.append(this.menuItem(Hr(t), !1, () => this.player.setTextTrack(t.id)));
3278
3359
  }
3279
3360
  onTracksChanged() {
3280
3361
  this.openMenu && this.renderMenu(this.openMenu);
@@ -3294,14 +3375,14 @@ var Or = class {
3294
3375
  }
3295
3376
  async toggleFullscreen() {
3296
3377
  try {
3297
- ye(this.video, this.root) ? await C(this.video, this.root) : await S(this.video, this.root);
3378
+ S(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
3298
3379
  } catch {}
3299
3380
  }
3300
3381
  syncFullscreenSupport() {
3301
- this.fsSupported = x(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
3382
+ this.fsSupported = C(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
3302
3383
  }
3303
3384
  syncFullscreen() {
3304
- let e = ye(this.video, this.root);
3385
+ let e = S(this.video, this.root);
3305
3386
  this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
3306
3387
  }
3307
3388
  poke() {
@@ -3362,7 +3443,7 @@ var Or = class {
3362
3443
  }
3363
3444
  }
3364
3445
  setIcon(e, t) {
3365
- e.innerHTML = $(t);
3446
+ e.innerHTML = Q(t);
3366
3447
  }
3367
3448
  destroy() {
3368
3449
  this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
@@ -3379,23 +3460,23 @@ var Or = class {
3379
3460
  this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
3380
3461
  }
3381
3462
  };
3382
- function kr(e) {
3463
+ function zr(e) {
3383
3464
  (!Number.isFinite(e) || e < 0) && (e = 0);
3384
3465
  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");
3385
3466
  return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
3386
3467
  }
3387
- function Ar(e) {
3468
+ function Br(e) {
3388
3469
  return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
3389
3470
  }
3390
- function jr(e) {
3471
+ function Vr(e) {
3391
3472
  return e.name || e.lang || `Track ${e.id}`;
3392
3473
  }
3393
- function Mr(e) {
3474
+ function Hr(e) {
3394
3475
  return e.name || e.lang || `Track ${e.id}`;
3395
3476
  }
3396
3477
  //#endregion
3397
3478
  //#region src/managed/index.ts
3398
- var Nr = 6e3, Pr = 45e3, Fr = 2e3, Ir = 3, Lr = 5e3, Rr = 2e3, zr = 48e4, Br = "keySystemLicenseRequestFailed", Vr = /* @__PURE__ */ new Set([
3479
+ var Ur = 6e3, Wr = 45e3, Gr = 2e3, Kr = 3, qr = 5e3, Jr = 2e3, Yr = 48e4, Xr = "keySystemLicenseRequestFailed", Zr = /* @__PURE__ */ new Set([
3399
3480
  "GONE",
3400
3481
  "NOT_FOUND",
3401
3482
  "INVALID_URN",
@@ -3403,27 +3484,27 @@ var Nr = 6e3, Pr = 45e3, Fr = 2e3, Ir = 3, Lr = 5e3, Rr = 2e3, zr = 48e4, Br = "
3403
3484
  "GEO_DENIED",
3404
3485
  "DRM_DEVICE_REVOKED"
3405
3486
  ]);
3406
- function Hr(e) {
3407
- return !Vr.has(e);
3487
+ function Qr(e) {
3488
+ return !Zr.has(e);
3408
3489
  }
3409
- function Ur(e) {
3490
+ function $r(e) {
3410
3491
  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)})`);
3411
- if (e.env !== void 0) return ct(e.env);
3492
+ if (e.env !== void 0) return lt(e.env);
3412
3493
  if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
3413
3494
  return e.baseUrl;
3414
3495
  }
3415
- async function Wr(e) {
3496
+ async function ei(e) {
3416
3497
  if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
3417
- let t = Ur(e);
3498
+ let t = $r(e);
3418
3499
  if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
3419
3500
  if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
3420
- let r = new Gr({
3501
+ let r = new ti({
3421
3502
  ...e,
3422
3503
  baseUrl: t
3423
3504
  });
3424
3505
  return await r.start(), r;
3425
3506
  }
3426
- var Gr = class {
3507
+ var ti = class {
3427
3508
  opts;
3428
3509
  abort = new AbortController();
3429
3510
  listeners = {};
@@ -3467,7 +3548,7 @@ var Gr = class {
3467
3548
  return this._state;
3468
3549
  }
3469
3550
  get offline() {
3470
- return !R();
3551
+ return !L();
3471
3552
  }
3472
3553
  get descriptor() {
3473
3554
  return this._descriptor;
@@ -3502,7 +3583,7 @@ var Gr = class {
3502
3583
  };
3503
3584
  }
3504
3585
  beginArming(e, t, n = !1) {
3505
- let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
3586
+ let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
3506
3587
  r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
3507
3588
  }
3508
3589
  beginArmingByPolling(e) {
@@ -3523,7 +3604,7 @@ var Gr = class {
3523
3604
  setTimeout(() => {
3524
3605
  a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
3525
3606
  phase: i ? "unavailable" : "tooEarly",
3526
- retryInMs: Pr,
3607
+ retryInMs: Wr,
3527
3608
  attempt: 1,
3528
3609
  elapsedMs: 0,
3529
3610
  ...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
@@ -3562,13 +3643,13 @@ var Gr = class {
3562
3643
  !a && !p() && h();
3563
3644
  }, e);
3564
3645
  };
3565
- _(Nr), this.armingSub = T({
3646
+ _(Ur), this.armingSub = D({
3566
3647
  eventsBaseUrl: t,
3567
3648
  matchUrn: this.opts.matchUrn,
3568
3649
  credential: this.opts.credential,
3569
- onAlive: () => _(Pr),
3650
+ onAlive: () => _(Wr),
3570
3651
  onState: (e) => {
3571
- a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Fr);
3652
+ a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Gr);
3572
3653
  },
3573
3654
  onError: () => h()
3574
3655
  });
@@ -3591,7 +3672,7 @@ var Gr = class {
3591
3672
  let n = await c(this.opts.credential);
3592
3673
  if (this.destroyed || t !== this.loadGen) return;
3593
3674
  this.setState("loading");
3594
- let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = ht(this.opts.video, (e) => {
3675
+ let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = gt(this.opts.video, (e) => {
3595
3676
  this._state !== "ended" && this._state !== "error" && this.setState(e);
3596
3677
  });
3597
3678
  if (await i.load(), this.destroyed || t !== this.loadGen) {
@@ -3613,26 +3694,26 @@ var Gr = class {
3613
3694
  if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
3614
3695
  let i = e.analytics?.sid;
3615
3696
  if (!i) return;
3616
- let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = or(this.opts.baseUrl, a, e.analytics?.endpoint);
3697
+ let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = gr(this.opts.baseUrl, a, e.analytics?.endpoint);
3617
3698
  if (!o) {
3618
3699
  s && setTimeout(() => {
3619
3700
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
3620
3701
  }, 0);
3621
3702
  return;
3622
3703
  }
3623
- let c = this.opts.video, l = new sr({
3704
+ let c = this.opts.video, l = new _r({
3624
3705
  endpoint: o,
3625
3706
  sid: i,
3626
3707
  player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
3627
- sdkVersion: pr,
3628
- environment: dr(c),
3708
+ sdkVersion: Cr,
3709
+ environment: xr(c),
3629
3710
  idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
3630
3711
  onIdle: () => this.onAnalyticsIdle(t),
3631
3712
  onBlocked: (e) => setTimeout(() => {
3632
3713
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
3633
3714
  }, 0),
3634
3715
  sample: () => {
3635
- let e = this.engine?.getStats() ?? ut, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3716
+ let e = this.engine?.getStats() ?? dt, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3636
3717
  return {
3637
3718
  ...e,
3638
3719
  bufferedMs: Math.round(t * 1e3),
@@ -3646,7 +3727,7 @@ var Gr = class {
3646
3727
  let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
3647
3728
  c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
3648
3729
  c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
3649
- }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), fr().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3730
+ }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Sr().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3650
3731
  }
3651
3732
  currentPresentation() {
3652
3733
  let e = this.opts.video;
@@ -3661,7 +3742,7 @@ var Gr = class {
3661
3742
  video: this.opts.video,
3662
3743
  descriptor: e,
3663
3744
  credential: t,
3664
- deviceId: k(),
3745
+ deviceId: Oe(),
3665
3746
  userId: this.opts.userId,
3666
3747
  lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
3667
3748
  snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
@@ -3677,11 +3758,11 @@ var Gr = class {
3677
3758
  emit: (e) => this.onEngineEvent(e),
3678
3759
  freshLicenseUrl: () => this.refreshLicense()
3679
3760
  }, o = this.opts.engine ?? "auto";
3680
- if (o === "native") return new U(a);
3681
- if (o === "hls") return new Un(a);
3682
- if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && V(this.opts.video) && H() || !e.drmEnabled && Dt() && V(this.opts.video)) return new U(a);
3683
- if (Ut()) return new Un(a);
3684
- if (V(this.opts.video)) return new U(a);
3761
+ if (o === "native") return new H(a);
3762
+ if (o === "hls") return new Xn(a);
3763
+ if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled && Ot() && B(this.opts.video)) return new H(a);
3764
+ if (Wt()) return new Xn(a);
3765
+ if (B(this.opts.video)) return new H(a);
3685
3766
  throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
3686
3767
  }
3687
3768
  onEngineEvent(e) {
@@ -3731,11 +3812,11 @@ var Gr = class {
3731
3812
  }
3732
3813
  startLiveState(e) {
3733
3814
  if (this.opts.liveStateEvents === !1) return;
3734
- let t = this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
3815
+ let t = this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
3735
3816
  if (!t) return;
3736
3817
  this.closeLiveState();
3737
3818
  let i = 0, a = !1;
3738
- this.liveStateSub = T({
3819
+ this.liveStateSub = D({
3739
3820
  eventsBaseUrl: t,
3740
3821
  matchUrn: this.opts.matchUrn,
3741
3822
  credential: this.opts.credential,
@@ -3747,11 +3828,11 @@ var Gr = class {
3747
3828
  },
3748
3829
  onError: (o) => {
3749
3830
  if (!(this.destroyed || e !== this.loadGen || a) && !this.endedHandled) {
3750
- if (o instanceof w && (o.terminal || o.status === 404)) {
3831
+ if (o instanceof E && (o.terminal || o.status === 404)) {
3751
3832
  a = !0, this.emit("warning", new n(r(o.status), o.status, `live-state events answered HTTP ${o.status} for ${this.opts.matchUrn}: the match is ` + (o.terminal ? "gone, so the subscription stopped" : "not in the catalog (ended and dropped, or not listed yet), so it retries every 5 min") + " — end-of-stream detection falls back to the HLS staleness watchdog."));
3752
3833
  return;
3753
3834
  }
3754
- i += 1, i >= Ir && (a = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${i} 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.`)));
3835
+ i += 1, i >= Kr && (a = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${i} 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.`)));
3755
3836
  }
3756
3837
  }
3757
3838
  });
@@ -3760,7 +3841,7 @@ var Gr = class {
3760
3841
  this.liveStateSub?.close(), this.liveStateSub = null;
3761
3842
  }
3762
3843
  watchConnectivity() {
3763
- this.connectivity || (this.connectivity = lt(), this.connectivity.onChange((e) => {
3844
+ this.connectivity || (this.connectivity = ut(), this.connectivity.onChange((e) => {
3764
3845
  if (this.destroyed) return;
3765
3846
  if (!e) {
3766
3847
  this.emit("offline");
@@ -3768,7 +3849,7 @@ var Gr = class {
3768
3849
  }
3769
3850
  if (this.emit("online"), this._state !== "error" || !this._lastError) return;
3770
3851
  let t = this._lastError.code;
3771
- Hr(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
3852
+ Qr(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
3772
3853
  }));
3773
3854
  }
3774
3855
  watchReturn() {
@@ -3778,7 +3859,7 @@ var Gr = class {
3778
3859
  return;
3779
3860
  }
3780
3861
  let e = this.hiddenAtMs;
3781
- this.hiddenAtMs = null, e != null && Date.now() - e >= Lr && this.resyncLiveState();
3862
+ this.hiddenAtMs = null, e != null && Date.now() - e >= qr && this.resyncLiveState();
3782
3863
  }, this.onReturnPageShow = (e) => {
3783
3864
  e.persisted && this.resyncLiveState();
3784
3865
  }, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
@@ -3810,7 +3891,7 @@ var Gr = class {
3810
3891
  scheduleRejoin(e) {
3811
3892
  this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
3812
3893
  this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
3813
- }, Math.random() * Fr));
3894
+ }, Math.random() * Gr));
3814
3895
  }
3815
3896
  cancelRejoin() {
3816
3897
  this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
@@ -3834,7 +3915,7 @@ var Gr = class {
3834
3915
  }
3835
3916
  t.controls = !1;
3836
3917
  let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
3837
- r && r.insertBefore(n, t), n.appendChild(t), gr(n, this.opts.theme), this.container = n, this.controlBar = Dr({
3918
+ r && r.insertBefore(n, t), n.appendChild(t), Er(n, this.opts.theme), this.container = n, this.controlBar = Lr({
3838
3919
  root: n,
3839
3920
  video: t,
3840
3921
  player: this,
@@ -3873,7 +3954,7 @@ var Gr = class {
3873
3954
  }
3874
3955
  startStats() {
3875
3956
  this.stopStats();
3876
- let e = Math.max(500, this.opts.statsIntervalMs ?? Rr);
3957
+ let e = Math.max(500, this.opts.statsIntervalMs ?? Jr);
3877
3958
  this.statsTimer = setInterval(() => {
3878
3959
  if (!this.engine) return;
3879
3960
  let e = this.engine.getStats();
@@ -3884,14 +3965,14 @@ var Gr = class {
3884
3965
  this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
3885
3966
  }
3886
3967
  isStaleLicenseDenial(e) {
3887
- return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== Br || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : G(this._descriptor?.drm?.widevine?.licenseUrl);
3968
+ return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== Xr || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : W(this._descriptor?.drm?.widevine?.licenseUrl);
3888
3969
  }
3889
3970
  scheduleLicenseRefresh() {
3890
3971
  if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
3891
3972
  typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
3892
- document.visibilityState !== "visible" || this.destroyed || G(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
3973
+ document.visibilityState !== "visible" || this.destroyed || W(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
3893
3974
  }, document.addEventListener("visibilitychange", this.onRefocus));
3894
- let e = this.opts.licenseRefreshMs ?? zr;
3975
+ let e = this.opts.licenseRefreshMs ?? Yr;
3895
3976
  e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
3896
3977
  }
3897
3978
  stopRefresh() {
@@ -3948,7 +4029,7 @@ var Gr = class {
3948
4029
  this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
3949
4030
  }
3950
4031
  getStats() {
3951
- return this.engine?.getStats() ?? ut;
4032
+ return this.engine?.getStats() ?? dt;
3952
4033
  }
3953
4034
  getQualityLevels() {
3954
4035
  return this.engine?.getQualityLevels() ?? [];
@@ -3987,13 +4068,13 @@ var Gr = class {
3987
4068
  e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
3988
4069
  }
3989
4070
  async enterFullscreen() {
3990
- return !this.destroyed && S(this.opts.video, this.container ?? void 0);
4071
+ return !this.destroyed && w(this.opts.video, this.container ?? void 0);
3991
4072
  }
3992
4073
  async exitFullscreen() {
3993
- await C(this.opts.video, this.container ?? void 0);
4074
+ await T(this.opts.video, this.container ?? void 0);
3994
4075
  }
3995
4076
  fullscreenSupported() {
3996
- return !this.destroyed && x(this.opts.video, this.container ?? void 0);
4077
+ return !this.destroyed && C(this.opts.video, this.container ?? void 0);
3997
4078
  }
3998
4079
  retry() {
3999
4080
  return this.reload();
@@ -4024,7 +4105,7 @@ var Gr = class {
4024
4105
  for (let e of Object.keys(this.listeners)) this.listeners[e]?.clear();
4025
4106
  }
4026
4107
  fail(e) {
4027
- this._lastError = e, this.failedWhileOffline = !R(), this.setState("error"), this.analyticsSession?.noteFatal(), this.emit("error", e);
4108
+ this._lastError = e, this.failedWhileOffline = !L(), this.setState("error"), this.analyticsSession?.noteFatal(), this.emit("error", e);
4028
4109
  }
4029
4110
  setState(e) {
4030
4111
  if (e === this._state) return;
@@ -4056,12 +4137,12 @@ var Gr = class {
4056
4137
  };
4057
4138
  //#endregion
4058
4139
  //#region src/embed/protocol.ts
4059
- function Kr(e) {
4140
+ function $(e) {
4060
4141
  return !!e && typeof e == "object" && typeof e.type == "string" && e.type.startsWith("oddin:");
4061
4142
  }
4062
4143
  //#endregion
4063
4144
  //#region src/embed/host.ts
4064
- function qr(e) {
4145
+ function ni(e) {
4065
4146
  if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
4066
4147
  if (!e.src) throw Error("mountEmbed: opts.src is required");
4067
4148
  if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
@@ -4070,7 +4151,7 @@ function qr(e) {
4070
4151
  let r = document.createElement("iframe");
4071
4152
  r.src = t.toString(), r.allow = "autoplay; encrypted-media; fullscreen", r.setAttribute("allowfullscreen", ""), r.referrerPolicy = "no-referrer", r.setAttribute("sandbox", e.sandbox ?? "allow-scripts allow-same-origin allow-presentation"), r.style.cssText = "border:0;width:100%;height:100%;display:block", e.container.appendChild(r);
4072
4153
  let i = /* @__PURE__ */ new Set(), a = (t) => {
4073
- if (t.source !== r.contentWindow || t.origin !== n || !Kr(t.data)) return;
4154
+ if (t.source !== r.contentWindow || t.origin !== n || !$(t.data)) return;
4074
4155
  let a = t.data;
4075
4156
  a.type === "oddin:ready" && a.protocol !== 1 && console.warn(`havik-player: embed protocol v${a.protocol} != host v1. Pin the embed page version to the SDK version to avoid skew.`), e.onEvent?.(a), i.forEach((e) => e(a));
4076
4157
  };
@@ -4120,15 +4201,15 @@ function qr(e) {
4120
4201
  }
4121
4202
  //#endregion
4122
4203
  //#region src/embed/page.ts
4123
- var Jr = /^[A-Za-z0-9:_.-]{1,128}$/;
4124
- function Yr(e) {
4204
+ var ri = /^[A-Za-z0-9:_.-]{1,128}$/;
4205
+ function ii(e) {
4125
4206
  if (typeof e == "boolean") return e;
4126
4207
  if (typeof e == "object" && e) {
4127
4208
  let t = e.endpoint;
4128
4209
  return typeof t == "string" ? { endpoint: t } : {};
4129
4210
  }
4130
4211
  }
4131
- function Xr() {
4212
+ function ai() {
4132
4213
  let e = window.HAVIK_EMBED_CONFIG;
4133
4214
  if (e) return {
4134
4215
  baseUrl: e.baseUrl ?? "",
@@ -4138,7 +4219,7 @@ function Xr() {
4138
4219
  autoplay: e.autoplay ?? !0,
4139
4220
  muted: e.muted ?? !0,
4140
4221
  waitForLive: e.waitForLive ?? !0,
4141
- analytics: Yr(e.analytics)
4222
+ analytics: ii(e.analytics)
4142
4223
  };
4143
4224
  let t = new URLSearchParams(location.search);
4144
4225
  return {
@@ -4151,9 +4232,9 @@ function Xr() {
4151
4232
  waitForLive: !0
4152
4233
  };
4153
4234
  }
4154
- async function Zr() {
4155
- let e = Xr();
4156
- $r();
4235
+ async function oi() {
4236
+ let e = ai();
4237
+ ci();
4157
4238
  let t = document.createElement("video");
4158
4239
  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);
4159
4240
  let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
@@ -4209,12 +4290,12 @@ async function Zr() {
4209
4290
  message: e.message,
4210
4291
  ...e.country === void 0 ? {} : { country: e.country }
4211
4292
  })), e.on("autoplayblocked", () => {
4212
- i({ type: "oddin:autoplayblocked" }), Qr(t, e);
4293
+ i({ type: "oddin:autoplayblocked" }), si(t, e);
4213
4294
  });
4214
4295
  }, s = async (r) => {
4215
4296
  a?.destroy(), a = null;
4216
4297
  try {
4217
- let n = await Wr({
4298
+ let n = await ei({
4218
4299
  video: t,
4219
4300
  baseUrl: e.baseUrl,
4220
4301
  matchUrn: r,
@@ -4277,30 +4358,30 @@ async function Zr() {
4277
4358
  a?.retry();
4278
4359
  break;
4279
4360
  case "oddin:load":
4280
- typeof e.matchUrn == "string" && Jr.test(e.matchUrn) && s(e.matchUrn);
4361
+ typeof e.matchUrn == "string" && ri.test(e.matchUrn) && s(e.matchUrn);
4281
4362
  break;
4282
4363
  case "oddin:destroy": c();
4283
4364
  }
4284
4365
  }, u = (e) => {
4285
- r && e.origin === r && Kr(e.data) && l(e.data);
4366
+ r && e.origin === r && $(e.data) && l(e.data);
4286
4367
  };
4287
4368
  r && window.addEventListener("message", u), window.addEventListener("pagehide", c, { once: !0 }), await s(e.matchUrn), i({
4288
4369
  type: "oddin:ready",
4289
4370
  protocol: 1
4290
4371
  });
4291
4372
  }
4292
- function Qr(e, t) {
4373
+ function si(e, t) {
4293
4374
  if (document.getElementById("havik-tap")) return;
4294
4375
  let n = document.createElement("button");
4295
4376
  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", () => {
4296
4377
  n.remove(), t.play();
4297
4378
  }), document.body.appendChild(n);
4298
4379
  }
4299
- function $r() {
4380
+ function ci() {
4300
4381
  let e = document.createElement("style");
4301
4382
  e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
4302
4383
  }
4303
4384
  //#endregion
4304
- export { w as LiveStateHttpError, mr as ODDIN_THEME, n as PlaybackError, gr as applyTheme, ct as baseUrlForEnv, Zr as bootEmbed, ke as clearDeviceId, Ve as clearRememberedBandwidth, Wr as createPlayer, E as deriveEventsBaseUrl, it as detectDrmSupport, S as enterVideoFullscreen, C as exitVideoFullscreen, be as fetchCatalog, Se as fetchTournament, we as flattenMatches, x as fullscreenSupported, k as getDeviceId, ot as isLowLatencyManifest, Kr as isOddinMessage, je as licenseRequestHeaders, qr as mountEmbed, fe as pollToLive, y as resolveStream, T as subscribeLiveState, ye as videoFullscreenActive, Ee as watchStatus };
4385
+ export { E as LiveStateHttpError, wr as ODDIN_THEME, n as PlaybackError, Er as applyTheme, lt as baseUrlForEnv, oi as bootEmbed, ke as clearDeviceId, He as clearRememberedBandwidth, ei as createPlayer, O as deriveEventsBaseUrl, at as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, C as fullscreenSupported, Oe as getDeviceId, st as isLowLatencyManifest, $ as isOddinMessage, je as licenseRequestHeaders, ni as mountEmbed, fe as pollToLive, y as resolveStream, D as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
4305
4386
 
4306
4387
  //# sourceMappingURL=index.js.map