@oddin-gg/havik-player 2.16.1 → 2.16.2

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
@@ -290,32 +290,32 @@ function me(e, t) {
290
290
  function he(e) {
291
291
  return e.ownerDocument ?? document;
292
292
  }
293
- function S(e) {
293
+ function ge(e) {
294
294
  return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
295
295
  }
296
- function C(e, t) {
297
- let n = S(he(e));
296
+ function S(e, t) {
297
+ let n = ge(he(e));
298
298
  return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
299
299
  }
300
- async function w(e, t) {
300
+ async function C(e, t) {
301
301
  let n = t ?? e;
302
302
  if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
303
303
  if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
304
304
  let r = e;
305
305
  return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
306
306
  }
307
- async function T(e, t) {
307
+ async function w(e, t) {
308
308
  let n = e;
309
309
  if (n.webkitDisplayingFullscreen) {
310
310
  n.webkitExitFullscreen?.();
311
311
  return;
312
312
  }
313
- let r = he(e), i = S(r);
313
+ let r = he(e), i = ge(r);
314
314
  i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
315
315
  }
316
316
  //#endregion
317
317
  //#region src/core/catalog.ts
318
- async function ge(e) {
318
+ async function _e(e) {
319
319
  let t = new URLSearchParams();
320
320
  e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
321
321
  let i = t.toString(), a = d(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
@@ -333,12 +333,12 @@ async function ge(e) {
333
333
  };
334
334
  if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
335
335
  return {
336
- tournaments: _e(await s.json()),
336
+ tournaments: ve(await s.json()),
337
337
  etag: s.headers.get("etag") ?? void 0,
338
338
  notModified: !1
339
339
  };
340
340
  }
341
- function _e(e) {
341
+ function ve(e) {
342
342
  return (e.tournaments ?? []).map((e) => {
343
343
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
344
344
  return {
@@ -360,7 +360,7 @@ function _e(e) {
360
360
  };
361
361
  });
362
362
  }
363
- async function ve(e) {
363
+ async function ye(e) {
364
364
  let t = d(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
365
365
  e.etag && i.set("If-None-Match", e.etag);
366
366
  let a = await p(t, {
@@ -380,13 +380,13 @@ async function ve(e) {
380
380
  };
381
381
  if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
382
382
  return {
383
- tournament: ye(await a.json()),
383
+ tournament: be(await a.json()),
384
384
  etag: a.headers.get("etag") ?? void 0,
385
385
  notModified: !1,
386
386
  notFound: !1
387
387
  };
388
388
  }
389
- function ye(e) {
389
+ function be(e) {
390
390
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
391
391
  return {
392
392
  urn: t,
@@ -406,17 +406,17 @@ function ye(e) {
406
406
  }))
407
407
  };
408
408
  }
409
- function be(e) {
409
+ function xe(e) {
410
410
  return e.tournaments.flatMap((e) => e.matches);
411
411
  }
412
412
  //#endregion
413
413
  //#region src/core/poll.ts
414
- var xe = /* @__PURE__ */ new Set([
414
+ var Se = /* @__PURE__ */ new Set([
415
415
  "NOT_FOUND",
416
416
  "GONE",
417
417
  "INVALID_URN"
418
418
  ]);
419
- function Se(e) {
419
+ function Ce(e) {
420
420
  let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, u = !1, f = () => {
421
421
  u || (a = setTimeout(m, t));
422
422
  }, m = async () => {
@@ -449,7 +449,7 @@ function Se(e) {
449
449
  } catch (t) {
450
450
  if (!i.signal.aborted) {
451
451
  let r = t instanceof n ? t : new n("NETWORK", 0, String(t));
452
- xe.has(r.code) && (u = !0), e.onError?.(r);
452
+ Se.has(r.code) && (u = !0), e.onError?.(r);
453
453
  }
454
454
  } finally {
455
455
  f();
@@ -461,9 +461,9 @@ function Se(e) {
461
461
  }
462
462
  //#endregion
463
463
  //#region src/core/events.ts
464
- var Ce = 45e3;
465
- function E(e) {
466
- let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ?? Ce, i = Number.isFinite(r) && r > 0 ? r : 0, a = new AbortController(), o = !1, c = (e) => new Promise((t) => {
464
+ var we = 45e3;
465
+ function T(e) {
466
+ let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ?? we, i = Number.isFinite(r) && r > 0 ? r : 0, a = new AbortController(), o = !1, c = (e) => new Promise((t) => {
467
467
  if (a.signal.aborted) return t();
468
468
  let n = setTimeout(t, e);
469
469
  a.signal.addEventListener("abort", () => {
@@ -544,7 +544,7 @@ function E(e) {
544
544
  o || (o = !0, a.abort());
545
545
  } };
546
546
  }
547
- function D(e) {
547
+ function E(e) {
548
548
  try {
549
549
  let t = new URL(e);
550
550
  return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
@@ -554,27 +554,27 @@ function D(e) {
554
554
  }
555
555
  //#endregion
556
556
  //#region src/core/drm/deviceId.ts
557
- var O = "havik.player.deviceId", k;
558
- function A() {
559
- if (k) return k;
557
+ var D = "havik.player.deviceId", O;
558
+ function k() {
559
+ if (O) return O;
560
560
  try {
561
- let e = globalThis.localStorage?.getItem(O);
562
- if (e) return k = e, e;
561
+ let e = globalThis.localStorage?.getItem(D);
562
+ if (e) return O = e, e;
563
563
  } catch {}
564
- let e = Te();
565
- k = e;
564
+ let e = Ee();
565
+ O = e;
566
566
  try {
567
- globalThis.localStorage?.setItem(O, e);
567
+ globalThis.localStorage?.setItem(D, e);
568
568
  } catch {}
569
569
  return e;
570
570
  }
571
- function we() {
572
- k = void 0;
571
+ function Te() {
572
+ O = void 0;
573
573
  try {
574
- globalThis.localStorage?.removeItem(O);
574
+ globalThis.localStorage?.removeItem(D);
575
575
  } catch {}
576
576
  }
577
- function Te() {
577
+ function Ee() {
578
578
  let e = globalThis.crypto;
579
579
  if (e && typeof e.randomUUID == "function") return e.randomUUID();
580
580
  let t = /* @__PURE__ */ new Uint8Array(16);
@@ -586,21 +586,21 @@ function Te() {
586
586
  }
587
587
  //#endregion
588
588
  //#region src/core/drm/headers.ts
589
- function Ee(e, t, n = {}) {
589
+ function De(e, t, n = {}) {
590
590
  let r = {
591
591
  "x-api-key": t.apiKey,
592
592
  "X-Match-Urn": e.matchUrn,
593
- "X-Device-Id": n.deviceId ?? A(),
593
+ "X-Device-Id": n.deviceId ?? k(),
594
594
  "Content-Type": "application/octet-stream"
595
595
  };
596
596
  return n.userId && (r["X-User-Id"] = n.userId), r;
597
597
  }
598
598
  //#endregion
599
599
  //#region src/core/drm/cdm.ts
600
- var j = /* @__PURE__ */ new WeakMap();
601
- function De(e, t) {
602
- let n = j.get(e);
603
- n || (n = /* @__PURE__ */ new Map(), j.set(e, n));
600
+ var A = /* @__PURE__ */ new WeakMap();
601
+ function Oe(e, t) {
602
+ let n = A.get(e);
603
+ n || (n = /* @__PURE__ */ new Map(), A.set(e, n));
604
604
  let r = n.get(t.keySystem);
605
605
  if (r) return r;
606
606
  let i = t.createMediaKeys().catch((e) => {
@@ -608,22 +608,22 @@ function De(e, t) {
608
608
  });
609
609
  return n.set(t.keySystem, i), i;
610
610
  }
611
- function M() {
611
+ function j() {
612
612
  return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
613
613
  }
614
- var N = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
615
- function Oe(e) {
614
+ var M = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
615
+ function ke(e) {
616
616
  return e.startsWith("com.widevine");
617
617
  }
618
- function P(e, t) {
619
- if (!Oe(e)) return t;
618
+ function N(e, t) {
619
+ if (!ke(e)) return t;
620
620
  let n = (e, t) => {
621
621
  let n = e.videoCapabilities;
622
622
  return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
623
- let n = N.indexOf(e.robustness);
624
- return n === -1 || N.indexOf(t) > n;
623
+ let n = M.indexOf(e.robustness);
624
+ return n === -1 || M.indexOf(t) > n;
625
625
  });
626
- }, r = N.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
626
+ }, r = M.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
627
627
  ...t,
628
628
  videoCapabilities: t.videoCapabilities?.map((t) => ({
629
629
  ...t,
@@ -632,53 +632,53 @@ function P(e, t) {
632
632
  })));
633
633
  return [...t, ...r];
634
634
  }
635
- function F(e) {
636
- return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, P(t, n)).then((t) => ({
635
+ function P(e) {
636
+ return (t, n) => j() ? navigator.requestMediaKeySystemAccess(t, N(t, n)).then((t) => ({
637
637
  keySystem: t.keySystem,
638
638
  getConfiguration: () => t.getConfiguration(),
639
- createMediaKeys: () => De(e, t)
639
+ createMediaKeys: () => Oe(e, t)
640
640
  })) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
641
641
  }
642
- var I = {
642
+ var F = {
643
643
  video: "SW_SECURE_DECODE",
644
644
  audio: "SW_SECURE_CRYPTO",
645
645
  scheme: "cbcs"
646
646
  };
647
- function ke(e) {
648
- if (!M()) return;
647
+ function Ae(e) {
648
+ if (!j()) return;
649
649
  let t = (e, t) => ({
650
650
  contentType: e,
651
651
  robustness: t,
652
- encryptionScheme: I.scheme
652
+ encryptionScheme: F.scheme
653
653
  });
654
- F(e)("com.widevine.alpha", [{
654
+ P(e)("com.widevine.alpha", [{
655
655
  initDataTypes: ["cenc"],
656
656
  distinctiveIdentifier: "optional",
657
657
  persistentState: "optional",
658
658
  sessionTypes: ["temporary"],
659
- audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", I.audio)],
660
- videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", I.video)]
659
+ audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", F.audio)],
660
+ videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", F.video)]
661
661
  }]).then((e) => e.createMediaKeys()).catch(() => {});
662
662
  }
663
- function L(e) {
664
- let t = R(e);
663
+ function I(e) {
664
+ let t = L(e);
665
665
  if (/^avc[13]/.test(t)) return "avc";
666
666
  if (/^(hvc1|hev1)/.test(t)) return "hevc";
667
667
  if (/^(dvh1|dvhe)/.test(t)) return "dv";
668
668
  if (t.startsWith("av01")) return "av1";
669
669
  if (/^vp0?9/.test(t)) return "vp9";
670
670
  }
671
- function R(e) {
671
+ function L(e) {
672
672
  return (e ?? "").trim().toLowerCase();
673
673
  }
674
- var Ae = {
674
+ var R = {
675
675
  hevc: "hvc1.1.6.L93.90",
676
676
  dv: "dvh1.05.06",
677
677
  av1: "av01.0.05M.08",
678
678
  vp9: "vp09.00.10.08"
679
- }, je = /* @__PURE__ */ new Map(), z = /* @__PURE__ */ new Map();
680
- function Me(e) {
681
- let t = R(e), n = je.get(t);
679
+ }, z = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map();
680
+ function V(e) {
681
+ let t = L(e), n = z.get(t);
682
682
  if (n) return n;
683
683
  let r = {
684
684
  initDataTypes: ["cenc"],
@@ -687,32 +687,32 @@ function Me(e) {
687
687
  sessionTypes: ["temporary"],
688
688
  videoCapabilities: [{
689
689
  contentType: `video/mp4; codecs="${e.trim()}"`,
690
- robustness: I.video,
691
- encryptionScheme: I.scheme
690
+ robustness: F.video,
691
+ encryptionScheme: F.scheme
692
692
  }]
693
693
  }, i = (async () => {
694
694
  try {
695
- return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", P("com.widevine.alpha", [r])), !0;
695
+ return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", N("com.widevine.alpha", [r])), !0;
696
696
  } catch {
697
697
  return !1;
698
698
  }
699
- })().then((e) => (z.set(t, e), e));
700
- return je.set(t, i), i;
699
+ })().then((e) => (B.set(t, e), e));
700
+ return z.set(t, i), i;
701
701
  }
702
- function Ne() {
703
- if (M()) for (let e of Object.values(Ae)) Me(e);
702
+ function je() {
703
+ if (j()) for (let e of Object.values(R)) V(e);
704
704
  }
705
- function Pe(e) {
706
- let t = L(e);
707
- if (t) return t === "avc" ? !0 : z.get(R(e)) ?? z.get(R(Ae[t]));
705
+ function Me(e) {
706
+ let t = I(e);
707
+ if (t) return t === "avc" ? !0 : B.get(L(e)) ?? B.get(L(R[t]));
708
708
  }
709
709
  //#endregion
710
710
  //#region src/core/drm/support.ts
711
- var Fe = 5e3, Ie = "video/mp4; codecs=\"avc1.42E01E\"", Le = "audio/mp4; codecs=\"mp4a.40.2\"", Re = {
711
+ var Ne = 5e3, Pe = "video/mp4; codecs=\"avc1.42E01E\"", Fe = "audio/mp4; codecs=\"mp4a.40.2\"", Ie = {
712
712
  widevine: ["com.widevine.alpha"],
713
713
  fairplay: ["com.apple.fps"]
714
714
  };
715
- function ze(e) {
715
+ function Le(e) {
716
716
  return e === "fairplay" ? [{
717
717
  initDataTypes: [
718
718
  "sinf",
@@ -720,30 +720,30 @@ function ze(e) {
720
720
  "cenc"
721
721
  ],
722
722
  videoCapabilities: [{
723
- contentType: Ie,
723
+ contentType: Pe,
724
724
  robustness: "",
725
725
  encryptionScheme: "cbcs"
726
726
  }],
727
727
  audioCapabilities: [{
728
- contentType: Le,
728
+ contentType: Fe,
729
729
  robustness: "",
730
730
  encryptionScheme: "cbcs"
731
731
  }]
732
- }] : P("com.widevine.alpha", [{
732
+ }] : N("com.widevine.alpha", [{
733
733
  initDataTypes: ["cenc"],
734
734
  videoCapabilities: [{
735
- contentType: Ie,
736
- robustness: I.video,
737
- encryptionScheme: I.scheme
735
+ contentType: Pe,
736
+ robustness: F.video,
737
+ encryptionScheme: F.scheme
738
738
  }],
739
739
  audioCapabilities: [{
740
- contentType: Le,
741
- robustness: I.audio,
742
- encryptionScheme: I.scheme
740
+ contentType: Fe,
741
+ robustness: F.audio,
742
+ encryptionScheme: F.scheme
743
743
  }]
744
744
  }]);
745
745
  }
746
- function Be(e, t) {
746
+ function Re(e, t) {
747
747
  return new Promise((n, r) => {
748
748
  let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
749
749
  e.then((e) => {
@@ -753,8 +753,8 @@ function Be(e, t) {
753
753
  });
754
754
  });
755
755
  }
756
- async function Ve(e = {}) {
757
- let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Fe, r = {};
756
+ async function ze(e = {}) {
757
+ let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ne, r = {};
758
758
  if (typeof window < "u" && window.isSecureContext === !1) return {
759
759
  verdict: "insecure-context",
760
760
  detail: r
@@ -766,7 +766,7 @@ async function Ve(e = {}) {
766
766
  };
767
767
  let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
768
768
  for (let e of t) {
769
- let t = Re[e];
769
+ let t = Ie[e];
770
770
  if (!t) {
771
771
  r[e] = "unknown system";
772
772
  continue;
@@ -777,7 +777,7 @@ async function Ve(e = {}) {
777
777
  break;
778
778
  }
779
779
  try {
780
- return await Be((await Be(i(n, ze(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
780
+ return await Re((await Re(i(n, Le(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
781
781
  verdict: "supported",
782
782
  system: e,
783
783
  detail: r
@@ -801,49 +801,49 @@ async function Ve(e = {}) {
801
801
  }
802
802
  //#endregion
803
803
  //#region src/core/manifest.ts
804
- var He = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
805
- function Ue(e) {
806
- return He.test(e);
804
+ var Be = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
805
+ function Ve(e) {
806
+ return Be.test(e);
807
807
  }
808
808
  //#endregion
809
809
  //#region src/core/env.ts
810
- var We = {
810
+ var He = {
811
811
  integration: "https://feed-dev.oddin-video.gg",
812
812
  production: "https://feed.oddin-video.gg"
813
813
  };
814
- function B(e) {
815
- let t = Object.prototype.hasOwnProperty.call(We, e) ? We[e] : void 0;
814
+ function Ue(e) {
815
+ let t = Object.prototype.hasOwnProperty.call(He, e) ? He[e] : void 0;
816
816
  if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
817
817
  return t;
818
818
  }
819
819
  //#endregion
820
820
  //#region src/core/stats.ts
821
- var V = { droppedFrames: 0 };
822
- function H(e) {
821
+ var We = { droppedFrames: 0 };
822
+ function Ge(e) {
823
823
  try {
824
824
  return new URL(e).host;
825
825
  } catch {
826
826
  return "";
827
827
  }
828
828
  }
829
- var Ge = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
830
- function Ke(e) {
829
+ var Ke = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
830
+ function qe(e) {
831
831
  if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
832
832
  let t = "", n = -1, r = performance.getEntriesByType("resource");
833
- for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Ge.test(i.name)) && i.startTime >= n) {
834
- let e = H(i.name);
833
+ for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Ke.test(i.name)) && i.startTime >= n) {
834
+ let e = Ge(i.name);
835
835
  e && (t = e, n = i.startTime);
836
836
  }
837
837
  return t;
838
838
  }
839
- function U(e) {
839
+ function H(e) {
840
840
  let t = e.getVideoPlaybackQuality?.();
841
841
  return {
842
842
  dropped: t?.droppedVideoFrames ?? 0,
843
843
  totalFrames: t?.totalVideoFrames ?? 0
844
844
  };
845
845
  }
846
- function qe(e, t) {
846
+ function Je(e, t) {
847
847
  let n = [
848
848
  ["playing", () => t("playing")],
849
849
  ["waiting", () => t("buffering")],
@@ -860,8 +860,8 @@ function qe(e, t) {
860
860
  }
861
861
  //#endregion
862
862
  //#region src/core/engine/native.ts
863
- var Je = 2e3, Ye = 3;
864
- function Xe(e) {
863
+ var Ye = 2e3, Xe = 3, U = 500, Ze = 6e3, Qe = .25;
864
+ function $e(e) {
865
865
  try {
866
866
  let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
867
867
  return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
@@ -877,7 +877,7 @@ function G() {
877
877
  let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
878
878
  return e || t;
879
879
  }
880
- function Ze() {
880
+ function et() {
881
881
  if (typeof navigator > "u" || !G()) return !1;
882
882
  let e = navigator.userAgent ?? "";
883
883
  return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
@@ -894,6 +894,7 @@ var K = class {
894
894
  onVisibility = null;
895
895
  onPageShow = null;
896
896
  hiddenSince = null;
897
+ refocusTimer = null;
897
898
  fairplayKeyIV;
898
899
  loadStarted;
899
900
  preloadTouched = !1;
@@ -921,7 +922,7 @@ var K = class {
921
922
  type: "error",
922
923
  error: new n("INTERNAL", 0, "native HLS playback error"),
923
924
  fatal: !0
924
- }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Qe(t.manifestUrl, t.analytics?.sid), e.load();
925
+ }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = tt(t.manifestUrl, t.analytics?.sid), e.load();
925
926
  }
926
927
  startLoad() {
927
928
  this.loadStarted || (this.loadStarted = !0, this.restorePreload());
@@ -943,7 +944,7 @@ var K = class {
943
944
  });
944
945
  this.onEncrypted = (n) => {
945
946
  let i = n;
946
- i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Xe(i.initData), (async () => {
947
+ i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = $e(i.initData), (async () => {
947
948
  try {
948
949
  let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
949
950
  initDataTypes: [i.initDataType],
@@ -1038,11 +1039,11 @@ var K = class {
1038
1039
  e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
1039
1040
  }
1040
1041
  getStats() {
1041
- let e = this.deps.video, t = U(e), n = {
1042
+ let e = this.deps.video, t = H(e), n = {
1042
1043
  droppedFrames: t.dropped,
1043
1044
  decodedFrames: t.totalFrames
1044
1045
  };
1045
- if (this.cdnHost ||= Ke(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1046
+ if (this.cdnHost ||= qe(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1046
1047
  if (n.isLive = !0, e.seekable.length > 0) {
1047
1048
  let t = e.seekable.end(e.seekable.length - 1);
1048
1049
  n.atLiveEdge = e.currentTime >= t - 2;
@@ -1061,27 +1062,48 @@ var K = class {
1061
1062
  this.deps.snapToLiveOnRefocus === !1 || typeof document > "u" || this.onVisibility || (this.onVisibility = () => {
1062
1063
  let e = typeof performance < "u" ? performance.now() : Date.now();
1063
1064
  if (document.visibilityState === "hidden") {
1064
- this.hiddenSince = e;
1065
+ this.hiddenSince = e, this.cancelRefocus();
1065
1066
  return;
1066
1067
  }
1067
1068
  let t = this.hiddenSince;
1068
- this.hiddenSince = null, t != null && e - t >= Je && this.snapToLive();
1069
+ this.hiddenSince = null, t != null && e - t >= Ye && this.armRefocus();
1069
1070
  }, this.onPageShow = (e) => {
1070
- e.persisted && this.snapToLive();
1071
+ e.persisted && this.armRefocus();
1071
1072
  }, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
1072
1073
  }
1073
- snapToLive() {
1074
+ armRefocus() {
1075
+ if (this.cancelRefocus(), Number.isFinite(this.deps.video.duration)) return;
1076
+ let e = this.liveEnd(), t = () => typeof performance < "u" ? performance.now() : Date.now(), n = t(), r = 0, i = () => {
1077
+ if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
1078
+ r += U;
1079
+ let a = this.liveEnd(), o = a != null && (e == null || a >= e + Qe), s = Math.max(r, t() - n) >= Ze;
1080
+ if (o || s && a != null) {
1081
+ this.snapToLive();
1082
+ return;
1083
+ }
1084
+ this.refocusTimer = setTimeout(i, U);
1085
+ };
1086
+ this.refocusTimer = setTimeout(i, U);
1087
+ }
1088
+ cancelRefocus() {
1089
+ this.refocusTimer != null && clearTimeout(this.refocusTimer), this.refocusTimer = null;
1090
+ }
1091
+ liveEnd() {
1074
1092
  let e = this.deps.video;
1075
- if (e.duration !== Infinity || e.seekable.length === 0) return;
1076
- let t = e.seekable.start(e.seekable.length - 1), n = e.seekable.end(e.seekable.length - 1);
1077
- if (!Number.isFinite(n)) return;
1078
- let r = Math.max(t, n - Ye);
1093
+ if (e.duration !== Infinity || e.seekable.length === 0) return null;
1094
+ let t = e.seekable.end(e.seekable.length - 1);
1095
+ return Number.isFinite(t) ? t : null;
1096
+ }
1097
+ snapToLive() {
1098
+ let e = this.deps.video, t = this.liveEnd();
1099
+ if (t == null) return;
1100
+ let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - Xe, r);
1079
1101
  try {
1080
- e.currentTime = r;
1102
+ e.currentTime = i;
1081
1103
  } catch {}
1082
1104
  }
1083
1105
  destroy() {
1084
- this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onPageShow && typeof window < "u" && (window.removeEventListener("pageshow", this.onPageShow), this.onPageShow = null);
1106
+ this.cancelRefocus(), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onPageShow && typeof window < "u" && (window.removeEventListener("pageshow", this.onPageShow), this.onPageShow = null);
1085
1107
  let { video: e } = this.deps;
1086
1108
  this.onLoaded && e.removeEventListener("loadedmetadata", this.onLoaded), this.onError && e.removeEventListener("error", this.onError), this.onEncrypted && e.removeEventListener("encrypted", this.onEncrypted), this.keySession?.close().catch(() => {}), this.keySession = null, this.fairplayArmed = !1, this.fairplayKeyIV = void 0;
1087
1109
  try {
@@ -1093,13 +1115,13 @@ var K = class {
1093
1115
  } catch {}
1094
1116
  }
1095
1117
  };
1096
- function Qe(e, t) {
1118
+ function tt(e, t) {
1097
1119
  return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
1098
1120
  }
1099
1121
  //#endregion
1100
1122
  //#region src/core/engine/prefetch.ts
1101
- var $e = 15e3, et = 5e3, tt = 6;
1102
- function nt(e) {
1123
+ var nt = 15e3, rt = 5e3, it = 6;
1124
+ function at(e) {
1103
1125
  try {
1104
1126
  let t = new URL(e);
1105
1127
  return t.searchParams.delete("CMCD"), t.toString();
@@ -1107,7 +1129,7 @@ function nt(e) {
1107
1129
  return e;
1108
1130
  }
1109
1131
  }
1110
- var rt = class {
1132
+ var ot = class {
1111
1133
  cmcd;
1112
1134
  entries = /* @__PURE__ */ new Map();
1113
1135
  keyed = /* @__PURE__ */ new Set();
@@ -1130,10 +1152,10 @@ var rt = class {
1130
1152
  }
1131
1153
  prefetch(e, t, n) {
1132
1154
  if (!this.isActive(t)) return;
1133
- let r = nt(e);
1155
+ let r = at(e);
1134
1156
  if (this.entries.has(r)) return;
1135
1157
  let i = this.perTrack.get(t) ?? 0;
1136
- if (i >= tt) return;
1158
+ if (i >= it) return;
1137
1159
  this.perTrack.set(t, i + 1);
1138
1160
  let a = new AbortController(), o = {
1139
1161
  started: performance.now(),
@@ -1147,10 +1169,10 @@ var rt = class {
1147
1169
  signal: a.signal
1148
1170
  }).then(async (e) => (o.first = performance.now(), e.ok ? e.arrayBuffer() : null)).catch(() => null), this.entries.set(r, o), this.stats.started += 1, setTimeout(() => {
1149
1171
  this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
1150
- }, $e);
1172
+ }, nt);
1151
1173
  }
1152
1174
  take(e) {
1153
- let t = nt(e), n = this.entries.get(t);
1175
+ let t = at(e), n = this.entries.get(t);
1154
1176
  return n && this.entries.delete(t), n;
1155
1177
  }
1156
1178
  destroy() {
@@ -1170,13 +1192,13 @@ var rt = class {
1170
1192
  }
1171
1193
  }
1172
1194
  };
1173
- function it(t) {
1195
+ function st(t) {
1174
1196
  let n = e.DefaultConfig?.loader;
1175
1197
  if (typeof n != "function") return;
1176
1198
  class r extends n {
1177
1199
  served = !1;
1178
1200
  cancelled = !1;
1179
- stats = at();
1201
+ stats = ct();
1180
1202
  load(e, n, r) {
1181
1203
  let i = e.rangeEnd ? void 0 : t.take(e.url);
1182
1204
  if (!i) {
@@ -1184,7 +1206,7 @@ function it(t) {
1184
1206
  return;
1185
1207
  }
1186
1208
  this.served = !0;
1187
- let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || et, s = setTimeout(() => {
1209
+ let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || rt, s = setTimeout(() => {
1188
1210
  !this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
1189
1211
  }, o);
1190
1212
  i.bytes.then((o) => {
@@ -1211,7 +1233,7 @@ function it(t) {
1211
1233
  }
1212
1234
  return r;
1213
1235
  }
1214
- function at() {
1236
+ function ct() {
1215
1237
  return {
1216
1238
  aborted: !1,
1217
1239
  loaded: 0,
@@ -1235,10 +1257,10 @@ function at() {
1235
1257
  }
1236
1258
  };
1237
1259
  }
1238
- function ot(e) {
1260
+ function lt(e) {
1239
1261
  return e === "audio" ? "audio" : "main";
1240
1262
  }
1241
- function st(e, t) {
1263
+ function ut(e, t) {
1242
1264
  let n = [];
1243
1265
  t.initSegment?.url && !t.initSegment.data && n.push({
1244
1266
  url: t.initSegment.url,
@@ -1257,24 +1279,24 @@ function st(e, t) {
1257
1279
  }
1258
1280
  //#endregion
1259
1281
  //#region src/core/engine/hls.ts
1260
- function ct() {
1282
+ function dt() {
1261
1283
  return e.isSupported();
1262
1284
  }
1263
- var lt = 3, ut = 5, dt = 3, ft = 3e4, pt = 12e3, mt = 3e3, ht = 6e3, gt = .5, _t = 3, vt = .5, yt = 1.1, bt = .25, xt = 5e3, St = 4e3, Ct = 2, wt = 5, Tt = 2, Et = 2, Dt = 4, Ot = 4, kt = 2e3, At = 3e4, jt = .2, Mt = 30, Nt = 2, Pt = 2, Ft = 9, It = .5, Lt = 64;
1264
- function Rt(e) {
1285
+ var ft = 3, pt = 5, mt = 3, ht = 3e4, gt = 12e3, _t = 3e3, vt = 6e3, yt = .5, bt = 3, xt = .5, St = 1.1, Ct = .25, wt = 5e3, Tt = 4e3, Et = 2, Dt = 5, Ot = 2, kt = 2, At = 4, jt = 4, Mt = 2e3, Nt = 3e4, Pt = .2, Ft = 30, It = 2, Lt = 2, Rt = 9, zt = .5, Bt = 64;
1286
+ function Vt(e) {
1265
1287
  if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
1266
1288
  delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
1267
1289
  return;
1268
1290
  }
1269
- e.liveSyncDuration ??= Pt;
1270
- let t = Math.max(12, e.liveSyncDuration + Ft);
1271
- (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), zt(e, e.liveSyncDuration);
1291
+ e.liveSyncDuration ??= Lt;
1292
+ let t = Math.max(12, e.liveSyncDuration + Rt);
1293
+ (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Ht(e, e.liveSyncDuration);
1272
1294
  }
1273
- function zt(e, t) {
1295
+ function Ht(e, t) {
1274
1296
  let n = (e, t, n) => Math.min(n, Math.max(t, e));
1275
1297
  e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
1276
1298
  }
1277
- var Bt = class {
1299
+ var Ut = class {
1278
1300
  name = "hls";
1279
1301
  hls = null;
1280
1302
  deps;
@@ -1364,7 +1386,7 @@ var Bt = class {
1364
1386
  });
1365
1387
  return;
1366
1388
  }
1367
- e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (ke(r), Ne()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1389
+ e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r), je()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1368
1390
  let e = this.hls;
1369
1391
  if (document.visibilityState !== "visible" || !e) return;
1370
1392
  let t = e.liveSyncPosition;
@@ -1387,7 +1409,7 @@ var Bt = class {
1387
1409
  }
1388
1410
  this.loadSuspended = !0;
1389
1411
  }
1390
- }, xt));
1412
+ }, wt));
1391
1413
  }
1392
1414
  resumeLoading() {
1393
1415
  if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
@@ -1419,7 +1441,7 @@ var Bt = class {
1419
1441
  let t = e.liveSyncPosition;
1420
1442
  if (typeof t != "number" || !Number.isFinite(t)) return;
1421
1443
  let { video: n } = this.deps;
1422
- n.currentTime <= t + It || (n.currentTime = t);
1444
+ n.currentTime <= t + zt || (n.currentTime = t);
1423
1445
  }
1424
1446
  startHls() {
1425
1447
  let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
@@ -1438,12 +1460,12 @@ var Bt = class {
1438
1460
  emeEnabled: !0,
1439
1461
  drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
1440
1462
  drmSystemOptions: {
1441
- videoRobustness: I.video,
1442
- audioRobustness: I.audio,
1443
- videoEncryptionScheme: I.scheme,
1444
- audioEncryptionScheme: I.scheme
1463
+ videoRobustness: F.video,
1464
+ audioRobustness: F.audio,
1465
+ videoEncryptionScheme: F.scheme,
1466
+ audioEncryptionScheme: F.scheme
1445
1467
  },
1446
- ...M() ? { requestMediaKeySystemAccessFunc: F(t) } : {},
1468
+ ...j() ? { requestMediaKeySystemAccessFunc: P(t) } : {},
1447
1469
  licenseXhrSetup: (e, t) => {
1448
1470
  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;
1449
1471
  let o = performance.now();
@@ -1460,20 +1482,20 @@ var Bt = class {
1460
1482
  ...c
1461
1483
  };
1462
1484
  if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !d.fLoader) {
1463
- let e = new rt({
1485
+ let e = new ot({
1464
1486
  sessionId: n.analytics?.sid,
1465
1487
  contentId: n.matchUrn
1466
- }), t = it(e);
1488
+ }), t = st(e);
1467
1489
  t && (this.prefetch = e, d.fLoader = t);
1468
1490
  }
1469
- Rt(d), this.catchUpRate = typeof d.maxLiveSyncPlaybackRate == "number" ? d.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (d.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = d.autoStartLoad !== !1;
1491
+ Vt(d), this.catchUpRate = typeof d.maxLiveSyncPlaybackRate == "number" ? d.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (d.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = d.autoStartLoad !== !1;
1470
1492
  let f = new e(d);
1471
1493
  if (this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
1472
1494
  this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(f), this.measureLadder(f), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
1473
1495
  }), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
1474
1496
  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(() => {
1475
1497
  this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
1476
- }, ft)));
1498
+ }, ht)));
1477
1499
  }), f.on(e.Events.FRAG_LOADING, (e, t) => {
1478
1500
  t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
1479
1501
  }), f.on(e.Events.FRAG_LOADED, (e, t) => {
@@ -1481,10 +1503,10 @@ var Bt = class {
1481
1503
  let n = t?.frag?.stats, r = n?.loaded;
1482
1504
  typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
1483
1505
  let i = n?.loading;
1484
- i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Lt && this.requestTimesMs.shift());
1506
+ i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Bt && this.requestTimesMs.shift());
1485
1507
  let a = t?.frag?.url;
1486
1508
  if (a) {
1487
- let e = H(a);
1509
+ let e = Ge(a);
1488
1510
  e && (this.cdnHost = e);
1489
1511
  }
1490
1512
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => {
@@ -1498,15 +1520,15 @@ var Bt = class {
1498
1520
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
1499
1521
  let t = this.prefetch;
1500
1522
  f.on(e.Events.KEY_LOADING, (e, n) => {
1501
- let r = n?.frag, i = ot(r?.type);
1502
- if (r && t.isActive(i)) for (let e of st(f, r)) t.prefetch(e.url, i, e.kind);
1503
- }), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(ot(n?.frag?.type)));
1523
+ let r = n?.frag, i = lt(r?.type);
1524
+ if (r && t.isActive(i)) for (let e of ut(f, r)) t.prefetch(e.url, i, e.kind);
1525
+ }), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(lt(n?.frag?.type)));
1504
1526
  }
1505
1527
  f.on(e.Events.KEY_LOADED, () => {
1506
1528
  u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
1507
1529
  }), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
1508
1530
  this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.checkFrameDrops();
1509
- }, mt), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1531
+ }, _t), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1510
1532
  this.renditionSwitches += 1;
1511
1533
  let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
1512
1534
  n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
@@ -1570,7 +1592,7 @@ var Bt = class {
1570
1592
  return;
1571
1593
  }
1572
1594
  this.capTimer && clearTimeout(this.capTimer);
1573
- let t = e > this.sizeCapLevel ? kt : At;
1595
+ let t = e > this.sizeCapLevel ? Mt : Nt;
1574
1596
  this.capTimer = setTimeout(() => {
1575
1597
  this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
1576
1598
  }, t);
@@ -1580,9 +1602,9 @@ var Bt = class {
1580
1602
  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;
1581
1603
  }
1582
1604
  dropLevelsWidevineCannotPlay(e) {
1583
- this.removeLevelsWhere(e, (e) => Pe(e) !== !0);
1584
- let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && L(e) !== "avc" && !!L(e)));
1585
- for (let n of t) Me(n).then((t) => {
1605
+ this.removeLevelsWhere(e, (e) => Me(e) !== !0);
1606
+ let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && I(e) !== "avc" && !!I(e)));
1607
+ for (let n of t) V(n).then((t) => {
1586
1608
  t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
1587
1609
  });
1588
1610
  }
@@ -1590,10 +1612,10 @@ var Bt = class {
1590
1612
  let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
1591
1613
  if (n.forEach((e, n) => {
1592
1614
  let a = e.videoCodec;
1593
- a && L(a) && t(a) && (r.push(n), i.add(a));
1615
+ a && I(a) && t(a) && (r.push(n), i.add(a));
1594
1616
  }), !r.length) return !1;
1595
1617
  let a = [...i].join(", ");
1596
- if (!n.some((e, t) => r.includes(t) ? !1 : !L(e.videoCodec) || Pe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
1618
+ if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) || Me(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
1597
1619
  for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
1598
1620
  return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
1599
1621
  }
@@ -1643,7 +1665,7 @@ var Bt = class {
1643
1665
  e.widevine && (this.licenseUrl = e.widevine);
1644
1666
  }
1645
1667
  getStats() {
1646
- let e = this.hls, t = U(this.deps.video), n = {
1668
+ let e = this.hls, t = H(this.deps.video), n = {
1647
1669
  droppedFrames: t.dropped,
1648
1670
  decodedFrames: t.totalFrames,
1649
1671
  lowLatency: this.detectedLowLatency,
@@ -1691,7 +1713,7 @@ var Bt = class {
1691
1713
  return;
1692
1714
  }
1693
1715
  let e = Date.now() - this.lastAdvanceMs;
1694
- !this.chaseSuspended && e > ht && this.suspendChasing(), e > pt && this.emitEnded("stalled");
1716
+ !this.chaseSuspended && e > vt && this.suspendChasing(), e > gt && this.emitEnded("stalled");
1695
1717
  }
1696
1718
  resetStarvationWindow() {
1697
1719
  this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
@@ -1706,7 +1728,7 @@ var Bt = class {
1706
1728
  this.resetStarvationWindow();
1707
1729
  return;
1708
1730
  }
1709
- let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < ht, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > St, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = U(t), c = o - s, l = c !== this.starvedFrames;
1731
+ let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < vt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > Tt, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = H(t), c = o - s, l = c !== this.starvedFrames;
1710
1732
  if (this.starvedFrames = c, !a || l) {
1711
1733
  (t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
1712
1734
  return;
@@ -1715,12 +1737,12 @@ var Bt = class {
1715
1737
  this.resetStarvationWindow();
1716
1738
  return;
1717
1739
  }
1718
- 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 > Dt && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= Tt && (this.clearKick(), this.starvationRebuilds < Et)) {
1740
+ 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 > At && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= Ot && (this.clearKick(), this.starvationRebuilds < kt)) {
1719
1741
  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");
1720
1742
  return;
1721
1743
  }
1722
- let u = i && this.starvedTicks >= Ct, d = !i && this.deadTicks >= Dt && this.recentMainFrags.reduce((e, t) => e + t, 0) >= Ot;
1723
- if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= wt))) {
1744
+ let u = i && this.starvedTicks >= Et, d = !i && this.deadTicks >= At && this.recentMainFrags.reduce((e, t) => e + t, 0) >= jt;
1745
+ if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= Dt))) {
1724
1746
  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");
1725
1747
  try {
1726
1748
  e.stopLoad(), e.startLoad(-1);
@@ -1735,7 +1757,7 @@ var Bt = class {
1735
1757
  let t = e.latency, n = e.targetLatency;
1736
1758
  if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
1737
1759
  let r = t - n;
1738
- !this.catchUpEngaged && r > gt ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= gt && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
1760
+ !this.catchUpEngaged && r > yt ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= yt && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
1739
1761
  let i = this.catchUpEngaged ? this.catchUpRate : 1;
1740
1762
  e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
1741
1763
  }
@@ -1756,16 +1778,16 @@ var Bt = class {
1756
1778
  this.resetFrameDropWindow();
1757
1779
  return;
1758
1780
  }
1759
- let { totalFrames: n, dropped: r } = U(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
1760
- if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Mt || o < 0) {
1781
+ let { totalFrames: n, dropped: r } = H(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
1782
+ if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Ft || o < 0) {
1761
1783
  this.fpsBadTicks = 0;
1762
1784
  return;
1763
1785
  }
1764
- if (o <= jt * a) {
1786
+ if (o <= Pt * a) {
1765
1787
  this.fpsBadTicks = 0;
1766
1788
  return;
1767
1789
  }
1768
- if (this.fpsBadTicks += 1, this.fpsBadTicks < Nt) return;
1790
+ if (this.fpsBadTicks += 1, this.fpsBadTicks < It) return;
1769
1791
  this.fpsBadTicks = 0;
1770
1792
  let s = e.levels, c = s[e.currentLevel];
1771
1793
  if (!c) return;
@@ -1782,20 +1804,20 @@ var Bt = class {
1782
1804
  return;
1783
1805
  }
1784
1806
  let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
1785
- if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(yt, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
1807
+ if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(St, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
1786
1808
  this.resetChaseWindow();
1787
1809
  return;
1788
1810
  }
1789
- if (this.chaseLatency < 0 || this.chaseLatency - n >= vt) {
1811
+ if (this.chaseLatency < 0 || this.chaseLatency - n >= xt) {
1790
1812
  this.chaseLatency = n, this.chaseTicks = 0;
1791
1813
  return;
1792
1814
  }
1793
- if (this.chaseTicks += 1, this.chaseTicks < _t) return;
1815
+ if (this.chaseTicks += 1, this.chaseTicks < bt) return;
1794
1816
  this.resetChaseWindow();
1795
1817
  let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
1796
1818
  if (!(a > 1)) return;
1797
1819
  let o = typeof e.targetLatency == "number" ? e.targetLatency : 0, s = Math.min(n, a - 1);
1798
- s < o + bt || (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);
1820
+ s < o + Ct || (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);
1799
1821
  }
1800
1822
  suspendChasing() {
1801
1823
  let e = this.hls;
@@ -1840,7 +1862,7 @@ var Bt = class {
1840
1862
  scheduleLicenseRetry(t) {
1841
1863
  if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
1842
1864
  let n = t.response?.code ?? 0;
1843
- if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= dt) return !1;
1865
+ if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= mt) return !1;
1844
1866
  this.licenseRecoveries += 1;
1845
1867
  let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
1846
1868
  return this.licenseRetryTimer = setTimeout(() => {
@@ -1872,7 +1894,7 @@ var Bt = class {
1872
1894
  return;
1873
1895
  }
1874
1896
  if (t.type === e.ErrorTypes.NETWORK_ERROR) {
1875
- if (this.networkRecoveries < ut) {
1897
+ if (this.networkRecoveries < pt) {
1876
1898
  this.networkRecoveries += 1;
1877
1899
  let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
1878
1900
  this.networkRetryTimer = setTimeout(() => {
@@ -1889,7 +1911,7 @@ var Bt = class {
1889
1911
  return;
1890
1912
  }
1891
1913
  if (t.type === e.ErrorTypes.MEDIA_ERROR) {
1892
- if (this.mediaRecoveries < lt) {
1914
+ if (this.mediaRecoveries < ft) {
1893
1915
  this.mediaRecoveries += 1, n.recoverMediaError();
1894
1916
  return;
1895
1917
  }
@@ -1913,19 +1935,19 @@ var Bt = class {
1913
1935
  let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
1914
1936
  return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
1915
1937
  }
1916
- }, Vt = 15e3, Ht = 6e5, Ut = 3e5, Wt = 100, q = 1, Gt = 1e3, Kt = 3e4, qt = 1e3, Jt = {
1938
+ }, Wt = 15e3, Gt = 6e5, Kt = 3e5, qt = 100, q = 1, Jt = 1e3, Yt = 3e4, Xt = 1e3, Zt = {
1917
1939
  inline: "PRESENTATION_INLINE",
1918
1940
  fullscreen: "PRESENTATION_FULLSCREEN",
1919
1941
  pip: "PRESENTATION_PIP"
1920
- }, Yt = {
1942
+ }, Qt = {
1921
1943
  widevine: "KEY_SYSTEM_WIDEVINE",
1922
1944
  fairplay: "KEY_SYSTEM_FAIRPLAY",
1923
1945
  none: "KEY_SYSTEM_NONE"
1924
1946
  };
1925
- function Xt(e, t) {
1947
+ function $t(e, t) {
1926
1948
  return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
1927
1949
  }
1928
- var Zt = /* @__PURE__ */ new Set([
1950
+ var en = /* @__PURE__ */ new Set([
1929
1951
  "INVALID_URN",
1930
1952
  "NOT_FOUND",
1931
1953
  "GONE",
@@ -1945,7 +1967,7 @@ var Zt = /* @__PURE__ */ new Set([
1945
1967
  ended: "PLAYER_STATE_ENDED",
1946
1968
  error: "PLAYER_STATE_ERROR"
1947
1969
  };
1948
- function Qt(e) {
1970
+ function tn(e) {
1949
1971
  try {
1950
1972
  let t = new URL(e), [n, ...r] = t.hostname.split(".");
1951
1973
  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);
@@ -1953,8 +1975,8 @@ function Qt(e) {
1953
1975
  return;
1954
1976
  }
1955
1977
  }
1956
- var $t = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), en = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), tn = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
1957
- function nn(e) {
1978
+ var nn = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), rn = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), an = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
1979
+ function on(e) {
1958
1980
  if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
1959
1981
  let t;
1960
1982
  try {
@@ -1963,19 +1985,19 @@ function nn(e) {
1963
1985
  } catch {
1964
1986
  return;
1965
1987
  }
1966
- if (en.has(t) && !Y.has(t)) {
1967
- Y.add(t), g(tn(new URL(t).origin));
1988
+ if (rn.has(t) && !Y.has(t)) {
1989
+ Y.add(t), g(an(new URL(t).origin));
1968
1990
  for (let e of X) e.noteCspBlocked();
1969
1991
  }
1970
1992
  }
1971
- function rn(e, t) {
1993
+ function sn(e, t) {
1972
1994
  return g(t, e), { disabledReason: t };
1973
1995
  }
1974
- function an(e, t, n) {
1975
- if (n) return t && !$t(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
1996
+ function cn(e, t, n) {
1997
+ if (n) return t && !nn(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
1976
1998
  if (t) return { endpoint: t };
1977
- if (t !== void 0) return rn("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).");
1978
- let r = Qt(e);
1999
+ if (t !== void 0) return sn("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).");
2000
+ let r = tn(e);
1979
2001
  if (r) return { endpoint: r };
1980
2002
  let i;
1981
2003
  try {
@@ -1983,9 +2005,9 @@ function an(e, t, n) {
1983
2005
  } catch {
1984
2006
  i = e;
1985
2007
  }
1986
- return rn(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).`);
2008
+ return sn(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).`);
1987
2009
  }
1988
- var on = class {
2010
+ var ln = class {
1989
2011
  opts;
1990
2012
  url;
1991
2013
  cspKey;
@@ -2067,8 +2089,8 @@ var on = class {
2067
2089
  constructor(e) {
2068
2090
  this.opts = {
2069
2091
  ...e,
2070
- heartbeatMs: e.heartbeatMs ?? Vt,
2071
- idleMs: e.idleMs ?? Ht
2092
+ heartbeatMs: e.heartbeatMs ?? Wt,
2093
+ idleMs: e.idleMs ?? Gt
2072
2094
  }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
2073
2095
  try {
2074
2096
  let e = new URL(this.url);
@@ -2085,11 +2107,11 @@ var on = class {
2085
2107
  sdkVersion: this.opts.sdkVersion,
2086
2108
  ...this.opts.environment
2087
2109
  };
2088
- this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Gt), 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 && en.add(this.cspKey), document.addEventListener("securitypolicyviolation", nn), X.add(this), this.noteCspBlocked(), this.onVisibility());
2110
+ this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Jt), 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 && rn.add(this.cspKey), document.addEventListener("securitypolicyviolation", on), X.add(this), this.noteCspBlocked(), this.onVisibility());
2089
2111
  }
2090
2112
  checkSuspension(e) {
2091
2113
  if (this.endedFlag || !this.opts.idleMs) return !1;
2092
- let t = Math.max(this.opts.idleMs, Ut);
2114
+ let t = Math.max(this.opts.idleMs, Kt);
2093
2115
  return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
2094
2116
  }
2095
2117
  syncIdle(e) {
@@ -2112,12 +2134,12 @@ var on = class {
2112
2134
  let a = {
2113
2135
  fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
2114
2136
  toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
2115
- presentation: Jt[this.presentation]
2137
+ presentation: Zt[this.presentation]
2116
2138
  }, o = this.causeOf(e, t, i);
2117
2139
  o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
2118
2140
  }
2119
2141
  seekInduced(e) {
2120
- return this.lastSeekMs >= 0 && e - this.lastSeekMs < qt;
2142
+ return this.lastSeekMs >= 0 && e - this.lastSeekMs < Xt;
2121
2143
  }
2122
2144
  causeOf(e, t, n) {
2123
2145
  if (t === "error") return "TRANSITION_CAUSE_ERROR";
@@ -2191,7 +2213,7 @@ var on = class {
2191
2213
  let r = n ?? "";
2192
2214
  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";
2193
2215
  if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
2194
- if (Zt.has(e)) return "ERROR_STAGE_RESOLVE";
2216
+ if (en.has(e)) return "ERROR_STAGE_RESOLVE";
2195
2217
  let i = t ?? "";
2196
2218
  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";
2197
2219
  }
@@ -2238,14 +2260,14 @@ var on = class {
2238
2260
  if (this.lastRequestCount = g, _ > 0) {
2239
2261
  o.requestCountDelta = _;
2240
2262
  let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
2241
- n.length > 0 && (o.requestTimeP50Ms = Xt(n, 50), o.requestTimeP95Ms = Xt(n, 95));
2263
+ n.length > 0 && (o.requestTimeP50Ms = $t(n, 50), o.requestTimeP95Ms = $t(n, 95));
2242
2264
  }
2243
2265
  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();
2244
2266
  }
2245
2267
  maybeEmitMediaInfo(e) {
2246
2268
  if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
2247
2269
  let t = {};
2248
- e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Yt[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);
2270
+ e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Qt[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);
2249
2271
  let n = JSON.stringify(t);
2250
2272
  n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
2251
2273
  }
@@ -2265,7 +2287,7 @@ var on = class {
2265
2287
  let c = r?.positionMs ?? 0;
2266
2288
  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));
2267
2289
  let l = e !== "END_REASON_ENDED";
2268
- l && this.lastStallMs > 0 && n - this.lastStallMs <= Kt && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Kt && (i.abandonAfterErrorMs = Math.max(q, 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);
2290
+ l && this.lastStallMs > 0 && n - this.lastStallMs <= Yt && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Yt && (i.abandonAfterErrorMs = Math.max(q, 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);
2269
2291
  let u = r?.decodedFrames ?? this.lastDecoded;
2270
2292
  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");
2271
2293
  }
@@ -2285,13 +2307,13 @@ var on = class {
2285
2307
  };
2286
2308
  }
2287
2309
  noteCspBlocked() {
2288
- this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(tn(new URL(this.url).origin)));
2310
+ this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(an(new URL(this.url).origin)));
2289
2311
  }
2290
2312
  cspBlocked() {
2291
2313
  return !!this.cspKey && Y.has(this.cspKey);
2292
2314
  }
2293
2315
  enqueue(e) {
2294
- if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > Wt;) {
2316
+ if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > qt;) {
2295
2317
  let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
2296
2318
  this.pending.splice(e >= 0 ? e : 0, 1);
2297
2319
  }
@@ -2318,7 +2340,7 @@ var on = class {
2318
2340
  };
2319
2341
  //#endregion
2320
2342
  //#region src/core/environment.ts
2321
- function sn() {
2343
+ function un() {
2322
2344
  if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
2323
2345
  let e;
2324
2346
  try {
@@ -2343,14 +2365,14 @@ function sn() {
2343
2365
  integration: "INTEGRATION_KIND_IFRAME"
2344
2366
  };
2345
2367
  }
2346
- function cn() {
2368
+ function dn() {
2347
2369
  if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
2348
2370
  let e = navigator.userAgentData, t = e?.platform ?? "";
2349
2371
  if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
2350
2372
  let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
2351
2373
  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";
2352
2374
  }
2353
- function ln() {
2375
+ function fn() {
2354
2376
  let e = typeof navigator < "u" ? navigator.connection : void 0;
2355
2377
  if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
2356
2378
  let t = {
@@ -2369,17 +2391,17 @@ function ln() {
2369
2391
  }
2370
2392
  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;
2371
2393
  }
2372
- function un(e) {
2373
- let t = sn(), n = {
2374
- deviceClass: cn(),
2394
+ function pn(e) {
2395
+ let t = un(), n = {
2396
+ deviceClass: dn(),
2375
2397
  integration: t.integration,
2376
- ...ln()
2398
+ ...fn()
2377
2399
  };
2378
2400
  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);
2379
2401
  let r = e.getBoundingClientRect?.();
2380
2402
  return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
2381
2403
  }
2382
- async function dn() {
2404
+ async function mn() {
2383
2405
  let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
2384
2406
  if (!e?.getHighEntropyValues) return {};
2385
2407
  try {
@@ -2391,7 +2413,7 @@ async function dn() {
2391
2413
  }
2392
2414
  //#endregion
2393
2415
  //#region src/core/version.ts
2394
- var fn = "2.16.1", pn = {
2416
+ var hn = "2.16.2", gn = {
2395
2417
  accent: "#E1B600",
2396
2418
  accentText: "#1B1C23",
2397
2419
  background: "#0e0f13",
@@ -2402,7 +2424,7 @@ var fn = "2.16.1", pn = {
2402
2424
  border: "rgba(255, 255, 255, 0.1)",
2403
2425
  radius: "8px",
2404
2426
  fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
2405
- }, mn = {
2427
+ }, _n = {
2406
2428
  accent: "--havik-accent",
2407
2429
  accentText: "--havik-accent-text",
2408
2430
  background: "--havik-bg",
@@ -2414,26 +2436,26 @@ var fn = "2.16.1", pn = {
2414
2436
  radius: "--havik-radius",
2415
2437
  fontFamily: "--havik-font"
2416
2438
  };
2417
- function hn(e, t) {
2439
+ function vn(e, t) {
2418
2440
  let n = {
2419
- ...pn,
2441
+ ...gn,
2420
2442
  ...t
2421
2443
  };
2422
- for (let t of Object.keys(mn)) e.style.setProperty(mn[t], n[t]);
2444
+ for (let t of Object.keys(_n)) e.style.setProperty(_n[t], n[t]);
2423
2445
  n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
2424
2446
  }
2425
2447
  //#endregion
2426
2448
  //#region src/ui/styles.ts
2427
- var gn = "havik-player-styles", _n = "\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", Z = /* @__PURE__ */ new WeakMap();
2428
- function vn(e = document, t) {
2429
- let n = e.querySelector(`style#${gn}`);
2430
- if (n && (!t || Z.get(n) === t)) return;
2449
+ var yn = "havik-player-styles", bn = "\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", xn = /* @__PURE__ */ new WeakMap();
2450
+ function Sn(e = document, t) {
2451
+ let n = e.querySelector(`style#${yn}`);
2452
+ if (n && (!t || xn.get(n) === t)) return;
2431
2453
  let r = e.createElement("style");
2432
- r.id = gn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = _n, Z.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
2454
+ r.id = yn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = bn, xn.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
2433
2455
  }
2434
2456
  //#endregion
2435
2457
  //#region src/ui/icons.ts
2436
- var yn = {
2458
+ var Cn = {
2437
2459
  play: "<path d=\"M8 5v14l11-7z\"/>",
2438
2460
  pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
2439
2461
  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\"/>",
@@ -2446,21 +2468,21 @@ var yn = {
2446
2468
  liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
2447
2469
  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\"/>"
2448
2470
  };
2449
- function Q(e) {
2450
- return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${yn[e]}</svg>`;
2471
+ function Z(e) {
2472
+ return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Cn[e]}</svg>`;
2451
2473
  }
2452
2474
  //#endregion
2453
2475
  //#region src/ui/controls.ts
2454
- var bn = 3e3, xn = 250, Sn = /* @__PURE__ */ new Set([
2476
+ var wn = 3e3, Tn = 250, En = /* @__PURE__ */ new Set([
2455
2477
  "GONE",
2456
2478
  "NOT_FOUND",
2457
2479
  "INVALID_URN",
2458
2480
  "UNAUTHORIZED"
2459
2481
  ]);
2460
- function Cn(e) {
2461
- return new wn(e);
2482
+ function Dn(e) {
2483
+ return new On(e);
2462
2484
  }
2463
- var wn = class {
2485
+ var On = class {
2464
2486
  root;
2465
2487
  video;
2466
2488
  player;
@@ -2506,7 +2528,7 @@ var wn = class {
2506
2528
  scrubbing = !1;
2507
2529
  offFns = [];
2508
2530
  constructor(e) {
2509
- this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? bn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, vn(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");
2531
+ this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? wn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, Sn(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");
2510
2532
  let t = (e, t, n) => {
2511
2533
  let r = this.doc.createElement(e);
2512
2534
  if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
@@ -2517,12 +2539,12 @@ var wn = class {
2517
2539
  "aria-label": r,
2518
2540
  title: r
2519
2541
  });
2520
- return i.innerHTML = Q(n), i;
2542
+ return i.innerHTML = Z(n), i;
2521
2543
  };
2522
2544
  this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
2523
2545
  type: "button",
2524
2546
  "aria-label": "Play"
2525
- }), 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", {
2547
+ }), this.center.innerHTML = Z("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", {
2526
2548
  role: "slider",
2527
2549
  "aria-label": "Seek",
2528
2550
  "aria-valuemin": "0",
@@ -2540,7 +2562,7 @@ var wn = class {
2540
2562
  "aria-label": "Volume"
2541
2563
  });
2542
2564
  let a = t("div", "havik-vol");
2543
- a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
2565
+ a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Z("liveDot");
2544
2566
  let o = this.doc.createElement("span");
2545
2567
  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";
2546
2568
  let s = t("div", "havik-spacer");
@@ -2592,7 +2614,7 @@ var wn = class {
2592
2614
  let t = this.surfaceWasHidden;
2593
2615
  this.tapTimer = setTimeout(() => {
2594
2616
  this.tapTimer = void 0, this.toggleBar(t);
2595
- }, xn);
2617
+ }, Tn);
2596
2618
  }
2597
2619
  toggleBar(e) {
2598
2620
  e ? this.poke() : this.hideIfIdle();
@@ -2624,12 +2646,12 @@ var wn = class {
2624
2646
  }
2625
2647
  if (e === "preplay") {
2626
2648
  let e = this.doc.createElement("button");
2627
- 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);
2649
+ e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Z("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
2628
2650
  } else {
2629
2651
  let r = this.doc.createElement("div");
2630
- if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Sn.has(this.lastError.code)) {
2652
+ if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !En.has(this.lastError.code)) {
2631
2653
  let e = this.doc.createElement("button");
2632
- 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);
2654
+ e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Z("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
2633
2655
  }
2634
2656
  }
2635
2657
  this.root.append(n), this.statusBox = n, this.show();
@@ -2668,7 +2690,7 @@ var wn = class {
2668
2690
  let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
2669
2691
  this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
2670
2692
  }
2671
- !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Tn(this.video.currentTime)} / ${Tn(this.video.duration)}`);
2693
+ !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${kn(this.video.currentTime)} / ${kn(this.video.duration)}`);
2672
2694
  }
2673
2695
  syncLive() {
2674
2696
  let e = this.player.getStats(), t = e.isLive !== !1;
@@ -2718,17 +2740,17 @@ var wn = class {
2718
2740
  renderQualityMenu() {
2719
2741
  let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
2720
2742
  n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
2721
- for (let n of e) this.menu.append(this.menuItem(En(n), t === n.index, () => this.player.setQuality(n.index)));
2743
+ for (let n of e) this.menu.append(this.menuItem(An(n), t === n.index, () => this.player.setQuality(n.index)));
2722
2744
  }
2723
2745
  renderAudioMenu() {
2724
2746
  let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
2725
2747
  t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
2726
- for (let t of e) this.menu.append(this.menuItem(Dn(t), t.default, () => this.player.setAudioTrack(t.id)));
2748
+ for (let t of e) this.menu.append(this.menuItem(jn(t), t.default, () => this.player.setAudioTrack(t.id)));
2727
2749
  }
2728
2750
  renderCcMenu() {
2729
2751
  let e = this.player.getTextTracks(), t = this.doc.createElement("div");
2730
2752
  t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
2731
- for (let t of e) this.menu.append(this.menuItem(On(t), !1, () => this.player.setTextTrack(t.id)));
2753
+ for (let t of e) this.menu.append(this.menuItem(Mn(t), !1, () => this.player.setTextTrack(t.id)));
2732
2754
  }
2733
2755
  onTracksChanged() {
2734
2756
  this.openMenu && this.renderMenu(this.openMenu);
@@ -2748,11 +2770,11 @@ var wn = class {
2748
2770
  }
2749
2771
  async toggleFullscreen() {
2750
2772
  try {
2751
- C(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
2773
+ S(this.video, this.root) ? await w(this.video, this.root) : await C(this.video, this.root);
2752
2774
  } catch {}
2753
2775
  }
2754
2776
  syncFullscreen() {
2755
- let e = C(this.video, this.root);
2777
+ let e = S(this.video, this.root);
2756
2778
  this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
2757
2779
  }
2758
2780
  poke() {
@@ -2812,7 +2834,7 @@ var wn = class {
2812
2834
  }
2813
2835
  }
2814
2836
  setIcon(e, t) {
2815
- e.innerHTML = Q(t);
2837
+ e.innerHTML = Z(t);
2816
2838
  }
2817
2839
  destroy() {
2818
2840
  this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
@@ -2829,41 +2851,41 @@ var wn = class {
2829
2851
  this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
2830
2852
  }
2831
2853
  };
2832
- function Tn(e) {
2854
+ function kn(e) {
2833
2855
  (!Number.isFinite(e) || e < 0) && (e = 0);
2834
2856
  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");
2835
2857
  return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
2836
2858
  }
2837
- function En(e) {
2859
+ function An(e) {
2838
2860
  return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
2839
2861
  }
2840
- function Dn(e) {
2862
+ function jn(e) {
2841
2863
  return e.name || e.lang || `Track ${e.id}`;
2842
2864
  }
2843
- function On(e) {
2865
+ function Mn(e) {
2844
2866
  return e.name || e.lang || `Track ${e.id}`;
2845
2867
  }
2846
2868
  //#endregion
2847
2869
  //#region src/managed/index.ts
2848
- var kn = 6e3, An = 45e3, jn = 2e3, Mn = 3, Nn = 2e3, Pn = 48e4;
2849
- function Fn(e) {
2870
+ var Nn = 6e3, Pn = 45e3, Q = 2e3, Fn = 3, In = 2e3, Ln = 48e4;
2871
+ function Rn(e) {
2850
2872
  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)})`);
2851
- if (e.env !== void 0) return B(e.env);
2873
+ if (e.env !== void 0) return Ue(e.env);
2852
2874
  if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
2853
2875
  return e.baseUrl;
2854
2876
  }
2855
- async function In(e) {
2877
+ async function zn(e) {
2856
2878
  if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
2857
- let t = Fn(e);
2879
+ let t = Rn(e);
2858
2880
  if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
2859
2881
  if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
2860
- let r = new Ln({
2882
+ let r = new Bn({
2861
2883
  ...e,
2862
2884
  baseUrl: t
2863
2885
  });
2864
2886
  return await r.start(), r;
2865
2887
  }
2866
- var Ln = class {
2888
+ var Bn = class {
2867
2889
  opts;
2868
2890
  abort = new AbortController();
2869
2891
  listeners = {};
@@ -2930,7 +2952,7 @@ var Ln = class {
2930
2952
  };
2931
2953
  }
2932
2954
  beginArming(e, t, n = !1) {
2933
- let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
2955
+ let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
2934
2956
  r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
2935
2957
  }
2936
2958
  beginArmingByPolling(e) {
@@ -2951,7 +2973,7 @@ var Ln = class {
2951
2973
  setTimeout(() => {
2952
2974
  a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
2953
2975
  phase: i ? "unavailable" : "tooEarly",
2954
- retryInMs: An,
2976
+ retryInMs: Pn,
2955
2977
  attempt: 1,
2956
2978
  elapsedMs: 0,
2957
2979
  ...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
@@ -2990,13 +3012,13 @@ var Ln = class {
2990
3012
  !a && !p() && h();
2991
3013
  }, e);
2992
3014
  };
2993
- _(kn), this.armingSub = E({
3015
+ _(Nn), this.armingSub = T({
2994
3016
  eventsBaseUrl: t,
2995
3017
  matchUrn: this.opts.matchUrn,
2996
3018
  credential: this.opts.credential,
2997
- onAlive: () => _(An),
3019
+ onAlive: () => _(Pn),
2998
3020
  onState: (e) => {
2999
- a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * jn);
3021
+ a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Q);
3000
3022
  },
3001
3023
  onError: () => h()
3002
3024
  });
@@ -3019,7 +3041,7 @@ var Ln = class {
3019
3041
  let n = await s(this.opts.credential);
3020
3042
  if (this.destroyed || t !== this.loadGen) return;
3021
3043
  this.setState("loading");
3022
- let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = qe(this.opts.video, (e) => {
3044
+ let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Je(this.opts.video, (e) => {
3023
3045
  this._state !== "ended" && this._state !== "error" && this.setState(e);
3024
3046
  });
3025
3047
  if (await i.load(), this.destroyed || t !== this.loadGen) {
@@ -3041,26 +3063,26 @@ var Ln = class {
3041
3063
  if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
3042
3064
  let i = e.analytics?.sid;
3043
3065
  if (!i) return;
3044
- let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = an(this.opts.baseUrl, a, e.analytics?.endpoint);
3066
+ let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = cn(this.opts.baseUrl, a, e.analytics?.endpoint);
3045
3067
  if (!o) {
3046
3068
  s && setTimeout(() => {
3047
3069
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
3048
3070
  }, 0);
3049
3071
  return;
3050
3072
  }
3051
- let c = this.opts.video, l = new on({
3073
+ let c = this.opts.video, l = new ln({
3052
3074
  endpoint: o,
3053
3075
  sid: i,
3054
3076
  player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
3055
- sdkVersion: fn,
3056
- environment: un(c),
3077
+ sdkVersion: hn,
3078
+ environment: pn(c),
3057
3079
  idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
3058
3080
  onIdle: () => this.onAnalyticsIdle(t),
3059
3081
  onBlocked: (e) => setTimeout(() => {
3060
3082
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
3061
3083
  }, 0),
3062
3084
  sample: () => {
3063
- let e = this.engine?.getStats() ?? V, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3085
+ let e = this.engine?.getStats() ?? We, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3064
3086
  return {
3065
3087
  ...e,
3066
3088
  bufferedMs: Math.round(t * 1e3),
@@ -3074,7 +3096,7 @@ var Ln = class {
3074
3096
  let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
3075
3097
  c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
3076
3098
  c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
3077
- }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), dn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3099
+ }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), mn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3078
3100
  }
3079
3101
  currentPresentation() {
3080
3102
  let e = this.opts.video;
@@ -3089,7 +3111,7 @@ var Ln = class {
3089
3111
  video: this.opts.video,
3090
3112
  descriptor: e,
3091
3113
  credential: t,
3092
- deviceId: A(),
3114
+ deviceId: k(),
3093
3115
  userId: this.opts.userId,
3094
3116
  lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
3095
3117
  snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
@@ -3100,9 +3122,9 @@ var Ln = class {
3100
3122
  emit: (e) => this.onEngineEvent(e)
3101
3123
  }, o = this.opts.engine ?? "auto";
3102
3124
  if (o === "native") return new K(a);
3103
- if (o === "hls") return new Bt(a);
3104
- if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && W(this.opts.video) && G() || !e.drmEnabled && Ze() && W(this.opts.video)) return new K(a);
3105
- if (ct()) return new Bt(a);
3125
+ if (o === "hls") return new Ut(a);
3126
+ if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && W(this.opts.video) && G() || !e.drmEnabled && et() && W(this.opts.video)) return new K(a);
3127
+ if (dt()) return new Ut(a);
3106
3128
  if (W(this.opts.video)) return new K(a);
3107
3129
  throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
3108
3130
  }
@@ -3140,11 +3162,11 @@ var Ln = class {
3140
3162
  }
3141
3163
  startLiveState(e) {
3142
3164
  if (this.opts.liveStateEvents === !1) return;
3143
- let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
3165
+ let t = this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
3144
3166
  if (!t) return;
3145
3167
  this.closeLiveState();
3146
3168
  let r = 0, i = !1;
3147
- this.liveStateSub = E({
3169
+ this.liveStateSub = T({
3148
3170
  eventsBaseUrl: t,
3149
3171
  matchUrn: this.opts.matchUrn,
3150
3172
  credential: this.opts.credential,
@@ -3155,7 +3177,7 @@ var Ln = class {
3155
3177
  r = 0, i = !1;
3156
3178
  },
3157
3179
  onError: () => {
3158
- this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Mn && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))));
3180
+ this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Fn && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))));
3159
3181
  }
3160
3182
  });
3161
3183
  }
@@ -3177,7 +3199,7 @@ var Ln = class {
3177
3199
  scheduleRejoin(e) {
3178
3200
  this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
3179
3201
  this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
3180
- }, Math.random() * jn));
3202
+ }, Math.random() * Q));
3181
3203
  }
3182
3204
  cancelRejoin() {
3183
3205
  this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
@@ -3201,7 +3223,7 @@ var Ln = class {
3201
3223
  }
3202
3224
  t.controls = !1;
3203
3225
  let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
3204
- r && r.insertBefore(n, t), n.appendChild(t), hn(n, this.opts.theme), this.container = n, this.controlBar = Cn({
3226
+ r && r.insertBefore(n, t), n.appendChild(t), vn(n, this.opts.theme), this.container = n, this.controlBar = Dn({
3205
3227
  root: n,
3206
3228
  video: t,
3207
3229
  player: this,
@@ -3232,7 +3254,7 @@ var Ln = class {
3232
3254
  }
3233
3255
  startStats() {
3234
3256
  this.stopStats();
3235
- let e = Math.max(500, this.opts.statsIntervalMs ?? Nn);
3257
+ let e = Math.max(500, this.opts.statsIntervalMs ?? In);
3236
3258
  this.statsTimer = setInterval(() => {
3237
3259
  if (!this.engine) return;
3238
3260
  let e = this.engine.getStats();
@@ -3244,7 +3266,7 @@ var Ln = class {
3244
3266
  }
3245
3267
  scheduleLicenseRefresh() {
3246
3268
  this.stopRefresh();
3247
- let e = this.opts.licenseRefreshMs ?? Pn;
3269
+ let e = this.opts.licenseRefreshMs ?? Ln;
3248
3270
  e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
3249
3271
  }
3250
3272
  stopRefresh() {
@@ -3289,7 +3311,7 @@ var Ln = class {
3289
3311
  this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
3290
3312
  }
3291
3313
  getStats() {
3292
- return this.engine?.getStats() ?? V;
3314
+ return this.engine?.getStats() ?? We;
3293
3315
  }
3294
3316
  getQualityLevels() {
3295
3317
  return this.engine?.getQualityLevels() ?? [];
@@ -3328,10 +3350,10 @@ var Ln = class {
3328
3350
  e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
3329
3351
  }
3330
3352
  async enterFullscreen() {
3331
- return !this.destroyed && w(this.opts.video, this.container ?? void 0);
3353
+ return !this.destroyed && C(this.opts.video, this.container ?? void 0);
3332
3354
  }
3333
3355
  async exitFullscreen() {
3334
- await T(this.opts.video, this.container ?? void 0);
3356
+ await w(this.opts.video, this.container ?? void 0);
3335
3357
  }
3336
3358
  retry() {
3337
3359
  return this.reload();
@@ -3399,7 +3421,7 @@ function $(e) {
3399
3421
  }
3400
3422
  //#endregion
3401
3423
  //#region src/embed/host.ts
3402
- function Rn(e) {
3424
+ function Vn(e) {
3403
3425
  if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
3404
3426
  if (!e.src) throw Error("mountEmbed: opts.src is required");
3405
3427
  if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
@@ -3458,15 +3480,15 @@ function Rn(e) {
3458
3480
  }
3459
3481
  //#endregion
3460
3482
  //#region src/embed/page.ts
3461
- var zn = /^[A-Za-z0-9:_.-]{1,128}$/;
3462
- function Bn(e) {
3483
+ var Hn = /^[A-Za-z0-9:_.-]{1,128}$/;
3484
+ function Un(e) {
3463
3485
  if (typeof e == "boolean") return e;
3464
3486
  if (typeof e == "object" && e) {
3465
3487
  let t = e.endpoint;
3466
3488
  return typeof t == "string" ? { endpoint: t } : {};
3467
3489
  }
3468
3490
  }
3469
- function Vn() {
3491
+ function Wn() {
3470
3492
  let e = window.HAVIK_EMBED_CONFIG;
3471
3493
  if (e) return {
3472
3494
  baseUrl: e.baseUrl ?? "",
@@ -3476,7 +3498,7 @@ function Vn() {
3476
3498
  autoplay: e.autoplay ?? !0,
3477
3499
  muted: e.muted ?? !0,
3478
3500
  waitForLive: e.waitForLive ?? !0,
3479
- analytics: Bn(e.analytics)
3501
+ analytics: Un(e.analytics)
3480
3502
  };
3481
3503
  let t = new URLSearchParams(location.search);
3482
3504
  return {
@@ -3489,9 +3511,9 @@ function Vn() {
3489
3511
  waitForLive: !0
3490
3512
  };
3491
3513
  }
3492
- async function Hn() {
3493
- let e = Vn();
3494
- Wn();
3514
+ async function Gn() {
3515
+ let e = Wn();
3516
+ qn();
3495
3517
  let t = document.createElement("video");
3496
3518
  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);
3497
3519
  let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
@@ -3546,12 +3568,12 @@ async function Hn() {
3546
3568
  code: e.code,
3547
3569
  message: e.message
3548
3570
  })), e.on("autoplayblocked", () => {
3549
- i({ type: "oddin:autoplayblocked" }), Un(t, e);
3571
+ i({ type: "oddin:autoplayblocked" }), Kn(t, e);
3550
3572
  });
3551
3573
  }, s = async (r) => {
3552
3574
  a?.destroy(), a = null;
3553
3575
  try {
3554
- let n = await In({
3576
+ let n = await zn({
3555
3577
  video: t,
3556
3578
  baseUrl: e.baseUrl,
3557
3579
  matchUrn: r,
@@ -3613,7 +3635,7 @@ async function Hn() {
3613
3635
  a?.retry();
3614
3636
  break;
3615
3637
  case "oddin:load":
3616
- typeof e.matchUrn == "string" && zn.test(e.matchUrn) && s(e.matchUrn);
3638
+ typeof e.matchUrn == "string" && Hn.test(e.matchUrn) && s(e.matchUrn);
3617
3639
  break;
3618
3640
  case "oddin:destroy": c();
3619
3641
  }
@@ -3625,18 +3647,18 @@ async function Hn() {
3625
3647
  protocol: 1
3626
3648
  });
3627
3649
  }
3628
- function Un(e, t) {
3650
+ function Kn(e, t) {
3629
3651
  if (document.getElementById("havik-tap")) return;
3630
3652
  let n = document.createElement("button");
3631
3653
  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", () => {
3632
3654
  n.remove(), t.play();
3633
3655
  }), document.body.appendChild(n);
3634
3656
  }
3635
- function Wn() {
3657
+ function qn() {
3636
3658
  let e = document.createElement("style");
3637
3659
  e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
3638
3660
  }
3639
3661
  //#endregion
3640
- export { pn as ODDIN_THEME, n as PlaybackError, hn as applyTheme, B as baseUrlForEnv, Hn as bootEmbed, we as clearDeviceId, In as createPlayer, D as deriveEventsBaseUrl, Ve as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ge as fetchCatalog, ve as fetchTournament, be as flattenMatches, A as getDeviceId, Ue as isLowLatencyManifest, $ as isOddinMessage, Ee as licenseRequestHeaders, Rn as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, Se as watchStatus };
3662
+ export { gn as ODDIN_THEME, n as PlaybackError, vn as applyTheme, Ue as baseUrlForEnv, Gn as bootEmbed, Te as clearDeviceId, zn as createPlayer, E as deriveEventsBaseUrl, ze as detectDrmSupport, C as enterVideoFullscreen, w as exitVideoFullscreen, _e as fetchCatalog, ye as fetchTournament, xe as flattenMatches, k as getDeviceId, Ve as isLowLatencyManifest, $ as isOddinMessage, De as licenseRequestHeaders, Vn as mountEmbed, v as pollToLive, b as resolveStream, T as subscribeLiveState, S as videoFullscreenActive, Ce as watchStatus };
3641
3663
 
3642
3664
  //# sourceMappingURL=index.js.map