@hadoku/watchparty-ui 0.44.16 → 0.44.18

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.
Files changed (23) hide show
  1. package/dist/chunks/{AdminPanel-CJtacvRu.js → AdminPanel-DfRZgmQ8.js} +12 -12
  2. package/dist/chunks/{AdminPanel-CJtacvRu.js.map → AdminPanel-DfRZgmQ8.js.map} +1 -1
  3. package/dist/chunks/{GameModule-BvqNQcVk.js → GameModule-DLAQtwXo.js} +19 -19
  4. package/dist/chunks/{GameModule-BvqNQcVk.js.map → GameModule-DLAQtwXo.js.map} +1 -1
  5. package/dist/chunks/{MapEditor-Bc0_hjZQ.js → MapEditor-BGlAunbV.js} +2 -2
  6. package/dist/chunks/{MapEditor-Bc0_hjZQ.js.map → MapEditor-BGlAunbV.js.map} +1 -1
  7. package/dist/chunks/{MediaDrawer-CgoGUHwV.js → MediaDrawer-CRMWTqGy.js} +51 -51
  8. package/dist/chunks/{MediaDrawer-CgoGUHwV.js.map → MediaDrawer-CRMWTqGy.js.map} +1 -1
  9. package/dist/chunks/{PlaylistPanel-BmKnGMqa.js → PlaylistPanel-CxweX09p.js} +20 -20
  10. package/dist/chunks/{PlaylistPanel-BmKnGMqa.js.map → PlaylistPanel-CxweX09p.js.map} +1 -1
  11. package/dist/chunks/{Room-CoE8L9aw.js → Room-CHqS_SkX.js} +464 -459
  12. package/dist/chunks/Room-CHqS_SkX.js.map +1 -0
  13. package/dist/chunks/{index-Buah62TP.js → index-BcGwR0hg.js} +1295 -1319
  14. package/dist/chunks/index-BcGwR0hg.js.map +1 -0
  15. package/dist/chunks/{submissionsApi-DXsG0ItW.js → submissionsApi-DI0nNhQi.js} +21 -21
  16. package/dist/chunks/{submissionsApi-DXsG0ItW.js.map → submissionsApi-DI0nNhQi.js.map} +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/room-chrome.css +1 -1
  19. package/dist/room-chrome.js +644 -658
  20. package/dist/room-chrome.js.map +1 -1
  21. package/package.json +2 -2
  22. package/dist/chunks/Room-CoE8L9aw.js.map +0 -1
  23. package/dist/chunks/index-Buah62TP.js.map +0 -1
@@ -1,23 +1,23 @@
1
- import { jsx as c, jsxs as v, Fragment as le } from "react/jsx-runtime";
2
- import $t, { useState as R, useRef as z, useMemo as Q, useCallback as E, useEffect as D, createContext as Bt, useContext as Pn, useId as Nn, useEffectEvent as Gt } from "react";
3
- import { themePrefs as ae, Icon as Rn, THEMES as Dn, useHadokuThemeOptional as On } from "@wolffm/themes";
1
+ import { jsx as c, jsxs as _, Fragment as le } from "react/jsx-runtime";
2
+ import Ht, { useState as R, useRef as z, useMemo as Q, useCallback as E, useEffect as D, createContext as $t, useContext as En, useId as Pn, useEffectEvent as Bt } from "react";
3
+ import { themePrefs as ie, Icon as Nn, THEMES as Rn, useHadokuThemeOptional as Dn } from "@wolffm/themes";
4
4
  import { z as r } from "zod";
5
- import { createCdnClient as Mn, kindOfType as Ln, MAX_BYTES as jn, measureImage as Un, filesFromClipboard as Fn, filesFromDrop as Hn, CdnError as qe } from "@wolffm/cdn-client";
6
- import { create as $n } from "zustand";
7
- import { createPrefsClient as Bn, getDeviceId as Gn, DEVICE_ID_KEY as Kn } from "@wolffm/prefs-client";
8
- import { io as Wn } from "socket.io-client";
9
- import { createAvatarClient as qn, AvatarError as ht } from "@wolffm/prefs-client/avatar";
10
- import { resolveIdentityReassert as Vn } from "@wolffm/rooms-protocol";
11
- import { createPortal as Yn } from "react-dom";
12
- import { useCatalogueSearch as zn } from "@wolffm/cdn-client/react";
13
- const Kt = "https://cdn.hadoku.me", Wt = /^[0-9a-f]{64}\.(?:png|jpe?g|gif|webp|avif)$/;
5
+ import { createCdnClient as On, kindOfType as Mn, MAX_BYTES as Ln, measureImage as jn, filesFromClipboard as Un, filesFromDrop as Fn, CdnError as qe } from "@wolffm/cdn-client";
6
+ import { create as Hn } from "zustand";
7
+ import { createPrefsClient as $n, getDeviceId as Bn, DEVICE_ID_KEY as Gn } from "@wolffm/prefs-client";
8
+ import { io as Kn } from "socket.io-client";
9
+ import { createAvatarClient as Wn, AvatarError as ht } from "@wolffm/prefs-client/avatar";
10
+ import { resolveIdentityReassert as qn } from "@wolffm/rooms-protocol";
11
+ import { createPortal as Vn } from "react-dom";
12
+ import { useCatalogueSearch as Yn } from "@wolffm/cdn-client/react";
13
+ const Gt = "https://cdn.hadoku.me", Kt = /^[0-9a-f]{64}\.(?:png|jpe?g|gif|webp|avif)$/;
14
14
  function Je(e) {
15
- return typeof e == "string" && Wt.test(e);
15
+ return typeof e == "string" && Kt.test(e);
16
16
  }
