@hadoku/watchparty-ui 0.45.33 → 0.45.34

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.
@@ -1,19 +1,19 @@
1
1
  import { jsx as d, jsxs as _, Fragment as Se } from "react/jsx-runtime";
2
- import Ve, { useState as $, useRef as P, useEffect as L, useCallback as U, useMemo as Ee, Component as Xr, useContext as Bn, createContext as On, useId as Zr, useEffectEvent as fe } from "react";
3
- import { k as es, M as ts, m as ns, f as rs, a as ss, C as dt, g as Qt, i as as, S as is, r as vt, d as E, e as ee, b as os, u as x, A as pt, c as cs, h as tt, j as Hn, n as Un, D as it, w as C, l as ls, o as ds, s as jn, p as Gn, q as Wn, t as us, L as fs, v as hs, x as ps, y as qt, z as ms, B as gs, E as bs, F as ys, G as Vn, H as Yt, I as Kn, J as zn, K as vs, N as Ss, O as Ce, P as un, T as It, Q as ws, R as Jn, U as xs, V as Es, W as Qn, X as Y, Y as Ms, Z as qn, _ as Yn, $ as Xe, a0 as ks, a1 as _s, a2 as As, a3 as Ts, a4 as Is, a5 as fn, a6 as ze, a7 as Cs, a8 as hn, a9 as Rs, aa as Fs, ab as pn, ac as Ns, ad as Ls, ae as $s, af as Ps, ag as Ds, ah as mn, ai as gn, aj as Bs, ak as Xn, al as bn, am as Os, an as gt, ao as Hs, ap as Us, aq as js, ar as Gs, as as Ws, at as Vs, au as Ks, av as zs, aw as Js, ax as Qs } from "./index-kMwjyNYE.js";
4
- import { createPortal as wt } from "react-dom";
5
- import { Icon as ut, THEMES as qs, useHadokuThemeOptional as Ys } from "@wolffm/themes";
6
- import { HadokuThemePicker as Xs, ConnectedSettings as Zs } from "@wolffm/task-ui-components";
7
- import { createRoot as ea } from "react-dom/client";
8
- function ta(t) {
2
+ import Ke, { useState as $, useRef as P, useEffect as L, useCallback as U, useMemo as Me, Component as Zr, useContext as On, createContext as Hn, useId as es, useEffectEvent as fe } from "react";
3
+ import { k as ts, M as ns, m as rs, f as ss, a as as, C as ut, g as qt, i as is, S as os, r as St, d as E, e as ee, b as cs, u as x, A as mt, c as ls, h as nt, j as Un, n as jn, D as ot, w as C, l as ds, o as us, s as Gn, p as Wn, q as Vn, t as fs, L as hs, v as ps, x as ms, y as Yt, z as gs, B as bs, E as ys, F as vs, G as Kn, H as Xt, I as zn, J as Jn, K as Ss, N as ws, O as Re, P as fn, T as Ct, Q as xs, R as Qn, U as Es, V as Ms, W as qn, X as Y, Y as ks, Z as Yn, _ as Xn, $ as Ze, a0 as _s, a1 as As, a2 as Ts, a3 as Is, a4 as Cs, a5 as hn, a6 as Je, a7 as Rs, a8 as pn, a9 as Fs, aa as Ns, ab as mn, ac as Ls, ad as $s, ae as Ps, af as Ds, ag as Bs, ah as gn, ai as bn, aj as Os, ak as Zn, al as yn, am as Hs, an as bt, ao as Us, ap as js, aq as Gs, ar as Ws, as as Vs, at as Ks, au as zs, av as Js, aw as Qs, ax as qs } from "./index-C3RLe9hY.js";
4
+ import { createPortal as xt } from "react-dom";
5
+ import { Icon as ft, THEMES as Ys, useHadokuThemeOptional as Xs } from "@wolffm/themes";
6
+ import { HadokuThemePicker as Zs, ConnectedSettings as ea } from "@wolffm/task-ui-components";
7
+ import { createRoot as ta } from "react-dom/client";
8
+ function na(t) {
9
9
  return t.kind === "file";
10
10
  }
11
- class Zn extends Error {
11
+ class er extends Error {
12
12
  constructor(e) {
13
13
  super(e), this.name = "ChatImageUploadError";
14
14
  }
15
15
  }
16
- function yt(t) {
16
+ function vt(t) {
17
17
  switch (t) {
18
18
  case "unauthenticated":
19
19
  return "Sign in to paste images";
@@ -33,57 +33,57 @@ function yt(t) {
33
33
  return "Image upload failed";
34
34
  }
35
35
  }
36
- function na(t) {
37
- return t instanceof dt ? yt(t.reason) : t instanceof Zn ? t.message : "Image upload failed";
38
- }
39
36
  function ra(t) {
40
- const e = t.type.toLowerCase().split(";")[0].trim();
41
- return e && es(e) !== "image" ? yt("unsupported-type") : t.size > ts.image ? yt("too-large") : t.size === 0 ? yt("invalid") : null;
37
+ return t instanceof ut ? vt(t.reason) : t instanceof er ? t.message : "Image upload failed";
42
38
  }
43
39
  function sa(t) {
44
- return rs(t);
40
+ const e = t.type.toLowerCase().split(";")[0].trim();
41
+ return e && ts(e) !== "image" ? vt("unsupported-type") : t.size > ns.image ? vt("too-large") : t.size === 0 ? vt("invalid") : null;
45
42
  }
46
43
  function aa(t) {
47
44
  return ss(t);
48
45
  }
49
- async function ia(t) {
50
- const e = await ns(t);
46
+ function ia(t) {
47
+ return as(t);
48
+ }
49
+ async function oa(t) {
50
+ const e = await rs(t);
51
51
  return { w: e?.width ?? 0, h: e?.height ?? 0 };
52
52
  }
53
- async function oa(t, e = {}) {
54
- const n = await Qt().upload(t, { signal: e.signal });
55
- if (!as(n.key))
56
- throw new Zn("Image upload returned an unusable key");
53
+ async function ca(t, e = {}) {
54
+ const n = await qt().upload(t, { signal: e.signal });
55
+ if (!is(n.key))
56
+ throw new er("Image upload returned an unusable key");
57
57
  return { key: n.key, deduplicated: n.deduplicated === !0 };
58
58
  }
59
- async function ca(t, e = {}) {
59
+ async function la(t, e = {}) {
60
60
  const n = [];
61
61
  for (const r of t) {
62
62
  if (r.kind === "remote") {
63
63
  n.push({ key: r.key, w: r.w, h: r.h, ...r.title ? { title: r.title } : {} });
64
64
  continue;
65
65
  }
66
- const { key: s } = await oa(r.file, e);
66
+ const { key: s } = await ca(r.file, e);
67
67
  n.push({ key: s, w: r.w, h: r.h });
68
68
  }
69
69
  return n;
70
70
  }
71
- function la(t) {
71
+ function da(t) {
72
72
  return {
73
73
  error: t instanceof Error ? t.message : String(t),
74
74
  name: t instanceof Error ? t.name : typeof t,
75
- reason: t instanceof dt ? t.reason : void 0,
76
- status: t instanceof dt ? t.status : void 0
75
+ reason: t instanceof ut ? t.reason : void 0,
76
+ status: t instanceof ut ? t.status : void 0
77
77
  };
78
78
  }
79
- function da(t) {
79
+ function ua(t) {
80
80
  const e = P(t);
81
81
  return L(() => {
82
82
  e.current = t;
83
83
  }), [e, `${t.cdnBase}|${t.uploadPath}`];
84
84
  }
85
- function ua(t, e, n, r = {}) {
86
- const { limit: s, debounceMs: i = is } = r, [a, l] = da(t), [o, c] = $([]), [u, h] = $(null), [f, y] = $(!1), [g, p] = $(null), [v, w] = $(0), A = P(null);
85
+ function fa(t, e, n, r = {}) {
86
+ const { limit: s, debounceMs: i = os } = r, [a, l] = ua(t), [o, c] = $([]), [u, h] = $(null), [f, y] = $(!1), [g, p] = $(null), [v, w] = $(0), A = P(null);
87
87
  L(() => {
88
88
  w(0), h(null);
89
89
  }, [n, e]), L(() => {
@@ -103,7 +103,7 @@ function ua(t, e, n, r = {}) {
103
103
  c((I) => m ? S.results : [...I, ...S.results]), h(S.next);
104
104
  } catch (S) {
105
105
  if (k || S instanceof Error && S.name === "AbortError") return;
106
- p(S instanceof dt ? S : new dt("unknown", String(S)));
106
+ p(S instanceof ut ? S : new ut("unknown", String(S)));
107
107
  } finally {
108
108
  k || y(!1);
109
109
  }
@@ -127,21 +127,21 @@ function ua(t, e, n, r = {}) {
127
127
  }, [f, u]);
128
128
  return { items: o, loading: f, error: g, hasMore: u !== null, loadMore: F };
129
129
  }
130
- const Wt = 240, je = 8, fa = 28, er = 240;
131
- function ha(t, e, n) {
132
- let r = e.left - Wt - je;
133
- r < je && (r = e.right + je), r = Math.min(r, n.width - Wt - je), r = Math.max(je, r);
134
- const s = er + fa;
130
+ const Vt = 240, Ge = 8, ha = 28, tr = 240;
131
+ function pa(t, e, n) {
132
+ let r = e.left - Vt - Ge;
133
+ r < Ge && (r = e.right + Ge), r = Math.min(r, n.width - Vt - Ge), r = Math.max(Ge, r);
134
+ const s = tr + ha;
135
135
  let i = t.top + t.height / 2 - s / 2;
136
- return i = Math.min(i, n.height - s - je), i = Math.max(je, i), { left: r, top: i };
136
+ return i = Math.min(i, n.height - s - Ge), i = Math.max(Ge, i), { left: r, top: i };
137
137
  }
138
- const tr = "/dataplatform/api/memes", pa = 120;
139
- function ma({ onClose: t, onPick: e, onUnavailable: n }) {
140
- const [r, s] = $(""), i = P(null), a = P(null), l = Qt(), { items: o, loading: c, error: u, hasMore: h, loadMore: f } = ua(
138
+ const nr = "/dataplatform/api/memes", ma = 120;
139
+ function ga({ onClose: t, onPick: e, onUnavailable: n }) {
140
+ const [r, s] = $(""), i = P(null), a = P(null), l = qt(), { items: o, loading: c, error: u, hasMore: h, loadMore: f } = fa(
141
141
  l,
142
- tr,
142
+ nr,
143
143
  r.trim()
144
- ), y = u?.reason ?? null, g = Ee(() => {
144
+ ), y = u?.reason ?? null, g = Me(() => {
145
145
  const b = /* @__PURE__ */ new Set();
146
146
  return o.filter((S) => b.has(S.key) ? !1 : (b.add(S.key), !0));
147
147
  }, [o]), [p, v] = $(null), w = P(null), A = U(() => {
@@ -154,12 +154,12 @@ function ma({ onClose: t, onPick: e, onUnavailable: n }) {
154
154
  if (!B) return;
155
155
  const H = () => v({
156
156
  item: b,
157
- ...ha(S.getBoundingClientRect(), B.getBoundingClientRect(), {
157
+ ...pa(S.getBoundingClientRect(), B.getBoundingClientRect(), {
158
158
  width: window.innerWidth,
159
159
  height: window.innerHeight
160
160
  })
161
161
  });
162
- A(), I ? H() : w.current = window.setTimeout(H, pa);
162
+ A(), I ? H() : w.current = window.setTimeout(H, ma);
163
163
  },
164
164
  [A]
165
165
  );
@@ -220,7 +220,7 @@ function ma({ onClose: t, onPick: e, onUnavailable: n }) {
220
220
  ),
221
221
  R && /* @__PURE__ */ d("p", { className: "p-4 text-center text-sm text-text-secondary", children: r.trim() ? `No memes match "${r.trim()}"` : "The meme library is empty" }),
222
222
  g.length > 0 && /* @__PURE__ */ d("div", { className: "grid grid-cols-3 gap-1.5 sm:grid-cols-4", children: g.map((b) => {
223
- const S = vt(b.key);
223
+ const S = St(b.key);
224
224
  return S ? /* @__PURE__ */ d(
225
225
  "button",
226
226
  {
@@ -271,7 +271,7 @@ function ma({ onClose: t, onPick: e, onUnavailable: n }) {
271
271
  style: {
272
272
  left: p.left,
273
273
  top: p.top,
274
- width: Wt,
274
+ width: Vt,
275
275
  /* The placement maths reserves exactly PREVIEW_PX of width.
276
276
  Without border-box the padding and border sit OUTSIDE that
277
277
  number and the box laps over the panel it is meant to sit
@@ -285,10 +285,10 @@ function ma({ onClose: t, onPick: e, onUnavailable: n }) {
285
285
  /* @__PURE__ */ d(
286
286
  "img",
287
287
  {
288
- src: vt(p.item.key) ?? void 0,
288
+ src: St(p.item.key) ?? void 0,
289
289
  alt: "",
290
290
  className: "block w-full rounded bg-bg object-contain",
291
- style: { height: "auto", maxHeight: er }
291
+ style: { height: "auto", maxHeight: tr }
292
292
  }
293
293
  ),
294
294
  p.item.title && /* One line. A long title must not change the box height, because
@@ -301,23 +301,23 @@ function ma({ onClose: t, onPick: e, onUnavailable: n }) {
301
301
  }
302
302
  );
303
303
  }
304
- function nr({ open: t, ...e }) {
305
- return t ? /* @__PURE__ */ d(ma, { ...e }) : null;
304
+ function rr({ open: t, ...e }) {
305
+ return t ? /* @__PURE__ */ d(ga, { ...e }) : null;
306
306
  }
307
- function ga(t) {
307
+ function ba(t) {
308
308
  return typeof t == "object" && t !== null && typeof t.mount == "function";
309
309
  }
310
- function ba(t) {
310
+ function ya(t) {
311
311
  if (typeof t != "object" || t === null)
312
312
  return !1;
313
313
  const e = t;
314
314
  return typeof e.unmount == "function" && typeof e.update == "function" && (e.mountSettings === void 0 || typeof e.mountSettings == "function");
315
315
  }
316
- const Vt = "watchparty:open-media-drawer";
317
- function rr(t) {
318
- E("navigation", `Select Media clicked (${t})`), window.dispatchEvent(new CustomEvent(Vt));
316
+ const Kt = "watchparty:open-media-drawer";
317
+ function sr(t) {
318
+ E("navigation", `Select Media clicked (${t})`), window.dispatchEvent(new CustomEvent(Kt));
319
319
  }
320
- class sr extends Xr {
320
+ class ar extends Zr {
321
321
  state = { hasError: !1 };
322
322
  static getDerivedStateFromError() {
323
323
  return { hasError: !0 };
@@ -339,7 +339,7 @@ class sr extends Xr {
339
339
  ] }) : this.props.children;
340
340
  }
341
341
  }
342
- function xt() {
342
+ function Et() {
343
343
  const [t, e] = $(
344
344
  () => typeof document < "u" && !!document.fullscreenElement
345
345
  );
@@ -348,51 +348,51 @@ function xt() {
348
348
  return n(), document.addEventListener("fullscreenchange", n), () => document.removeEventListener("fullscreenchange", n);
349
349
  }, []), t;
350
350
  }
351
- function Et(t) {
351
+ function Mt(t) {
352
352
  return t.hasMedia && (t.chatCollapsed || t.isFullscreen);
353
353
  }
354
- function ya(t, e) {
355
- return t && Et(e);
354
+ function va(t, e) {
355
+ return t && Mt(e);
356
356
  }
357
- function Xt(t) {
358
- return t.isLeader ? Et(t) ? t.gameOverlay && !t.isFullscreen ? "room-corner" : "control-bar" : "chat-toolbar" : "none";
357
+ function Zt(t) {
358
+ return t.isLeader ? Mt(t) ? t.gameOverlay && !t.isFullscreen ? "room-corner" : "control-bar" : "chat-toolbar" : "none";
359
359
  }
360
- function ar(t) {
360
+ function ir(t) {
361
361
  return t.hasMedia ? t.gameOverlay && !t.isFullscreen ? "room-corner" : "control-bar" : "none";
362
362
  }
363
- function ir(t, e) {
363
+ function or(t, e) {
364
364
  if (e) {
365
365
  for (const n of Object.values(t))
366
366
  if (n.author === e && n.avatarUrl) return n.avatarUrl;
367
367
  }
368
368
  }
369
- const va = On(!0);
370
- function or() {
371
- const t = Bn(va);
369
+ const Sa = Hn(!0);
370
+ function cr() {
371
+ const t = On(Sa);
372
372
  L(() => {
373
- t && os();
373
+ t && cs();
374
374
  }, [t]);
375
375
  }
376
- function Sa(t, e) {
376
+ function wa(t, e) {
377
377
  if (!e) return "";
378
378
  for (const n of Object.values(t))
379
379
  if (n.author === e && n.cosmetics) return JSON.stringify(n.cosmetics);
380
380
  return "";
381
381
  }
382
- function cr(t) {
383
- const e = x((n) => Sa(n.roster, t));
384
- return Ee(() => e ? JSON.parse(e) : void 0, [e]);
385
- }
386
382
  function lr(t) {
383
+ const e = x((n) => wa(n.roster, t));
384
+ return Me(() => e ? JSON.parse(e) : void 0, [e]);
385
+ }
386
+ function dr(t) {
387
387
  return t ? { "--hc-base": t } : {};
388
388
  }
389
- const ft = Ve.memo(
389
+ const ht = Ke.memo(
390
390
  function({ html: e, as: n = "span", className: r, style: s }) {
391
- return Ve.createElement(n, { className: r, style: s, dangerouslySetInnerHTML: { __html: e } });
391
+ return Ke.createElement(n, { className: r, style: s, dangerouslySetInnerHTML: { __html: e } });
392
392
  },
393
393
  (t, e) => t.html === e.html && t.as === e.as && t.className === e.className && JSON.stringify(t.style) === JSON.stringify(e.style)
394
394
  );
395
- function wa(t, e) {
395
+ function xa(t, e) {
396
396
  L(() => {
397
397
  const n = t.current;
398
398
  if (!n || !e || typeof IntersectionObserver > "u") return;
@@ -404,10 +404,10 @@ function wa(t, e) {
404
404
  };
405
405
  }, [t, e]);
406
406
  }
407
- function dr({ sprite: t, url: e, alt: n, worn: r }) {
407
+ function ur({ sprite: t, url: e, alt: n, worn: r }) {
408
408
  return /* @__PURE__ */ _("span", { className: "hc-av", style: { "--hc-sz": "32px" }, children: [
409
409
  /* @__PURE__ */ d("span", { className: "hc-pic", children: /* @__PURE__ */ d(
410
- pt,
410
+ mt,
411
411
  {
412
412
  sprite: t,
413
413
  url: e,
@@ -416,25 +416,25 @@ function dr({ sprite: t, url: e, alt: n, worn: r }) {
416
416
  fallback: /* @__PURE__ */ d("span", { className: "inline-block w-8 h-8 bg-bg-alt/50 rounded-full flex-shrink-0" })
417
417
  }
418
418
  ) }),
419
- r?.overlay && /* @__PURE__ */ d(ft, { html: cs(r), style: { display: "contents" } })
419
+ r?.overlay && /* @__PURE__ */ d(ht, { html: ls(r), style: { display: "contents" } })
420
420
  ] });
421
421
  }
422
- function xa(t) {
422
+ function Ea(t) {
423
423
  return !(t.button !== 0 || t.ctrlKey || t.metaKey || t.shiftKey || t.altKey);
424
424
  }
425
- const Ea = On(null);
426
- function Ma() {
427
- return Bn(Ea);
425
+ const Ma = Hn(null);
426
+ function ka() {
427
+ return On(Ma);
428
428
  }
429
- function ka({ src: t, title: e, onClose: n }) {
429
+ function _a({ src: t, title: e, onClose: n }) {
430
430
  L(() => {
431
431
  const i = (a) => {
432
432
  a.key === "Escape" && (a.stopPropagation(), n());
433
433
  };
434
434
  return document.addEventListener("keydown", i, !0), () => document.removeEventListener("keydown", i, !0);
435
435
  }, [n]);
436
- const r = Ma(), s = typeof document > "u" ? null : document.fullscreenElement ?? r ?? document.body;
437
- return s ? wt(
436
+ const r = ka(), s = typeof document > "u" ? null : document.fullscreenElement ?? r ?? document.body;
437
+ return s ? xt(
438
438
  /* @__PURE__ */ _(
439
439
  "div",
440
440
  {
@@ -472,11 +472,11 @@ function ka({ src: t, title: e, onClose: n }) {
472
472
  s
473
473
  ) : null;
474
474
  }
475
- const Ct = 240, _a = 320;
476
- function Aa({ image: t }) {
477
- const [e, n] = $(!1), r = vt(t.key);
475
+ const Rt = 240, Aa = 320;
476
+ function Ta({ image: t }) {
477
+ const [e, n] = $(!1), r = St(t.key);
478
478
  if (!r) return null;
479
- const s = t.w > 0 && t.h > 0, i = s ? Math.min(1, _a / t.w, Ct / t.h) : 1;
479
+ const s = t.w > 0 && t.h > 0, i = s ? Math.min(1, Aa / t.w, Rt / t.h) : 1;
480
480
  return /* @__PURE__ */ _(Se, { children: [
481
481
  /* @__PURE__ */ d(
482
482
  "a",
@@ -487,7 +487,7 @@ function Aa({ image: t }) {
487
487
  className: "block max-w-full cursor-zoom-in",
488
488
  "data-testid": "chat-image",
489
489
  onClick: (a) => {
490
- xa(a) && (a.preventDefault(), n(!0));
490
+ Ea(a) && (a.preventDefault(), n(!0));
491
491
  },
492
492
  children: /* @__PURE__ */ d(
493
493
  "img",
@@ -499,13 +499,13 @@ function Aa({ image: t }) {
499
499
  width: s ? Math.round(t.w * i) : void 0,
500
500
  height: s ? Math.round(t.h * i) : void 0,
501
501
  className: "rounded border border-border-light object-contain bg-bg-alt/30",
502
- style: s ? { aspectRatio: `${t.w} / ${t.h}`, maxWidth: "100%", maxHeight: Ct } : { maxWidth: "100%", maxHeight: Ct }
502
+ style: s ? { aspectRatio: `${t.w} / ${t.h}`, maxWidth: "100%", maxHeight: Rt } : { maxWidth: "100%", maxHeight: Rt }
503
503
  }
504
504
  )
505
505
  }
506
506
  ),
507
507
  e && /* @__PURE__ */ d(
508
- ka,
508
+ _a,
509
509
  {
510
510
  src: r,
511
511
  title: t.title,
@@ -514,42 +514,42 @@ function Aa({ image: t }) {
514
514
  )
515
515
  ] });
516
516
  }
517
- function ur({ images: t }) {
518
- return t?.length ? /* @__PURE__ */ d("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: t.map((e, n) => /* @__PURE__ */ d(Aa, { image: e }, `${e.key}-${n}`)) }) : null;
517
+ function fr({ images: t }) {
518
+ return t?.length ? /* @__PURE__ */ d("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: t.map((e, n) => /* @__PURE__ */ d(Ta, { image: e }, `${e.key}-${n}`)) }) : null;
519
519
  }
520
- function Ta(t, e) {
520
+ function Ia(t, e) {
521
521
  return t.author && e.author ? t.author === e.author : !!e.clientId && t.clientId === e.clientId;
522
522
  }
523
- function Rt(t) {
523
+ function Ft(t) {
524
524
  return new Date(t).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
525
525
  }
526
- const Ia = Ve.memo(function({ message: e }) {
527
- const n = x((u) => u.me.clientId), r = x((u) => u.me.clientId ? u.roster[u.me.clientId]?.author : void 0), s = Ta(e, { clientId: n, author: r }), i = x((u) => ir(u.roster, e.author)), a = tt(e.sprite, i), l = cr(e.isSystem ? void 0 : e.author), o = P(null);
528
- wa(o, !!l);
526
+ const Ca = Ke.memo(function({ message: e }) {
527
+ const n = x((u) => u.me.clientId), r = x((u) => u.me.clientId ? u.roster[u.me.clientId]?.author : void 0), s = Ia(e, { clientId: n, author: r }), i = x((u) => or(u.roster, e.author)), a = nt(e.sprite, i), l = lr(e.isSystem ? void 0 : e.author), o = P(null);
528
+ xa(o, !!l);
529
529
  const [c] = $(
530
- () => e.live && e.text ? Hn(e.text, l) : null
530
+ () => e.live && e.text ? Un(e.text, l) : null
531
531
  );
532
532
  return e.isSystem && e.systemType === "recap" ? /* @__PURE__ */ d("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ _("div", { className: "border-l-2 border-border-light pl-2.5 py-0.5", children: [
533
533
  /* @__PURE__ */ _("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-0.5", children: [
534
534
  "Recap",
535
- /* @__PURE__ */ d("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: Rt(e.ts) })
535
+ /* @__PURE__ */ d("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: Ft(e.ts) })
536
536
  ] }),
537
537
  /* @__PURE__ */ d("p", { className: "text-[13px] text-text-secondary leading-relaxed whitespace-pre-wrap break-words", children: e.text })
538
538
  ] }) }) : e.isSystem ? /* @__PURE__ */ _("div", { className: "px-2 py-0.5 text-[11px] text-text-muted italic text-center leading-tight", children: [
539
539
  e.text,
540
- /* @__PURE__ */ d("span", { className: "ml-1 text-[10px] opacity-50", children: Rt(e.ts) })
541
- ] }) : /* @__PURE__ */ _("div", { ref: o, style: lr(a), className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${s ? "bg-bg-card/30" : ""}`, children: [
542
- /* @__PURE__ */ d(dr, { sprite: e.sprite, url: i, alt: e.name, worn: l }),
540
+ /* @__PURE__ */ d("span", { className: "ml-1 text-[10px] opacity-50", children: Ft(e.ts) })
541
+ ] }) : /* @__PURE__ */ _("div", { ref: o, style: dr(a), className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${s ? "bg-bg-card/30" : ""}`, children: [
542
+ /* @__PURE__ */ d(ur, { sprite: e.sprite, url: i, alt: e.name, worn: l }),
543
543
  /* @__PURE__ */ _("div", { className: "flex-1 min-w-0 -mt-0.5", children: [
544
- l ? /* @__PURE__ */ d(ft, { html: Un(e.name, l), className: "text-[13px]", style: { color: a } }) : /* @__PURE__ */ d("span", { className: "font-medium text-[13px]", style: { color: a }, children: e.name }),
545
- /* @__PURE__ */ d("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: Rt(e.ts) }),
546
- e.text && (c ? /* @__PURE__ */ d(ft, { as: "p", html: c, className: "text-[13px] text-text break-words leading-snug m-0" }) : /* @__PURE__ */ d("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: e.text })),
547
- /* @__PURE__ */ d(ur, { images: e.images })
544
+ l ? /* @__PURE__ */ d(ht, { html: jn(e.name, l), className: "text-[13px]", style: { color: a } }) : /* @__PURE__ */ d("span", { className: "font-medium text-[13px]", style: { color: a }, children: e.name }),
545
+ /* @__PURE__ */ d("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: Ft(e.ts) }),
546
+ e.text && (c ? /* @__PURE__ */ d(ht, { as: "p", html: c, className: "text-[13px] text-text break-words leading-snug m-0" }) : /* @__PURE__ */ d("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: e.text })),
547
+ /* @__PURE__ */ d(fr, { images: e.images })
548
548
  ] })
549
549
  ] });
550
550
  });
551
- function Ca() {
552
- or();
551
+ function Ra() {
552
+ cr();
553
553
  const t = x((s) => s.chat), e = P(null), n = P(!1), r = U(() => {
554
554
  const s = e.current;
555
555
  if (!s) return;
@@ -567,19 +567,19 @@ function Ca() {
567
567
  className: "flex-1 overflow-y-auto overflow-x-hidden chat-messages",
568
568
  children: t.length === 0 ? /* @__PURE__ */ d("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ d(Se, { children: t.map((s, i) => {
569
569
  const a = i > 0 ? t[i - 1] : null, l = a && s.ts - a.ts > 1440 * 60 * 1e3;
570
- return /* @__PURE__ */ _(Ve.Fragment, { children: [
570
+ return /* @__PURE__ */ _(Ke.Fragment, { children: [
571
571
  l && /* @__PURE__ */ _("div", { className: "flex items-center gap-2 px-4 py-2 my-1", children: [
572
572
  /* @__PURE__ */ d("div", { className: "flex-1 h-px bg-border" }),
573
573
  /* @__PURE__ */ d("span", { className: "text-[10px] text-text-muted whitespace-nowrap", children: new Date(s.ts).toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" }) }),
574
574
  /* @__PURE__ */ d("div", { className: "flex-1 h-px bg-border" })
575
575
  ] }),
576
- /* @__PURE__ */ d(Ia, { message: s })
576
+ /* @__PURE__ */ d(Ca, { message: s })
577
577
  ] }, s.id);
578
578
  }) })
579
579
  }
580
580
  );
581
581
  }
582
- const Zt = [
582
+ const en = [
583
583
  {
584
584
  name: "recap",
585
585
  description: "Summarise the previous episode of what is loaded",
@@ -599,13 +599,13 @@ const Zt = [
599
599
  usage: "/help",
600
600
  scope: "local"
601
601
  }
602
- ], et = "/";
603
- function Ra(t) {
604
- if (!t.startsWith(et)) return null;
605
- const e = t.slice(et.length);
602
+ ], tt = "/";
603
+ function Fa(t) {
604
+ if (!t.startsWith(tt)) return null;
605
+ const e = t.slice(tt.length);
606
606
  return /\s/.test(e) ? null : e.toLowerCase();
607
607
  }
608
- function Fa(t, e = Zt) {
608
+ function Na(t, e = en) {
609
609
  const n = t.toLowerCase();
610
610
  if (!n) return [...e].sort((s, i) => s.name.localeCompare(i.name));
611
611
  const r = [];
@@ -615,23 +615,23 @@ function Fa(t, e = Zt) {
615
615
  }
616
616
  return r.sort((s, i) => s.rank - i.rank || s.cmd.name.localeCompare(i.cmd.name)).map((s) => s.cmd);
617
617
  }
618
- function Na(t) {
619
- return `${et}${t.name} `;
618
+ function La(t) {
619
+ return `${tt}${t.name} `;
620
620
  }
621
- function Ft(t, e) {
621
+ function Nt(t, e) {
622
622
  return e <= 0 ? 0 : (t % e + e) % e;
623
623
  }
624
- function La(t, e = Zt) {
624
+ function $a(t, e = en) {
625
625
  const n = t.trim();
626
626
  if (!n) return null;
627
- if (!n.startsWith(et)) return { kind: "chat", text: n };
628
- const r = n.slice(et.length), s = r.search(/\s/), i = (s === -1 ? r : r.slice(0, s)).toLowerCase(), a = s === -1 ? "" : r.slice(s).trim(), l = e.find((o) => o.name.toLowerCase() === i);
627
+ if (!n.startsWith(tt)) return { kind: "chat", text: n };
628
+ const r = n.slice(tt.length), s = r.search(/\s/), i = (s === -1 ? r : r.slice(0, s)).toLowerCase(), a = s === -1 ? "" : r.slice(s).trim(), l = e.find((o) => o.name.toLowerCase() === i);
629
629
  return l ? { kind: "command", command: l, args: a } : { kind: "chat", text: n };
630
630
  }
631
- function $a(t, e) {
632
- return t.requiresMedia && !e.hasMedia ? `${et}${t.name} needs an episode loaded.` : null;
631
+ function Pa(t, e) {
632
+ return t.requiresMedia && !e.hasMedia ? `${tt}${t.name} needs an episode loaded.` : null;
633
633
  }
634
- function Pa({
634
+ function Da({
635
635
  commands: t,
636
636
  activeIndex: e,
637
637
  hasMedia: n,
@@ -673,7 +673,7 @@ function Pa({
673
673
  }
674
674
  );
675
675
  }
676
- function fr({
676
+ function hr({
677
677
  pending: t,
678
678
  uploading: e,
679
679
  onRemove: n
@@ -700,24 +700,24 @@ function fr({
700
700
  )
701
701
  ] }, r.id)) }) : null;
702
702
  }
703
- function hr() {
703
+ function pr() {
704
704
  const [t, e] = $([]), [n, r] = $(!1), s = x((p) => p.pushToast), i = P(/* @__PURE__ */ new Set());
705
705
  L(() => () => {
706
706
  for (const p of i.current) URL.revokeObjectURL(p);
707
707
  i.current.clear();
708
708
  }, []);
709
709
  const a = U((p) => {
710
- ta(p) && (URL.revokeObjectURL(p.previewUrl), i.current.delete(p.previewUrl));
710
+ na(p) && (URL.revokeObjectURL(p.previewUrl), i.current.delete(p.previewUrl));
711
711
  }, []), l = U(async (p) => {
712
712
  if (!p.length) return;
713
713
  const v = [];
714
714
  for (const w of p) {
715
- const A = ra(w);
715
+ const A = sa(w);
716
716
  if (A) {
717
717
  s("error", A);
718
718
  continue;
719
719
  }
720
- const { w: F, h: k } = await ia(w), m = URL.createObjectURL(w);
720
+ const { w: F, h: k } = await oa(w), m = URL.createObjectURL(w);
721
721
  i.current.add(m), v.push({
722
722
  kind: "file",
723
723
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
@@ -728,21 +728,21 @@ function hr() {
728
728
  });
729
729
  }
730
730
  v.length && e((w) => {
731
- const A = it - w.length;
731
+ const A = ot - w.length;
732
732
  if (A <= 0) {
733
- s("info", `Up to ${it} images per message`);
733
+ s("info", `Up to ${ot} images per message`);
734
734
  for (const F of v) a(F);
735
735
  return w;
736
736
  }
737
737
  if (v.length > A) {
738
- s("info", `Up to ${it} images per message`);
738
+ s("info", `Up to ${ot} images per message`);
739
739
  for (const F of v.slice(A)) a(F);
740
740
  }
741
741
  return [...w, ...v.slice(0, A)];
742
742
  });
743
743
  }, [s, a]), o = U((p) => {
744
- const v = vt(p.key);
745
- v && (e((w) => w.length >= it ? (s("info", `Up to ${it} images per message`), w) : [...w, {
744
+ const v = St(p.key);
745
+ v && (e((w) => w.length >= ot ? (s("info", `Up to ${ot} images per message`), w) : [...w, {
746
746
  kind: "remote",
747
747
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
748
748
  key: p.key,
@@ -752,7 +752,7 @@ function hr() {
752
752
  w: p.width ?? 0,
753
753
  h: p.height ?? 0,
754
754
  title: p.title || void 0
755
- }]), Qt().catalogue(tr).recordUse(p.key));
755
+ }]), qt().catalogue(nr).recordUse(p.key));
756
756
  }, [s]), c = U((p) => {
757
757
  e((v) => {
758
758
  const w = v.find((A) => A.id === p);
@@ -764,10 +764,10 @@ function hr() {
764
764
  return [];
765
765
  });
766
766
  }, [a]), h = U((p) => {
767
- const v = sa(p.clipboardData);
767
+ const v = aa(p.clipboardData);
768
768
  v.length && (p.preventDefault(), l(v));
769
769
  }, [l]), f = U((p) => {
770
- const v = aa(p.dataTransfer);
770
+ const v = ia(p.dataTransfer);
771
771
  v.length && (p.preventDefault(), l(v));
772
772
  }, [l]), y = U((p) => {
773
773
  p.dataTransfer?.types?.includes("Files") && p.preventDefault();
@@ -775,9 +775,9 @@ function hr() {
775
775
  if (!t.length) return [];
776
776
  r(!0);
777
777
  try {
778
- return await ca(t);
778
+ return await la(t);
779
779
  } catch (p) {
780
- return C("chat", "Image upload failed", la(p)), s("error", na(p)), null;
780
+ return C("chat", "Image upload failed", da(p)), s("error", ra(p)), null;
781
781
  } finally {
782
782
  r(!1);
783
783
  }
@@ -795,16 +795,16 @@ function hr() {
795
795
  onDragOver: y
796
796
  };
797
797
  }
798
- const yn = Wn, Da = Gn;
799
- function Ba({ commands: t = Zt }) {
800
- const [e, n] = $(""), [r, s] = $(!1), [i, a] = $({ q: null, i: 0 }), [l, o] = $(!1), c = P(null), u = Zr(), [h, f] = $(!1), [y, g] = $(!1), p = hr(), v = x((N) => N.snapshot.mediaId), w = x((N) => N.pushToast), A = x((N) => N.setTierlistOpen), F = !!v, k = Ra(e), m = Ee(
801
- () => k === null ? [] : Fa(k, t),
798
+ const vn = Vn, Ba = Wn;
799
+ function Oa({ commands: t = en }) {
800
+ const [e, n] = $(""), [r, s] = $(!1), [i, a] = $({ q: null, i: 0 }), [l, o] = $(!1), c = P(null), u = es(), [h, f] = $(!1), [y, g] = $(!1), p = pr(), v = x((N) => N.snapshot.mediaId), w = x((N) => N.pushToast), A = x((N) => N.setTierlistOpen), F = !!v, k = Fa(e), m = Me(
801
+ () => k === null ? [] : Na(k, t),
802
802
  [k, t]
803
- ), T = k !== null && !l && m.length > 0, R = i.q === k ? Ft(i.i, m.length) : 0, b = U(
803
+ ), T = k !== null && !l && m.length > 0, R = i.q === k ? Nt(i.i, m.length) : 0, b = U(
804
804
  (N) => a({ q: k, i: N }),
805
805
  [k]
806
806
  ), S = U((N, O) => {
807
- const Q = $a(N, { hasMedia: F });
807
+ const Q = Pa(N, { hasMedia: F });
808
808
  if (Q) {
809
809
  w("info", Q);
810
810
  return;
@@ -814,19 +814,19 @@ function Ba({ commands: t = Zt }) {
814
814
  w("info", t.map((W) => W.usage).join(" "));
815
815
  break;
816
816
  case "recap":
817
- ds();
817
+ us();
818
818
  break;
819
819
  case "tierlist":
820
- ls(), A(!0);
820
+ ds(), A(!0);
821
821
  break;
822
822
  default:
823
823
  w("info", `${N.usage} is not implemented yet.`);
824
824
  }
825
825
  }, [F, w, t, A]), I = U((N) => {
826
- n(Na(N)), o(!1), c.current?.focus();
826
+ n(La(N)), o(!1), c.current?.focus();
827
827
  }, []), B = U(async (N) => {
828
828
  if (N.preventDefault(), r || p.uploading) return;
829
- const O = La(e, t);
829
+ const O = $a(e, t);
830
830
  if (!O && !p.pending.length) return;
831
831
  if (O?.kind === "command" && p.pending.length) {
832
832
  w("info", "Send images on their own, not with a command.");
@@ -837,7 +837,7 @@ function Ba({ commands: t = Zt }) {
837
837
  return;
838
838
  }
839
839
  const Q = await p.uploadPending();
840
- Q !== null && (jn(O?.text ?? "", Q), n(""), p.clear(), s(!0), setTimeout(() => s(!1), Da), !document.hidden && document.hasFocus() && c.current?.focus());
840
+ Q !== null && (Gn(O?.text ?? "", Q), n(""), p.clear(), s(!0), setTimeout(() => s(!1), Ba), !document.hidden && document.hasFocus() && c.current?.focus());
841
841
  }, [e, r, S, p, w, t]), H = U((N) => {
842
842
  if (N.key === "Escape" && T) {
843
843
  N.preventDefault(), o(!0);
@@ -845,9 +845,9 @@ function Ba({ commands: t = Zt }) {
845
845
  }
846
846
  if (T) {
847
847
  if (N.key === "ArrowDown")
848
- N.preventDefault(), b(Ft(R + 1, m.length));
848
+ N.preventDefault(), b(Nt(R + 1, m.length));
849
849
  else if (N.key === "ArrowUp")
850
- N.preventDefault(), b(Ft(R - 1, m.length));
850
+ N.preventDefault(), b(Nt(R - 1, m.length));
851
851
  else if (N.key === "Tab") {
852
852
  N.preventDefault();
853
853
  const O = m[R];
@@ -865,7 +865,7 @@ function Ba({ commands: t = Zt }) {
865
865
  };
866
866
  return window.addEventListener("watchparty:focus-chat-input", N), () => window.removeEventListener("watchparty:focus-chat-input", N);
867
867
  }, []);
868
- const j = yn - e.length, K = j <= 100, X = T ? m[R] : void 0;
868
+ const j = vn - e.length, K = j <= 100, X = T ? m[R] : void 0;
869
869
  return /* @__PURE__ */ _(
870
870
  "form",
871
871
  {
@@ -877,10 +877,10 @@ function Ba({ commands: t = Zt }) {
877
877
  onDragOver: p.onDragOver,
878
878
  className: "p-2 border-t border-border",
879
879
  children: [
880
- /* @__PURE__ */ d(fr, { pending: p.pending, uploading: p.uploading, onRemove: p.remove }),
880
+ /* @__PURE__ */ d(hr, { pending: p.pending, uploading: p.uploading, onRemove: p.remove }),
881
881
  /* @__PURE__ */ _("div", { className: "relative", children: [
882
882
  T && /* @__PURE__ */ d(
883
- Pa,
883
+ Da,
884
884
  {
885
885
  commands: m,
886
886
  activeIndex: R,
@@ -891,7 +891,7 @@ function Ba({ commands: t = Zt }) {
891
891
  }
892
892
  ),
893
893
  /* @__PURE__ */ d(
894
- nr,
894
+ rr,
895
895
  {
896
896
  open: h,
897
897
  onClose: () => f(!1),
@@ -913,7 +913,7 @@ function Ba({ commands: t = Zt }) {
913
913
  n(N.target.value), o(!1);
914
914
  },
915
915
  onKeyDown: H,
916
- maxLength: yn,
916
+ maxLength: vn,
917
917
  placeholder: "Send a message",
918
918
  role: "combobox",
919
919
  "aria-expanded": T,
@@ -935,7 +935,7 @@ function Ba({ commands: t = Zt }) {
935
935
  title: "Add a meme",
936
936
  "data-testid": "meme-button",
937
937
  className: `shrink-0 rounded border border-border-light px-2 py-1.5 text-sm hover:border-primary ${h ? "text-text border-primary" : "text-text-secondary"}`,
938
- children: /* @__PURE__ */ d(ut, { name: "image" })
938
+ children: /* @__PURE__ */ d(ft, { name: "image" })
939
939
  }
940
940
  )
941
941
  ] })
@@ -944,15 +944,15 @@ function Ba({ commands: t = Zt }) {
944
944
  }
945
945
  );
946
946
  }
947
- function Oa() {
947
+ function Ha() {
948
948
  const t = x((n) => n.roster), e = Object.values(t);
949
- return e.length ? /* @__PURE__ */ d("div", { className: "flex flex-col gap-1", children: e.map((n) => /* @__PURE__ */ d(Ha, { u: n }, n.clientId)) }) : /* @__PURE__ */ d("div", { className: "text-xs text-text-muted", children: "No users online" });
949
+ return e.length ? /* @__PURE__ */ d("div", { className: "flex flex-col gap-1", children: e.map((n) => /* @__PURE__ */ d(Ua, { u: n }, n.clientId)) }) : /* @__PURE__ */ d("div", { className: "text-xs text-text-muted", children: "No users online" });
950
950
  }
951
- function Ha({ u: t }) {
952
- const e = tt(t.sprite, t.avatarUrl);
951
+ function Ua({ u: t }) {
952
+ const e = nt(t.sprite, t.avatarUrl);
953
953
  return /* @__PURE__ */ _("div", { className: "flex items-center gap-2 py-0.5", children: [
954
954
  /* @__PURE__ */ d(
955
- pt,
955
+ mt,
956
956
  {
957
957
  sprite: t.sprite,
958
958
  url: t.avatarUrl,
@@ -965,7 +965,7 @@ function Ha({ u: t }) {
965
965
  t.isLeader && /* @__PURE__ */ d("span", { className: "ml-auto px-1.5 py-0.5 rounded text-[9px] font-medium bg-success/20 text-success", children: "Leader" })
966
966
  ] });
967
967
  }
968
- function Ua() {
968
+ function ja() {
969
969
  const t = x((s) => Object.keys(s.roster).length), [e, n] = $(!1), r = P(null);
970
970
  return L(() => {
971
971
  if (!e) return;
@@ -993,20 +993,20 @@ function Ua() {
993
993
  t,
994
994
  " online"
995
995
  ] }),
996
- /* @__PURE__ */ d(Oa, {})
996
+ /* @__PURE__ */ d(Ha, {})
997
997
  ] })
998
998
  ] });
999
999
  }
1000
- function ja({ leaderId: t, clientId: e, keyType: n }) {
1000
+ function Ga({ leaderId: t, clientId: e, keyType: n }) {
1001
1001
  return t !== null ? t === e : n === "leader";
1002
1002
  }
1003
- const Ga = /-[0-9a-fA-F]{16}$/;
1004
- function Wa(t) {
1005
- return t && Ga.test(t) ? "leader" : null;
1003
+ const Wa = /-[0-9a-fA-F]{16}$/;
1004
+ function Va(t) {
1005
+ return t && Wa.test(t) ? "leader" : null;
1006
1006
  }
1007
- const Va = /\/room\/([^/]+)\/?$/;
1008
- function Ka(t) {
1009
- const e = t ? Va.exec(t) : null;
1007
+ const Ka = /\/room\/([^/]+)\/?$/;
1008
+ function za(t) {
1009
+ const e = t ? Ka.exec(t) : null;
1010
1010
  if (!e) return null;
1011
1011
  try {
1012
1012
  return decodeURIComponent(e[1]);
@@ -1014,39 +1014,39 @@ function Ka(t) {
1014
1014
  return e[1];
1015
1015
  }
1016
1016
  }
1017
- function za(t, e) {
1018
- return t && e?.roomKey === t ? e.type : Wa(t);
1017
+ function Ja(t, e) {
1018
+ return t && e?.roomKey === t ? e.type : Va(t);
1019
1019
  }
1020
- function nt() {
1020
+ function rt() {
1021
1021
  return x((t) => !!t.snapshot.leaderId && t.snapshot.leaderId === t.me.clientId);
1022
1022
  }
1023
- function Mt() {
1024
- const t = x((n) => n.activeGameId), e = us();
1023
+ function kt() {
1024
+ const t = x((n) => n.activeGameId), e = fs();
1025
1025
  return t ? e.find((n) => n.id === t) ?? null : null;
1026
1026
  }
1027
- function en() {
1028
- return x((t) => ja({
1027
+ function tn() {
1028
+ return x((t) => Ga({
1029
1029
  leaderId: t.snapshot.leaderId,
1030
1030
  clientId: t.me.clientId,
1031
- keyType: za(Ka(globalThis.location?.pathname), t.roomKeyType)
1031
+ keyType: Ja(za(globalThis.location?.pathname), t.roomKeyType)
1032
1032
  }));
1033
1033
  }
1034
- function pr() {
1034
+ function mr() {
1035
1035
  return x((t) => t.readiness);
1036
1036
  }
1037
- function Ja() {
1037
+ function Qa() {
1038
1038
  return x((t) => t.snapshot);
1039
1039
  }
1040
- const Qa = 3e4;
1041
- function mr() {
1042
- const t = pr(), [e, n] = $(!1), [r, s] = $({ mediaId: t.mediaId, ready: t.ready });
1040
+ const qa = 3e4;
1041
+ function gr() {
1042
+ const t = mr(), [e, n] = $(!1), [r, s] = $({ mediaId: t.mediaId, ready: t.ready });
1043
1043
  return (r.mediaId !== t.mediaId || r.ready !== t.ready) && (s({ mediaId: t.mediaId, ready: t.ready }), n(!1)), L(() => {
1044
1044
  if (t.ready) return;
1045
- const i = setTimeout(() => n(!0), Qa);
1045
+ const i = setTimeout(() => n(!0), qa);
1046
1046
  return () => clearTimeout(i);
1047
1047
  }, [t.mediaId, t.ready]), e;
1048
1048
  }
1049
- function qa({ draw: t }) {
1049
+ function Ya({ draw: t }) {
1050
1050
  const e = P(null);
1051
1051
  return L(() => {
1052
1052
  const n = e.current;
@@ -1054,42 +1054,42 @@ function qa({ draw: t }) {
1054
1054
  return t(n) ?? void 0;
1055
1055
  }, [t]), /* @__PURE__ */ d("div", { ref: e, "data-testid": "game-settings" });
1056
1056
  }
1057
- const Ya = qt(() => import("./AdminPanel-nU-YUW-1.js")), Xa = qt(() => import("./PlaylistPanel-BHQKt_A8.js"));
1058
- function Za() {
1059
- const t = x((f) => f.chatCollapsed), e = xt(), n = x((f) => f.sidebarTab), r = x((f) => f.setSidebarTab), s = x((f) => f.healthSnapshot?.clients.length ?? 0), i = x((f) => !!f.playlist), a = nt(), l = en(), o = x((f) => f.gameSettings), c = x((f) => f.snapshot.mediaId), u = Mt() !== null;
1060
- if (Et({ hasMedia: !!c, chatCollapsed: t, isFullscreen: e }))
1057
+ const Xa = Yt(() => import("./AdminPanel-CcPA3gyf.js")), Za = Yt(() => import("./PlaylistPanel-CUtkEqZF.js"));
1058
+ function ei() {
1059
+ const t = x((f) => f.chatCollapsed), e = Et(), n = x((f) => f.sidebarTab), r = x((f) => f.setSidebarTab), s = x((f) => f.healthSnapshot?.clients.length ?? 0), i = x((f) => !!f.playlist), a = rt(), l = tn(), o = x((f) => f.gameSettings), c = x((f) => f.snapshot.mediaId), u = kt() !== null;
1060
+ if (Mt({ hasMedia: !!c, chatCollapsed: t, isFullscreen: e }))
1061
1061
  return null;
1062
1062
  const h = n === "health" && !a || n === "playlist" && !i ? "chat" : n;
1063
1063
  return /* @__PURE__ */ _("aside", { className: "w-80 self-stretch border-l border-border flex flex-col bg-bg relative z-10", children: [
1064
1064
  /* @__PURE__ */ _("div", { className: "chat-toolbar relative flex items-center gap-1 px-2 py-1.5 border-b border-border", children: [
1065
1065
  /* @__PURE__ */ d(
1066
- fs,
1066
+ hs,
1067
1067
  {
1068
1068
  to: "/",
1069
1069
  className: "p-1.5 rounded text-text-secondary hover:text-white hover:bg-bg-alt transition-colors cursor-pointer",
1070
1070
  title: "Home",
1071
1071
  "aria-label": "Home",
1072
1072
  onClick: () => {
1073
- E("navigation", "Home button clicked (chat toolbar)"), hs();
1073
+ E("navigation", "Home button clicked (chat toolbar)"), ps();
1074
1074
  },
1075
1075
  children: /* @__PURE__ */ d("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" }) })
1076
1076
  }
1077
1077
  ),
1078
- Xt({ isLeader: l, hasMedia: !!c, chatCollapsed: t, isFullscreen: e, gameOverlay: u }) === "chat-toolbar" && /* @__PURE__ */ d(
1078
+ Zt({ isLeader: l, hasMedia: !!c, chatCollapsed: t, isFullscreen: e, gameOverlay: u }) === "chat-toolbar" && /* @__PURE__ */ d(
1079
1079
  "button",
1080
1080
  {
1081
- onClick: () => rr("chat toolbar"),
1081
+ onClick: () => sr("chat toolbar"),
1082
1082
  className: "p-1.5 rounded text-text-secondary hover:text-white hover:bg-bg-alt transition-colors cursor-pointer",
1083
1083
  title: "Select Media",
1084
1084
  "aria-label": "Select Media",
1085
1085
  children: /* @__PURE__ */ d("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 4v16M17 4v16M3 8h4m10 0h4M3 12h18M3 16h4m10 0h4M4 4h16a1 1 0 011 1v14a1 1 0 01-1 1H4a1 1 0 01-1-1V5a1 1 0 011-1z" }) })
1086
1086
  }
1087
1087
  ),
1088
- /* @__PURE__ */ d(Xs, {}),
1089
- /* @__PURE__ */ d(Zs, { onNameChange: (f) => {
1090
- f && x.getState().me.clientId && ps(f);
1091
- }, children: o ? /* @__PURE__ */ d(qa, { draw: o }) : null }),
1092
- /* @__PURE__ */ d(Ua, {})
1088
+ /* @__PURE__ */ d(Zs, {}),
1089
+ /* @__PURE__ */ d(ea, { onNameChange: (f) => {
1090
+ f && x.getState().me.clientId && ms(f);
1091
+ }, children: o ? /* @__PURE__ */ d(Ya, { draw: o }) : null }),
1092
+ /* @__PURE__ */ d(ja, {})
1093
1093
  ] }),
1094
1094
  (a || i) && /* @__PURE__ */ _("div", { className: "flex border-b border-border shrink-0", children: [
1095
1095
  /* @__PURE__ */ d(
@@ -1120,37 +1120,37 @@ function Za() {
1120
1120
  }
1121
1121
  )
1122
1122
  ] }),
1123
- h === "health" ? /* @__PURE__ */ d(Ve.Suspense, { fallback: /* @__PURE__ */ d("div", { className: "p-4 text-xs text-text-muted", children: "Loading..." }), children: /* @__PURE__ */ d(Ya, {}) }) : h === "playlist" ? /* @__PURE__ */ d(Ve.Suspense, { fallback: /* @__PURE__ */ d("div", { className: "p-4 text-xs text-text-muted", children: "Loading..." }), children: /* @__PURE__ */ d(Xa, {}) }) : /* @__PURE__ */ _(Se, { children: [
1124
- /* @__PURE__ */ d(Ca, {}),
1125
- /* @__PURE__ */ d(Ba, {})
1123
+ h === "health" ? /* @__PURE__ */ d(Ke.Suspense, { fallback: /* @__PURE__ */ d("div", { className: "p-4 text-xs text-text-muted", children: "Loading..." }), children: /* @__PURE__ */ d(Xa, {}) }) : h === "playlist" ? /* @__PURE__ */ d(Ke.Suspense, { fallback: /* @__PURE__ */ d("div", { className: "p-4 text-xs text-text-muted", children: "Loading..." }), children: /* @__PURE__ */ d(Za, {}) }) : /* @__PURE__ */ _(Se, { children: [
1124
+ /* @__PURE__ */ d(Ra, {}),
1125
+ /* @__PURE__ */ d(Oa, {})
1126
1126
  ] })
1127
1127
  ] });
1128
1128
  }
1129
- const vn = (t) => typeof t == "string" && qs.includes(t);
1130
- function ei(t, e, n) {
1131
- return vn(e) ? e : vn(n) ? n : "dark";
1129
+ const Sn = (t) => typeof t == "string" && Ys.includes(t);
1130
+ function ti(t, e, n) {
1131
+ return Sn(e) ? e : Sn(n) ? n : "dark";
1132
1132
  }
1133
- function ti(t, e) {
1134
- if (!ms(t)) return null;
1133
+ function ni(t, e) {
1134
+ if (!gs(t)) return null;
1135
1135
  const n = new URL(t, e);
1136
1136
  return n.origin === e ? n.href : null;
1137
1137
  }
1138
- function ni(t, e) {
1139
- const n = ti(t.url, e);
1138
+ function ri(t, e) {
1139
+ const n = ni(t.url, e);
1140
1140
  return { id: t.id, name: t.name, load: n ? () => import(
1141
1141
  /* @vite-ignore */
1142
1142
  n
1143
1143
  ) : null };
1144
1144
  }
1145
- const Je = (t) => t instanceof Error ? t.message : String(t);
1146
- function ri(t) {
1145
+ const Qe = (t) => t instanceof Error ? t.message : String(t);
1146
+ function si(t) {
1147
1147
  let e = t.ctx, n = null, r = !1, s = !1;
1148
1148
  const i = /* @__PURE__ */ new Set(), a = (f, y) => t.onSettingsError?.(f, y), l = (f) => {
1149
1149
  if (i.delete(f))
1150
1150
  try {
1151
1151
  f.cleanup();
1152
1152
  } catch (y) {
1153
- a(`the game's settings failed to close: ${Je(y)}`, y);
1153
+ a(`the game's settings failed to close: ${Qe(y)}`, y);
1154
1154
  }
1155
1155
  }, o = (f) => {
1156
1156
  for (const y of [...i]) l(y);
@@ -1160,7 +1160,7 @@ function ri(t) {
1160
1160
  try {
1161
1161
  f.unmount();
1162
1162
  } catch (y) {
1163
- s || t.onError(`unmount threw: ${Je(y)}`, y);
1163
+ s || t.onError(`unmount threw: ${Qe(y)}`, y);
1164
1164
  }
1165
1165
  }, u = (f, y) => {
1166
1166
  if (s || r) return;
@@ -1172,7 +1172,7 @@ function ri(t) {
1172
1172
  try {
1173
1173
  n.update(f);
1174
1174
  } catch (y) {
1175
- u(`the game failed to update: ${Je(y)}`, y);
1175
+ u(`the game failed to update: ${Qe(y)}`, y);
1176
1176
  }
1177
1177
  };
1178
1178
  return (async () => {
@@ -1180,11 +1180,11 @@ function ri(t) {
1180
1180
  try {
1181
1181
  f = await t.load();
1182
1182
  } catch (p) {
1183
- u(`could not load the game: ${Je(p)}`, p);
1183
+ u(`could not load the game: ${Qe(p)}`, p);
1184
1184
  return;
1185
1185
  }
1186
1186
  if (r) return;
1187
- if (!ga(f)) {
1187
+ if (!ba(f)) {
1188
1188
  u("the game module does not export mount()");
1189
1189
  return;
1190
1190
  }
@@ -1193,10 +1193,10 @@ function ri(t) {
1193
1193
  try {
1194
1194
  g = await f.mount(t.el, y);
1195
1195
  } catch (p) {
1196
- u(`the game failed to start: ${Je(p)}`, p);
1196
+ u(`the game failed to start: ${Qe(p)}`, p);
1197
1197
  return;
1198
1198
  }
1199
- if (!ba(g)) {
1199
+ if (!ya(g)) {
1200
1200
  u("the game's mount() did not return { unmount, update }");
1201
1201
  return;
1202
1202
  }
@@ -1217,7 +1217,7 @@ function ri(t) {
1217
1217
  try {
1218
1218
  g = y.mountSettings(f);
1219
1219
  } catch (v) {
1220
- return a(`the game's settings failed to open: ${Je(v)}`, v), null;
1220
+ return a(`the game's settings failed to open: ${Qe(v)}`, v), null;
1221
1221
  }
1222
1222
  if (typeof g != "function")
1223
1223
  return a("the game's mountSettings() did not return a cleanup function"), null;
@@ -1226,19 +1226,19 @@ function ri(t) {
1226
1226
  }
1227
1227
  };
1228
1228
  }
1229
- function Sn({ activity: t, roomKey: e, layer: n }) {
1230
- const r = P(null), s = P(null), [i, a] = $(null), [l, o] = $(!1), c = x((k) => k.snapshot.leaderId), u = x((k) => k.me.clientId), h = !!c && c === u, f = x((k) => k.name), y = Ys()?.theme, g = ei(void 0, y, gs().theme), p = Ee(() => ({
1229
+ function wn({ activity: t, roomKey: e, layer: n }) {
1230
+ const r = P(null), s = P(null), [i, a] = $(null), [l, o] = $(!1), c = x((k) => k.snapshot.leaderId), u = x((k) => k.me.clientId), h = !!c && c === u, f = x((k) => k.name), y = Xs()?.theme, g = ti(void 0, y, bs().theme), p = Me(() => ({
1231
1231
  roomKey: e,
1232
1232
  identity: {
1233
1233
  // The registry userId — what RoomChrome's `userId` prop is.
1234
- userId: ys(),
1235
- userType: bs(),
1234
+ userId: vs(),
1235
+ userType: ys(),
1236
1236
  name: f || null
1237
1237
  },
1238
1238
  theme: g,
1239
1239
  isLeader: h,
1240
1240
  close: () => {
1241
- E("game", "bundle close", { gameId: t.id, isLeader: h, layer: n }), n !== "base" && (h ? Vn(null) : o(!0));
1241
+ E("game", "bundle close", { gameId: t.id, isLeader: h, layer: n }), n !== "base" && (h ? Kn(null) : o(!0));
1242
1242
  }
1243
1243
  }), [e, f, g, h, t.id, n]), v = fe(() => p), w = fe((k, m) => {
1244
1244
  C("game", "bundle failed", { gameId: t.id, message: k, cause: String(m) }), a(k);
@@ -1249,7 +1249,7 @@ function Sn({ activity: t, roomKey: e, layer: n }) {
1249
1249
  const k = r.current, m = t.load;
1250
1250
  if (!k || !m || l) return;
1251
1251
  E("game", "bundle mount", { gameId: t.id });
1252
- const { setGameSettings: T } = x.getState(), R = (S) => b.mountSettings(S), b = ri({
1252
+ const { setGameSettings: T } = x.getState(), R = (S) => b.mountSettings(S), b = si({
1253
1253
  load: m,
1254
1254
  el: k,
1255
1255
  ctx: v(),
@@ -1287,8 +1287,8 @@ function Sn({ activity: t, roomKey: e, layer: n }) {
1287
1287
  }
1288
1288
  );
1289
1289
  }
1290
- const si = "drawer-btn";
1291
- function ai({ open: t, onClose: e, header: n, footer: r, children: s }) {
1290
+ const ai = "drawer-btn";
1291
+ function ii({ open: t, onClose: e, header: n, footer: r, children: s }) {
1292
1292
  return L(() => {
1293
1293
  if (!t) return;
1294
1294
  function i(a) {
@@ -1302,7 +1302,7 @@ function ai({ open: t, onClose: e, header: n, footer: r, children: s }) {
1302
1302
  onClick: (i) => i.stopPropagation(),
1303
1303
  children: [
1304
1304
  /* @__PURE__ */ _("div", { className: "p-3 border-b border-border flex items-center gap-2 text-sm", children: [
1305
- /* @__PURE__ */ d("button", { onClick: e, className: si, children: "Close" }),
1305
+ /* @__PURE__ */ d("button", { onClick: e, className: ai, children: "Close" }),
1306
1306
  n
1307
1307
  ] }),
1308
1308
  s,
@@ -1311,43 +1311,43 @@ function ai({ open: t, onClose: e, header: n, footer: r, children: s }) {
1311
1311
  }
1312
1312
  ) }) : null;
1313
1313
  }
1314
- function ii({ open: t, onClose: e }) {
1315
- return /* @__PURE__ */ d(ai, { open: t, onClose: e, children: /* @__PURE__ */ d("div", { className: "px-4 py-3 text-xs text-text-muted", children: "Loading…" }) });
1314
+ function oi({ open: t, onClose: e }) {
1315
+ return /* @__PURE__ */ d(ii, { open: t, onClose: e, children: /* @__PURE__ */ d("div", { className: "px-4 py-3 text-xs text-text-muted", children: "Loading…" }) });
1316
1316
  }
1317
- const gr = 9e3, wn = 1500, oi = {
1317
+ const br = 9e3, xn = 1500, ci = {
1318
1318
  classic: "[text-shadow:_-1px_-1px_0_#000,_1px_-1px_0_#000,_-1px_1px_0_#000,_1px_1px_0_#000,_0_-1px_0_#000,_0_1px_0_#000,_-1px_0_0_#000,_1px_0_0_#000]",
1319
1319
  cinema: "drop-shadow-[0_2px_4px_rgba(0,0,0,0.9)]",
1320
1320
  minimal: "drop-shadow-[0_2px_4px_rgba(0,0,0,0.9)] drop-shadow-[0_0_8px_rgba(0,0,0,0.7)]",
1321
1321
  contrast: "bg-black/70 px-2 py-0.5 rounded"
1322
- }, xn = { WebkitTextStroke: "0.5px black", paintOrder: "stroke fill" }, En = {
1322
+ }, En = { WebkitTextStroke: "0.5px black", paintOrder: "stroke fill" }, Mn = {
1323
1323
  textShadow: "none",
1324
1324
  filter: "drop-shadow(0 0 1px black) drop-shadow(0 0 1px black)"
1325
1325
  };
1326
- function ci({ message: t, age: e, ccStyle: n }) {
1327
- const r = gr - wn;
1326
+ function li({ message: t, age: e, ccStyle: n }) {
1327
+ const r = br - xn;
1328
1328
  let s = 1;
1329
- e > r && (s = Math.max(0, 1 - (e - r) / wn));
1330
- const i = oi[n], a = x((u) => ir(u.roster, t.author)), l = tt(t.sprite, a), o = cr(t.isSystem ? void 0 : t.author), [c] = $(
1331
- () => t.live && t.text ? Hn(t.text, o) : null
1329
+ e > r && (s = Math.max(0, 1 - (e - r) / xn));
1330
+ const i = ci[n], a = x((u) => or(u.roster, t.author)), l = nt(t.sprite, a), o = lr(t.isSystem ? void 0 : t.author), [c] = $(
1331
+ () => t.live && t.text ? Un(t.text, o) : null
1332
1332
  );
1333
1333
  return /* @__PURE__ */ _(
1334
1334
  "div",
1335
1335
  {
1336
1336
  className: `flex items-start gap-2 py-1 ${i}`,
1337
- style: { opacity: s, transition: "opacity 0.15s ease-out", ...lr(l) },
1337
+ style: { opacity: s, transition: "opacity 0.15s ease-out", ...dr(l) },
1338
1338
  children: [
1339
- /* @__PURE__ */ d(dr, { sprite: t.sprite, url: a, worn: o }),
1339
+ /* @__PURE__ */ d(ur, { sprite: t.sprite, url: a, worn: o }),
1340
1340
  /* @__PURE__ */ _("div", { className: "min-w-0 flex-1", children: [
1341
- o ? /* @__PURE__ */ d(ft, { html: Un(t.name, o), className: "text-sm mr-2", style: { color: l, ...En } }) : /* @__PURE__ */ d("span", { className: "font-medium text-sm mr-2", style: { color: l, ...xn }, children: t.name }),
1342
- c ? /* @__PURE__ */ d(ft, { html: c, className: "text-sm text-white break-words", style: En }) : /* @__PURE__ */ d("span", { className: "text-sm text-white break-words", style: xn, children: t.text }),
1343
- /* @__PURE__ */ d(ur, { images: t.images })
1341
+ o ? /* @__PURE__ */ d(ht, { html: jn(t.name, o), className: "text-sm mr-2", style: { color: l, ...Mn } }) : /* @__PURE__ */ d("span", { className: "font-medium text-sm mr-2", style: { color: l, ...En }, children: t.name }),
1342
+ c ? /* @__PURE__ */ d(ht, { html: c, className: "text-sm text-white break-words", style: Mn }) : /* @__PURE__ */ d("span", { className: "text-sm text-white break-words", style: En, children: t.text }),
1343
+ /* @__PURE__ */ d(fr, { images: t.images })
1344
1344
  ] })
1345
1345
  ]
1346
1346
  }
1347
1347
  );
1348
1348
  }
1349
- function li() {
1350
- or();
1349
+ function di() {
1350
+ cr();
1351
1351
  const t = x((f) => f.chat), e = x((f) => f.chatCollapsed), n = x((f) => f.snapshot.mediaId), r = x((f) => f.floatingChatEnabled), s = x((f) => f.mediaPrefs.subtitleStyle), [i, a] = $(!1), [l, o] = $(() => Date.now());
1352
1352
  L(() => {
1353
1353
  const f = () => {
@@ -1362,8 +1362,8 @@ function li() {
1362
1362
  }, 200);
1363
1363
  return () => clearInterval(f);
1364
1364
  }, [c]);
1365
- const u = ya(r, { hasMedia: !!n, chatCollapsed: e, isFullscreen: i }), h = Ee(() => {
1366
- const f = l - gr;
1365
+ const u = va(r, { hasMedia: !!n, chatCollapsed: e, isFullscreen: i }), h = Me(() => {
1366
+ const f = l - br;
1367
1367
  return t.filter((y) => !y.isSystem && y.ts > f).slice(-12);
1368
1368
  }, [t, l]);
1369
1369
  return !u || h.length === 0 ? null : /* @__PURE__ */ d(
@@ -1373,7 +1373,7 @@ function li() {
1373
1373
  style: { bottom: "35%" },
1374
1374
  "data-testid": "floating-chat",
1375
1375
  children: h.map((f) => /* @__PURE__ */ d(
1376
- ci,
1376
+ li,
1377
1377
  {
1378
1378
  message: f,
1379
1379
  age: l - f.ts,
@@ -1384,92 +1384,92 @@ function li() {
1384
1384
  }
1385
1385
  );
1386
1386
  }
1387
- const di = 2;
1388
- function br(t) {
1389
- return t.duration_ms > 0 && t.duration_ms - t.playhead_ms <= Yt;
1390
- }
1387
+ const ui = 2;
1391
1388
  function yr(t) {
1389
+ return t.duration_ms > 0 && t.duration_ms - t.playhead_ms <= Xt;
1390
+ }
1391
+ function vr(t) {
1392
1392
  const e = t.video_ready_state ?? -1;
1393
- return e < 0 ? !0 : !(e <= di && t.buffered_ahead_ms > Yt);
1393
+ return e < 0 ? !0 : !(e <= ui && t.buffered_ahead_ms > Xt);
1394
1394
  }
1395
- function _c(t) {
1396
- return t.playhead_ms === 0 && !t.is_buffering && t.buffered_ahead_ms === 0 ? "idle" : t.is_buffering ? "buffering" : br(t) ? "healthy" : !yr(t) || t.buffered_ahead_ms <= Kn ? "critical" : t.buffered_ahead_ms <= Yt ? "warning" : "healthy";
1395
+ function Ac(t) {
1396
+ return t.playhead_ms === 0 && !t.is_buffering && t.buffered_ahead_ms === 0 ? "idle" : t.is_buffering ? "buffering" : yr(t) ? "healthy" : !vr(t) || t.buffered_ahead_ms <= zn ? "critical" : t.buffered_ahead_ms <= Xt ? "warning" : "healthy";
1397
1397
  }
1398
- const Ac = {
1398
+ const Tc = {
1399
1399
  idle: "Idle",
1400
1400
  buffering: "Buffering",
1401
1401
  critical: "Critical",
1402
1402
  warning: "Low Buffer",
1403
1403
  healthy: "Healthy"
1404
1404
  };
1405
- let bt = null;
1406
- function vr() {
1407
- if (bt) return bt;
1405
+ let yt = null;
1406
+ function Sr() {
1407
+ if (yt) return yt;
1408
1408
  try {
1409
1409
  const t = window.AudioContext ?? window.webkitAudioContext;
1410
- t && (bt = new t());
1410
+ t && (yt = new t());
1411
1411
  } catch {
1412
1412
  }
1413
- return bt;
1413
+ return yt;
1414
1414
  }
1415
- function Sr(t) {
1415
+ function wr(t) {
1416
1416
  t.state === "suspended" && t.resume().catch(() => {
1417
1417
  });
1418
1418
  }
1419
- function wr(t, e, n, r) {
1419
+ function xr(t, e, n, r) {
1420
1420
  t.gain.setValueAtTime(0, e), t.gain.linearRampToValueAtTime(n, e + 5e-3), t.gain.exponentialRampToValueAtTime(1e-4, e + r);
1421
1421
  }
1422
- function We(t, e, n = 0.15, r = 0) {
1423
- const s = vr();
1422
+ function Ve(t, e, n = 0.15, r = 0) {
1423
+ const s = Sr();
1424
1424
  if (!s) return;
1425
- Sr(s);
1425
+ wr(s);
1426
1426
  const i = s.currentTime + r, a = s.createOscillator(), l = s.createGain();
1427
- a.type = "sine", a.frequency.value = t, wr(l, i, n, e / 1e3), a.connect(l).connect(s.destination), a.start(i), a.stop(i + e / 1e3 + 0.05);
1427
+ a.type = "sine", a.frequency.value = t, xr(l, i, n, e / 1e3), a.connect(l).connect(s.destination), a.start(i), a.stop(i + e / 1e3 + 0.05);
1428
1428
  }
1429
- function Nt(t, e, n, r, s = 0.15, i = 0) {
1430
- const a = vr();
1429
+ function Lt(t, e, n, r, s = 0.15, i = 0) {
1430
+ const a = Sr();
1431
1431
  if (!a) return;
1432
- Sr(a);
1432
+ wr(a);
1433
1433
  const l = a.currentTime + i, o = a.createOscillator(), c = a.createOscillator(), u = a.createGain(), h = a.createGain();
1434
- o.type = "sine", o.frequency.value = t, c.type = "sine", c.frequency.value = e, u.gain.value = n * e, c.connect(u).connect(o.frequency), wr(h, l, s, r / 1e3), o.connect(h).connect(a.destination), o.start(l), o.stop(l + r / 1e3 + 0.05), c.start(l), c.stop(l + r / 1e3 + 0.05);
1435
- }
1436
- function xr() {
1437
- We(700, 60, 0.14, 0), We(700, 60, 0.14, 0.1), We(932, 120, 0.17, 0.2);
1434
+ o.type = "sine", o.frequency.value = t, c.type = "sine", c.frequency.value = e, u.gain.value = n * e, c.connect(u).connect(o.frequency), xr(h, l, s, r / 1e3), o.connect(h).connect(a.destination), o.start(l), o.stop(l + r / 1e3 + 0.05), c.start(l), c.stop(l + r / 1e3 + 0.05);
1438
1435
  }
1439
1436
  function Er() {
1440
- We(784, 45, 0.07, 0), We(1047, 60, 0.07, 0.045);
1437
+ Ve(700, 60, 0.14, 0), Ve(700, 60, 0.14, 0.1), Ve(932, 120, 0.17, 0.2);
1441
1438
  }
1442
1439
  function Mr() {
1443
- We(659, 45, 0.06, 0), We(494, 70, 0.06, 0.045);
1440
+ Ve(784, 45, 0.07, 0), Ve(1047, 60, 0.07, 0.045);
1444
1441
  }
1445
1442
  function kr() {
1446
- Nt(587, 1174, 3, 320, 0.12, 0), Nt(880, 1760, 3, 320, 0.12, 0.06), Nt(884, 1768, 3, 320, 0.08, 0.06);
1443
+ Ve(659, 45, 0.06, 0), Ve(494, 70, 0.06, 0.045);
1444
+ }
1445
+ function _r() {
1446
+ Lt(587, 1174, 3, 320, 0.12, 0), Lt(880, 1760, 3, 320, 0.12, 0.06), Lt(884, 1768, 3, 320, 0.08, 0.06);
1447
1447
  }
1448
- zn("__WP_SOUNDS__", {
1449
- start: xr,
1450
- finish: kr,
1451
- on: Er,
1452
- off: Mr
1448
+ Jn("__WP_SOUNDS__", {
1449
+ start: Er,
1450
+ finish: _r,
1451
+ on: Mr,
1452
+ off: kr
1453
1453
  });
1454
- const Mn = { on: 0, off: 0 };
1455
- function ui(t, e, n, r) {
1456
- if (!n || !r) return Mn;
1454
+ const kn = { on: 0, off: 0 };
1455
+ function fi(t, e, n, r) {
1456
+ if (!n || !r) return kn;
1457
1457
  const s = new Set(t), i = new Set(e);
1458
1458
  let a = 0;
1459
1459
  for (const o of i) s.has(o) || a++;
1460
1460
  let l = 0;
1461
1461
  for (const o of s) i.has(o) || l++;
1462
- return a === 0 && l === 0 ? Mn : { on: a, off: l };
1463
- }
1464
- const fi = 1200, be = 52, St = 4, Kt = (be - St) / 2, kn = 2 * Math.PI * Kt, $e = be - St * 2 - 4;
1465
- function hi(t) {
1466
- return br(t) ? !0 : yr(t) ? t.buffered_ahead_ms >= Ce : !1;
1462
+ return a === 0 && l === 0 ? kn : { on: a, off: l };
1467
1463
  }
1464
+ const hi = 1200, be = 52, wt = 4, zt = (be - wt) / 2, _n = 2 * Math.PI * zt, Pe = be - wt * 2 - 4;
1468
1465
  function pi(t) {
1466
+ return yr(t) ? !0 : vr(t) ? t.buffered_ahead_ms >= Re : !1;
1467
+ }
1468
+ function mi(t) {
1469
1469
  return `hsl(${Math.round(t * 120)}, 90%, 55%)`;
1470
1470
  }
1471
- function mi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1472
- const s = Math.min(1, t.buffered_ahead_ms / Ce), i = kn * (1 - s), a = pi(s), l = tt(t.sprite_id, e);
1471
+ function gi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1472
+ const s = Math.min(1, t.buffered_ahead_ms / Re), i = _n * (1 - s), a = mi(s), l = nt(t.sprite_id, e);
1473
1473
  return /* @__PURE__ */ _(
1474
1474
  "div",
1475
1475
  {
@@ -1477,7 +1477,7 @@ function mi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1477
1477
  "data-client-id": t.client_id,
1478
1478
  className: "flex flex-col items-center gap-1",
1479
1479
  style: n ? {
1480
- animation: `bufferFadeOut ${fi}ms ease forwards`
1480
+ animation: `bufferFadeOut ${hi}ms ease forwards`
1481
1481
  } : void 0,
1482
1482
  onAnimationEnd: n ? r : void 0,
1483
1483
  children: [
@@ -1495,10 +1495,10 @@ function mi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1495
1495
  {
1496
1496
  cx: be / 2,
1497
1497
  cy: be / 2,
1498
- r: Kt,
1498
+ r: zt,
1499
1499
  fill: "none",
1500
1500
  stroke: "rgba(255,255,255,0.15)",
1501
- strokeWidth: St
1501
+ strokeWidth: wt
1502
1502
  }
1503
1503
  ),
1504
1504
  /* @__PURE__ */ d(
@@ -1506,12 +1506,12 @@ function mi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1506
1506
  {
1507
1507
  cx: be / 2,
1508
1508
  cy: be / 2,
1509
- r: Kt,
1509
+ r: zt,
1510
1510
  fill: "none",
1511
1511
  stroke: a,
1512
- strokeWidth: St,
1512
+ strokeWidth: wt,
1513
1513
  strokeLinecap: "round",
1514
- strokeDasharray: kn,
1514
+ strokeDasharray: _n,
1515
1515
  strokeDashoffset: i,
1516
1516
  style: { transition: "stroke-dashoffset 0.4s ease, stroke 0.4s ease" }
1517
1517
  }
@@ -1520,18 +1520,18 @@ function mi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1520
1520
  }
1521
1521
  ),
1522
1522
  /* @__PURE__ */ d(
1523
- pt,
1523
+ mt,
1524
1524
  {
1525
1525
  sprite: t.sprite_id,
1526
1526
  url: e,
1527
1527
  alt: t.name,
1528
1528
  className: "rounded-full object-cover flex-shrink-0",
1529
- style: { width: $e, height: $e, border: `2px solid ${l}` },
1529
+ style: { width: Pe, height: Pe, border: `2px solid ${l}` },
1530
1530
  fallback: /* @__PURE__ */ d(
1531
1531
  "div",
1532
1532
  {
1533
1533
  className: "rounded-full bg-bg-alt flex-shrink-0",
1534
- style: { width: $e, height: $e, border: `2px solid ${l}` }
1534
+ style: { width: Pe, height: Pe, border: `2px solid ${l}` }
1535
1535
  }
1536
1536
  )
1537
1537
  }
@@ -1556,8 +1556,8 @@ function mi({ client: t, pictureUrl: e, fading: n, onFadeEnd: r }) {
1556
1556
  }
1557
1557
  );
1558
1558
  }
1559
- function gi({ clientId: t, sprite: e, pictureUrl: n, name: r, isReady: s, isSelf: i, onToggle: a }) {
1560
- const l = tt(e, n), o = s ? "success" : "neutral", c = s ? /* @__PURE__ */ d(ut, { name: "tick" }) : /* @__PURE__ */ d(ut, { name: "hourglass" });
1559
+ function bi({ clientId: t, sprite: e, pictureUrl: n, name: r, isReady: s, isSelf: i, onToggle: a }) {
1560
+ const l = nt(e, n), o = s ? "success" : "neutral", c = s ? /* @__PURE__ */ d(ft, { name: "tick" }) : /* @__PURE__ */ d(ft, { name: "hourglass" });
1561
1561
  return /* @__PURE__ */ _(
1562
1562
  "button",
1563
1563
  {
@@ -1574,18 +1574,18 @@ function gi({ clientId: t, sprite: e, pictureUrl: n, name: r, isReady: s, isSelf
1574
1574
  children: [
1575
1575
  /* @__PURE__ */ _("div", { className: "relative flex items-center justify-center", style: { width: be, height: be }, children: [
1576
1576
  /* @__PURE__ */ d(
1577
- pt,
1577
+ mt,
1578
1578
  {
1579
1579
  sprite: e,
1580
1580
  url: n,
1581
1581
  alt: r,
1582
1582
  className: "rounded-full object-cover flex-shrink-0",
1583
- style: { width: $e, height: $e, border: `2px solid ${l}`, opacity: s ? 1 : 0.55 },
1583
+ style: { width: Pe, height: Pe, border: `2px solid ${l}`, opacity: s ? 1 : 0.55 },
1584
1584
  fallback: /* @__PURE__ */ d(
1585
1585
  "div",
1586
1586
  {
1587
1587
  className: "rounded-full bg-bg-alt flex-shrink-0",
1588
- style: { width: $e, height: $e, border: `2px solid ${l}` }
1588
+ style: { width: Pe, height: Pe, border: `2px solid ${l}` }
1589
1589
  }
1590
1590
  )
1591
1591
  }
@@ -1628,19 +1628,19 @@ function gi({ clientId: t, sprite: e, pictureUrl: n, name: r, isReady: s, isSelf
1628
1628
  }
1629
1629
  );
1630
1630
  }
1631
- const bi = { status: null, entries: [], completed: /* @__PURE__ */ new Set(), below: /* @__PURE__ */ new Set() };
1632
- function _n(t, e) {
1631
+ const yi = { status: null, entries: [], completed: /* @__PURE__ */ new Set(), below: /* @__PURE__ */ new Set() };
1632
+ function An(t, e) {
1633
1633
  if (!e || e.clients.length === 0) return { ...t, status: e, entries: [] };
1634
1634
  const n = new Set(t.completed), r = new Set(t.below), s = [];
1635
1635
  for (const i of e.clients) {
1636
1636
  const a = i.client_id;
1637
- hi(i) ? r.has(a) && !n.has(a) ? (n.add(a), s.push({ client: i, completed: !0 })) : n.has(a) && s.push({ client: i, completed: !0 }) : (n.delete(a), r.add(a), s.push({ client: i, completed: !1 }));
1637
+ pi(i) ? r.has(a) && !n.has(a) ? (n.add(a), s.push({ client: i, completed: !0 })) : n.has(a) && s.push({ client: i, completed: !0 }) : (n.delete(a), r.add(a), s.push({ client: i, completed: !1 }));
1638
1638
  }
1639
1639
  return { status: e, entries: s, completed: n, below: r };
1640
1640
  }
1641
- function yi() {
1642
- const t = x((m) => m.bufferStatus), e = x((m) => m.readyCheck), n = x((m) => m.roster), r = x((m) => m.me.clientId), s = x((m) => m.snapshot.playing), i = nt(), [a, l] = $(() => _n(bi, t));
1643
- a.status !== t && l(_n(a, t));
1641
+ function vi() {
1642
+ const t = x((m) => m.bufferStatus), e = x((m) => m.readyCheck), n = x((m) => m.roster), r = x((m) => m.me.clientId), s = x((m) => m.snapshot.playing), i = rt(), [a, l] = $(() => An(yi, t));
1643
+ a.status !== t && l(An(a, t));
1644
1644
  const o = a.entries, c = (m) => {
1645
1645
  l((T) => {
1646
1646
  const R = new Set(T.completed), b = new Set(T.below);
@@ -1648,19 +1648,19 @@ function yi() {
1648
1648
  });
1649
1649
  }, u = new Set(e.ready), h = Object.values(n), f = !!r && u.has(r), y = e.active && h.length > 0 && e.ready.length >= h.length, g = P(e.active), p = P(y);
1650
1650
  L(() => {
1651
- !g.current && e.active && xr(), g.current = e.active;
1651
+ !g.current && e.active && Er(), g.current = e.active;
1652
1652
  }, [e.active]), L(() => {
1653
- !p.current && y && kr(), p.current = y;
1653
+ !p.current && y && _r(), p.current = y;
1654
1654
  }, [y]);
1655
1655
  const v = P(e.ready), w = P(e.active);
1656
1656
  L(() => {
1657
- const { on: m, off: T } = ui(
1657
+ const { on: m, off: T } = fi(
1658
1658
  v.current,
1659
1659
  e.ready,
1660
1660
  w.current,
1661
1661
  e.active
1662
1662
  );
1663
- m > 0 && Er(), T > 0 && Mr(), v.current = e.ready, w.current = e.active;
1663
+ m > 0 && Mr(), T > 0 && kr(), v.current = e.ready, w.current = e.active;
1664
1664
  }, [e.ready, e.active]);
1665
1665
  const A = e.active, F = !A && o.length > 0, k = !A && !F && i && h.length > 0 && !s;
1666
1666
  return !A && !F && !k ? null : /* @__PURE__ */ _(Se, { children: [
@@ -1693,7 +1693,7 @@ function yi() {
1693
1693
  }
1694
1694
  ),
1695
1695
  /* @__PURE__ */ d("div", { className: "flex flex-col gap-3", children: h.map((m) => /* @__PURE__ */ d(
1696
- gi,
1696
+ bi,
1697
1697
  {
1698
1698
  clientId: m.clientId,
1699
1699
  sprite: m.sprite,
@@ -1701,13 +1701,13 @@ function yi() {
1701
1701
  name: m.name || "Anon",
1702
1702
  isReady: u.has(m.clientId),
1703
1703
  isSelf: m.clientId === r,
1704
- onToggle: () => vs(!f)
1704
+ onToggle: () => Ss(!f)
1705
1705
  },
1706
1706
  m.clientId
1707
1707
  )) })
1708
1708
  ] }),
1709
1709
  F && o.map(({ client: m, completed: T }) => /* @__PURE__ */ d(
1710
- mi,
1710
+ gi,
1711
1711
  {
1712
1712
  client: m,
1713
1713
  pictureUrl: n[m.client_id]?.avatarUrl,
@@ -1721,7 +1721,7 @@ function yi() {
1721
1721
  {
1722
1722
  type: "button",
1723
1723
  "data-testid": "start-ready-check",
1724
- onClick: () => Ss(),
1724
+ onClick: () => ws(),
1725
1725
  className: "px-2.5 py-1 rounded bg-black/55 text-xs font-semibold tracking-wide hover:bg-black/75 transition-colors",
1726
1726
  style: { color: "#fff", pointerEvents: "auto" },
1727
1727
  title: "Ask everyone if they're ready",
@@ -1733,18 +1733,18 @@ function yi() {
1733
1733
  )
1734
1734
  ] });
1735
1735
  }
1736
- const zt = {
1736
+ const Jt = {
1737
1737
  S: "var(--color-tier-s)",
1738
1738
  A: "var(--color-tier-a)",
1739
1739
  B: "var(--color-tier-b)",
1740
1740
  C: "var(--color-tier-c)",
1741
1741
  D: "var(--color-tier-d)",
1742
1742
  F: "var(--color-tier-f)"
1743
- }, Ge = "unranked";
1744
- function _r(t) {
1743
+ }, We = "unranked";
1744
+ function Ar(t) {
1745
1745
  t?.complete && t.naturalWidth > 0 && (t.dataset.loaded = "true");
1746
1746
  }
1747
- function An({
1747
+ function Tn({
1748
1748
  entry: t,
1749
1749
  draggable: e,
1750
1750
  picked: n,
@@ -1771,12 +1771,12 @@ function An({
1771
1771
  /* @__PURE__ */ d(
1772
1772
  "img",
1773
1773
  {
1774
- src: Jn(t.id, t.thumbnail),
1774
+ src: Qn(t.id, t.thumbnail),
1775
1775
  alt: "",
1776
1776
  loading: "eager",
1777
1777
  decoding: "async",
1778
1778
  draggable: !1,
1779
- ref: _r,
1779
+ ref: Ar,
1780
1780
  onLoad: (i) => {
1781
1781
  i.currentTarget.dataset.loaded = "true";
1782
1782
  },
@@ -1791,10 +1791,10 @@ function An({
1791
1791
  }
1792
1792
  );
1793
1793
  }
1794
- function vi({ sprite: t, url: e }) {
1795
- const n = tt(t, e);
1794
+ function Si({ sprite: t, url: e }) {
1795
+ const n = nt(t, e);
1796
1796
  return /* @__PURE__ */ d(
1797
- pt,
1797
+ mt,
1798
1798
  {
1799
1799
  sprite: t,
1800
1800
  url: e,
@@ -1804,7 +1804,7 @@ function vi({ sprite: t, url: e }) {
1804
1804
  }
1805
1805
  );
1806
1806
  }
1807
- function Si({
1807
+ function wi({
1808
1808
  anchor: t,
1809
1809
  itemId: e,
1810
1810
  snap: n
@@ -1820,7 +1820,7 @@ function Si({
1820
1820
  h < 8 && (h = t.bottom + 8), i({ left: Math.round(u), top: Math.round(h) });
1821
1821
  }, [t, e]), !a) return null;
1822
1822
  const l = n.items.find((o) => o.id === e)?.displayName ?? e;
1823
- return wt(
1823
+ return xt(
1824
1824
  /* @__PURE__ */ _(
1825
1825
  "div",
1826
1826
  {
@@ -1831,13 +1831,13 @@ function Si({
1831
1831
  children: [
1832
1832
  /* @__PURE__ */ d("div", { className: "text-[11px] font-semibold text-text leading-snug pb-1.5 mb-1.5 border-b border-border", children: l }),
1833
1833
  Object.entries(a.votes).map(([o, c]) => /* @__PURE__ */ _("div", { className: "flex items-center gap-2 py-0.5", children: [
1834
- /* @__PURE__ */ d(vi, { sprite: n.sprites[o], url: n.pictures?.[o] }),
1834
+ /* @__PURE__ */ d(Si, { sprite: n.sprites[o], url: n.pictures?.[o] }),
1835
1835
  /* @__PURE__ */ d("span", { className: "flex-1 text-[11px] text-text-secondary truncate", children: n.names[o] ?? "viewer" }),
1836
1836
  /* @__PURE__ */ d(
1837
1837
  "span",
1838
1838
  {
1839
1839
  className: "w-5 h-4 grid place-items-center rounded text-[10px] font-bold shrink-0",
1840
- style: { background: zt[c], color: "var(--color-tier-ink)" },
1840
+ style: { background: Jt[c], color: "var(--color-tier-ink)" },
1841
1841
  children: c
1842
1842
  }
1843
1843
  )
@@ -1848,12 +1848,12 @@ function Si({
1848
1848
  document.body
1849
1849
  );
1850
1850
  }
1851
- function wi() {
1851
+ function xi() {
1852
1852
  const t = x((b) => b.tierlistOpen), e = x((b) => b.setTierlistOpen), n = x((b) => b.tierlist), r = x((b) => b.tierlistDraft), s = x((b) => b.tierlistSaving), i = x((b) => b.moveTierlistItem), [a, l] = $(null), [o, c] = $(null), [u, h] = $(null), [f, y] = $(null), [g, p] = $("mine");
1853
1853
  L(() => {
1854
- un(!0);
1854
+ fn(!0);
1855
1855
  }, []), L(() => {
1856
- t && un(!0);
1856
+ t && fn(!0);
1857
1857
  }, [t]), L(() => {
1858
1858
  if (!t) return;
1859
1859
  const b = (S) => {
@@ -1861,14 +1861,14 @@ function wi() {
1861
1861
  };
1862
1862
  return window.addEventListener("keydown", b), () => window.removeEventListener("keydown", b);
1863
1863
  }, [t, e]);
1864
- const v = Ee(() => new Map((n?.items ?? []).map((b) => [b.id, b])), [n]), w = Ee(() => {
1865
- const b = { S: [], A: [], B: [], C: [], D: [], F: [], [Ge]: [] }, S = /* @__PURE__ */ new Set();
1866
- for (const I of It)
1864
+ const v = Me(() => new Map((n?.items ?? []).map((b) => [b.id, b])), [n]), w = Me(() => {
1865
+ const b = { S: [], A: [], B: [], C: [], D: [], F: [], [We]: [] }, S = /* @__PURE__ */ new Set();
1866
+ for (const I of Ct)
1867
1867
  for (const B of r[I] ?? []) {
1868
1868
  const H = v.get(B);
1869
1869
  H && (b[I].push(H), S.add(B));
1870
1870
  }
1871
- for (const I of v.values()) S.has(I.id) || b[Ge].push(I);
1871
+ for (const I of v.values()) S.has(I.id) || b[We].push(I);
1872
1872
  return b;
1873
1873
  }, [r, v]), A = (b, S, I) => {
1874
1874
  const B = [...b.querySelectorAll("article[data-item-id]")].filter((j) => j.dataset.itemId !== I);
@@ -1886,13 +1886,13 @@ function wi() {
1886
1886
  onDrop: (S) => {
1887
1887
  S.preventDefault(), c(null);
1888
1888
  const I = S.dataTransfer.getData("text/plain");
1889
- I && i(I, b === Ge ? null : b, A(S.currentTarget, S.clientX, I));
1889
+ I && i(I, b === We ? null : b, A(S.currentTarget, S.clientX, I));
1890
1890
  },
1891
1891
  onClick: () => {
1892
- a && (i(a, b === Ge ? null : b), l(null));
1892
+ a && (i(a, b === We ? null : b), l(null));
1893
1893
  }
1894
1894
  }), k = U(async () => {
1895
- await ws(x.getState().tierlistDraft) && y(Date.now());
1895
+ await xs(x.getState().tierlistDraft) && y(Date.now());
1896
1896
  }, []);
1897
1897
  if (L(() => {
1898
1898
  if (f === null) return;
@@ -1900,7 +1900,7 @@ function wi() {
1900
1900
  return () => clearTimeout(b);
1901
1901
  }, [f]), !t) return null;
1902
1902
  const m = JSON.stringify(r) !== JSON.stringify(n?.myBoard ?? {}), T = Object.values(n?.myBoard ?? {}).some((b) => (b?.length ?? 0) > 0), R = T ? g : "mine";
1903
- return wt(
1903
+ return xt(
1904
1904
  /* @__PURE__ */ _(
1905
1905
  "div",
1906
1906
  {
@@ -1939,12 +1939,12 @@ function wi() {
1939
1939
  ] }),
1940
1940
  /* @__PURE__ */ _("div", { className: "flex-1 overflow-y-auto", children: [
1941
1941
  R === "mine" && /* @__PURE__ */ _(Se, { children: [
1942
- It.map((b) => /* @__PURE__ */ _("div", { className: "grid grid-cols-[56px_1fr] border-b border-border/50 min-h-[86px]", children: [
1942
+ Ct.map((b) => /* @__PURE__ */ _("div", { className: "grid grid-cols-[56px_1fr] border-b border-border/50 min-h-[86px]", children: [
1943
1943
  /* @__PURE__ */ d(
1944
1944
  "div",
1945
1945
  {
1946
1946
  className: "grid place-items-center select-none cursor-pointer",
1947
- style: { background: zt[b], color: "var(--color-tier-ink)" },
1947
+ style: { background: Jt[b], color: "var(--color-tier-ink)" },
1948
1948
  onClick: () => {
1949
1949
  a && (i(a, b), l(null));
1950
1950
  },
@@ -1958,7 +1958,7 @@ function wi() {
1958
1958
  ...F(b),
1959
1959
  className: `flex items-center gap-2 p-2 overflow-x-auto transition-colors ${o === b ? "bg-primary/15 ring-1 ring-inset ring-primary" : "bg-bg-card"}`,
1960
1960
  children: w[b].map((S) => /* @__PURE__ */ d(
1961
- An,
1961
+ Tn,
1962
1962
  {
1963
1963
  entry: S,
1964
1964
  draggable: !0,
@@ -1974,10 +1974,10 @@ function wi() {
1974
1974
  /* @__PURE__ */ d(
1975
1975
  "div",
1976
1976
  {
1977
- ...F(Ge),
1978
- className: `flex items-center gap-2 p-2 overflow-x-auto min-h-[96px] border-t border-dashed border-border transition-colors ${o === Ge ? "bg-primary/15 ring-1 ring-inset ring-primary" : "bg-bg"}`,
1979
- children: w[Ge].map((b) => /* @__PURE__ */ d(
1980
- An,
1977
+ ...F(We),
1978
+ className: `flex items-center gap-2 p-2 overflow-x-auto min-h-[96px] border-t border-dashed border-border transition-colors ${o === We ? "bg-primary/15 ring-1 ring-inset ring-primary" : "bg-bg"}`,
1979
+ children: w[We].map((b) => /* @__PURE__ */ d(
1980
+ Tn,
1981
1981
  {
1982
1982
  entry: b,
1983
1983
  draggable: !0,
@@ -1990,14 +1990,14 @@ function wi() {
1990
1990
  }
1991
1991
  )
1992
1992
  ] }),
1993
- R === "everyone" && n && /* @__PURE__ */ d(Se, { children: It.map((b) => {
1993
+ R === "everyone" && n && /* @__PURE__ */ d(Se, { children: Ct.map((b) => {
1994
1994
  const S = n.placed.filter((I) => I.tier === b);
1995
1995
  return /* @__PURE__ */ _("div", { className: "grid grid-cols-[56px_1fr] border-b border-border/50 min-h-[86px]", children: [
1996
1996
  /* @__PURE__ */ d(
1997
1997
  "div",
1998
1998
  {
1999
1999
  className: "grid place-items-center select-none",
2000
- style: { background: zt[b], color: "var(--color-tier-ink)" },
2000
+ style: { background: Jt[b], color: "var(--color-tier-ink)" },
2001
2001
  children: /* @__PURE__ */ d("span", { className: "text-2xl font-bold leading-none", children: b })
2002
2002
  }
2003
2003
  ),
@@ -2017,11 +2017,11 @@ function wi() {
2017
2017
  /* @__PURE__ */ d(
2018
2018
  "img",
2019
2019
  {
2020
- src: Jn(I.mediaId, B?.thumbnail),
2020
+ src: Qn(I.mediaId, B?.thumbnail),
2021
2021
  alt: "",
2022
2022
  loading: "eager",
2023
2023
  decoding: "async",
2024
- ref: _r,
2024
+ ref: Ar,
2025
2025
  onLoad: (H) => {
2026
2026
  H.currentTarget.dataset.loaded = "true";
2027
2027
  },
@@ -2047,97 +2047,97 @@ function wi() {
2047
2047
  ]
2048
2048
  }
2049
2049
  ),
2050
- u && n && /* @__PURE__ */ d(Si, { anchor: u.anchor, itemId: u.itemId, snap: n })
2050
+ u && n && /* @__PURE__ */ d(wi, { anchor: u.anchor, itemId: u.itemId, snap: n })
2051
2051
  ]
2052
2052
  }
2053
2053
  ),
2054
2054
  document.body
2055
2055
  );
2056
2056
  }
2057
- function xi({ children: t }) {
2057
+ function Ei({ children: t }) {
2058
2058
  const [e, n] = $(null);
2059
2059
  return L(() => {
2060
2060
  const r = () => n(document.fullscreenElement);
2061
2061
  return r(), document.addEventListener("fullscreenchange", r), () => document.removeEventListener("fullscreenchange", r);
2062
- }, []), e ? wt(t, e) : /* @__PURE__ */ d(Se, { children: t });
2062
+ }, []), e ? xt(t, e) : /* @__PURE__ */ d(Se, { children: t });
2063
2063
  }
2064
- function Tc({ className: t = "w-5 h-5" }) {
2064
+ function Ic({ className: t = "w-5 h-5" }) {
2065
2065
  return /* @__PURE__ */ d("svg", { className: t, fill: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ d("path", { d: "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" }) });
2066
2066
  }
2067
- function Ei({ className: t = "w-5 h-5" }) {
2067
+ function Mi({ className: t = "w-5 h-5" }) {
2068
2068
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ d("path", { d: "M8 5v14l11-7z" }) });
2069
2069
  }
2070
- function Mi({ className: t = "w-5 h-5" }) {
2070
+ function ki({ className: t = "w-5 h-5" }) {
2071
2071
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ d("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }) });
2072
2072
  }
2073
- function ki({ className: t = "w-5 h-5" }) {
2073
+ function _i({ className: t = "w-5 h-5" }) {
2074
2074
  return /* @__PURE__ */ _("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2075
2075
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z" }),
2076
2076
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2" })
2077
2077
  ] });
2078
2078
  }
2079
- function _i({ className: t = "w-5 h-5" }) {
2079
+ function Ai({ className: t = "w-5 h-5" }) {
2080
2080
  return /* @__PURE__ */ _("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2081
2081
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z" }),
2082
2082
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.536 8.464a5 5 0 010 7.072" })
2083
2083
  ] });
2084
2084
  }
2085
- function Ai({ className: t = "w-5 h-5" }) {
2085
+ function Ti({ className: t = "w-5 h-5" }) {
2086
2086
  return /* @__PURE__ */ _("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2087
2087
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z" }),
2088
2088
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.536 8.464a5 5 0 010 7.072M18.364 5.636a9 9 0 010 12.728" })
2089
2089
  ] });
2090
2090
  }
2091
- function Ti({ className: t = "w-5 h-5" }) {
2091
+ function Ii({ className: t = "w-5 h-5" }) {
2092
2092
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) });
2093
2093
  }
2094
- function Ii({ className: t = "w-5 h-5" }) {
2094
+ function Ci({ className: t = "w-5 h-5" }) {
2095
2095
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 9V4H4m0 0l5 5M9 15v5H4m0 0l5-5M15 9V4h5m0 0l-5 5M15 15v5h5m0 0l-5-5" }) });
2096
2096
  }
2097
- function Ci({ className: t = "w-5 h-5" }) {
2097
+ function Ri({ className: t = "w-5 h-5" }) {
2098
2098
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) });
2099
2099
  }
2100
- function Ri({ className: t = "w-5 h-5" }) {
2100
+ function Fi({ className: t = "w-5 h-5" }) {
2101
2101
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
2102
2102
  }
2103
- function Fi({ className: t = "w-4 h-4" }) {
2103
+ function Ni({ className: t = "w-4 h-4" }) {
2104
2104
  return /* @__PURE__ */ _("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2105
2105
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 4v16" }),
2106
2106
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 12l-5 4v-8l5 4z" })
2107
2107
  ] });
2108
2108
  }
2109
- function Ni({ className: t = "w-4 h-4" }) {
2109
+ function Li({ className: t = "w-4 h-4" }) {
2110
2110
  return /* @__PURE__ */ _("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2111
2111
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 4v16" }),
2112
2112
  /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l5 4v-8l-5 4z" })
2113
2113
  ] });
2114
2114
  }
2115
- function Li({ className: t = "w-5 h-5" }) {
2115
+ function $i({ className: t = "w-5 h-5" }) {
2116
2116
  return /* @__PURE__ */ d("svg", { className: t, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M18 6L6 18" }) });
2117
2117
  }
2118
- function $i({ className: t = "w-5 h-5" }) {
2118
+ function Pi({ className: t = "w-5 h-5" }) {
2119
2119
  return /* @__PURE__ */ _("svg", { className: t, viewBox: "0 0 24 24", fill: "currentColor", children: [
2120
2120
  /* @__PURE__ */ d("path", { d: "M12 5l8 11H4z" }),
2121
2121
  /* @__PURE__ */ d("rect", { x: "4", y: "17", width: "16", height: "3", rx: "0.5" })
2122
2122
  ] });
2123
2123
  }
2124
- function Pi({ className: t = "w-5 h-5" }) {
2124
+ function Di({ className: t = "w-5 h-5" }) {
2125
2125
  return /* @__PURE__ */ d("svg", { className: t, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 4v16M17 4v16M3 8h4m10 0h4M3 12h18M3 16h4m10 0h4M4 4h16a1 1 0 011 1v14a1 1 0 01-1 1H4a1 1 0 01-1-1V5a1 1 0 011-1z" }) });
2126
2126
  }
2127
- function Ar({ site: t = "control bar", className: e = "ctr-btn" }) {
2127
+ function Tr({ site: t = "control bar", className: e = "ctr-btn" }) {
2128
2128
  return /* @__PURE__ */ d(
2129
2129
  "button",
2130
2130
  {
2131
- onClick: () => rr(t),
2131
+ onClick: () => sr(t),
2132
2132
  className: e,
2133
2133
  title: "Select Media",
2134
2134
  "aria-label": "Select Media",
2135
- children: /* @__PURE__ */ d(Pi, {})
2135
+ children: /* @__PURE__ */ d(Di, {})
2136
2136
  }
2137
2137
  );
2138
2138
  }
2139
- function Di() {
2140
- const t = x((a) => a.chatCollapsed), e = x((a) => a.toggleChatCollapsed), n = x((a) => !!a.snapshot.mediaId), r = xt(), s = Et({ hasMedia: n, chatCollapsed: t, isFullscreen: r });
2139
+ function Bi() {
2140
+ const t = x((a) => a.chatCollapsed), e = x((a) => a.toggleChatCollapsed), n = x((a) => !!a.snapshot.mediaId), r = Et(), s = Mt({ hasMedia: n, chatCollapsed: t, isFullscreen: r });
2141
2141
  return { panelHidden: s, toggle: () => {
2142
2142
  if (E("chat", s ? "Show chat" : "Hide chat", { isFullscreen: r, chatCollapsed: t }), !s) {
2143
2143
  e();
@@ -2148,8 +2148,8 @@ function Di() {
2148
2148
  });
2149
2149
  } };
2150
2150
  }
2151
- function Tr({ className: t }) {
2152
- const { panelHidden: e, toggle: n } = Di(), r = e ? "Show chat" : "Hide chat";
2151
+ function Ir({ className: t }) {
2152
+ const { panelHidden: e, toggle: n } = Bi(), r = e ? "Show chat" : "Hide chat";
2153
2153
  return /* @__PURE__ */ d(
2154
2154
  "button",
2155
2155
  {
@@ -2159,38 +2159,38 @@ function Tr({ className: t }) {
2159
2159
  title: r,
2160
2160
  "aria-label": r,
2161
2161
  "aria-expanded": !e,
2162
- children: e ? /* @__PURE__ */ d(Ni, { className: "w-5 h-5" }) : /* @__PURE__ */ d(Fi, { className: "w-5 h-5" })
2162
+ children: e ? /* @__PURE__ */ d(Li, { className: "w-5 h-5" }) : /* @__PURE__ */ d(Ni, { className: "w-5 h-5" })
2163
2163
  }
2164
2164
  );
2165
2165
  }
2166
- function Bi() {
2167
- const t = x((u) => u.chatCollapsed), e = x((u) => !!u.snapshot.mediaId), n = xt(), r = Mt(), s = nt(), i = en(), a = Xt({
2166
+ function Oi() {
2167
+ const t = x((u) => u.chatCollapsed), e = x((u) => !!u.snapshot.mediaId), n = Et(), r = kt(), s = rt(), i = tn(), a = Zt({
2168
2168
  isLeader: i,
2169
2169
  hasMedia: e,
2170
2170
  chatCollapsed: t,
2171
2171
  isFullscreen: n,
2172
2172
  gameOverlay: r !== null
2173
- }) === "room-corner", l = s && r !== null && !n, o = ar({ hasMedia: e, isFullscreen: n, gameOverlay: r !== null }) === "room-corner";
2173
+ }) === "room-corner", l = s && r !== null && !n, o = ir({ hasMedia: e, isFullscreen: n, gameOverlay: r !== null }) === "room-corner";
2174
2174
  return !a && !l && !o ? null : /* @__PURE__ */ _("div", { className: "absolute top-2 right-2 z-40 flex items-center gap-2", "data-testid": "room-corner-controls", children: [
2175
- a && /* @__PURE__ */ d(Ar, { site: "room corner", className: "corner-btn" }),
2175
+ a && /* @__PURE__ */ d(Tr, { site: "room corner", className: "corner-btn" }),
2176
2176
  l && /* @__PURE__ */ d("button", { type: "button", onClick: () => {
2177
- E("game", "game_select", { gameId: null, source: "room corner" }), Vn(null);
2178
- }, className: "corner-btn", title: "Stop game", "aria-label": "Stop game", children: /* @__PURE__ */ d(Li, {}) }),
2179
- o && /* @__PURE__ */ d(Tr, { className: "corner-btn" })
2177
+ E("game", "game_select", { gameId: null, source: "room corner" }), Kn(null);
2178
+ }, className: "corner-btn", title: "Stop game", "aria-label": "Stop game", children: /* @__PURE__ */ d($i, {}) }),
2179
+ o && /* @__PURE__ */ d(Ir, { className: "corner-btn" })
2180
2180
  ] });
2181
2181
  }
2182
- function Oi() {
2183
- L(() => xs((t) => {
2184
- const e = Es(t);
2185
- E("avatar", "Avatar changed in the settings popout", { sprite: e, source: t.avatar?.source }), Qn(e);
2182
+ function Hi() {
2183
+ L(() => Es((t) => {
2184
+ const e = Ms(t);
2185
+ E("avatar", "Avatar changed in the settings popout", { sprite: e, source: t.avatar?.source }), qn(e);
2186
2186
  }), []);
2187
2187
  }
2188
- const Ir = [];
2189
- function Tn(t) {
2190
- Ir.push(t);
2188
+ const Cr = [];
2189
+ function In(t) {
2190
+ Cr.push(t);
2191
2191
  }
2192
- function Qe() {
2193
- const t = Ir.splice(0);
2192
+ function qe() {
2193
+ const t = Cr.splice(0);
2194
2194
  for (const e of t)
2195
2195
  try {
2196
2196
  e();
@@ -2198,50 +2198,50 @@ function Qe() {
2198
2198
  C("audio", "audio-unlock callback threw", Y(n));
2199
2199
  }
2200
2200
  }
2201
- let Lt = !1;
2202
- function Hi() {
2203
- return Lt ? () => {
2204
- } : (Lt = !0, document.addEventListener("click", Qe, { capture: !0, passive: !0 }), document.addEventListener("touchend", Qe, { capture: !0, passive: !0 }), document.addEventListener("keydown", Qe, { capture: !0, passive: !0 }), () => {
2205
- document.removeEventListener("click", Qe, { capture: !0 }), document.removeEventListener("touchend", Qe, { capture: !0 }), document.removeEventListener("keydown", Qe, { capture: !0 }), Lt = !1;
2201
+ let $t = !1;
2202
+ function Ui() {
2203
+ return $t ? () => {
2204
+ } : ($t = !0, document.addEventListener("click", qe, { capture: !0, passive: !0 }), document.addEventListener("touchend", qe, { capture: !0, passive: !0 }), document.addEventListener("keydown", qe, { capture: !0, passive: !0 }), () => {
2205
+ document.removeEventListener("click", qe, { capture: !0 }), document.removeEventListener("touchend", qe, { capture: !0 }), document.removeEventListener("keydown", qe, { capture: !0 }), $t = !1;
2206
2206
  });
2207
2207
  }
2208
- const Ui = 400;
2209
- function ji(t) {
2208
+ const ji = 400;
2209
+ function Gi(t) {
2210
2210
  return t === "leader" || t === "viewer" ? t : null;
2211
2211
  }
2212
- async function Gi(t) {
2213
- const e = Ms(), n = await fetch(`${e}/api/rooms/validate/${encodeURIComponent(t)}`);
2212
+ async function Wi(t) {
2213
+ const e = ks(), n = await fetch(`${e}/api/rooms/validate/${encodeURIComponent(t)}`);
2214
2214
  if (n.status === 404) return null;
2215
2215
  if (!n.ok) throw new Error(`validate returned ${n.status}`);
2216
2216
  const r = await n.json();
2217
- return ji(r?.type);
2217
+ return Gi(r?.type);
2218
2218
  }
2219
- async function Wi(t) {
2219
+ async function Vi(t) {
2220
2220
  for (let e = 0; e < 2; e++)
2221
2221
  try {
2222
- const n = await Gi(t);
2222
+ const n = await Wi(t);
2223
2223
  x.getState().setRoomKeyType({ roomKey: t, type: n }), E("room", "Room key type probed", { roomKey: t, type: n });
2224
2224
  return;
2225
2225
  } catch (n) {
2226
2226
  if (e === 0) {
2227
- await new Promise((r) => setTimeout(r, Ui));
2227
+ await new Promise((r) => setTimeout(r, ji));
2228
2228
  continue;
2229
2229
  }
2230
2230
  C("room", "Room key type probe failed, falling back to socket truth", Y(n));
2231
2231
  }
2232
2232
  }
2233
- function Pe(t, e) {
2233
+ function De(t, e) {
2234
2234
  const r = x.getState().allocateClientSeq(), s = { kind: t, client_seq: r, ...e || {} };
2235
- return qn().emit(Yn.CONTROL, s), r;
2236
- }
2237
- function Ic(t) {
2238
- return Pe("load", { media_id: t });
2235
+ return Yn().emit(Xn.CONTROL, s), r;
2239
2236
  }
2240
- function Vi() {
2241
- return Pe("home");
2237
+ function Cc(t) {
2238
+ return De("load", { media_id: t });
2242
2239
  }
2243
2240
  function Ki() {
2244
- const t = Ja(), e = pr(), n = nt(), r = mr(), s = n && r && !e.ready, i = !e.ready && !s;
2241
+ return De("home");
2242
+ }
2243
+ function zi() {
2244
+ const t = Qa(), e = mr(), n = rt(), r = gr(), s = n && r && !e.ready, i = !e.ready && !s;
2245
2245
  return /* @__PURE__ */ d(
2246
2246
  "button",
2247
2247
  {
@@ -2256,18 +2256,18 @@ function Ki() {
2256
2256
  C("controls", "Play/pause click blocked: not ready", { readyCount: e.readyCount, total: e.total });
2257
2257
  return;
2258
2258
  }
2259
- s && C("controls", "Play/pause: leader overriding stuck readiness gate", { readyCount: e.readyCount, total: e.total }), E("controls", "Play/pause clicked", { action: t.playing ? "pause" : "play" }), Pe(t.playing ? "pause" : "play");
2259
+ s && C("controls", "Play/pause: leader overriding stuck readiness gate", { readyCount: e.readyCount, total: e.total }), E("controls", "Play/pause clicked", { action: t.playing ? "pause" : "play" }), De(t.playing ? "pause" : "play");
2260
2260
  },
2261
2261
  className: "ctr-btn",
2262
2262
  title: s ? "Some viewers still loading — play anyway" : i ? "Waiting for sync..." : n ? t.playing ? "Pause" : "Play" : "Only the leader can control playback",
2263
2263
  "data-active": !i && n && t.playing ? "1" : "0",
2264
- children: t.playing ? /* @__PURE__ */ d(Mi, {}) : /* @__PURE__ */ d(Ei, {})
2264
+ children: t.playing ? /* @__PURE__ */ d(ki, {}) : /* @__PURE__ */ d(Mi, {})
2265
2265
  }
2266
2266
  );
2267
2267
  }
2268
- function zi() {
2268
+ function Ji() {
2269
2269
  function t() {
2270
- E("controls", "Unload episode clicked"), Vi();
2270
+ E("controls", "Unload episode clicked"), Ki();
2271
2271
  }
2272
2272
  return /* @__PURE__ */ d(
2273
2273
  "button",
@@ -2276,29 +2276,29 @@ function zi() {
2276
2276
  className: "ctr-btn",
2277
2277
  title: "Unload episode (return to lobby)",
2278
2278
  "aria-label": "Unload episode",
2279
- children: /* @__PURE__ */ d($i, {})
2279
+ children: /* @__PURE__ */ d(Pi, {})
2280
2280
  }
2281
2281
  );
2282
2282
  }
2283
- function Ji(t) {
2283
+ function Qi(t) {
2284
2284
  return !t.isLeader || t.durationMs === 0 ? !0 : !t.ready && !t.canOverride;
2285
2285
  }
2286
- function Qi(t) {
2286
+ function qi(t) {
2287
2287
  return t.localValue !== null ? t.localValue : t.displayPlayheadMs ?? t.snapshotPlayheadMs;
2288
2288
  }
2289
- function qi(t, e) {
2289
+ function Yi(t, e) {
2290
2290
  return e <= 0 ? 0 : t / e;
2291
2291
  }
2292
- function $t(t) {
2292
+ function Pt(t) {
2293
2293
  const e = Math.floor(t / 1e3), n = Math.floor(e / 3600), r = Math.floor(e % 3600 / 60), s = e % 60;
2294
2294
  return n > 0 ? `${n}:${r.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}` : `${r}:${s.toString().padStart(2, "0")}`;
2295
2295
  }
2296
- function Yi({ durationMs: t, displayPlayheadMs: e }) {
2297
- const n = x((S) => S.snapshot), r = x((S) => S.readiness), s = nt(), i = mr(), a = s && i && !r.ready, l = P(null), [o, c] = $(null), [u, h] = $(0), [f, y] = $(!1), [g, p] = $(null), v = P(0), [w, A] = $(n.mediaId);
2296
+ function Xi({ durationMs: t, displayPlayheadMs: e }) {
2297
+ const n = x((S) => S.snapshot), r = x((S) => S.readiness), s = rt(), i = gr(), a = s && i && !r.ready, l = P(null), [o, c] = $(null), [u, h] = $(0), [f, y] = $(!1), [g, p] = $(null), v = P(0), [w, A] = $(n.mediaId);
2298
2298
  w !== n.mediaId && (A(n.mediaId), p(null), y(!1));
2299
2299
  const F = e ?? n.playheadMs;
2300
- !f && g !== null && Math.abs(F - g) < Kn && p(null);
2301
- const k = t || 0, m = Qi({ localValue: g, displayPlayheadMs: e, snapshotPlayheadMs: n.playheadMs }), T = P(0);
2300
+ !f && g !== null && Math.abs(F - g) < zn && p(null);
2301
+ const k = t || 0, m = qi({ localValue: g, displayPlayheadMs: e, snapshotPlayheadMs: n.playheadMs }), T = P(0);
2302
2302
  L(() => {
2303
2303
  if (f || g === null) return;
2304
2304
  const S = 1e4 - (Date.now() - T.current), I = setTimeout(() => {
@@ -2317,7 +2317,7 @@ function Yi({ durationMs: t, displayPlayheadMs: e }) {
2317
2317
  c(null);
2318
2318
  }, []);
2319
2319
  return /* @__PURE__ */ _("div", { className: "flex items-center gap-2 flex-1", children: [
2320
- /* @__PURE__ */ d("span", { className: "text-[11px] font-mono text-text-secondary w-[45px] text-right shrink-0", children: $t(m) }),
2320
+ /* @__PURE__ */ d("span", { className: "text-[11px] font-mono text-text-secondary w-[45px] text-right shrink-0", children: Pt(m) }),
2321
2321
  /* @__PURE__ */ _("div", { className: "flex-1 relative", children: [
2322
2322
  /* @__PURE__ */ d(
2323
2323
  "input",
@@ -2326,8 +2326,8 @@ function Yi({ durationMs: t, displayPlayheadMs: e }) {
2326
2326
  min: 0,
2327
2327
  max: k,
2328
2328
  value: m,
2329
- disabled: Ji({ isLeader: s, ready: r.ready, canOverride: a, durationMs: k }),
2330
- style: { "--progress": `${qi(m, k) * 100}%` },
2329
+ disabled: Qi({ isLeader: s, ready: r.ready, canOverride: a, durationMs: k }),
2330
+ style: { "--progress": `${Yi(m, k) * 100}%` },
2331
2331
  onChange: (S) => {
2332
2332
  const I = Number(S.target.value);
2333
2333
  p(I), T.current = Date.now();
@@ -2336,11 +2336,11 @@ function Yi({ durationMs: t, displayPlayheadMs: e }) {
2336
2336
  y(!0), v.current = e ?? n.playheadMs;
2337
2337
  },
2338
2338
  onMouseUp: () => {
2339
- y(!1), g !== null && g !== v.current && (E("seek", "Final seek on mouseup", { to_ms: g }), Pe("seek", { to_ms: g }), v.current = g);
2339
+ y(!1), g !== null && g !== v.current && (E("seek", "Final seek on mouseup", { to_ms: g }), De("seek", { to_ms: g }), v.current = g);
2340
2340
  },
2341
2341
  onMouseMove: R,
2342
2342
  onMouseLeave: () => {
2343
- b(), f && g !== null && g !== v.current && (y(!1), E("seek", "Final seek on mouseleave-while-dragging", { to_ms: g }), Pe("seek", { to_ms: g }), v.current = g);
2343
+ b(), f && g !== null && g !== v.current && (y(!1), E("seek", "Final seek on mouseleave-while-dragging", { to_ms: g }), De("seek", { to_ms: g }), v.current = g);
2344
2344
  },
2345
2345
  className: "w-full range-fill",
2346
2346
  ref: l,
@@ -2352,14 +2352,14 @@ function Yi({ durationMs: t, displayPlayheadMs: e }) {
2352
2352
  {
2353
2353
  className: "absolute bottom-full mb-2 px-2 py-1 bg-bg-card text-white text-xs rounded pointer-events-none transform -translate-x-1/2 whitespace-nowrap",
2354
2354
  style: { left: o },
2355
- children: $t(u)
2355
+ children: Pt(u)
2356
2356
  }
2357
2357
  )
2358
2358
  ] }),
2359
- /* @__PURE__ */ d("span", { className: "text-[11px] font-mono text-text-muted w-[45px] text-left shrink-0", children: $t(k) })
2359
+ /* @__PURE__ */ d("span", { className: "text-[11px] font-mono text-text-muted w-[45px] text-left shrink-0", children: Pt(k) })
2360
2360
  ] });
2361
2361
  }
2362
- function Xi({ videoRef: t }) {
2362
+ function Zi({ videoRef: t }) {
2363
2363
  const e = x((u) => u.mediaPrefs.volume), n = x((u) => u.mediaPrefs.muted), r = x((u) => u.setVolume), s = x((u) => u.setMuted);
2364
2364
  L(() => {
2365
2365
  const u = t.current;
@@ -2370,7 +2370,7 @@ function Xi({ videoRef: t }) {
2370
2370
  r(h), h > 0 && n && s(!1);
2371
2371
  }, a = () => {
2372
2372
  s(!n);
2373
- }, l = () => n || e === 0 ? /* @__PURE__ */ d(ki, {}) : e < 0.5 ? /* @__PURE__ */ d(_i, {}) : /* @__PURE__ */ d(Ai, {}), o = n ? 0 : e, c = Math.round(o * 100);
2373
+ }, l = () => n || e === 0 ? /* @__PURE__ */ d(_i, {}) : e < 0.5 ? /* @__PURE__ */ d(Ai, {}) : /* @__PURE__ */ d(Ti, {}), o = n ? 0 : e, c = Math.round(o * 100);
2374
2374
  return /* @__PURE__ */ _("div", { className: "flex items-center gap-2", children: [
2375
2375
  /* @__PURE__ */ d(
2376
2376
  "button",
@@ -2403,7 +2403,7 @@ function Xi({ videoRef: t }) {
2403
2403
  ] })
2404
2404
  ] });
2405
2405
  }
2406
- function Zi({
2406
+ function eo({
2407
2407
  tracks: t,
2408
2408
  selectedIndex: e,
2409
2409
  onSelect: n
@@ -2427,7 +2427,7 @@ function Zi({
2427
2427
  )
2428
2428
  ] });
2429
2429
  }
2430
- function eo({
2430
+ function to({
2431
2431
  tracks: t,
2432
2432
  selectedIndex: e,
2433
2433
  onSelect: n,
@@ -2464,13 +2464,13 @@ function eo({
2464
2464
  )
2465
2465
  ] });
2466
2466
  }
2467
- const to = [
2467
+ const no = [
2468
2468
  { value: "classic", label: "Classic" },
2469
2469
  { value: "cinema", label: "Cinema" },
2470
2470
  { value: "minimal", label: "Minimal" },
2471
2471
  { value: "contrast", label: "High Contrast" }
2472
2472
  ];
2473
- function no({ style: t, onStyleChange: e, enabled: n }) {
2473
+ function ro({ style: t, onStyleChange: e, enabled: n }) {
2474
2474
  return n ? /* @__PURE__ */ _("div", { className: "flex items-center gap-2", children: [
2475
2475
  /* @__PURE__ */ d("span", { className: "text-[10px] opacity-60 uppercase tracking-wide", children: "Style" }),
2476
2476
  /* @__PURE__ */ d(
@@ -2481,12 +2481,12 @@ function no({ style: t, onStyleChange: e, enabled: n }) {
2481
2481
  className: "text-xs rounded px-2 py-1 cursor-pointer",
2482
2482
  title: "Select subtitle style",
2483
2483
  "aria-label": "Subtitle style selection",
2484
- children: to.map((r) => /* @__PURE__ */ d("option", { value: r.value, children: r.label }, r.value))
2484
+ children: no.map((r) => /* @__PURE__ */ d("option", { value: r.value, children: r.label }, r.value))
2485
2485
  }
2486
2486
  )
2487
2487
  ] }) : null;
2488
2488
  }
2489
- function ro({ videoRef: t }) {
2489
+ function so({ videoRef: t }) {
2490
2490
  const [e, n] = $(!1);
2491
2491
  L(() => {
2492
2492
  const s = () => {
@@ -2516,11 +2516,11 @@ function ro({ videoRef: t }) {
2516
2516
  },
2517
2517
  className: "ctr-btn",
2518
2518
  title: e ? "Exit Fullscreen" : "Enter Fullscreen",
2519
- children: e ? /* @__PURE__ */ d(Ii, {}) : /* @__PURE__ */ d(Ti, {})
2519
+ children: e ? /* @__PURE__ */ d(Ci, {}) : /* @__PURE__ */ d(Ii, {})
2520
2520
  }
2521
2521
  );
2522
2522
  }
2523
- function so({
2523
+ function ao({
2524
2524
  videoRef: t,
2525
2525
  mediaId: e,
2526
2526
  durationMs: n,
@@ -2539,25 +2539,25 @@ function so({
2539
2539
  onChatActivity: p,
2540
2540
  onMenuHeld: v
2541
2541
  }) {
2542
- const w = nt(), A = x((z) => z.chatCollapsed), F = xt(), k = en(), m = Mt() !== null, T = Xt({
2542
+ const w = rt(), A = x((z) => z.chatCollapsed), F = Et(), k = tn(), m = kt() !== null, T = Zt({
2543
2543
  isLeader: k,
2544
2544
  hasMedia: !0,
2545
2545
  chatCollapsed: A,
2546
2546
  isFullscreen: F,
2547
2547
  gameOverlay: m
2548
- }) === "control-bar", R = ar({ hasMedia: !0, isFullscreen: F, gameOverlay: m }) === "control-bar", b = x((z) => z.floatingChatEnabled), S = P(null), I = P(null), [B, H] = $(!1), [j, K] = $(!1), [X, N] = $(""), [O, Q] = $(!1), W = hr(), [re, le] = $(!1), [Re, Ke] = $(!1), kt = U(async (z) => {
2548
+ }) === "control-bar", R = ir({ hasMedia: !0, isFullscreen: F, gameOverlay: m }) === "control-bar", b = x((z) => z.floatingChatEnabled), S = P(null), I = P(null), [B, H] = $(!1), [j, K] = $(!1), [X, N] = $(""), [O, Q] = $(!1), W = pr(), [re, le] = $(!1), [Fe, ze] = $(!1), _t = U(async (z) => {
2549
2549
  if (z.key !== "Enter") return;
2550
2550
  const he = X.trim();
2551
2551
  if (!he && !W.pending.length || O || W.uploading) return;
2552
- const Me = await W.uploadPending();
2553
- Me !== null && (jn(he, Me), N(""), W.clear(), Q(!0), setTimeout(() => Q(!1), Gn), !document.hidden && document.hasFocus() && I.current?.focus());
2552
+ const ke = await W.uploadPending();
2553
+ ke !== null && (Gn(he, ke), N(""), W.clear(), Q(!0), setTimeout(() => Q(!1), Wn), !document.hidden && document.hasFocus() && I.current?.focus());
2554
2554
  }, [X, O, W]);
2555
2555
  L(() => () => v?.(!1), [e, v]);
2556
- const De = r ?? !0, ye = U(() => {
2556
+ const Be = r ?? !0, ye = U(() => {
2557
2557
  const z = S.current;
2558
2558
  if (!z) return;
2559
- const { scrollLeft: he, scrollWidth: Me, clientWidth: _t } = z;
2560
- H(he > 5), K(he + _t < Me - 5);
2559
+ const { scrollLeft: he, scrollWidth: ke, clientWidth: At } = z;
2560
+ H(he > 5), K(he + At < ke - 5);
2561
2561
  }, []);
2562
2562
  L(() => {
2563
2563
  const z = S.current;
@@ -2567,22 +2567,22 @@ function so({
2567
2567
  return he.observe(z), () => {
2568
2568
  z.removeEventListener("scroll", ye), he.disconnect();
2569
2569
  };
2570
- }, [ye, De]);
2571
- const Be = U((z) => {
2570
+ }, [ye, Be]);
2571
+ const Oe = U((z) => {
2572
2572
  const he = S.current;
2573
2573
  if (!he) return;
2574
- const Me = z === "left" ? -200 : 200;
2575
- he.scrollBy({ left: Me, behavior: "smooth" });
2574
+ const ke = z === "left" ? -200 : 200;
2575
+ he.scrollBy({ left: ke, behavior: "smooth" });
2576
2576
  }, []);
2577
2577
  if (!e) return null;
2578
2578
  const we = [
2579
2579
  "ctr-bar",
2580
- De && "show"
2581
- ].filter(Boolean).join(" "), rt = B || j;
2580
+ Be && "show"
2581
+ ].filter(Boolean).join(" "), st = B || j;
2582
2582
  return /* @__PURE__ */ _(
2583
2583
  "div",
2584
2584
  {
2585
- className: `ctr-bar-wrapper ${De ? "show" : ""}`,
2585
+ className: `ctr-bar-wrapper ${Be ? "show" : ""}`,
2586
2586
  onFocus: (z) => {
2587
2587
  z.target instanceof HTMLSelectElement && v?.(!0);
2588
2588
  },
@@ -2595,18 +2595,18 @@ function so({
2595
2595
  children: [
2596
2596
  /* @__PURE__ */ _("div", { ref: S, className: we, children: [
2597
2597
  w && /* @__PURE__ */ _("div", { className: "cluster", children: [
2598
- /* @__PURE__ */ d(Ki, {}),
2599
- T && /* @__PURE__ */ d(Ar, {}),
2600
- /* @__PURE__ */ d(zi, {})
2598
+ /* @__PURE__ */ d(zi, {}),
2599
+ T && /* @__PURE__ */ d(Tr, {}),
2600
+ /* @__PURE__ */ d(Ji, {})
2601
2601
  ] }),
2602
- /* @__PURE__ */ d("div", { className: "cluster-seek", children: /* @__PURE__ */ d(Yi, { durationMs: n, displayPlayheadMs: g }) }),
2602
+ /* @__PURE__ */ d("div", { className: "cluster-seek", children: /* @__PURE__ */ d(Xi, { durationMs: n, displayPlayheadMs: g }) }),
2603
2603
  /* @__PURE__ */ _("div", { className: "cluster", children: [
2604
- /* @__PURE__ */ d(Xi, { videoRef: t }),
2604
+ /* @__PURE__ */ d(Zi, { videoRef: t }),
2605
2605
  s.length > 1 && /* @__PURE__ */ _(Se, { children: [
2606
2606
  /* @__PURE__ */ d("div", { className: "w-px h-5 bg-white/20" }),
2607
2607
  " ",
2608
2608
  /* @__PURE__ */ d(
2609
- Zi,
2609
+ eo,
2610
2610
  {
2611
2611
  tracks: s,
2612
2612
  selectedIndex: i,
@@ -2617,7 +2617,7 @@ function so({
2617
2617
  ] }),
2618
2618
  l.length > 0 && /* @__PURE__ */ _("div", { className: "cluster", children: [
2619
2619
  /* @__PURE__ */ d(
2620
- eo,
2620
+ to,
2621
2621
  {
2622
2622
  tracks: l,
2623
2623
  selectedIndex: o,
@@ -2627,7 +2627,7 @@ function so({
2627
2627
  }
2628
2628
  ),
2629
2629
  /* @__PURE__ */ d(
2630
- no,
2630
+ ro,
2631
2631
  {
2632
2632
  style: f,
2633
2633
  onStyleChange: y,
@@ -2643,15 +2643,15 @@ function so({
2643
2643
  onDrop: W.onDrop,
2644
2644
  onDragOver: W.onDragOver,
2645
2645
  children: [
2646
- /* @__PURE__ */ d(fr, { pending: W.pending, uploading: W.uploading, onRemove: W.remove }),
2646
+ /* @__PURE__ */ d(hr, { pending: W.pending, uploading: W.uploading, onRemove: W.remove }),
2647
2647
  /* @__PURE__ */ d(
2648
- nr,
2648
+ rr,
2649
2649
  {
2650
2650
  open: re,
2651
2651
  onClose: () => le(!1),
2652
2652
  onPick: W.addMeme,
2653
2653
  onUnavailable: () => {
2654
- Ke(!0), le(!1);
2654
+ ze(!0), le(!1);
2655
2655
  }
2656
2656
  }
2657
2657
  ),
@@ -2662,17 +2662,17 @@ function so({
2662
2662
  type: "text",
2663
2663
  value: X,
2664
2664
  onChange: (z) => {
2665
- N(z.target.value.slice(0, Wn)), p?.();
2665
+ N(z.target.value.slice(0, Vn)), p?.();
2666
2666
  },
2667
2667
  onKeyDown: (z) => {
2668
- kt(z);
2668
+ _t(z);
2669
2669
  },
2670
2670
  placeholder: "Message...",
2671
2671
  className: "bg-transparent border-none outline-none text-sm max-w-[240px] w-48 h-7 px-2",
2672
2672
  style: { color: "var(--color-chip-text)" }
2673
2673
  }
2674
2674
  ),
2675
- !Re && /* @__PURE__ */ d(
2675
+ !Fe && /* @__PURE__ */ d(
2676
2676
  "button",
2677
2677
  {
2678
2678
  type: "button",
@@ -2682,34 +2682,34 @@ function so({
2682
2682
  title: "Add a meme",
2683
2683
  "data-testid": "meme-button-inline",
2684
2684
  className: `shrink-0 px-1 ${re ? "text-text" : "text-text-secondary"} hover:text-text`,
2685
- children: /* @__PURE__ */ d(ut, { name: "image" })
2685
+ children: /* @__PURE__ */ d(ft, { name: "image" })
2686
2686
  }
2687
2687
  )
2688
2688
  ]
2689
2689
  }
2690
2690
  ),
2691
2691
  /* @__PURE__ */ _("div", { className: "cluster cluster-tight", children: [
2692
- R && /* @__PURE__ */ d(Tr, { className: "ctr-btn" }),
2693
- /* @__PURE__ */ d(ro, { videoRef: t })
2692
+ R && /* @__PURE__ */ d(Ir, { className: "ctr-btn" }),
2693
+ /* @__PURE__ */ d(so, { videoRef: t })
2694
2694
  ] })
2695
2695
  ] }),
2696
- rt && /* @__PURE__ */ _("div", { className: "ctr-scroll-group", children: [
2696
+ st && /* @__PURE__ */ _("div", { className: "ctr-scroll-group", children: [
2697
2697
  /* @__PURE__ */ d(
2698
2698
  "button",
2699
2699
  {
2700
2700
  className: `ctr-scroll-btn ${B ? "visible" : ""}`,
2701
- onClick: () => Be("left"),
2701
+ onClick: () => Oe("left"),
2702
2702
  "aria-label": "Scroll left",
2703
- children: /* @__PURE__ */ d(Ci, {})
2703
+ children: /* @__PURE__ */ d(Ri, {})
2704
2704
  }
2705
2705
  ),
2706
2706
  /* @__PURE__ */ d(
2707
2707
  "button",
2708
2708
  {
2709
2709
  className: `ctr-scroll-btn ${j ? "visible" : ""}`,
2710
- onClick: () => Be("right"),
2710
+ onClick: () => Oe("right"),
2711
2711
  "aria-label": "Scroll right",
2712
- children: /* @__PURE__ */ d(Ri, {})
2712
+ children: /* @__PURE__ */ d(Fi, {})
2713
2713
  }
2714
2714
  )
2715
2715
  ] })
@@ -2717,45 +2717,50 @@ function so({
2717
2717
  }
2718
2718
  );
2719
2719
  }
2720
- const ao = 1e3;
2721
- function io(t) {
2722
- return t.hidden && t.roomPlaying && !t.seekInFlight && !t.ended && !t.localPause && t.sinceUserPauseMs >= ao;
2720
+ const io = 1e3;
2721
+ function oo(t) {
2722
+ return t.hidden && t.roomPlaying && !t.seekInFlight && !t.ended && !t.localPause && t.sinceUserPauseMs >= io;
2723
2723
  }
2724
- function oo(t, e) {
2724
+ function co(t, e) {
2725
2725
  return e.isLeader ? t === "play" && e.roomPlaying ? { kind: "resync" } : t === "pause" && !e.roomPlaying ? { kind: "none" } : { kind: "control", control: t } : t === "pause" ? { kind: "local-pause" } : e.roomPlaying ? { kind: "resync" } : { kind: "none" };
2726
2726
  }
2727
- const co = 1e3;
2728
- function lo(t) {
2727
+ const lo = 1e3;
2728
+ function uo(t) {
2729
2729
  if (!t.roomPlaying || t.seekInFlight) return { kind: "none" };
2730
2730
  const e = t.durationMs > 0 ? Math.min(t.roomMs, t.durationMs) : t.roomMs;
2731
2731
  return Math.abs(e - t.elementMs) > t.driftToleranceMs ? { kind: "seek", targetMs: Math.round(e) } : t.elementPaused ? { kind: "resume" } : { kind: "none" };
2732
2732
  }
2733
- function uo(t, e, n) {
2733
+ function fo(t, e, n) {
2734
2734
  return t.playheadMs + (t.playing ? Math.max(0, n - e) : 0);
2735
2735
  }
2736
- function Cr(t) {
2736
+ function Rr(t) {
2737
2737
  const e = t.split("/").filter(Boolean);
2738
2738
  return e.length >= 2 ? e.slice(-2).join(" ") : e[e.length - 1] || t;
2739
2739
  }
2740
- function fo(t) {
2740
+ function ho(t) {
2741
2741
  const e = t.split("/").filter(Boolean), n = [`${e.join("/")}/poster.jpg`];
2742
2742
  return e.length >= 2 && n.push(`${e.slice(0, -1).join("/")}/poster.jpg`), n;
2743
2743
  }
2744
- function ho({ mediaId: t, visible: e }) {
2745
- return t ? /* @__PURE__ */ d("div", { className: `media-title ${e ? "show" : ""}`, children: Cr(t) }) : null;
2744
+ function po({ mediaId: t, visible: e }) {
2745
+ return t ? /* @__PURE__ */ d("div", { className: `media-title ${e ? "show" : ""}`, children: Rr(t) }) : null;
2746
+ }
2747
+ const Ye = 3, mo = 1e3, go = 15e3;
2748
+ function Ee(t) {
2749
+ const e = t?.readyState;
2750
+ return e === "open" || e === "ended";
2746
2751
  }
2747
- const qe = 3, po = 1e3, mo = 15e3, Z = {
2752
+ const Z = {
2748
2753
  EQUAL: 1e-3,
2749
2754
  POINT: 0.05,
2750
2755
  RANGE: 0.1,
2751
2756
  FALLBACK: 1
2752
- }, Pt = 0.5, Dt = 3e3;
2753
- function ct(t, e = {}) {
2754
- const { baseMs: n = po, capMs: r = mo, jitter: s = 0.25 } = e, i = Math.min(n * Math.pow(2, t - 1), r), a = s > 0 ? Math.round(i * Math.random() * s) : 0;
2757
+ }, Dt = 0.5, Bt = 3e3;
2758
+ function lt(t, e = {}) {
2759
+ const { baseMs: n = mo, capMs: r = go, jitter: s = 0.25 } = e, i = Math.min(n * Math.pow(2, t - 1), r), a = s > 0 ? Math.round(i * Math.random() * s) : 0;
2755
2760
  return i + a;
2756
2761
  }
2757
- const In = 15, go = 35e3, bo = 2e3, Bt = 10;
2758
- function Ie(t, e) {
2762
+ const Cn = 15, bo = 35e3, yo = 2e3, Ot = 10;
2763
+ function Ce(t, e) {
2759
2764
  if (t.length === 0) return 0;
2760
2765
  if (e >= t[t.length - 1].end_ms) return t.length - 1;
2761
2766
  let n = 0, r = t.length - 1;
@@ -2765,8 +2770,8 @@ function Ie(t, e) {
2765
2770
  }
2766
2771
  return n;
2767
2772
  }
2768
- function tn(t, e) {
2769
- const n = Ie(t, e);
2773
+ function nn(t, e) {
2774
+ const n = Ce(t, e);
2770
2775
  if (t.length === 0 || t[0].keyframe === void 0) return n;
2771
2776
  for (let r = n; r >= 0; r--)
2772
2777
  if (t[r].keyframe) return r;
@@ -2774,12 +2779,12 @@ function tn(t, e) {
2774
2779
  if (t[r].keyframe) return r;
2775
2780
  return n;
2776
2781
  }
2777
- function Ye(t, e, n = Z.POINT) {
2782
+ function Xe(t, e, n = Z.POINT) {
2778
2783
  for (let r = 0; r < t.length; r++)
2779
2784
  if (e >= t.start(r) - n && e <= t.end(r)) return r;
2780
2785
  return -1;
2781
2786
  }
2782
- function Ot(t, e, n, r = Z.RANGE) {
2787
+ function Ht(t, e, n, r = Z.RANGE) {
2783
2788
  const s = e / 1e3, i = n / 1e3;
2784
2789
  for (let a = 0; a < t.length; a++)
2785
2790
  if (t.start(a) < i + r && t.end(a) > s - r) return !0;
@@ -2788,23 +2793,23 @@ function Ot(t, e, n, r = Z.RANGE) {
2788
2793
  function ge(t) {
2789
2794
  return t ? Array.from({ length: t.length }, (e, n) => `${t.start(n).toFixed(2)}-${t.end(n).toFixed(2)}`) : [];
2790
2795
  }
2791
- function yo(t) {
2796
+ function vo(t) {
2792
2797
  if (t.length === 0) return 0;
2793
2798
  const e = t.reduce((r, s) => r + s.bytes, 0), n = t.reduce((r, s) => r + s.durationMs, 0);
2794
2799
  return n === 0 ? 0 : e / n * 1e3;
2795
2800
  }
2796
- const vo = 8e5, So = 4;
2797
- function ot(t) {
2801
+ const So = 8e5, wo = 4;
2802
+ function ct(t) {
2798
2803
  if (t === 0) return 6e4;
2799
- const e = vo / t * 1e3 * So;
2804
+ const e = So / t * 1e3 * wo;
2800
2805
  return Math.max(3e4, Math.min(12e4, Math.round(e)));
2801
2806
  }
2802
- function Cn(t, e) {
2807
+ function Rn(t, e) {
2803
2808
  for (let n = e; n >= 0; n--)
2804
2809
  if (t[n]?.keyframe) return n;
2805
2810
  return -1;
2806
2811
  }
2807
- function wo(t, e, n, r) {
2812
+ function xo(t, e, n, r) {
2808
2813
  const s = t * 1e3 - 100, i = e * 1e3 + 100;
2809
2814
  for (const a of r) {
2810
2815
  const l = n[a];
@@ -2813,7 +2818,7 @@ function wo(t, e, n, r) {
2813
2818
  }
2814
2819
  return !1;
2815
2820
  }
2816
- function xo(t) {
2821
+ function Eo(t) {
2817
2822
  const e = [], n = t.replace(/\r\n/g, `
2818
2823
  `).split(`
2819
2824
  `);
@@ -2823,7 +2828,7 @@ function xo(t) {
2823
2828
  for (; r < n.length; ) {
2824
2829
  const s = n[r].trim();
2825
2830
  if (s.includes("-->")) {
2826
- const i = s.split("-->"), a = Rn(i[0].trim()), l = i[1].trim().split(/\s+/), o = Rn(l[0]);
2831
+ const i = s.split("-->"), a = Fn(i[0].trim()), l = i[1].trim().split(/\s+/), o = Fn(l[0]);
2827
2832
  let c, u, h;
2828
2833
  for (let y = 1; y < l.length; y++) {
2829
2834
  const g = l[y];
@@ -2862,16 +2867,16 @@ function xo(t) {
2862
2867
  }
2863
2868
  return e;
2864
2869
  }
2865
- function Rn(t) {
2870
+ function Fn(t) {
2866
2871
  const e = t.split(":");
2867
2872
  if (e.length < 2) return null;
2868
2873
  let n = 0, r, s;
2869
2874
  return e.length === 3 ? (n = parseInt(e[0], 10), r = parseInt(e[1], 10), s = parseFloat(e[2])) : (r = parseInt(e[0], 10), s = parseFloat(e[1])), isNaN(n) || isNaN(r) || isNaN(s) ? null : n * 3600 + r * 60 + s;
2870
2875
  }
2871
- function Eo(t) {
2876
+ function Mo(t) {
2872
2877
  return t.replace(/<\/?[^>]+(>|$)/g, "").replace(/\{[^}]+\}/g, "").replace(/\\N/g, " ").replace(/\s*\n\s*/g, " ").replace(/\s{2,}/g, " ").trim();
2873
2878
  }
2874
- const Mo = {
2879
+ const ko = {
2875
2880
  // Standard CC look: white text with thick black outline stroke
2876
2881
  classic: "text-white [text-shadow:_-2px_-2px_0_#000,_2px_-2px_0_#000,_-2px_2px_0_#000,_2px_2px_0_#000,_0_-2px_0_#000,_0_2px_0_#000,_-2px_0_0_#000,_2px_0_0_#000]",
2877
2882
  // DVD/theater style: yellow text on dark translucent box
@@ -2881,7 +2886,7 @@ const Mo = {
2881
2886
  // Accessibility-focused: bold white text on solid black box
2882
2887
  contrast: "text-white font-bold bg-black px-3 py-1"
2883
2888
  };
2884
- function ko({ subtitleUrl: t, videoRef: e, style: n, enabled: r }) {
2889
+ function _o({ subtitleUrl: t, videoRef: e, style: n, enabled: r }) {
2885
2890
  const [s, i] = $([]), [a, l] = $([]), o = P(null), [c, u] = $(40), [h, f] = $(18), [y, g] = $(t);
2886
2891
  y !== t && (g(t), t || i([])), L(() => {
2887
2892
  if (!t) return;
@@ -2895,13 +2900,13 @@ function ko({ subtitleUrl: t, videoRef: e, style: n, enabled: r }) {
2895
2900
  if (!b.ok) throw new Error(`Failed to fetch subtitles (status ${b.status})`);
2896
2901
  const S = await b.text();
2897
2902
  if (m) return;
2898
- const I = xo(S);
2903
+ const I = Eo(S);
2899
2904
  i(I);
2900
2905
  return;
2901
2906
  } catch (b) {
2902
2907
  if (m) return;
2903
2908
  if (R < T) {
2904
- const S = ct(R + 1, { baseMs: 1e3, capMs: 2e3, jitter: 0 });
2909
+ const S = lt(R + 1, { baseMs: 1e3, capMs: 2e3, jitter: 0 });
2905
2910
  C("subtitles", `Fetch failed, retrying in ${S}ms (attempt ${R + 1}/${T + 1})`, { error: b?.message }), await new Promise((I) => setTimeout(I, S));
2906
2911
  } else
2907
2912
  C("subtitles", "All fetch attempts failed", { error: b?.message }), i([]);
@@ -2965,8 +2970,8 @@ function ko({ subtitleUrl: t, videoRef: e, style: n, enabled: r }) {
2965
2970
  children: /* @__PURE__ */ d(
2966
2971
  "div",
2967
2972
  {
2968
- className: `${R} font-medium max-w-[95%] inline-block antialiased ${Mo[n]}`,
2969
- children: Eo(b.text)
2973
+ className: `${R} font-medium max-w-[95%] inline-block antialiased ${ko[n]}`,
2974
+ children: Mo(b.text)
2970
2975
  }
2971
2976
  )
2972
2977
  },
@@ -3003,28 +3008,28 @@ function ko({ subtitleUrl: t, videoRef: e, style: n, enabled: r }) {
3003
3008
  k(A.bl, A.bc, A.br, { bottom: `${c}px` }, o)
3004
3009
  ] });
3005
3010
  }
3006
- const _o = 300, Ao = 50, To = 100, Io = 100, Co = 100, Ro = 100;
3007
- function Ht(t, e) {
3011
+ const Ao = 300, To = 50, Io = 100, Co = 100, Ro = 100, Fo = 100;
3012
+ function Ut(t, e) {
3008
3013
  if (t.length === 0) return 0;
3009
3014
  const n = Math.min(Math.floor(e / 100 * t.length), t.length - 1);
3010
3015
  return t[n];
3011
3016
  }
3012
- function Ne(t) {
3017
+ function Le(t) {
3013
3018
  if (t.length === 0) return { count: 0, mean: 0, p50: 0, p90: 0, p99: 0, max: 0 };
3014
3019
  const e = [...t].sort((r, s) => r - s), n = e.reduce((r, s) => r + s, 0);
3015
3020
  return {
3016
3021
  count: e.length,
3017
3022
  mean: Math.round(n / e.length),
3018
- p50: Math.round(Ht(e, 50)),
3019
- p90: Math.round(Ht(e, 90)),
3020
- p99: Math.round(Ht(e, 99)),
3023
+ p50: Math.round(Ut(e, 50)),
3024
+ p90: Math.round(Ut(e, 90)),
3025
+ p99: Math.round(Ut(e, 99)),
3021
3026
  max: Math.round(e[e.length - 1])
3022
3027
  };
3023
3028
  }
3024
- function Le(t, e = _o) {
3029
+ function $e(t, e = Ao) {
3025
3030
  t.length > e && t.splice(0, t.length - e);
3026
3031
  }
3027
- class Fo {
3032
+ class No {
3028
3033
  // Fetch
3029
3034
  _fetches = [];
3030
3035
  _fetchTimeoutCount = 0;
@@ -3052,7 +3057,7 @@ class Fo {
3052
3057
  // ── Recording API ─────────────────────────────────────────────────────────
3053
3058
  /** Called on every successful fragment fetch. */
3054
3059
  recordFetch(e, n, r) {
3055
- this._fetches.push({ index: e, bytes: n, durationMs: r, ts: performance.now() }), Le(this._fetches);
3060
+ this._fetches.push({ index: e, bytes: n, durationMs: r, ts: performance.now() }), $e(this._fetches);
3056
3061
  }
3057
3062
  /** Called when a fetch times out (before retry). */
3058
3063
  recordFetchTimeout(e) {
@@ -3078,15 +3083,15 @@ class Fo {
3078
3083
  queueDepth: n.queueDepth,
3079
3084
  latencyMs: performance.now() - n.time,
3080
3085
  ts: performance.now()
3081
- }), Le(this._appends));
3086
+ }), $e(this._appends));
3082
3087
  }
3083
3088
  /** Called when waitForAppend times out. */
3084
3089
  recordAppendTimeout(e, n, r) {
3085
- this._appendTimeouts.push({ index: e, timeoutMs: n, queueDepth: r, ts: performance.now() }), Le(this._appendTimeouts, Ao);
3090
+ this._appendTimeouts.push({ index: e, timeoutMs: n, queueDepth: r, ts: performance.now() }), $e(this._appendTimeouts, To);
3086
3091
  }
3087
3092
  /** Called when a seek completes (COMPLETED path in _execute). */
3088
3093
  recordSeekCompleted(e, n, r) {
3089
- this._seeks.push({ caller: e, targetMs: n, durationMs: r, ts: performance.now() }), Le(this._seeks, To);
3094
+ this._seeks.push({ caller: e, targetMs: n, durationMs: r, ts: performance.now() }), $e(this._seeks, Io);
3090
3095
  }
3091
3096
  /** Called when waitForSeeked resolves via timeout rather than the 'seeked' event. */
3092
3097
  recordWaitForSeekedTimeout() {
@@ -3097,7 +3102,7 @@ class Fo {
3097
3102
  * after both elements have started playing, not at the sync assignment moment.
3098
3103
  */
3099
3104
  recordAudioDrift(e) {
3100
- this._audioDrifts.push(e), Le(this._audioDrifts);
3105
+ this._audioDrifts.push(e), $e(this._audioDrifts);
3101
3106
  }
3102
3107
  /** Called when the video 'waiting' event fires. */
3103
3108
  recordStallStart(e, n) {
@@ -3108,18 +3113,18 @@ class Fo {
3108
3113
  this._stallStart && (this._stalls.push({
3109
3114
  ...this._stallStart,
3110
3115
  durationMs: Math.round(performance.now() - this._stallStart.ts)
3111
- }), Le(this._stalls, Io), this._stallStart = null);
3116
+ }), $e(this._stalls, Co), this._stallStart = null);
3112
3117
  }
3113
3118
  /** Called from _doEvict with the reason tag passed by the caller. */
3114
3119
  recordEvict(e, n, r) {
3115
- this._evictCounts[e] = (this._evictCounts[e] ?? 0) + 1, this._evicts.push({ reason: e, start: n, end: r, ts: performance.now() }), Le(this._evicts, Co);
3120
+ this._evictCounts[e] = (this._evictCounts[e] ?? 0) + 1, this._evicts.push({ reason: e, start: n, end: r, ts: performance.now() }), $e(this._evicts, Ro);
3116
3121
  }
3117
3122
  /** Called from FragmentManager.reconcileLoadedStates() when the browser's
3118
3123
  * own silent quota eviction is detected (fragments 'loaded' but gone from
3119
3124
  * sb.buffered). The MSE spec fires no event for this, so reconcile is our
3120
3125
  * only signal — without this counter the eviction is invisible. */
3121
3126
  recordBrowserEviction(e, n) {
3122
- this._browserEvictions.push({ fragmentCount: e, survivingRanges: n, ts: performance.now() }), Le(this._browserEvictions);
3127
+ this._browserEvictions.push({ fragmentCount: e, survivingRanges: n, ts: performance.now() }), $e(this._browserEvictions);
3123
3128
  }
3124
3129
  // ── Reporting ─────────────────────────────────────────────────────────────
3125
3130
  report() {
@@ -3127,18 +3132,18 @@ class Fo {
3127
3132
  for (const c of this._seeks)
3128
3133
  (l[c.caller] ??= []).push(c.durationMs);
3129
3134
  const o = Object.fromEntries(
3130
- Object.entries(l).map(([c, u]) => [c, Ne(u)])
3135
+ Object.entries(l).map(([c, u]) => [c, Le(u)])
3131
3136
  );
3132
3137
  return {
3133
3138
  fetch: {
3134
- ...Ne(e),
3135
- throughputBytesPerSec: Ne(n),
3139
+ ...Le(e),
3140
+ throughputBytesPerSec: Le(n),
3136
3141
  timeoutCount: this._fetchTimeoutCount,
3137
3142
  errorCount: this._fetchErrorCount
3138
3143
  },
3139
3144
  append: {
3140
- queueDepth: Ne(s),
3141
- latencyMs: Ne(r),
3145
+ queueDepth: Le(s),
3146
+ latencyMs: Le(r),
3142
3147
  timeoutCount: this._appendTimeouts.length,
3143
3148
  timeouts: this._appendTimeouts.slice(-10).map((c) => ({
3144
3149
  index: c.index,
@@ -3148,18 +3153,18 @@ class Fo {
3148
3153
  },
3149
3154
  seek: {
3150
3155
  count: this._seeks.length,
3151
- durationMs: Ne(i),
3156
+ durationMs: Le(i),
3152
3157
  byCaller: o,
3153
3158
  waitForSeekedTimeouts: this._waitForSeekedTimeouts
3154
3159
  },
3155
3160
  audio: {
3156
- driftMs: Ne(this._audioDrifts),
3157
- highDriftCount: this._audioDrifts.filter((c) => c > Ro).length,
3161
+ driftMs: Le(this._audioDrifts),
3162
+ highDriftCount: this._audioDrifts.filter((c) => c > Fo).length,
3158
3163
  samples: this._audioDrifts.slice(-20).map((c) => Math.round(c))
3159
3164
  },
3160
3165
  stalls: {
3161
3166
  count: this._stalls.length + (this._stallStart ? 1 : 0),
3162
- durationMs: Ne(a),
3167
+ durationMs: Le(a),
3163
3168
  openStall: this._stallStart ? {
3164
3169
  currentMs: Math.round(this._stallStart.currentMs),
3165
3170
  aheadMs: Math.round(this._stallStart.aheadMs),
@@ -3203,9 +3208,9 @@ class Fo {
3203
3208
  this._fetches = [], this._fetchTimeoutCount = 0, this._fetchErrorCount = 0, this._appends = [], this._appendStarts.clear(), this._appendTimeouts = [], this._seeks = [], this._waitForSeekedTimeouts = 0, this._audioDrifts = [], this._stalls = [], this._stallStart = null, this._evictCounts = {}, this._evicts = [], this._browserEvictions = [];
3204
3209
  }
3205
3210
  }
3206
- const oe = new Fo();
3207
- zn("__WP_PERF__", oe);
3208
- class No {
3211
+ const oe = new No();
3212
+ Jn("__WP_PERF__", oe);
3213
+ class Lo {
3209
3214
  cache = /* @__PURE__ */ new Map();
3210
3215
  getOrCreate(e) {
3211
3216
  let n = this.cache.get(e);
@@ -3234,7 +3239,7 @@ class No {
3234
3239
  if (n.length === 0) return 0;
3235
3240
  const r = this.cache.get(e);
3236
3241
  if (!r) return 0;
3237
- const s = tn(n, 0);
3242
+ const s = nn(n, 0);
3238
3243
  let i = 0;
3239
3244
  for (let a = s; a < n.length && r.fragments.has(a); a++)
3240
3245
  i = n[a].end_ms;
@@ -3244,8 +3249,8 @@ class No {
3244
3249
  this.cache.clear();
3245
3250
  }
3246
3251
  }
3247
- const ve = new No(), Fn = 60, Lo = 5e3;
3248
- class $o {
3252
+ const ve = new Lo(), Nn = 60, $o = 5e3;
3253
+ class Po {
3249
3254
  constructor(e) {
3250
3255
  this.deps = e;
3251
3256
  }
@@ -3325,7 +3330,7 @@ class $o {
3325
3330
  if (this.evictStartedAt === 0)
3326
3331
  return this.evictStartedAt = Date.now(), !0;
3327
3332
  const e = Date.now() - this.evictStartedAt;
3328
- return e < Lo ? !0 : (C("buffer", `EVICT-STUCK isEvicting held ${e}ms — clearing; a remove() updateend was lost, eviction was disabled`), oe.recordEvict("stuck-recovered", 0, 0), this._isEvicting = !1, this.evictStartedAt = 0, !1);
3333
+ return e < $o ? !0 : (C("buffer", `EVICT-STUCK isEvicting held ${e}ms — clearing; a remove() updateend was lost, eviction was disabled`), oe.recordEvict("stuck-recovered", 0, 0), this._isEvicting = !1, this.evictStartedAt = 0, !1);
3329
3334
  }
3330
3335
  /** Called on dispose, on SourceBuffer error, and on media change
3331
3336
  * (FragmentManager.setIndex) — see the note at that call site. */
@@ -3338,7 +3343,7 @@ class $o {
3338
3343
  * range per call; the updateend chain handles any remainder. */
3339
3344
  evictSeekGap(e) {
3340
3345
  const n = this.deps.getSourceBuffer(), r = this.deps.getMediaSource();
3341
- if (!n || n.updating || this.deps.isDisposed() || r?.readyState !== "open" || this.clearIfStuck()) return;
3346
+ if (!n || n.updating || this.deps.isDisposed() || !Ee(r) || this.clearIfStuck()) return;
3342
3347
  this.pendingEvictionMs = e;
3343
3348
  const s = e / 1e3, i = n.buffered;
3344
3349
  for (let l = 0; l < i.length; l++) {
@@ -3348,7 +3353,7 @@ class $o {
3348
3353
  return;
3349
3354
  }
3350
3355
  }
3351
- const a = s + Xe / 1e3;
3356
+ const a = s + Ze / 1e3;
3352
3357
  for (let l = 0; l < i.length; l++) {
3353
3358
  const o = i.start(l);
3354
3359
  if (o <= a) continue;
@@ -3364,17 +3369,17 @@ class $o {
3364
3369
  evictBefore(e) {
3365
3370
  this.pendingEvictionMs = e;
3366
3371
  const n = this.deps.getSourceBuffer(), r = this.deps.getMediaSource();
3367
- if (!n || n.updating || this.deps.isDisposed() || r?.readyState !== "open" || this.clearIfStuck()) return;
3372
+ if (!n || n.updating || this.deps.isDisposed() || !Ee(r) || this.clearIfStuck()) return;
3368
3373
  const s = e / 1e3, i = n.buffered, a = this.deps.getPendingSeekTargetMs(), l = a === null ? null : a / 1e3;
3369
3374
  for (let o = 0; o < i.length; o++) {
3370
3375
  const c = i.start(o), u = i.end(o);
3371
- if (c < s - Fn && u > s) {
3372
- const v = s - Fn;
3376
+ if (c < s - Nn && u > s) {
3377
+ const v = s - Nn;
3373
3378
  E("buffer", `EVICT-START [behind-tail-trim] range=${c.toFixed(2)}-${u.toFixed(2)} → trim [${c.toFixed(2)}-${v.toFixed(2)}] playhead=${s.toFixed(2)}`), this._doEvict(c, v, "behind-tail-trim");
3374
3379
  return;
3375
3380
  }
3376
- if (c < 0.5 && u > s || l !== null && u > l - Z.FALLBACK && c < l + Xe / 1e3) continue;
3377
- const h = u < s - 25, f = c > s + 4 * Xe / 1e3, y = o < i.length - 1 ? i.start(o + 1) - u : 0, g = u < s - 25 && y > 5, p = c > s + Xe / 1e3 && (o === 0 || i.end(o - 1) < c - Z.FALLBACK);
3381
+ if (c < 0.5 && u > s || l !== null && u > l - Z.FALLBACK && c < l + Ze / 1e3) continue;
3382
+ const h = u < s - 25, f = c > s + 4 * Ze / 1e3, y = o < i.length - 1 ? i.start(o + 1) - u : 0, g = u < s - 25 && y > 5, p = c > s + Ze / 1e3 && (o === 0 || i.end(o - 1) < c - Z.FALLBACK);
3378
3383
  if (h || f || g || p) {
3379
3384
  const v = h ? "behind" : f ? "far-ahead-island" : g ? "orphaned-gap" : "forward-orphan";
3380
3385
  E("buffer", `EVICT-START [${v}] range=${c.toFixed(2)}-${u.toFixed(2)} playhead=${s.toFixed(2)}`), this._doEvict(c, u, v);
@@ -3403,7 +3408,7 @@ class $o {
3403
3408
  }
3404
3409
  }
3405
3410
  }
3406
- class Ze {
3411
+ class et {
3407
3412
  fragments = [];
3408
3413
  mediaUrl = "";
3409
3414
  /** Fragment-route addressing for this media, when available. Null => Range only. */
@@ -3490,13 +3495,13 @@ class Ze {
3490
3495
  * hold began. Lets processAppendQueue bound a hold that would otherwise
3491
3496
  * never end — see APPEND_HOLD_MAX_MS. */
3492
3497
  appendHold = null;
3493
- eviction = new $o({
3498
+ eviction = new Po({
3494
3499
  getFragments: () => this.fragments,
3495
3500
  getSourceBuffer: () => this.sourceBuffer,
3496
3501
  getMediaSource: () => this.mediaSource,
3497
3502
  isDisposed: () => this.disposed,
3498
3503
  fragmentStates: this.fragmentStates,
3499
- getPendingSeekTargetMs: () => this.pendingSeekTargetMs !== null && Date.now() - this.pendingSeekSetAtMs > go ? null : this.pendingSeekTargetMs
3504
+ getPendingSeekTargetMs: () => this.pendingSeekTargetMs !== null && Date.now() - this.pendingSeekSetAtMs > bo ? null : this.pendingSeekTargetMs
3500
3505
  });
3501
3506
  lastGapWarnMs = 0;
3502
3507
  stableGapSignature = null;
@@ -3522,7 +3527,7 @@ class Ze {
3522
3527
  // timing, and APPEND-HOLD reason counts. Read by emitInitDigest() which warns
3523
3528
  // once at gate-pass time so the load shape is visible in session logs without
3524
3529
  // wp:reportLogs=true.
3525
- static INIT_TRACK_FRAGS = ks;
3530
+ static INIT_TRACK_FRAGS = _s;
3526
3531
  loadStartTs = 0;
3527
3532
  initFetchStart = 0;
3528
3533
  initFetchEnd = 0;
@@ -3597,8 +3602,8 @@ class Ze {
3597
3602
  * `fragment-route.realmedia.test.ts`; this is the client-side backstop.
3598
3603
  */
3599
3604
  async tryFragmentRoute(e, n, r) {
3600
- if (this.fragmentRouteDisabled || !this.delivery || !_s()) return null;
3601
- const s = As(this.delivery, e);
3605
+ if (this.fragmentRouteDisabled || !this.delivery || !As()) return null;
3606
+ const s = Ts(this.delivery, e);
3602
3607
  if (!s)
3603
3608
  return this.disableFragmentRoute(e, "could not build a URL for this config"), null;
3604
3609
  try {
@@ -3633,7 +3638,7 @@ class Ze {
3633
3638
  * first INIT_TRACK_FRAGS distinct indices and stop after the digest fires
3634
3639
  * to keep memory bounded and avoid logging steady-state behavior. */
3635
3640
  isInInitPhase() {
3636
- return !this.initDigestEmitted && this.fragInitTimings.size < Ze.INIT_TRACK_FRAGS;
3641
+ return !this.initDigestEmitted && this.fragInitTimings.size < et.INIT_TRACK_FRAGS;
3637
3642
  }
3638
3643
  recordInitFragEvent(e, n) {
3639
3644
  if (this.initDigestEmitted) return;
@@ -3641,7 +3646,7 @@ class Ze {
3641
3646
  if (r)
3642
3647
  Object.assign(r, n);
3643
3648
  else {
3644
- if (this.fragInitTimings.size >= Ze.INIT_TRACK_FRAGS) return;
3649
+ if (this.fragInitTimings.size >= et.INIT_TRACK_FRAGS) return;
3645
3650
  this.fragInitTimings.set(e, { ...n });
3646
3651
  }
3647
3652
  }
@@ -3678,7 +3683,7 @@ class Ze {
3678
3683
  const c = await this.tryFragmentRoute(
3679
3684
  "init",
3680
3685
  n - e + 1,
3681
- AbortSignal.timeout(ot(this.getAverageDownloadRate()))
3686
+ AbortSignal.timeout(ct(this.getAverageDownloadRate()))
3682
3687
  );
3683
3688
  if (c) {
3684
3689
  if (this.initTtfbMs = c.ttfbMs, this.initCfStatus = c.cfStatus, l = c.buf, a()) {
@@ -3692,7 +3697,7 @@ class Ze {
3692
3697
  } else {
3693
3698
  const u = performance.now(), h = await fetch(s, {
3694
3699
  headers: { Range: `bytes=${e}-${n}` },
3695
- signal: AbortSignal.timeout(ot(this.getAverageDownloadRate()))
3700
+ signal: AbortSignal.timeout(ct(this.getAverageDownloadRate()))
3696
3701
  });
3697
3702
  if (this.initTtfbMs = Math.round(performance.now() - u), this.initCfStatus = h.headers.get("cf-cache-status") || h.headers.get("x-cache") || "", !h.ok) throw new Error(`HTTP ${h.status}`);
3698
3703
  if (h.status !== 206)
@@ -3725,14 +3730,14 @@ class Ze {
3725
3730
  }
3726
3731
  this.initAppendDone = performance.now(), this.initState = "loaded", this.initRetryCount = 0, E("buffer", `INIT-LOADED sbRanges=[${ge(this.sourceBuffer?.buffered).join(", ")}]`), this.processAppendQueue();
3727
3732
  } catch (l) {
3728
- ee("buffer", "Init segment fetch/append failed", { error: l.message }), a() || (this.initState = "pending", this.initRetryCount += 1, this.initRetryCount >= Ts ? (this.initFailed = !0, C("buffer", "INIT-GIVE-UP — init segment failed repeatedly; rejecting waiters for fast recovery", {
3733
+ ee("buffer", "Init segment fetch/append failed", { error: l.message }), a() || (this.initState = "pending", this.initRetryCount += 1, this.initRetryCount >= Is ? (this.initFailed = !0, C("buffer", "INIT-GIVE-UP — init segment failed repeatedly; rejecting waiters for fast recovery", {
3729
3734
  attempts: this.initRetryCount,
3730
3735
  error: l.message
3731
3736
  }), this.rejectAllWaiters(new Error("init segment failed after repeated retries"))) : this.disposed || setTimeout(() => {
3732
3737
  !this.disposed && this.initState === "pending" && this.fetchInit().catch((o) => {
3733
3738
  ee("buffer", "INIT-RETRY failed", Y(o));
3734
3739
  });
3735
- }, Is));
3740
+ }, Cs));
3736
3741
  }
3737
3742
  }
3738
3743
  /** Runs inside updateend after an append completes. Decides whether MSE
@@ -3820,14 +3825,14 @@ class Ze {
3820
3825
  ]), r = [], s = this.currentPlayheadMs / 1e3;
3821
3826
  for (let l = 1; l < e.buffered.length; l++) {
3822
3827
  const o = e.buffered.end(l - 1), c = e.buffered.start(l);
3823
- c <= s || wo(o, c, this.fragments, n) || r.push(`${o.toFixed(2)}-${c.toFixed(2)}`);
3828
+ c <= s || xo(o, c, this.fragments, n) || r.push(`${o.toFixed(2)}-${c.toFixed(2)}`);
3824
3829
  }
3825
3830
  if (r.length === 0) {
3826
3831
  this.stableGapSignature = null, this.stableGapSince = 0;
3827
3832
  return;
3828
3833
  }
3829
3834
  const i = r.join("|"), a = Date.now();
3830
- this.stableGapSignature !== i ? (this.stableGapSignature = i, this.stableGapSince = a) : a - this.stableGapSince >= fn && a - this.lastGapWarnMs > fn && (this.lastGapWarnMs = a, C("buffer", `SB has ${e.buffered.length} ranges with ${r.length} stable unfillable gap(s) ${JSON.stringify({
3835
+ this.stableGapSignature !== i ? (this.stableGapSignature = i, this.stableGapSince = a) : a - this.stableGapSince >= hn && a - this.lastGapWarnMs > hn && (this.lastGapWarnMs = a, C("buffer", `SB has ${e.buffered.length} ranges with ${r.length} stable unfillable gap(s) ${JSON.stringify({
3831
3836
  ranges: ge(e.buffered),
3832
3837
  unfillableGaps: r,
3833
3838
  stableForMs: a - this.stableGapSince,
@@ -3851,7 +3856,7 @@ class Ze {
3851
3856
  if (this.disposed) return Promise.reject(new Error("FragmentManager disposed"));
3852
3857
  if (this.initFailed) return Promise.reject(new Error("init segment failed after repeated retries"));
3853
3858
  if (this.fragmentStates.get(e) === "loaded") return Promise.resolve();
3854
- const r = n ?? ot(this.getAverageDownloadRate());
3859
+ const r = n ?? ct(this.getAverageDownloadRate());
3855
3860
  return new Promise((s, i) => {
3856
3861
  const a = setTimeout(() => {
3857
3862
  this.appendWaiters = this.appendWaiters.filter((l) => l.index !== e), oe.recordAppendTimeout(e, r, this.appendQueue.length), C("buffer", "waitForAppend timeout", {
@@ -3875,7 +3880,7 @@ class Ze {
3875
3880
  });
3876
3881
  }
3877
3882
  isBuffered(e) {
3878
- return !this.sourceBuffer?.buffered || this.mediaSource?.readyState !== "open" ? !1 : Ye(this.sourceBuffer.buffered, e / 1e3, Z.RANGE) >= 0;
3883
+ return !this.sourceBuffer?.buffered || !Ee(this.mediaSource) ? !1 : Xe(this.sourceBuffer.buffered, e / 1e3, Z.RANGE) >= 0;
3879
3884
  }
3880
3885
  /** True when `timeMs` is comfortably inside a buffered range — more than
3881
3886
  * GAP_SKIP_EDGE_SEC of data ahead of it. `isBuffered` is a point test and says
@@ -3884,9 +3889,9 @@ class Ze {
3884
3889
  * a viewer frozen 45ms short of their audio buffer's end (mistral-bluff
3885
3890
  * 2026-10-20, 55s). Test: fragmentManager.trailingEdgeRefill.test.ts. */
3886
3891
  hasDataAhead(e) {
3887
- if (!this.sourceBuffer?.buffered || this.mediaSource?.readyState !== "open") return !1;
3888
- const n = this.sourceBuffer.buffered, r = e / 1e3, s = Ye(n, r, Z.RANGE);
3889
- return s >= 0 && n.end(s) - r > Pt;
3892
+ if (!this.sourceBuffer?.buffered || !Ee(this.mediaSource)) return !1;
3893
+ const n = this.sourceBuffer.buffered, r = e / 1e3, s = Xe(n, r, Z.RANGE);
3894
+ return s >= 0 && n.end(s) - r > Dt;
3890
3895
  }
3891
3896
  /** Wait for a specific time position to be buffered in the SourceBuffer.
3892
3897
  * Event-driven: resolves on updateend when the position enters a buffered range. */
@@ -3915,16 +3920,15 @@ class Ze {
3915
3920
  * the last ~BUFFER_AHEAD of every clip they reported 0 buffered while the
3916
3921
  * whole rest of the clip sat in the buffer: health cards and buffer rings
3917
3922
  * read it as starved, and the party analyzer flagged every viewer as
3918
- * draining at once ~25s into each short trailer (10-5-26 party). Deliberately
3919
- * NOT applied to `isBuffered`/seek routing, which decide what to fetch.
3923
+ * draining at once ~25s into each short trailer (10-5-26 party). The fetch
3924
+ * and seek gates follow the same rule (`isMediaSourceAttached`).
3920
3925
  */
3921
3926
  canReportBuffered() {
3922
- const e = this.mediaSource?.readyState;
3923
- return e === "open" || e === "ended";
3927
+ return Ee(this.mediaSource);
3924
3928
  }
3925
3929
  getBufferedEnd(e) {
3926
3930
  if (!this.sourceBuffer?.buffered || !this.canReportBuffered()) return 0;
3927
- const n = e / 1e3, r = this.sourceBuffer.buffered, s = Ye(r, n, Z.POINT);
3931
+ const n = e / 1e3, r = this.sourceBuffer.buffered, s = Xe(r, n, Z.POINT);
3928
3932
  if (s >= 0) return r.end(s) * 1e3;
3929
3933
  for (let i = 0; i < r.length; i++)
3930
3934
  if (r.start(i) > n && r.start(i) - n <= Z.FALLBACK) return r.end(i) * 1e3;
@@ -3932,7 +3936,7 @@ class Ze {
3932
3936
  }
3933
3937
  getBufferedAheadMs(e) {
3934
3938
  if (!this.sourceBuffer?.buffered?.length || !this.canReportBuffered()) return 0;
3935
- const n = e / 1e3, r = this.sourceBuffer.buffered, s = Ye(r, n, Z.RANGE);
3939
+ const n = e / 1e3, r = this.sourceBuffer.buffered, s = Xe(r, n, Z.RANGE);
3936
3940
  if (s >= 0) return (r.end(s) - n) * 1e3;
3937
3941
  for (let i = 0; i < r.length; i++)
3938
3942
  if (r.start(i) > n && r.start(i) - n <= Z.FALLBACK)
@@ -3974,7 +3978,7 @@ class Ze {
3974
3978
  for (const [s, i] of this.fragmentStates) {
3975
3979
  if (i !== "loaded") continue;
3976
3980
  const a = this.fragments[s];
3977
- a && (Ot(e, a.start_ms, a.end_ms) || (this.fragmentStates.set(s, "pending"), n.push(s)));
3981
+ a && (Ht(e, a.start_ms, a.end_ms) || (this.fragmentStates.set(s, "pending"), n.push(s)));
3978
3982
  }
3979
3983
  if (n.length === 0) return;
3980
3984
  const r = ge(e).join(", ") || "(none)";
@@ -3989,11 +3993,11 @@ class Ze {
3989
3993
  }
3990
3994
  resolveTarget(e) {
3991
3995
  this.reconcileLoadedStates();
3992
- const n = Ie(this.fragments, e);
3996
+ const n = Ce(this.fragments, e);
3993
3997
  if (this.isBuffered(e)) return { status: "buffered", fragmentIndex: n };
3994
3998
  const r = this.currentJobs.get(n);
3995
3999
  if (r) return { status: "loading", fragmentIndex: n, existingPromise: r.promise };
3996
- const s = Math.max(0, n - In), i = Math.min(this.fragments.length - 1, n + In);
4000
+ const s = Math.max(0, n - Cn), i = Math.min(this.fragments.length - 1, n + Cn);
3997
4001
  for (let a = s; a <= i; a++) {
3998
4002
  const l = this.fragmentStates.get(a);
3999
4003
  if (l === "loaded" || l === "loading") return { status: "nearby-pending", fragmentIndex: n };
@@ -4005,7 +4009,7 @@ class Ze {
4005
4009
  }
4006
4010
  async ensureBuffered(e, n, r) {
4007
4011
  if (!(this.disposed || !this.sourceBuffer || !this.fragments.length || this.isBuffered(e))) {
4008
- if (this.mediaSource?.readyState !== "open") {
4012
+ if (!Ee(this.mediaSource)) {
4009
4013
  E("buffer", `ENSURE-SKIP — mediaSource.readyState=${this.mediaSource?.readyState ?? "null"}`);
4010
4014
  return;
4011
4015
  }
@@ -4013,16 +4017,16 @@ class Ze {
4013
4017
  }
4014
4018
  }
4015
4019
  async _fetchRange(e, n) {
4016
- if (this.disposed || !this.sourceBuffer || !this.fragments.length || this.hasDataAhead(e) || this.mediaSource?.readyState !== "open") return;
4020
+ if (this.disposed || !this.sourceBuffer || !this.fragments.length || this.hasDataAhead(e) || !Ee(this.mediaSource)) return;
4017
4021
  const { abort: r = !1, minimal: s = !1, signal: i, caller: a = "unknown" } = n;
4018
4022
  r && this.abortAllJobs(a);
4019
- const l = Ie(this.fragments, e);
4023
+ const l = Ce(this.fragments, e);
4020
4024
  if (r) {
4021
- const p = Ie(this.fragments, e + Xe);
4025
+ const p = Ce(this.fragments, e + Ze);
4022
4026
  for (let v = l; v <= p; v++)
4023
4027
  this.discardCounts.delete(v), this.fetchErrorCycles.delete(v);
4024
4028
  }
4025
- const o = tn(this.fragments, e), c = this.fragments[o], u = c && this.sourceBuffer?.buffered && Ot(this.sourceBuffer.buffered, c.start_ms, c.end_ms), h = u ? l : o, f = s ? Math.min(this.fragments.length - 1, l + 1) : Ie(this.fragments, e + Ce);
4029
+ const o = nn(this.fragments, e), c = this.fragments[o], u = c && this.sourceBuffer?.buffered && Ht(this.sourceBuffer.buffered, c.start_ms, c.end_ms), h = u ? l : o, f = s ? Math.min(this.fragments.length - 1, l + 1) : Ce(this.fragments, e + Re);
4026
4030
  this.initRange && this.initState !== "loaded" && await this.fetchInit();
4027
4031
  const y = [], g = [];
4028
4032
  for (let p = h; p <= f; p++) {
@@ -4058,7 +4062,7 @@ class Ze {
4058
4062
  return;
4059
4063
  }
4060
4064
  if (i?.aborted) throw new DOMException("Aborted", "AbortError");
4061
- !r && this.currentJobs.size >= ze && this.evictFurthestJob(e), this.onBufferingChange?.(!0), this.pendingSeekTargetMs = e, this.pendingSeekSetAtMs = Date.now();
4065
+ !r && this.currentJobs.size >= Je && this.evictFurthestJob(e), this.onBufferingChange?.(!0), this.pendingSeekTargetMs = e, this.pendingSeekSetAtMs = Date.now();
4062
4066
  try {
4063
4067
  if (await this.fetchFragments(y), i?.aborted) throw new DOMException("Aborted", "AbortError");
4064
4068
  await this.waitForAppend(l);
@@ -4069,7 +4073,7 @@ class Ze {
4069
4073
  // MAX_CONCURRENT_JOBS - 1: batch size is one below the outer guard so a second
4070
4074
  // concurrent caller (e.g. prefetchAround while _fetchRange runs) can still launch
4071
4075
  // one job before hitting the MAX_CONCURRENT_JOBS cap.
4072
- async fetchFragments(e, n = ze - 1) {
4076
+ async fetchFragments(e, n = Je - 1) {
4073
4077
  if (e.length === 0) return;
4074
4078
  const r = [...e].sort((s, i) => s - i);
4075
4079
  E("buffer", `FETCH-BATCH-START total=${r.length} concurrency=${n} indices=[${r.join(",")}]`);
@@ -4080,7 +4084,7 @@ class Ze {
4080
4084
  a.push(`#${o}=loaded`);
4081
4085
  continue;
4082
4086
  }
4083
- if (this.currentJobs.size >= ze) {
4087
+ if (this.currentJobs.size >= Je) {
4084
4088
  a.push(`#${o}=max-jobs`);
4085
4089
  continue;
4086
4090
  }
@@ -4116,7 +4120,7 @@ class Ze {
4116
4120
  return;
4117
4121
  }
4118
4122
  }
4119
- for (let o = 1; o <= qe; o++) {
4123
+ for (let o = 1; o <= Ye; o++) {
4120
4124
  if (this.disposed) return;
4121
4125
  E("buffer", `FETCH-START #${e} [${i}] attempt=${o} bytes=${a} pending=${JSON.stringify(Array.from(this.pendingFetchIndices).sort((c, u) => c - u))}`);
4122
4126
  try {
@@ -4130,7 +4134,7 @@ class Ze {
4130
4134
  bytes: f.buf.byteLength,
4131
4135
  ttfbMs: f.ttfbMs,
4132
4136
  cf: f.cfStatus
4133
- }), E("buffer", `FETCH-OK #${e} [${i}] ${f.buf.byteLength}B in ${Math.round(k)}ms via=frag-route (ttfb=${f.ttfbMs}ms cf=${f.cfStatus || "-"})`), k > 0 && (this.downloadSamples.push({ bytes: f.buf.byteLength, durationMs: k }), this.downloadSamples.length > Bt && this.downloadSamples.shift(), oe.recordFetch(e, f.buf.byteLength, k)), this.disposed || this.mediaUrl !== h) {
4137
+ }), E("buffer", `FETCH-OK #${e} [${i}] ${f.buf.byteLength}B in ${Math.round(k)}ms via=frag-route (ttfb=${f.ttfbMs}ms cf=${f.cfStatus || "-"})`), k > 0 && (this.downloadSamples.push({ bytes: f.buf.byteLength, durationMs: k }), this.downloadSamples.length > Ot && this.downloadSamples.shift(), oe.recordFetch(e, f.buf.byteLength, k)), this.disposed || this.mediaUrl !== h) {
4134
4138
  E("buffer", `FETCH-STALE #${e} discarding frag-route bytes (mediaUrl changed)`);
4135
4139
  return;
4136
4140
  }
@@ -4142,7 +4146,7 @@ class Ze {
4142
4146
  Range: `bytes=${n.start_byte}-${n.end_byte}`,
4143
4147
  "X-Buffer-Ahead-Ms": String(Math.round(this.getBufferedAheadMs(this.currentPlayheadMs)))
4144
4148
  },
4145
- signal: AbortSignal.any([s.signal, AbortSignal.timeout(ot(this.getAverageDownloadRate()))])
4149
+ signal: AbortSignal.any([s.signal, AbortSignal.timeout(ct(this.getAverageDownloadRate()))])
4146
4150
  }), p = Math.round(performance.now() - c), v = g.headers.get("cf-cache-status") || g.headers.get("x-cache") || "";
4147
4151
  if (!g.ok) throw new Error(`HTTP ${g.status}`);
4148
4152
  const w = n.end_byte - n.start_byte + 1;
@@ -4153,8 +4157,8 @@ class Ze {
4153
4157
  contentLength: g.headers.get("content-length"),
4154
4158
  cfCacheStatus: v,
4155
4159
  expectedBytes: w
4156
- }), this.fragmentStates.set(e, "pending"), o < qe) {
4157
- await new Promise((k) => setTimeout(k, ct(o)));
4160
+ }), this.fragmentStates.set(e, "pending"), o < Ye) {
4161
+ await new Promise((k) => setTimeout(k, lt(o)));
4158
4162
  continue;
4159
4163
  }
4160
4164
  throw new Error(`fragment expected 206, got ${g.status}`);
@@ -4165,15 +4169,15 @@ class Ze {
4165
4169
  expectedBytes: w,
4166
4170
  actualBytes: A.byteLength
4167
4171
  }), A.byteLength === 0 || A.byteLength !== w) {
4168
- if (this.fragmentStates.set(e, "pending"), o < qe) {
4169
- await new Promise((k) => setTimeout(k, ct(o)));
4172
+ if (this.fragmentStates.set(e, "pending"), o < Ye) {
4173
+ await new Promise((k) => setTimeout(k, lt(o)));
4170
4174
  continue;
4171
4175
  }
4172
- ee("buffer", `Fragment #${e} bad response after ${qe} retries`, { expected: w, actual: A.byteLength }), this.fragmentStates.set(e, "error"), this.errorTimestamps.set(e, Date.now()), this.fetchErrorCycles.set(e, (this.fetchErrorCycles.get(e) ?? 0) + 1), oe.recordFetchError(e);
4176
+ ee("buffer", `Fragment #${e} bad response after ${Ye} retries`, { expected: w, actual: A.byteLength }), this.fragmentStates.set(e, "error"), this.errorTimestamps.set(e, Date.now()), this.fetchErrorCycles.set(e, (this.fetchErrorCycles.get(e) ?? 0) + 1), oe.recordFetchError(e);
4173
4177
  return;
4174
4178
  }
4175
4179
  const F = performance.now() - c;
4176
- if (this.isInInitPhase() && this.recordInitFragEvent(e, { fetchEnd: performance.now(), bytes: A.byteLength, ttfbMs: p, cf: v }), E("buffer", `FETCH-OK #${e} [${i}] ${A.byteLength}B in ${Math.round(F)}ms (ttfb=${p}ms cf=${v || "-"}) (${(A.byteLength / F * 1e3 / 1024).toFixed(0)} KB/s)`), F > 0 && (this.downloadSamples.push({ bytes: A.byteLength, durationMs: F }), this.downloadSamples.length > Bt && this.downloadSamples.shift(), oe.recordFetch(e, A.byteLength, F)), this.disposed || this.mediaUrl !== y) {
4180
+ if (this.isInInitPhase() && this.recordInitFragEvent(e, { fetchEnd: performance.now(), bytes: A.byteLength, ttfbMs: p, cf: v }), E("buffer", `FETCH-OK #${e} [${i}] ${A.byteLength}B in ${Math.round(F)}ms (ttfb=${p}ms cf=${v || "-"}) (${(A.byteLength / F * 1e3 / 1024).toFixed(0)} KB/s)`), F > 0 && (this.downloadSamples.push({ bytes: A.byteLength, durationMs: F }), this.downloadSamples.length > Ot && this.downloadSamples.shift(), oe.recordFetch(e, A.byteLength, F)), this.disposed || this.mediaUrl !== y) {
4177
4181
  E("buffer", `FETCH-STALE #${e} discarding (mediaUrl changed)`);
4178
4182
  return;
4179
4183
  }
@@ -4185,15 +4189,15 @@ class Ze {
4185
4189
  return;
4186
4190
  }
4187
4191
  if ((c.name === "TimeoutError" || c.message?.includes("signal timed out") || c.message?.includes("The operation was aborted")) && c.name !== "AbortError") {
4188
- const h = ot(this.getAverageDownloadRate());
4189
- this.downloadSamples.push({ bytes: 0, durationMs: h }), this.downloadSamples.length > Bt && this.downloadSamples.shift(), oe.recordFetchTimeout(e), C("buffer", `FETCH-ERR #${e} [${i}] attempt=${o} timeout=${h}ms avgRate=${Math.round(this.getAverageDownloadRate())}Bps error=${c.message}`);
4192
+ const h = ct(this.getAverageDownloadRate());
4193
+ this.downloadSamples.push({ bytes: 0, durationMs: h }), this.downloadSamples.length > Ot && this.downloadSamples.shift(), oe.recordFetchTimeout(e), C("buffer", `FETCH-ERR #${e} [${i}] attempt=${o} timeout=${h}ms avgRate=${Math.round(this.getAverageDownloadRate())}Bps error=${c.message}`);
4190
4194
  } else
4191
4195
  C("buffer", `FETCH-ERR #${e} [${i}] attempt=${o} error=${c.message}`);
4192
- if (this.isInInitPhase() && this.recordInitFragEvent(e, { err: (c.name === "TimeoutError" ? "timeout" : c.message?.slice(0, 40)) || "err" }), this.fragmentStates.set(e, "pending"), o < qe) {
4193
- await new Promise((h) => setTimeout(h, ct(o)));
4196
+ if (this.isInInitPhase() && this.recordInitFragEvent(e, { err: (c.name === "TimeoutError" ? "timeout" : c.message?.slice(0, 40)) || "err" }), this.fragmentStates.set(e, "pending"), o < Ye) {
4197
+ await new Promise((h) => setTimeout(h, lt(o)));
4194
4198
  continue;
4195
4199
  }
4196
- throw ee("buffer", `Fragment #${e} failed after ${qe} retries`, { error: c.message }), this.fragmentStates.set(e, "error"), this.errorTimestamps.set(e, Date.now()), this.fetchErrorCycles.set(e, (this.fetchErrorCycles.get(e) ?? 0) + 1), oe.recordFetchError(e), c;
4200
+ throw ee("buffer", `Fragment #${e} failed after ${Ye} retries`, { error: c.message }), this.fragmentStates.set(e, "error"), this.errorTimestamps.set(e, Date.now()), this.fetchErrorCycles.set(e, (this.fetchErrorCycles.get(e) ?? 0) + 1), oe.recordFetchError(e), c;
4197
4201
  }
4198
4202
  }
4199
4203
  } finally {
@@ -4218,10 +4222,10 @@ class Ze {
4218
4222
  if (e <= 0 || this.fragments.length === 0 || this.fragments[0].keyframe === void 0) return !1;
4219
4223
  const n = this.fragments[e];
4220
4224
  if (!n || n.keyframe) return !1;
4221
- const r = Cn(this.fragments, e - 1);
4225
+ const r = Rn(this.fragments, e - 1);
4222
4226
  if (r < 0 || this.fragmentStates.get(r) !== "error") return !1;
4223
4227
  const s = this.fragments[r];
4224
- if (this.sourceBuffer ? Ot(this.sourceBuffer.buffered, s.start_ms, s.end_ms) : !1) return !1;
4228
+ if (this.sourceBuffer ? Ht(this.sourceBuffer.buffered, s.start_ms, s.end_ms) : !1) return !1;
4225
4229
  const a = [], l = [];
4226
4230
  for (const o of this.appendQueue) {
4227
4231
  const c = this.fragments[o.index];
@@ -4229,7 +4233,7 @@ class Ze {
4229
4233
  l.push(o);
4230
4234
  continue;
4231
4235
  }
4232
- Cn(this.fragments, o.index - 1) === r ? (a.push(o.index), this.fragmentStates.set(o.index, "pending")) : l.push(o);
4236
+ Rn(this.fragments, o.index - 1) === r ? (a.push(o.index), this.fragmentStates.set(o.index, "pending")) : l.push(o);
4233
4237
  }
4234
4238
  return a.length === 0 ? !1 : (this.appendQueue = l, C("buffer", `APPEND-DROP-DEPENDENT [${a.join(",")}] — keyframe #${r} in error, not in SB`, {
4235
4239
  kfIdx: r,
@@ -4260,7 +4264,7 @@ class Ze {
4260
4264
  if (this.appendHold?.index !== e)
4261
4265
  return this.appendHold = { index: e, since: r }, !1;
4262
4266
  const s = r - this.appendHold.since;
4263
- if (s < Cs) return !1;
4267
+ if (s < Rs) return !1;
4264
4268
  C("buffer", `APPEND-HOLD-BREAK #${e} held ${s}ms behind ${n.length} pending fetch(es) — declaring them dead so the queue can drain`, {
4265
4269
  headIndex: e,
4266
4270
  heldMs: s,
@@ -4269,11 +4273,11 @@ class Ze {
4269
4273
  liveJobs: Array.from(this.currentJobs.keys()).sort((i, a) => i - a)
4270
4274
  });
4271
4275
  for (const i of n)
4272
- this.currentJobs.get(i)?.abortController.abort(), this.currentJobs.delete(i), this.pendingFetchIndices.delete(i), this.fragmentStates.set(i, "error"), this.errorTimestamps.set(i, r), this.fetchErrorCycles.set(i, hn);
4276
+ this.currentJobs.get(i)?.abortController.abort(), this.currentJobs.delete(i), this.pendingFetchIndices.delete(i), this.fragmentStates.set(i, "error"), this.errorTimestamps.set(i, r), this.fetchErrorCycles.set(i, pn);
4273
4277
  return this.appendHold = null, !0;
4274
4278
  }
4275
4279
  processAppendQueue() {
4276
- if (this.isAppending || this.disposed || !this.sourceBuffer || this.sourceBuffer.updating || this.mediaSource?.readyState !== "open" || this.appendQueue.length === 0) return;
4280
+ if (this.isAppending || this.disposed || !this.sourceBuffer || this.sourceBuffer.updating || !Ee(this.mediaSource) || this.appendQueue.length === 0) return;
4277
4281
  const e = this.appendQueue[0];
4278
4282
  if (e) {
4279
4283
  if (this.initRange && this.initState !== "loaded") {
@@ -4316,17 +4320,17 @@ class Ze {
4316
4320
  const a = this.fragments[i];
4317
4321
  a && a.start_ms > r && (r = a.start_ms, n = i);
4318
4322
  }
4319
- if (n < 0 || r - e < Ce) return;
4323
+ if (n < 0 || r - e < Re) return;
4320
4324
  const s = this.currentJobs.get(n);
4321
4325
  s && (s.abortController.abort(), this.currentJobs.delete(n), this.fragmentStates.set(n, "pending"));
4322
4326
  }
4323
4327
  prefetchAround(e) {
4324
- if (this.disposed || !this.sourceBuffer || (this.currentPlayheadMs = e, this.currentJobs.size >= ze)) return;
4325
- const n = Ie(this.fragments, e), r = Math.min(this.fragments.length - 1, Ie(this.fragments, e + Xe)), s = Date.now();
4328
+ if (this.disposed || !this.sourceBuffer || (this.currentPlayheadMs = e, this.currentJobs.size >= Je)) return;
4329
+ const n = Ce(this.fragments, e), r = Math.min(this.fragments.length - 1, Ce(this.fragments, e + Ze)), s = Date.now();
4326
4330
  for (let a = n; a <= r; a++)
4327
- this.fragmentStates.get(a) === "error" && s - (this.errorTimestamps.get(a) ?? 0) >= Rs && ((this.fetchErrorCycles.get(a) ?? 0) >= hn ? E("buffer", `PREFETCH-DEAD #${a} cycles=${this.fetchErrorCycles.get(a)} not resetting`) : (this.fragmentStates.set(a, "pending"), this.errorTimestamps.delete(a)));
4331
+ this.fragmentStates.get(a) === "error" && s - (this.errorTimestamps.get(a) ?? 0) >= Fs && ((this.fetchErrorCycles.get(a) ?? 0) >= pn ? E("buffer", `PREFETCH-DEAD #${a} cycles=${this.fetchErrorCycles.get(a)} not resetting`) : (this.fragmentStates.set(a, "pending"), this.errorTimestamps.delete(a)));
4328
4332
  let i = 0;
4329
- for (let a = n; a <= r && i < ze - this.currentJobs.size; a++) {
4333
+ for (let a = n; a <= r && i < Je - this.currentJobs.size; a++) {
4330
4334
  const l = this.fragmentStates.get(a);
4331
4335
  if (!(l !== "pending" && l !== "error") && !((this.discardCounts.get(a) ?? 0) >= 2) && !((this.fetchErrorCycles.get(a) ?? 0) >= 3)) {
4332
4336
  if (a > n) {
@@ -4346,7 +4350,7 @@ class Ze {
4346
4350
  ((a.pending ?? 0) > 0 || (a.error ?? 0) > 0) && C("buffer", "PREFETCH-STALL no new fetches launched", {
4347
4351
  stateMap: a,
4348
4352
  jobs: this.currentJobs.size,
4349
- maxJobs: ze,
4353
+ maxJobs: Je,
4350
4354
  playheadMs: e,
4351
4355
  aheadFragments: r - n + 1
4352
4356
  });
@@ -4355,7 +4359,7 @@ class Ze {
4355
4359
  /** Public eviction entry point used by MediaPlayer / prefetch. Delegates
4356
4360
  * to the strategy which owns the isEvicting state + range choice logic. */
4357
4361
  evictBefore(e) {
4358
- this.pendingSeekTargetMs !== null && Math.abs(e - this.pendingSeekTargetMs) <= bo && (this.pendingSeekTargetMs = null), this.eviction.evictBefore(e);
4362
+ this.pendingSeekTargetMs !== null && Math.abs(e - this.pendingSeekTargetMs) <= yo && (this.pendingSeekTargetMs = null), this.eviction.evictBefore(e);
4359
4363
  }
4360
4364
  // Public entry point for socket reconnect scenarios. Clears stale in-flight
4361
4365
  // fetches and their pendingFetchIndices entries so the queue is unblocked on
@@ -4454,7 +4458,7 @@ class Ze {
4454
4458
  })}`);
4455
4459
  }
4456
4460
  dumpBufferDiagnostics(e, n) {
4457
- const r = Ie(this.fragments, e), s = Math.max(0, r - 3), i = Math.min(this.fragments.length - 1, r + 6), a = [];
4461
+ const r = Ce(this.fragments, e), s = Math.max(0, r - 3), i = Math.min(this.fragments.length - 1, r + 6), a = [];
4458
4462
  for (let l = s; l <= i; l++) {
4459
4463
  const o = this.fragments[l], c = this.fragmentStates.get(l) || "unknown";
4460
4464
  a.push(`#${l}[${(o.start_ms / 1e3).toFixed(1)}-${(o.end_ms / 1e3).toFixed(1)}s]=${c}${this.currentJobs.has(l) ? "+job" : ""}${l === r ? " <<PLAYHEAD" : ""}`);
@@ -4503,7 +4507,7 @@ class Ze {
4503
4507
  return { ranges: e, gaps: e.length > 1, fragmentStates: n };
4504
4508
  }
4505
4509
  getAverageDownloadRate() {
4506
- return yo(this.downloadSamples);
4510
+ return vo(this.downloadSamples);
4507
4511
  }
4508
4512
  /** Nominal media end time (ms) = last fragment's end. 0 if no index loaded.
4509
4513
  * Reported in health so the leader's status card can tell "near end-of-stream,
@@ -4517,9 +4521,9 @@ class Ze {
4517
4521
  * structural gaps caused by late-IDR fragments (where the IDR is deep inside the
4518
4522
  * fragment's mdat so MSE only buffers from the IDR timestamp, not the nominal start). */
4519
4523
  findNextRangeStart(e, n) {
4520
- if (!this.sourceBuffer?.buffered || this.mediaSource?.readyState !== "open") return null;
4521
- const r = e / 1e3, s = this.sourceBuffer.buffered, i = Ye(s, r, Z.RANGE);
4522
- if (i >= 0 && s.end(i) - r > Pt) return null;
4524
+ if (!this.sourceBuffer?.buffered || !Ee(this.mediaSource)) return null;
4525
+ const r = e / 1e3, s = this.sourceBuffer.buffered, i = Xe(s, r, Z.RANGE);
4526
+ if (i >= 0 && s.end(i) - r > Dt) return null;
4523
4527
  const a = i >= 0 ? Math.max(r, s.end(i)) : r;
4524
4528
  for (let l = 0; l < s.length; l++) {
4525
4529
  const o = s.start(l);
@@ -4538,8 +4542,8 @@ class Ze {
4538
4542
  * same way the skip decision measures it (from the containing range's end).
4539
4543
  * Returns null only when there is no usable SourceBuffer. */
4540
4544
  getForwardGapDiag(e) {
4541
- if (!this.sourceBuffer?.buffered || this.mediaSource?.readyState !== "open") return null;
4542
- const n = e / 1e3, r = this.sourceBuffer.buffered, s = Ye(r, n, Z.RANGE), i = s >= 0 ? Math.max(0, r.end(s) - n) : 0, a = s >= 0 ? Math.max(n, r.end(s)) : n;
4545
+ if (!this.sourceBuffer?.buffered || !Ee(this.mediaSource)) return null;
4546
+ const n = e / 1e3, r = this.sourceBuffer.buffered, s = Xe(r, n, Z.RANGE), i = s >= 0 ? Math.max(0, r.end(s) - n) : 0, a = s >= 0 ? Math.max(n, r.end(s)) : n;
4543
4547
  let l = null;
4544
4548
  for (let o = 0; o < r.length; o++)
4545
4549
  if (r.start(o) > a) {
@@ -4547,7 +4551,7 @@ class Ze {
4547
4551
  break;
4548
4552
  }
4549
4553
  return {
4550
- atEdge: s >= 0 && i <= Pt,
4554
+ atEdge: s >= 0 && i <= Dt,
4551
4555
  aheadInRangeMs: i * 1e3,
4552
4556
  nextRangeStartMs: l !== null ? l * 1e3 : null,
4553
4557
  gapMs: l !== null ? (l - a) * 1e3 : null
@@ -4577,7 +4581,7 @@ class Ze {
4577
4581
  if (this.eosRetryTimer) return;
4578
4582
  this.eosRetryTimer = setTimeout(() => {
4579
4583
  this.eosRetryTimer = null, this.tryEndOfStream();
4580
- }, Fs);
4584
+ }, Ns);
4581
4585
  return;
4582
4586
  }
4583
4587
  try {
@@ -4590,28 +4594,28 @@ class Ze {
4590
4594
  this.disposed = !0, this.eosRetryTimer && (clearTimeout(this.eosRetryTimer), this.eosRetryTimer = null), this.pendingEndOfStream = !1, this.abortAllJobs("dispose"), this.rejectAllWaiters(new Error("FragmentManager disposed")), this.appendQueue = [], this.isAppending = !1, this.eviction.reset(), this.appendingIndex = null, this.fragmentStates.clear(), this.errorTimestamps.clear(), this.discardCounts.clear(), this.fetchErrorCycles.clear(), this.downloadSamples = [], this.preAppendRanges = [], this.sourceBuffer = null, this.mediaSource = null, this.initState = "pending", this.initRange = null;
4591
4595
  }
4592
4596
  }
4593
- function Po(t, e) {
4597
+ function Do(t, e) {
4594
4598
  return !!t && t !== "eng" && e;
4595
4599
  }
4596
- function Do(t) {
4597
- return t.override !== null ? t.override : t.globalEnabled || Po(t.selectedAudioLang, t.hasEngSub);
4600
+ function Bo(t) {
4601
+ return t.override !== null ? t.override : t.globalEnabled || Do(t.selectedAudioLang, t.hasEngSub);
4598
4602
  }
4599
- const Rr = "wp_reload_history", nn = "wp_phantom_reload", Fr = 5 * 6e4, Nn = 3;
4600
- function Bo() {
4603
+ const Fr = "wp_reload_history", rn = "wp_phantom_reload", Nr = 5 * 6e4, Ln = 3;
4604
+ function Oo() {
4601
4605
  try {
4602
- const t = sessionStorage.getItem(Rr);
4603
- return (t ? JSON.parse(t) : []).filter((n) => Date.now() - n < Fr);
4606
+ const t = sessionStorage.getItem(Fr);
4607
+ return (t ? JSON.parse(t) : []).filter((n) => Date.now() - n < Nr);
4604
4608
  } catch {
4605
4609
  return [];
4606
4610
  }
4607
4611
  }
4608
- function Jt(t, e) {
4609
- const n = Bo();
4610
- if (n.length >= Nn) {
4611
- pn(
4612
+ function Qt(t, e) {
4613
+ const n = Oo();
4614
+ if (n.length >= Ln) {
4615
+ mn(
4612
4616
  "error",
4613
4617
  "buffer",
4614
- `AUTO-RELOAD SUPPRESSED reason=${t} — ${n.length} reloads in ${Fr / 6e4}m, giving up (connection looks unstable)`,
4618
+ `AUTO-RELOAD SUPPRESSED reason=${t} — ${n.length} reloads in ${Nr / 6e4}m, giving up (connection looks unstable)`,
4615
4619
  e
4616
4620
  );
4617
4621
  try {
@@ -4624,31 +4628,31 @@ function Jt(t, e) {
4624
4628
  return !1;
4625
4629
  }
4626
4630
  try {
4627
- n.push(Date.now()), sessionStorage.setItem(Rr, JSON.stringify(n)), sessionStorage.setItem(nn, String(Date.now()));
4631
+ n.push(Date.now()), sessionStorage.setItem(Fr, JSON.stringify(n)), sessionStorage.setItem(rn, String(Date.now()));
4628
4632
  } catch {
4629
4633
  }
4630
- pn("error", "buffer", `AUTO-RELOAD reason=${t} attempt=${n.length}/${Nn}`, e);
4634
+ mn("error", "buffer", `AUTO-RELOAD reason=${t} attempt=${n.length}/${Ln}`, e);
4631
4635
  try {
4632
4636
  window.location.reload();
4633
4637
  } catch {
4634
4638
  }
4635
4639
  return !0;
4636
4640
  }
4637
- function Ln() {
4641
+ function $n() {
4638
4642
  try {
4639
- const t = sessionStorage.getItem(nn);
4643
+ const t = sessionStorage.getItem(rn);
4640
4644
  return t ? Number(t) : null;
4641
4645
  } catch {
4642
4646
  return null;
4643
4647
  }
4644
4648
  }
4645
- function Oo() {
4649
+ function Ho() {
4646
4650
  try {
4647
- sessionStorage.removeItem(nn);
4651
+ sessionStorage.removeItem(rn);
4648
4652
  } catch {
4649
4653
  }
4650
4654
  }
4651
- function Ho() {
4655
+ function Uo() {
4652
4656
  const t = navigator;
4653
4657
  try {
4654
4658
  return typeof t.getAutoplayPolicy == "function" ? t.getAutoplayPolicy("mediaelement") : void 0;
@@ -4656,32 +4660,32 @@ function Ho() {
4656
4660
  return;
4657
4661
  }
4658
4662
  }
4659
- function Uo(t, e) {
4663
+ function jo(t, e) {
4660
4664
  return t === "disallowed" ? "deferred" : e ? "user-muted" : t === "allowed-muted" ? "muted-bridge" : "audible";
4661
4665
  }
4662
- function Nr(t, e) {
4663
- const n = Ho(), r = Uo(n, e.userWantsMuted);
4666
+ function Lr(t, e) {
4667
+ const n = Uo(), r = jo(n, e.userWantsMuted);
4664
4668
  E(e.label, "autoplay plan", { policy: n ?? "unknown", plan: r, userWantsMuted: e.userWantsMuted });
4665
4669
  const s = () => {
4666
4670
  t.muted = !0, t.play().then(() => {
4667
- e.onMutedBridge?.(), Tn(() => {
4671
+ e.onMutedBridge?.(), In(() => {
4668
4672
  e.userWantsMuted || (t.muted = !1, e.onUnmuted?.(), E(e.label, "autoplay bridge unmuted on interaction"));
4669
4673
  });
4670
4674
  }).catch((i) => C(e.label, "muted-bridge play failed", { error: i?.name }));
4671
4675
  };
4672
- return r === "deferred" ? (Tn(() => {
4676
+ return r === "deferred" ? (In(() => {
4673
4677
  t.play().catch((i) => C(e.label, "deferred play retry failed", { error: i?.name }));
4674
4678
  }), r) : r === "muted-bridge" ? (s(), r) : (t.muted = e.userWantsMuted, t.play().catch((i) => {
4675
4679
  i?.name === "NotAllowedError" && !e.userWantsMuted ? s() : i?.name !== "AbortError" && C(e.label, "video.play() failed", { error: i?.name, message: i?.message });
4676
4680
  }), r);
4677
4681
  }
4678
- const ht = {
4682
+ const pt = {
4679
4683
  /** Viewer join-time correction — can be preempted by any sync seek. */
4680
4684
  VIEWER_CORRECTION: 2,
4681
4685
  /** Room-level seeks from snapshot changes — highest priority. */
4682
4686
  SEEK_EFFECT: 3
4683
4687
  };
4684
- function Lr(t, e = 3e3) {
4688
+ function $r(t, e = 3e3) {
4685
4689
  return new Promise((n) => {
4686
4690
  if (!t.seeking) {
4687
4691
  n();
@@ -4700,7 +4704,7 @@ function Lr(t, e = 3e3) {
4700
4704
  t.addEventListener("seeked", s, { once: !0 });
4701
4705
  });
4702
4706
  }
4703
- class jo {
4707
+ class Go {
4704
4708
  // ── State ──
4705
4709
  _seekInFlight = !1;
4706
4710
  /** Route taken by the in-flight seek (buffered/loading/nearby-pending/far) —
@@ -4779,7 +4783,7 @@ class jo {
4779
4783
  } else
4780
4784
  E("seek-coord", `ALREADY BUFFERED [${s}] target=${Math.round(r)}ms`);
4781
4785
  const f = r / 1e3;
4782
- a.currentTime = f, await Lr(a), this._checkAborted(n);
4786
+ a.currentTime = f, await $r(a), this._checkAborted(n);
4783
4787
  const y = a.currentTime * 1e3, g = Math.round(performance.now() - o);
4784
4788
  C("seek-coord", `SEEK-DIGEST [${s}] route=${this._lastSeekRoute} ${g}ms`, {
4785
4789
  targetMs: Math.round(r),
@@ -4883,7 +4887,7 @@ class jo {
4883
4887
  }
4884
4888
  _resume(e) {
4885
4889
  const n = x.getState();
4886
- Nr(e, {
4890
+ Lr(e, {
4887
4891
  userWantsMuted: n.mediaPrefs.muted,
4888
4892
  onMutedBridge: () => x.getState().setMutedForAutoplay(!0),
4889
4893
  onUnmuted: () => x.getState().setMutedForAutoplay(!1),
@@ -4891,15 +4895,15 @@ class jo {
4891
4895
  });
4892
4896
  }
4893
4897
  }
4894
- let lt = null;
4895
- function Go() {
4896
- lt === null && (E("health", "Starting health reporting"), $n(), lt = window.setInterval($n, Ns));
4897
- }
4898
+ let dt = null;
4898
4899
  function Wo() {
4899
- lt !== null && (E("health", "Stopping health reporting"), window.clearInterval(lt), lt = null);
4900
+ dt === null && (E("health", "Starting health reporting"), Pn(), dt = window.setInterval(Pn, Ls));
4900
4901
  }
4901
- function $n() {
4902
- const t = qn();
4902
+ function Vo() {
4903
+ dt !== null && (E("health", "Stopping health reporting"), window.clearInterval(dt), dt = null);
4904
+ }
4905
+ function Pn() {
4906
+ const t = Yn();
4903
4907
  if (!t.connected) return;
4904
4908
  const e = x.getState();
4905
4909
  if (!e.snapshot.mediaId) return;
@@ -4917,7 +4921,7 @@ function $n() {
4917
4921
  (o < 0 || y < o) && (o = y);
4918
4922
  }
4919
4923
  const c = Math.max(0, a - s), u = o < 0 ? c : Math.min(c, o), h = e.drift.rtts.length > 0 ? e.drift.rtts.reduce((f, y) => f + y, 0) / e.drift.rtts.length : 0;
4920
- t.emit(Yn.HEALTH_REPORT, {
4924
+ t.emit(Xn.HEALTH_REPORT, {
4921
4925
  avg_download_rate_bps: n.getAverageDownloadRate(),
4922
4926
  buffered_ahead_ms: u,
4923
4927
  audio_buffered_ahead_ms: o < 0 ? -1 : Math.round(o),
@@ -4929,13 +4933,13 @@ function $n() {
4929
4933
  fragments_error: i.fragmentStates.error || 0,
4930
4934
  video_ready_state: r?.readyState ?? -1,
4931
4935
  duration_ms: n.getMediaEndMs(),
4932
- delivery_arm: $s(),
4933
- ...Vo(r),
4934
- pong_age_ms: Ls(),
4936
+ delivery_arm: Ps(),
4937
+ ...Ko(r),
4938
+ pong_age_ms: $s(),
4935
4939
  reported_at: Date.now()
4936
4940
  });
4937
4941
  }
4938
- function Vo(t) {
4942
+ function Ko(t) {
4939
4943
  const e = typeof navigator > "u" ? void 0 : navigator, n = e?.connection;
4940
4944
  return {
4941
4945
  page_visible: typeof document.visibilityState == "string" ? document.visibilityState === "visible" : void 0,
@@ -4947,8 +4951,8 @@ function Vo(t) {
4947
4951
  net_downlink_mbps: typeof n?.downlink == "number" && n.downlink >= 0 ? n.downlink : void 0
4948
4952
  };
4949
4953
  }
4950
- const Ko = 3e3;
4951
- function zo() {
4954
+ const zo = 3e3;
4955
+ function Jo() {
4952
4956
  const [t, e] = $(!1), n = P(null), r = P(!1), s = () => {
4953
4957
  n.current && (clearTimeout(n.current), n.current = null);
4954
4958
  }, i = U((o = 3e3) => {
@@ -4958,7 +4962,7 @@ function zo() {
4958
4962
  }, []), a = U(() => {
4959
4963
  r.current || (s(), e(!1));
4960
4964
  }, []), l = U((o) => {
4961
- r.current !== o && (r.current = o, o ? (s(), e(!0)) : i(Ko));
4965
+ r.current !== o && (r.current = o, o ? (s(), e(!0)) : i(zo));
4962
4966
  }, [i]);
4963
4967
  return L(() => {
4964
4968
  const o = () => {
@@ -4969,27 +4973,27 @@ function zo() {
4969
4973
  };
4970
4974
  }, [i]), { controlsVisible: t, showControls: i, hideControls: a, setControlsHeld: l };
4971
4975
  }
4972
- const $r = [], Pr = [], Jo = {
4973
- fragments: $r,
4976
+ const Pr = [], Dr = [], Qo = {
4977
+ fragments: Pr,
4974
4978
  durationMs: null,
4975
4979
  mseCodec: null,
4976
4980
  initSegment: void 0,
4977
- audioTracks: Pr,
4981
+ audioTracks: Dr,
4978
4982
  contentToken: null
4979
4983
  };
4980
- function Qo(t, e) {
4981
- if (!t || t.url !== e) return Jo;
4984
+ function qo(t, e) {
4985
+ if (!t || t.url !== e) return Qo;
4982
4986
  const n = t.data;
4983
4987
  return {
4984
- fragments: n.fragments || $r,
4988
+ fragments: n.fragments || Pr,
4985
4989
  durationMs: n.duration_ms || null,
4986
4990
  mseCodec: n.mse_codec || null,
4987
4991
  initSegment: n.init_segment || void 0,
4988
- audioTracks: n.audio_tracks || Pr,
4992
+ audioTracks: n.audio_tracks || Dr,
4989
4993
  contentToken: n.content_token || null
4990
4994
  };
4991
4995
  }
4992
- function Pn(t) {
4996
+ function Dn(t) {
4993
4997
  try {
4994
4998
  const e = performance.getEntriesByName(t, "resource");
4995
4999
  if (!e.length) return null;
@@ -5007,7 +5011,7 @@ function Pn(t) {
5007
5011
  return null;
5008
5012
  }
5009
5013
  }
5010
- function qo(t) {
5014
+ function Yo(t) {
5011
5015
  const [e, n] = $(null);
5012
5016
  return L(() => {
5013
5017
  const r = new AbortController();
@@ -5028,7 +5032,7 @@ function qo(t) {
5028
5032
  const u = await o.text(), h = Math.round(performance.now() - l) - c, f = JSON.parse(u), y = Math.round(performance.now() - l) - c - h, g = c + h + y;
5029
5033
  if (r.signal.aborted) return;
5030
5034
  n({ url: t, data: f });
5031
- const p = Pn(t);
5035
+ const p = Dn(t);
5032
5036
  E("mse", "Index loaded", {
5033
5037
  attempt: i + 1,
5034
5038
  headerMs: c,
@@ -5046,13 +5050,13 @@ function qo(t) {
5046
5050
  } catch (o) {
5047
5051
  if (r.signal.aborted) return;
5048
5052
  i++;
5049
- const c = Math.round(performance.now() - l), u = Pn(t);
5053
+ const c = Math.round(performance.now() - l), u = Dn(t);
5050
5054
  C("mse", `Index fetch attempt ${i} failed (${c}ms)`, {
5051
5055
  error: o?.message,
5052
5056
  elapsedMs: c,
5053
5057
  ...u && { timing: u }
5054
5058
  });
5055
- const h = i <= 1 ? 0 : ct(i - 1, { baseMs: 500, capMs: a, jitter: 0 });
5059
+ const h = i <= 1 ? 0 : lt(i - 1, { baseMs: 500, capMs: a, jitter: 0 });
5056
5060
  h > 0 && await new Promise((f) => setTimeout(f, h));
5057
5061
  }
5058
5062
  }
@@ -5060,18 +5064,18 @@ function qo(t) {
5060
5064
  return s(), () => {
5061
5065
  r.abort();
5062
5066
  };
5063
- }, [t]), Ee(() => Qo(e, t), [e, t]);
5067
+ }, [t]), Me(() => qo(e, t), [e, t]);
5064
5068
  }
5065
- const Ut = {
5069
+ const jt = {
5066
5070
  audioTracks: [],
5067
5071
  subtitleTracks: [],
5068
5072
  selectedAudioIndex: 0,
5069
5073
  selectedSubtitleIndex: 0
5070
5074
  };
5071
- function Yo(t) {
5072
- const [e, n] = $(Ut), r = Ps(), s = x((u) => u.mediaPrefs.preferredAudioLang), [i, a] = $(t);
5073
- i !== t && (a(t), t && n(Ut));
5074
- const l = fe(() => ({ origin: Ds(r), preferredAudioLang: s }));
5075
+ function Xo(t) {
5076
+ const [e, n] = $(jt), r = Ds(), s = x((u) => u.mediaPrefs.preferredAudioLang), [i, a] = $(t);
5077
+ i !== t && (a(t), t && n(jt));
5078
+ const l = fe(() => ({ origin: Bs(r), preferredAudioLang: s }));
5075
5079
  L(() => {
5076
5080
  if (!t) return;
5077
5081
  const u = new AbortController(), { origin: h, preferredAudioLang: f } = l();
@@ -5084,7 +5088,7 @@ function Yo(t) {
5084
5088
  } catch (g) {
5085
5089
  const p = Y(g);
5086
5090
  if (p.name === "AbortError") return;
5087
- C("mse", "Tracks fetch error", { mediaId: t, status: y?.status, ...p }), n(Ut);
5091
+ C("mse", "Tracks fetch error", { mediaId: t, status: y?.status, ...p }), n(jt);
5088
5092
  }
5089
5093
  })().catch((g) => ee("mse", "Tracks load threw", { mediaId: t, ...Y(g) })), () => {
5090
5094
  u.abort();
@@ -5104,12 +5108,12 @@ function Yo(t) {
5104
5108
  setSelectedSubtitleIndex: c
5105
5109
  };
5106
5110
  }
5107
- const Xo = 100;
5108
- function Zo(t) {
5109
- return !t.roomPlaying || t.videoPaused ? "not-playing" : t.seekInFlight ? "seeking" : t.advancedMs > Xo ? "advancing" : "stalled";
5111
+ const Zo = 100;
5112
+ function ec(t) {
5113
+ return !t.roomPlaying || t.videoPaused ? "not-playing" : t.seekInFlight ? "seeking" : t.advancedMs > Zo ? "advancing" : "stalled";
5110
5114
  }
5111
- const jt = 4e4, ec = 3e3;
5112
- function tc(t, e, n, r, s, i) {
5115
+ const Gt = 4e4, tc = 3e3;
5116
+ function nc(t, e, n, r, s, i) {
5113
5117
  const a = fe((w) => {
5114
5118
  const A = {};
5115
5119
  return (i?.current ?? []).forEach((k, m) => {
@@ -5134,13 +5138,13 @@ function tc(t, e, n, r, s, i) {
5134
5138
  function F() {
5135
5139
  A();
5136
5140
  const S = t.current;
5137
- S && (p.current = S.currentTime, g.current = setTimeout(k, ec));
5141
+ S && (p.current = S.currentTime, g.current = setTimeout(k, tc));
5138
5142
  }
5139
5143
  function k() {
5140
5144
  g.current = null;
5141
5145
  const S = t.current;
5142
5146
  if (!S) return;
5143
- const I = x.getState(), B = n.current, H = Zo({
5147
+ const I = x.getState(), B = n.current, H = ec({
5144
5148
  roomPlaying: I.snapshot.playing,
5145
5149
  videoPaused: S.paused,
5146
5150
  seekInFlight: !!B?.seekInFlight,
@@ -5167,13 +5171,13 @@ function tc(t, e, n, r, s, i) {
5167
5171
  ...a(j)
5168
5172
  }), l(j, "silent-stall"), K) {
5169
5173
  K.reconcileLoadedStates();
5170
- const O = K.findNextRangeStart(j, Dt);
5174
+ const O = K.findNextRangeStart(j, Bt);
5171
5175
  O !== null && B ? (C("sync", "SILENT-STALL gap-skip", {
5172
5176
  currentMs: Math.round(j),
5173
5177
  gapSkipTarget: Math.round(O)
5174
5178
  }), B.submit({
5175
5179
  targetMs: O,
5176
- priority: ht.VIEWER_CORRECTION,
5180
+ priority: pt.VIEWER_CORRECTION,
5177
5181
  caller: "silent-stall-gap-skip",
5178
5182
  pauseSeekResume: !1
5179
5183
  }).catch((Q) => ee("sync", "SILENT-STALL gap-skip seek threw", Y(Q)))) : K.fetchNearby(j).catch((Q) => {
@@ -5184,8 +5188,8 @@ function tc(t, e, n, r, s, i) {
5184
5188
  });
5185
5189
  });
5186
5190
  }
5187
- if (N >= jt) {
5188
- K?.dumpBufferDiagnostics(j, "silent-stall-reload"), Jt("silent-stall", {
5191
+ if (N >= Gt) {
5192
+ K?.dumpBufferDiagnostics(j, "silent-stall-reload"), Qt("silent-stall", {
5189
5193
  frozenMs: N,
5190
5194
  currentTime: +S.currentTime.toFixed(2),
5191
5195
  readyState: S.readyState,
@@ -5220,14 +5224,14 @@ function tc(t, e, n, r, s, i) {
5220
5224
  }
5221
5225
  if (B && !X?.seekInFlight && S > 0 && l(S, "waiting"), B && K && !X?.seekInFlight && S > 0) {
5222
5226
  K.reconcileLoadedStates();
5223
- const O = K.getBufferedAheadMs(S), Q = K.findNextRangeStart(S, Dt);
5227
+ const O = K.getBufferedAheadMs(S), Q = K.findNextRangeStart(S, Bt);
5224
5228
  if (Q !== null && X)
5225
5229
  C("sync", "GAP-SKIP seeking over late-IDR gap", {
5226
5230
  currentMs: Math.round(S),
5227
5231
  gapSkipTarget: Math.round(Q)
5228
5232
  }), X.submit({
5229
5233
  targetMs: Q,
5230
- priority: ht.VIEWER_CORRECTION,
5234
+ priority: pt.VIEWER_CORRECTION,
5231
5235
  caller: "gap-skip",
5232
5236
  pauseSeekResume: !1
5233
5237
  }).catch((W) => ee("sync", "GAP-SKIP seek threw", Y(W)));
@@ -5239,7 +5243,7 @@ function tc(t, e, n, r, s, i) {
5239
5243
  aheadInRangeMs: Math.round(W.aheadInRangeMs),
5240
5244
  nextRangeStartMs: Math.round(W.nextRangeStartMs),
5241
5245
  gapMs: W.gapMs !== null ? Math.round(W.gapMs) : null,
5242
- windowMs: Dt
5246
+ windowMs: Bt
5243
5247
  }), K.fetchNearby(S).catch((re) => {
5244
5248
  const le = Y(re);
5245
5249
  le.name !== "AbortError" && C("sync", "Stall recovery fetchNearby failed", {
@@ -5252,35 +5256,35 @@ function tc(t, e, n, r, s, i) {
5252
5256
  H && B && !c.current && (c.current = setTimeout(() => {
5253
5257
  c.current = null;
5254
5258
  const O = x.getState(), Q = !!O.snapshot.leaderId && O.snapshot.leaderId === O.me.clientId, W = !!n.current?.seekInFlight;
5255
- Q && !w.paused && w.readyState < 3 && !W && (C("sync", "Leader stall threshold reached — pausing room", { stallMs: mn }), u.current = !0, Pe("pause"));
5256
- }, mn)), B && !f.current && (y.current = w.currentTime, f.current = setTimeout(() => {
5259
+ Q && !w.paused && w.readyState < 3 && !W && (C("sync", "Leader stall threshold reached — pausing room", { stallMs: gn }), u.current = !0, De("pause"));
5260
+ }, gn)), B && !f.current && (y.current = w.currentTime, f.current = setTimeout(() => {
5257
5261
  f.current = null;
5258
5262
  const O = t.current;
5259
5263
  if (!O) return;
5260
- const W = x.getState().snapshot.playing, re = e.current, le = re?.getBufferedAheadMs(O.currentTime * 1e3) ?? -1, Re = O.currentTime - y.current;
5261
- if (!(W && Re < 0.5 && O.readyState < 3 && le < 1e3)) {
5264
+ const W = x.getState().snapshot.playing, re = e.current, le = re?.getBufferedAheadMs(O.currentTime * 1e3) ?? -1, Fe = O.currentTime - y.current;
5265
+ if (!(W && Fe < 0.5 && O.readyState < 3 && le < 1e3)) {
5262
5266
  E("sync", "STUCK-CHECK cleared — playback progressed, no reload", {
5263
- advancedSec: +Re.toFixed(2),
5267
+ advancedSec: +Fe.toFixed(2),
5264
5268
  readyState: O.readyState,
5265
5269
  bufferedAheadMs: Math.round(le),
5266
5270
  playing: W
5267
5271
  });
5268
5272
  return;
5269
5273
  }
5270
- re?.dumpBufferDiagnostics(O.currentTime * 1e3, "stuck-reload"), Jt("stuck-watchdog", {
5271
- stuckMs: jt,
5272
- advancedSec: +Re.toFixed(2),
5274
+ re?.dumpBufferDiagnostics(O.currentTime * 1e3, "stuck-reload"), Qt("stuck-watchdog", {
5275
+ stuckMs: Gt,
5276
+ advancedSec: +Fe.toFixed(2),
5273
5277
  currentTime: +O.currentTime.toFixed(2),
5274
5278
  readyState: O.readyState,
5275
5279
  bufferedAheadMs: Math.round(le),
5276
5280
  loaded: re?.getLoadedCount?.() ?? -1
5277
5281
  });
5278
- }, jt));
5282
+ }, Gt));
5279
5283
  }
5280
5284
  function R() {
5281
5285
  oe.recordStallEnd(), c.current && (clearTimeout(c.current), c.current = null), f.current && (clearTimeout(f.current), f.current = null), v.current = null, F();
5282
5286
  const S = x.getState(), I = S.snapshot.playing, B = !!S.snapshot.leaderId && S.snapshot.leaderId === S.me.clientId;
5283
- !I && !w.paused && o(w), B && u.current && !I && (u.current = !1, C("sync", "Leader stall recovered — resuming room", { currentTime: w.currentTime.toFixed(2) }), Pe("play"));
5287
+ !I && !w.paused && o(w), B && u.current && !I && (u.current = !1, C("sync", "Leader stall recovered — resuming room", { currentTime: w.currentTime.toFixed(2) }), De("play"));
5284
5288
  const H = h.current !== null ? Date.now() - h.current : null;
5285
5289
  h.current = null;
5286
5290
  const j = x.getState(), K = j.snapshot.playheadMs + (j.snapshot.playing ? Date.now() - j.snapshotReceivedAt : 0), X = w.currentTime * 1e3;
@@ -5300,8 +5304,8 @@ function tc(t, e, n, r, s, i) {
5300
5304
  };
5301
5305
  }, [r, t, e, n]);
5302
5306
  }
5303
- const nc = 1.5;
5304
- function rc(t, e, n, r, s, i) {
5307
+ const rc = 1.5;
5308
+ function sc(t, e, n, r, s, i) {
5305
5309
  const a = P(null), l = P(null), o = U(() => {
5306
5310
  a.current && (clearInterval(a.current), a.current = null), l.current?.(), l.current = null;
5307
5311
  }, []);
@@ -5328,9 +5332,9 @@ function rc(t, e, n, r, s, i) {
5328
5332
  s({ bufferedEndMs: v });
5329
5333
  }
5330
5334
  };
5331
- a.current = setInterval(y, gn);
5335
+ a.current = setInterval(y, bn);
5332
5336
  const g = () => {
5333
- performance.now() - f >= gn * nc && y();
5337
+ performance.now() - f >= bn * rc && y();
5334
5338
  };
5335
5339
  if (c && (c.addEventListener("timeupdate", g), l.current = () => c.removeEventListener("timeupdate", g)), c && !n.current?.seekInFlight) {
5336
5340
  f = performance.now();
@@ -5340,20 +5344,20 @@ function rc(t, e, n, r, s, i) {
5340
5344
  return o;
5341
5345
  }, [r, s, t, e, n, i, o]), { stopPrefetch: o };
5342
5346
  }
5343
- function sc(t, e, n, r, s, i) {
5347
+ function ac(t, e, n, r, s, i) {
5344
5348
  const a = x((h) => h.snapshot), l = x((h) => h.loadGeneration), o = P(l), c = fe((h) => s(h)), u = fe((h) => i(h));
5345
5349
  L(() => {
5346
5350
  const h = t.current;
5347
5351
  if (!h || !r) return;
5348
5352
  const f = a.playheadMs, y = n.current, g = l !== o.current;
5349
- o.current = l, !(!g && Math.abs(f - y) <= Bs) && (E("buffer", "Seek triggered", {
5353
+ o.current = l, !(!g && Math.abs(f - y) <= Os) && (E("buffer", "Seek triggered", {
5350
5354
  targetMs: f,
5351
5355
  lastApplied: y,
5352
5356
  delta: Math.round(f - y),
5353
5357
  genChanged: g
5354
5358
  }), n.current = f, h.submit({
5355
5359
  targetMs: f,
5356
- priority: ht.SEEK_EFFECT,
5360
+ priority: pt.SEEK_EFFECT,
5357
5361
  caller: "seek-effect",
5358
5362
  pauseSeekResume: !0
5359
5363
  }).catch((p) => ee("buffer", "Seek effect submit threw", Y(p))));
@@ -5364,7 +5368,7 @@ function sc(t, e, n, r, s, i) {
5364
5368
  f && y ? (E("sync", "Play/pause sync", { playing: f, videoPaused: y, currentTime: Math.round(h.currentTime * 1e3) }), c(h)) : !f && !y && (E("sync", "Play/pause sync", { playing: f, videoPaused: y, currentTime: Math.round(h.currentTime * 1e3) }), u(h));
5365
5369
  }, [a.playing, r, t, e]);
5366
5370
  }
5367
- function Dn(t, e) {
5371
+ function Bn(t, e) {
5368
5372
  return new Promise((n, r) => {
5369
5373
  const s = setTimeout(n, t);
5370
5374
  e.addEventListener("abort", () => {
@@ -5372,7 +5376,7 @@ function Dn(t, e) {
5372
5376
  }, { once: !0 });
5373
5377
  });
5374
5378
  }
5375
- function ac(t) {
5379
+ function ic(t) {
5376
5380
  const e = x((a) => a.playlist), n = x((a) => a.activePlaylistIndex), r = x((a) => a.snapshot.mediaId), s = e?.id, i = fe(() => e);
5377
5381
  L(() => {
5378
5382
  const a = i();
@@ -5382,16 +5386,16 @@ function ac(t) {
5382
5386
  for (let o = 0; o < a.videos.length; o++) {
5383
5387
  if (l.signal.aborted) return;
5384
5388
  if (o === n) continue;
5385
- const c = a.videos[o], { mediaUrl: u, indexUrl: h } = Xn(c.mediaId), f = 3e3, y = async () => {
5389
+ const c = a.videos[o], { mediaUrl: u, indexUrl: h } = Zn(c.mediaId), f = 3e3, y = async () => {
5386
5390
  for (; !l.signal.aborted && (t.current?.getPendingCount() ?? 0) !== 0; )
5387
5391
  try {
5388
- await Dn(2e3, l.signal);
5392
+ await Bn(2e3, l.signal);
5389
5393
  } catch {
5390
5394
  return !1;
5391
5395
  }
5392
5396
  if (l.signal.aborted) return !1;
5393
5397
  try {
5394
- await Dn(f, l.signal);
5398
+ await Bn(f, l.signal);
5395
5399
  } catch {
5396
5400
  return !1;
5397
5401
  }
@@ -5413,7 +5417,7 @@ function ac(t) {
5413
5417
  }
5414
5418
  const { fragments: p, init_segment: v } = g;
5415
5419
  if (!p?.length) continue;
5416
- const w = tn(p, 0), A = Ie(p, Ce), F = ve.getInit(c.mediaId) !== void 0, k = ve.getBufferedMs(c.mediaId, p) >= Ce;
5420
+ const w = nn(p, 0), A = Ce(p, Re), F = ve.getInit(c.mediaId) !== void 0, k = ve.getBufferedMs(c.mediaId, p) >= Re;
5417
5421
  if (F && k) {
5418
5422
  E("prebuffer", `${c.mediaId} already fully pre-buffered, skipping`);
5419
5423
  continue;
@@ -5424,7 +5428,7 @@ function ac(t) {
5424
5428
  const m = await fetch(u, {
5425
5429
  headers: {
5426
5430
  Range: `bytes=${v.start_byte}-${v.end_byte}`,
5427
- "X-Buffer-Ahead-Ms": String(bn)
5431
+ "X-Buffer-Ahead-Ms": String(yn)
5428
5432
  // background fetch — low priority
5429
5433
  },
5430
5434
  signal: l.signal
@@ -5447,7 +5451,7 @@ function ac(t) {
5447
5451
  const R = await fetch(u, {
5448
5452
  headers: {
5449
5453
  Range: `bytes=${T.start_byte}-${T.end_byte}`,
5450
- "X-Buffer-Ahead-Ms": String(bn)
5454
+ "X-Buffer-Ahead-Ms": String(yn)
5451
5455
  },
5452
5456
  signal: l.signal
5453
5457
  });
@@ -5470,12 +5474,12 @@ function ac(t) {
5470
5474
  };
5471
5475
  }, [s, n, r, t]);
5472
5476
  }
5473
- const Te = "bg-play";
5474
- function ic() {
5477
+ const Ie = "bg-play";
5478
+ function oc() {
5475
5479
  const t = x.getState();
5476
5480
  return !!t.snapshot.leaderId && t.snapshot.leaderId === t.me.clientId;
5477
5481
  }
5478
- function oc(t) {
5482
+ function cc(t) {
5479
5483
  return typeof Image > "u" ? Promise.resolve(null) : t.reduce(
5480
5484
  (e, n) => e.then((r) => r ?? new Promise((s) => {
5481
5485
  const i = new Image();
@@ -5484,38 +5488,38 @@ function oc(t) {
5484
5488
  Promise.resolve(null)
5485
5489
  );
5486
5490
  }
5487
- function cc(t, e, n, r, s, i) {
5491
+ function lc(t, e, n, r, s, i) {
5488
5492
  const a = P(!1), l = P(0), o = fe((u) => i(u)), c = fe((u) => {
5489
5493
  const h = t.current, f = e.current;
5490
5494
  if (!h || !s) return;
5491
- const y = x.getState(), g = h.currentTime * 1e3, p = uo(y.snapshot, y.snapshotReceivedAt, Date.now()), v = lo({
5495
+ const y = x.getState(), g = h.currentTime * 1e3, p = fo(y.snapshot, y.snapshotReceivedAt, Date.now()), v = uo({
5492
5496
  roomPlaying: y.snapshot.playing,
5493
5497
  seekInFlight: !!f?.seekInFlight,
5494
5498
  elementPaused: h.paused,
5495
5499
  elementMs: g,
5496
5500
  roomMs: p,
5497
5501
  durationMs: r,
5498
- driftToleranceMs: co
5502
+ driftToleranceMs: lo
5499
5503
  }), w = Math.round(p - g);
5500
5504
  if (v.kind === "none") {
5501
- E(Te, "resync not needed", { reason: u, driftMs: w });
5505
+ E(Ie, "resync not needed", { reason: u, driftMs: w });
5502
5506
  return;
5503
5507
  }
5504
- v.kind === "seek" ? C(Te, "BG-RESYNC seek", { reason: u, driftMs: w, elementMs: Math.round(g) }) : E(Te, "resync", { reason: u, plan: v.kind, driftMs: w }), v.kind === "resume" ? i(h) : f && f.submit({ targetMs: v.targetMs, priority: ht.SEEK_EFFECT, caller: `bg-resync:${u}` });
5508
+ v.kind === "seek" ? C(Ie, "BG-RESYNC seek", { reason: u, driftMs: w, elementMs: Math.round(g) }) : E(Ie, "resync", { reason: u, plan: v.kind, driftMs: w }), v.kind === "resume" ? i(h) : f && f.submit({ targetMs: v.targetMs, priority: pt.SEEK_EFFECT, caller: `bg-resync:${u}` });
5505
5509
  });
5506
5510
  L(() => {
5507
5511
  const u = t.current;
5508
5512
  if (!u || !s) return;
5509
5513
  const h = () => {
5510
5514
  const y = x.getState();
5511
- io({
5515
+ oo({
5512
5516
  hidden: document.visibilityState === "hidden",
5513
5517
  roomPlaying: y.snapshot.playing,
5514
5518
  seekInFlight: !!e.current?.seekInFlight,
5515
5519
  ended: u.ended,
5516
5520
  localPause: a.current,
5517
5521
  sinceUserPauseMs: l.current ? Date.now() - l.current : 1 / 0
5518
- }) && (E(Te, "keep-alive: browser paused a hidden video, resuming", { currentMs: Math.round(u.currentTime * 1e3) }), o(u));
5522
+ }) && (E(Ie, "keep-alive: browser paused a hidden video, resuming", { currentMs: Math.round(u.currentTime * 1e3) }), o(u));
5519
5523
  }, f = () => {
5520
5524
  document.visibilityState === "visible" && (a.current = !1, c("visible"));
5521
5525
  };
@@ -5527,19 +5531,19 @@ function cc(t, e, n, r, s, i) {
5527
5531
  if (!u || typeof navigator > "u" || !("mediaSession" in navigator)) return;
5528
5532
  const h = navigator.mediaSession;
5529
5533
  let f = !1;
5530
- const y = Cr(n), g = (k) => {
5534
+ const y = Rr(n), g = (k) => {
5531
5535
  f || typeof MediaMetadata > "u" || (h.metadata = new MediaMetadata({
5532
5536
  title: y,
5533
5537
  artist: "Watch Party",
5534
5538
  artwork: k ? [{ src: k }] : []
5535
5539
  }));
5536
5540
  };
5537
- g(null), oc(fo(n).map(Os)).then(g);
5541
+ g(null), cc(ho(n).map(Hs)).then(g);
5538
5542
  const p = (k) => () => {
5539
- const m = x.getState(), T = oo(k, { isLeader: ic(), roomPlaying: m.snapshot.playing });
5540
- switch (E(Te, "media session press", { action: k, result: T.kind }), k === "pause" && (l.current = Date.now()), T.kind) {
5543
+ const m = x.getState(), T = co(k, { isLeader: oc(), roomPlaying: m.snapshot.playing });
5544
+ switch (E(Ie, "media session press", { action: k, result: T.kind }), k === "pause" && (l.current = Date.now()), T.kind) {
5541
5545
  case "control":
5542
- Pe(T.control), T.control === "pause" && u.pause();
5546
+ De(T.control), T.control === "pause" && u.pause();
5543
5547
  break;
5544
5548
  case "local-pause":
5545
5549
  a.current = !0, u.pause();
@@ -5560,7 +5564,7 @@ function cc(t, e, n, r, s, i) {
5560
5564
  try {
5561
5565
  h.setActionHandler(k, m);
5562
5566
  } catch (T) {
5563
- E(Te, "media session action unsupported", { action: k, ...Y(T) });
5567
+ E(Ie, "media session action unsupported", { action: k, ...Y(T) });
5564
5568
  }
5565
5569
  const w = () => {
5566
5570
  const k = r / 1e3;
@@ -5568,7 +5572,7 @@ function cc(t, e, n, r, s, i) {
5568
5572
  try {
5569
5573
  h.setPositionState({ duration: k, position: Math.min(Math.max(u.currentTime, 0), k), playbackRate: u.playbackRate || 1 });
5570
5574
  } catch (m) {
5571
- C(Te, "setPositionState rejected", Y(m));
5575
+ C(Ie, "setPositionState rejected", Y(m));
5572
5576
  }
5573
5577
  }, A = () => {
5574
5578
  h.playbackState = "playing", w();
@@ -5590,7 +5594,7 @@ function cc(t, e, n, r, s, i) {
5590
5594
  let h = null, f = !1, y = !1;
5591
5595
  const g = () => {
5592
5596
  const v = h;
5593
- h = null, v && v.release().catch((w) => E(Te, "wake lock release failed", Y(w)));
5597
+ h = null, v && v.release().catch((w) => E(Ie, "wake lock release failed", Y(w)));
5594
5598
  }, p = () => {
5595
5599
  if (!(!y && !u.paused && !u.ended && document.visibilityState === "visible")) {
5596
5600
  g();
@@ -5601,7 +5605,7 @@ function cc(t, e, n, r, s, i) {
5601
5605
  h === w && (h = null);
5602
5606
  }), (y || u.paused || document.visibilityState !== "visible") && g();
5603
5607
  }).catch((w) => {
5604
- f = !1, E(Te, "wake lock refused", Y(w));
5608
+ f = !1, E(Ie, "wake lock refused", Y(w));
5605
5609
  }));
5606
5610
  };
5607
5611
  return u.addEventListener("play", p), u.addEventListener("pause", p), u.addEventListener("ended", p), document.addEventListener("visibilitychange", p), p(), () => {
@@ -5609,12 +5613,12 @@ function cc(t, e, n, r, s, i) {
5609
5613
  };
5610
5614
  }, [t]);
5611
5615
  }
5612
- const lc = 3e5, dc = 1, uc = 1;
5613
- function Gt(t) {
5616
+ const dc = 3e5, uc = 1, fc = 1;
5617
+ function Wt(t) {
5614
5618
  ee("buffer", "initializePlayback threw", Y(t));
5615
5619
  }
5616
- function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5617
- const r = P(null), [s, i] = $(!1), [a, l] = $(!1), { controlsVisible: o, showControls: c, hideControls: u, setControlsHeld: h } = zo();
5620
+ function hc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5621
+ const r = P(null), [s, i] = $(!1), [a, l] = $(!1), { controlsVisible: o, showControls: c, hideControls: u, setControlsHeld: h } = Jo();
5618
5622
  L(() => {
5619
5623
  const M = () => l(!!document.fullscreenElement);
5620
5624
  return document.addEventListener("fullscreenchange", M), () => document.removeEventListener("fullscreenchange", M);
@@ -5626,49 +5630,49 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5626
5630
  initSegment: p,
5627
5631
  audioTracks: v,
5628
5632
  contentToken: w
5629
- } = qo(e), A = U((M) => {
5633
+ } = Yo(e), A = U((M) => {
5630
5634
  if (!w) return null;
5631
- const D = t.replace(new RegExp(`/${gt.replace(/\./g, "\\.")}$`), "");
5635
+ const D = t.replace(new RegExp(`/${bt.replace(/\./g, "\\.")}$`), "");
5632
5636
  return D === t ? null : { baseUrl: D, token: w, trackId: M };
5633
- }, [w, t]), k = g !== null && v.length > 0, m = x((M) => M.readiness), T = P(!1), R = P(!1), b = P(null), S = P(null), I = P(null), B = P(0), H = P(0), j = P(null), [K, X] = $(0), N = P([]), O = P([]), Q = P(-1), W = P(!1), re = P(null), le = P(0), Re = P(null), Ke = P(0), kt = x((M) => M.bufferState), De = x((M) => M.setBufferState), {
5637
+ }, [w, t]), k = g !== null && v.length > 0, m = x((M) => M.readiness), T = P(!1), R = P(!1), b = P(null), S = P(null), I = P(null), B = P(0), H = P(0), j = P(null), [K, X] = $(0), N = P([]), O = P([]), Q = P(-1), W = P(!1), re = P(null), le = P(0), Fe = P(null), ze = P(0), _t = x((M) => M.bufferState), Be = x((M) => M.setBufferState), {
5634
5638
  audioTracks: ye,
5635
- subtitleTracks: Be,
5639
+ subtitleTracks: Oe,
5636
5640
  selectedAudioIndex: we,
5637
- setSelectedAudioIndex: rt,
5641
+ setSelectedAudioIndex: st,
5638
5642
  selectedSubtitleIndex: z,
5639
5643
  setSelectedSubtitleIndex: he
5640
- } = Yo(n), Me = x((M) => M.mediaPrefs), _t = x((M) => M.mutedForAutoplay), Dr = x((M) => M.setMutedForAutoplay), rn = x((M) => M.setSubtitlesEnabled), Br = x((M) => M.setSubtitleStyle), At = x((M) => M.setPreferredAudioLang), Or = Me.subtitlesEnabled, sn = Me.subtitleStyle, Hr = ye[we]?.lang, Ur = Be.some((M) => M.lang === "eng"), [jr, an] = $(null), st = Do({
5641
- override: jr,
5642
- globalEnabled: Or,
5643
- selectedAudioLang: Hr,
5644
- hasEngSub: Ur
5645
- }), Gr = U(() => {
5646
- const M = !st;
5647
- an(M), rn(M);
5648
- }, [st, rn]), mt = U((M) => {
5644
+ } = Xo(n), ke = x((M) => M.mediaPrefs), At = x((M) => M.mutedForAutoplay), Br = x((M) => M.setMutedForAutoplay), sn = x((M) => M.setSubtitlesEnabled), Or = x((M) => M.setSubtitleStyle), Tt = x((M) => M.setPreferredAudioLang), Hr = ke.subtitlesEnabled, an = ke.subtitleStyle, Ur = ye[we]?.lang, jr = Oe.some((M) => M.lang === "eng"), [Gr, on] = $(null), at = Bo({
5645
+ override: Gr,
5646
+ globalEnabled: Hr,
5647
+ selectedAudioLang: Ur,
5648
+ hasEngSub: jr
5649
+ }), Wr = U(() => {
5650
+ const M = !at;
5651
+ on(M), sn(M);
5652
+ }, [at, sn]), gt = U((M) => {
5649
5653
  const D = x.getState();
5650
- Nr(M, {
5654
+ Lr(M, {
5651
5655
  userWantsMuted: D.mediaPrefs.muted,
5652
5656
  onMutedBridge: () => D.setMutedForAutoplay(!0),
5653
5657
  onUnmuted: () => D.setMutedForAutoplay(!1),
5654
5658
  label: "video"
5655
5659
  });
5656
- }, []), on = U((M) => {
5660
+ }, []), cn = U((M) => {
5657
5661
  M.pause();
5658
- }, []), [Wr, cn] = $(0), [Vr, Kr] = $(n);
5659
- Vr !== n && (Kr(n), an(null), cn(0)), L(() => {
5662
+ }, []), [Vr, ln] = $(0), [Kr, zr] = $(n);
5663
+ Kr !== n && (zr(n), on(null), ln(0)), L(() => {
5660
5664
  const M = r.current;
5661
5665
  if (!M) return;
5662
5666
  const D = () => {
5663
- cn(Math.round(M.currentTime * 1e3));
5667
+ ln(Math.round(M.currentTime * 1e3));
5664
5668
  };
5665
5669
  return M.addEventListener("timeupdate", D), () => M.removeEventListener("timeupdate", D);
5666
5670
  }, []);
5667
- const at = U((M) => {
5668
- De({ isBuffering: M });
5669
- }, [De]), ln = U((M) => {
5670
- if (H.current >= uc) {
5671
- Jt("phantom-recreate-exhausted", { reason: M, recreates: H.current, mediaId: n });
5671
+ const it = U((M) => {
5672
+ Be({ isBuffering: M });
5673
+ }, [Be]), dn = U((M) => {
5674
+ if (H.current >= fc) {
5675
+ Qt("phantom-recreate-exhausted", { reason: M, recreates: H.current, mediaId: n });
5672
5676
  return;
5673
5677
  }
5674
5678
  H.current += 1, B.current = 0, C("buffer", "MSE-RECREATE — rebuilding MediaSource to clear corrupt buffer", {
@@ -5676,7 +5680,7 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5676
5680
  attempt: H.current
5677
5681
  }), X((D) => D + 1);
5678
5682
  }, [n]);
5679
- async function Tt() {
5683
+ async function It() {
5680
5684
  const M = I.current, D = r.current;
5681
5685
  if (!M || !f.length || R.current) return;
5682
5686
  const pe = x.getState().snapshot, V = pe.playheadMs || 0;
@@ -5691,33 +5695,33 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5691
5695
  })
5692
5696
  );
5693
5697
  if (await M.ensureBuffered(V, "initial"), M.isDisposed) return;
5694
- const ne = Hs;
5698
+ const ne = Us;
5695
5699
  await Promise.allSettled(te);
5696
5700
  const J = ie.map(
5697
- (G) => G.waitForBuffered(V + Ce, ne)
5698
- ), xe = await M.waitForBuffered(V + Ce, ne);
5701
+ (G) => G.waitForBuffered(V + Re, ne)
5702
+ ), xe = await M.waitForBuffered(V + Re, ne);
5699
5703
  if (await Promise.allSettled(J), xe || C("buffer", "Buffer gate timeout — proceeding with partial buffer", {
5700
5704
  startMs: V,
5701
5705
  aheadMs: Math.round(M.getBufferedAheadMs(V)),
5702
- targetMs: Ce
5706
+ targetMs: Re
5703
5707
  }), M.isDisposed) return;
5704
- if (M.getBufferedAheadMs(V) > lc && M.getLoadedCount() === 0) {
5708
+ if (M.getBufferedAheadMs(V) > dc && M.getLoadedCount() === 0) {
5705
5709
  M.dumpBufferDiagnostics(V, "phantom-detected"), C("buffer", "PHANTOM-BUFFER detected at gate — recreating MediaSource", {
5706
5710
  gateAheadMs: Math.round(M.getBufferedAheadMs(V)),
5707
5711
  loaded: M.getLoadedCount(),
5708
5712
  startMs: Math.round(V),
5709
5713
  recreateAttempt: H.current,
5710
5714
  mediaId: n
5711
- }), ln("phantom-buffer");
5715
+ }), dn("phantom-buffer");
5712
5716
  return;
5713
5717
  }
5714
- const Oe = Math.round(performance.now() - de);
5718
+ const He = Math.round(performance.now() - de);
5715
5719
  E("buffer", "Buffer gate passed", {
5716
5720
  aheadMs: Math.round(M.getBufferedAheadMs(V)),
5717
- totalMs: Oe
5721
+ totalMs: He
5718
5722
  });
5719
- const ke = xe ? "gate-pass" : "gate-timeout";
5720
- M.emitInitDigest("video", ke), ie.forEach((G, se) => G.emitInitDigest(`audio:${se}`, ke)), T.current || (T.current = !0, Us(n));
5723
+ const _e = xe ? "gate-pass" : "gate-timeout";
5724
+ M.emitInitDigest("video", _e), ie.forEach((G, se) => G.emitInitDigest(`audio:${se}`, _e)), T.current || (T.current = !0, js(n));
5721
5725
  let q = V;
5722
5726
  if (D && q > 0) {
5723
5727
  const G = D.buffered;
@@ -5725,16 +5729,16 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5725
5729
  const se = q / 1e3, ae = G.start(0);
5726
5730
  se < ae && ae - se < 1 && (q = ae * 1e3);
5727
5731
  }
5728
- D.currentTime = q / 1e3, await Lr(D, 3e3);
5732
+ D.currentTime = q / 1e3, await $r(D, 3e3);
5729
5733
  }
5730
- le.current = q, i(!0), R.current = !0, B.current = 0, Ln() && C("buffer", "RECOVERY-SUCCESS — playback initialized after an auto-reload", { mediaId: n }), Oo(), E("buffer", "initializePlayback complete", {
5734
+ le.current = q, i(!0), R.current = !0, B.current = 0, $n() && C("buffer", "RECOVERY-SUCCESS — playback initialized after an auto-reload", { mediaId: n }), Ho(), E("buffer", "initializePlayback complete", {
5731
5735
  mediaId: n,
5732
5736
  startMs: V,
5733
5737
  seekMs: q,
5734
5738
  initDurationMs: Math.round(performance.now() - de)
5735
5739
  });
5736
- const He = x.getState().snapshot;
5737
- if (D && He.playing && D.paused && (E("buffer", "initializePlayback: calling play()", { playing: He.playing }), mt(D)), M.isDisposed) return;
5740
+ const Ue = x.getState().snapshot;
5741
+ if (D && Ue.playing && D.paused && (E("buffer", "initializePlayback: calling play()", { playing: Ue.playing }), gt(D)), M.isDisposed) return;
5738
5742
  const ce = x.getState();
5739
5743
  if (!(!!ce.snapshot.leaderId && ce.snapshot.leaderId === ce.me.clientId) && ce.snapshot.playing)
5740
5744
  try {
@@ -5745,27 +5749,27 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5745
5749
  elapsed: G,
5746
5750
  correctedMs: se,
5747
5751
  deltaSec: ((se - V) / 1e3).toFixed(1),
5748
- initialBufferMs: Oe
5752
+ initialBufferMs: He
5749
5753
  }), se > V) {
5750
5754
  const ae = re.current;
5751
5755
  if (D && ae) {
5752
- const ue = x.getState(), me = Date.now() - ue.snapshotReceivedAt, Ue = ue.snapshot.playheadMs + me, Ae = Ue > se ? Ue : se;
5756
+ const ue = x.getState(), me = Date.now() - ue.snapshotReceivedAt, je = ue.snapshot.playheadMs + me, Te = je > se ? je : se;
5753
5757
  await ae.submit({
5754
- targetMs: Ae,
5755
- priority: ht.VIEWER_CORRECTION,
5758
+ targetMs: Te,
5759
+ priority: pt.VIEWER_CORRECTION,
5756
5760
  caller: "viewer-correction",
5757
5761
  pauseSeekResume: !0,
5758
- onComplete: (Fe) => {
5759
- le.current = Fe, E("buffer", "Viewer correction applied", {
5762
+ onComplete: (Ne) => {
5763
+ le.current = Ne, E("buffer", "Viewer correction applied", {
5760
5764
  startMs: V,
5761
5765
  correctedMs: se,
5762
- seekTarget: Ae,
5763
- actualMs: Fe,
5766
+ seekTarget: Te,
5767
+ actualMs: Ne,
5764
5768
  totalInitMs: Math.round(performance.now() - de)
5765
5769
  });
5766
5770
  },
5767
- onAborted: (Fe) => {
5768
- Fe === null ? C("buffer", "Viewer correction preempted by sync seek — OK") : C("buffer", "Viewer correction aborted", { error: Fe?.message });
5771
+ onAborted: (Ne) => {
5772
+ Ne === null ? C("buffer", "Viewer correction preempted by sync seek — OK") : C("buffer", "Viewer correction aborted", { error: Ne?.message });
5769
5773
  }
5770
5774
  });
5771
5775
  }
@@ -5782,7 +5786,7 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5782
5786
  error: ie?.message
5783
5787
  }), i(!0), R.current = !0;
5784
5788
  const te = x.getState().snapshot;
5785
- D && te.playing && D.paused && mt(D);
5789
+ D && te.playing && D.paused && gt(D);
5786
5790
  } else {
5787
5791
  const te = ie?.message || "";
5788
5792
  if (M.isDisposed || te.includes("FragmentManager disposed")) {
@@ -5792,29 +5796,29 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5792
5796
  return;
5793
5797
  }
5794
5798
  const ne = te.includes("SourceBuffer is full"), J = te.includes("init segment failed");
5795
- B.current += 1, ne || J || B.current > dc ? (ee("buffer", "Initialize playback failed — recreating MediaSource", {
5799
+ B.current += 1, ne || J || B.current > uc ? (ee("buffer", "Initialize playback failed — recreating MediaSource", {
5796
5800
  error: te,
5797
5801
  mediaId: n,
5798
5802
  attempt: B.current,
5799
5803
  sbFull: ne,
5800
5804
  initFailed: J
5801
- }), ln(ne ? "sourcebuffer-full" : J ? "init-failed" : "init-retry-cap")) : (ee("buffer", "Initialize playback error — will retry in 3s", {
5805
+ }), dn(ne ? "sourcebuffer-full" : J ? "init-failed" : "init-retry-cap")) : (ee("buffer", "Initialize playback error — will retry in 3s", {
5802
5806
  error: te,
5803
5807
  mediaId: n,
5804
5808
  attempt: B.current
5805
5809
  }), setTimeout(() => {
5806
- I.current && !M.isDisposed && !R.current && (E("buffer", "Retrying initializePlayback"), Tt().catch(Gt));
5810
+ I.current && !M.isDisposed && !R.current && (E("buffer", "Retrying initializePlayback"), It().catch(Wt));
5807
5811
  }, 3e3));
5808
5812
  }
5809
5813
  }
5810
5814
  }
5811
- const zr = fe(() => ({
5815
+ const Jr = fe(() => ({
5812
5816
  useMseAudio: k,
5813
5817
  selectedAudioIndex: we,
5814
5818
  mseAudioTracks: v,
5815
5819
  fragments: f,
5816
5820
  deliveryFor: A,
5817
- initializePlayback: Tt
5821
+ initializePlayback: It
5818
5822
  }));
5819
5823
  L(() => {
5820
5824
  if (!g) return;
@@ -5825,9 +5829,9 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5825
5829
  fragments: V,
5826
5830
  deliveryFor: de,
5827
5831
  initializePlayback: ie
5828
- } = zr();
5832
+ } = Jr();
5829
5833
  j.current !== n && (j.current = n, H.current = 0, B.current = 0);
5830
- const te = Ln();
5834
+ const te = $n();
5831
5835
  te && C("buffer", "POST-AUTO-RELOAD — this load follows an auto-reload recovery", {
5832
5836
  reloadAtMs: te,
5833
5837
  sinceReloadMs: Date.now() - te,
@@ -5836,24 +5840,24 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5836
5840
  let ne = null;
5837
5841
  const J = new MediaSource();
5838
5842
  S.current = J;
5839
- const xe = new Ze(at);
5843
+ const xe = new et(it);
5840
5844
  I.current = xe;
5841
- const Oe = ++Ke.current;
5845
+ const He = ++ze.current;
5842
5846
  window.__FRAGMENT_MANAGER__ = xe, window.__AUDIO_FRAGMENT_MANAGERS__ = N.current;
5843
- const ke = new jo({
5847
+ const _e = new Go({
5844
5848
  videoRef: r,
5845
5849
  fragmentManagerRef: I,
5846
5850
  audioFragmentManagersRef: N
5847
5851
  });
5848
- re.current = ke, window.__SEEK_COORDINATOR__ = ke, Go();
5849
- const q = r.current, He = () => {
5852
+ re.current = _e, window.__SEEK_COORDINATOR__ = _e, Wo();
5853
+ const q = r.current, Ue = () => {
5850
5854
  const G = q?.error;
5851
5855
  G && (ee("video", `Media error code=${G.code}: ${G.message}`, {
5852
5856
  code: G.code,
5853
5857
  networkState: q.networkState,
5854
5858
  readyState: q.readyState
5855
5859
  }), x.getState().pushToast("error", "Video playback error. Try reloading."));
5856
- }, ce = t.replace(new RegExp(`/${gt.replace(/\./g, "\\.")}$`), ""), _e = () => {
5860
+ }, ce = t.replace(new RegExp(`/${bt.replace(/\./g, "\\.")}$`), ""), Ae = () => {
5857
5861
  try {
5858
5862
  const G = `video/mp4; codecs="${g}"`;
5859
5863
  MediaSource.isTypeSupported(G) || (C("mse", `Codec not supported by browser MSE: ${G}`), x.getState().pushToast("error", "Video codec not supported by your browser.")), E("mse", `addSourceBuffer: ${G}`);
@@ -5871,47 +5875,47 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5871
5875
  C("mse", `Audio codec not supported: ${me}, track=${ue.track_id}`);
5872
5876
  else
5873
5877
  try {
5874
- const Ae = J.addSourceBuffer(me);
5875
- Ae.addEventListener("error", () => {
5878
+ const Te = J.addSourceBuffer(me);
5879
+ Te.addEventListener("error", () => {
5876
5880
  ee("mse", "Audio SourceBuffer error", {
5877
5881
  trackId: ue.track_id,
5878
5882
  readyState: J.readyState,
5879
- updating: Ae.updating
5883
+ updating: Te.updating
5880
5884
  });
5881
5885
  });
5882
- const Fe = new Ze(
5883
- at,
5886
+ const Ne = new et(
5887
+ it,
5884
5888
  { suppressEndOfStream: !0, label: `audio:${ue.track_id}` }
5885
5889
  );
5886
- Fe.setSourceBuffer(Ae, J), N.current.push(Fe), O.current.push(Ae), Q.current = ae, E("mse", `Audio SB added: codec=${me} track=${ue.track_id} lang=${ue.lang} idx=${ae}`);
5887
- } catch (Ae) {
5888
- C("mse", `Audio SB creation failed for track ${ue.track_id}`, { error: Ae?.message });
5890
+ Ne.setSourceBuffer(Te, J), N.current.push(Ne), O.current.push(Te), Q.current = ae, E("mse", `Audio SB added: codec=${me} track=${ue.track_id} lang=${ue.lang} idx=${ae}`);
5891
+ } catch (Te) {
5892
+ C("mse", `Audio SB creation failed for track ${ue.track_id}`, { error: Te?.message });
5889
5893
  }
5890
- const Ue = r.current;
5891
- Ue && (Ue.muted = !1);
5894
+ const je = r.current;
5895
+ je && (je.muted = !1);
5892
5896
  }
5893
5897
  if (V.length) {
5894
- if (xe.setIndex(V, t, p, n, de()), xe.epoch = Oe, M) {
5898
+ if (xe.setIndex(V, t, p, n, de()), xe.epoch = He, M) {
5895
5899
  const ae = Q.current, ue = N.current[0], me = ae >= 0 ? pe[ae] : void 0;
5896
5900
  if (ue && me) {
5897
- const Ue = `${ce}/${me.path}`.replace(/\\/g, "/");
5901
+ const je = `${ce}/${me.path}`.replace(/\\/g, "/");
5898
5902
  ue.setIndex(
5899
5903
  me.fragments,
5900
- Ue,
5904
+ je,
5901
5905
  me.init_segment,
5902
5906
  `${n}::audio::${me.track_id}`,
5903
5907
  de(me.track_id)
5904
- ), ue.epoch = Oe;
5908
+ ), ue.epoch = He;
5905
5909
  }
5906
5910
  }
5907
- ie().catch(Gt);
5911
+ ie().catch(Wt);
5908
5912
  }
5909
5913
  } catch (G) {
5910
5914
  C("buffer", "MSE source error", { error: G?.message });
5911
5915
  }
5912
5916
  };
5913
- return q && (J.addEventListener("sourceopen", _e), ne = URL.createObjectURL(J), q.src = ne, q.addEventListener("error", He)), () => {
5914
- q?.pause(), q && q.removeEventListener("error", He), J.removeEventListener("sourceopen", _e), Wo(), ke.dispose(), re.current = null, xe.dispose(), I.current = null, window.__FRAGMENT_MANAGER__ = null, window.__AUDIO_FRAGMENT_MANAGERS__ = null;
5917
+ return q && (J.addEventListener("sourceopen", Ae), ne = URL.createObjectURL(J), q.src = ne, q.addEventListener("error", Ue)), () => {
5918
+ q?.pause(), q && q.removeEventListener("error", Ue), J.removeEventListener("sourceopen", Ae), Vo(), _e.dispose(), re.current = null, xe.dispose(), I.current = null, window.__FRAGMENT_MANAGER__ = null, window.__AUDIO_FRAGMENT_MANAGERS__ = null;
5915
5919
  for (const G of N.current) G.dispose();
5916
5920
  if (N.current = [], J.readyState === "open") {
5917
5921
  for (const G of [b.current, ...O.current])
@@ -5926,15 +5930,15 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5926
5930
  q.removeAttribute("src"), q.load();
5927
5931
  } catch {
5928
5932
  }
5929
- Re.current?.(), R.current = !1, T.current = !1, b.current = null, i(!1);
5933
+ Fe.current?.(), R.current = !1, T.current = !1, b.current = null, i(!1);
5930
5934
  };
5931
- }, [t, n, g, p, at, K]);
5932
- const Jr = fe(() => {
5933
- const M = I.current, D = Ke.current;
5935
+ }, [t, n, g, p, it, K]);
5936
+ const Qr = fe(() => {
5937
+ const M = I.current, D = ze.current;
5934
5938
  if (S.current?.readyState === "open" && b.current && f.length && M) {
5935
5939
  if (M.hasIndex && M.epoch === D) return;
5936
5940
  if (M.setIndex(f, t, p, n, A()), M.epoch = D, k) {
5937
- const pe = t.replace(new RegExp(`/${gt.replace(/\./g, "\\.")}$`), ""), V = Q.current, de = N.current[0], ie = V >= 0 ? v[V] : void 0;
5941
+ const pe = t.replace(new RegExp(`/${bt.replace(/\./g, "\\.")}$`), ""), V = Q.current, de = N.current[0], ie = V >= 0 ? v[V] : void 0;
5938
5942
  if (de && ie && !(de.hasIndex && de.epoch === D)) {
5939
5943
  const te = `${pe}/${ie.path}`.replace(/\\/g, "/");
5940
5944
  de.setIndex(
@@ -5946,11 +5950,11 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5946
5950
  ), de.epoch = D;
5947
5951
  }
5948
5952
  }
5949
- R.current || Tt().catch(Gt);
5953
+ R.current || It().catch(Wt);
5950
5954
  }
5951
5955
  });
5952
5956
  L(() => {
5953
- Jr();
5957
+ Qr();
5954
5958
  }, [f, t, p, v]), L(() => {
5955
5959
  const M = () => {
5956
5960
  I.current?.abortStaleJobs("socket-reconnect");
@@ -5958,12 +5962,12 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5958
5962
  };
5959
5963
  return window.addEventListener("watchparty:socket-reconnect", M), () => window.removeEventListener("watchparty:socket-reconnect", M);
5960
5964
  }, []), L(() => (window.__AUDIO_SELECT__ = (M) => {
5961
- rt(M);
5965
+ st(M);
5962
5966
  const D = ye[M];
5963
- D?.lang && At(D.lang);
5967
+ D?.lang && Tt(D.lang);
5964
5968
  }, () => {
5965
5969
  window.__AUDIO_SELECT__ = null;
5966
- }), [ye, rt, At]), L(() => {
5970
+ }), [ye, st, Tt]), L(() => {
5967
5971
  if (!k || !s || we < 0 || we >= v.length || we === Q.current) return;
5968
5972
  if (W.current) {
5969
5973
  E("audio", "MSE audio swap requested while another in flight — deferring");
@@ -5976,7 +5980,7 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5976
5980
  }
5977
5981
  const D = r.current;
5978
5982
  if (!D) return;
5979
- const pe = we, V = v[pe], de = Ke.current;
5983
+ const pe = we, V = v[pe], de = ze.current;
5980
5984
  W.current = !0;
5981
5985
  const ie = Math.round(D.currentTime * 1e3);
5982
5986
  E("audio", `MSE audio swap START idx=${Q.current}→${pe} lang=${V.lang} playheadMs=${ie}`), (async () => {
@@ -5989,11 +5993,11 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
5989
5993
  te && te.dispose();
5990
5994
  try {
5991
5995
  if (ne.updating && ne.abort(), M.readyState === "open") {
5992
- const ce = new Promise((_e) => {
5996
+ const ce = new Promise((Ae) => {
5993
5997
  const G = () => {
5994
- ne.removeEventListener("updateend", G), _e();
5998
+ ne.removeEventListener("updateend", G), Ae();
5995
5999
  };
5996
- ne.addEventListener("updateend", G, { once: !0 }), setTimeout(_e, 2e3);
6000
+ ne.addEventListener("updateend", G, { once: !0 }), setTimeout(Ae, 2e3);
5997
6001
  });
5998
6002
  ne.remove(0, 1 / 0), await ce;
5999
6003
  }
@@ -6004,41 +6008,41 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
6004
6008
  C("audio", "MSE audio swap aborted mid-flight — MS no longer open");
6005
6009
  return;
6006
6010
  }
6007
- const J = new Ze(
6008
- at,
6011
+ const J = new et(
6012
+ it,
6009
6013
  { suppressEndOfStream: !0, label: `audio:${V.track_id}` }
6010
6014
  );
6011
6015
  J.setSourceBuffer(ne, M);
6012
- const Oe = `${t.replace(new RegExp(`/${gt.replace(/\./g, "\\.")}$`), "")}/${V.path}`.replace(/\\/g, "/");
6016
+ const He = `${t.replace(new RegExp(`/${bt.replace(/\./g, "\\.")}$`), "")}/${V.path}`.replace(/\\/g, "/");
6013
6017
  J.setIndex(
6014
6018
  V.fragments,
6015
- Oe,
6019
+ He,
6016
6020
  V.init_segment,
6017
6021
  `${n}::audio::${V.track_id}`,
6018
6022
  A(V.track_id)
6019
6023
  ), J.epoch = de, N.current.length = 0, N.current.push(J), Q.current = pe;
6020
- const ke = re.current?.inFlightTargetMs ?? Math.round(D.currentTime * 1e3), q = new AbortController();
6021
- J.setPlayhead(ke);
6022
- const He = J.ensureBuffered(ke, "audio-swap", q.signal);
6023
- J.supersededSignal.addEventListener("abort", () => q.abort(), { once: !0 }), He.catch((ce) => {
6024
- const _e = J.isDisposed || q.signal.aborted;
6025
- (_e ? E : C)("audio", _e ? "audio-swap load superseded by a seek or a later swap" : "audio-swap ensureBuffered failed", { error: ce?.message });
6024
+ const _e = re.current?.inFlightTargetMs ?? Math.round(D.currentTime * 1e3), q = new AbortController();
6025
+ J.setPlayhead(_e);
6026
+ const Ue = J.ensureBuffered(_e, "audio-swap", q.signal);
6027
+ J.supersededSignal.addEventListener("abort", () => q.abort(), { once: !0 }), Ue.catch((ce) => {
6028
+ const Ae = J.isDisposed || q.signal.aborted;
6029
+ (Ae ? E : C)("audio", Ae ? "audio-swap load superseded by a seek or a later swap" : "audio-swap ensureBuffered failed", { error: ce?.message });
6026
6030
  }), E("audio", `MSE audio swap DONE idx=${pe} track=${V.track_id}`);
6027
6031
  } finally {
6028
6032
  W.current = !1;
6029
6033
  }
6030
6034
  })().catch((te) => ee("audio", "MSE audio swap failed", Y(te)));
6031
- }, [k, s, we, v, n, t, at, A]), sc(re, r, le, s, mt, on), tc(r, I, re, s, on, N), cc(r, re, n, y ?? 0, s, mt);
6032
- const { stopPrefetch: dn } = rc(r, I, re, s, De, N);
6033
- ac(I), L(() => {
6034
- Re.current = dn;
6035
- }, [dn]);
6036
- const Qr = U(() => {
6035
+ }, [k, s, we, v, n, t, it, A]), ac(re, r, le, s, gt, cn), nc(r, I, re, s, cn, N), lc(r, re, n, y ?? 0, s, gt);
6036
+ const { stopPrefetch: un } = sc(r, I, re, s, Be, N);
6037
+ ic(I), L(() => {
6038
+ Fe.current = un;
6039
+ }, [un]);
6040
+ const qr = U(() => {
6037
6041
  const M = r.current?.parentElement;
6038
6042
  M && (document.fullscreenElement ? document.exitFullscreen().catch((D) => C("ui", "exitFullscreen failed", Y(D))) : M.requestFullscreen().catch((D) => C("ui", "requestFullscreen failed", Y(D))));
6039
- }, []), qr = U((M) => {
6043
+ }, []), Yr = U((M) => {
6040
6044
  M.preventDefault();
6041
- }, []), Yr = st && Be[z] ? Be[z].url : null;
6045
+ }, []), Xr = at && Oe[z] ? Oe[z].url : null;
6042
6046
  return /* @__PURE__ */ _(
6043
6047
  "div",
6044
6048
  {
@@ -6053,62 +6057,62 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
6053
6057
  ref: r,
6054
6058
  className: "w-full h-full",
6055
6059
  playsInline: !0,
6056
- onDoubleClick: Qr,
6057
- onContextMenu: qr
6060
+ onDoubleClick: qr,
6061
+ onContextMenu: Yr
6058
6062
  }
6059
6063
  ),
6060
6064
  /* @__PURE__ */ d(
6061
- ko,
6065
+ _o,
6062
6066
  {
6063
- subtitleUrl: Yr,
6067
+ subtitleUrl: Xr,
6064
6068
  videoRef: r,
6065
- style: sn,
6066
- enabled: st
6069
+ style: an,
6070
+ enabled: at
6067
6071
  }
6068
6072
  ),
6069
- /* @__PURE__ */ d(ho, { mediaId: n, visible: o }),
6073
+ /* @__PURE__ */ d(po, { mediaId: n, visible: o }),
6070
6074
  /* @__PURE__ */ d(
6071
- so,
6075
+ ao,
6072
6076
  {
6073
6077
  videoRef: r,
6074
6078
  mediaId: n,
6075
6079
  durationMs: y || void 0,
6076
6080
  visible: o,
6077
- displayPlayheadMs: Wr,
6081
+ displayPlayheadMs: Vr,
6078
6082
  audioTracks: ye,
6079
6083
  selectedAudioIndex: we,
6080
6084
  onAudioSelect: (M) => {
6081
- rt(M);
6085
+ st(M);
6082
6086
  const D = ye[M];
6083
- D?.lang && At(D.lang);
6087
+ D?.lang && Tt(D.lang);
6084
6088
  },
6085
- subtitleTracks: Be,
6089
+ subtitleTracks: Oe,
6086
6090
  selectedSubtitleIndex: z,
6087
6091
  onSubtitleSelect: he,
6088
- subtitlesEnabled: st,
6089
- onSubtitlesToggle: Gr,
6090
- subtitleStyle: sn,
6091
- onSubtitleStyleChange: Br,
6092
+ subtitlesEnabled: at,
6093
+ onSubtitlesToggle: Wr,
6094
+ subtitleStyle: an,
6095
+ onSubtitleStyleChange: Or,
6092
6096
  onChatActivity: () => c(5e3),
6093
6097
  onMenuHeld: h
6094
6098
  }
6095
6099
  ),
6096
- _t && /* @__PURE__ */ _(
6100
+ At && /* @__PURE__ */ _(
6097
6101
  "button",
6098
6102
  {
6099
6103
  type: "button",
6100
6104
  onClick: () => {
6101
6105
  const M = r.current;
6102
- M && (M.muted = !1), Dr(!1);
6106
+ M && (M.muted = !1), Br(!1);
6103
6107
  },
6104
6108
  className: "autoplay-sound-badge",
6105
6109
  children: [
6106
- /* @__PURE__ */ d(ut, { name: "volume-high" }),
6110
+ /* @__PURE__ */ d(ft, { name: "volume-high" }),
6107
6111
  " Tap for sound"
6108
6112
  ]
6109
6113
  }
6110
6114
  ),
6111
- kt.isBuffering && m.ready && /* @__PURE__ */ d("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ _("div", { className: "flex flex-col items-center gap-2", children: [
6115
+ _t.isBuffering && m.ready && /* @__PURE__ */ d("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ _("div", { className: "flex flex-col items-center gap-2", children: [
6112
6116
  /* @__PURE__ */ d("div", { className: "w-8 h-8 border-2 border-text border-t-transparent rounded-full animate-spin" }),
6113
6117
  /* @__PURE__ */ d("div", { className: "px-4 py-2 rounded bg-wp-surface-2/80 text-xs font-medium", children: "Buffering…" })
6114
6118
  ] }) })
@@ -6116,14 +6120,14 @@ function fc({ mediaUrl: t, indexUrl: e, mediaId: n }) {
6116
6120
  }
6117
6121
  );
6118
6122
  }
6119
- function hc() {
6120
- const t = x((n) => n.snapshot.mediaId), e = Ee(() => t ? { mediaId: t, ...Xn(t) } : null, [t]);
6121
- return e ? /* @__PURE__ */ d(sr, { children: /* @__PURE__ */ d(fc, { mediaUrl: e.mediaUrl, indexUrl: e.indexUrl, mediaId: e.mediaId }) }) : /* @__PURE__ */ d(Ws, {});
6123
+ function pc() {
6124
+ const t = x((n) => n.snapshot.mediaId), e = Me(() => t ? { mediaId: t, ...Zn(t) } : null, [t]);
6125
+ return e ? /* @__PURE__ */ d(ar, { children: /* @__PURE__ */ d(hc, { mediaUrl: e.mediaUrl, indexUrl: e.indexUrl, mediaId: e.mediaId }) }) : /* @__PURE__ */ d(Vs, {});
6122
6126
  }
6123
- const pc = (t) => {
6124
- const e = ea(t);
6127
+ const mc = (t) => {
6128
+ const e = ta(t);
6125
6129
  return e.render(
6126
- /* @__PURE__ */ d(js.Provider, { value: Gs(), children: /* @__PURE__ */ d(hc, {}) })
6130
+ /* @__PURE__ */ d(Gs.Provider, { value: Ws(), children: /* @__PURE__ */ d(pc, {}) })
6127
6131
  ), {
6128
6132
  update() {
6129
6133
  },
@@ -6134,24 +6138,24 @@ const pc = (t) => {
6134
6138
  queueMicrotask(() => e.unmount());
6135
6139
  }
6136
6140
  };
6137
- }, mc = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6141
+ }, gc = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6138
6142
  __proto__: null,
6139
- mount: pc
6140
- }, Symbol.toStringTag, { value: "Module" })), gc = {
6143
+ mount: mc
6144
+ }, Symbol.toStringTag, { value: "Module" })), bc = {
6141
6145
  id: "player",
6142
6146
  name: "Media player",
6143
- load: () => Promise.resolve(mc)
6144
- }, bc = qt(() => import("./MediaDrawer-CF4FGXOt.js"));
6145
- function yc() {
6146
- const t = x((u) => u.snapshot), e = x((u) => u.ensureAutoIdentity), n = Mt(), r = Ee(
6147
- () => n ? ni(n, window.location.origin) : null,
6147
+ load: () => Promise.resolve(gc)
6148
+ }, yc = Yt(() => import("./MediaDrawer-EA9TYHow.js"));
6149
+ function vc() {
6150
+ const t = x((u) => u.snapshot), e = x((u) => u.ensureAutoIdentity), n = kt(), r = Me(
6151
+ () => n ? ri(n, window.location.origin) : null,
6148
6152
  [n]
6149
- ), s = Vs(), i = P(!1), [a, l] = $(!1), o = s.roomKey || null;
6150
- Oi(), L(() => Hi(), []), L(() => {
6151
- o && Wi(o);
6153
+ ), s = Ks(), i = P(!1), [a, l] = $(!1), o = s.roomKey || null;
6154
+ Hi(), L(() => Ui(), []), L(() => {
6155
+ o && Vi(o);
6152
6156
  }, [o]), L(() => {
6153
6157
  const u = () => l(!0);
6154
- return window.addEventListener(Vt, u), () => window.removeEventListener(Vt, u);
6158
+ return window.addEventListener(Kt, u), () => window.removeEventListener(Kt, u);
6155
6159
  }, []), L(() => {
6156
6160
  if (!o || i.current) return;
6157
6161
  let u = !1;
@@ -6160,9 +6164,9 @@ function yc() {
6160
6164
  try {
6161
6165
  await Promise.race([
6162
6166
  Promise.all([
6163
- Ks(),
6164
6167
  zs(),
6165
- Js().then(Qn)
6168
+ Js(),
6169
+ Qs().then(qn)
6166
6170
  ]),
6167
6171
  new Promise((g) => setTimeout(g, h))
6168
6172
  ]);
@@ -6173,7 +6177,7 @@ function yc() {
6173
6177
  const f = x.getState();
6174
6178
  E("room", "Joining room", { roomKey: o, name: f.name, sprite: f.sprite }), e();
6175
6179
  const y = x.getState();
6176
- Qs({
6180
+ qs({
6177
6181
  room_key: o,
6178
6182
  name: y.name || void 0,
6179
6183
  sprite: y.sprite || void 0
@@ -6187,37 +6191,37 @@ function yc() {
6187
6191
  }
6188
6192
  return o ? /* @__PURE__ */ _("div", { className: "relative flex-1 flex overflow-hidden min-h-0", children: [
6189
6193
  /* @__PURE__ */ _("div", { className: "flex-1 relative bg-black overflow-hidden min-w-0", children: [
6190
- /* @__PURE__ */ d(Sn, { activity: gc, roomKey: t.roomId ?? "", layer: "base" }),
6191
- r && t.roomId && /* @__PURE__ */ d(sr, { children: /* @__PURE__ */ d(Sn, { activity: r, roomKey: t.roomId, layer: "overlay" }, r.id) }),
6192
- /* @__PURE__ */ _(xi, { children: [
6193
- /* @__PURE__ */ d(li, {}),
6194
- /* @__PURE__ */ d(yi, {}),
6195
- /* @__PURE__ */ d(Bi, {}),
6196
- /* @__PURE__ */ d(wi, {})
6194
+ /* @__PURE__ */ d(wn, { activity: bc, roomKey: t.roomId ?? "", layer: "base" }),
6195
+ r && t.roomId && /* @__PURE__ */ d(ar, { children: /* @__PURE__ */ d(wn, { activity: r, roomKey: t.roomId, layer: "overlay" }, r.id) }),
6196
+ /* @__PURE__ */ _(Ei, { children: [
6197
+ /* @__PURE__ */ d(di, {}),
6198
+ /* @__PURE__ */ d(vi, {}),
6199
+ /* @__PURE__ */ d(Oi, {}),
6200
+ /* @__PURE__ */ d(xi, {})
6197
6201
  ] })
6198
6202
  ] }),
6199
- /* @__PURE__ */ d(Za, {}),
6200
- /* @__PURE__ */ d(Ve.Suspense, { fallback: /* @__PURE__ */ d(ii, { open: a, onClose: c }), children: /* @__PURE__ */ d(bc, { open: a, onClose: c }) })
6203
+ /* @__PURE__ */ d(ei, {}),
6204
+ /* @__PURE__ */ d(Ke.Suspense, { fallback: /* @__PURE__ */ d(oi, { open: a, onClose: c }), children: /* @__PURE__ */ d(yc, { open: a, onClose: c }) })
6201
6205
  ] }) : (C("room", "No room key provided"), /* @__PURE__ */ d("div", { className: "flex-1 flex items-center justify-center p-6", children: /* @__PURE__ */ _("div", { className: "text-text-secondary", children: [
6202
6206
  "No room key provided. Go to the ",
6203
6207
  /* @__PURE__ */ d("a", { href: "/", className: "underline", children: "home page" }),
6204
6208
  " to select a room."
6205
6209
  ] }) }));
6206
6210
  }
6207
- const Cc = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6211
+ const Rc = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6208
6212
  __proto__: null,
6209
- default: yc
6213
+ default: vc
6210
6214
  }, Symbol.toStringTag, { value: "Module" }));
6211
6215
  export {
6212
- Ac as B,
6213
- ai as D,
6214
- Cc as R,
6215
- Tc as S,
6216
- si as a,
6217
- Vi as b,
6218
- _c as c,
6219
- nt as d,
6220
- Ic as s,
6221
- en as u
6216
+ Tc as B,
6217
+ ii as D,
6218
+ Rc as R,
6219
+ Ic as S,
6220
+ ai as a,
6221
+ Ki as b,
6222
+ Ac as c,
6223
+ rt as d,
6224
+ Cc as s,
6225
+ tn as u
6222
6226
  };
6223
- //# sourceMappingURL=Room-DESl744M.js.map
6227
+ //# sourceMappingURL=Room-0ahmcpqH.js.map