17
- const Qe = 8080, qt = 5173, Xn = "/watchparty/ws", Vt = 500, Jn = 1e3, V = 4, Yt = typeof process < "u" && process.env ? process.env : {};
18
- Yt.PRODUCTION_UI_URL;
19
- Yt.PRODUCTION_SERVER_URL;
20
- const xe = r.enum(["S", "A", "B", "C", "D", "F"]), gt = 2e4, Qn = 300;
17
+ const Qe = 8080, Wt = 5173, zn = "/watchparty/ws", qt = 500, Xn = 1e3, V = 4, Vt = typeof process < "u" && process.env ? process.env : {};
18
+ Vt.PRODUCTION_UI_URL;
19
+ Vt.PRODUCTION_SERVER_URL;
20
+ const xe = r.enum(["S", "A", "B", "C", "D", "F"]), gt = 2e4, Jn = 300;
21
21
  r.object({
22
22
  name: r.string().min(1).max(32).optional(),
23
23
  sprite: r.string().min(1).max(32).optional(),
@@ -44,7 +44,7 @@ const w = {
44
44
  // 'ready_state' here = playback-readiness gate (distinct from READY_EVENTS.STATE = "ready check" UX feature)
45
45
  READY_STATE: "ready_state",
46
46
  ERROR: "error"
47
- }, Zn = r.enum(["play", "pause", "seek", "load", "home"]), er = r.object({
47
+ }, Qn = r.enum(["play", "pause", "seek", "load", "home"]), Zn = r.object({
48
48
  framed: r.boolean(),
49
49
  depth: r.number().int().nonnegative().max(10)
50
50
  });
@@ -52,7 +52,7 @@ r.object({
52
52
  room_key: r.string(),
53
53
  name: r.string().min(1).max(32).optional(),
54
54
  sprite: r.string().min(1).max(32).optional(),
55
- embed: er.optional(),
55
+ embed: Zn.optional(),
56
56
  /** Which media-delivery path this client resolved to ('range' | 'fragment').
57
57
  * Optional so older clients still validate. Reported so a party's logs can be split by
58
58
  * arm — without it an A/B rollout is unmeasurable, exactly as entry path was before
@@ -100,13 +100,13 @@ r.object({
100
100
  });
101
101
  r.object({
102
102
  client_seq: r.number().int().positive(),
103
- kind: Zn,
103
+ kind: Qn,
104
104
  to_ms: r.number().int().nonnegative().optional(),
105
105
  media_id: r.string().optional()
106
106
  // leader_id removed - not needed since set_leader control was removed
107
107
  });
108
- const zt = r.object({
109
- key: r.string().regex(Wt, "not a CDN image key"),
108
+ const Yt = r.object({
109
+ key: r.string().regex(Kt, "not a CDN image key"),
110
110
  /**
111
111
  * Intrinsic pixels, or **0 meaning "unknown"**.
112
112
  *
@@ -134,14 +134,14 @@ const zt = r.object({
134
134
  * value only, never as markup. Bounded so one message cannot carry a
135
135
  * paragraph; the library's own titles run well under this.
136
136
  */
137
- title: r.string().max(Qn).optional()
137
+ title: r.string().max(Jn).optional()
138
138
  });
139
139
  r.object({
140
- text: r.string().max(Vt),
140
+ text: r.string().max(qt),
141
141
  style: r.string().max(64).optional(),
142
- images: r.array(zt).max(V).optional()
142
+ images: r.array(Yt).max(V).optional()
143
143
  }).refine((e) => e.text.length > 0 || (e.images?.length ?? 0) > 0, { message: "message must carry text or at least one image" });
144
- const tr = r.enum(["join", "leave", "media_change", "identity_change", "recap"]);
144
+ const er = r.enum(["join", "leave", "media_change", "identity_change", "recap"]);
145
145
  r.object({
146
146
  id: r.string(),
147
147
  client_id: r.string(),
@@ -154,11 +154,11 @@ r.object({
154
154
  ts: r.number(),
155
155
  // Optional so a client on an older bundle still validates a message that
156
156
  // has none, and so system messages (which never carry images) stay unchanged.
157
- images: r.array(zt).max(V).optional(),
157
+ images: r.array(Yt).max(V).optional(),
158
158
  isSystem: r.boolean().optional(),
159
- systemType: tr.optional()
159
+ systemType: er.optional()
160
160
  });
161
- const nr = r.object({
161
+ const tr = r.object({
162
162
  avg_download_rate_bps: r.number().nonnegative(),
163
163
  buffered_ahead_ms: r.number().nonnegative(),
164
164
  rtt_ms: r.number().nonnegative(),
@@ -200,7 +200,7 @@ const nr = r.object({
200
200
  * socket shows here as a growing number while everything else looks fine. */
201
201
  pong_age_ms: r.number().int().nonnegative().optional(),
202
202
  reported_at: r.number().int().nonnegative()
203
- }), rr = nr.extend({
203
+ }), nr = tr.extend({
204
204
  client_id: r.string(),
205
205
  name: r.string(),
206
206
  sprite_id: r.string().nullable(),
@@ -211,10 +211,10 @@ const nr = r.object({
211
211
  stale_ms: r.number().int().nonnegative().optional()
212
212
  });
213
213
  r.object({
214
- clients: r.array(rr),
214
+ clients: r.array(nr),
215
215
  server_ts: r.number().int().nonnegative()
216
216
  });
217
- const or = r.object({
217
+ const rr = r.object({
218
218
  client_id: r.string(),
219
219
  sprite_id: r.string().nullable(),
220
220
  name: r.string(),
@@ -232,13 +232,13 @@ const or = r.object({
232
232
  video_ready_state: r.number().int().default(-1)
233
233
  });
234
234
  r.object({
235
- clients: r.array(or),
235
+ clients: r.array(rr),
236
236
  server_ts: r.number().int().nonnegative()
237
237
  });
238
238
  r.object({
239
239
  media_id: r.string()
240
240
  });
241
- const Ze = r.enum(["super_upvote", "upvote", "mid", "downvote"]), ar = r.object({
241
+ const Ze = r.enum(["super_upvote", "upvote", "mid", "downvote"]), or = r.object({
242
242
  mediaId: r.string(),
243
243
  displayName: r.string(),
244
244
  // Enrichment fields — present for flat-playlist ingest output, absent for
@@ -249,11 +249,11 @@ const Ze = r.enum(["super_upvote", "upvote", "mid", "downvote"]), ar = r.object(
249
249
  durationMs: r.number().optional(),
250
250
  uploadDate: r.string().optional()
251
251
  // YouTube upload date 'YYYY-MM-DD'; drives playlist order
252
- }), ir = r.enum(["basic", "vote"]), Xt = r.object({
252
+ }), ir = r.enum(["basic", "vote"]), zt = r.object({
253
253
  id: r.string(),
254
254
  name: r.string(),
255
255
  type: ir.default("vote"),
256
- videos: r.array(ar),
256
+ videos: r.array(or),
257
257
  cover: r.string().optional()
258
258
  // media-relative path to the playlist cover image
259
259
  });
@@ -267,22 +267,22 @@ r.object({
267
267
  r.object({ voterKey: r.string().min(1).max(128) });
268
268
  r.object({ playlistId: r.string(), mediaIds: r.array(r.string()) });
269
269
  r.object({
270
- playlist: Xt.nullable(),
270
+ playlist: zt.nullable(),
271
271
  activeIndex: r.number().int().nullable(),
272
272
  myVotes: r.record(r.string(), Ze)
273
273
  // mediaId -> VoteValue
274
274
  });
275
- const sr = r.object({
275
+ const ar = r.object({
276
276
  clientId: r.string(),
277
277
  name: r.string(),
278
278
  votedCount: r.number().int().nonnegative(),
279
279
  totalVideos: r.number().int().nonnegative()
280
280
  });
281
281
  r.object({
282
- progress: r.array(sr)
282
+ progress: r.array(ar)
283
283
  });
284
284
  r.object({
285
- playlist: Xt,
285
+ playlist: zt,
286
286
  votes: r.record(r.string(), r.record(r.string(), Ze)),
287
287
  // votes[clientId][mediaId]
288
288
  names: r.record(r.string(), r.string()),
@@ -301,17 +301,17 @@ const be = {
301
301
  RESULTS: "playlist_results",
302
302
  /** Server -> the removed voter: forget the ballot you hold in localStorage. */
303
303
  VOTES_CLEARED: "playlist_votes_cleared"
304
- }, Jt = r.object({
304
+ }, Xt = r.object({
305
305
  id: r.string(),
306
306
  displayName: r.string(),
307
307
  thumbnail: r.string().optional()
308
308
  });
309
309
  r.object({
310
- items: r.array(Jt)
310
+ items: r.array(Xt)
311
311
  });
312
- const Qt = r.partialRecord(xe, r.array(r.string()));
313
- r.object({ board: Qt });
314
- const lr = r.object({
312
+ const Jt = r.partialRecord(xe, r.array(r.string()));
313
+ r.object({ board: Jt });
314
+ const sr = r.object({
315
315
  mediaId: r.string(),
316
316
  tier: xe,
317
317
  absoluteTier: xe,
@@ -324,17 +324,17 @@ const lr = r.object({
324
324
  // opaque voterId -> the letter they gave
325
325
  });
326
326
  r.object({
327
- items: r.array(Jt),
328
- placed: r.array(lr),
327
+ items: r.array(Xt),
328
+ placed: r.array(sr),
329
329
  unrated: r.array(r.string()),
330
330
  spread: r.number(),
331
331
  nudged: r.boolean(),
332
332
  names: r.record(r.string(), r.string()),
333
333
  sprites: r.record(r.string(), r.string()),
334
334
  voterCount: r.number().int().nonnegative(),
335
- myBoard: Qt
335
+ myBoard: Jt
336
336
  });
337
- const cr = {
337
+ const lr = {
338
338
  /** Broadcast to EVERY connected socket when anyone saves. Carries no board —
339
339
  * it is a "re-fetch" ping, because the shared result is identical for all
340
340
  * viewers but `myBoard` is not, and one payload cannot serve both. */
@@ -347,10 +347,10 @@ r.object({
347
347
  ready: r.array(r.string())
348
348
  // clientIds who have flagged ready
349
349
  });
350
- const dr = {
350
+ const cr = {
351
351
  STATE: "ready_check_state"
352
352
  // distinct from buffer-readiness 'ready_state'
353
- }, Zt = {
353
+ }, Qt = {
354
354
  ACTIVE: "game_active",
355
355
  // server -> room (room-wide active game id; null = none)
356
356
  SYNC: "game_sync"
@@ -376,7 +376,7 @@ r.object({
376
376
  r.object({
377
377
  gameId: r.string().min(1).max(32)
378
378
  });
379
- const ur = r.object({
379
+ const dr = r.object({
380
380
  clientId: r.string(),
381
381
  playerId: r.number().int().min(0),
382
382
  name: r.string(),
@@ -390,12 +390,12 @@ r.object({
390
390
  gameId: r.string(),
391
391
  hostClientId: r.string().nullable(),
392
392
  seed: r.number().int(),
393
- players: r.array(ur)
393
+ players: r.array(dr)
394
394
  });
395
395
  r.object({ d: r.unknown() });
396
396
  r.object({ d: r.unknown() });
397
397
  r.object({ fromClientId: r.string(), d: r.unknown() });
398
- const mr = r.object({
398
+ const ur = r.object({
399
399
  playerId: r.number().int().min(0),
400
400
  clientId: r.string().nullable(),
401
401
  name: r.string(),
@@ -436,7 +436,7 @@ const mr = r.object({
436
436
  r.object({
437
437
  winnerPlayerId: r.number().int().min(0).nullable(),
438
438
  draw: r.boolean(),
439
- players: r.array(mr),
439
+ players: r.array(ur),
440
440
  // Optional session metadata + round-level extras (Phase C).
441
441
  sessionOver: r.boolean().optional(),
442
442
  roundNo: r.number().int().min(0).optional(),
@@ -444,7 +444,7 @@ r.object({
444
444
  maxMultiKill: r.number().int().min(0).optional(),
445
445
  maxChainKill: r.number().int().min(0).optional()
446
446
  });
447
- const fr = [
447
+ const mr = [
448
448
  {
449
449
  id: "fantasy",
450
450
  characters: [
@@ -488,37 +488,37 @@ const fr = [
488
488
  { id: "mentor", color: "#e1e0dc" }
489
489
  ]
490
490
  }
491
- ], et = fr.flatMap((e) => e.characters), Me = et.map((e) => e.id), pr = Object.fromEntries(et.map((e) => [e.id, e.color])), hr = Object.fromEntries(et.map((e) => [e.id, "rev" in e ? e.rev : 1]));
492
- function gr(e) {
493
- const t = hr[e];
491
+ ], et = mr.flatMap((e) => e.characters), Me = et.map((e) => e.id), fr = Object.fromEntries(et.map((e) => [e.id, e.color])), pr = Object.fromEntries(et.map((e) => [e.id, "rev" in e ? e.rev : 1]));
492
+ function hr(e) {
493
+ const t = pr[e];
494
494
  return `/media/sprites/square_${e}.png${t > 1 ? `?v=${t}` : ""}`;
495
495
  }
496
496
  function tt(e) {
497
497
  return !!e && Me.includes(e);
498
498
  }
499
- const br = 5e3, en = { mode: "off", percent: 0 }, yr = ["off", "on", "ab"];
499
+ const gr = 5e3, Zt = { mode: "off", percent: 0 }, br = ["off", "on", "ab"];
500
+ function yr(e) {
501
+ return typeof e == "string" && br.includes(e);
502
+ }
500
503
  function vr(e) {
501
- return typeof e == "string" && yr.includes(e);
504
+ const t = e && typeof e == "object" ? e : {}, n = yr(t.mode) ? t.mode : Zt.mode, o = Number(t.percent), i = Number.isFinite(o) ? Math.min(100, Math.max(0, Math.round(o))) : 0;
505
+ return { mode: n, percent: i };
502
506
  }
503
507
  function Sr(e) {
504
- const t = e && typeof e == "object" ? e : {}, n = vr(t.mode) ? t.mode : en.mode, o = Number(t.percent), a = Number.isFinite(o) ? Math.min(100, Math.max(0, Math.round(o))) : 0;
505
- return { mode: n, percent: a };
506
- }
507
- function _r(e) {
508
508
  let t = 2166136261;
509
509
  for (let n = 0; n < e.length; n++)
510
510
  t ^= e.charCodeAt(n), t = Math.imul(t, 16777619) >>> 0;
511
511
  return t >>> 0;
512
512
  }
513
- function wr(e, t, n) {
513
+ function _r(e, t, n) {
514
514
  if (n === !0)
515
515
  return "fragment";
516
516
  if (n === !1)
517
517
  return "range";
518
- const o = Sr(e);
519
- return o.mode === "on" ? "fragment" : o.mode === "off" || o.percent <= 0 ? "range" : o.percent >= 100 || t && _r(t) % 100 < o.percent ? "fragment" : "range";
518
+ const o = vr(e);
519
+ return o.mode === "on" ? "fragment" : o.mode === "off" || o.percent <= 0 ? "range" : o.percent >= 100 || t && Sr(t) % 100 < o.percent ? "fragment" : "range";
520
520
  }
521
- const tn = r.enum(["url", "magnet", "upload"]), xr = r.enum([
521
+ const en = r.enum(["url", "magnet", "upload"]), wr = r.enum([
522
522
  "pending",
523
523
  "approved",
524
524
  "fetching",
@@ -536,11 +536,11 @@ const tn = r.enum(["url", "magnet", "upload"]), xr = r.enum([
536
536
  failed: ["approved"]
537
537
  };
538
538
  Object.keys(bt).filter((e) => bt[e].length === 0);
539
- const Ir = r.object({
539
+ const xr = r.object({
540
540
  id: r.string().min(1),
541
541
  /** Stable userId from whoami. Never the raw `X-User-Key`. */
542
542
  ownerUserId: r.string().min(1),
543
- kind: tn,
543
+ kind: en,
544
544
  /** The magnet URI, the https URL, or the filetransfer binding id. */
545
545
  source: r.string().min(1),
546
546
  title: r.string().optional(),
@@ -555,7 +555,7 @@ const Ir = r.object({
555
555
  * misroute the copy.
556
556
  */
557
557
  series: r.string().optional(),
558
- state: xr,
558
+ state: wr,
559
559
  createdAt: r.number().int().nonnegative(),
560
560
  updatedAt: r.number().int().nonnegative(),
561
561
  /** Why it failed, or why an operator rejected it. */
@@ -563,19 +563,19 @@ const Ir = r.object({
563
563
  /** Size once known. 0 means "known to be empty"; absent means "not yet known" —
564
564
  * the same distinction `chatImages` draws for image dimensions. */
565
565
  bytes: r.number().int().nonnegative().optional()
566
- }), Cr = 4096, nn = 300, Tr = 100;
566
+ }), Ir = 4096, tn = 300, Cr = 100;
567
567
  r.object({
568
- kind: tn,
569
- source: r.string().min(1).max(Cr),
570
- title: r.string().min(1).max(nn).optional(),
568
+ kind: en,
569
+ source: r.string().min(1).max(Ir),
570
+ title: r.string().min(1).max(tn).optional(),
571
571
  /** Required for `kind: 'magnet'` by `checkSource`; ignored for `url`/`upload`. */
572
- series: r.string().min(1).max(Tr).optional()
572
+ series: r.string().min(1).max(Cr).optional()
573
573
  });
574
574
  r.object({
575
- reason: r.string().min(1).max(nn).optional()
575
+ reason: r.string().min(1).max(tn).optional()
576
576
  });
577
577
  r.object({
578
- submissions: r.array(Ir)
578
+ submissions: r.array(xr)
579
579
  });
580
580
  r.object({
581
581
  error: r.literal("submissions/quota_exceeded"),
@@ -584,8 +584,8 @@ r.object({
584
584
  /** The cap that was applied, from the server's config. */
585
585
  capBytes: r.number().int().nonnegative()
586
586
  });
587
- const kr = /^[a-z0-9][a-z0-9-]{0,31}$/, yt = "https://game-catalog.invalid";
588
- function Ar(e) {
587
+ const Tr = /^[a-z0-9][a-z0-9-]{0,31}$/, yt = "https://game-catalog.invalid";
588
+ function kr(e) {
589
589
  if (!e.startsWith("/") || e.startsWith("//") || /[\\\s]/.test(e) || [...e].some((t) => t.charCodeAt(0) < 32 || t.charCodeAt(0) === 127))
590
590
  return !1;
591
591
  try {
@@ -594,18 +594,18 @@ function Ar(e) {
594
594
  return !1;
595
595
  }
596
596
  }
597
- const rn = r.string().min(2).max(512).refine(Ar, {
597
+ const nn = r.string().min(2).max(512).refine(kr, {
598
598
  message: "must be a root-relative path on the page origin (e.g. /cardtable/embed/x.js)"
599
599
  }), vt = {
600
- id: r.string().regex(kr),
600
+ id: r.string().regex(Tr),
601
601
  name: r.string().min(1).max(64),
602
- cover: rn.optional()
603
- }, Er = r.discriminatedUnion("kind", [
602
+ cover: nn.optional()
603
+ }, Ar = r.discriminatedUnion("kind", [
604
604
  r.object({ ...vt, kind: r.literal("iframe") }).strict(),
605
- r.object({ ...vt, kind: r.literal("module"), url: rn }).strict()
605
+ r.object({ ...vt, kind: r.literal("module"), url: nn }).strict()
606
606
  ]);
607
- r.array(Er).max(32).refine((e) => new Set(e.map((t) => t.id)).size === e.length, { message: "game ids must be unique" });
608
- const nt = r.enum(["anilist", "tmdb"]), Pr = r.object({
607
+ r.array(Ar).max(32).refine((e) => new Set(e.map((t) => t.id)).size === e.length, { message: "game ids must be unique" });
608
+ const nt = r.enum(["anilist", "tmdb"]), Er = r.object({
609
609
  source: nt,
610
610
  /** The provider's own id, as a string (AniList and TMDB both use integers). */
611
611
  id: r.string(),
@@ -627,11 +627,11 @@ const nt = r.enum(["anilist", "tmdb"]), Pr = r.object({
627
627
  addable: r.boolean()
628
628
  });
629
629
  r.object({
630
- results: r.array(Pr),
630
+ results: r.array(Er),
631
631
  /** Providers that answered. TMDB is absent when no token is configured. */
632
632
  sources: r.array(nt)
633
633
  });
634
- const Nr = r.object({
634
+ const Pr = r.object({
635
635
  id: r.string(),
636
636
  url: r.string(),
637
637
  title: r.string(),
@@ -639,30 +639,30 @@ const Nr = r.object({
639
639
  durationS: r.number().nullable(),
640
640
  thumb: r.string().nullable()
641
641
  });
642
- r.object({ results: r.array(Nr) });
642
+ r.object({ results: r.array(Pr) });
643
643
  r.object({
644
644
  source: nt,
645
645
  id: r.string().regex(/^\d{1,12}$/)
646
646
  });
647
647
  r.object({ series: r.string(), title: r.string() });
648
- let ye = null, on = Kt;
649
- function Rr(e) {
650
- e.cdnBase && (on = e.cdnBase);
648
+ let ye = null, rn = Gt;
649
+ function Nr(e) {
650
+ e.cdnBase && (rn = e.cdnBase);
651
651
  }
652
- function an() {
653
- return on.replace(/\/+$/, "");
652
+ function on() {
653
+ return rn.replace(/\/+$/, "");
654
654
  }
655
655
  function Le() {
656
- const e = an();
657
- return (!ye || ye.base !== e) && (ye = { base: e, client: Mn({ cdnBase: e }) }), ye.client;
656
+ const e = on();
657
+ return (!ye || ye.base !== e) && (ye = { base: e, client: On({ cdnBase: e }) }), ye.client;
658
658
  }
659
659
  function Pe(e) {
660
- return !Je(e) || !an() ? null : Le().urlFor(e);
660
+ return !Je(e) || !on() ? null : Le().urlFor(e);
661
661
  }
662
- function Dr(e) {
662
+ function Rr(e) {
663
663
  return e.kind === "file";
664
664
  }
665
- class sn extends Error {
665
+ class an extends Error {
666
666
  constructor(t) {
667
667
  super(t), this.name = "ChatImageUploadError";
668
668
  }
@@ -687,42 +687,42 @@ function Ie(e) {
687
687
  return "Image upload failed";
688
688
  }
689
689
  }
690
+ function Dr(e) {
691
+ return e instanceof qe ? Ie(e.reason) : e instanceof an ? e.message : "Image upload failed";
692
+ }
690
693
  function Or(e) {
691
- return e instanceof qe ? Ie(e.reason) : e instanceof sn ? e.message : "Image upload failed";
694
+ const t = e.type.toLowerCase().split(";")[0].trim();
695
+ return t && Mn(t) !== "image" ? Ie("unsupported-type") : e.size > Ln.image ? Ie("too-large") : e.size === 0 ? Ie("invalid") : null;
692
696
  }
693
697
  function Mr(e) {
694
- const t = e.type.toLowerCase().split(";")[0].trim();
695
- return t && Ln(t) !== "image" ? Ie("unsupported-type") : e.size > jn.image ? Ie("too-large") : e.size === 0 ? Ie("invalid") : null;
698
+ return Un(e);
696
699
  }
697
700
  function Lr(e) {
698
701
  return Fn(e);
699
702
  }
700
- function jr(e) {
701
- return Hn(e);
702
- }
703
- async function Ur(e) {
704
- const t = await Un(e);
703
+ async function jr(e) {
704
+ const t = await jn(e);
705
705
  return { w: t?.width ?? 0, h: t?.height ?? 0 };
706
706
  }
707
- async function Fr(e, t = {}) {
707
+ async function Ur(e, t = {}) {
708
708
  const n = await Le().upload(e, { signal: t.signal });
709
709
  if (!Je(n.key))
710
- throw new sn("Image upload returned an unusable key");
710
+ throw new an("Image upload returned an unusable key");
711
711
  return { key: n.key, deduplicated: n.deduplicated === !0 };
712
712
  }
713
- async function Hr(e, t = {}) {
713
+ async function Fr(e, t = {}) {
714
714
  const n = [];
715
715
  for (const o of e) {
716
716
  if (o.kind === "remote") {
717
717
  n.push({ key: o.key, w: o.w, h: o.h, ...o.title ? { title: o.title } : {} });
718
718
  continue;
719
719
  }
720
- const { key: a } = await Fr(o.file, t);
721
- n.push({ key: a, w: o.w, h: o.h });
720
+ const { key: i } = await Ur(o.file, t);
721
+ n.push({ key: i, w: o.w, h: o.h });
722
722
  }
723
723
  return n;
724
724
  }
725
- function $r(e) {
725
+ function Hr(e) {
726
726
  return {
727
727
  error: e instanceof Error ? e.message : String(e),
728
728
  name: e instanceof Error ? e.name : typeof e,
@@ -730,39 +730,39 @@ function $r(e) {
730
730
  status: e instanceof qe ? e.status : void 0
731
731
  };
732
732
  }
733
- const Ve = 240, X = 8, Br = 28, ln = 240;
734
- function Gr(e, t, n) {
733
+ const Ve = 240, X = 8, $r = 28, sn = 240;
734
+ function Br(e, t, n) {
735
735
  let o = t.left - Ve - X;
736
736
  o < X && (o = t.right + X), o = Math.min(o, n.width - Ve - X), o = Math.max(X, o);
737
- const a = ln + Br;
738
- let i = e.top + e.height / 2 - a / 2;
739
- return i = Math.min(i, n.height - a - X), i = Math.max(X, i), { left: o, top: i };
737
+ const i = sn + $r;
738
+ let a = e.top + e.height / 2 - i / 2;
739
+ return a = Math.min(a, n.height - i - X), a = Math.max(X, a), { left: o, top: a };
740
740
  }
741
- const cn = "/dataplatform/api/memes", Kr = 120;
742
- function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
743
- const [o, a] = R(""), i = z(null), s = z(null), l = Le(), { items: p, loading: h, error: f, hasMore: L, loadMore: O } = zn(
741
+ const ln = "/dataplatform/api/memes", Gr = 120;
742
+ function Kr({ onClose: e, onPick: t, onUnavailable: n }) {
743
+ const [o, i] = R(""), a = z(null), s = z(null), l = Le(), { items: p, loading: h, error: f, hasMore: L, loadMore: O } = Yn(
744
744
  l,
745
- cn,
745
+ ln,
746
746
  o.trim()
747
747
  ), M = f?.reason ?? null, C = Q(() => {
748
748
  const x = /* @__PURE__ */ new Set();
749
749
  return p.filter((P) => x.has(P.key) ? !1 : (x.add(P.key), !0));
750
- }, [p]), [m, S] = R(null), y = z(null), I = E(() => {
750
+ }, [p]), [m, v] = R(null), y = z(null), I = E(() => {
751
751
  y.current !== null && (window.clearTimeout(y.current), y.current = null);
752
752
  }, []), g = E(() => {
753
- I(), S(null);
753
+ I(), v(null);
754
754
  }, [I]), A = typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(hover: hover)").matches, N = E(
755
755
  (x, P, T = !1) => {
756
- const pe = i.current;
756
+ const pe = a.current;
757
757
  if (!pe) return;
758
- const he = () => S({
758
+ const he = () => v({
759
759
  item: x,
760
- ...Gr(P.getBoundingClientRect(), pe.getBoundingClientRect(), {
760
+ ...Br(P.getBoundingClientRect(), pe.getBoundingClientRect(), {
761
761
  width: window.innerWidth,
762
762
  height: window.innerHeight
763
763
  })
764
764
  });
765
- I(), T ? he() : y.current = window.setTimeout(he, Kr);
765
+ I(), T ? he() : y.current = window.setTimeout(he, Gr);
766
766
  },
767
767
  [I]
768
768
  );
@@ -774,7 +774,7 @@ function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
774
774
  const x = (T) => {
775
775
  T.key === "Escape" && (T.stopPropagation(), e());
776
776
  }, P = (T) => {
777
- i.current && !i.current.contains(T.target) && e();
777
+ a.current && !a.current.contains(T.target) && e();
778
778
  };
779
779
  return document.addEventListener("keydown", x), document.addEventListener("mousedown", P), () => {
780
780
  document.removeEventListener("keydown", x), document.removeEventListener("mousedown", P);
@@ -783,10 +783,10 @@ function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
783
783
  const U = E((x) => {
784
784
  t(x), e();
785
785
  }, [t, e]), F = !h && !f && C.length === 0;
786
- return /* @__PURE__ */ v(
786
+ return /* @__PURE__ */ _(
787
787
  "div",
788
788
  {
789
- ref: i,
789
+ ref: a,
790
790
  role: "dialog",
791
791
  "aria-label": "Meme library",
792
792
  "data-testid": "meme-picker",
@@ -798,14 +798,14 @@ function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
798
798
  ref: s,
799
799
  type: "text",
800
800
  value: o,
801
- onChange: (x) => a(x.target.value),
801
+ onChange: (x) => i(x.target.value),
802
802
  placeholder: "Search memes...",
803
803
  "aria-label": "Search memes",
804
804
  "data-testid": "meme-search",
805
805
  className: "w-full rounded border border-border-light bg-bg-alt px-2 py-1 text-sm text-text placeholder:text-text-secondary focus:outline-none focus:border-primary"
806
806
  }
807
807
  ) }),
808
- /* @__PURE__ */ v(
808
+ /* @__PURE__ */ _(
809
809
  "div",
810
810
  {
811
811
  className: "flex-1 overflow-y-auto p-2",
@@ -866,7 +866,7 @@ function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
866
866
  ]
867
867
  }
868
868
  ),
869
- m && /* @__PURE__ */ v(
869
+ m && /* @__PURE__ */ _(
870
870
  "div",
871
871
  {
872
872
  "data-testid": "meme-preview",
@@ -891,7 +891,7 @@ function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
891
891
  src: Pe(m.item.key) ?? void 0,
892
892
  alt: "",
893
893
  className: "block w-full rounded bg-bg object-contain",
894
- style: { height: "auto", maxHeight: ln }
894
+ style: { height: "auto", maxHeight: sn }
895
895
  }
896
896
  ),
897
897
  m.item.title && /* One line. A long title must not change the box height, because
@@ -904,34 +904,34 @@ function Wr({ onClose: e, onPick: t, onUnavailable: n }) {
904
904
  }
905
905
  );
906
906
  }
907
- function qr({ open: e, ...t }) {
908
- return e ? /* @__PURE__ */ c(Wr, { ...t }) : null;
907
+ function Wr({ open: e, ...t }) {
908
+ return e ? /* @__PURE__ */ c(Kr, { ...t }) : null;
909
909
  }
910
910
  const rt = {
911
911
  serverOrigin: `http://localhost:${Qe}`,
912
912
  defaultRoomKey: "dev-room",
913
- cdnBase: Kt
913
+ cdnBase: Gt
914
914
  };
915
915
  let Ce = { ...rt };
916
- function Vr(e) {
916
+ function qr(e) {
917
917
  const t = Object.fromEntries(
918
918
  Object.entries(e).filter(([n, o]) => o !== void 0)
919
919
  );
920
- Ce = { ...Ce, ...t }, Rr({ cdnBase: Ce.cdnBase });
920
+ Ce = { ...Ce, ...t }, Nr({ cdnBase: Ce.cdnBase });
921
921
  }
922
922
  function me() {
923
923
  return Ce;
924
924
  }
925
- const Yr = Bt(rt);
926
- function zr(e) {
925
+ const Vr = $t(rt);
926
+ function Yr(e) {
927
927
  return e.serverOrigin?.replace(/\/$/, "") || "";
928
928
  }
929
- function dn() {
930
- return zr(me());
929
+ function cn() {
930
+ return Yr(me());
931
931
  }
932
- const un = Bt(null);
933
- function Xr() {
934
- return Pn(un);
932
+ const dn = $t(null);
933
+ function zr() {
934
+ return En(dn);
935
935
  }
936
936
  const te = {
937
937
  ANON_KEY: "watchparty_preferences",
@@ -961,7 +961,7 @@ function ot(e, t) {
961
961
  return !1;
962
962
  }
963
963
  }
964
- function Jr() {
964
+ function Xr() {
965
965
  try {
966
966
  const e = je();
967
967
  if (!e) return [];
@@ -981,45 +981,45 @@ function Ne(e) {
981
981
  } catch {
982
982
  }
983
983
  }
984
- function Qr(e) {
984
+ function Jr(e) {
985
985
  const t = B(e);
986
986
  return t === null ? null : t === "true" ? !0 : t === "false" ? !1 : null;
987
987
  }
988
- const mn = /* @__PURE__ */ new Map();
989
- let fn = !1;
988
+ const un = /* @__PURE__ */ new Map();
989
+ let mn = !1;
990
990
  function Ue(e, t) {
991
- mn.set(e, t), fn && pn(e, t);
991
+ un.set(e, t), mn && fn(e, t);
992
992
  }
993
- function Zr() {
994
- fn = !0;
995
- for (const [e, t] of mn) pn(e, t);
993
+ function Qr() {
994
+ mn = !0;
995
+ for (const [e, t] of un) fn(e, t);
996
996
  }
997
- function pn(e, t) {
997
+ function fn(e, t) {
998
998
  typeof window > "u" || (window[e] = t);
999
999
  }
1000
- const ie = [], eo = 500;
1000
+ const ae = [], Zr = 500;
1001
1001
  let Te = [], Ye = null;
1002
- const to = 1e3, no = 200;
1002
+ const eo = 1e3, to = 200;
1003
1003
  let ze = null;
1004
- function hn(e) {
1004
+ function pn(e) {
1005
1005
  ze = e;
1006
1006
  }
1007
- function gn() {
1007
+ function hn() {
1008
1008
  return B(te.REPORT_LOGS_FLAG) === "true";
1009
1009
  }
1010
- function ro() {
1010
+ function no() {
1011
1011
  if (typeof window > "u") return !1;
1012
1012
  if (window.__WP_DEBUG__ || new URLSearchParams(window.location.search).get("debug") === "true") return !0;
1013
1013
  const t = B(te.DEBUG_FLAG);
1014
1014
  return t !== null && t !== "false";
1015
1015
  }
1016
- function oo() {
1016
+ function ro() {
1017
1017
  const e = B(te.DEBUG_FLAG);
1018
1018
  if (!e || e === "true") return null;
1019
1019
  const t = e.split(",").map((n) => n.trim().toLowerCase()).filter(Boolean);
1020
1020
  return t.length > 0 ? new Set(t) : null;
1021
1021
  }
1022
- function ao() {
1022
+ function oo() {
1023
1023
  return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
1024
1024
  hour12: !1,
1025
1025
  hour: "2-digit",
@@ -1029,7 +1029,7 @@ function ao() {
1029
1029
  });
1030
1030
  }
1031
1031
  function io(e) {
1032
- ie.push(e), ie.length > eo && ie.shift();
1032
+ ae.push(e), ae.length > Zr && ae.shift();
1033
1033
  }
1034
1034
  const Fe = {
1035
1035
  debug: "color: #64748b; font-weight: normal;",
@@ -1038,67 +1038,67 @@ const Fe = {
1038
1038
  category: "color: #3b82f6; font-weight: bold;",
1039
1039
  time: "color: #6b7280; font-weight: normal;"
1040
1040
  };
1041
- function so(e) {
1041
+ function ao(e) {
1042
1042
  try {
1043
1043
  return JSON.stringify(e);
1044
1044
  } catch {
1045
1045
  return "[unserializable]";
1046
1046
  }
1047
1047
  }
1048
- function at(e, t, n, o, a, i, s) {
1048
+ function it(e, t, n, o, i, a, s) {
1049
1049
  const l = {
1050
1050
  level: e,
1051
- category: a,
1052
- message: i,
1051
+ category: i,
1052
+ message: a,
1053
1053
  data: s,
1054
1054
  timestamp: Date.now()
1055
1055
  };
1056
- if (io(l), (n || gn()) && St(l), !o) {
1057
- if (!ro()) return;
1058
- const f = oo();
1059
- if (f && !f.has(a.toLowerCase())) return;
1056
+ if (io(l), (n || hn()) && St(l), !o) {
1057
+ if (!no()) return;
1058
+ const f = ro();
1059
+ if (f && !f.has(i.toLowerCase())) return;
1060
1060
  }
1061
- const p = ao(), h = s !== void 0 ? " " + so(s) : "";
1061
+ const p = oo(), h = s !== void 0 ? " " + ao(s) : "";
1062
1062
  t(
1063
- `%c[${p}]%c [${a}]%c ${i}${h}`,
1063
+ `%c[${p}]%c [${i}]%c ${a}${h}`,
1064
1064
  Fe.time,
1065
1065
  Fe.category,
1066
1066
  Fe[e]
1067
1067
  );
1068
1068
  }
1069
1069
  function d(e, t, n) {
1070
- at("debug", console.log, !1, !1, e, t, n);
1070
+ it("debug", console.log, !1, !1, e, t, n);
1071
1071
  }
1072
1072
  function k(e, t, n) {
1073
- at("warn", console.warn, !0, !1, e, t, n);
1073
+ it("warn", console.warn, !0, !1, e, t, n);
1074
1074
  }
1075
1075
  function ke(e, t, n) {
1076
- at("error", console.error, !0, !0, e, t, n);
1076
+ it("error", console.error, !0, !0, e, t, n);
1077
1077
  }
1078
- function lo() {
1079
- return [...ie];
1078
+ function so() {
1079
+ return [...ae];
1080
1080
  }
1081
- function co() {
1082
- ie.length = 0;
1081
+ function lo() {
1082
+ ae.length = 0;
1083
1083
  }
1084
- function uo(e) {
1084
+ function co(e) {
1085
1085
  const t = e && e.length > 0 ? e.join(",") : "true";
1086
1086
  ot(te.DEBUG_FLAG, t), console.log("[wp] Debug mode enabled");
1087
1087
  }
1088
- function mo() {
1088
+ function uo() {
1089
1089
  Ne(te.DEBUG_FLAG), console.log("[wp] Debug mode disabled");
1090
1090
  }
1091
- const fo = 1024, po = 5e4;
1092
- function ho(e) {
1091
+ const mo = 1024, fo = 5e4;
1092
+ function po(e) {
1093
1093
  if (e == null) return e;
1094
1094
  try {
1095
1095
  const t = JSON.stringify(e);
1096
- if (t.length <= fo) return e;
1096
+ if (t.length <= mo) return e;
1097
1097
  if (typeof e == "object" && !Array.isArray(e)) {
1098
1098
  const n = {};
1099
- for (const [o, a] of Object.entries(e)) {
1100
- const i = JSON.stringify(a);
1101
- n[o] = i && i.length > 200 ? `[truncated ${i.length} chars]` : a;
1099
+ for (const [o, i] of Object.entries(e)) {
1100
+ const a = JSON.stringify(i);
1101
+ n[o] = a && a.length > 200 ? `[truncated ${a.length} chars]` : i;
1102
1102
  }
1103
1103
  return n;
1104
1104
  }
@@ -1107,7 +1107,7 @@ function ho(e) {
1107
1107
  return "[unserializable]";
1108
1108
  }
1109
1109
  }
1110
- async function go() {
1110
+ async function ho() {
1111
1111
  if (Te.length === 0) return;
1112
1112
  const e = Te;
1113
1113
  Te = [], Ye = null;
@@ -1115,32 +1115,32 @@ async function go() {
1115
1115
  let n = me().serverOrigin || "";
1116
1116
  if ((n === "/" || !n) && typeof window < "u") {
1117
1117
  const l = window.location;
1118
- (l.hostname === "localhost" || l.hostname === "127.0.0.1") && l.port === String(qt) ? n = `${l.protocol}//${l.hostname}:${Qe}` : n = l.origin;
1118
+ (l.hostname === "localhost" || l.hostname === "127.0.0.1") && l.port === String(Wt) ? n = `${l.protocol}//${l.hostname}:${Qe}` : n = l.origin;
1119
1119
  }
1120
- const o = `${n.replace(/\/$/, "")}/api/client-log`, a = e.map((l) => ({
1120
+ const o = `${n.replace(/\/$/, "")}/api/client-log`, i = e.map((l) => ({
1121
1121
  level: l.level,
1122
1122
  category: l.category,
1123
1123
  message: l.message,
1124
- data: ho(l.data),
1124
+ data: po(l.data),
1125
1125
  timestamp: l.timestamp,
1126
1126
  url: typeof window < "u" ? window.location.href : void 0,
1127
1127
  userAgent: typeof navigator < "u" ? navigator.userAgent : void 0,
1128
1128
  room_key: ze?.room_key,
1129
1129
  client_id: ze?.client_id
1130
1130
  }));
1131
- let i = [], s = 0;
1132
- for (const l of a) {
1131
+ let a = [], s = 0;
1132
+ for (const l of i) {
1133
1133
  const p = JSON.stringify(l).length + 1;
1134
- s + p > po && i.length > 0 && (await fetch(o, {
1134
+ s + p > fo && a.length > 0 && (await fetch(o, {
1135
1135
  method: "POST",
1136
1136
  headers: { "Content-Type": "application/json" },
1137
- body: JSON.stringify({ logs: i })
1138
- }), i = [], s = 0), i.push(l), s += p;
1137
+ body: JSON.stringify({ logs: a })
1138
+ }), a = [], s = 0), a.push(l), s += p;
1139
1139
  }
1140
- i.length > 0 && await fetch(o, {
1140
+ a.length > 0 && await fetch(o, {
1141
1141
  method: "POST",
1142
1142
  headers: { "Content-Type": "application/json" },
1143
- body: JSON.stringify({ logs: i })
1143
+ body: JSON.stringify({ logs: a })
1144
1144
  });
1145
1145
  } catch (t) {
1146
1146
  console.warn("[wp] log flush failed (client logs may be lost):", fe(t).error);
@@ -1148,44 +1148,44 @@ async function go() {
1148
1148
  }
1149
1149
  function St(e) {
1150
1150
  if (Te.push(e), !Ye) {
1151
- const t = gn() ? no : to;
1152
- Ye = setTimeout(go, t);
1151
+ const t = hn() ? to : eo;
1152
+ Ye = setTimeout(ho, t);
1153
1153
  }
1154
1154
  }
1155
1155
  function fe(e) {
1156
1156
  return e instanceof Error ? { error: e.message, name: e.name } : { error: String(e), name: typeof e };
1157
1157
  }
1158
1158
  Ue("__wpDebug", {
1159
- enable: uo,
1160
- disable: mo,
1161
- history: lo,
1162
- clear: co
1159
+ enable: co,
1160
+ disable: uo,
1161
+ history: so,
1162
+ clear: lo
1163
1163
  });
1164
1164
  const Y = {
1165
1165
  resolved: !1,
1166
1166
  userType: "public",
1167
1167
  accountId: null
1168
1168
  };
1169
- function it() {
1169
+ function at() {
1170
1170
  return Y.accountId ? Y.accountId : Y.resolved && Y.userType === "public" ? "anon" : null;
1171
1171
  }
1172
- function bo(e) {
1172
+ function go(e) {
1173
1173
  Y.resolved = !0, e.userType && (Y.userType = e.userType), e.userId !== void 0 && (Y.accountId = e.userId && e.userId !== "public" ? e.userId : null);
1174
1174
  }
1175
1175
  function st() {
1176
1176
  return Y.accountId ?? "public";
1177
1177
  }
1178
- function yo() {
1179
- return it() ?? "unscoped";
1178
+ function bo() {
1179
+ return at() ?? "unscoped";
1180
1180
  }
1181
- function bn(e) {
1182
- return tt(e) ? pr[e] : "var(--color-neutral-bg)";
1181
+ function gn(e) {
1182
+ return tt(e) ? fr[e] : "var(--color-neutral-bg)";
1183
1183
  }
1184
- function vo(e) {
1185
- return tt(e) ? `${me().serverOrigin.replace(/\/$/, "")}${gr(e)}` : void 0;
1184
+ function yo(e) {
1185
+ return tt(e) ? `${me().serverOrigin.replace(/\/$/, "")}${hr(e)}` : void 0;
1186
1186
  }
1187
1187
  let ce = null, ve = null;
1188
- function So() {
1188
+ function vo() {
1189
1189
  return ce ? Promise.resolve() : ve || (ve = (async () => {
1190
1190
  try {
1191
1191
  const e = me().serverOrigin.replace(/\/$/, ""), t = await fetch(`${e}/media/sprites/names.json`, { cache: "no-cache" });
@@ -1204,7 +1204,7 @@ function J(e) {
1204
1204
  const t = e.toLowerCase();
1205
1205
  return Me.some((n) => n === t) ? !0 : ce ? Object.values(ce).some((n) => n.toLowerCase() === t) : !1;
1206
1206
  }
1207
- const _o = r.object({
1207
+ const So = r.object({
1208
1208
  // Identity. There is deliberately NO `name`: a person's name is their
1209
1209
  // hadoku key-registry name, resolved by the server from whoami and renamed
1210
1210
  // through hadoku_site's POST /session/name (operator decision 2026-10-08).
@@ -1229,16 +1229,16 @@ const _o = r.object({
1229
1229
  preferredAudioLang: r.string().optional(),
1230
1230
  subtitlesEnabled: r.boolean().optional(),
1231
1231
  subtitleStyle: r.string().optional()
1232
- }), se = Bn({
1232
+ }), se = $n({
1233
1233
  appId: "watchparty",
1234
- schema: _o
1235
- }), wo = /* @__PURE__ */ new Set(["theme", "themeMode"]);
1234
+ schema: So
1235
+ }), _o = /* @__PURE__ */ new Set(["theme", "themeMode"]);
1236
1236
  function Re(e) {
1237
- const t = it();
1237
+ const t = at();
1238
1238
  return t ? `prefs-cache:${t}:${e}` : null;
1239
1239
  }
1240
- function xo() {
1241
- return it() === null;
1240
+ function wo() {
1241
+ return at() === null;
1242
1242
  }
1243
1243
  function _t(e) {
1244
1244
  const t = Re(e);
@@ -1251,35 +1251,35 @@ function _t(e) {
1251
1251
  return {};
1252
1252
  }
1253
1253
  }
1254
- function Io() {
1254
+ function xo() {
1255
1255
  let e = 0;
1256
- for (const t of Jr()) {
1256
+ for (const t of Xr()) {
1257
1257
  const n = t.startsWith("prefs-cache:") && t.endsWith(":watchparty"), o = t === De || t.startsWith(`${De}:`) && !t.endsWith(":_serverSynced_v1");
1258
1258
  if (!n && !o) continue;
1259
- const a = B(t);
1260
- if (!a) continue;
1261
- let i;
1259
+ const i = B(t);
1260
+ if (!i) continue;
1261
+ let a;
1262
1262
  try {
1263
- i = JSON.parse(a);
1263
+ a = JSON.parse(i);
1264
1264
  } catch {
1265
1265
  continue;
1266
1266
  }
1267
- const s = n ? i?.blob : i;
1267
+ const s = n ? a?.blob : a;
1268
1268
  if (!s || typeof s != "object" || !("name" in s)) continue;
1269
- const { name: l, ...p } = s, h = n ? { ...i, blob: p } : p;
1269
+ const { name: l, ...p } = s, h = n ? { ...a, blob: p } : p;
1270
1270
  ot(t, JSON.stringify(h)) && e++;
1271
1271
  }
1272
1272
  return e > 0 && d("preferences", "Stripped retired name from cached prefs rows", { rewritten: e }), e;
1273
1273
  }
1274
- let yn = null, vn = null;
1274
+ let bn = null, yn = null;
1275
1275
  const wt = /* @__PURE__ */ new Set();
1276
1276
  function lt() {
1277
- if (xo())
1277
+ if (wo())
1278
1278
  return d("preferences", "Boot read deferred — session pending, identity unresolved"), {};
1279
- const e = _t("portfolio"), t = _t("watchparty"), n = Object.keys(e).length > 0 ? e : yn ?? {}, o = Object.keys(t).length > 0 ? t : vn ?? {}, a = st() || "public";
1280
- if (wt.has(a))
1279
+ const e = _t("portfolio"), t = _t("watchparty"), n = Object.keys(e).length > 0 ? e : bn ?? {}, o = Object.keys(t).length > 0 ? t : yn ?? {}, i = st() || "public";
1280
+ if (wt.has(i))
1281
1281
  return d("preferences", "Loaded (sync, SDK-only after first read)", {
1282
- uid: a,
1282
+ uid: i,
1283
1283
  sdkThemeKeys: Object.keys(n).length,
1284
1284
  sdkAppKeys: Object.keys(o).length,
1285
1285
  // 'mem' indicates in-memory backstop fired (cache was empty,
@@ -1287,55 +1287,55 @@ function lt() {
1287
1287
  themeSource: Object.keys(e).length > 0 ? "cache" : "mem",
1288
1288
  appSource: Object.keys(t).length > 0 ? "cache" : "mem"
1289
1289
  }), { ...o, ...n };
1290
- wt.add(a);
1291
- const i = _n() ?? {}, s = { ...i, ...o, ...n };
1290
+ wt.add(i);
1291
+ const a = Sn() ?? {}, s = { ...a, ...o, ...n };
1292
1292
  return d("preferences", "Loaded (sync, first read — legacy + SDK)", {
1293
- uid: a,
1293
+ uid: i,
1294
1294
  sdkThemeKeys: Object.keys(n).length,
1295
1295
  sdkAppKeys: Object.keys(o).length,
1296
- legacyKeys: Object.keys(i).length,
1296
+ legacyKeys: Object.keys(a).length,
1297
1297
  themeSource: Object.keys(e).length > 0 ? "cache" : "mem",
1298
1298
  appSource: Object.keys(t).length > 0 ? "cache" : "mem"
1299
1299
  }), s;
1300
1300
  }
1301
- let Sn = !1;
1302
- function Co() {
1301
+ let vn = !1;
1302
+ function Io() {
1303
1303
  const e = st();
1304
1304
  return !e || e === "public";
1305
1305
  }
1306
1306
  function G(e, t) {
1307
- Co() && (Sn = !0), wo.has(e) ? ae.save({ [e]: t }, { scope: "device" }).catch((n) => k("preferences", "themePrefs.save failed", { key: e, err: n?.message })) : se.save({ [e]: t }).catch((n) => k("preferences", "watchpartyPrefs.save failed", { key: e, err: n?.message })), d("preferences", "Saved (via SDK)", { key: e, value: t });
1307
+ Io() && (vn = !0), _o.has(e) ? ie.save({ [e]: t }, { scope: "device" }).catch((n) => k("preferences", "themePrefs.save failed", { key: e, err: n?.message })) : se.save({ [e]: t }).catch((n) => k("preferences", "watchpartyPrefs.save failed", { key: e, err: n?.message })), d("preferences", "Saved (via SDK)", { key: e, value: t });
1308
1308
  }
1309
1309
  let Se = null, xt = !1;
1310
- function To() {
1310
+ function Co() {
1311
1311
  return Se || (Se = (async () => {
1312
1312
  if (typeof window > "u") return !1;
1313
1313
  try {
1314
- xt || (xt = !0, ae.subscribe((s) => {
1315
- yn = s, Tt("portfolio", s), kt("theme");
1314
+ xt || (xt = !0, ie.subscribe((s) => {
1315
+ bn = s, Tt("portfolio", s), kt("theme");
1316
1316
  }), se.subscribe((s) => {
1317
- vn = s, Tt("watchparty", s), kt("watchparty");
1317
+ yn = s, Tt("watchparty", s), kt("watchparty");
1318
1318
  }));
1319
1319
  const [e, t] = await Promise.all([
1320
- ae.read(),
1320
+ ie.read(),
1321
1321
  se.read()
1322
1322
  ]);
1323
1323
  try {
1324
- const { useAppStore: s } = await Promise.resolve().then(() => xn);
1324
+ const { useAppStore: s } = await Promise.resolve().then(() => wn);
1325
1325
  s.getState().rehydrateFromPrefs();
1326
1326
  } catch (s) {
1327
1327
  k("preferences", "inline rehydrate after SDK read failed", { err: s?.message });
1328
1328
  }
1329
- const n = Re("portfolio"), o = Re("watchparty"), a = n ? B(n) : null, i = o ? B(o) : null;
1329
+ const n = Re("portfolio"), o = Re("watchparty"), i = n ? B(n) : null, a = o ? B(o) : null;
1330
1330
  return d("preferences", "sdk.read", {
1331
1331
  themeKeys: Object.keys(e ?? {}),
1332
1332
  appKeys: Object.keys(t ?? {}),
1333
1333
  appName: t?.name,
1334
1334
  // Post-fetch cache state: should be non-zero if SDK wrote it.
1335
- sdkThemeBytesPost: a?.length ?? 0,
1336
- sdkAppBytesPost: i?.length ?? 0
1337
- }), await ko(e, t), Sn ? (d("preferences", "Promoting this load's pre-auth picks to the signed-in user"), await Promise.all([
1338
- ae.promoteAnonPrefsToUser().catch(() => {
1335
+ sdkThemeBytesPost: i?.length ?? 0,
1336
+ sdkAppBytesPost: a?.length ?? 0
1337
+ }), await To(e, t), vn ? (d("preferences", "Promoting this load's pre-auth picks to the signed-in user"), await Promise.all([
1338
+ ie.promoteAnonPrefsToUser().catch(() => {
1339
1339
  }),
1340
1340
  se.promoteAnonPrefsToUser().catch(() => {
1341
1341
  })
@@ -1346,12 +1346,12 @@ function To() {
1346
1346
  })(), Se);
1347
1347
  }
1348
1348
  const De = "watchparty_preferences";
1349
- Io();
1349
+ xo();
1350
1350
  function Xe() {
1351
1351
  const e = st();
1352
1352
  return !e || e === "public" ? De : `${De}:${e}`;
1353
1353
  }
1354
- function _n() {
1354
+ function Sn() {
1355
1355
  const e = B(Xe());
1356
1356
  if (!e) return null;
1357
1357
  try {
@@ -1364,13 +1364,13 @@ function _n() {
1364
1364
  function It() {
1365
1365
  Ne(Xe()), Ne(`${Xe()}:_serverSynced_v1`);
1366
1366
  }
1367
- async function ko(e, t) {
1368
- const n = _n();
1367
+ async function To(e, t) {
1368
+ const n = Sn();
1369
1369
  if (!n || Object.keys(n).length === 0) return;
1370
- const o = Object.keys(e ?? {}).length > 0, a = Object.keys(t ?? {}).length > 0, i = {}, s = {};
1370
+ const o = Object.keys(e ?? {}).length > 0, i = Object.keys(t ?? {}).length > 0, a = {}, s = {};
1371
1371
  for (const [h, f] of Object.entries(n))
1372
- o || (h === "theme" && typeof f == "string" ? i.theme = f : h === "themeMode" && (f === "simple" || f === "advanced") && (i.themeMode = f)), a || (h === "chatCollapsed" && typeof f == "boolean" ? s.chatCollapsed = f : h === "floatingChatEnabled" && typeof f == "boolean" ? s.floatingChatEnabled = f : h === "volume" && typeof f == "number" && f >= 0 && f <= 1 ? s.volume = f : h === "muted" && typeof f == "boolean" ? s.muted = f : h === "preferredAudioLang" && typeof f == "string" ? s.preferredAudioLang = f : h === "subtitlesEnabled" && typeof f == "boolean" ? s.subtitlesEnabled = f : h === "subtitleStyle" && typeof f == "string" && (s.subtitleStyle = f));
1373
- const l = Object.keys(i), p = Object.keys(s);
1372
+ o || (h === "theme" && typeof f == "string" ? a.theme = f : h === "themeMode" && (f === "simple" || f === "advanced") && (a.themeMode = f)), i || (h === "chatCollapsed" && typeof f == "boolean" ? s.chatCollapsed = f : h === "floatingChatEnabled" && typeof f == "boolean" ? s.floatingChatEnabled = f : h === "volume" && typeof f == "number" && f >= 0 && f <= 1 ? s.volume = f : h === "muted" && typeof f == "boolean" ? s.muted = f : h === "preferredAudioLang" && typeof f == "string" ? s.preferredAudioLang = f : h === "subtitlesEnabled" && typeof f == "boolean" ? s.subtitlesEnabled = f : h === "subtitleStyle" && typeof f == "string" && (s.subtitleStyle = f));
1373
+ const l = Object.keys(a), p = Object.keys(s);
1374
1374
  if (l.length === 0 && p.length === 0) {
1375
1375
  It();
1376
1376
  return;
@@ -1379,11 +1379,11 @@ async function ko(e, t) {
1379
1379
  themeKeys: l,
1380
1380
  appKeys: p,
1381
1381
  sdkHasTheme: o,
1382
- sdkHasApp: a
1382
+ sdkHasApp: i
1383
1383
  });
1384
1384
  try {
1385
1385
  await Promise.all([
1386
- l.length > 0 ? ae.save(i, { scope: "device" }) : Promise.resolve(),
1386
+ l.length > 0 ? ie.save(a, { scope: "device" }) : Promise.resolve(),
1387
1387
  p.length > 0 ? se.save(s) : Promise.resolve()
1388
1388
  ]), It(), d("preferences", "Legacy migration complete");
1389
1389
  } catch (h) {
@@ -1413,7 +1413,7 @@ function Tt(e, t) {
1413
1413
  }
1414
1414
  }
1415
1415
  function kt(e) {
1416
- Promise.resolve().then(() => xn).then(({ useAppStore: t }) => {
1416
+ Promise.resolve().then(() => wn).then(({ useAppStore: t }) => {
1417
1417
  try {
1418
1418
  t.getState().rehydrateFromPrefs();
1419
1419
  } catch (n) {
@@ -1421,16 +1421,16 @@ function kt(e) {
1421
1421
  }
1422
1422
  }).catch((t) => k("preferences", "store import failed", { reason: e, err: t?.message }));
1423
1423
  }
1424
- const wn = 320, Oe = 240, ct = 640, Ao = 320, Eo = 36, At = 16;
1424
+ const _n = 320, Oe = 240, ct = 640, ko = 320, Ao = 36, At = 16;
1425
1425
  function W(e, t) {
1426
- if (!Number.isFinite(e)) return wn;
1426
+ if (!Number.isFinite(e)) return _n;
1427
1427
  let n = ct;
1428
- return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t - Ao)), n = Math.max(n, Oe), Math.round(Math.min(n, Math.max(Oe, e)));
1428
+ return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t - ko)), n = Math.max(n, Oe), Math.round(Math.min(n, Math.max(Oe, e)));
1429
1429
  }
1430
1430
  function Et(e, t, n, o) {
1431
1431
  return W(e + (t - n), o);
1432
1432
  }
1433
- function Po(e, t, n) {
1433
+ function Eo(e, t, n) {
1434
1434
  switch (t) {
1435
1435
  case "ArrowLeft":
1436
1436
  return W(e + At, n);
@@ -1444,10 +1444,10 @@ function Po(e, t, n) {
1444
1444
  return null;
1445
1445
  }
1446
1446
  }
1447
- function No(e, t) {
1448
- return { collapsed: e, width: e ? Eo : t };
1447
+ function Po(e, t) {
1448
+ return { collapsed: e, width: e ? Ao : t };
1449
1449
  }
1450
- const K = lt(), u = $n((e, t) => ({
1450
+ const K = lt(), u = Hn((e, t) => ({
1451
1451
  ready: !1,
1452
1452
  name: "",
1453
1453
  sprite: null,
@@ -1457,7 +1457,7 @@ const K = lt(), u = $n((e, t) => ({
1457
1457
  chat: [],
1458
1458
  chatCollapsed: K.chatCollapsed ?? !1,
1459
1459
  chromeChatCollapsed: K.chromeChatCollapsed ?? !1,
1460
- chromeChatWidth: W(K.chromeChatWidth ?? wn),
1460
+ chromeChatWidth: W(K.chromeChatWidth ?? _n),
1461
1461
  // Hardcoded on for everyone — the per-user toggle was removed from the
1462
1462
  // control bar; FloatingChat + toggleFloatingChat code is kept for future
1463
1463
  // re-enablement but the value is no longer user-controllable.
@@ -1503,18 +1503,18 @@ const K = lt(), u = $n((e, t) => ({
1503
1503
  ensureAutoIdentity: () => e((n) => {
1504
1504
  if (n.name) return {};
1505
1505
  if (n.sprite) {
1506
- const a = de(n.sprite);
1507
- return d("store", "Auto-identity: deriving name from the requested sprite", { name: a, sprite: n.sprite }), { name: a };
1506
+ const i = de(n.sprite);
1507
+ return d("store", "Auto-identity: deriving name from the requested sprite", { name: i, sprite: n.sprite }), { name: i };
1508
1508
  }
1509
- const o = new Set(Object.values(n.roster).map((a) => a.sprite).filter(Boolean));
1509
+ const o = new Set(Object.values(n.roster).map((i) => i.sprite).filter(Boolean));
1510
1510
  d("store", "ensureAutoIdentity checking", {
1511
1511
  rosterSize: Object.keys(n.roster).length,
1512
1512
  usedSprites: Array.from(o)
1513
1513
  });
1514
- for (const a of Me)
1515
- if (!o.has(a)) {
1516
- const i = de(a);
1517
- return d("store", "Auto-identity assigned", { name: i, sprite: a }), { name: i, sprite: a };
1514
+ for (const i of Me)
1515
+ if (!o.has(i)) {
1516
+ const a = de(i);
1517
+ return d("store", "Auto-identity assigned", { name: a, sprite: i }), { name: a, sprite: i };
1518
1518
  }
1519
1519
  return k("store", "All characters taken, leaving identity unset"), {};
1520
1520
  }),
@@ -1522,12 +1522,12 @@ const K = lt(), u = $n((e, t) => ({
1522
1522
  d("store", "Client ID set", { clientId: n }), e((o) => ({ me: { ...o.me, clientId: n } }));
1523
1523
  },
1524
1524
  applySnapshot: (n) => e((o) => {
1525
- const a = { ...o.roster };
1525
+ const i = { ...o.roster };
1526
1526
  if (n.users)
1527
- for (const p of n.users) a[p.clientId] = p;
1528
- const i = n.mediaId !== void 0 ? n.mediaId : o.snapshot.mediaId, s = n.leaderId !== void 0 ? n.leaderId : o.snapshot.leaderId;
1527
+ for (const p of n.users) i[p.clientId] = p;
1528
+ const a = n.mediaId !== void 0 ? n.mediaId : o.snapshot.mediaId, s = n.leaderId !== void 0 ? n.leaderId : o.snapshot.leaderId;
1529
1529
  d("store", "Snapshot applied", {
1530
- mediaId: i,
1530
+ mediaId: a,
1531
1531
  playing: n.playing ?? o.snapshot.playing,
1532
1532
  serverSeq: n.serverSeq ?? o.snapshot.serverSeq,
1533
1533
  userCount: n.users?.length ?? 0
@@ -1536,13 +1536,13 @@ const K = lt(), u = $n((e, t) => ({
1536
1536
  return {
1537
1537
  snapshot: {
1538
1538
  roomId: n.roomId !== void 0 ? n.roomId : o.snapshot.roomId,
1539
- mediaId: i,
1539
+ mediaId: a,
1540
1540
  playheadMs: l,
1541
1541
  playing: n.playing ?? o.snapshot.playing,
1542
1542
  serverSeq: n.serverSeq ?? o.snapshot.serverSeq,
1543
1543
  leaderId: s
1544
1544
  },
1545
- roster: a,
1545
+ roster: i,
1546
1546
  // Always update — initial snapshot on join often has playheadMs=0
1547
1547
  // matching the store default, so the old playheadChanged guard left
1548
1548
  // snapshotReceivedAt at page-load time. This inflated viewer correction
@@ -1555,8 +1555,8 @@ const K = lt(), u = $n((e, t) => ({
1555
1555
  },
1556
1556
  removeUser: (n) => {
1557
1557
  d("store", "User removed", { clientId: n }), e((o) => {
1558
- const a = { ...o.roster };
1559
- return delete a[n], { roster: a };
1558
+ const i = { ...o.roster };
1559
+ return delete i[n], { roster: i };
1560
1560
  });
1561
1561
  },
1562
1562
  appendChat: (n) => {
@@ -1595,19 +1595,19 @@ const K = lt(), u = $n((e, t) => ({
1595
1595
  snapshotReceivedAt: Date.now()
1596
1596
  }));
1597
1597
  },
1598
- addRttSample: (n, o, a) => e((i) => {
1599
- const s = [...i.drift.rtts, n].slice(-5);
1600
- let l = i.drift.offsetMs;
1601
- if (o && a) {
1602
- const p = a + n / 2;
1598
+ addRttSample: (n, o, i) => e((a) => {
1599
+ const s = [...a.drift.rtts, n].slice(-5);
1600
+ let l = a.drift.offsetMs;
1601
+ if (o && i) {
1602
+ const p = i + n / 2;
1603
1603
  l = o - p;
1604
1604
  }
1605
1605
  return { drift: { rtts: s, offsetMs: l } };
1606
1606
  }),
1607
1607
  pushToast: (n, o) => {
1608
- d("store", "Toast pushed", { kind: n, msg: o }), e((a) => ({ toasts: [...a.toasts, { id: Math.random().toString(36).slice(2), kind: n, msg: o, ts: Date.now() }].slice(-5) }));
1608
+ d("store", "Toast pushed", { kind: n, msg: o }), e((i) => ({ toasts: [...i.toasts, { id: Math.random().toString(36).slice(2), kind: n, msg: o, ts: Date.now() }].slice(-5) }));
1609
1609
  },
1610
- popToast: (n) => e((o) => ({ toasts: o.toasts.filter((a) => a.id !== n) })),
1610
+ popToast: (n) => e((o) => ({ toasts: o.toasts.filter((i) => i.id !== n) })),
1611
1611
  setReadiness: (n) => e({ readiness: { mediaId: n.mediaId, ready: n.ready, readyCount: n.readyCount, total: n.total } }),
1612
1612
  setBufferState: (n) => e((o) => ({ bufferState: { ...o.bufferState, ...n } })),
1613
1613
  setMutedForAutoplay: (n) => e({ mutedForAutoplay: n }),
@@ -1639,9 +1639,9 @@ const K = lt(), u = $n((e, t) => ({
1639
1639
  * board or saves its own, which are the two moments its draft is not ahead of
1640
1640
  * the server.
1641
1641
  */
1642
- setTierlistSnapshot: (n, o) => e((a) => ({
1642
+ setTierlistSnapshot: (n, o) => e((i) => ({
1643
1643
  tierlist: n,
1644
- tierlistDraft: o ? { ...n.myBoard } : a.tierlistDraft
1644
+ tierlistDraft: o ? { ...n.myBoard } : i.tierlistDraft
1645
1645
  })),
1646
1646
  /**
1647
1647
  * Move one item on the draft board. Local only — nothing reaches the server
@@ -1652,14 +1652,14 @@ const K = lt(), u = $n((e, t) => ({
1652
1652
  * present-with-a-low-value — is what keeps "not rated" distinguishable from
1653
1653
  * "rated F" in placeTierlist.
1654
1654
  */
1655
- moveTierlistItem: (n, o, a) => e((i) => {
1655
+ moveTierlistItem: (n, o, i) => e((a) => {
1656
1656
  const s = {};
1657
- for (const [l, p] of Object.entries(i.tierlistDraft)) {
1657
+ for (const [l, p] of Object.entries(a.tierlistDraft)) {
1658
1658
  const h = (p ?? []).filter((f) => f !== n);
1659
1659
  h.length > 0 && (s[l] = h);
1660
1660
  }
1661
1661
  if (o !== null) {
1662
- const l = s[o] ?? [], p = Math.max(0, Math.min(a ?? l.length, l.length));
1662
+ const l = s[o] ?? [], p = Math.max(0, Math.min(i ?? l.length, l.length));
1663
1663
  l.splice(p, 0, n), s[o] = l;
1664
1664
  }
1665
1665
  return { tierlistDraft: s };
@@ -1671,32 +1671,32 @@ const K = lt(), u = $n((e, t) => ({
1671
1671
  setGameSessionWins: (n) => e({ gameSessionWins: { ...n } }),
1672
1672
  setGameBotCount: (n) => e({ gameBotCount: Math.max(0, Math.floor(n)) }),
1673
1673
  rehydrateFromPrefs: () => e((n) => {
1674
- const o = lt(), a = {};
1675
- if (o.chatCollapsed !== void 0 && (a.chatCollapsed = o.chatCollapsed), o.chromeChatCollapsed !== void 0 && (a.chromeChatCollapsed = o.chromeChatCollapsed), o.chromeChatWidth !== void 0 && (a.chromeChatWidth = W(o.chromeChatWidth)), ["volume", "muted", "preferredAudioLang", "subtitlesEnabled", "subtitleStyle"].some((l) => o[l] !== void 0)) {
1674
+ const o = lt(), i = {};
1675
+ if (o.chatCollapsed !== void 0 && (i.chatCollapsed = o.chatCollapsed), o.chromeChatCollapsed !== void 0 && (i.chromeChatCollapsed = o.chromeChatCollapsed), o.chromeChatWidth !== void 0 && (i.chromeChatWidth = W(o.chromeChatWidth)), ["volume", "muted", "preferredAudioLang", "subtitlesEnabled", "subtitleStyle"].some((l) => o[l] !== void 0)) {
1676
1676
  const l = { ...n.mediaPrefs };
1677
- o.volume !== void 0 && (l.volume = o.volume), o.muted !== void 0 && (l.muted = o.muted), o.preferredAudioLang !== void 0 && (l.preferredAudioLang = o.preferredAudioLang), o.subtitlesEnabled !== void 0 && (l.subtitlesEnabled = o.subtitlesEnabled), o.subtitleStyle !== void 0 && ["classic", "cinema", "minimal", "contrast"].includes(o.subtitleStyle) && (l.subtitleStyle = o.subtitleStyle), a.mediaPrefs = l;
1677
+ o.volume !== void 0 && (l.volume = o.volume), o.muted !== void 0 && (l.muted = o.muted), o.preferredAudioLang !== void 0 && (l.preferredAudioLang = o.preferredAudioLang), o.subtitlesEnabled !== void 0 && (l.subtitlesEnabled = o.subtitlesEnabled), o.subtitleStyle !== void 0 && ["classic", "cinema", "minimal", "contrast"].includes(o.subtitleStyle) && (l.subtitleStyle = o.subtitleStyle), i.mediaPrefs = l;
1678
1678
  }
1679
- return a;
1679
+ return i;
1680
1680
  }),
1681
1681
  setSidebarTab: (n) => e((o) => o.sidebarTab === n && n !== "chat" ? { sidebarTab: "chat" } : { sidebarTab: n, chatCollapsed: !1 })
1682
1682
  }));
1683
1683
  Ue("__ZUSTAND_STORE__", u);
1684
- const xn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1684
+ const wn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1685
1685
  __proto__: null,
1686
1686
  useAppStore: u
1687
1687
  }, Symbol.toStringTag, { value: "Module" }));
1688
- function Ro(e) {
1689
- return `${dn()}/media/${e}`.replace(/\\/g, "/");
1688
+ function No(e) {
1689
+ return `${cn()}/media/${e}`.replace(/\\/g, "/");
1690
1690
  }
1691
- function Do(e, t) {
1692
- return Ro(t ?? `${e}/poster.jpg`);
1691
+ function Ro(e, t) {
1692
+ return No(t ?? `${e}/poster.jpg`);
1693
1693
  }
1694
- function Oo(e) {
1695
- return `${dn()}${e}`.replace(/\\/g, "/");
1694
+ function Do(e) {
1695
+ return `${cn()}${e}`.replace(/\\/g, "/");
1696
1696
  }
1697
- async function Mo(e) {
1697
+ async function Oo(e) {
1698
1698
  try {
1699
- const t = await fetch(Oo("/api/tierlist"));
1699
+ const t = await fetch(Do("/api/tierlist"));
1700
1700
  if (!t.ok)
1701
1701
  return k("tierlist", "Board fetch failed", { status: t.status }), null;
1702
1702
  const n = await t.json();
@@ -1710,47 +1710,44 @@ async function Mo(e) {
1710
1710
  }
1711
1711
  }
1712
1712
  let Pt = !1;
1713
- function Lo() {
1713
+ function Mo() {
1714
1714
  if (Pt || typeof Image > "u") return;
1715
1715
  const e = u.getState().tierlist;
1716
1716
  if (!(!e || e.items.length === 0)) {
1717
1717
  Pt = !0;
1718
1718
  for (const t of e.items) {
1719
1719
  const n = new Image();
1720
- n.decoding = "async", n.src = Do(t.id, t.thumbnail);
1720
+ n.decoding = "async", n.src = Ro(t.id, t.thumbnail);
1721
1721
  }
1722
1722
  d("tierlist", "Warming posters", { count: e.items.length });
1723
1723
  }
1724
1724
  }
1725
- function jo() {
1726
- const e = u.getState(), t = new Set(Object.values(e.roster).map((i) => i.sprite).filter(Boolean)), n = Me.find((i) => !t.has(i));
1725
+ function Lo() {
1726
+ const e = u.getState(), t = new Set(Object.values(e.roster).map((a) => a.sprite).filter(Boolean)), n = Me.find((a) => !t.has(a));
1727
1727
  if (!n)
1728
1728
  return k("socket", "sprite_taken: no available sprites to retry with"), null;
1729
- const o = !!e.name && !J(e.name), a = o ? e.name : de(n);
1730
- return d("socket", "sprite_taken: retrying with next available", { from: e.sprite, to: n, name: a, keptCustomName: o }), e.setSessionIdentity(a, n), { name: a, sprite: n };
1729
+ const o = !!e.name && !J(e.name), i = o ? e.name : de(n);
1730
+ return d("socket", "sprite_taken: retrying with next available", { from: e.sprite, to: n, name: i, keptCustomName: o }), e.setSessionIdentity(i, n), { name: i, sprite: n };
1731
1731
  }
1732
- function Uo(e) {
1732
+ function jo(e) {
1733
1733
  const t = u.getState(), n = e ? t.roster[e] : void 0;
1734
1734
  return !n || !!n.sprite && n.sprite === t.sprite;
1735
1735
  }
1736
1736
  const Nt = "hadoku:avatar";
1737
- function Fo(e) {
1738
- return e === "discord" || e === "steam" || e === "upload";
1739
- }
1740
- function In(e) {
1737
+ function xn(e) {
1741
1738
  const t = e?.sprite ?? e?.avatar?.sprite ?? null;
1742
1739
  return tt(t) ? t : null;
1743
1740
  }
1744
- async function Ho(e = {}) {
1741
+ async function Uo(e = {}) {
1745
1742
  const t = e.fetch ?? (typeof fetch > "u" ? void 0 : fetch), n = typeof window > "u" ? void 0 : window.location?.origin, o = e.baseUrl ?? (n ? `${n}/prefs` : void 0);
1746
1743
  if (!t || !o) return null;
1747
1744
  try {
1748
- const a = await qn({ baseUrl: o, fetch: t }).get(), i = In(a);
1749
- return d("avatar", "Requested character from prefs-api", { sprite: i }), i;
1750
- } catch (a) {
1751
- return a instanceof ht && (a.status === 401 || a.status === 403 || a.status === 404) ? d("avatar", "No avatar settings here (signed out, or no prefs-api on this origin)", { status: a.status }) : k("avatar", "Avatar settings read failed — keeping the auto-assigned character", {
1752
- status: a instanceof ht ? a.status : void 0,
1753
- ...fe(a)
1745
+ const i = await Wn({ baseUrl: o, fetch: t }).get(), a = xn(i);
1746
+ return d("avatar", "Requested character from prefs-api", { sprite: a }), a;
1747
+ } catch (i) {
1748
+ return i instanceof ht && (i.status === 401 || i.status === 403 || i.status === 404) ? d("avatar", "No avatar settings here (signed out, or no prefs-api on this origin)", { status: i.status }) : k("avatar", "Avatar settings read failed — keeping the auto-assigned character", {
1749
+ status: i instanceof ht ? i.status : void 0,
1750
+ ...fe(i)
1754
1751
  }), null;
1755
1752
  }
1756
1753
  }
@@ -1761,29 +1758,29 @@ function Rt(e) {
1761
1758
  const o = !!(t.me.clientId && t.roster[t.me.clientId]?.registryName) || !t.name || !J(t.name) ? t.name : de(e);
1762
1759
  return t.setSessionIdentity(o, e), !0;
1763
1760
  }
1764
- function $o(e, t = typeof window > "u" ? void 0 : window) {
1761
+ function Fo(e, t = typeof window > "u" ? void 0 : window) {
1765
1762
  if (!t) return () => {
1766
1763
  };
1767
1764
  const n = (o) => {
1768
- const a = o.detail;
1769
- !a || typeof a != "object" || e(a);
1765
+ const i = o.detail;
1766
+ !i || typeof i != "object" || e(i);
1770
1767
  };
1771
1768
  return t.addEventListener(Nt, n), () => t.removeEventListener(Nt, n);
1772
1769
  }
1773
- const Bo = 10;
1774
- function Go(e = typeof window < "u" ? window : void 0) {
1770
+ const Ho = 10;
1771
+ function $o(e = typeof window < "u" ? window : void 0) {
1775
1772
  if (!e) return { framed: !1, depth: 0 };
1776
1773
  try {
1777
1774
  let t = 0, n = e;
1778
- for (; n !== n.parent && t < Bo; )
1775
+ for (; n !== n.parent && t < Ho; )
1779
1776
  t++, n = n.parent;
1780
1777
  return { framed: e.top ? e.top !== e.self : t > 0, depth: t };
1781
1778
  } catch {
1782
1779
  return { framed: !1, depth: 0 };
1783
1780
  }
1784
1781
  }
1785
- const Ko = "watchparty_fragment_delivery";
1786
- function Wo() {
1782
+ const Bo = "watchparty_fragment_delivery";
1783
+ function Go() {
1787
1784
  if (typeof window > "u") return null;
1788
1785
  try {
1789
1786
  const e = new URLSearchParams(window.location.search).get("fragmentDelivery");
@@ -1791,93 +1788,93 @@ function Wo() {
1791
1788
  if (e === "0" || e === "false") return !1;
1792
1789
  } catch {
1793
1790
  }
1794
- return Qr(Ko);
1791
+ return Jr(Bo);
1795
1792
  }
1796
- let qo = { ...en }, He = null;
1793
+ let Ko = { ...Zt }, He = null;
1797
1794
  const Dt = "watchparty_delivery_client_id";
1798
- function Vo() {
1795
+ function Wo() {
1799
1796
  const e = B(Dt);
1800
1797
  if (e) return e;
1801
1798
  const t = globalThis.crypto?.randomUUID?.() ?? `d${Math.random().toString(36).slice(2)}`;
1802
1799
  return ot(Dt, t) ? t : "";
1803
1800
  }
1804
- function Yo() {
1805
- return He === null && (He = wr(qo, Vo(), Wo())), He;
1801
+ function qo() {
1802
+ return He === null && (He = _r(Ko, Wo(), Go())), He;
1806
1803
  }
1807
- function zo() {
1808
- return Yo();
1804
+ function Vo() {
1805
+ return qo();
1809
1806
  }
1810
1807
  let Ae;
1811
- function Cn() {
1812
- return B(Kn) || void 0;
1808
+ function In() {
1809
+ return B(Gn) || void 0;
1813
1810
  }
1814
- function Xo() {
1811
+ function Yo() {
1815
1812
  if (Ae) return;
1816
- const e = Cn();
1813
+ const e = In();
1817
1814
  if (e) {
1818
1815
  Ae = e;
1819
1816
  return;
1820
1817
  }
1821
- Gn().then((t) => {
1818
+ Bn().then((t) => {
1822
1819
  t && (Ae = t);
1823
1820
  }).catch(() => {
1824
1821
  d("identity", "device id unavailable — joining without one");
1825
1822
  });
1826
1823
  }
1827
- function Jo() {
1828
- return Ae ??= Cn();
1824
+ function zo() {
1825
+ return Ae ??= In();
1829
1826
  }
1830
- function Qo(e, t) {
1827
+ function Xo(e, t) {
1831
1828
  let n = 0;
1832
1829
  for (const o of e.videos) {
1833
- const a = te.voteKey(t, e.id, o.mediaId);
1834
- globalThis.localStorage?.getItem(a) != null && n++, Ne(a);
1830
+ const i = te.voteKey(t, e.id, o.mediaId);
1831
+ globalThis.localStorage?.getItem(i) != null && n++, Ne(i);
1835
1832
  }
1836
1833
  return n;
1837
1834
  }
1838
- const Zo = 2e4, ea = 1e4;
1839
- function ta() {
1835
+ const Jo = 2e4, Qo = 1e4;
1836
+ function Zo() {
1840
1837
  return { unansweredSince: null, lastPongAt: null, lastTickAt: null };
1841
1838
  }
1842
- function na(e, t) {
1839
+ function ei(e, t) {
1843
1840
  e.lastPongAt = t, e.unansweredSince = null;
1844
1841
  }
1845
- function ra(e, t, n) {
1846
- const o = e.lastTickAt !== null && t - e.lastTickAt > ea;
1847
- return e.lastTickAt = t, n ? o || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince > Zo : (e.unansweredSince = null, !1);
1842
+ function ti(e, t, n) {
1843
+ const o = e.lastTickAt !== null && t - e.lastTickAt > Qo;
1844
+ return e.lastTickAt = t, n ? o || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince > Jo : (e.unansweredSince = null, !1);
1848
1845
  }
1849
- function oa(e, t) {
1846
+ function ni(e, t) {
1850
1847
  return e.lastPongAt === null ? void 0 : Math.max(0, t - e.lastPongAt);
1851
1848
  }
1852
- let _ = null, H = null, Ee = null, $ = null, q = null;
1853
- const aa = la(), Z = ta();
1854
- let _e = null, $e = null, Ot = 0, dt = null, ue = !1, ut = !1, oe = !1, Tn = null;
1855
- function ia(e) {
1849
+ let S = null, H = null, Ee = null, $ = null, q = null;
1850
+ const ri = ai(), Z = Zo();
1851
+ let _e = null, $e = null, Ot = 0, dt = null, ue = !1, ut = !1, oe = !1, Cn = null;
1852
+ function oi(e) {
1856
1853
  const t = ne(), n = u.getState();
1857
1854
  if (n.me.clientId && n.roster[n.me.clientId])
1858
1855
  return (e.name || e.sprite) && (d("socket", "Identity update (already joined)", { name: e.name, sprite: e.sprite }), t.emit(w.IDENTITY_UPDATE, { name: e.name, sprite: e.sprite })), t;
1859
- const o = sa(e);
1856
+ const o = ii(e);
1860
1857
  return q = o, dt = { name: o.name, sprite: o.sprite }, t.connected ? (d("socket", "Emitting join", o), t.emit(w.JOIN, o)) : t.once("connect", () => {
1861
1858
  d("socket", "Emitting join", o), t.emit(w.JOIN, o);
1862
1859
  }), t;
1863
1860
  }
1864
- function sa(e) {
1861
+ function ii(e) {
1865
1862
  return {
1866
1863
  room_key: e.room_key,
1867
1864
  name: e.name,
1868
1865
  sprite: e.sprite,
1869
1866
  // Entry-path telemetry — see lib/embedContext.ts. Sent on every join AND
1870
1867
  // rejoin (lastJoinPayload carries it), so a reconnect keeps the attribution.
1871
- embed: Go(),
1872
- delivery_arm: zo(),
1868
+ embed: $o(),
1869
+ delivery_arm: Vo(),
1873
1870
  // Identity tier input — see lib/deviceId.ts. Sent on every join AND rejoin
1874
1871
  // (lastJoinPayload carries it) so a reconnect lands on the same
1875
1872
  // ParticipantId rather than minting a new person.
1876
- device_id: Jo(),
1877
- tab_id: aa
1873
+ device_id: zo(),
1874
+ tab_id: ri
1878
1875
  };
1879
1876
  }
1880
- function la() {
1877
+ function ai() {
1881
1878
  const e = globalThis.crypto;
1882
1879
  if (e && typeof e.randomUUID == "function") return e.randomUUID();
1883
1880
  const t = new Uint8Array(16);
@@ -1886,61 +1883,61 @@ function la() {
1886
1883
  return Array.from(t, (n) => n.toString(16).padStart(2, "0")).join("");
1887
1884
  }
1888
1885
  function ne() {
1889
- if (!_) {
1886
+ if (!S) {
1890
1887
  let t = me().serverOrigin || "/";
1891
1888
  if (t === "/" && typeof window < "u") {
1892
1889
  const o = window.location;
1893
- (o.hostname === "localhost" || o.hostname === "127.0.0.1") && o.port === String(qt) && (t = `${o.protocol}//${o.hostname}:${Qe}`, d("socket", "Using dev fallback origin", { origin: t }));
1890
+ (o.hostname === "localhost" || o.hostname === "127.0.0.1") && o.port === String(Wt) && (t = `${o.protocol}//${o.hostname}:${Qe}`, d("socket", "Using dev fallback origin", { origin: t }));
1894
1891
  }
1895
1892
  const n = new URL(t.startsWith("http") ? t : `${window.location.origin}${t}`).origin;
1896
- _ = Wn(n, { path: Xn, transports: ["websocket", "polling"] }), d("socket", "Socket initialized", { origin: t }), Ue("__SOCKET__", _), $ && (clearTimeout($), $ = null), H = null, Ee = setInterval(() => {
1897
- if (ra(Z, Date.now(), !!_?.connected)) {
1893
+ S = Kn(n, { path: zn, transports: ["websocket", "polling"] }), d("socket", "Socket initialized", { origin: t }), Ue("__SOCKET__", S), $ && (clearTimeout($), $ = null), H = null, Ee = setInterval(() => {
1894
+ if (ti(Z, Date.now(), !!S?.connected)) {
1898
1895
  k("socket", "PONG-WATCHDOG no time_pong for 20s — replacing the connection", {
1899
- sid: _?.id,
1900
- lastPongAgeMs: oa(Z, Date.now()) ?? null
1901
- }), $e = "pong-watchdog", Z.unansweredSince = null, _?.io.engine?.close();
1896
+ sid: S?.id,
1897
+ lastPongAgeMs: ni(Z, Date.now()) ?? null
1898
+ }), $e = "pong-watchdog", Z.unansweredSince = null, S?.io.engine?.close();
1902
1899
  return;
1903
1900
  }
1904
- va();
1905
- }, br), _.on("connect", () => {
1901
+ bi();
1902
+ }, gr), S.on("connect", () => {
1906
1903
  ut = !1;
1907
- const o = _?.id;
1904
+ const o = S?.id;
1908
1905
  if (d("socket", "Connected", { id: o, isReconnect: oe }), o)
1909
1906
  try {
1910
- u.getState().ensureMe(o), u.setState((a) => ({ me: { ...a.me, nextClientSeq: 1 } })), d("socket", "Reset client sequence for new connection");
1911
- } catch (a) {
1912
- ke("socket", "Failed to initialize store on connect", { error: a.message, sid: o });
1907
+ u.getState().ensureMe(o), u.setState((i) => ({ me: { ...i.me, nextClientSeq: 1 } })), d("socket", "Reset client sequence for new connection");
1908
+ } catch (i) {
1909
+ ke("socket", "Failed to initialize store on connect", { error: i.message, sid: o });
1913
1910
  }
1914
1911
  if (oe && q) {
1915
- const a = u.getState();
1912
+ const i = u.getState();
1916
1913
  Ot += 1;
1917
- const i = {
1914
+ const a = {
1918
1915
  ...q,
1919
- name: a.name,
1920
- sprite: a.sprite,
1916
+ name: i.name,
1917
+ sprite: i.sprite,
1921
1918
  reconnect: {
1922
1919
  count: Ot,
1923
1920
  reason: (_e?.reason ?? "unknown").slice(0, 64),
1924
1921
  offline_ms: _e ? Math.max(0, Date.now() - _e.at) : 0
1925
1922
  }
1926
- }, s = Tn;
1927
- if (d("socket", "Re-emitting join after reconnect", { room_key: i.room_key, name: i.name, sprite: i.sprite }), s) {
1923
+ }, s = Cn;
1924
+ if (d("socket", "Re-emitting join after reconnect", { room_key: a.room_key, name: a.name, sprite: a.sprite }), s) {
1928
1925
  let l = !1;
1929
1926
  const p = () => {
1930
- l || (l = !0, _.off(w.SNAPSHOT, p), _.emit(w.CLIENT_READY, { media_id: s }), d("socket", "Re-emitted client_ready after reconnect snapshot", { mediaId: s }));
1927
+ l || (l = !0, S.off(w.SNAPSHOT, p), S.emit(w.CLIENT_READY, { media_id: s }), d("socket", "Re-emitted client_ready after reconnect snapshot", { mediaId: s }));
1931
1928
  };
1932
- _.on(w.SNAPSHOT, p), setTimeout(() => {
1933
- l || (l = !0, _.off(w.SNAPSHOT, p), k("socket", "client_ready re-emit timed out waiting for snapshot", { mediaId: s }));
1929
+ S.on(w.SNAPSHOT, p), setTimeout(() => {
1930
+ l || (l = !0, S.off(w.SNAPSHOT, p), k("socket", "client_ready re-emit timed out waiting for snapshot", { mediaId: s }));
1934
1931
  }, 1e4);
1935
1932
  }
1936
- dt = { name: i.name, sprite: i.sprite }, _.emit(w.JOIN, i), window.dispatchEvent(new CustomEvent("watchparty:socket-reconnect"));
1933
+ dt = { name: a.name, sprite: a.sprite }, S.emit(w.JOIN, a), window.dispatchEvent(new CustomEvent("watchparty:socket-reconnect"));
1937
1934
  } else oe && k("socket", "Reconnected — no join payload, not re-joining any room");
1938
1935
  oe = !0;
1939
- }), _.on("disconnect", (o) => {
1940
- hn(null), _e = { reason: $e ?? o, at: Date.now() }, $e = null, d("socket", "Disconnected", { reason: o });
1941
- }), _.on("connect_error", (o) => ke("socket", "Connection error", { message: o?.message })), _.on("reconnect_attempt", (o) => k("socket", "Reconnect attempt", { attempt: o })), _.on("reconnect_failed", () => ke("socket", "Reconnect failed")), ba(_);
1936
+ }), S.on("disconnect", (o) => {
1937
+ pn(null), _e = { reason: $e ?? o, at: Date.now() }, $e = null, d("socket", "Disconnected", { reason: o });
1938
+ }), S.on("connect_error", (o) => ke("socket", "Connection error", { message: o?.message })), S.on("reconnect_attempt", (o) => k("socket", "Reconnect attempt", { attempt: o })), S.on("reconnect_failed", () => ke("socket", "Reconnect failed")), hi(S);
1942
1939
  }
1943
- return _;
1940
+ return S;
1944
1941
  }
1945
1942
  function Be(e) {
1946
1943
  return e.play_state === "playing" || e.playing === !0;
@@ -1962,9 +1959,9 @@ function Mt(e, t) {
1962
1959
  systemType: e.systemType
1963
1960
  };
1964
1961
  }
1965
- function ca(e) {
1962
+ function si(e) {
1966
1963
  e.on(w.SNAPSHOT, (t) => {
1967
- e.emit(Zt.SYNC), u.getState().applySnapshot({
1964
+ e.emit(Qt.SYNC), u.getState().applySnapshot({
1968
1965
  roomId: t.room_id ?? null,
1969
1966
  mediaId: t.media_id ?? null,
1970
1967
  playheadMs: t.playhead_ms || 0,
@@ -1972,9 +1969,9 @@ function ca(e) {
1972
1969
  serverSeq: t.server_seq || 0,
1973
1970
  leaderId: t.leader_id || null
1974
1971
  }), u.getState().name || d("socket", "Deferring identity to presence event (snapshot carries no roster)");
1975
- const n = u.getState(), o = _?.id, i = (o ? n.roster[o] : void 0) ?? dt, s = Vn(
1972
+ const n = u.getState(), o = S?.id, a = (o ? n.roster[o] : void 0) ?? dt, s = qn(
1976
1973
  { name: n.name, avatarId: n.sprite },
1977
- i ? { name: i.name, avatarId: i.sprite ?? null } : void 0,
1974
+ a ? { name: a.name, avatarId: a.sprite ?? null } : void 0,
1978
1975
  // A join that carried no name counts as a default one, so a name that
1979
1976
  // landed after the join (prefs) is still asserted.
1980
1977
  (l) => l === "" || J(l)
@@ -1993,7 +1990,7 @@ function ca(e) {
1993
1990
  leaderId: t.leader_id || null,
1994
1991
  serverSeq: t.server_seq || 0,
1995
1992
  rosterSize: Object.keys(n.roster).length
1996
- }), q?.room_key && _?.id && hn({ room_key: q.room_key, client_id: _.id });
1993
+ }), q?.room_key && S?.id && pn({ room_key: q.room_key, client_id: S.id });
1997
1994
  }), e.on(w.CONTROL_BROADCAST, (t) => {
1998
1995
  const n = u.getState();
1999
1996
  if (Object.prototype.hasOwnProperty.call(t, "media_id")) {
@@ -2015,17 +2012,17 @@ function ca(e) {
2015
2012
  }), e.on(w.CONTROL_ACK, (t) => {
2016
2013
  typeof t?.client_seq == "number" && typeof t?.server_seq == "number" && d("socket", "Control ack received", t);
2017
2014
  }), e.on(w.TIME_PONG, (t) => {
2018
- if (na(Z, Date.now()), H && H.ts) {
2015
+ if (ei(Z, Date.now()), H && H.ts) {
2019
2016
  const n = Date.now() - H.ts;
2020
2017
  u.getState().addRttSample(n, t?.server_ts, H.ts), H = null, $ && (clearTimeout($), $ = null), d("socket", "Time sync RTT", { rtt: n, offset: u.getState().drift.offsetMs });
2021
2018
  }
2022
2019
  }), e.on(w.READY_STATE, (t) => {
2023
2020
  if (!t) return;
2024
- const n = t.media_id ?? null, o = typeof t.ready_count == "number" ? t.ready_count : 0, a = typeof t.total == "number" ? t.total : 0, i = t.ready === !0;
2025
- u.getState().setReadiness({ mediaId: n, ready: i, readyCount: o, total: a }), d("socket", "Ready state received", { mediaId: n, readyCount: o, total: a, ready: i });
2021
+ const n = t.media_id ?? null, o = typeof t.ready_count == "number" ? t.ready_count : 0, i = typeof t.total == "number" ? t.total : 0, a = t.ready === !0;
2022
+ u.getState().setReadiness({ mediaId: n, ready: a, readyCount: o, total: i }), d("socket", "Ready state received", { mediaId: n, readyCount: o, total: i, ready: a });
2026
2023
  });
2027
2024
  }
2028
- function da(e) {
2025
+ function li(e) {
2029
2026
  e.on(w.PRESENCE, (t) => {
2030
2027
  if (!t) return;
2031
2028
  if (Array.isArray(t.users)) {
@@ -2038,16 +2035,16 @@ function da(e) {
2038
2035
  sprite: l.sprite_id ?? l.sprite ?? null,
2039
2036
  isLeader: l.is_leader,
2040
2037
  ...l.registry_name ? { registryName: !0 } : {},
2041
- ...l.avatar_url && Fo(l.avatar_source) ? { avatarUrl: l.avatar_url, avatarSource: l.avatar_source } : {}
2038
+ ...l.avatar_url ? { avatarUrl: l.avatar_url } : {}
2042
2039
  };
2043
- const a = u.getState(), i = _?.id, s = i ? o[i] : void 0;
2040
+ const i = u.getState(), a = S?.id, s = a ? o[a] : void 0;
2044
2041
  if (s?.registryName)
2045
- u.setState({ roster: o }), (s.name !== a.name || s.sprite && s.sprite !== a.sprite) && (d("socket", "Adopting registry name", { from: a.name, to: s.name }), u.getState().setSessionIdentity(s.name, s.sprite ?? a.sprite));
2046
- else if (i && o[i]) {
2047
- const l = o[i].name, p = o[i].sprite;
2048
- if (a.name && !J(a.name) && (o[i].name = a.name), u.setState({ roster: o }), p && p !== a.sprite) {
2049
- const h = a.name && !J(a.name), f = h ? a.name : de(p);
2050
- d("socket", "Server reassigned sprite", { from: a.sprite, to: p, newName: f, preservingCustomName: h }), u.getState().setSessionIdentity(f, p), f !== l && e.emit(w.IDENTITY_UPDATE, { name: f });
2042
+ u.setState({ roster: o }), (s.name !== i.name || s.sprite && s.sprite !== i.sprite) && (d("socket", "Adopting registry name", { from: i.name, to: s.name }), u.getState().setSessionIdentity(s.name, s.sprite ?? i.sprite));
2043
+ else if (a && o[a]) {
2044
+ const l = o[a].name, p = o[a].sprite;
2045
+ if (i.name && !J(i.name) && (o[a].name = i.name), u.setState({ roster: o }), p && p !== i.sprite) {
2046
+ const h = i.name && !J(i.name), f = h ? i.name : de(p);
2047
+ d("socket", "Server reassigned sprite", { from: i.sprite, to: p, newName: f, preservingCustomName: h }), u.getState().setSessionIdentity(f, p), f !== l && e.emit(w.IDENTITY_UPDATE, { name: f });
2051
2048
  }
2052
2049
  }
2053
2050
  }
@@ -2060,7 +2057,7 @@ function da(e) {
2060
2057
  }
2061
2058
  });
2062
2059
  }
2063
- function ua(e) {
2060
+ function ci(e) {
2064
2061
  e.on(w.CHAT_BROADCAST, (t) => {
2065
2062
  const n = Mt(t, t.server_seq);
2066
2063
  u.getState().appendChat(n), d("chat", "Message received", n);
@@ -2070,7 +2067,7 @@ function ua(e) {
2070
2067
  u.getState().setChat(n), d("chat", "History loaded", { count: n.length });
2071
2068
  });
2072
2069
  }
2073
- function ma(e) {
2070
+ function di(e) {
2074
2071
  e.on(be.STATE, (t) => {
2075
2072
  u.getState().applyPlaylistState({
2076
2073
  playlist: t?.playlist ?? null,
@@ -2083,61 +2080,61 @@ function ma(e) {
2083
2080
  u.getState().setPlaylistResults(t ?? null), d("playlist", "Results received", { playlistId: t?.playlist?.id, update: t?.update === !0 });
2084
2081
  }), e.on(be.VOTES_CLEARED, (t) => {
2085
2082
  if (!t?.playlistId || !Array.isArray(t.mediaIds)) return;
2086
- const n = Qo(
2087
- { id: t.playlistId, videos: t.mediaIds.map((a) => ({ mediaId: a })) },
2088
- yo()
2083
+ const n = Xo(
2084
+ { id: t.playlistId, videos: t.mediaIds.map((i) => ({ mediaId: i })) },
2085
+ bo()
2089
2086
  ), o = u.getState();
2090
2087
  o.playlist?.id === t.playlistId && o.applyPlaylistState({ playlist: o.playlist, activeIndex: o.activePlaylistIndex, myVotes: {} }), d("playlist", "Votes cleared by leader", { playlistId: t.playlistId, removed: n });
2091
2088
  });
2092
2089
  }
2093
- function fa(e) {
2094
- e.on(cr.UPDATED, () => {
2095
- d("tierlist", "Someone saved — refreshing the board"), Mo(!1);
2090
+ function ui(e) {
2091
+ e.on(lr.UPDATED, () => {
2092
+ d("tierlist", "Someone saved — refreshing the board"), Oo(!1);
2096
2093
  });
2097
2094
  }
2098
- function pa(e) {
2099
- e.on(dr.STATE, (t) => {
2095
+ function mi(e) {
2096
+ e.on(cr.STATE, (t) => {
2100
2097
  if (!t || typeof t.active != "boolean") return;
2101
2098
  const n = Array.isArray(t.ready) ? t.ready.filter((o) => typeof o == "string") : [];
2102
2099
  u.getState().setReadyCheckState({ active: t.active, ready: n }), d("ready-check", "State received", { active: t.active, readyCount: n.length });
2103
2100
  });
2104
2101
  }
2105
- function ha(e) {
2106
- e.on(Zt.ACTIVE, (t) => {
2102
+ function fi(e) {
2103
+ e.on(Qt.ACTIVE, (t) => {
2107
2104
  const n = typeof t?.gameId == "string" ? t.gameId : null;
2108
2105
  u.getState().setActiveGameId(n), t?.sessionWins && typeof t.sessionWins == "object" ? u.getState().setGameSessionWins(t.sessionWins) : n === null && u.getState().setGameSessionWins({}), typeof t?.botCount == "number" ? u.getState().setGameBotCount(t.botCount) : n === null && u.getState().setGameBotCount(0), d("game", "game_active", { gameId: n, sessionWins: t?.sessionWins, botCount: t?.botCount });
2109
2106
  });
2110
2107
  }
2111
- function ga(e) {
2108
+ function pi(e) {
2112
2109
  e.on(w.HEALTH_SNAPSHOT, (t) => {
2113
2110
  u.getState().setHealthSnapshot(t);
2114
2111
  }), e.on(w.BUFFER_STATUS, (t) => {
2115
2112
  u.getState().setBufferStatus(t);
2116
2113
  });
2117
2114
  }
2118
- function ba(e) {
2119
- ca(e), da(e), ua(e), ga(e), ma(e), fa(e), pa(e), ha(e), e.on(w.ERROR, (t) => {
2115
+ function hi(e) {
2116
+ si(e), li(e), ci(e), pi(e), di(e), ui(e), mi(e), fi(e), e.on(w.ERROR, (t) => {
2120
2117
  const n = t?.code || "error/unknown";
2121
2118
  if (n === "conflict" && t?.message === "sprite_held_by_you") {
2122
2119
  ut = !0, d("socket", "sprite held by this account's other connection: keeping the server-assigned sprite");
2123
2120
  return;
2124
2121
  }
2125
2122
  if (n === "conflict" && t?.message === "sprite_taken") {
2126
- if (Uo(_?.id)) {
2123
+ if (jo(S?.id)) {
2127
2124
  d("socket", "sprite_taken: stale, the server already has our sprite");
2128
2125
  return;
2129
2126
  }
2130
2127
  ue = !0;
2131
2128
  let s;
2132
2129
  try {
2133
- s = jo();
2130
+ s = Lo();
2134
2131
  } finally {
2135
2132
  ue = !1;
2136
2133
  }
2137
2134
  s && e.emit(w.IDENTITY_UPDATE, s);
2138
2135
  return;
2139
2136
  }
2140
- const a = {
2137
+ const i = {
2141
2138
  "control/forbidden": "You are not the leader.",
2142
2139
  "control/stale_seq": "Stale control sequence.",
2143
2140
  "control/seq_gap": "Control sequence gap detected.",
@@ -2155,21 +2152,21 @@ function ba(e) {
2155
2152
  "recap/not_found": "No recap available for the previous episode."
2156
2153
  }[n] || n;
2157
2154
  if (n.startsWith("recap/")) {
2158
- d("socket", `recap unavailable: ${a}`, { code: n }), u.getState().pushToast("info", a);
2155
+ d("socket", `recap unavailable: ${i}`, { code: n }), u.getState().pushToast("info", i);
2159
2156
  return;
2160
2157
  }
2161
- (n.startsWith("auth/") ? k : ke)("socket", `Server error: ${a}`, { code: n, raw: t }), u.getState().pushToast("error", a);
2158
+ (n.startsWith("auth/") ? k : ke)("socket", `Server error: ${i}`, { code: n, raw: t }), u.getState().pushToast("error", i);
2162
2159
  });
2163
2160
  }
2164
- function ya(e, t) {
2161
+ function gi(e, t) {
2165
2162
  ne().emit(w.CHAT_SEND, t?.length ? { text: e, images: t } : { text: e });
2166
2163
  }
2167
- function va() {
2164
+ function bi() {
2168
2165
  H || (H = { ts: Date.now() }, ne().emit(w.TIME_PING, {}), $ = setTimeout(() => {
2169
2166
  H && (d("socket", "Time ping timed out after 10s, clearing inflight"), H = null), $ = null;
2170
2167
  }, 1e4));
2171
2168
  }
2172
- function kn(e) {
2169
+ function Tn(e) {
2173
2170
  const t = u.getState(), n = t.me.clientId;
2174
2171
  if (!n || !t.roster[n]) {
2175
2172
  Rt(e), d("socket", "Avatar change before join: the join will carry it", { sprite: e });
@@ -2181,8 +2178,8 @@ function kn(e) {
2181
2178
  } finally {
2182
2179
  ue = !1;
2183
2180
  }
2184
- const o = u.getState(), a = { avatar: !0 };
2185
- o.sprite && o.sprite !== t.sprite && (a.sprite = o.sprite), o.name && o.name !== t.name && (a.name = o.name), d("socket", "Sending avatar change", a), ne().emit(w.IDENTITY_UPDATE, a);
2181
+ const o = u.getState(), i = { avatar: !0 };
2182
+ o.sprite && o.sprite !== t.sprite && (i.sprite = o.sprite), o.name && o.name !== t.name && (i.name = o.name), d("socket", "Sending avatar change", i), ne().emit(w.IDENTITY_UPDATE, i);
2186
2183
  }
2187
2184
  let we = { name: "", sprite: "" };
2188
2185
  u.subscribe((e, t) => {
@@ -2191,19 +2188,19 @@ u.subscribe((e, t) => {
2191
2188
  if (!n) return;
2192
2189
  const o = e.roster[n];
2193
2190
  if (!o) return;
2194
- const a = !!e.name && !J(e.name) && e.name !== we.name && (J(o.name || "") || o.name !== e.name), i = !!e.sprite && e.sprite !== we.sprite && o.sprite !== e.sprite;
2195
- if (!a && !i) return;
2191
+ const i = !!e.name && !J(e.name) && e.name !== we.name && (J(o.name || "") || o.name !== e.name), a = !!e.sprite && e.sprite !== we.sprite && o.sprite !== e.sprite;
2192
+ if (!i && !a) return;
2196
2193
  const s = {};
2197
- a && (s.name = e.name, we.name = e.name), i && (s.sprite = e.sprite, we.sprite = e.sprite), d("socket", "Identity reassert (store change)", s), _?.connected ? _.emit(w.IDENTITY_UPDATE, s) : ne().emit(w.IDENTITY_UPDATE, s);
2194
+ i && (s.name = e.name, we.name = e.name), a && (s.sprite = e.sprite, we.sprite = e.sprite), d("socket", "Identity reassert (store change)", s), S?.connected ? S.emit(w.IDENTITY_UPDATE, s) : ne().emit(w.IDENTITY_UPDATE, s);
2198
2195
  });
2199
- function Sa() {
2196
+ function yi() {
2200
2197
  Ee && (clearInterval(Ee), Ee = null), $ && (clearTimeout($), $ = null), H = null, Z.unansweredSince = null, Z.lastTickAt = null;
2201
2198
  }
2202
- function _a() {
2203
- d("socket", "clearJoinState called", { hadPayload: q !== null, room_key: q?.room_key }), q = null, oe = !1, Tn = null;
2199
+ function vi() {
2200
+ d("socket", "clearJoinState called", { hadPayload: q !== null, room_key: q?.room_key }), q = null, oe = !1, Cn = null;
2204
2201
  }
2205
2202
  function Lt() {
2206
- d("socket", "leaveRoom called", { room_key: q?.room_key }), _a(), Sa(), _ && (_.disconnect(), _ = null), u.setState({
2203
+ d("socket", "leaveRoom called", { room_key: q?.room_key }), vi(), yi(), S && (S.disconnect(), S = null), u.setState({
2207
2204
  me: { clientId: null, nextClientSeq: 1 },
2208
2205
  roster: {},
2209
2206
  snapshot: { roomId: null, mediaId: null, playheadMs: 0, playing: !1, serverSeq: 0, leaderId: null },
@@ -2219,27 +2216,24 @@ function Lt() {
2219
2216
  gameSessionWins: {}
2220
2217
  });
2221
2218
  }
2222
- function wa() {
2219
+ function Si() {
2223
2220
  d("chat", "Emitting recap_request"), ne().emit("recap_request");
2224
2221
  }
2225
- function xa() {
2226
- D(() => $o((e) => {
2227
- const t = In(e);
2228
- d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }), kn(t);
2222
+ function _i() {
2223
+ D(() => Fo((e) => {
2224
+ const t = xn(e);
2225
+ d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }), Tn(t);
2229
2226
  }), []);
2230
2227
  }
2231
- function Ia(e, t) {
2228
+ function wi(e, t) {
2232
2229
  if (t) {
2233
2230
  for (const n of Object.values(e))
2234
2231
  if (n.author === t && n.avatarUrl) return n.avatarUrl;
2235
2232
  }
2236
2233
  }
2237
- function jt(e) {
2238
- return e.some((t) => t === "steam");
2239
- }
2240
- function An({ sprite: e, url: t, alt: n = "", className: o, fallback: a }) {
2241
- const [i, s] = R(null);
2242
- if (t && t !== i)
2234
+ function kn({ sprite: e, url: t, alt: n = "", className: o, fallback: i }) {
2235
+ const [a, s] = R(null);
2236
+ if (t && t !== a)
2243
2237
  return /* @__PURE__ */ c(
2244
2238
  "img",
2245
2239
  {
@@ -2251,22 +2245,22 @@ function An({ sprite: e, url: t, alt: n = "", className: o, fallback: a }) {
2251
2245
  onError: () => s(t)
2252
2246
  }
2253
2247
  );
2254
- const l = vo(e);
2255
- return l ? /* @__PURE__ */ c("img", { src: l, alt: n, crossOrigin: "anonymous", className: o, draggable: !1 }) : /* @__PURE__ */ c(le, { children: a });
2248
+ const l = yo(e);
2249
+ return l ? /* @__PURE__ */ c("img", { src: l, alt: n, crossOrigin: "anonymous", className: o, draggable: !1 }) : /* @__PURE__ */ c(le, { children: i });
2256
2250
  }
2257
- function Ca(e) {
2251
+ function xi(e) {
2258
2252
  return !(e.button !== 0 || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey);
2259
2253
  }
2260
- function Ta({ src: e, title: t, onClose: n }) {
2254
+ function Ii({ src: e, title: t, onClose: n }) {
2261
2255
  D(() => {
2262
- const i = (s) => {
2256
+ const a = (s) => {
2263
2257
  s.key === "Escape" && (s.stopPropagation(), n());
2264
2258
  };
2265
- return document.addEventListener("keydown", i, !0), () => document.removeEventListener("keydown", i, !0);
2259
+ return document.addEventListener("keydown", a, !0), () => document.removeEventListener("keydown", a, !0);
2266
2260
  }, [n]);
2267
- const o = Xr(), a = typeof document > "u" ? null : document.fullscreenElement ?? o ?? document.body;
2268
- return a ? Yn(
2269
- /* @__PURE__ */ v(
2261
+ const o = zr(), i = typeof document > "u" ? null : document.fullscreenElement ?? o ?? document.body;
2262
+ return i ? Vn(
2263
+ /* @__PURE__ */ _(
2270
2264
  "div",
2271
2265
  {
2272
2266
  className: "fixed inset-0 z-[10000] flex flex-col items-center justify-center bg-black/85 p-6",
@@ -2281,7 +2275,7 @@ function Ta({ src: e, title: t, onClose: n }) {
2281
2275
  {
2282
2276
  src: e,
2283
2277
  alt: t ?? "",
2284
- onClick: (i) => i.stopPropagation(),
2278
+ onClick: (a) => a.stopPropagation(),
2285
2279
  className: "max-h-full max-w-full rounded object-contain shadow-2xl",
2286
2280
  "data-testid": "chat-image-lightbox-img"
2287
2281
  }
@@ -2300,15 +2294,15 @@ function Ta({ src: e, title: t, onClose: n }) {
2300
2294
  ]
2301
2295
  }
2302
2296
  ),
2303
- a
2297
+ i
2304
2298
  ) : null;
2305
2299
  }
2306
- const Ge = 240, ka = 320;
2307
- function Aa({ image: e }) {
2300
+ const Ge = 240, Ci = 320;
2301
+ function Ti({ image: e }) {
2308
2302
  const [t, n] = R(!1), o = Pe(e.key);
2309
2303
  if (!o) return null;
2310
- const a = e.w > 0 && e.h > 0, i = a ? Math.min(1, ka / e.w, Ge / e.h) : 1;
2311
- return /* @__PURE__ */ v(le, { children: [
2304
+ const i = e.w > 0 && e.h > 0, a = i ? Math.min(1, Ci / e.w, Ge / e.h) : 1;
2305
+ return /* @__PURE__ */ _(le, { children: [
2312
2306
  /* @__PURE__ */ c(
2313
2307
  "a",
2314
2308
  {
@@ -2318,7 +2312,7 @@ function Aa({ image: e }) {
2318
2312
  className: "block max-w-full cursor-zoom-in",
2319
2313
  "data-testid": "chat-image",
2320
2314
  onClick: (s) => {
2321
- Ca(s) && (s.preventDefault(), n(!0));
2315
+ xi(s) && (s.preventDefault(), n(!0));
2322
2316
  },
2323
2317
  children: /* @__PURE__ */ c(
2324
2318
  "img",
@@ -2327,16 +2321,16 @@ function Aa({ image: e }) {
2327
2321
  alt: e.title ?? "",
2328
2322
  loading: "lazy",
2329
2323
  decoding: "async",
2330
- width: a ? Math.round(e.w * i) : void 0,
2331
- height: a ? Math.round(e.h * i) : void 0,
2324
+ width: i ? Math.round(e.w * a) : void 0,
2325
+ height: i ? Math.round(e.h * a) : void 0,
2332
2326
  className: "rounded border border-border-light object-contain bg-bg-alt/30",
2333
- style: a ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight: Ge } : { maxWidth: "100%", maxHeight: Ge }
2327
+ style: i ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight: Ge } : { maxWidth: "100%", maxHeight: Ge }
2334
2328
  }
2335
2329
  )
2336
2330
  }
2337
2331
  ),
2338
2332
  t && /* @__PURE__ */ c(
2339
- Ta,
2333
+ Ii,
2340
2334
  {
2341
2335
  src: o,
2342
2336
  title: e.title,
@@ -2345,76 +2339,76 @@ function Aa({ image: e }) {
2345
2339
  )
2346
2340
  ] });
2347
2341
  }
2348
- function Ea({ images: e }) {
2349
- return e?.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: e.map((t, n) => /* @__PURE__ */ c(Aa, { image: t }, `${t.key}-${n}`)) }) : null;
2342
+ function ki({ images: e }) {
2343
+ return e?.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: e.map((t, n) => /* @__PURE__ */ c(Ti, { image: t }, `${t.key}-${n}`)) }) : null;
2350
2344
  }
2351
- function Pa(e, t) {
2345
+ function Ai(e, t) {
2352
2346
  return e.author && t.author ? e.author === t.author : !!t.clientId && e.clientId === t.clientId;
2353
2347
  }
2354
2348
  function Ke(e) {
2355
2349
  return new Date(e).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
2356
2350
  }
2357
- const Na = $t.memo(function({ message: t }) {
2358
- const n = u((l) => l.me.clientId), o = u((l) => l.me.clientId ? l.roster[l.me.clientId]?.author : void 0), a = Pa(t, { clientId: n, author: o }), i = u((l) => Ia(l.roster, t.author));
2351
+ const Ei = Ht.memo(function({ message: t }) {
2352
+ const n = u((l) => l.me.clientId), o = u((l) => l.me.clientId ? l.roster[l.me.clientId]?.author : void 0), i = Ai(t, { clientId: n, author: o }), a = u((l) => wi(l.roster, t.author));
2359
2353
  if (t.isSystem && t.systemType === "recap")
2360
- return /* @__PURE__ */ c("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ v("div", { className: "border-l-2 border-border-light pl-2.5 py-0.5", children: [
2361
- /* @__PURE__ */ v("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-0.5", children: [
2354
+ return /* @__PURE__ */ c("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ _("div", { className: "border-l-2 border-border-light pl-2.5 py-0.5", children: [
2355
+ /* @__PURE__ */ _("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-0.5", children: [
2362
2356
  "Recap",
2363
2357
  /* @__PURE__ */ c("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: Ke(t.ts) })
2364
2358
  ] }),
2365
2359
  /* @__PURE__ */ c("p", { className: "text-[13px] text-text-secondary leading-relaxed whitespace-pre-wrap break-words", children: t.text })
2366
2360
  ] }) });
2367
2361
  if (t.isSystem)
2368
- return /* @__PURE__ */ v("div", { className: "px-2 py-0.5 text-[11px] text-text-muted italic text-center leading-tight", children: [
2362
+ return /* @__PURE__ */ _("div", { className: "px-2 py-0.5 text-[11px] text-text-muted italic text-center leading-tight", children: [
2369
2363
  t.text,
2370
2364
  /* @__PURE__ */ c("span", { className: "ml-1 text-[10px] opacity-50", children: Ke(t.ts) })
2371
2365
  ] });
2372
- const s = bn(t.sprite);
2373
- return /* @__PURE__ */ v("div", { className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${a ? "bg-bg-card/30" : ""}`, children: [
2366
+ const s = gn(t.sprite);
2367
+ return /* @__PURE__ */ _("div", { className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${i ? "bg-bg-card/30" : ""}`, children: [
2374
2368
  /* @__PURE__ */ c(
2375
- An,
2369
+ kn,
2376
2370
  {
2377
2371
  sprite: t.sprite,
2378
- url: i,
2372
+ url: a,
2379
2373
  alt: t.name,
2380
2374
  className: "w-8 h-8 rounded-full object-cover flex-shrink-0",
2381
2375
  fallback: /* @__PURE__ */ c("span", { className: "w-8 h-8 bg-bg-alt/50 rounded-full flex-shrink-0" })
2382
2376
  }
2383
2377
  ),
2384
- /* @__PURE__ */ v("div", { className: "flex-1 min-w-0 -mt-0.5", children: [
2378
+ /* @__PURE__ */ _("div", { className: "flex-1 min-w-0 -mt-0.5", children: [
2385
2379
  /* @__PURE__ */ c("span", { className: "font-medium text-[13px]", style: { color: s }, children: t.name }),
2386
2380
  /* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: Ke(t.ts) }),
2387
2381
  t.text && /* @__PURE__ */ c("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: t.text }),
2388
- /* @__PURE__ */ c(Ea, { images: t.images })
2382
+ /* @__PURE__ */ c(ki, { images: t.images })
2389
2383
  ] })
2390
2384
  ] });
2391
2385
  });
2392
- function Ra() {
2393
- const e = u((a) => a.chat), t = z(null), n = z(!1), o = E(() => {
2394
- const a = t.current;
2395
- if (!a) return;
2396
- const { scrollHeight: i, scrollTop: s, clientHeight: l } = a, p = i - s - l;
2386
+ function Pi() {
2387
+ const e = u((i) => i.chat), t = z(null), n = z(!1), o = E(() => {
2388
+ const i = t.current;
2389
+ if (!i) return;
2390
+ const { scrollHeight: a, scrollTop: s, clientHeight: l } = i, p = a - s - l;
2397
2391
  n.current = p > 40;
2398
2392
  }, []);
2399
2393
  return D(() => {
2400
- const a = t.current;
2401
- a && !n.current && a.scrollTo({ top: a.scrollHeight, behavior: "smooth" });
2394
+ const i = t.current;
2395
+ i && !n.current && i.scrollTo({ top: i.scrollHeight, behavior: "smooth" });
2402
2396
  }, [e.length]), /* @__PURE__ */ c(
2403
2397
  "div",
2404
2398
  {
2405
2399
  ref: t,
2406
2400
  onScroll: o,
2407
2401
  className: "flex-1 overflow-y-auto overflow-x-hidden chat-messages",
2408
- children: e.length === 0 ? /* @__PURE__ */ c("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ c(le, { children: e.map((a, i) => {
2409
- const s = i > 0 ? e[i - 1] : null, l = s && a.ts - s.ts > 1440 * 60 * 1e3;
2410
- return /* @__PURE__ */ v($t.Fragment, { children: [
2411
- l && /* @__PURE__ */ v("div", { className: "flex items-center gap-2 px-4 py-2 my-1", children: [
2402
+ children: e.length === 0 ? /* @__PURE__ */ c("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ c(le, { children: e.map((i, a) => {
2403
+ const s = a > 0 ? e[a - 1] : null, l = s && i.ts - s.ts > 1440 * 60 * 1e3;
2404
+ return /* @__PURE__ */ _(Ht.Fragment, { children: [
2405
+ l && /* @__PURE__ */ _("div", { className: "flex items-center gap-2 px-4 py-2 my-1", children: [
2412
2406
  /* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" }),
2413
- /* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted whitespace-nowrap", children: new Date(a.ts).toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" }) }),
2407
+ /* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted whitespace-nowrap", children: new Date(i.ts).toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" }) }),
2414
2408
  /* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" })
2415
2409
  ] }),
2416
- /* @__PURE__ */ c(Na, { message: a })
2417
- ] }, a.id);
2410
+ /* @__PURE__ */ c(Ei, { message: i })
2411
+ ] }, i.id);
2418
2412
  }) })
2419
2413
  }
2420
2414
  );
@@ -2440,49 +2434,49 @@ const mt = [
2440
2434
  scope: "local"
2441
2435
  }
2442
2436
  ], ee = "/";
2443
- function Da(e) {
2437
+ function Ni(e) {
2444
2438
  if (!e.startsWith(ee)) return null;
2445
2439
  const t = e.slice(ee.length);
2446
2440
  return /\s/.test(t) ? null : t.toLowerCase();
2447
2441
  }
2448
- function Oa(e, t = mt) {
2442
+ function Ri(e, t = mt) {
2449
2443
  const n = e.toLowerCase();
2450
- if (!n) return [...t].sort((a, i) => a.name.localeCompare(i.name));
2444
+ if (!n) return [...t].sort((i, a) => i.name.localeCompare(a.name));
2451
2445
  const o = [];
2452
- for (const a of t) {
2453
- const i = a.name.toLowerCase();
2454
- i.startsWith(n) ? o.push({ cmd: a, rank: 0 }) : i.includes(n) && o.push({ cmd: a, rank: 1 });
2446
+ for (const i of t) {
2447
+ const a = i.name.toLowerCase();
2448
+ a.startsWith(n) ? o.push({ cmd: i, rank: 0 }) : a.includes(n) && o.push({ cmd: i, rank: 1 });
2455
2449
  }
2456
- return o.sort((a, i) => a.rank - i.rank || a.cmd.name.localeCompare(i.cmd.name)).map((a) => a.cmd);
2450
+ return o.sort((i, a) => i.rank - a.rank || i.cmd.name.localeCompare(a.cmd.name)).map((i) => i.cmd);
2457
2451
  }
2458
- function Ma(e) {
2452
+ function Di(e) {
2459
2453
  return `${ee}${e.name} `;
2460
2454
  }
2461
2455
  function We(e, t) {
2462
2456
  return t <= 0 ? 0 : (e % t + t) % t;
2463
2457
  }
2464
- function La(e, t = mt) {
2458
+ function Oi(e, t = mt) {
2465
2459
  const n = e.trim();
2466
2460
  if (!n) return null;
2467
2461
  if (!n.startsWith(ee)) return { kind: "chat", text: n };
2468
- const o = n.slice(ee.length), a = o.search(/\s/), i = (a === -1 ? o : o.slice(0, a)).toLowerCase(), s = a === -1 ? "" : o.slice(a).trim(), l = t.find((p) => p.name.toLowerCase() === i);
2462
+ const o = n.slice(ee.length), i = o.search(/\s/), a = (i === -1 ? o : o.slice(0, i)).toLowerCase(), s = i === -1 ? "" : o.slice(i).trim(), l = t.find((p) => p.name.toLowerCase() === a);
2469
2463
  return l ? { kind: "command", command: l, args: s } : { kind: "chat", text: n };
2470
2464
  }
2471
- function ja(e, t) {
2465
+ function Mi(e, t) {
2472
2466
  return e.requiresMedia && !t.hasMedia ? `${ee}${e.name} needs an episode loaded.` : null;
2473
2467
  }
2474
- function Ua({
2468
+ function Li({
2475
2469
  commands: e,
2476
2470
  activeIndex: t,
2477
2471
  hasMedia: n,
2478
2472
  onPick: o,
2479
- onHover: a,
2480
- listboxId: i
2473
+ onHover: i,
2474
+ listboxId: a
2481
2475
  }) {
2482
2476
  return e.length === 0 ? null : /* @__PURE__ */ c(
2483
2477
  "ul",
2484
2478
  {
2485
- id: i,
2479
+ id: a,
2486
2480
  role: "listbox",
2487
2481
  "aria-label": "Slash commands",
2488
2482
  className: `absolute bottom-full left-0 right-0 z-30 max-h-56 overflow-y-auto
@@ -2490,17 +2484,17 @@ function Ua({
2490
2484
  list-none m-0 p-0 py-1 mb-1`,
2491
2485
  children: e.map((s, l) => {
2492
2486
  const p = !!s.requiresMedia && !n, h = l === t;
2493
- return /* @__PURE__ */ v(
2487
+ return /* @__PURE__ */ _(
2494
2488
  "li",
2495
2489
  {
2496
- id: `${i}-opt-${s.name}`,
2490
+ id: `${a}-opt-${s.name}`,
2497
2491
  role: "option",
2498
2492
  "aria-selected": h,
2499
2493
  "aria-disabled": p,
2500
2494
  onMouseDown: (f) => {
2501
2495
  f.preventDefault(), o(s);
2502
2496
  },
2503
- onMouseEnter: () => a(l),
2497
+ onMouseEnter: () => i(l),
2504
2498
  className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${h ? "bg-bg-alt" : ""} ${p ? "opacity-50" : ""}`,
2505
2499
  children: [
2506
2500
  /* @__PURE__ */ c("span", { className: "text-sm font-semibold text-text shrink-0", children: s.usage }),
@@ -2513,12 +2507,12 @@ function Ua({
2513
2507
  }
2514
2508
  );
2515
2509
  }
2516
- function Fa({
2510
+ function ji({
2517
2511
  pending: e,
2518
2512
  uploading: t,
2519
2513
  onRemove: n
2520
2514
  }) {
2521
- return e.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1.5 pb-1.5", "data-testid": "chat-attachment-strip", children: e.map((o) => /* @__PURE__ */ v("div", { className: "relative", children: [
2515
+ return e.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1.5 pb-1.5", "data-testid": "chat-attachment-strip", children: e.map((o) => /* @__PURE__ */ _("div", { className: "relative", children: [
2522
2516
  /* @__PURE__ */ c(
2523
2517
  "img",
2524
2518
  {
@@ -2540,25 +2534,25 @@ function Fa({
2540
2534
  )
2541
2535
  ] }, o.id)) }) : null;
2542
2536
  }
2543
- function Ha() {
2544
- const [e, t] = R([]), [n, o] = R(!1), a = u((m) => m.pushToast), i = z(/* @__PURE__ */ new Set());
2537
+ function Ui() {
2538
+ const [e, t] = R([]), [n, o] = R(!1), i = u((m) => m.pushToast), a = z(/* @__PURE__ */ new Set());
2545
2539
  D(() => () => {
2546
- for (const m of i.current) URL.revokeObjectURL(m);
2547
- i.current.clear();
2540
+ for (const m of a.current) URL.revokeObjectURL(m);
2541
+ a.current.clear();
2548
2542
  }, []);
2549
2543
  const s = E((m) => {
2550
- Dr(m) && (URL.revokeObjectURL(m.previewUrl), i.current.delete(m.previewUrl));
2544
+ Rr(m) && (URL.revokeObjectURL(m.previewUrl), a.current.delete(m.previewUrl));
2551
2545
  }, []), l = E(async (m) => {
2552
2546
  if (!m.length) return;
2553
- const S = [];
2547
+ const v = [];
2554
2548
  for (const y of m) {
2555
- const I = Mr(y);
2549
+ const I = Or(y);
2556
2550
  if (I) {
2557
- a("error", I);
2551
+ i("error", I);
2558
2552
  continue;
2559
2553
  }
2560
- const { w: g, h: A } = await Ur(y), N = URL.createObjectURL(y);
2561
- i.current.add(N), S.push({
2554
+ const { w: g, h: A } = await jr(y), N = URL.createObjectURL(y);
2555
+ a.current.add(N), v.push({
2562
2556
  kind: "file",
2563
2557
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
2564
2558
  file: y,
@@ -2567,61 +2561,61 @@ function Ha() {
2567
2561
  h: A
2568
2562
  });
2569
2563
  }
2570
- S.length && t((y) => {
2564
+ v.length && t((y) => {
2571
2565
  const I = V - y.length;
2572
2566
  if (I <= 0) {
2573
- a("info", `Up to ${V} images per message`);
2574
- for (const g of S) s(g);
2567
+ i("info", `Up to ${V} images per message`);
2568
+ for (const g of v) s(g);
2575
2569
  return y;
2576
2570
  }
2577
- if (S.length > I) {
2578
- a("info", `Up to ${V} images per message`);
2579
- for (const g of S.slice(I)) s(g);
2571
+ if (v.length > I) {
2572
+ i("info", `Up to ${V} images per message`);
2573
+ for (const g of v.slice(I)) s(g);
2580
2574
  }
2581
- return [...y, ...S.slice(0, I)];
2575
+ return [...y, ...v.slice(0, I)];
2582
2576
  });
2583
- }, [a, s]), p = E((m) => {
2584
- const S = Pe(m.key);
2585
- S && (t((y) => y.length >= V ? (a("info", `Up to ${V} images per message`), y) : [...y, {
2577
+ }, [i, s]), p = E((m) => {
2578
+ const v = Pe(m.key);
2579
+ v && (t((y) => y.length >= V ? (i("info", `Up to ${V} images per message`), y) : [...y, {
2586
2580
  kind: "remote",
2587
2581
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
2588
2582
  key: m.key,
2589
- previewUrl: S,
2583
+ previewUrl: v,
2590
2584
  // The catalogue spells "unknown" as null; the wire schema spells it
2591
2585
  // as 0, and the renderer falls back to natural flow on that.
2592
2586
  w: m.width ?? 0,
2593
2587
  h: m.height ?? 0,
2594
2588
  title: m.title || void 0
2595
- }]), Le().catalogue(cn).recordUse(m.key));
2596
- }, [a]), h = E((m) => {
2597
- t((S) => {
2598
- const y = S.find((I) => I.id === m);
2599
- return y && s(y), S.filter((I) => I.id !== m);
2589
+ }]), Le().catalogue(ln).recordUse(m.key));
2590
+ }, [i]), h = E((m) => {
2591
+ t((v) => {
2592
+ const y = v.find((I) => I.id === m);
2593
+ return y && s(y), v.filter((I) => I.id !== m);
2600
2594
  });
2601
2595
  }, [s]), f = E(() => {
2602
2596
  t((m) => {
2603
- for (const S of m) s(S);
2597
+ for (const v of m) s(v);
2604
2598
  return [];
2605
2599
  });
2606
2600
  }, [s]), L = E((m) => {
2607
- const S = Lr(m.clipboardData);
2608
- S.length && (m.preventDefault(), l(S));
2601
+ const v = Mr(m.clipboardData);
2602
+ v.length && (m.preventDefault(), l(v));
2609
2603
  }, [l]), O = E((m) => {
2610
- const S = jr(m.dataTransfer);
2611
- S.length && (m.preventDefault(), l(S));
2604
+ const v = Lr(m.dataTransfer);
2605
+ v.length && (m.preventDefault(), l(v));
2612
2606
  }, [l]), M = E((m) => {
2613
2607
  m.dataTransfer?.types?.includes("Files") && m.preventDefault();
2614
2608
  }, []), C = E(async () => {
2615
2609
  if (!e.length) return [];
2616
2610
  o(!0);
2617
2611
  try {
2618
- return await Hr(e);
2612
+ return await Fr(e);
2619
2613
  } catch (m) {
2620
- return k("chat", "Image upload failed", $r(m)), a("error", Or(m)), null;
2614
+ return k("chat", "Image upload failed", Hr(m)), i("error", Dr(m)), null;
2621
2615
  } finally {
2622
2616
  o(!1);
2623
2617
  }
2624
- }, [e, a]);
2618
+ }, [e, i]);
2625
2619
  return {
2626
2620
  pending: e,
2627
2621
  uploading: n,
@@ -2635,38 +2629,38 @@ function Ha() {
2635
2629
  onDragOver: M
2636
2630
  };
2637
2631
  }
2638
- const Ut = Vt, $a = Jn;
2639
- function Ba({ commands: e = mt }) {
2640
- const [t, n] = R(""), [o, a] = R(!1), [i, s] = R({ q: null, i: 0 }), [l, p] = R(!1), h = z(null), f = Nn(), [L, O] = R(!1), [M, C] = R(!1), m = Ha(), S = u((b) => b.snapshot.mediaId), y = u((b) => b.pushToast), I = u((b) => b.setTierlistOpen), g = !!S, A = Da(t), N = Q(
2641
- () => A === null ? [] : Oa(A, e),
2632
+ const jt = qt, Fi = Xn;
2633
+ function Hi({ commands: e = mt }) {
2634
+ const [t, n] = R(""), [o, i] = R(!1), [a, s] = R({ q: null, i: 0 }), [l, p] = R(!1), h = z(null), f = Pn(), [L, O] = R(!1), [M, C] = R(!1), m = Ui(), v = u((b) => b.snapshot.mediaId), y = u((b) => b.pushToast), I = u((b) => b.setTierlistOpen), g = !!v, A = Ni(t), N = Q(
2635
+ () => A === null ? [] : Ri(A, e),
2642
2636
  [A, e]
2643
- ), U = A !== null && !l && N.length > 0, F = i.q === A ? We(i.i, N.length) : 0, x = E(
2637
+ ), U = A !== null && !l && N.length > 0, F = a.q === A ? We(a.i, N.length) : 0, x = E(
2644
2638
  (b) => s({ q: A, i: b }),
2645
2639
  [A]
2646
2640
  ), P = E((b, j) => {
2647
- const re = ja(b, { hasMedia: g });
2641
+ const re = Mi(b, { hasMedia: g });
2648
2642
  if (re) {
2649
2643
  y("info", re);
2650
2644
  return;
2651
2645
  }
2652
2646
  switch (b.name) {
2653
2647
  case "help":
2654
- y("info", e.map((En) => En.usage).join(" "));
2648
+ y("info", e.map((An) => An.usage).join(" "));
2655
2649
  break;
2656
2650
  case "recap":
2657
- wa();
2651
+ Si();
2658
2652
  break;
2659
2653
  case "tierlist":
2660
- Lo(), I(!0);
2654
+ Mo(), I(!0);
2661
2655
  break;
2662
2656
  default:
2663
2657
  y("info", `${b.usage} is not implemented yet.`);
2664
2658
  }
2665
2659
  }, [g, y, e, I]), T = E((b) => {
2666
- n(Ma(b)), p(!1), h.current?.focus();
2660
+ n(Di(b)), p(!1), h.current?.focus();
2667
2661
  }, []), pe = E(async (b) => {
2668
2662
  if (b.preventDefault(), o || m.uploading) return;
2669
- const j = La(t, e);
2663
+ const j = Oi(t, e);
2670
2664
  if (!j && !m.pending.length) return;
2671
2665
  if (j?.kind === "command" && m.pending.length) {
2672
2666
  y("info", "Send images on their own, not with a command.");
@@ -2677,7 +2671,7 @@ function Ba({ commands: e = mt }) {
2677
2671
  return;
2678
2672
  }
2679
2673
  const re = await m.uploadPending();
2680
- re !== null && (ya(j?.text ?? "", re), n(""), m.clear(), a(!0), setTimeout(() => a(!1), $a), !document.hidden && document.hasFocus() && h.current?.focus());
2674
+ re !== null && (gi(j?.text ?? "", re), n(""), m.clear(), i(!0), setTimeout(() => i(!1), Fi), !document.hidden && document.hasFocus() && h.current?.focus());
2681
2675
  }, [t, o, P, m, y, e]), he = E((b) => {
2682
2676
  if (b.key === "Escape" && U) {
2683
2677
  b.preventDefault(), p(!0);
@@ -2705,8 +2699,8 @@ function Ba({ commands: e = mt }) {
2705
2699
  };
2706
2700
  return window.addEventListener("watchparty:focus-chat-input", b), () => window.removeEventListener("watchparty:focus-chat-input", b);
2707
2701
  }, []);
2708
- const ge = Ut - t.length, ft = ge <= 100, pt = U ? N[F] : void 0;
2709
- return /* @__PURE__ */ v(
2702
+ const ge = jt - t.length, ft = ge <= 100, pt = U ? N[F] : void 0;
2703
+ return /* @__PURE__ */ _(
2710
2704
  "form",
2711
2705
  {
2712
2706
  onSubmit: (b) => {
@@ -2717,10 +2711,10 @@ function Ba({ commands: e = mt }) {
2717
2711
  onDragOver: m.onDragOver,
2718
2712
  className: "p-2 border-t border-border",
2719
2713
  children: [
2720
- /* @__PURE__ */ c(Fa, { pending: m.pending, uploading: m.uploading, onRemove: m.remove }),
2721
- /* @__PURE__ */ v("div", { className: "relative", children: [
2714
+ /* @__PURE__ */ c(ji, { pending: m.pending, uploading: m.uploading, onRemove: m.remove }),
2715
+ /* @__PURE__ */ _("div", { className: "relative", children: [
2722
2716
  U && /* @__PURE__ */ c(
2723
- Ua,
2717
+ Li,
2724
2718
  {
2725
2719
  commands: N,
2726
2720
  activeIndex: F,
@@ -2731,7 +2725,7 @@ function Ba({ commands: e = mt }) {
2731
2725
  }
2732
2726
  ),
2733
2727
  /* @__PURE__ */ c(
2734
- qr,
2728
+ Wr,
2735
2729
  {
2736
2730
  open: L,
2737
2731
  onClose: () => O(!1),
@@ -2741,8 +2735,8 @@ function Ba({ commands: e = mt }) {
2741
2735
  }
2742
2736
  }
2743
2737
  ),
2744
- /* @__PURE__ */ v("div", { className: "flex items-center gap-1.5", children: [
2745
- /* @__PURE__ */ v("div", { className: "relative flex-1", children: [
2738
+ /* @__PURE__ */ _("div", { className: "flex items-center gap-1.5", children: [
2739
+ /* @__PURE__ */ _("div", { className: "relative flex-1", children: [
2746
2740
  /* @__PURE__ */ c(
2747
2741
  "input",
2748
2742
  {
@@ -2753,7 +2747,7 @@ function Ba({ commands: e = mt }) {
2753
2747
  n(b.target.value), p(!1);
2754
2748
  },
2755
2749
  onKeyDown: he,
2756
- maxLength: Ut,
2750
+ maxLength: jt,
2757
2751
  placeholder: "Send a message",
2758
2752
  role: "combobox",
2759
2753
  "aria-expanded": U,
@@ -2775,7 +2769,7 @@ function Ba({ commands: e = mt }) {
2775
2769
  title: "Add a meme",
2776
2770
  "data-testid": "meme-button",
2777
2771
  className: `shrink-0 rounded border border-border-light px-2 py-1.5 text-sm hover:border-primary ${L ? "text-text border-primary" : "text-text-secondary"}`,
2778
- children: /* @__PURE__ */ c(Rn, { name: "image" })
2772
+ children: /* @__PURE__ */ c(Nn, { name: "image" })
2779
2773
  }
2780
2774
  )
2781
2775
  ] })
@@ -2784,13 +2778,13 @@ function Ba({ commands: e = mt }) {
2784
2778
  }
2785
2779
  );
2786
2780
  }
2787
- function Ga() {
2781
+ function $i() {
2788
2782
  const e = u((n) => n.roster), t = Object.values(e);
2789
2783
  return t.length ? /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: t.map((n) => {
2790
- const o = bn(n.sprite);
2791
- return /* @__PURE__ */ v("div", { className: "flex items-center gap-2 py-0.5", children: [
2784
+ const o = gn(n.sprite);
2785
+ return /* @__PURE__ */ _("div", { className: "flex items-center gap-2 py-0.5", children: [
2792
2786
  /* @__PURE__ */ c(
2793
- An,
2787
+ kn,
2794
2788
  {
2795
2789
  sprite: n.sprite,
2796
2790
  url: n.avatarUrl,
@@ -2804,16 +2798,16 @@ function Ga() {
2804
2798
  ] }, n.clientId);
2805
2799
  }) }) : /* @__PURE__ */ c("div", { className: "text-xs text-text-muted", children: "No users online" });
2806
2800
  }
2807
- function Ka() {
2808
- const e = u((a) => Object.keys(a.roster).length), [t, n] = R(!1), o = z(null);
2801
+ function Bi() {
2802
+ const e = u((i) => Object.keys(i.roster).length), [t, n] = R(!1), o = z(null);
2809
2803
  return D(() => {
2810
2804
  if (!t) return;
2811
- function a(i) {
2812
- o.current && !o.current.contains(i.target) && n(!1);
2805
+ function i(a) {
2806
+ o.current && !o.current.contains(a.target) && n(!1);
2813
2807
  }
2814
- return document.addEventListener("mousedown", a), () => document.removeEventListener("mousedown", a);
2815
- }, [t]), /* @__PURE__ */ v("div", { className: "relative", ref: o, children: [
2816
- /* @__PURE__ */ v(
2808
+ return document.addEventListener("mousedown", i), () => document.removeEventListener("mousedown", i);
2809
+ }, [t]), /* @__PURE__ */ _("div", { className: "relative", ref: o, children: [
2810
+ /* @__PURE__ */ _(
2817
2811
  "button",
2818
2812
  {
2819
2813
  onClick: () => {
@@ -2827,117 +2821,110 @@ function Ka() {
2827
2821
  ]
2828
2822
  }
2829
2823
  ),
2830
- t && /* @__PURE__ */ v("div", { className: "absolute top-full right-0 mt-1 bg-bg-card rounded-lg shadow-xl p-3 max-h-64 overflow-y-auto z-50 w-max min-w-[180px] max-w-[220px]", children: [
2831
- /* @__PURE__ */ v("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-2", children: [
2824
+ t && /* @__PURE__ */ _("div", { className: "absolute top-full right-0 mt-1 bg-bg-card rounded-lg shadow-xl p-3 max-h-64 overflow-y-auto z-50 w-max min-w-[180px] max-w-[220px]", children: [
2825
+ /* @__PURE__ */ _("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-2", children: [
2832
2826
  e,
2833
2827
  " online"
2834
2828
  ] }),
2835
- /* @__PURE__ */ c(Ga, {})
2829
+ /* @__PURE__ */ c($i, {})
2836
2830
  ] })
2837
2831
  ] });
2838
2832
  }
2839
- function Wa({ sources: e }) {
2840
- const t = u((n) => jt(Object.values(n.roster).map((o) => o.avatarSource)));
2841
- return (e ? jt(e) : t) ? /* @__PURE__ */ v("p", { className: "m-0 px-2 py-0.5 text-[10px] text-text-muted", children: [
2842
- /* @__PURE__ */ c("a", { href: "https://store.steampowered.com/", target: "_blank", rel: "noopener noreferrer", className: "underline", children: "Steam avatars via the Steam Web API" }),
2843
- " · not affiliated with Valve"
2844
- ] }) : null;
2845
- }
2846
- function Ft({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
2833
+ function Ut({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
2847
2834
  const t = u((o) => o.toasts), n = u((o) => o.popToast);
2848
2835
  return D(() => {
2849
- const o = t.map((a) => setTimeout(() => n(a.id), 4e3));
2836
+ const o = t.map((i) => setTimeout(() => n(i.id), 4e3));
2850
2837
  return () => {
2851
2838
  o.forEach(clearTimeout);
2852
2839
  };
2853
2840
  }, [t, n]), /* @__PURE__ */ c("div", { className: `${e} flex flex-col gap-2 z-50`, children: t.map((o) => /* @__PURE__ */ c("div", { className: `px-3 py-2 rounded text-sm shadow font-medium border ${o.kind === "error" ? "bg-danger-bg text-on-danger-bg border-danger" : "bg-bg-card border-border-light text-text"}`, children: o.msg }, o.id)) });
2854
2841
  }
2855
- const Ht = (e) => typeof e == "string" && Dn.includes(e);
2856
- function qa(e, t, n) {
2857
- return e || (Ht(t) ? t : Ht(n) ? n : "dark");
2842
+ const Ft = (e) => typeof e == "string" && Rn.includes(e);
2843
+ function Gi(e, t, n) {
2844
+ return e || (Ft(t) ? t : Ft(n) ? n : "dark");
2858
2845
  }
2859
- function Va(e, t) {
2846
+ function Ki(e, t) {
2860
2847
  if (t(e.clientWidth), typeof ResizeObserver > "u") return () => {
2861
2848
  };
2862
2849
  const n = new ResizeObserver(() => t(e.clientWidth));
2863
2850
  return n.observe(e), () => n.disconnect();
2864
2851
  }
2865
- function Ya(e) {
2852
+ function Wi(e) {
2866
2853
  const t = e?.trim() ?? "";
2867
2854
  return t ? { source: "host", name: t } : { source: "auto" };
2868
2855
  }
2869
- function za(e) {
2856
+ function qi(e) {
2870
2857
  if (e.source !== "host") return;
2871
2858
  const { setSessionIdentity: t, sprite: n } = u.getState();
2872
2859
  t(e.name, n);
2873
2860
  }
2874
- function Xa({ className: e = "w-4 h-4" }) {
2875
- return /* @__PURE__ */ v("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2861
+ function Vi({ className: e = "w-4 h-4" }) {
2862
+ return /* @__PURE__ */ _("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2876
2863
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 4v16" }),
2877
2864
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 12l-5 4v-8l5 4z" })
2878
2865
  ] });
2879
2866
  }
2880
- function Ja({ className: e = "w-4 h-4" }) {
2881
- return /* @__PURE__ */ v("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2867
+ function Yi({ className: e = "w-4 h-4" }) {
2868
+ return /* @__PURE__ */ _("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2882
2869
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 4v16" }),
2883
2870
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l5 4v-8l-5 4z" })
2884
2871
  ] });
2885
2872
  }
2886
- const Qa = 1500;
2887
- function mi({
2873
+ const zi = 1500;
2874
+ function ca({
2888
2875
  roomKey: e,
2889
2876
  serverOrigin: t,
2890
2877
  userType: n,
2891
2878
  userId: o,
2892
- theme: a,
2893
- name: i,
2879
+ theme: i,
2880
+ name: a,
2894
2881
  onLeave: s,
2895
2882
  onLayoutChange: l,
2896
2883
  collapsible: p = !0,
2897
2884
  debug: h,
2898
2885
  children: f
2899
2886
  }) {
2900
- const [L, O] = R(null), { setFrame: M, ...C } = Za(l, p), m = Gt(() => i), S = Q(() => (bo({ userType: n, userId: o ?? null }), lt().theme), [n, o]), y = On(), I = y?.theme, g = Q(
2901
- () => qa(a, I, S),
2902
- [a, I, S]
2887
+ const [L, O] = R(null), { setFrame: M, ...C } = Xi(l, p), m = Bt(() => a), v = Q(() => (go({ userType: n, userId: o ?? null }), lt().theme), [n, o]), y = Dn(), I = y?.theme, g = Q(
2888
+ () => Gi(i, I, v),
2889
+ [i, I, v]
2903
2890
  );
2904
2891
  D(() => {
2905
- }, [a, y !== null]);
2892
+ }, [i, y !== null]);
2906
2893
  const N = Q(
2907
2894
  () => ({ ...rt, serverOrigin: t, defaultRoomKey: e }),
2908
2895
  [t, e]
2909
2896
  );
2910
2897
  return D(() => {
2911
- h && Zr();
2912
- }, [h]), xa(), D(() => {
2913
- Vr({ serverOrigin: t, defaultRoomKey: e }), u.getState().rehydrateFromPrefs(), Xo();
2898
+ h && Qr();
2899
+ }, [h]), _i(), D(() => {
2900
+ qr({ serverOrigin: t, defaultRoomKey: e }), u.getState().rehydrateFromPrefs(), Yo();
2914
2901
  let U = !1;
2915
- const F = So();
2902
+ const F = vo();
2916
2903
  return (async () => {
2917
2904
  try {
2918
2905
  await Promise.race([
2919
2906
  Promise.all([
2920
2907
  F,
2921
- To().then((T) => {
2908
+ Co().then((T) => {
2922
2909
  T && u.getState().rehydrateFromPrefs();
2923
2910
  }),
2924
2911
  // The character chosen in the settings popout (lib/avatar.ts).
2925
- Ho().then(kn)
2912
+ Uo().then(Tn)
2926
2913
  ]),
2927
- new Promise((T) => setTimeout(T, Qa))
2914
+ new Promise((T) => setTimeout(T, zi))
2928
2915
  ]);
2929
2916
  } catch (T) {
2930
2917
  k("room-chrome", "pre-join wait threw, proceeding anyway", fe(T));
2931
2918
  }
2932
2919
  if (U) return;
2933
- const x = Ya(m());
2934
- u.getState().ensureAutoIdentity(), za(x);
2920
+ const x = Wi(m());
2921
+ u.getState().ensureAutoIdentity(), qi(x);
2935
2922
  const P = u.getState();
2936
- d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }), ia({ room_key: e, name: P.name || void 0, sprite: P.sprite || void 0 });
2923
+ d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }), oi({ room_key: e, name: P.name || void 0, sprite: P.sprite || void 0 });
2937
2924
  })(), () => {
2938
2925
  U = !0, Lt();
2939
2926
  };
2940
- }, [e, t, n, o]), /* @__PURE__ */ c(Yr.Provider, { value: N, children: /* @__PURE__ */ c(un.Provider, { value: L, children: /* @__PURE__ */ v("div", { ref: M, className: "wp-room-chrome-frame", children: [
2927
+ }, [e, t, n, o]), /* @__PURE__ */ c(Vr.Provider, { value: N, children: /* @__PURE__ */ c(dn.Provider, { value: L, children: /* @__PURE__ */ _("div", { ref: M, className: "wp-room-chrome-frame", children: [
2941
2928
  /* @__PURE__ */ c("div", { className: "wp-room-chrome-frame__content", children: f }),
2942
2929
  /* @__PURE__ */ c(
2943
2930
  "aside",
@@ -2947,7 +2934,7 @@ function mi({
2947
2934
  "data-theme": g,
2948
2935
  "data-collapsed": C.collapsed ? "1" : "0",
2949
2936
  style: { "--wp-room-chrome-width": `${C.state.width}px` },
2950
- children: C.collapsed ? /* @__PURE__ */ v(le, { children: [
2937
+ children: C.collapsed ? /* @__PURE__ */ _(le, { children: [
2951
2938
  /* @__PURE__ */ c(
2952
2939
  "button",
2953
2940
  {
@@ -2956,11 +2943,11 @@ function mi({
2956
2943
  title: "Show chat",
2957
2944
  "aria-label": "Show chat",
2958
2945
  "aria-expanded": !1,
2959
- children: /* @__PURE__ */ c(Ja, {})
2946
+ children: /* @__PURE__ */ c(Yi, {})
2960
2947
  }
2961
2948
  ),
2962
- /* @__PURE__ */ c(Ft, { className: "absolute bottom-2 right-full mr-2 w-72" })
2963
- ] }) : /* @__PURE__ */ v(le, { children: [
2949
+ /* @__PURE__ */ c(Ut, { className: "absolute bottom-2 right-full mr-2 w-72" })
2950
+ ] }) : /* @__PURE__ */ _(le, { children: [
2964
2951
  /* @__PURE__ */ c(
2965
2952
  "div",
2966
2953
  {
@@ -2980,8 +2967,8 @@ function mi({
2980
2967
  onKeyDown: C.onKeyDown
2981
2968
  }
2982
2969
  ),
2983
- /* @__PURE__ */ v("div", { className: "flex items-center gap-1 px-2 py-1.5 border-b border-border", children: [
2984
- /* @__PURE__ */ c(Ka, {}),
2970
+ /* @__PURE__ */ _("div", { className: "flex items-center gap-1 px-2 py-1.5 border-b border-border", children: [
2971
+ /* @__PURE__ */ c(Bi, {}),
2985
2972
  /* @__PURE__ */ c("div", { className: "flex-1" }),
2986
2973
  s && /* @__PURE__ */ c(
2987
2974
  "button",
@@ -3003,26 +2990,25 @@ function mi({
3003
2990
  title: "Hide chat",
3004
2991
  "aria-label": "Hide chat",
3005
2992
  "aria-expanded": !0,
3006
- children: /* @__PURE__ */ c(Xa, {})
2993
+ children: /* @__PURE__ */ c(Vi, {})
3007
2994
  }
3008
2995
  )
3009
2996
  ] }),
3010
- /* @__PURE__ */ c(Ra, {}),
3011
- /* @__PURE__ */ c(Wa, {}),
3012
- /* @__PURE__ */ c(Ba, { commands: [] }),
3013
- /* @__PURE__ */ c(Ft, { className: "absolute bottom-14 left-2 right-2" })
2997
+ /* @__PURE__ */ c(Pi, {}),
2998
+ /* @__PURE__ */ c(Hi, { commands: [] }),
2999
+ /* @__PURE__ */ c(Ut, { className: "absolute bottom-14 left-2 right-2" })
3014
3000
  ] })
3015
3001
  }
3016
3002
  )
3017
3003
  ] }) }) });
3018
3004
  }
3019
- function Za(e, t) {
3020
- const n = u((g) => g.chromeChatCollapsed) && t, o = u((g) => g.chromeChatWidth), a = u((g) => g.toggleChromeChatCollapsed), i = u((g) => g.setChromeChatWidth), [s, l] = R(null), [p, h] = R(void 0), [f, L] = R(null);
3005
+ function Xi(e, t) {
3006
+ const n = u((g) => g.chromeChatCollapsed) && t, o = u((g) => g.chromeChatWidth), i = u((g) => g.toggleChromeChatCollapsed), a = u((g) => g.setChromeChatWidth), [s, l] = R(null), [p, h] = R(void 0), [f, L] = R(null);
3021
3007
  D(() => {
3022
3008
  if (s)
3023
- return Va(s, h);
3009
+ return Ki(s, h);
3024
3010
  }, [s]);
3025
- const O = W(f?.current ?? o, p), M = Q(() => No(n, O), [n, O]), C = Gt((g) => e?.(g));
3011
+ const O = W(f?.current ?? o, p), M = Q(() => Po(n, O), [n, O]), C = Bt((g) => e?.(g));
3026
3012
  return D(() => {
3027
3013
  C(M);
3028
3014
  }, [M]), {
@@ -3030,7 +3016,7 @@ function Za(e, t) {
3030
3016
  collapsed: n,
3031
3017
  state: M,
3032
3018
  dragging: f !== null,
3033
- toggleCollapsed: a,
3019
+ toggleCollapsed: i,
3034
3020
  onPointerDown: (g) => {
3035
3021
  g.button === 0 && (g.preventDefault(), g.currentTarget.setPointerCapture(g.pointerId), L({ pointerId: g.pointerId, startX: g.clientX, startWidth: O, current: O }));
3036
3022
  },
@@ -3040,15 +3026,15 @@ function Za(e, t) {
3040
3026
  onPointerEnd: (g) => {
3041
3027
  if (!f || f.pointerId !== g.pointerId) return;
3042
3028
  const A = Et(f.startWidth, f.startX, g.clientX, p);
3043
- L(null), A !== o && i(A);
3029
+ L(null), A !== o && a(A);
3044
3030
  },
3045
3031
  onKeyDown: (g) => {
3046
- const A = Po(O, g.key, p);
3047
- A !== null && (g.preventDefault(), A !== o && i(A));
3032
+ const A = Eo(O, g.key, p);
3033
+ A !== null && (g.preventDefault(), A !== o && a(A));
3048
3034
  }
3049
3035
  };
3050
3036
  }
3051
3037
  export {
3052
- mi as RoomChrome
3038
+ ca as RoomChrome
3053
3039
  };
3054
3040
  //# sourceMappingURL=room-chrome.js.map