@ai-matrx/meet 0.7.10 → 0.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -241,7 +241,14 @@ var MEET_ROUTES = {
241
241
  */
242
242
  moderate: "/api/v1/meet/moderate",
243
243
  /** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
244
- chat: "/api/v1/meet/chat"
244
+ chat: "/api/v1/meet/chat",
245
+ /**
246
+ * Meet wave 5: polls, Q&A, the shared whiteboard and breakout rooms. `POST` acts
247
+ * (`{meeting_id, action, …}`), `GET ?meeting_id=` reads what this viewer may see.
248
+ */
249
+ collab: "/api/v1/meet/collab",
250
+ /** Meet wave 5: translate finished caption lines into this viewer's language. */
251
+ captionsTranslate: "/api/v1/meet/captions/translate"
245
252
  };
246
253
  function meetingPath(template, meetingId) {
247
254
  return template.replace("{meeting_id}", encodeURIComponent(meetingId));
@@ -300,7 +307,8 @@ function parseRoomToken(body, roomName) {
300
307
  // server that has not landed MRI-A11 — and never invents a host from
301
308
  // silence, because both fallbacks below grant nothing.
302
309
  role: readRole(payload, "role") ?? (isHost ? "host" : identity.startsWith("guest:") ? "guest" : "participant"),
303
- lobby: readBoolean(payload, "lobby", false)
310
+ lobby: readBoolean(payload, "lobby", false),
311
+ breakoutRoomId: readString(payload, "breakout_room_id") ?? null
304
312
  };
305
313
  }
306
314
  function createTokenClient(options) {
@@ -348,6 +356,7 @@ function createTokenClient(options) {
348
356
  room_name: input.roomName,
349
357
  ...input.meetingId !== void 0 ? { meeting_id: input.meetingId } : {},
350
358
  ...input.slug !== void 0 ? { slug: input.slug } : {},
359
+ ...input.breakoutRoomId != null ? { breakout_room_id: input.breakoutRoomId } : {},
351
360
  organization_id: input.identity.organizationId,
352
361
  display_name: input.identity.displayName,
353
362
  device_id: input.identity.deviceId,
@@ -411,7 +420,8 @@ function createTokenClient(options) {
411
420
  return {
412
421
  get(input) {
413
422
  const entry = cache.get(input.roomName);
414
- if (entry !== void 0) {
423
+ const sameRoom = entry !== void 0 && (entry.token.breakoutRoomId ?? null) === (input.breakoutRoomId ?? null);
424
+ if (entry !== void 0 && sameRoom) {
415
425
  if (entry.inFlight !== null) return entry.inFlight;
416
426
  if (!expired(entry)) return Promise.resolve(entry.token);
417
427
  }
@@ -457,7 +467,8 @@ function placeholder(roomName) {
457
467
  canRecord: false,
458
468
  isHost: false,
459
469
  role: "participant",
460
- lobby: false
470
+ lobby: false,
471
+ breakoutRoomId: null
461
472
  };
462
473
  }
463
474
  async function serverSentence(response) {
@@ -1515,6 +1526,339 @@ function listenOnlyNotice(media) {
1515
1526
  return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
1516
1527
  }
1517
1528
 
1529
+ // src/core/collab.ts
1530
+ var EMPTY_COLLAB = {
1531
+ loaded: false,
1532
+ error: null,
1533
+ settings: null,
1534
+ polls: [],
1535
+ questions: [],
1536
+ strokes: [],
1537
+ breakout: null,
1538
+ broadcast: null,
1539
+ moveRequest: null,
1540
+ panelRequest: null,
1541
+ captionLanguage: null,
1542
+ captionTranslations: {},
1543
+ captionTranslationError: null
1544
+ };
1545
+ function obj(value) {
1546
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1547
+ }
1548
+ function str(value) {
1549
+ return typeof value === "string" ? value : null;
1550
+ }
1551
+ function num(value) {
1552
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
1553
+ }
1554
+ function strings(value) {
1555
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
1556
+ }
1557
+ function pollFromRow(row) {
1558
+ const id = str(row["id"]);
1559
+ if (id === null) return null;
1560
+ const options = [];
1561
+ for (const raw of Array.isArray(row["options"]) ? row["options"] : []) {
1562
+ const option = obj(raw);
1563
+ const optionId = option === null ? null : str(option["id"]);
1564
+ if (option === null || optionId === null) continue;
1565
+ const votes = num(option["votes"]);
1566
+ options.push({
1567
+ id: optionId,
1568
+ text: str(option["text"]) ?? "",
1569
+ ...votes !== null ? { votes } : {},
1570
+ ...Array.isArray(option["voters"]) ? { voters: strings(option["voters"]) } : {}
1571
+ });
1572
+ }
1573
+ const state = str(row["state"]);
1574
+ return {
1575
+ id,
1576
+ question: str(row["question"]) ?? "",
1577
+ options,
1578
+ multiple: row["multiple"] === true,
1579
+ anonymous: row["anonymous"] === true,
1580
+ state: state === "live" || state === "closed" ? state : "draft",
1581
+ resultsShared: row["results_shared"] === true,
1582
+ voterCount: num(row["voter_count"]),
1583
+ myVote: strings(row["my_vote"]),
1584
+ createdByName: str(row["created_by_name"]) ?? "",
1585
+ createdAt: str(row["created_at"])
1586
+ };
1587
+ }
1588
+ function questionFromRow(row) {
1589
+ const id = str(row["id"]);
1590
+ if (id === null) return null;
1591
+ const state = str(row["state"]);
1592
+ return {
1593
+ id,
1594
+ text: str(row["text"]) ?? "",
1595
+ askerName: str(row["asker_name"]) ?? "",
1596
+ anonymous: row["anonymous"] === true,
1597
+ state: state === "answered" || state === "dismissed" ? state : "open",
1598
+ answer: str(row["answer"]),
1599
+ answeredByName: str(row["answered_by_name"]),
1600
+ upvotes: num(row["upvotes"]) ?? 0,
1601
+ upvotedByMe: row["upvoted_by_me"] === true,
1602
+ mine: row["mine"] === true,
1603
+ createdAt: str(row["created_at"])
1604
+ };
1605
+ }
1606
+ function strokeFromRow(row) {
1607
+ const id = str(row["id"]);
1608
+ if (id === null || !Array.isArray(row["points"])) return null;
1609
+ const points = [];
1610
+ for (const raw of row["points"]) {
1611
+ if (Array.isArray(raw) && typeof raw[0] === "number" && typeof raw[1] === "number") {
1612
+ points.push([raw[0], raw[1]]);
1613
+ }
1614
+ }
1615
+ return {
1616
+ id,
1617
+ points,
1618
+ color: str(row["color"]) ?? "#111827",
1619
+ width: num(row["width"]) ?? 3,
1620
+ tool: row["tool"] === "highlighter" ? "highlighter" : "pen",
1621
+ by: str(row["by"]) ?? "",
1622
+ byName: str(row["by_name"]) ?? ""
1623
+ };
1624
+ }
1625
+ function broadcastFrom(value) {
1626
+ const row = obj(value);
1627
+ const text3 = row === null ? null : str(row["text"]);
1628
+ if (row === null || text3 === null) return null;
1629
+ return { text: text3, by: str(row["by"]) ?? "", at: str(row["at"]) ?? "" };
1630
+ }
1631
+ function planFromRow(row) {
1632
+ const id = str(row["id"]);
1633
+ if (id === null) return null;
1634
+ const rooms = [];
1635
+ for (const raw of Array.isArray(row["rooms"]) ? row["rooms"] : []) {
1636
+ const room = obj(raw);
1637
+ const roomId = room === null ? null : str(room["id"]);
1638
+ if (room === null || roomId === null) continue;
1639
+ rooms.push({ id: roomId, name: str(room["name"]) ?? roomId, identities: strings(room["identities"]) });
1640
+ }
1641
+ return {
1642
+ id,
1643
+ state: row["state"] === "open" ? "open" : "closed",
1644
+ rooms,
1645
+ allowChoose: row["allow_choose"] === true,
1646
+ minutes: num(row["minutes"]) ?? 0,
1647
+ openedAt: str(row["opened_at"]),
1648
+ endsAt: str(row["ends_at"]),
1649
+ closedAt: str(row["closed_at"]),
1650
+ broadcasts: (Array.isArray(row["broadcasts"]) ? row["broadcasts"] : []).map(broadcastFrom).filter((b) => b !== null)
1651
+ };
1652
+ }
1653
+ function settingsFromRow(row) {
1654
+ if (row === null) return null;
1655
+ return {
1656
+ pollsEnabled: row["polls_enabled"] === true,
1657
+ pollMaxOptions: num(row["poll_max_options"]) ?? 10,
1658
+ qaEnabled: row["qa_enabled"] === true,
1659
+ qaAnonymousAllowed: row["qa_anonymous_allowed"] === true,
1660
+ whiteboardEnabled: row["whiteboard_enabled"] === true,
1661
+ breakoutsEnabled: row["breakouts_enabled"] === true,
1662
+ breakoutMaxRooms: num(row["breakout_max_rooms"]) ?? 20,
1663
+ breakoutDefaultMinutes: num(row["breakout_default_minutes"]) ?? 15,
1664
+ captionTranslationEnabled: row["caption_translation_enabled"] === true,
1665
+ captionTranslationLanguage: str(row["caption_translation_language"]) ?? ""
1666
+ };
1667
+ }
1668
+ function collabFromState(body, previous) {
1669
+ const list = (key, parse) => (Array.isArray(body[key]) ? body[key] : []).map((raw) => {
1670
+ const row = obj(raw);
1671
+ return row === null ? null : parse(row);
1672
+ }).filter((item) => item !== null);
1673
+ const breakoutRow = obj(body["breakout"]);
1674
+ return {
1675
+ ...previous,
1676
+ loaded: true,
1677
+ error: null,
1678
+ settings: settingsFromRow(obj(body["settings"])),
1679
+ polls: list("polls", pollFromRow),
1680
+ questions: list("questions", questionFromRow),
1681
+ strokes: list("strokes", strokeFromRow),
1682
+ breakout: breakoutRow === null ? null : planFromRow(breakoutRow)
1683
+ };
1684
+ }
1685
+ function upsert(items, next) {
1686
+ const index = items.findIndex((item) => item.id === next.id);
1687
+ if (index === -1) return [...items, next];
1688
+ const copy = items.slice();
1689
+ copy[index] = next;
1690
+ return copy;
1691
+ }
1692
+ function withItem(collab, row, fromRoom = false) {
1693
+ const kind = str(row["kind"]);
1694
+ if (kind === "poll") {
1695
+ const poll = pollFromRow(row);
1696
+ if (poll === null) return collab;
1697
+ const known = collab.polls.find((p) => p.id === poll.id);
1698
+ const merged = fromRoom && known !== void 0 ? { ...poll, myVote: known.myVote } : poll;
1699
+ return { ...collab, polls: upsert(collab.polls, merged) };
1700
+ }
1701
+ if (kind === "question") {
1702
+ const question = questionFromRow(row);
1703
+ if (question === null) return collab;
1704
+ const known = collab.questions.find((q) => q.id === question.id);
1705
+ const merged = fromRoom && known !== void 0 ? { ...question, mine: known.mine, upvotedByMe: known.upvotedByMe } : question;
1706
+ return { ...collab, questions: upsert(collab.questions, merged) };
1707
+ }
1708
+ if (kind === "stroke") {
1709
+ const stroke = strokeFromRow(row);
1710
+ if (stroke === null) return collab;
1711
+ return { ...collab, strokes: upsert(collab.strokes, stroke) };
1712
+ }
1713
+ if (kind === "breakout") {
1714
+ const plan = planFromRow(row);
1715
+ if (plan === null) return collab;
1716
+ return { ...collab, breakout: plan };
1717
+ }
1718
+ return collab;
1719
+ }
1720
+ function without(collab, ids) {
1721
+ const gone = new Set(ids);
1722
+ return {
1723
+ ...collab,
1724
+ polls: collab.polls.filter((p) => !gone.has(p.id)),
1725
+ questions: collab.questions.filter((q) => !gone.has(q.id)),
1726
+ strokes: collab.strokes.filter((s) => !gone.has(s.id))
1727
+ };
1728
+ }
1729
+ function applyCollabPacket(collab, payload, context) {
1730
+ const item = obj(payload["item"]);
1731
+ const audience = str(payload["audience"]);
1732
+ if (item !== null) {
1733
+ const kind = str(item["kind"]);
1734
+ const hostOnlyView = kind === "poll" || kind === "question";
1735
+ if (hostOnlyView && context.isHost && audience !== "hosts") {
1736
+ return { next: null, dropped: "the room copy of an item a host receives in full" };
1737
+ }
1738
+ let next = withItem(collab, item, true);
1739
+ if (kind === "poll" && str(item["state"]) === "live") {
1740
+ const before = collab.polls.find((p) => p.id === str(item["id"]));
1741
+ if (before === void 0 || before.state !== "live") {
1742
+ next = { ...next, panelRequest: { panel: "polls", at: context.now } };
1743
+ }
1744
+ }
1745
+ if (kind === "breakout") {
1746
+ const plan = planFromRow(item);
1747
+ if (plan !== null && plan.state === "closed") {
1748
+ next = { ...next, moveRequest: { roomId: null, at: context.now } };
1749
+ }
1750
+ }
1751
+ const move = obj(payload["move"]);
1752
+ if (move !== null && str(move["identity"]) === context.localIdentity) {
1753
+ next = { ...next, moveRequest: { roomId: str(move["room_id"]), at: context.now } };
1754
+ }
1755
+ return { next };
1756
+ }
1757
+ if (Array.isArray(payload["removed"])) {
1758
+ return { next: without(collab, strings(payload["removed"])) };
1759
+ }
1760
+ if (Array.isArray(payload["hidden"])) {
1761
+ return context.isHost ? { next: null, dropped: "hosts keep dismissed questions" } : { next: without(collab, strings(payload["hidden"])) };
1762
+ }
1763
+ if (payload["cleared"] === "whiteboard") {
1764
+ return { next: { ...collab, strokes: [] } };
1765
+ }
1766
+ const broadcast = broadcastFrom(payload["broadcast"]);
1767
+ if (broadcast !== null) {
1768
+ return { next: { ...collab, broadcast } };
1769
+ }
1770
+ return { next: null, dropped: "a collab packet with nothing this version understands" };
1771
+ }
1772
+ function assignedRoom(plan, identity) {
1773
+ if (plan === null || plan.state !== "open" || identity === null) return null;
1774
+ return plan.rooms.find((room) => room.identities.includes(identity)) ?? null;
1775
+ }
1776
+ function autoAssign(identities, rooms, exclude = []) {
1777
+ const count2 = Math.max(1, Math.floor(rooms));
1778
+ const out = Array.from({ length: count2 }, () => []);
1779
+ const skip = new Set(exclude);
1780
+ let index = 0;
1781
+ for (const identity of identities) {
1782
+ if (skip.has(identity)) continue;
1783
+ out[index % count2].push(identity);
1784
+ index += 1;
1785
+ }
1786
+ return out;
1787
+ }
1788
+ function breakoutRemainingMs(plan, now) {
1789
+ if (plan === null || plan.state !== "open" || plan.endsAt === null) return null;
1790
+ const end = Date.parse(plan.endsAt);
1791
+ return Number.isNaN(end) ? null : Math.max(0, end - now);
1792
+ }
1793
+ function defaultCaptionLanguage(settings, viewerLanguage) {
1794
+ const configured = settings?.captionTranslationLanguage.trim() ?? "";
1795
+ if (configured.length > 0) return configured;
1796
+ const own = (viewerLanguage ?? "").trim();
1797
+ return own.length > 0 ? own : "en";
1798
+ }
1799
+ var CAPTION_LANGUAGES = [
1800
+ { tag: "en", name: "English" },
1801
+ { tag: "es", name: "Spanish" },
1802
+ { tag: "fr", name: "French" },
1803
+ { tag: "de", name: "German" },
1804
+ { tag: "it", name: "Italian" },
1805
+ { tag: "pt", name: "Portuguese" },
1806
+ { tag: "nl", name: "Dutch" },
1807
+ { tag: "pl", name: "Polish" },
1808
+ { tag: "ru", name: "Russian" },
1809
+ { tag: "uk", name: "Ukrainian" },
1810
+ { tag: "tr", name: "Turkish" },
1811
+ { tag: "ar", name: "Arabic" },
1812
+ { tag: "he", name: "Hebrew" },
1813
+ { tag: "fa", name: "Persian" },
1814
+ { tag: "hi", name: "Hindi" },
1815
+ { tag: "bn", name: "Bengali" },
1816
+ { tag: "zh", name: "Chinese" },
1817
+ { tag: "ja", name: "Japanese" },
1818
+ { tag: "ko", name: "Korean" },
1819
+ { tag: "vi", name: "Vietnamese" },
1820
+ { tag: "th", name: "Thai" },
1821
+ { tag: "id", name: "Indonesian" },
1822
+ { tag: "sv", name: "Swedish" }
1823
+ ];
1824
+ async function loadMeetingActivities(api, meetingId, roomToken = null) {
1825
+ let response;
1826
+ try {
1827
+ response = await api.request({
1828
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(meetingId)}`,
1829
+ method: "GET",
1830
+ operation: "meet.loadMeetingActivities",
1831
+ requireAuth: roomToken === null,
1832
+ ...roomToken !== null ? { headers: { [ROOM_TOKEN_HEADER]: roomToken } } : {}
1833
+ });
1834
+ } catch (error) {
1835
+ return {
1836
+ collab: null,
1837
+ refusal: {
1838
+ message: `Polls, questions and the whiteboard could not be read (${error.message}).`,
1839
+ remedy: error.remedy ?? "Reload the page."
1840
+ }
1841
+ };
1842
+ }
1843
+ if (!response.ok) {
1844
+ let body = null;
1845
+ try {
1846
+ body = await response.json();
1847
+ } catch {
1848
+ body = null;
1849
+ }
1850
+ const said = readServerRefusal(body);
1851
+ return {
1852
+ collab: null,
1853
+ refusal: {
1854
+ message: said?.reason ?? `Polls and questions could not be read (the server answered ${response.status}).`,
1855
+ remedy: said?.remedy || "Reload the page."
1856
+ }
1857
+ };
1858
+ }
1859
+ return { collab: collabFromState(await response.json(), EMPTY_COLLAB), refusal: null };
1860
+ }
1861
+
1518
1862
  // src/core/transcript.ts
1519
1863
  function normalizeSpoken(text3) {
1520
1864
  return text3.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
@@ -1616,7 +1960,9 @@ var EMPTY = {
1616
1960
  wrapUp: null,
1617
1961
  noteTakerRefusal: null,
1618
1962
  media: IDLE_MEDIA,
1619
- failure: null
1963
+ failure: null,
1964
+ collab: EMPTY_COLLAB,
1965
+ breakoutRoomId: null
1620
1966
  };
1621
1967
  function effectiveRole(snapshot) {
1622
1968
  const me = snapshot.participants.find(
@@ -2267,7 +2613,19 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
2267
2613
  var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
2268
2614
  var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
2269
2615
  var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
2270
- var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at";
2616
+ var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at,sessions:metadata->sessions";
2617
+ function projectStays(value) {
2618
+ if (!Array.isArray(value)) return [];
2619
+ const stays = [];
2620
+ for (const item of value) {
2621
+ if (item === null || typeof item !== "object") continue;
2622
+ const joined = item["joined_at"];
2623
+ const left = item["left_at"];
2624
+ if (typeof joined !== "string" || joined.length === 0) continue;
2625
+ stays.push({ joinedAt: joined, leftAt: typeof left === "string" && left.length > 0 ? left : null });
2626
+ }
2627
+ return stays;
2628
+ }
2271
2629
  function text(row, key) {
2272
2630
  const value = row[key];
2273
2631
  return typeof value === "string" && value.length > 0 ? value : null;
@@ -2366,7 +2724,7 @@ var OCCURRENCE_STATES = ["scheduled", "moved", "cancelled"];
2366
2724
  function rsvpState(value) {
2367
2725
  return RSVP_STATES.includes(value) ? value : "needs_action";
2368
2726
  }
2369
- function num(row, key) {
2727
+ function num2(row, key) {
2370
2728
  const value = row[key];
2371
2729
  return typeof value === "number" ? value : null;
2372
2730
  }
@@ -2388,7 +2746,7 @@ function projectInvitee(row) {
2388
2746
  rsvpState: rsvpState(text(row, "rsvp_state")),
2389
2747
  respondedAt: when(row, "responded_at"),
2390
2748
  rsvpNote: text(row, "rsvp_note"),
2391
- lastSentSequence: num(row, "last_sent_sequence"),
2749
+ lastSentSequence: num2(row, "last_sent_sequence"),
2392
2750
  lastSentAt: when(row, "last_sent_at")
2393
2751
  };
2394
2752
  }
@@ -2399,10 +2757,10 @@ function projectOccurrence(row) {
2399
2757
  meetingId: asMeetingId(requireText(row, "meeting_id", operation)),
2400
2758
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2401
2759
  occurrenceStart: when(row, "occurrence_start") ?? requireText(row, "occurrence_start", operation),
2402
- durationMinutes: num(row, "duration_minutes"),
2760
+ durationMinutes: num2(row, "duration_minutes"),
2403
2761
  // An unknown state is shown as scheduled, never dropped: the row is real.
2404
2762
  state: OCCURRENCE_STATES.includes(state) ? state : "scheduled",
2405
- sequence: num(row, "sequence") ?? 0
2763
+ sequence: num2(row, "sequence") ?? 0
2406
2764
  };
2407
2765
  }
2408
2766
  function projectUpcoming(row) {
@@ -2431,9 +2789,9 @@ function projectOverride(row) {
2431
2789
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2432
2790
  state: text(row, "state") === "moved" ? "moved" : "cancelled",
2433
2791
  newStart: when(row, "new_start"),
2434
- newDurationMinutes: num(row, "new_duration_minutes"),
2792
+ newDurationMinutes: num2(row, "new_duration_minutes"),
2435
2793
  reason: text(row, "reason"),
2436
- calendarSequence: num(row, "calendar_sequence") ?? 0,
2794
+ calendarSequence: num2(row, "calendar_sequence") ?? 0,
2437
2795
  deletedAt: when(row, "deleted_at")
2438
2796
  };
2439
2797
  }
@@ -2457,7 +2815,7 @@ function projectRsvpInvitation(body) {
2457
2815
  title: text(meeting, "title") ?? "Meeting",
2458
2816
  slug: requireText(meeting, "slug", operation),
2459
2817
  scheduledFor: when(meeting, "scheduled_for"),
2460
- durationMinutes: num(meeting, "duration_minutes"),
2818
+ durationMinutes: num2(meeting, "duration_minutes"),
2461
2819
  timeZone: text(meeting, "time_zone") ?? "UTC",
2462
2820
  agenda: text(meeting, "agenda"),
2463
2821
  recurrenceRule: text(meeting, "recurrence_rule"),
@@ -2491,6 +2849,7 @@ function changesPatch(changes) {
2491
2849
  patch["scheduled_duration_minutes"] = changes.scheduledDurationMinutes;
2492
2850
  }
2493
2851
  if (changes.recurrenceRule !== void 0) patch["recurrence_rule"] = changes.recurrenceRule;
2852
+ if (changes.keepExceptions !== void 0) patch["keep_exceptions"] = changes.keepExceptions;
2494
2853
  return patch;
2495
2854
  }
2496
2855
  function createMeetRepository(options) {
@@ -2637,7 +2996,8 @@ function createMeetRepository(options) {
2637
2996
  admissionState: states.includes(admission) ? admission : "admitted",
2638
2997
  isAgent: bool(row, "is_agent", false),
2639
2998
  joinedAt: text(row, "joined_at"),
2640
- leftAt: text(row, "left_at")
2999
+ leftAt: text(row, "left_at"),
3000
+ sessions: projectStays(row["sessions"])
2641
3001
  };
2642
3002
  }
2643
3003
  function requireOrg(organizationId, operation) {
@@ -3031,8 +3391,8 @@ function projectLibraryRecording(row) {
3031
3391
  fileId: text(row, "file_id"),
3032
3392
  startedAt: text(row, "started_at"),
3033
3393
  endedAt: text(row, "ended_at"),
3034
- durationMs: num(row, "duration_ms"),
3035
- sizeBytes: num(row, "size_bytes"),
3394
+ durationMs: num2(row, "duration_ms"),
3395
+ sizeBytes: num2(row, "size_bytes"),
3036
3396
  failureReason: text(row, "failure_reason"),
3037
3397
  archivedAt: text(row, "deleted_at"),
3038
3398
  organizationId: asOrganizationId(requireText(row, "organization_id", operation))
@@ -3059,7 +3419,7 @@ function projectSearchHit(row) {
3059
3419
  speaker: text(row, "speaker"),
3060
3420
  snippet: text(row, "snippet") ?? "",
3061
3421
  at: text(row, "said_at"),
3062
- rank: num(row, "rank") ?? 0
3422
+ rank: num2(row, "rank") ?? 0
3063
3423
  };
3064
3424
  }
3065
3425
  function snippetRuns(snippet) {
@@ -3204,7 +3564,14 @@ var ROOM_EVENTS = {
3204
3564
  * person concerned; `lower-hands {identities: [...] | "*"}` · `role {identity,
3205
3565
  * role}` — to everyone.
3206
3566
  */
3207
- moderation: "matrx.meet.moderation"
3567
+ moderation: "matrx.meet.moderation",
3568
+ /**
3569
+ * A meeting ROOM ITEM changed (Meet wave 5): a poll, a Q&A question, a whiteboard
3570
+ * stroke or the breakout plan. Payload `{ meeting_id, item }` · `{ removed: [ids] }` ·
3571
+ * `{ hidden: [ids] }` · `{ cleared: "whiteboard" }` · `{ broadcast }` · `{ item, move }`.
3572
+ * A host's fuller copy of a poll or question carries `audience: "hosts"`.
3573
+ */
3574
+ collab: "matrx.meet.collab"
3208
3575
  };
3209
3576
  function isRoomEventTopic(topic) {
3210
3577
  return topic.startsWith(ROOM_EVENT_PREFIX);
@@ -3244,10 +3611,27 @@ function applyRoomEvent(args) {
3244
3611
  return applyChat(store, payload);
3245
3612
  case ROOM_EVENTS.moderation:
3246
3613
  return applyModeration(store, payload, now);
3614
+ case ROOM_EVENTS.collab:
3615
+ return applyCollab(store, payload, now);
3247
3616
  default:
3248
3617
  return ignored(`${topic} is not known to this version of @ai-matrx/meet`);
3249
3618
  }
3250
3619
  }
3620
+ function applyCollab(store, payload, now) {
3621
+ const snapshot = store.snapshot();
3622
+ const meeting = snapshot.meeting;
3623
+ if (meeting !== null && text2(payload["meeting_id"]) !== null && payload["meeting_id"] !== meeting.id) {
3624
+ return ignored("a collab event for a different meeting than this room is showing");
3625
+ }
3626
+ const result = applyCollabPacket(snapshot.collab, payload, {
3627
+ localIdentity: snapshot.localIdentity,
3628
+ isHost: ROLE_RANK[effectiveRole(snapshot)] >= ROLE_RANK.cohost,
3629
+ now: now()
3630
+ });
3631
+ if (result.next === null) return ignored(result.dropped ?? "a collab packet that changed nothing");
3632
+ store.patch({ collab: result.next });
3633
+ return HANDLED;
3634
+ }
3251
3635
  function applyNote(store, payload) {
3252
3636
  const row = object(payload["note"]);
3253
3637
  if (row === null) return ignored("a note event with no `note` row");
@@ -3569,6 +3953,7 @@ function createRoomEngine(options) {
3569
3953
  let joining = null;
3570
3954
  let lastRequest = null;
3571
3955
  let disposed = false;
3956
+ let moving = false;
3572
3957
  const confirmingEnds = /* @__PURE__ */ new WeakSet();
3573
3958
  async function leaveRoom() {
3574
3959
  const target = driver;
@@ -3798,6 +4183,7 @@ function createRoomEngine(options) {
3798
4183
  }
3799
4184
  },
3800
4185
  disconnected(reason) {
4186
+ if (moving) return;
3801
4187
  if (current !== null) {
3802
4188
  tokens.invalidate(current.roomName);
3803
4189
  current = null;
@@ -3812,11 +4198,13 @@ function createRoomEngine(options) {
3812
4198
  roomName: request.roomName,
3813
4199
  identity,
3814
4200
  ...request.meetingId !== void 0 ? { meetingId: request.meetingId } : {},
3815
- ...request.slug !== void 0 ? { slug: request.slug } : {}
4201
+ ...request.slug !== void 0 ? { slug: request.slug } : {},
4202
+ ...request.breakoutRoomId != null ? { breakoutRoomId: request.breakoutRoomId } : {}
3816
4203
  });
3817
4204
  current = token;
3818
4205
  store.patch({
3819
4206
  localIdentity: token.identity,
4207
+ breakoutRoomId: token.breakoutRoomId ?? null,
3820
4208
  grants: {
3821
4209
  role: token.role,
3822
4210
  canRecord: token.canRecord,
@@ -3935,6 +4323,56 @@ function createRoomEngine(options) {
3935
4323
  });
3936
4324
  return joining;
3937
4325
  },
4326
+ async moveToBreakout(roomId) {
4327
+ const request = lastRequest;
4328
+ if (request === null || driver === null) {
4329
+ report(
4330
+ "warn",
4331
+ "meet.moveToBreakout: this engine is not in a meeting room",
4332
+ "Join the meeting first; a breakout is a room OF a meeting."
4333
+ );
4334
+ return;
4335
+ }
4336
+ if ((store.snapshot().breakoutRoomId ?? null) === roomId) return;
4337
+ if (joining !== null) await joining.catch(() => void 0);
4338
+ const previous = driver;
4339
+ const next = {
4340
+ ...request,
4341
+ breakoutRoomId: roomId,
4342
+ // Arrive as you were: camera and microphone as they are now.
4343
+ mode: store.snapshot().media.camera.enabled ? "video" : "audio",
4344
+ microphone: store.snapshot().media.microphone.enabled
4345
+ };
4346
+ moving = true;
4347
+ try {
4348
+ driver = null;
4349
+ tokens.invalidate(request.roomName);
4350
+ current = null;
4351
+ await previous.disconnect();
4352
+ lastRequest = next;
4353
+ joining = connect(next).finally(() => {
4354
+ joining = null;
4355
+ });
4356
+ await joining;
4357
+ } catch (error) {
4358
+ const normalized = normalizeMeetError(error, "meet.moveToBreakout");
4359
+ report("warn", normalized.message, normalized.remedy);
4360
+ if (roomId !== null) {
4361
+ lastRequest = { ...next, breakoutRoomId: null };
4362
+ joining = connect(lastRequest).finally(() => {
4363
+ joining = null;
4364
+ });
4365
+ await joining.catch((again) => {
4366
+ throw fail(again, "meet.moveToBreakout");
4367
+ });
4368
+ } else {
4369
+ throw fail(error, "meet.moveToBreakout");
4370
+ }
4371
+ throw normalized;
4372
+ } finally {
4373
+ moving = false;
4374
+ }
4375
+ },
3938
4376
  leave: leaveRoom,
3939
4377
  // Turning a device on mid-meeting is the SAME operation as turning it on
3940
4378
  // during the join, so it runs the same function. A failure here used to
@@ -4204,6 +4642,109 @@ function createInRoomClient(options) {
4204
4642
  (row) => typeof row === "object" && row !== null ? chatFromRow(row) : null
4205
4643
  ).filter((message) => message !== null);
4206
4644
  store.loadChat(messages);
4645
+ },
4646
+ async loadCollab() {
4647
+ const operation = "meet.loadCollab";
4648
+ const id = meetingId(operation);
4649
+ const hdrs = headers();
4650
+ const response = await api.request({
4651
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(id)}`,
4652
+ method: "GET",
4653
+ operation,
4654
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4655
+ });
4656
+ if (!response.ok) {
4657
+ const error = await refusal2(
4658
+ response,
4659
+ operation,
4660
+ "Polls, questions and the whiteboard could not be read. New ones still arrive."
4661
+ );
4662
+ store.patch({ collab: { ...store.snapshot().collab, loaded: true, error: error.message } });
4663
+ throw error;
4664
+ }
4665
+ const body = await response.json();
4666
+ store.patch({ collab: collabFromState(body, store.snapshot().collab) });
4667
+ },
4668
+ async collab(request) {
4669
+ const operation = `meet.collab(${request.action})`;
4670
+ const hdrs = headers();
4671
+ const response = await api.request({
4672
+ path: MEET_ROUTES.collab,
4673
+ method: "POST",
4674
+ operation,
4675
+ body: {
4676
+ meeting_id: meetingId(operation),
4677
+ action: request.action,
4678
+ ...request.itemId !== void 0 ? { item_id: request.itemId } : {},
4679
+ ...request.question !== void 0 ? { question: request.question } : {},
4680
+ ...request.options !== void 0 ? { options: request.options } : {},
4681
+ ...request.multiple !== void 0 ? { multiple: request.multiple } : {},
4682
+ ...request.anonymous !== void 0 ? { anonymous: request.anonymous } : {},
4683
+ ...request.optionIds !== void 0 ? { option_ids: request.optionIds } : {},
4684
+ ...request.text !== void 0 ? { text: request.text } : {},
4685
+ ...request.stroke !== void 0 ? { stroke: request.stroke } : {},
4686
+ ...request.rooms !== void 0 ? { rooms: request.rooms } : {},
4687
+ ...request.allowChoose !== void 0 ? { allow_choose: request.allowChoose } : {},
4688
+ ...request.minutes !== void 0 ? { minutes: request.minutes } : {},
4689
+ ...request.identity !== void 0 ? { identity: request.identity } : {},
4690
+ ...request.roomId !== void 0 ? { room_id: request.roomId } : {}
4691
+ },
4692
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4693
+ });
4694
+ if (!response.ok) {
4695
+ throw await refusal2(response, operation, "Nothing was changed.");
4696
+ }
4697
+ const payload = await response.json();
4698
+ const removed = Array.isArray(payload["removed"]) ? payload["removed"].filter((v) => typeof v === "string") : [];
4699
+ let next = store.snapshot().collab;
4700
+ const item = payload["item"];
4701
+ if (typeof item === "object" && item !== null) next = withItem(next, item);
4702
+ if (removed.length > 0) {
4703
+ const gone = new Set(removed);
4704
+ next = {
4705
+ ...next,
4706
+ polls: next.polls.filter((p) => !gone.has(p.id)),
4707
+ questions: next.questions.filter((q) => !gone.has(q.id)),
4708
+ strokes: next.strokes.filter((st) => !gone.has(st.id))
4709
+ };
4710
+ }
4711
+ store.patch({ collab: next });
4712
+ const itemId = typeof item === "object" && item !== null && typeof item["id"] === "string" ? item["id"] : null;
4713
+ return {
4714
+ action: request.action,
4715
+ message: typeof payload["message"] === "string" ? payload["message"] : "Done.",
4716
+ removed,
4717
+ itemId
4718
+ };
4719
+ },
4720
+ async translateCaptions(language, lines) {
4721
+ if (lines.length === 0) return;
4722
+ const operation = "meet.translateCaptions";
4723
+ const hdrs = headers();
4724
+ const response = await api.request({
4725
+ path: MEET_ROUTES.captionsTranslate,
4726
+ method: "POST",
4727
+ operation,
4728
+ body: { meeting_id: meetingId(operation), target_language: language, lines },
4729
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4730
+ });
4731
+ if (!response.ok) {
4732
+ const error = await refusal2(response, operation, "Captions stay in the language they were spoken.");
4733
+ store.patch({
4734
+ collab: { ...store.snapshot().collab, captionTranslationError: error.message }
4735
+ });
4736
+ throw error;
4737
+ }
4738
+ const payload = await response.json();
4739
+ const current = store.snapshot().collab;
4740
+ if (current.captionLanguage !== language) return;
4741
+ const merged = { ...current.captionTranslations };
4742
+ for (const [id, value] of Object.entries(payload.translations ?? {})) {
4743
+ if (typeof value === "string") merged[id] = value;
4744
+ }
4745
+ store.patch({
4746
+ collab: { ...current, captionTranslations: merged, captionTranslationError: null }
4747
+ });
4207
4748
  }
4208
4749
  };
4209
4750
  }
@@ -4771,6 +5312,14 @@ function MeetRuntime(props) {
4771
5312
  }
4772
5313
  if (chatReadFor === snapshot.meeting.id) return;
4773
5314
  chatReadFor = snapshot.meeting.id;
5315
+ void inRoom.loadCollab().catch((error) => {
5316
+ const normalized = error;
5317
+ report({
5318
+ level: "warn",
5319
+ message: normalized.message ?? "meet: polls, questions and the whiteboard could not be read",
5320
+ ...normalized.remedy !== void 0 ? { remedy: normalized.remedy } : {}
5321
+ });
5322
+ });
4774
5323
  void inRoom.loadChat().catch((error) => {
4775
5324
  const normalized = error;
4776
5325
  store.patch({
@@ -6111,7 +6660,7 @@ function useGuestRecordAccess(meeting) {
6111
6660
  }
6112
6661
 
6113
6662
  // src/react/components.tsx
6114
- import { useEffect as useEffect3, useLayoutEffect, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
6663
+ import { useEffect as useEffect4, useLayoutEffect, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
6115
6664
  import { ErrorBox } from "@ai-matrx/design-system";
6116
6665
  import { avatarPaletteIndex, formatDurationMs as formatDurationMs3, getInitials } from "@ai-matrx/kit/format";
6117
6666
 
@@ -6178,12 +6727,19 @@ function coveredMs(intervals) {
6178
6727
  }
6179
6728
  function attendanceReport(meeting, attendees, names = {}) {
6180
6729
  const end = ms(meeting.endedAt);
6730
+ const measuredOf = /* @__PURE__ */ new Map();
6181
6731
  const perJoin = attendees.map((person) => {
6182
- const joined = ms(person.joinedAt);
6183
- const left = ms(person.leftAt);
6184
- const until = left ?? end;
6185
- const duration = joined !== null && until !== null && until >= joined ? until - joined : null;
6186
- return {
6732
+ const stays = person.sessions !== void 0 && person.sessions.length > 0 ? person.sessions.map((stay) => [ms(stay.joinedAt), ms(stay.leftAt)]) : [[ms(person.joinedAt), ms(person.leftAt)]];
6733
+ let toEnd = false;
6734
+ const measured = [];
6735
+ for (const [joined, left] of stays) {
6736
+ const until = left ?? end;
6737
+ if (joined === null || until === null || until < joined) continue;
6738
+ if (left === null) toEnd = true;
6739
+ measured.push([joined, until]);
6740
+ }
6741
+ const duration = measured.length === 0 ? null : coveredMs(measured);
6742
+ const row = {
6187
6743
  id: person.id,
6188
6744
  identity: person.identity,
6189
6745
  name: displayNameFor(names, person.identity, person.displayName),
@@ -6192,10 +6748,12 @@ function attendanceReport(meeting, attendees, names = {}) {
6192
6748
  joinedAt: person.joinedAt,
6193
6749
  leftAt: person.leftAt,
6194
6750
  durationMs: duration,
6195
- durationToEnd: duration !== null && left === null,
6751
+ durationToEnd: duration !== null && toEnd,
6196
6752
  admission: person.admissionState,
6197
- joins: 1
6753
+ joins: Math.max(1, person.sessions?.length ?? 0)
6198
6754
  };
6755
+ measuredOf.set(row, measured);
6756
+ return row;
6199
6757
  });
6200
6758
  const groups = /* @__PURE__ */ new Map();
6201
6759
  attendees.forEach((person, index) => {
@@ -6218,17 +6776,14 @@ function attendanceReport(meeting, attendees, names = {}) {
6218
6776
  const left = ms(row.leftAt);
6219
6777
  return left !== null && (latest === null || left > latest) ? left : latest;
6220
6778
  }, null);
6221
- const intervals = came.flatMap((row) => {
6222
- const joined = ms(row.joinedAt);
6223
- return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
6224
- });
6779
+ const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
6225
6780
  return {
6226
6781
  ...first,
6227
6782
  kind,
6228
6783
  leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
6229
6784
  durationMs: intervals.length === 0 ? null : coveredMs(intervals),
6230
6785
  durationToEnd: came.some((row) => row.durationToEnd),
6231
- joins: came.length === 0 ? joins.length : came.length
6786
+ joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
6232
6787
  };
6233
6788
  });
6234
6789
  const rank = KIND_RANK;
@@ -6372,8 +6927,8 @@ function transcriptDocument(bundle, format, options = {}) {
6372
6927
  if (line.identity !== last) {
6373
6928
  if (last !== null) out.push("");
6374
6929
  const who = speaker(line);
6375
- const clock = clockOfDay(line.startedAt, options);
6376
- out.push(format === "md" ? `**${who}** \xB7 ${clock}` : `${who} (${clock})`);
6930
+ const clock2 = clockOfDay(line.startedAt, options);
6931
+ out.push(format === "md" ? `**${who}** \xB7 ${clock2}` : `${who} (${clock2})`);
6377
6932
  last = line.identity;
6378
6933
  }
6379
6934
  out.push(line.text.trim());
@@ -6554,6 +7109,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
6554
7109
  return `${count2} ${count2 === 1 ? singular : plural}`;
6555
7110
  }
6556
7111
 
7112
+ // src/react/collab.tsx
7113
+ import { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
7114
+
6557
7115
  // src/react/icons.tsx
6558
7116
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
6559
7117
  function Icon({ children, ...props }) {
@@ -6738,109 +7296,1138 @@ function FlagIcon(props) {
6738
7296
  function PencilIcon(props) {
6739
7297
  return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
6740
7298
  }
6741
-
6742
- // src/react/components.tsx
6743
- import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
6744
- function InertNotice({ what }) {
6745
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
6746
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__empty-title", children: [
6747
- what,
6748
- " is not ready yet"
6749
- ] }),
6750
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Calls and meetings need a signed-in identity and an active organization. This will appear as soon as they resolve." })
7299
+ function ActivitiesIcon(props) {
7300
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7301
+ /* @__PURE__ */ jsx2("path", { d: "M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z" }),
7302
+ /* @__PURE__ */ jsx2("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
7303
+ /* @__PURE__ */ jsx2("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
6751
7304
  ] });
6752
7305
  }
6753
- function Avatar({
6754
- name,
6755
- url,
6756
- size = 40
6757
- }) {
6758
- const tint = avatarPaletteIndex(name);
6759
- if (url != null && url.length > 0) {
6760
- return /* @__PURE__ */ jsx3(
6761
- "img",
6762
- {
6763
- className: "mx-meet__avatar",
6764
- src: url,
6765
- alt: "",
6766
- width: size,
6767
- height: size,
6768
- style: { width: size, height: size }
6769
- }
6770
- );
6771
- }
6772
- return /* @__PURE__ */ jsx3(
6773
- "span",
6774
- {
6775
- className: "mx-meet__avatar mx-meet__avatar--initials",
6776
- style: {
6777
- width: size,
6778
- height: size,
6779
- fontSize: Math.round(size * 0.38),
6780
- background: `var(--mx-meet-avatar-${tint})`
6781
- },
6782
- "aria-hidden": "true",
6783
- children: getInitials(name)
6784
- }
6785
- );
7306
+ function PollIcon(props) {
7307
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7308
+ /* @__PURE__ */ jsx2("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
7309
+ /* @__PURE__ */ jsx2("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
7310
+ /* @__PURE__ */ jsx2("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
7311
+ ] });
6786
7312
  }
6787
- function ControlButton({
6788
- label,
6789
- active = false,
6790
- danger = false,
6791
- onClick,
6792
- children
6793
- }) {
6794
- return /* @__PURE__ */ jsx3(
6795
- "button",
6796
- {
6797
- type: "button",
6798
- className: [
6799
- "mx-meet__control",
6800
- active ? "mx-meet__control--active" : "",
6801
- danger ? "mx-meet__control--danger" : ""
6802
- ].filter(Boolean).join(" "),
6803
- "aria-label": label,
6804
- title: label,
6805
- onClick,
6806
- children
6807
- }
6808
- );
7313
+ function QuestionIcon(props) {
7314
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7315
+ /* @__PURE__ */ jsx2("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
7316
+ /* @__PURE__ */ jsx2("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
7317
+ /* @__PURE__ */ jsx2("path", { d: "M12 17h.01" })
7318
+ ] });
6809
7319
  }
6810
- function RecordingIndicator() {
6811
- const { state, label } = useRecording();
6812
- if (label === null) return null;
6813
- return /* @__PURE__ */ jsxs2(
6814
- "span",
6815
- {
6816
- className: `mx-meet__recording mx-meet__recording--${state}`,
6817
- role: "status",
6818
- "aria-live": "polite",
6819
- children: [
6820
- /* @__PURE__ */ jsx3(RecordIcon, { width: 10, height: 10 }),
6821
- label
6822
- ]
6823
- }
6824
- );
7320
+ function WhiteboardIcon(props) {
7321
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7322
+ /* @__PURE__ */ jsx2("path", { d: "M2 3h20" }),
7323
+ /* @__PURE__ */ jsx2("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
7324
+ /* @__PURE__ */ jsx2("path", { d: "m7 21 5-5 5 5" })
7325
+ ] });
6825
7326
  }
6826
- function ConnectionDot({ quality }) {
6827
- if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
6828
- return /* @__PURE__ */ jsx3("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx3(WifiLowIcon, { width: 14, height: 14 }) });
7327
+ function BreakoutIcon(props) {
7328
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7329
+ /* @__PURE__ */ jsx2("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
7330
+ /* @__PURE__ */ jsx2("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
7331
+ /* @__PURE__ */ jsx2("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
7332
+ ] });
6829
7333
  }
6830
- function RoleBadge({ role }) {
6831
- if (role === "host") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Host" });
6832
- if (role === "cohost") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Co-host" });
6833
- if (role === "guest") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" });
6834
- return null;
7334
+ function UpvoteIcon(props) {
7335
+ return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
6835
7336
  }
6836
- function ParticipantTile({
7337
+ function EraserIcon(props) {
7338
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7339
+ /* @__PURE__ */ jsx2("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
7340
+ /* @__PURE__ */ jsx2("path", { d: "M22 21H7" }),
7341
+ /* @__PURE__ */ jsx2("path", { d: "m5 11 9 9" })
7342
+ ] });
7343
+ }
7344
+ function HighlighterIcon(props) {
7345
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7346
+ /* @__PURE__ */ jsx2("path", { d: "m9 11-6 6v3h9l3-3" }),
7347
+ /* @__PURE__ */ jsx2("path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" })
7348
+ ] });
7349
+ }
7350
+ function UndoIcon(props) {
7351
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7352
+ /* @__PURE__ */ jsx2("path", { d: "M9 14 4 9l5-5" }),
7353
+ /* @__PURE__ */ jsx2("path", { d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11" })
7354
+ ] });
7355
+ }
7356
+
7357
+ // src/react/collab.tsx
7358
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
7359
+ function useCollab() {
7360
+ const host = useMeetHost();
7361
+ const snapshot = useMeetSnapshot();
7362
+ const isHost = useIsHost();
7363
+ return {
7364
+ collab: snapshot?.collab ?? null,
7365
+ isHost,
7366
+ localIdentity: snapshot?.localIdentity ?? null,
7367
+ breakoutRoomId: snapshot?.breakoutRoomId ?? null,
7368
+ async act(request) {
7369
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7370
+ try {
7371
+ const result = await host.inRoom.collab(request);
7372
+ return { ok: true, message: result.message, itemId: result.itemId };
7373
+ } catch (error) {
7374
+ return { ok: false, message: error.message ?? "That did not work." };
7375
+ }
7376
+ },
7377
+ async moveTo(roomId) {
7378
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7379
+ try {
7380
+ await host.engine.moveToBreakout(roomId);
7381
+ return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
7382
+ } catch (error) {
7383
+ return { ok: false, message: error.message ?? "That room could not be joined." };
7384
+ }
7385
+ }
7386
+ };
7387
+ }
7388
+ function useNotice() {
7389
+ const [notice, setNotice] = useState3(null);
7390
+ useEffect3(() => {
7391
+ if (notice === null) return void 0;
7392
+ const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
7393
+ return () => clearTimeout(timer);
7394
+ }, [notice]);
7395
+ return [notice, (result) => setNotice({ text: result.message, failed: !result.ok })];
7396
+ }
7397
+ function Notice({ notice }) {
7398
+ if (notice === null) return null;
7399
+ return /* @__PURE__ */ jsx3("p", { className: notice.failed ? "mx-meet__panel-note mx-meet__collab-error" : "mx-meet__panel-note", role: "status", children: notice.text });
7400
+ }
7401
+ var ACTIVITY_LABELS = {
7402
+ polls: "Polls",
7403
+ qa: "Q&A",
7404
+ whiteboard: "Whiteboard",
7405
+ breakouts: "Breakout rooms"
7406
+ };
7407
+ function ActivityIcon({ panel }) {
7408
+ const props = { width: 16, height: 16 };
7409
+ if (panel === "polls") return /* @__PURE__ */ jsx3(PollIcon, { ...props });
7410
+ if (panel === "qa") return /* @__PURE__ */ jsx3(QuestionIcon, { ...props });
7411
+ if (panel === "whiteboard") return /* @__PURE__ */ jsx3(WhiteboardIcon, { ...props });
7412
+ return /* @__PURE__ */ jsx3(BreakoutIcon, { ...props });
7413
+ }
7414
+ function useAvailableActivities() {
7415
+ const { collab, isHost } = useCollab();
7416
+ const settings = collab?.settings ?? null;
7417
+ if (settings === null) return [];
7418
+ const out = [];
7419
+ if (settings.whiteboardEnabled) out.push("whiteboard");
7420
+ if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
7421
+ if (settings.qaEnabled) out.push("qa");
7422
+ if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
7423
+ return out;
7424
+ }
7425
+ function useActivityAttention() {
7426
+ const { collab, isHost } = useCollab();
7427
+ if (collab === null) return false;
7428
+ if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
7429
+ if (isHost && collab.questions.some((q) => q.state === "open")) return true;
7430
+ return false;
7431
+ }
7432
+ function ActivitiesControl({
7433
+ active,
7434
+ onOpen
7435
+ }) {
7436
+ const [open, setOpen] = useState3(false);
7437
+ const available = useAvailableActivities();
7438
+ const attention = useActivityAttention();
7439
+ if (available.length === 0) return null;
7440
+ return /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7441
+ /* @__PURE__ */ jsxs2(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
7442
+ /* @__PURE__ */ jsx3(ActivitiesIcon, {}),
7443
+ attention ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7444
+ ] }),
7445
+ open ? /* @__PURE__ */ jsx3(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs2(
7446
+ MenuItem,
7447
+ {
7448
+ onSelect: () => {
7449
+ setOpen(false);
7450
+ onOpen(panel);
7451
+ },
7452
+ children: [
7453
+ /* @__PURE__ */ jsx3(ActivityIcon, { panel }),
7454
+ " ",
7455
+ ACTIVITY_LABELS[panel]
7456
+ ]
7457
+ },
7458
+ panel
7459
+ )) }) }) : null
7460
+ ] });
7461
+ }
7462
+ function PollComposer({ maxOptions, onDone }) {
7463
+ const { act } = useCollab();
7464
+ const [question, setQuestion] = useState3("");
7465
+ const [options, setOptions] = useState3(["", ""]);
7466
+ const [multiple, setMultiple] = useState3(false);
7467
+ const [anonymous, setAnonymous] = useState3(false);
7468
+ const [busy, setBusy] = useState3(false);
7469
+ const [notice, show] = useNotice();
7470
+ const filled = options.map((o) => o.trim()).filter(Boolean);
7471
+ const ready = question.trim().length > 0 && filled.length >= 2;
7472
+ const save = async (launch) => {
7473
+ setBusy(true);
7474
+ const created = await act({ action: "poll_create", question, options: filled, multiple, anonymous });
7475
+ if (!created.ok) {
7476
+ show(created);
7477
+ setBusy(false);
7478
+ return;
7479
+ }
7480
+ if (launch && created.itemId != null) {
7481
+ const launched = await act({ action: "poll_launch", itemId: created.itemId });
7482
+ if (!launched.ok) {
7483
+ show(launched);
7484
+ setBusy(false);
7485
+ return;
7486
+ }
7487
+ }
7488
+ setBusy(false);
7489
+ onDone();
7490
+ };
7491
+ return /* @__PURE__ */ jsxs2(
7492
+ "form",
7493
+ {
7494
+ className: "mx-meet__collab-card",
7495
+ onSubmit: (event) => {
7496
+ event.preventDefault();
7497
+ if (ready) void save(true);
7498
+ },
7499
+ children: [
7500
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7501
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Question" }),
7502
+ /* @__PURE__ */ jsx3(
7503
+ "input",
7504
+ {
7505
+ className: "mx-meet__input",
7506
+ value: question,
7507
+ maxLength: 1e3,
7508
+ onChange: (event) => setQuestion(event.target.value),
7509
+ placeholder: "Ask the room something",
7510
+ autoFocus: true
7511
+ }
7512
+ )
7513
+ ] }),
7514
+ options.map((option, index) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7515
+ /* @__PURE__ */ jsx3(
7516
+ "input",
7517
+ {
7518
+ className: "mx-meet__input",
7519
+ value: option,
7520
+ maxLength: 200,
7521
+ "aria-label": `Answer ${index + 1}`,
7522
+ placeholder: `Answer ${index + 1}`,
7523
+ onChange: (event) => setOptions(options.map((o, i) => i === index ? event.target.value : o))
7524
+ }
7525
+ ),
7526
+ options.length > 2 ? /* @__PURE__ */ jsx3(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) }) : null
7527
+ ] }, index)),
7528
+ options.length < maxOptions ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
7529
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7530
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
7531
+ "People can pick more than one"
7532
+ ] }),
7533
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7534
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
7535
+ "Anonymous \u2014 nobody sees who picked what"
7536
+ ] }),
7537
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7538
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
7539
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
7540
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
7541
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
7542
+ ] })
7543
+ ]
7544
+ }
7545
+ );
7546
+ }
7547
+ function PollCard({ poll }) {
7548
+ const { act, isHost } = useCollab();
7549
+ const [picked, setPicked] = useState3(poll.myVote.slice());
7550
+ const [notice, show] = useNotice();
7551
+ useEffect3(() => setPicked(poll.myVote.slice()), [poll.myVote]);
7552
+ const counts = poll.options.some((o) => o.votes !== void 0);
7553
+ const total = poll.options.reduce((sum, o) => sum + (o.votes ?? 0), 0);
7554
+ const canVote = poll.state === "live";
7555
+ const voted = poll.myVote.length > 0;
7556
+ const stateWord = poll.state === "draft" ? "Draft" : poll.state === "live" ? "Open" : "Closed";
7557
+ const toggle = (id) => {
7558
+ if (!canVote) return;
7559
+ setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
7560
+ };
7561
+ return /* @__PURE__ */ jsxs2("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
7562
+ /* @__PURE__ */ jsxs2("header", { className: "mx-meet__collab-head", children: [
7563
+ /* @__PURE__ */ jsx3("strong", { className: "mx-meet__collab-title", children: poll.question }),
7564
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: stateWord })
7565
+ ] }),
7566
+ /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
7567
+ poll.multiple ? "Pick any." : "Pick one.",
7568
+ poll.anonymous ? " Anonymous." : "",
7569
+ counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
7570
+ isHost && poll.state !== "draft" && !poll.resultsShared ? " Results are visible only to hosts." : ""
7571
+ ] }),
7572
+ /* @__PURE__ */ jsx3("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
7573
+ const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
7574
+ const chosen = picked.includes(option.id);
7575
+ return /* @__PURE__ */ jsxs2("li", { children: [
7576
+ /* @__PURE__ */ jsxs2(
7577
+ "button",
7578
+ {
7579
+ type: "button",
7580
+ className: chosen ? "mx-meet__poll-option mx-meet__poll-option--chosen" : "mx-meet__poll-option",
7581
+ "aria-pressed": chosen,
7582
+ disabled: !canVote,
7583
+ onClick: () => toggle(option.id),
7584
+ children: [
7585
+ counts ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
7586
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-text", children: option.text }),
7587
+ counts ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__poll-count", children: [
7588
+ option.votes ?? 0,
7589
+ " \xB7 ",
7590
+ share,
7591
+ "%"
7592
+ ] }) : null
7593
+ ]
7594
+ }
7595
+ ),
7596
+ option.voters !== void 0 && option.voters.length > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-voters", children: option.voters.join(", ") }) : null
7597
+ ] }, option.id);
7598
+ }) }),
7599
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7600
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
7601
+ canVote ? /* @__PURE__ */ jsx3(
7602
+ "button",
7603
+ {
7604
+ type: "button",
7605
+ className: "mx-meet__primary mx-meet__primary--small",
7606
+ disabled: picked.length === 0 || voted && picked.join() === poll.myVote.join(),
7607
+ onClick: () => void act({ action: "poll_vote", itemId: poll.id, optionIds: picked }).then(show),
7608
+ children: voted ? "Change vote" : "Vote"
7609
+ }
7610
+ ) : null,
7611
+ isHost && poll.state === "draft" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void act({ action: "poll_launch", itemId: poll.id }).then(show), children: "Launch" }) : null,
7612
+ isHost && poll.state === "live" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_close", itemId: poll.id }).then(show), children: "End poll" }) : null,
7613
+ isHost && poll.state !== "draft" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_share", itemId: poll.id }).then(show), children: poll.resultsShared ? "Hide results" : "Share results" }) : null,
7614
+ isHost && poll.state === "live" ? null : isHost ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "poll_delete", itemId: poll.id }).then(show), children: "Delete" }) : null
7615
+ ] })
7616
+ ] });
7617
+ }
7618
+ function PollsPanel({ onClose }) {
7619
+ const { collab, isHost } = useCollab();
7620
+ const [composing, setComposing] = useState3(false);
7621
+ const polls = collab?.polls ?? [];
7622
+ const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
7623
+ const ordered = [...polls].reverse();
7624
+ return /* @__PURE__ */ jsxs2(PanelShell, { title: "Polls", onClose, children: [
7625
+ collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
7626
+ isHost && !composing ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
7627
+ isHost && composing ? /* @__PURE__ */ jsx3(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
7628
+ ordered.length === 0 && !composing ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: isHost ? "No polls yet. Polls and their results are kept with the meeting." : "No polls yet." }) : null,
7629
+ ordered.map((poll) => /* @__PURE__ */ jsx3(PollCard, { poll }, poll.id))
7630
+ ] });
7631
+ }
7632
+ function QuestionCard({ question }) {
7633
+ const { act, isHost } = useCollab();
7634
+ const [answering, setAnswering] = useState3(false);
7635
+ const [reply, setReply] = useState3("");
7636
+ const [notice, show] = useNotice();
7637
+ return /* @__PURE__ */ jsxs2("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
7638
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-row", children: [
7639
+ /* @__PURE__ */ jsxs2(
7640
+ "button",
7641
+ {
7642
+ type: "button",
7643
+ className: question.upvotedByMe ? "mx-meet__upvote mx-meet__upvote--on" : "mx-meet__upvote",
7644
+ "aria-pressed": question.upvotedByMe,
7645
+ "aria-label": question.upvotedByMe ? "Remove your upvote" : "Upvote",
7646
+ disabled: question.state === "dismissed",
7647
+ onClick: () => void act({ action: "question_upvote", itemId: question.id }).then((r) => r.ok ? void 0 : show(r)),
7648
+ children: [
7649
+ /* @__PURE__ */ jsx3(UpvoteIcon, { width: 16, height: 16 }),
7650
+ /* @__PURE__ */ jsx3("span", { children: question.upvotes })
7651
+ ]
7652
+ }
7653
+ ),
7654
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-body", children: [
7655
+ /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
7656
+ /* @__PURE__ */ jsx3("strong", { children: question.mine ? "You" : question.askerName }),
7657
+ question.mine && question.anonymous ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
7658
+ question.state !== "open" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
7659
+ ] }),
7660
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-text", children: question.text }),
7661
+ question.answer !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__question-answer", children: [
7662
+ /* @__PURE__ */ jsxs2("strong", { children: [
7663
+ question.answeredByName ?? "Host",
7664
+ ":"
7665
+ ] }),
7666
+ " ",
7667
+ question.answer
7668
+ ] }) : null
7669
+ ] })
7670
+ ] }),
7671
+ answering ? /* @__PURE__ */ jsxs2(
7672
+ "form",
7673
+ {
7674
+ className: "mx-meet__composer-row",
7675
+ onSubmit: (event) => {
7676
+ event.preventDefault();
7677
+ void act({ action: "question_answer", itemId: question.id, text: reply }).then((r) => {
7678
+ show(r);
7679
+ if (r.ok) {
7680
+ setAnswering(false);
7681
+ setReply("");
7682
+ }
7683
+ });
7684
+ },
7685
+ children: [
7686
+ /* @__PURE__ */ jsx3(
7687
+ "input",
7688
+ {
7689
+ className: "mx-meet__input",
7690
+ value: reply,
7691
+ maxLength: 2e3,
7692
+ onChange: (event) => setReply(event.target.value),
7693
+ placeholder: "Type an answer, or leave empty if you answered out loud",
7694
+ "aria-label": "Answer",
7695
+ autoFocus: true
7696
+ }
7697
+ ),
7698
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", children: "Done" })
7699
+ ]
7700
+ }
7701
+ ) : null,
7702
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7703
+ isHost || question.mine ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
7704
+ isHost && question.state === "open" && !answering ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
7705
+ isHost && question.state === "open" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
7706
+ isHost && question.state !== "open" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
7707
+ question.mine || isHost ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "question_delete", itemId: question.id }).then(show), children: "Delete" }) : null
7708
+ ] }) : null
7709
+ ] });
7710
+ }
7711
+ function QaPanel({ onClose }) {
7712
+ const { collab, act } = useCollab();
7713
+ const [draft, setDraft] = useState3("");
7714
+ const [anonymous, setAnonymous] = useState3(false);
7715
+ const [order, setOrder] = useState3("popular");
7716
+ const [notice, show] = useNotice();
7717
+ const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
7718
+ const questions = [...collab?.questions ?? []];
7719
+ const rank = (q) => q.state === "open" ? 0 : q.state === "answered" ? 1 : 2;
7720
+ questions.sort(
7721
+ (a, b) => rank(a) !== rank(b) ? rank(a) - rank(b) : order === "popular" ? b.upvotes - a.upvotes || (b.createdAt ?? "").localeCompare(a.createdAt ?? "") : (b.createdAt ?? "").localeCompare(a.createdAt ?? "")
7722
+ );
7723
+ return /* @__PURE__ */ jsxs2(PanelShell, { title: "Q&A", onClose, children: [
7724
+ collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
7725
+ /* @__PURE__ */ jsxs2(
7726
+ "form",
7727
+ {
7728
+ className: "mx-meet__composer mx-meet__composer--chat",
7729
+ onSubmit: (event) => {
7730
+ event.preventDefault();
7731
+ const text3 = draft.trim();
7732
+ if (text3.length === 0) return;
7733
+ void act({ action: "question_ask", text: text3, anonymous: allowAnonymous && anonymous }).then((r) => {
7734
+ if (r.ok) setDraft("");
7735
+ else show(r);
7736
+ });
7737
+ },
7738
+ children: [
7739
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7740
+ /* @__PURE__ */ jsx3(
7741
+ "input",
7742
+ {
7743
+ className: "mx-meet__input",
7744
+ value: draft,
7745
+ maxLength: 1e3,
7746
+ onChange: (event) => setDraft(event.target.value),
7747
+ placeholder: "Ask the host a question",
7748
+ "aria-label": "Ask the host a question"
7749
+ }
7750
+ ),
7751
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
7752
+ ] }),
7753
+ allowAnonymous ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7754
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
7755
+ "Ask anonymously"
7756
+ ] }) : null
7757
+ ]
7758
+ }
7759
+ ),
7760
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7761
+ questions.length > 1 ? /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "Order questions", children: ["popular", "recent"].map((value) => /* @__PURE__ */ jsx3(
7762
+ "button",
7763
+ {
7764
+ type: "button",
7765
+ className: order === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
7766
+ "aria-pressed": order === value,
7767
+ onClick: () => setOrder(value),
7768
+ children: value === "popular" ? "Popular" : "Recent"
7769
+ },
7770
+ value
7771
+ )) }) : null,
7772
+ questions.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "No questions yet. Questions are kept with the meeting." }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__chat", children: questions.map((question) => /* @__PURE__ */ jsx3(QuestionCard, { question }, question.id)) })
7773
+ ] });
7774
+ }
7775
+ var BOARD_W = 1600;
7776
+ var BOARD_H = 1e3;
7777
+ var INK = ["#111827", "#dc2626", "#2563eb", "#16a34a", "#f59e0b", "#7c3aed"];
7778
+ function strokePath(points) {
7779
+ if (points.length === 0) return "";
7780
+ const [first, ...rest] = points;
7781
+ const move = `M${(first[0] * BOARD_W).toFixed(1)} ${(first[1] * BOARD_H).toFixed(1)}`;
7782
+ if (rest.length === 0) return `${move} l0.1 0`;
7783
+ return `${move} ${rest.map(([x, y]) => `L${(x * BOARD_W).toFixed(1)} ${(y * BOARD_H).toFixed(1)}`).join(" ")}`;
7784
+ }
7785
+ function StrokeView({ stroke, onPick }) {
7786
+ return /* @__PURE__ */ jsx3(
7787
+ "path",
7788
+ {
7789
+ d: strokePath(stroke.points),
7790
+ fill: "none",
7791
+ stroke: stroke.color,
7792
+ strokeWidth: stroke.tool === "highlighter" ? stroke.width * 4 : stroke.width,
7793
+ strokeOpacity: stroke.tool === "highlighter" ? 0.35 : stroke.pending === true ? 0.6 : 1,
7794
+ strokeLinecap: "round",
7795
+ strokeLinejoin: "round",
7796
+ onPointerDown: onPick,
7797
+ style: onPick !== void 0 ? { cursor: "pointer" } : void 0,
7798
+ children: /* @__PURE__ */ jsx3("title", { children: stroke.byName })
7799
+ }
7800
+ );
7801
+ }
7802
+ function WhiteboardPanel({ onClose }) {
7803
+ const { collab, act, isHost, localIdentity } = useCollab();
7804
+ const [tool, setTool] = useState3("pen");
7805
+ const [color, setColor] = useState3(INK[0]);
7806
+ const [drawing, setDrawing] = useState3(null);
7807
+ const [pending, setPending] = useState3([]);
7808
+ const [notice, show] = useNotice();
7809
+ const svgRef = useRef3(null);
7810
+ const strokes = collab?.strokes ?? [];
7811
+ const mine = strokes.filter((s) => s.by === localIdentity);
7812
+ const point = (event) => {
7813
+ const svg = svgRef.current;
7814
+ if (svg === null) return null;
7815
+ const rect = svg.getBoundingClientRect();
7816
+ const scale = Math.min(rect.width / BOARD_W, rect.height / BOARD_H);
7817
+ const offsetX = (rect.width - BOARD_W * scale) / 2;
7818
+ const offsetY = (rect.height - BOARD_H * scale) / 2;
7819
+ const x = (event.clientX - rect.left - offsetX) / (BOARD_W * scale);
7820
+ const y = (event.clientY - rect.top - offsetY) / (BOARD_H * scale);
7821
+ return [Math.min(1, Math.max(0, x)), Math.min(1, Math.max(0, y))];
7822
+ };
7823
+ const finish = () => {
7824
+ const points = drawing;
7825
+ setDrawing(null);
7826
+ if (points === null || points.length === 0 || tool === "eraser") return;
7827
+ const thinned = points.filter((p, i) => i === 0 || i === points.length - 1 || i % 2 === 0).slice(0, 2e3);
7828
+ const stroke = {
7829
+ points: thinned.map(([x, y]) => [Number(x.toFixed(4)), Number(y.toFixed(4))]),
7830
+ color,
7831
+ width: tool === "highlighter" ? 4 : 3,
7832
+ tool: tool === "highlighter" ? "highlighter" : "pen"
7833
+ };
7834
+ const localId = `pending-${Date.now()}`;
7835
+ setPending((list) => [...list, { id: localId, ...stroke, by: localIdentity ?? "", byName: "You", pending: true }]);
7836
+ void act({ action: "stroke_add", stroke }).then((result) => {
7837
+ setPending((list) => list.filter((s) => s.id !== localId));
7838
+ if (!result.ok) show(result);
7839
+ });
7840
+ };
7841
+ return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
7842
+ /* @__PURE__ */ jsxs2("header", { className: "mx-meet__whiteboard-bar", children: [
7843
+ /* @__PURE__ */ jsx3("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
7844
+ /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
7845
+ ["pen", "Pen", /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }, "p")],
7846
+ ["highlighter", "Highlighter", /* @__PURE__ */ jsx3(HighlighterIcon, { width: 16, height: 16 }, "h")],
7847
+ ["eraser", "Eraser \u2014 click a stroke", /* @__PURE__ */ jsx3(EraserIcon, { width: 16, height: 16 }, "e")]
7848
+ ].map(([value, label, icon]) => /* @__PURE__ */ jsx3(
7849
+ "button",
7850
+ {
7851
+ type: "button",
7852
+ className: tool === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
7853
+ "aria-pressed": tool === value,
7854
+ "aria-label": label,
7855
+ title: label,
7856
+ onClick: () => setTool(value),
7857
+ children: icon
7858
+ },
7859
+ value
7860
+ )) }),
7861
+ /* @__PURE__ */ jsx3("div", { className: "mx-meet__swatches", role: "group", "aria-label": "Color", children: INK.map((ink) => /* @__PURE__ */ jsx3(
7862
+ "button",
7863
+ {
7864
+ type: "button",
7865
+ className: ink === color ? "mx-meet__swatch mx-meet__swatch--on" : "mx-meet__swatch",
7866
+ style: { background: ink },
7867
+ "aria-label": `Color ${ink}`,
7868
+ "aria-pressed": ink === color,
7869
+ onClick: () => {
7870
+ setColor(ink);
7871
+ if (tool === "eraser") setTool("pen");
7872
+ }
7873
+ },
7874
+ ink
7875
+ )) }),
7876
+ /* @__PURE__ */ jsx3(
7877
+ ControlButton,
7878
+ {
7879
+ label: "Undo my last stroke",
7880
+ onClick: () => {
7881
+ const last = mine[mine.length - 1];
7882
+ if (last !== void 0) void act({ action: "stroke_erase", itemId: last.id }).then((r) => r.ok ? void 0 : show(r));
7883
+ },
7884
+ children: /* @__PURE__ */ jsx3(UndoIcon, { width: 16, height: 16 })
7885
+ }
7886
+ ),
7887
+ isHost && strokes.length > 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "whiteboard_clear" }).then(show), children: "Clear board" }) : null,
7888
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__whiteboard-note", children: "Saved with the meeting" }),
7889
+ /* @__PURE__ */ jsx3(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
7890
+ ] }),
7891
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7892
+ /* @__PURE__ */ jsxs2(
7893
+ "svg",
7894
+ {
7895
+ ref: svgRef,
7896
+ className: tool === "eraser" ? "mx-meet__board mx-meet__board--erase" : "mx-meet__board",
7897
+ viewBox: `0 0 ${BOARD_W} ${BOARD_H}`,
7898
+ preserveAspectRatio: "xMidYMid meet",
7899
+ role: "img",
7900
+ "aria-label": `Shared whiteboard, ${strokes.length} strokes`,
7901
+ onPointerDown: (event) => {
7902
+ if (tool === "eraser") return;
7903
+ const p = point(event);
7904
+ if (p === null) return;
7905
+ event.target.setPointerCapture?.(event.pointerId);
7906
+ setDrawing([p]);
7907
+ },
7908
+ onPointerMove: (event) => {
7909
+ if (drawing === null) return;
7910
+ const p = point(event);
7911
+ if (p !== null) setDrawing([...drawing, p]);
7912
+ },
7913
+ onPointerUp: finish,
7914
+ onPointerCancel: finish,
7915
+ children: [
7916
+ /* @__PURE__ */ jsx3("rect", { x: 0, y: 0, width: BOARD_W, height: BOARD_H, className: "mx-meet__board-paper" }),
7917
+ strokes.map((stroke) => /* @__PURE__ */ jsx3(
7918
+ StrokeView,
7919
+ {
7920
+ stroke,
7921
+ onPick: tool === "eraser" && (isHost || stroke.by === localIdentity) ? () => void act({ action: "stroke_erase", itemId: stroke.id }).then((r) => r.ok ? void 0 : show(r)) : void 0
7922
+ },
7923
+ stroke.id
7924
+ )),
7925
+ pending.map((stroke) => /* @__PURE__ */ jsx3(StrokeView, { stroke }, stroke.id)),
7926
+ drawing !== null ? /* @__PURE__ */ jsx3(
7927
+ StrokeView,
7928
+ {
7929
+ stroke: {
7930
+ id: "drawing",
7931
+ points: drawing,
7932
+ color,
7933
+ width: tool === "highlighter" ? 4 : 3,
7934
+ tool: tool === "highlighter" ? "highlighter" : "pen",
7935
+ by: "",
7936
+ byName: "You"
7937
+ }
7938
+ }
7939
+ ) : null
7940
+ ]
7941
+ }
7942
+ )
7943
+ ] });
7944
+ }
7945
+ function clock(ms2) {
7946
+ const total = Math.ceil(ms2 / 1e3);
7947
+ const minutes = Math.floor(total / 60);
7948
+ const seconds = total % 60;
7949
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
7950
+ }
7951
+ function useNow(active) {
7952
+ const [now, setNow] = useState3(() => Date.now());
7953
+ useEffect3(() => {
7954
+ if (!active) return void 0;
7955
+ const timer = setInterval(() => setNow(Date.now()), 1e3);
7956
+ return () => clearInterval(timer);
7957
+ }, [active]);
7958
+ return now;
7959
+ }
7960
+ function BreakoutSetup() {
7961
+ const { collab, act } = useCollab();
7962
+ const snapshot = useMeetSnapshot();
7963
+ const settings = collab?.settings ?? null;
7964
+ const people = (snapshot?.participants ?? []).filter(
7965
+ (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
7966
+ );
7967
+ const [count2, setCount] = useState3(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
7968
+ const [mode, setMode] = useState3("auto");
7969
+ const [minutes, setMinutes] = useState3(settings?.breakoutDefaultMinutes ?? 15);
7970
+ const [manual, setManual] = useState3({});
7971
+ const [busy, setBusy] = useState3(false);
7972
+ const [notice, show] = useNotice();
7973
+ const max = settings?.breakoutMaxRooms ?? 20;
7974
+ const rooms = Math.min(Math.max(1, count2), max);
7975
+ const assignment = mode === "auto" ? autoAssign(
7976
+ people.map((p) => p.identity),
7977
+ rooms
7978
+ ) : mode === "manual" ? Array.from(
7979
+ { length: rooms },
7980
+ (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
7981
+ ) : Array.from({ length: rooms }, () => []);
7982
+ const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
7983
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
7984
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7985
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Rooms" }),
7986
+ /* @__PURE__ */ jsx3(
7987
+ "input",
7988
+ {
7989
+ className: "mx-meet__input",
7990
+ type: "number",
7991
+ min: 1,
7992
+ max,
7993
+ value: count2,
7994
+ onChange: (event) => setCount(Number(event.target.value) || 1)
7995
+ }
7996
+ )
7997
+ ] }),
7998
+ /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "How people are placed", children: [
7999
+ ["auto", "Automatically"],
8000
+ ["manual", "Manually"],
8001
+ ["choose", "Let people choose"]
8002
+ ].map(([value, label]) => /* @__PURE__ */ jsx3(
8003
+ "button",
8004
+ {
8005
+ type: "button",
8006
+ className: mode === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8007
+ "aria-pressed": mode === value,
8008
+ onClick: () => setMode(value),
8009
+ children: label
8010
+ },
8011
+ value
8012
+ )) }),
8013
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8014
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
8015
+ /* @__PURE__ */ jsx3(
8016
+ "input",
8017
+ {
8018
+ className: "mx-meet__input",
8019
+ type: "number",
8020
+ min: 0,
8021
+ max: 720,
8022
+ value: minutes,
8023
+ onChange: (event) => setMinutes(Math.max(0, Number(event.target.value) || 0))
8024
+ }
8025
+ )
8026
+ ] }),
8027
+ mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
8028
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__person-name", children: person.displayName }),
8029
+ /* @__PURE__ */ jsxs2(
8030
+ "select",
8031
+ {
8032
+ className: "mx-meet__select mx-meet__select--compact",
8033
+ "aria-label": `Room for ${person.displayName}`,
8034
+ value: manual[person.identity] ?? -1,
8035
+ onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
8036
+ children: [
8037
+ /* @__PURE__ */ jsx3("option", { value: -1, children: "Main room" }),
8038
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs2("option", { value: index, children: [
8039
+ "Room ",
8040
+ index + 1
8041
+ ] }, index))
8042
+ ]
8043
+ }
8044
+ )
8045
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx3("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs2("li", { children: [
8046
+ /* @__PURE__ */ jsxs2("strong", { children: [
8047
+ "Room ",
8048
+ index + 1
8049
+ ] }),
8050
+ " ",
8051
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
8052
+ ] }, index)) }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
8053
+ /* @__PURE__ */ jsx3(Notice, { notice }),
8054
+ /* @__PURE__ */ jsxs2(
8055
+ "button",
8056
+ {
8057
+ type: "button",
8058
+ className: "mx-meet__primary mx-meet__primary--small",
8059
+ disabled: busy,
8060
+ onClick: () => {
8061
+ setBusy(true);
8062
+ void act({
8063
+ action: "breakout_open",
8064
+ rooms: assignment.map((identities, index) => ({ name: `Room ${index + 1}`, identities })),
8065
+ allowChoose: mode === "choose",
8066
+ minutes
8067
+ }).then((result) => {
8068
+ setBusy(false);
8069
+ show(result);
8070
+ });
8071
+ },
8072
+ children: [
8073
+ "Open ",
8074
+ rooms,
8075
+ " room",
8076
+ rooms === 1 ? "" : "s"
8077
+ ]
8078
+ }
8079
+ )
8080
+ ] });
8081
+ }
8082
+ function BreakoutRun({ plan }) {
8083
+ const { act, moveTo, isHost, breakoutRoomId, localIdentity } = useCollab();
8084
+ const snapshot = useMeetSnapshot();
8085
+ const now = useNow(plan.endsAt !== null);
8086
+ const remaining = breakoutRemainingMs(plan, now);
8087
+ const [broadcast, setBroadcast] = useState3("");
8088
+ const [notice, show] = useNotice();
8089
+ const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
8090
+ const mine = assignedRoom(plan, localIdentity);
8091
+ const join = async (roomId) => {
8092
+ const said = await act({ action: "breakout_join", roomId });
8093
+ if (!said.ok) {
8094
+ show(said);
8095
+ return;
8096
+ }
8097
+ show(await moveTo(roomId));
8098
+ };
8099
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
8100
+ /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
8101
+ plan.rooms.length,
8102
+ " room",
8103
+ plan.rooms.length === 1 ? "" : "s",
8104
+ " open",
8105
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8106
+ plan.allowChoose ? " \xB7 people choose their room" : ""
8107
+ ] }),
8108
+ /* @__PURE__ */ jsx3("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
8109
+ const here = breakoutRoomId === room.id;
8110
+ const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
8111
+ return /* @__PURE__ */ jsxs2("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
8112
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-head", children: [
8113
+ /* @__PURE__ */ jsx3("strong", { children: room.name }),
8114
+ here ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
8115
+ ] }),
8116
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
8117
+ isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx3("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
8118
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
8119
+ /* @__PURE__ */ jsxs2(
8120
+ "select",
8121
+ {
8122
+ className: "mx-meet__select mx-meet__select--compact",
8123
+ "aria-label": `Move ${nameOf(identity)}`,
8124
+ value: room.id,
8125
+ onChange: (event) => void act({
8126
+ action: "breakout_move",
8127
+ identity,
8128
+ roomId: event.target.value === "" ? null : event.target.value
8129
+ }).then(show),
8130
+ children: [
8131
+ /* @__PURE__ */ jsx3("option", { value: "", children: "Main room" }),
8132
+ plan.rooms.map((option) => /* @__PURE__ */ jsx3("option", { value: option.id, children: option.name }, option.id))
8133
+ ]
8134
+ }
8135
+ )
8136
+ ] }, identity)) }) : null
8137
+ ] }, room.id);
8138
+ }) }),
8139
+ breakoutRoomId !== null ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
8140
+ isHost ? /* @__PURE__ */ jsxs2(
8141
+ "form",
8142
+ {
8143
+ className: "mx-meet__composer-row",
8144
+ onSubmit: (event) => {
8145
+ event.preventDefault();
8146
+ const text3 = broadcast.trim();
8147
+ if (text3.length === 0) return;
8148
+ void act({ action: "breakout_broadcast", text: text3 }).then((result) => {
8149
+ show(result);
8150
+ if (result.ok) setBroadcast("");
8151
+ });
8152
+ },
8153
+ children: [
8154
+ /* @__PURE__ */ jsx3(
8155
+ "input",
8156
+ {
8157
+ className: "mx-meet__input",
8158
+ value: broadcast,
8159
+ maxLength: 500,
8160
+ onChange: (event) => setBroadcast(event.target.value),
8161
+ placeholder: "Message every room",
8162
+ "aria-label": "Message every room"
8163
+ }
8164
+ ),
8165
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: broadcast.trim().length === 0, children: "Send" })
8166
+ ]
8167
+ }
8168
+ ) : null,
8169
+ /* @__PURE__ */ jsx3(Notice, { notice }),
8170
+ isHost ? /* @__PURE__ */ jsx3(
8171
+ "button",
8172
+ {
8173
+ type: "button",
8174
+ className: "mx-meet__primary mx-meet__primary--small",
8175
+ onClick: () => void act({ action: "breakout_close" }).then(show),
8176
+ children: "Bring everyone back"
8177
+ }
8178
+ ) : null
8179
+ ] });
8180
+ }
8181
+ function BreakoutsPanel({ onClose }) {
8182
+ const { collab, isHost } = useCollab();
8183
+ const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
8184
+ return /* @__PURE__ */ jsxs2(PanelShell, { title: "Breakout rooms", onClose, children: [
8185
+ collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
8186
+ plan !== null ? /* @__PURE__ */ jsx3(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ jsx3(BreakoutSetup, {}) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
8187
+ ] });
8188
+ }
8189
+ function BreakoutBanner() {
8190
+ const host = useMeetHost();
8191
+ const { collab, act, moveTo, localIdentity, breakoutRoomId } = useCollab();
8192
+ const plan = collab?.breakout ?? null;
8193
+ const open = plan?.state === "open" ? plan : null;
8194
+ const now = useNow(open?.endsAt != null);
8195
+ const remaining = breakoutRemainingMs(open, now);
8196
+ const assigned = assignedRoom(open, localIdentity);
8197
+ const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
8198
+ const [failure, setFailure] = useState3(null);
8199
+ const expireAsked = useRef3(null);
8200
+ const moveAt = collab?.moveRequest?.at ?? null;
8201
+ useEffect3(() => {
8202
+ const request = host?.store.snapshot().collab.moveRequest ?? null;
8203
+ if (request === null || host === null) return;
8204
+ host.store.patch({ collab: { ...host.store.snapshot().collab, moveRequest: null } });
8205
+ const here = host.store.snapshot().breakoutRoomId;
8206
+ if ((here ?? null) === request.roomId) return;
8207
+ void moveTo(request.roomId).then((result) => setFailure(result.ok ? null : result.message));
8208
+ }, [moveAt, host, moveTo]);
8209
+ useEffect3(() => {
8210
+ if (open === null || remaining === null || remaining > 0) return;
8211
+ if (expireAsked.current === open.id) return;
8212
+ expireAsked.current = open.id;
8213
+ void act({ action: "breakout_expire" });
8214
+ }, [open, remaining, act]);
8215
+ const broadcast = collab?.broadcast ?? null;
8216
+ const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
8217
+ const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
8218
+ if (open === null && failure === null) return null;
8219
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__breakout-banner", role: "status", children: [
8220
+ failure !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-error", children: failure }) : null,
8221
+ room !== null ? /* @__PURE__ */ jsxs2("span", { children: [
8222
+ /* @__PURE__ */ jsx3("strong", { children: room.name }),
8223
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8224
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
8225
+ ] }) : assigned !== null ? /* @__PURE__ */ jsxs2("span", { children: [
8226
+ "You are assigned to ",
8227
+ /* @__PURE__ */ jsx3("strong", { children: assigned.name }),
8228
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8229
+ /* @__PURE__ */ jsx3(
8230
+ "button",
8231
+ {
8232
+ type: "button",
8233
+ className: "mx-meet__primary mx-meet__primary--small",
8234
+ onClick: () => void act({ action: "breakout_join", roomId: assigned.id }).then(async (said) => {
8235
+ const result = said.ok ? await moveTo(assigned.id) : said;
8236
+ setFailure(result.ok ? null : result.message);
8237
+ }),
8238
+ children: "Join"
8239
+ }
8240
+ )
8241
+ ] }) : open?.allowChoose ? /* @__PURE__ */ jsx3("span", { children: "Breakout rooms are open \u2014 pick one under Activities." }) : null,
8242
+ showBroadcast ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__breakout-broadcast", children: [
8243
+ /* @__PURE__ */ jsxs2("strong", { children: [
8244
+ broadcast.by,
8245
+ ":"
8246
+ ] }),
8247
+ " ",
8248
+ broadcast.text,
8249
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setDismissedBroadcast(broadcast.at), children: "Dismiss" })
8250
+ ] }) : null
8251
+ ] });
8252
+ }
8253
+ function useCaptionTranslation(lines) {
8254
+ const host = useMeetHost();
8255
+ const snapshot = useMeetSnapshot();
8256
+ const collab = snapshot?.collab ?? null;
8257
+ const language = collab?.captionLanguage ?? null;
8258
+ const asked = useRef3(/* @__PURE__ */ new Set());
8259
+ const translations = collab?.captionTranslations ?? {};
8260
+ const missing = lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
8261
+ const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
8262
+ const pending = useRef3(missing);
8263
+ pending.current = missing;
8264
+ useEffect3(() => {
8265
+ if (host === null || language === null) return;
8266
+ const batch = pending.current.filter((line) => !asked.current.has(`${language}:${line.id}`)).slice(-20);
8267
+ if (batch.length === 0) return;
8268
+ for (const line of batch) asked.current.add(`${language}:${line.id}`);
8269
+ void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
8270
+ }, [host, language, key]);
8271
+ return { language, translations, error: collab?.captionTranslationError ?? null };
8272
+ }
8273
+ function CaptionLanguageSettings() {
8274
+ const host = useMeetHost();
8275
+ const snapshot = useMeetSnapshot();
8276
+ const collab = snapshot?.collab ?? null;
8277
+ const settings = collab?.settings ?? null;
8278
+ if (host === null || settings === null || !settings.captionTranslationEnabled) return null;
8279
+ const viewer = typeof navigator !== "undefined" && typeof navigator.language === "string" ? navigator.language.slice(0, 2) : null;
8280
+ const preferred = defaultCaptionLanguage(settings, viewer);
8281
+ const current = collab?.captionLanguage ?? "";
8282
+ const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
8283
+ return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
8284
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8285
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
8286
+ /* @__PURE__ */ jsxs2(
8287
+ "select",
8288
+ {
8289
+ className: "mx-meet__select",
8290
+ value: current,
8291
+ onChange: (event) => {
8292
+ const next = event.target.value === "" ? null : event.target.value;
8293
+ host.store.patch({
8294
+ collab: {
8295
+ ...host.store.snapshot().collab,
8296
+ captionLanguage: next,
8297
+ captionTranslations: {},
8298
+ captionTranslationError: null
8299
+ }
8300
+ });
8301
+ },
8302
+ children: [
8303
+ /* @__PURE__ */ jsx3("option", { value: "", children: "Off \u2014 as spoken" }),
8304
+ current === "" ? /* @__PURE__ */ jsxs2("option", { value: preferred, children: [
8305
+ choices.find((c) => c.tag === preferred)?.name ?? preferred,
8306
+ " (yours)"
8307
+ ] }) : null,
8308
+ choices.filter((choice) => current !== "" || choice.tag !== preferred).map((choice) => /* @__PURE__ */ jsx3("option", { value: choice.tag, children: choice.name }, choice.tag))
8309
+ ]
8310
+ }
8311
+ )
8312
+ ] }),
8313
+ collab?.captionTranslationError != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.captionTranslationError }) : null
8314
+ ] });
8315
+ }
8316
+ function useCollabPanelRequest(onRequest) {
8317
+ const host = useMeetHost();
8318
+ const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
8319
+ const callback = useRef3(onRequest);
8320
+ callback.current = onRequest;
8321
+ useEffect3(() => {
8322
+ const request = host?.store.snapshot().collab.panelRequest ?? null;
8323
+ if (request === null || host === null) return;
8324
+ host.store.patch({ collab: { ...host.store.snapshot().collab, panelRequest: null } });
8325
+ callback.current(request.panel);
8326
+ }, [at, host]);
8327
+ }
8328
+
8329
+ // src/react/components.tsx
8330
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
8331
+ function InertNotice({ what }) {
8332
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
8333
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-title", children: [
8334
+ what,
8335
+ " is not ready yet"
8336
+ ] }),
8337
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Calls and meetings need a signed-in identity and an active organization. This will appear as soon as they resolve." })
8338
+ ] });
8339
+ }
8340
+ function Avatar({
8341
+ name,
8342
+ url,
8343
+ size = 40
8344
+ }) {
8345
+ const tint = avatarPaletteIndex(name);
8346
+ if (url != null && url.length > 0) {
8347
+ return /* @__PURE__ */ jsx4(
8348
+ "img",
8349
+ {
8350
+ className: "mx-meet__avatar",
8351
+ src: url,
8352
+ alt: "",
8353
+ width: size,
8354
+ height: size,
8355
+ style: { width: size, height: size }
8356
+ }
8357
+ );
8358
+ }
8359
+ return /* @__PURE__ */ jsx4(
8360
+ "span",
8361
+ {
8362
+ className: "mx-meet__avatar mx-meet__avatar--initials",
8363
+ style: {
8364
+ width: size,
8365
+ height: size,
8366
+ fontSize: Math.round(size * 0.38),
8367
+ background: `var(--mx-meet-avatar-${tint})`
8368
+ },
8369
+ "aria-hidden": "true",
8370
+ children: getInitials(name)
8371
+ }
8372
+ );
8373
+ }
8374
+ function ControlButton({
8375
+ label,
8376
+ active = false,
8377
+ danger = false,
8378
+ onClick,
8379
+ children
8380
+ }) {
8381
+ return /* @__PURE__ */ jsx4(
8382
+ "button",
8383
+ {
8384
+ type: "button",
8385
+ className: [
8386
+ "mx-meet__control",
8387
+ active ? "mx-meet__control--active" : "",
8388
+ danger ? "mx-meet__control--danger" : ""
8389
+ ].filter(Boolean).join(" "),
8390
+ "aria-label": label,
8391
+ title: label,
8392
+ onClick,
8393
+ children
8394
+ }
8395
+ );
8396
+ }
8397
+ function RecordingIndicator() {
8398
+ const { state, label } = useRecording();
8399
+ if (label === null) return null;
8400
+ return /* @__PURE__ */ jsxs3(
8401
+ "span",
8402
+ {
8403
+ className: `mx-meet__recording mx-meet__recording--${state}`,
8404
+ role: "status",
8405
+ "aria-live": "polite",
8406
+ children: [
8407
+ /* @__PURE__ */ jsx4(RecordIcon, { width: 10, height: 10 }),
8408
+ label
8409
+ ]
8410
+ }
8411
+ );
8412
+ }
8413
+ function ConnectionDot({ quality }) {
8414
+ if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
8415
+ return /* @__PURE__ */ jsx4("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx4(WifiLowIcon, { width: 14, height: 14 }) });
8416
+ }
8417
+ function RoleBadge({ role }) {
8418
+ if (role === "host") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Host" });
8419
+ if (role === "cohost") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Co-host" });
8420
+ if (role === "guest") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" });
8421
+ return null;
8422
+ }
8423
+ function ParticipantTile({
6837
8424
  participant,
6838
8425
  featured = false
6839
8426
  }) {
6840
8427
  const host = useMeetHost();
6841
8428
  const snapshot = useMeetSnapshot();
6842
8429
  const queue = useHandQueue();
6843
- const [menu, setMenu] = useState3(false);
8430
+ const [menu, setMenu] = useState4(false);
6844
8431
  const videoRef = useTrack(
6845
8432
  participant.identity,
6846
8433
  participant.screenSharing ? "screen" : "camera"
@@ -6849,7 +8436,7 @@ function ParticipantTile({
6849
8436
  const pinnedHere = snapshot?.pinned === participant.identity;
6850
8437
  const spotlit = snapshot?.spotlight === participant.identity;
6851
8438
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
6852
- return /* @__PURE__ */ jsxs2(
8439
+ return /* @__PURE__ */ jsxs3(
6853
8440
  "div",
6854
8441
  {
6855
8442
  className: [
@@ -6859,7 +8446,7 @@ function ParticipantTile({
6859
8446
  ].filter(Boolean).join(" "),
6860
8447
  "data-identity": participant.identity,
6861
8448
  children: [
6862
- showVideo ? /* @__PURE__ */ jsx3(
8449
+ showVideo ? /* @__PURE__ */ jsx4(
6863
8450
  "video",
6864
8451
  {
6865
8452
  ref: videoRef,
@@ -6868,43 +8455,43 @@ function ParticipantTile({
6868
8455
  playsInline: true,
6869
8456
  muted: participant.isLocal
6870
8457
  }
6871
- ) : /* @__PURE__ */ jsx3("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
6872
- participant.handRaised ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
6873
- /* @__PURE__ */ jsx3(HandIcon, { width: 14, height: 14 }),
8458
+ ) : /* @__PURE__ */ jsx4("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
8459
+ participant.handRaised ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
8460
+ /* @__PURE__ */ jsx4(HandIcon, { width: 14, height: 14 }),
6874
8461
  handPosition > 0 ? handPosition : null
6875
8462
  ] }) : null,
6876
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__tile-bar", children: [
6877
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__tile-name", children: [
6878
- spotlit ? /* @__PURE__ */ jsx3("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx3(SpotlightIcon, { width: 12, height: 12 }) }) : null,
8463
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__tile-bar", children: [
8464
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-name", children: [
8465
+ spotlit ? /* @__PURE__ */ jsx4("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx4(SpotlightIcon, { width: 12, height: 12 }) }) : null,
6879
8466
  participant.displayName,
6880
8467
  participant.isLocal ? " (you)" : "",
6881
- participant.isAgent ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "AI" }) : null,
6882
- /* @__PURE__ */ jsx3(RoleBadge, { role: participant.role })
8468
+ participant.isAgent ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "AI" }) : null,
8469
+ /* @__PURE__ */ jsx4(RoleBadge, { role: participant.role })
6883
8470
  ] }),
6884
- !participant.micEnabled ? /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }) : null,
6885
- /* @__PURE__ */ jsx3(QualityBars, { quality: participant.quality })
8471
+ !participant.micEnabled ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
8472
+ /* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality })
6886
8473
  ] }),
6887
- /* @__PURE__ */ jsxs2("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
6888
- /* @__PURE__ */ jsx3(
8474
+ /* @__PURE__ */ jsxs3("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
8475
+ /* @__PURE__ */ jsx4(
6889
8476
  ControlButton,
6890
8477
  {
6891
8478
  label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
6892
8479
  active: pinnedHere,
6893
8480
  onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
6894
- children: /* @__PURE__ */ jsx3(PinIcon, { width: 16, height: 16 })
8481
+ children: /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 })
6895
8482
  }
6896
8483
  ),
6897
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
6898
- /* @__PURE__ */ jsx3(
8484
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8485
+ /* @__PURE__ */ jsx4(
6899
8486
  ControlButton,
6900
8487
  {
6901
8488
  label: `More for ${participant.displayName}`,
6902
8489
  active: menu,
6903
8490
  onClick: () => setMenu(!menu),
6904
- children: /* @__PURE__ */ jsx3(MoreIcon, { width: 16, height: 16 })
8491
+ children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
6905
8492
  }
6906
8493
  ),
6907
- menu ? /* @__PURE__ */ jsx3(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
8494
+ menu ? /* @__PURE__ */ jsx4(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
6908
8495
  ] })
6909
8496
  ] })
6910
8497
  ]
@@ -6920,28 +8507,28 @@ function QualityBars({ quality }) {
6920
8507
  if (quality === "unknown") return null;
6921
8508
  const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
6922
8509
  const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
6923
- return /* @__PURE__ */ jsx3("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ jsx3(SignalIcon, { bars, width: 14, height: 14 }) });
8510
+ return /* @__PURE__ */ jsx4("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ jsx4(SignalIcon, { bars, width: 14, height: 14 }) });
6924
8511
  }
6925
8512
  function Stage({ pageSize }) {
6926
8513
  const stage = useStage(pageSize);
6927
8514
  const columns = gridColumns(stage.tiles.length);
6928
8515
  if (stage.feature === null && stage.tiles.length === 0) {
6929
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
6930
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
6931
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
8516
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
8517
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
8518
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
6932
8519
  ] });
6933
8520
  }
6934
- return /* @__PURE__ */ jsxs2("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
6935
- stage.feature !== null ? /* @__PURE__ */ jsx3(ParticipantTile, { participant: stage.feature, featured: true }) : null,
6936
- /* @__PURE__ */ jsx3(
8521
+ return /* @__PURE__ */ jsxs3("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
8522
+ stage.feature !== null ? /* @__PURE__ */ jsx4(ParticipantTile, { participant: stage.feature, featured: true }) : null,
8523
+ /* @__PURE__ */ jsx4(
6937
8524
  "div",
6938
8525
  {
6939
8526
  className: "mx-meet__grid",
6940
8527
  style: { "--mx-meet-columns": columns },
6941
- children: stage.tiles.map((participant) => /* @__PURE__ */ jsx3(ParticipantTile, { participant }, participant.identity))
8528
+ children: stage.tiles.map((participant) => /* @__PURE__ */ jsx4(ParticipantTile, { participant }, participant.identity))
6942
8529
  }
6943
8530
  ),
6944
- stage.overflow > 0 ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__overflow", children: [
8531
+ stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
6945
8532
  "+",
6946
8533
  stage.overflow,
6947
8534
  " more ",
@@ -6954,20 +8541,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
6954
8541
  function ControlBar({ onLeave }) {
6955
8542
  const room = useRoom();
6956
8543
  const recording = useRecording();
6957
- const [panel, setPanel] = useState3("none");
6958
- const [chatTo, setChatTo] = useState3(null);
6959
- const [popover, setPopover] = useState3("none");
6960
- const [shortcuts, setShortcuts] = useState3(false);
8544
+ const [panel, setPanel] = useState4("none");
8545
+ const [chatTo, setChatTo] = useState4(null);
8546
+ const [popover, setPopover] = useState4("none");
8547
+ const [shortcuts, setShortcuts] = useState4(false);
6961
8548
  const snapshot = useMeetSnapshot();
6962
8549
  const lobby = useLobby();
6963
8550
  const controls = useHostControls();
6964
8551
  const queue = useHandQueue();
6965
8552
  const micUnavailable = useLocalMedia().microphone.unavailable;
6966
8553
  const unread = useUnreadChat(panel === "chat");
8554
+ const [whiteboard, setWhiteboard] = useState4(false);
6967
8555
  const toggle = (next) => setPanel(panel === next ? "none" : next);
8556
+ const openActivity = (activity) => {
8557
+ if (activity === "whiteboard") setWhiteboard(true);
8558
+ else setPanel(activity);
8559
+ };
8560
+ useCollabPanelRequest((activity) => {
8561
+ if (!controls.isHost) openActivity(activity);
8562
+ });
6968
8563
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
6969
8564
  const meetStore = useMeetHost()?.store ?? null;
6970
- useEffect3(() => {
8565
+ useEffect4(() => {
6971
8566
  const request = meetStore?.snapshot().privateChatRequest ?? null;
6972
8567
  if (request === null) return;
6973
8568
  setChatTo(request.to);
@@ -6983,11 +8578,11 @@ function ControlBar({ onLeave }) {
6983
8578
  help: () => setShortcuts(true)
6984
8579
  });
6985
8580
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
6986
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
6987
- /* @__PURE__ */ jsx3(MeetingOverlays, {}),
6988
- shortcuts ? /* @__PURE__ */ jsx3(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
6989
- panel === "chat" ? /* @__PURE__ */ jsx3(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
6990
- panel === "people" ? /* @__PURE__ */ jsx3(
8581
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
8582
+ /* @__PURE__ */ jsx4(MeetingOverlays, {}),
8583
+ shortcuts ? /* @__PURE__ */ jsx4(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
8584
+ panel === "chat" ? /* @__PURE__ */ jsx4(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
8585
+ panel === "people" ? /* @__PURE__ */ jsx4(
6991
8586
  PeoplePanel,
6992
8587
  {
6993
8588
  onClose: () => setPanel("none"),
@@ -6997,48 +8592,53 @@ function ControlBar({ onLeave }) {
6997
8592
  }
6998
8593
  }
6999
8594
  ) : null,
7000
- panel === "ai" ? /* @__PURE__ */ jsx3(AiPanel, { onClose: () => setPanel("none") }) : null,
7001
- panel === "settings" ? /* @__PURE__ */ jsx3(SettingsPanel, { onClose: () => setPanel("none") }) : null,
7002
- controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx3(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
7003
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__controls", children: [
7004
- /* @__PURE__ */ jsx3(
8595
+ panel === "ai" ? /* @__PURE__ */ jsx4(AiPanel, { onClose: () => setPanel("none") }) : null,
8596
+ panel === "settings" ? /* @__PURE__ */ jsx4(SettingsPanel, { onClose: () => setPanel("none") }) : null,
8597
+ panel === "polls" ? /* @__PURE__ */ jsx4(PollsPanel, { onClose: () => setPanel("none") }) : null,
8598
+ panel === "qa" ? /* @__PURE__ */ jsx4(QaPanel, { onClose: () => setPanel("none") }) : null,
8599
+ panel === "breakouts" ? /* @__PURE__ */ jsx4(BreakoutsPanel, { onClose: () => setPanel("none") }) : null,
8600
+ whiteboard ? /* @__PURE__ */ jsx4(WhiteboardPanel, { onClose: () => setWhiteboard(false) }) : null,
8601
+ /* @__PURE__ */ jsx4(BreakoutBanner, {}),
8602
+ controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx4(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
8603
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__controls", children: [
8604
+ /* @__PURE__ */ jsx4(
7005
8605
  ControlButton,
7006
8606
  {
7007
8607
  label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
7008
8608
  active: room.local?.micEnabled === true,
7009
8609
  onClick: () => void room.toggleMicrophone(),
7010
- children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx3(MicIcon, {}) : /* @__PURE__ */ jsx3(MicOffIcon, {})
8610
+ children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx4(MicIcon, {}) : /* @__PURE__ */ jsx4(MicOffIcon, {})
7011
8611
  }
7012
8612
  ),
7013
- /* @__PURE__ */ jsx3(
8613
+ /* @__PURE__ */ jsx4(
7014
8614
  ControlButton,
7015
8615
  {
7016
8616
  label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
7017
8617
  active: room.local?.cameraEnabled === true,
7018
8618
  onClick: () => void room.toggleCamera(),
7019
- children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx3(CameraIcon, {}) : /* @__PURE__ */ jsx3(CameraOffIcon, {})
8619
+ children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx4(CameraIcon, {}) : /* @__PURE__ */ jsx4(CameraOffIcon, {})
7020
8620
  }
7021
8621
  ),
7022
- /* @__PURE__ */ jsx3(
8622
+ /* @__PURE__ */ jsx4(
7023
8623
  ControlButton,
7024
8624
  {
7025
8625
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
7026
8626
  active: room.local?.screenSharing === true,
7027
8627
  onClick: () => void room.toggleScreenShare(),
7028
- children: /* @__PURE__ */ jsx3(ScreenShareIcon, {})
8628
+ children: /* @__PURE__ */ jsx4(ScreenShareIcon, {})
7029
8629
  }
7030
8630
  ),
7031
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7032
- /* @__PURE__ */ jsx3(
8631
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8632
+ /* @__PURE__ */ jsx4(
7033
8633
  ControlButton,
7034
8634
  {
7035
8635
  label: "Send a reaction",
7036
8636
  active: popover === "reactions",
7037
8637
  onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
7038
- children: /* @__PURE__ */ jsx3(SmileIcon, {})
8638
+ children: /* @__PURE__ */ jsx4(SmileIcon, {})
7039
8639
  }
7040
8640
  ),
7041
- popover === "reactions" ? /* @__PURE__ */ jsx3(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsx3("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ jsx3(
8641
+ popover === "reactions" ? /* @__PURE__ */ jsx4(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsx4("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ jsx4(
7042
8642
  "button",
7043
8643
  {
7044
8644
  type: "button",
@@ -7050,46 +8650,53 @@ function ControlBar({ onLeave }) {
7050
8650
  emoji
7051
8651
  )) }) }) : null
7052
8652
  ] }),
7053
- /* @__PURE__ */ jsx3(
8653
+ /* @__PURE__ */ jsx4(
7054
8654
  ControlButton,
7055
8655
  {
7056
8656
  label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
7057
8657
  active: room.local?.handRaised === true,
7058
8658
  onClick: () => void room.toggleHand(),
7059
- children: /* @__PURE__ */ jsx3(HandIcon, {})
8659
+ children: /* @__PURE__ */ jsx4(HandIcon, {})
7060
8660
  }
7061
8661
  ),
7062
- /* @__PURE__ */ jsxs2(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
7063
- /* @__PURE__ */ jsx3(ChatIcon, {}),
7064
- unread > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8662
+ /* @__PURE__ */ jsxs3(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
8663
+ /* @__PURE__ */ jsx4(ChatIcon, {}),
8664
+ unread > 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7065
8665
  ] }),
7066
- /* @__PURE__ */ jsxs2(
8666
+ /* @__PURE__ */ jsxs3(
7067
8667
  ControlButton,
7068
8668
  {
7069
8669
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
7070
8670
  active: panel === "people",
7071
8671
  onClick: () => toggle("people"),
7072
8672
  children: [
7073
- /* @__PURE__ */ jsx3(PeopleIcon, {}),
7074
- lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8673
+ /* @__PURE__ */ jsx4(PeopleIcon, {}),
8674
+ lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7075
8675
  ]
7076
8676
  }
7077
8677
  ),
7078
- /* @__PURE__ */ jsx3(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
7079
- recording.canStart ? /* @__PURE__ */ jsx3(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx3(RecordIcon, {}) }) : null,
7080
- recording.canStop ? /* @__PURE__ */ jsx3(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx3(RecordIcon, {}) }) : null,
7081
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7082
- /* @__PURE__ */ jsx3(
8678
+ /* @__PURE__ */ jsx4(
8679
+ ActivitiesControl,
8680
+ {
8681
+ active: whiteboard ? "whiteboard" : panel === "polls" || panel === "qa" || panel === "breakouts" ? panel : null,
8682
+ onOpen: openActivity
8683
+ }
8684
+ ),
8685
+ /* @__PURE__ */ jsx4(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
8686
+ recording.canStart ? /* @__PURE__ */ jsx4(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx4(RecordIcon, {}) }) : null,
8687
+ recording.canStop ? /* @__PURE__ */ jsx4(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx4(RecordIcon, {}) }) : null,
8688
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8689
+ /* @__PURE__ */ jsx4(
7083
8690
  ControlButton,
7084
8691
  {
7085
8692
  label: "More options",
7086
8693
  active: popover === "more" || panel === "settings",
7087
8694
  onClick: () => setPopover(popover === "more" ? "none" : "more"),
7088
- children: /* @__PURE__ */ jsx3(MoreIcon, {})
8695
+ children: /* @__PURE__ */ jsx4(MoreIcon, {})
7089
8696
  }
7090
8697
  ),
7091
- popover === "more" ? /* @__PURE__ */ jsx3(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu", role: "menu", children: [
7092
- /* @__PURE__ */ jsxs2(
8698
+ popover === "more" ? /* @__PURE__ */ jsx4(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
8699
+ /* @__PURE__ */ jsxs3(
7093
8700
  MenuItem,
7094
8701
  {
7095
8702
  onSelect: () => {
@@ -7097,12 +8704,12 @@ function ControlBar({ onLeave }) {
7097
8704
  setPanel("settings");
7098
8705
  },
7099
8706
  children: [
7100
- /* @__PURE__ */ jsx3(SettingsIcon, { width: 16, height: 16 }),
7101
- " Audio, video and effects"
8707
+ /* @__PURE__ */ jsx4(SettingsIcon, { width: 16, height: 16 }),
8708
+ " Settings"
7102
8709
  ]
7103
8710
  }
7104
8711
  ),
7105
- /* @__PURE__ */ jsxs2(
8712
+ /* @__PURE__ */ jsxs3(
7106
8713
  MenuItem,
7107
8714
  {
7108
8715
  onSelect: () => {
@@ -7110,14 +8717,14 @@ function ControlBar({ onLeave }) {
7110
8717
  setShortcuts(true);
7111
8718
  },
7112
8719
  children: [
7113
- /* @__PURE__ */ jsx3(KeyboardIcon, { width: 16, height: 16 }),
8720
+ /* @__PURE__ */ jsx4(KeyboardIcon, { width: 16, height: 16 }),
7114
8721
  " Keyboard shortcuts"
7115
8722
  ]
7116
8723
  }
7117
8724
  ),
7118
- controls.isHost ? /* @__PURE__ */ jsxs2(Fragment, { children: [
7119
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu-sep", role: "separator" }),
7120
- /* @__PURE__ */ jsxs2(
8725
+ controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
8726
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
8727
+ /* @__PURE__ */ jsxs3(
7121
8728
  MenuItem,
7122
8729
  {
7123
8730
  onSelect: () => {
@@ -7125,12 +8732,12 @@ function ControlBar({ onLeave }) {
7125
8732
  void controls.run({ action: "mute_all" });
7126
8733
  },
7127
8734
  children: [
7128
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 16, height: 16 }),
8735
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
7129
8736
  " Mute everyone"
7130
8737
  ]
7131
8738
  }
7132
8739
  ),
7133
- /* @__PURE__ */ jsxs2(
8740
+ /* @__PURE__ */ jsxs3(
7134
8741
  MenuItem,
7135
8742
  {
7136
8743
  onSelect: () => {
@@ -7138,12 +8745,12 @@ function ControlBar({ onLeave }) {
7138
8745
  void controls.run({ action: "ask_all_unmute" });
7139
8746
  },
7140
8747
  children: [
7141
- /* @__PURE__ */ jsx3(MicIcon, { width: 16, height: 16 }),
8748
+ /* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
7142
8749
  " Ask everyone to unmute"
7143
8750
  ]
7144
8751
  }
7145
8752
  ),
7146
- queue.length > 0 ? /* @__PURE__ */ jsxs2(
8753
+ queue.length > 0 ? /* @__PURE__ */ jsxs3(
7147
8754
  MenuItem,
7148
8755
  {
7149
8756
  onSelect: () => {
@@ -7151,14 +8758,14 @@ function ControlBar({ onLeave }) {
7151
8758
  void controls.run({ action: "lower_all_hands" });
7152
8759
  },
7153
8760
  children: [
7154
- /* @__PURE__ */ jsx3(HandIcon, { width: 16, height: 16 }),
8761
+ /* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
7155
8762
  " Lower all hands (",
7156
8763
  queue.length,
7157
8764
  ")"
7158
8765
  ]
7159
8766
  }
7160
8767
  ) : null,
7161
- hasSpotlight ? /* @__PURE__ */ jsxs2(
8768
+ hasSpotlight ? /* @__PURE__ */ jsxs3(
7162
8769
  MenuItem,
7163
8770
  {
7164
8771
  onSelect: () => {
@@ -7166,7 +8773,7 @@ function ControlBar({ onLeave }) {
7166
8773
  void controls.run({ action: "spotlight", identity: null });
7167
8774
  },
7168
8775
  children: [
7169
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
8776
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7170
8777
  " Remove spotlight"
7171
8778
  ]
7172
8779
  }
@@ -7174,7 +8781,7 @@ function ControlBar({ onLeave }) {
7174
8781
  ] }) : null
7175
8782
  ] }) }) : null
7176
8783
  ] }),
7177
- /* @__PURE__ */ jsx3(
8784
+ /* @__PURE__ */ jsx4(
7178
8785
  ControlButton,
7179
8786
  {
7180
8787
  label: "Leave",
@@ -7183,7 +8790,7 @@ function ControlBar({ onLeave }) {
7183
8790
  void room.leave();
7184
8791
  onLeave?.();
7185
8792
  },
7186
- children: /* @__PURE__ */ jsx3(PhoneOffIcon, {})
8793
+ children: /* @__PURE__ */ jsx4(PhoneOffIcon, {})
7187
8794
  }
7188
8795
  )
7189
8796
  ] })
@@ -7193,13 +8800,13 @@ function useUnreadChat(open) {
7193
8800
  const snapshot = useMeetSnapshot();
7194
8801
  const chat = snapshot?.chat ?? [];
7195
8802
  const local = snapshot?.localIdentity ?? null;
7196
- const [seen, setSeen] = useState3(0);
7197
- useEffect3(() => {
8803
+ const [seen, setSeen] = useState4(0);
8804
+ useEffect4(() => {
7198
8805
  if (open) setSeen(chat.length);
7199
8806
  }, [open, chat.length]);
7200
8807
  const loaded = snapshot?.chatLoaded === true;
7201
- const [baseline, setBaseline] = useState3(null);
7202
- useEffect3(() => {
8808
+ const [baseline, setBaseline] = useState4(null);
8809
+ useEffect4(() => {
7203
8810
  if (loaded && baseline === null) setBaseline(chat.length);
7204
8811
  }, [loaded, baseline, chat.length]);
7205
8812
  if (open) return 0;
@@ -7212,8 +8819,8 @@ function Popover({
7212
8819
  children,
7213
8820
  placement = "up"
7214
8821
  }) {
7215
- const ref = useRef3(null);
7216
- const [style, setStyle] = useState3({
8822
+ const ref = useRef4(null);
8823
+ const [style, setStyle] = useState4({
7217
8824
  position: "fixed",
7218
8825
  top: 0,
7219
8826
  left: 0,
@@ -7264,7 +8871,7 @@ function Popover({
7264
8871
  window.removeEventListener("scroll", place, true);
7265
8872
  };
7266
8873
  }, [placement]);
7267
- useEffect3(() => {
8874
+ useEffect4(() => {
7268
8875
  const onKey = (event) => {
7269
8876
  if (event.key === "Escape") onClose();
7270
8877
  };
@@ -7279,14 +8886,14 @@ function Popover({
7279
8886
  window.removeEventListener("pointerdown", onPointer);
7280
8887
  };
7281
8888
  }, [onClose]);
7282
- return /* @__PURE__ */ jsx3("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
8889
+ return /* @__PURE__ */ jsx4("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
7283
8890
  }
7284
8891
  function MenuItem({
7285
8892
  onSelect,
7286
8893
  danger = false,
7287
8894
  children
7288
8895
  }) {
7289
- return /* @__PURE__ */ jsx3(
8896
+ return /* @__PURE__ */ jsx4(
7290
8897
  "button",
7291
8898
  {
7292
8899
  type: "button",
@@ -7298,28 +8905,28 @@ function MenuItem({
7298
8905
  );
7299
8906
  }
7300
8907
  function Toast({ text: text3, failed, onDone }) {
7301
- useEffect3(() => {
8908
+ useEffect4(() => {
7302
8909
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
7303
8910
  return () => clearTimeout(timer);
7304
8911
  }, [text3, failed, onDone]);
7305
- return /* @__PURE__ */ jsxs2("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
7306
- /* @__PURE__ */ jsx3("span", { children: text3 }),
7307
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) })
8912
+ return /* @__PURE__ */ jsxs3("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
8913
+ /* @__PURE__ */ jsx4("span", { children: text3 }),
8914
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 14, height: 14 }) })
7308
8915
  ] });
7309
8916
  }
7310
8917
  function MeetingOverlays() {
7311
8918
  const reactions = useReactions();
7312
8919
  const { notice, dismiss } = useModerationNotice();
7313
8920
  const room = useRoom();
7314
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
7315
- /* @__PURE__ */ jsx3(ReactionOverlay, { reactions }),
8921
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
8922
+ /* @__PURE__ */ jsx4(ReactionOverlay, { reactions }),
7316
8923
  notice !== null && notice.kind !== "removed" ? (
7317
8924
  // A host's request ("the host is asking you to unmute"), not an error:
7318
8925
  // an assertive status, so it is announced at once without being filed
7319
8926
  // as a failure (design-system error-box census).
7320
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
7321
- /* @__PURE__ */ jsx3("span", { children: notice.text }),
7322
- notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx3(
8927
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
8928
+ /* @__PURE__ */ jsx4("span", { children: notice.text }),
8929
+ notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx4(
7323
8930
  "button",
7324
8931
  {
7325
8932
  type: "button",
@@ -7331,20 +8938,20 @@ function MeetingOverlays() {
7331
8938
  children: "Unmute"
7332
8939
  }
7333
8940
  ) : null,
7334
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) })
8941
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 14, height: 14 }) })
7335
8942
  ] })
7336
8943
  ) : null
7337
8944
  ] });
7338
8945
  }
7339
8946
  function ShortcutsSheet({ onClose }) {
7340
- useEffect3(() => {
8947
+ useEffect4(() => {
7341
8948
  const onKey = (event) => {
7342
8949
  if (event.key === "Escape") onClose();
7343
8950
  };
7344
8951
  window.addEventListener("keydown", onKey);
7345
8952
  return () => window.removeEventListener("keydown", onKey);
7346
8953
  }, [onClose]);
7347
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs2(
8954
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
7348
8955
  "div",
7349
8956
  {
7350
8957
  className: "mx-meet__sheet",
@@ -7352,13 +8959,13 @@ function ShortcutsSheet({ onClose }) {
7352
8959
  "aria-label": "Keyboard shortcuts",
7353
8960
  onClick: (event) => event.stopPropagation(),
7354
8961
  children: [
7355
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__panel-head", children: [
7356
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
7357
- /* @__PURE__ */ jsx3(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
8962
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
8963
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
8964
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }) })
7358
8965
  ] }),
7359
- /* @__PURE__ */ jsx3("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__shortcut", children: [
7360
- /* @__PURE__ */ jsx3("dt", { children: shortcut.label }),
7361
- /* @__PURE__ */ jsx3("dd", { children: /* @__PURE__ */ jsx3("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
8966
+ /* @__PURE__ */ jsx4("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__shortcut", children: [
8967
+ /* @__PURE__ */ jsx4("dt", { children: shortcut.label }),
8968
+ /* @__PURE__ */ jsx4("dd", { children: /* @__PURE__ */ jsx4("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
7362
8969
  ] }, shortcut.id)) })
7363
8970
  ]
7364
8971
  }
@@ -7368,19 +8975,32 @@ function AiControl({ active, onToggle }) {
7368
8975
  const snapshot = useMeetSnapshot();
7369
8976
  const meeting = snapshot?.meeting ?? null;
7370
8977
  if (meeting === null || !meeting.aiEnabled) return null;
7371
- return /* @__PURE__ */ jsx3(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ jsx3(SparklesIcon, {}) });
8978
+ return /* @__PURE__ */ jsx4(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ jsx4(SparklesIcon, {}) });
7372
8979
  }
7373
8980
  function PanelShell({
7374
8981
  title,
7375
8982
  onClose,
7376
8983
  children
7377
8984
  }) {
7378
- return /* @__PURE__ */ jsxs2("aside", { className: "mx-meet__panel", "aria-label": title, children: [
7379
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__panel-head", children: [
7380
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__panel-title", children: title }),
7381
- /* @__PURE__ */ jsx3(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
8985
+ const ref = useRef4(null);
8986
+ useLayoutEffect(() => {
8987
+ const panel = ref.current;
8988
+ const root = panel?.closest(".mx-meet");
8989
+ const header = root?.querySelector(":scope > .mx-meet__header") ?? null;
8990
+ if (!panel || !header) return void 0;
8991
+ const place = () => panel.style.setProperty("--mx-meet-panel-top", `${header.offsetHeight}px`);
8992
+ place();
8993
+ if (typeof ResizeObserver === "undefined") return void 0;
8994
+ const observer = new ResizeObserver(place);
8995
+ observer.observe(header);
8996
+ return () => observer.disconnect();
8997
+ }, []);
8998
+ return /* @__PURE__ */ jsxs3("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
8999
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
9000
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__panel-title", children: title }),
9001
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }) })
7382
9002
  ] }),
7383
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__panel-body", children })
9003
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__panel-body", children })
7384
9004
  ] });
7385
9005
  }
7386
9006
  function ChatPanel({
@@ -7390,17 +9010,17 @@ function ChatPanel({
7390
9010
  }) {
7391
9011
  const snapshot = useMeetSnapshot();
7392
9012
  const room = useRoom();
7393
- const [draft, setDraft] = useState3("");
7394
- const [recipient, setRecipient] = useState3(to);
7395
- const listRef = useRef3(null);
9013
+ const [draft, setDraft] = useState4("");
9014
+ const [recipient, setRecipient] = useState4(to);
9015
+ const listRef = useRef4(null);
7396
9016
  const messages = snapshot?.chat ?? [];
7397
9017
  const local = snapshot?.localIdentity ?? null;
7398
9018
  const people = (snapshot?.participants ?? []).filter(
7399
9019
  (participant) => !participant.isLocal && !participant.isAgent
7400
9020
  );
7401
9021
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
7402
- useEffect3(() => setRecipient(to), [to]);
7403
- useEffect3(() => {
9022
+ useEffect4(() => setRecipient(to), [to]);
9023
+ useEffect4(() => {
7404
9024
  const list = listRef.current;
7405
9025
  if (list !== null) list.scrollTop = list.scrollHeight;
7406
9026
  }, [messages.length]);
@@ -7408,13 +9028,13 @@ function ChatPanel({
7408
9028
  setRecipient(next);
7409
9029
  onTo?.(next);
7410
9030
  };
7411
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Chat", onClose, children: [
7412
- /* @__PURE__ */ jsxs2("ul", { className: "mx-meet__chat", ref: listRef, children: [
7413
- snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx3("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
7414
- snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx3("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx3("li", { className: "mx-meet__panel-note", children: "No messages yet. Messages to everyone stay with the meeting, so people who join later see them." }) : null,
7415
- messages.map((message) => /* @__PURE__ */ jsx3(ChatLine, { message, local, people }, message.id))
9031
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Chat", onClose, children: [
9032
+ /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__chat", ref: listRef, children: [
9033
+ snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
9034
+ snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: "No messages yet. Messages to everyone stay with the meeting, so people who join later see them." }) : null,
9035
+ messages.map((message) => /* @__PURE__ */ jsx4(ChatLine, { message, local, people }, message.id))
7416
9036
  ] }),
7417
- /* @__PURE__ */ jsxs2(
9037
+ /* @__PURE__ */ jsxs3(
7418
9038
  "form",
7419
9039
  {
7420
9040
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -7427,7 +9047,7 @@ function ChatPanel({
7427
9047
  else void room.sendPrivateChat(recipient, text3);
7428
9048
  },
7429
9049
  children: [
7430
- people.length > 0 ? /* @__PURE__ */ jsxs2(
9050
+ people.length > 0 ? /* @__PURE__ */ jsxs3(
7431
9051
  "select",
7432
9052
  {
7433
9053
  className: "mx-meet__select mx-meet__select--compact",
@@ -7435,16 +9055,16 @@ function ChatPanel({
7435
9055
  value: recipient ?? "",
7436
9056
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
7437
9057
  children: [
7438
- /* @__PURE__ */ jsx3("option", { value: "", children: "Everyone" }),
7439
- people.map((participant) => /* @__PURE__ */ jsxs2("option", { value: participant.identity, children: [
9058
+ /* @__PURE__ */ jsx4("option", { value: "", children: "Everyone" }),
9059
+ people.map((participant) => /* @__PURE__ */ jsxs3("option", { value: participant.identity, children: [
7440
9060
  participant.displayName,
7441
9061
  " (private)"
7442
9062
  ] }, participant.identity))
7443
9063
  ]
7444
9064
  }
7445
9065
  ) : null,
7446
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7447
- /* @__PURE__ */ jsx3(
9066
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
9067
+ /* @__PURE__ */ jsx4(
7448
9068
  "input",
7449
9069
  {
7450
9070
  className: "mx-meet__input",
@@ -7455,9 +9075,9 @@ function ChatPanel({
7455
9075
  maxLength: 4e3
7456
9076
  }
7457
9077
  ),
7458
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
9078
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
7459
9079
  ] }),
7460
- recipientName !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
9080
+ recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
7461
9081
  "Only ",
7462
9082
  recipientName,
7463
9083
  " sees this. Private messages are not saved."
@@ -7475,7 +9095,7 @@ function ChatLine({
7475
9095
  const mine = message.identity === local;
7476
9096
  const privateTo = message.to ?? null;
7477
9097
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
7478
- return /* @__PURE__ */ jsxs2(
9098
+ return /* @__PURE__ */ jsxs3(
7479
9099
  "li",
7480
9100
  {
7481
9101
  className: [
@@ -7484,17 +9104,17 @@ function ChatLine({
7484
9104
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
7485
9105
  ].filter(Boolean).join(" "),
7486
9106
  children: [
7487
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
7488
- /* @__PURE__ */ jsx3("strong", { children: mine ? "You" : message.displayName }),
7489
- counterpart !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-private", children: [
9107
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
9108
+ /* @__PURE__ */ jsx4("strong", { children: mine ? "You" : message.displayName }),
9109
+ counterpart !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-private", children: [
7490
9110
  "to ",
7491
9111
  counterpart,
7492
9112
  " \xB7 private"
7493
9113
  ] }) : null,
7494
- /* @__PURE__ */ jsx3("time", { dateTime: message.at, children: clockOf(message.at) })
9114
+ /* @__PURE__ */ jsx4("time", { dateTime: message.at, children: clockOf(message.at) })
7495
9115
  ] }),
7496
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-text", children: message.text }),
7497
- message.failed !== void 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-pending", children: message.id.startsWith("pending-") ? "Sending\u2026" : "Not saved \u2014 people who join later will not see this" }) : null
9116
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-text", children: message.text }),
9117
+ message.failed !== void 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-pending", children: message.id.startsWith("pending-") ? "Sending\u2026" : "Not saved \u2014 people who join later will not see this" }) : null
7498
9118
  ]
7499
9119
  }
7500
9120
  );
@@ -7506,22 +9126,22 @@ function PeoplePanel({
7506
9126
  const snapshot = useMeetSnapshot();
7507
9127
  const controls = useHostControls();
7508
9128
  const queue = useHandQueue();
7509
- const [query, setQuery] = useState3("");
7510
- const [menuFor, setMenuFor] = useState3(null);
9129
+ const [query, setQuery] = useState4("");
9130
+ const [menuFor, setMenuFor] = useState4(null);
7511
9131
  const myRole = useRole();
7512
9132
  const local = snapshot?.localIdentity ?? null;
7513
9133
  const everyone = snapshot?.participants ?? [];
7514
9134
  const needle = query.trim().toLowerCase();
7515
9135
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
7516
- return /* @__PURE__ */ jsxs2(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
7517
- /* @__PURE__ */ jsx3(LobbyPanel, {}),
7518
- queue.length > 0 ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
7519
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__section-head", children: [
7520
- /* @__PURE__ */ jsxs2("h3", { className: "mx-meet__section-title", children: [
9136
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
9137
+ /* @__PURE__ */ jsx4(LobbyPanel, {}),
9138
+ queue.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
9139
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__section-head", children: [
9140
+ /* @__PURE__ */ jsxs3("h3", { className: "mx-meet__section-title", children: [
7521
9141
  "Raised hands \xB7 ",
7522
9142
  queue.length
7523
9143
  ] }),
7524
- controls.isHost ? /* @__PURE__ */ jsx3(
9144
+ controls.isHost ? /* @__PURE__ */ jsx4(
7525
9145
  "button",
7526
9146
  {
7527
9147
  type: "button",
@@ -7531,13 +9151,13 @@ function PeoplePanel({
7531
9151
  }
7532
9152
  ) : null
7533
9153
  ] }),
7534
- /* @__PURE__ */ jsx3("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
7535
- /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
7536
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
9154
+ /* @__PURE__ */ jsx4("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
9155
+ /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
9156
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
7537
9157
  participant.displayName,
7538
- participant.identity === local ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__you", children: " (you)" }) : null
9158
+ participant.identity === local ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__you", children: " (you)" }) : null
7539
9159
  ] }),
7540
- controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx3(
9160
+ controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx4(
7541
9161
  "button",
7542
9162
  {
7543
9163
  type: "button",
@@ -7548,27 +9168,27 @@ function PeoplePanel({
7548
9168
  ) : null
7549
9169
  ] }, participant.identity)) })
7550
9170
  ] }) : null,
7551
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__bulk", children: [
7552
- /* @__PURE__ */ jsxs2("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
7553
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }),
9171
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__bulk", children: [
9172
+ /* @__PURE__ */ jsxs3("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
9173
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }),
7554
9174
  " Mute all"
7555
9175
  ] }),
7556
- /* @__PURE__ */ jsxs2(
9176
+ /* @__PURE__ */ jsxs3(
7557
9177
  "button",
7558
9178
  {
7559
9179
  type: "button",
7560
9180
  className: "mx-meet__chip",
7561
9181
  onClick: () => void controls.run({ action: "ask_all_unmute" }),
7562
9182
  children: [
7563
- /* @__PURE__ */ jsx3(MicIcon, { width: 14, height: 14 }),
9183
+ /* @__PURE__ */ jsx4(MicIcon, { width: 14, height: 14 }),
7564
9184
  " Ask all to unmute"
7565
9185
  ]
7566
9186
  }
7567
9187
  )
7568
9188
  ] }) : null,
7569
- everyone.length > 4 ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__search", children: [
7570
- /* @__PURE__ */ jsx3(SearchIcon, { width: 16, height: 16 }),
7571
- /* @__PURE__ */ jsx3(
9189
+ everyone.length > 4 ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__search", children: [
9190
+ /* @__PURE__ */ jsx4(SearchIcon, { width: 16, height: 16 }),
9191
+ /* @__PURE__ */ jsx4(
7572
9192
  "input",
7573
9193
  {
7574
9194
  className: "mx-meet__input mx-meet__input--bare",
@@ -7579,31 +9199,31 @@ function PeoplePanel({
7579
9199
  }
7580
9200
  )
7581
9201
  ] }) : null,
7582
- controls.notice !== null ? /* @__PURE__ */ jsx3("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
7583
- /* @__PURE__ */ jsxs2("ul", { className: "mx-meet__people", children: [
7584
- shown.map((participant) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
7585
- /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
7586
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
9202
+ controls.notice !== null ? /* @__PURE__ */ jsx4("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
9203
+ /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__people", children: [
9204
+ shown.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
9205
+ /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
9206
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
7587
9207
  participant.displayName,
7588
- participant.identity === local ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__you", children: " (you)" }) : null,
7589
- /* @__PURE__ */ jsx3(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
7590
- isNoteTaker(participant) ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
7591
- snapshot?.spotlight === participant.identity ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
9208
+ participant.identity === local ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__you", children: " (you)" }) : null,
9209
+ /* @__PURE__ */ jsx4(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
9210
+ isNoteTaker(participant) ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
9211
+ snapshot?.spotlight === participant.identity ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
7592
9212
  ] }),
7593
- participant.handRaised ? /* @__PURE__ */ jsx3(HandIcon, { width: 14, height: 14 }) : null,
7594
- !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }) : null,
7595
- /* @__PURE__ */ jsx3(QualityBars, { quality: participant.quality }),
7596
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7597
- /* @__PURE__ */ jsx3(
9213
+ participant.handRaised ? /* @__PURE__ */ jsx4(HandIcon, { width: 14, height: 14 }) : null,
9214
+ !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
9215
+ /* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality }),
9216
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
9217
+ /* @__PURE__ */ jsx4(
7598
9218
  ControlButton,
7599
9219
  {
7600
9220
  label: `More for ${participant.displayName}`,
7601
9221
  active: menuFor === participant.identity,
7602
9222
  onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
7603
- children: /* @__PURE__ */ jsx3(MoreIcon, { width: 16, height: 16 })
9223
+ children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
7604
9224
  }
7605
9225
  ),
7606
- menuFor === participant.identity ? /* @__PURE__ */ jsx3(
9226
+ menuFor === participant.identity ? /* @__PURE__ */ jsx4(
7607
9227
  PersonMenu,
7608
9228
  {
7609
9229
  participant,
@@ -7614,13 +9234,13 @@ function PeoplePanel({
7614
9234
  ) : null
7615
9235
  ] })
7616
9236
  ] }, participant.identity)),
7617
- shown.length === 0 ? /* @__PURE__ */ jsxs2("li", { className: "mx-meet__panel-note", children: [
9237
+ shown.length === 0 ? /* @__PURE__ */ jsxs3("li", { className: "mx-meet__panel-note", children: [
7618
9238
  "Nobody matches \u201C",
7619
9239
  query,
7620
9240
  "\u201D."
7621
9241
  ] }) : null
7622
9242
  ] }),
7623
- snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ jsx3(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
9243
+ snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ jsx4(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
7624
9244
  ] });
7625
9245
  }
7626
9246
  function PersonMenu({
@@ -7632,14 +9252,14 @@ function PersonMenu({
7632
9252
  const host = useMeetHost();
7633
9253
  const snapshot = useMeetSnapshot();
7634
9254
  const controls = useHostControls();
7635
- const [mode, setMode] = useState3("menu");
7636
- const [text3, setText] = useState3("");
9255
+ const [mode, setMode] = useState4("menu");
9256
+ const [text3, setText] = useState4("");
7637
9257
  const self = participant.identity === snapshot?.localIdentity;
7638
9258
  const moderate = controls.canModerate(participant);
7639
9259
  const pinned = snapshot?.pinned === participant.identity;
7640
9260
  const spotlit = snapshot?.spotlight === participant.identity;
7641
9261
  const hasAccount = participant.userId !== null;
7642
- const [refused, setRefused] = useState3(false);
9262
+ const [refused, setRefused] = useState4(false);
7643
9263
  const act = (request) => {
7644
9264
  setRefused(false);
7645
9265
  void controls.run(request).then((result) => {
@@ -7647,10 +9267,10 @@ function PersonMenu({
7647
9267
  else setRefused(true);
7648
9268
  });
7649
9269
  };
7650
- const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx3(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
9270
+ const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx4(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
7651
9271
  if (mode === "rename" || mode === "report") {
7652
9272
  const renaming = mode === "rename";
7653
- return /* @__PURE__ */ jsx3(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs2(
9273
+ return /* @__PURE__ */ jsx4(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs3(
7654
9274
  "form",
7655
9275
  {
7656
9276
  className: "mx-meet__menu-form",
@@ -7662,9 +9282,9 @@ function PersonMenu({
7662
9282
  );
7663
9283
  },
7664
9284
  children: [
7665
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7666
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
7667
- renaming ? /* @__PURE__ */ jsx3(
9285
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
9286
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
9287
+ renaming ? /* @__PURE__ */ jsx4(
7668
9288
  "input",
7669
9289
  {
7670
9290
  className: "mx-meet__input",
@@ -7673,7 +9293,7 @@ function PersonMenu({
7673
9293
  value: text3,
7674
9294
  onChange: (event) => setText(event.target.value)
7675
9295
  }
7676
- ) : /* @__PURE__ */ jsx3(
9296
+ ) : /* @__PURE__ */ jsx4(
7677
9297
  "textarea",
7678
9298
  {
7679
9299
  className: "mx-meet__input",
@@ -7686,9 +9306,9 @@ function PersonMenu({
7686
9306
  )
7687
9307
  ] }),
7688
9308
  refusal2,
7689
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-actions", children: [
7690
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
7691
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
9309
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
9310
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
9311
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
7692
9312
  ] })
7693
9313
  ]
7694
9314
  }
@@ -7696,12 +9316,12 @@ function PersonMenu({
7696
9316
  }
7697
9317
  if (mode === "remove" || mode === "transfer") {
7698
9318
  const removing = mode === "remove";
7699
- return /* @__PURE__ */ jsx3(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-form", children: [
7700
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__confirm-text", children: removing ? `Remove ${participant.displayName}? They leave immediately and cannot rejoin this meeting.` : `Make ${participant.displayName} the host? They get every host control and own this meeting. You stay on as a co-host.` }),
9319
+ return /* @__PURE__ */ jsx4(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-form", children: [
9320
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__confirm-text", children: removing ? `Remove ${participant.displayName}? They leave immediately and cannot rejoin this meeting.` : `Make ${participant.displayName} the host? They get every host control and own this meeting. You stay on as a co-host.` }),
7701
9321
  refusal2,
7702
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-actions", children: [
7703
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
7704
- /* @__PURE__ */ jsx3(
9322
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
9323
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
9324
+ /* @__PURE__ */ jsx4(
7705
9325
  "button",
7706
9326
  {
7707
9327
  type: "button",
@@ -7714,8 +9334,8 @@ function PersonMenu({
7714
9334
  ] })
7715
9335
  ] }) });
7716
9336
  }
7717
- return /* @__PURE__ */ jsx3(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu", role: "menu", children: [
7718
- /* @__PURE__ */ jsxs2(
9337
+ return /* @__PURE__ */ jsx4(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
9338
+ /* @__PURE__ */ jsxs3(
7719
9339
  MenuItem,
7720
9340
  {
7721
9341
  onSelect: () => {
@@ -7723,13 +9343,13 @@ function PersonMenu({
7723
9343
  onClose();
7724
9344
  },
7725
9345
  children: [
7726
- /* @__PURE__ */ jsx3(PinIcon, { width: 16, height: 16 }),
9346
+ /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 }),
7727
9347
  " ",
7728
9348
  pinned ? "Unpin" : "Pin for me"
7729
9349
  ]
7730
9350
  }
7731
9351
  ),
7732
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs2(
9352
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
7733
9353
  MenuItem,
7734
9354
  {
7735
9355
  onSelect: () => {
@@ -7741,42 +9361,42 @@ function PersonMenu({
7741
9361
  onClose();
7742
9362
  },
7743
9363
  children: [
7744
- /* @__PURE__ */ jsx3(ChatIcon, { width: 16, height: 16 }),
9364
+ /* @__PURE__ */ jsx4(ChatIcon, { width: 16, height: 16 }),
7745
9365
  " Message privately"
7746
9366
  ]
7747
9367
  }
7748
9368
  ) : null,
7749
- controls.isHost ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
7750
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
9369
+ controls.isHost ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
9370
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7751
9371
  " ",
7752
9372
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
7753
9373
  ] }) : null,
7754
- moderate ? /* @__PURE__ */ jsxs2(Fragment, { children: [
7755
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu-sep", role: "separator" }),
7756
- participant.micEnabled ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
7757
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 16, height: 16 }),
9374
+ moderate ? /* @__PURE__ */ jsxs3(Fragment, { children: [
9375
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
9376
+ participant.micEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
9377
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
7758
9378
  " Mute"
7759
- ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
7760
- /* @__PURE__ */ jsx3(MicIcon, { width: 16, height: 16 }),
9379
+ ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
9380
+ /* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
7761
9381
  " Ask to unmute"
7762
9382
  ] }) : null,
7763
- participant.cameraEnabled ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
7764
- /* @__PURE__ */ jsx3(CameraOffIcon, { width: 16, height: 16 }),
9383
+ participant.cameraEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
9384
+ /* @__PURE__ */ jsx4(CameraOffIcon, { width: 16, height: 16 }),
7765
9385
  " Stop video"
7766
9386
  ] }) : null,
7767
- participant.screenSharing ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
7768
- /* @__PURE__ */ jsx3(ScreenShareIcon, { width: 16, height: 16 }),
9387
+ participant.screenSharing ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
9388
+ /* @__PURE__ */ jsx4(ScreenShareIcon, { width: 16, height: 16 }),
7769
9389
  " Stop screen share"
7770
9390
  ] }) : null,
7771
- participant.handRaised ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
7772
- /* @__PURE__ */ jsx3(HandIcon, { width: 16, height: 16 }),
9391
+ participant.handRaised ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
9392
+ /* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
7773
9393
  " Lower hand"
7774
9394
  ] }) : null,
7775
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
7776
- /* @__PURE__ */ jsx3(PeopleIcon, { width: 16, height: 16 }),
9395
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
9396
+ /* @__PURE__ */ jsx4(PeopleIcon, { width: 16, height: 16 }),
7777
9397
  " Make co-host"
7778
9398
  ] }) : null,
7779
- !participant.isAgent ? /* @__PURE__ */ jsxs2(
9399
+ !participant.isAgent ? /* @__PURE__ */ jsxs3(
7780
9400
  MenuItem,
7781
9401
  {
7782
9402
  onSelect: () => {
@@ -7784,21 +9404,21 @@ function PersonMenu({
7784
9404
  setMode("rename");
7785
9405
  },
7786
9406
  children: [
7787
- /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }),
9407
+ /* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
7788
9408
  " Rename"
7789
9409
  ]
7790
9410
  }
7791
9411
  ) : null
7792
9412
  ] }) : null,
7793
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
7794
- /* @__PURE__ */ jsx3(PeopleIcon, { width: 16, height: 16 }),
9413
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
9414
+ /* @__PURE__ */ jsx4(PeopleIcon, { width: 16, height: 16 }),
7795
9415
  " Remove co-host"
7796
9416
  ] }) : null,
7797
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => setMode("transfer"), children: [
7798
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
9417
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => setMode("transfer"), children: [
9418
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7799
9419
  " Make host"
7800
9420
  ] }) : null,
7801
- self ? /* @__PURE__ */ jsxs2(
9421
+ self ? /* @__PURE__ */ jsxs3(
7802
9422
  MenuItem,
7803
9423
  {
7804
9424
  onSelect: () => {
@@ -7806,12 +9426,12 @@ function PersonMenu({
7806
9426
  setMode("rename");
7807
9427
  },
7808
9428
  children: [
7809
- /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }),
9429
+ /* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
7810
9430
  " Rename yourself"
7811
9431
  ]
7812
9432
  }
7813
9433
  ) : null,
7814
- !self && !participant.isAgent ? /* @__PURE__ */ jsxs2(
9434
+ !self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
7815
9435
  MenuItem,
7816
9436
  {
7817
9437
  onSelect: () => {
@@ -7819,21 +9439,21 @@ function PersonMenu({
7819
9439
  setMode("report");
7820
9440
  },
7821
9441
  children: [
7822
- /* @__PURE__ */ jsx3(FlagIcon, { width: 16, height: 16 }),
9442
+ /* @__PURE__ */ jsx4(FlagIcon, { width: 16, height: 16 }),
7823
9443
  " Report"
7824
9444
  ]
7825
9445
  }
7826
9446
  ) : null,
7827
- moderate && !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
7828
- /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }),
9447
+ moderate && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
9448
+ /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }),
7829
9449
  " Remove from meeting"
7830
9450
  ] }) : null
7831
9451
  ] }) });
7832
9452
  }
7833
9453
  function SettingsPanel({ onClose }) {
7834
9454
  const host = useRequiredMeetHost();
7835
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Audio, video and effects", onClose, children: [
7836
- /* @__PURE__ */ jsx3(
9455
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
9456
+ /* @__PURE__ */ jsx4(
7837
9457
  DeviceSettings,
7838
9458
  {
7839
9459
  onPick: (kind, deviceId2) => {
@@ -7842,7 +9462,8 @@ function SettingsPanel({ onClose }) {
7842
9462
  }
7843
9463
  }
7844
9464
  ),
7845
- /* @__PURE__ */ jsx3(EffectsSettings, {})
9465
+ /* @__PURE__ */ jsx4(EffectsSettings, {}),
9466
+ /* @__PURE__ */ jsx4(CaptionLanguageSettings, {})
7846
9467
  ] });
7847
9468
  }
7848
9469
  function DeviceSettings({
@@ -7854,15 +9475,15 @@ function DeviceSettings({
7854
9475
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
7855
9476
  const stream = useMicrophoneStream(microphone);
7856
9477
  const level = useAudioLevel(stream);
7857
- const [testing, setTesting] = useState3(false);
7858
- useEffect3(() => {
9478
+ const [testing, setTesting] = useState4(false);
9479
+ useEffect4(() => {
7859
9480
  void host.devices.refresh();
7860
9481
  }, [host]);
7861
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
7862
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
7863
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__meter", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx3("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
7864
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
7865
- /* @__PURE__ */ jsxs2(
9482
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
9483
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
9484
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__meter", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx4("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
9485
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
9486
+ /* @__PURE__ */ jsxs3(
7866
9487
  "button",
7867
9488
  {
7868
9489
  type: "button",
@@ -7873,19 +9494,19 @@ function DeviceSettings({
7873
9494
  void playTestSound(speaker).finally(() => setTesting(false));
7874
9495
  },
7875
9496
  children: [
7876
- /* @__PURE__ */ jsx3(SpeakerIcon, { width: 14, height: 14 }),
9497
+ /* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
7877
9498
  " ",
7878
9499
  testing ? "Playing\u2026" : "Test speaker"
7879
9500
  ]
7880
9501
  }
7881
9502
  ),
7882
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
9503
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
7883
9504
  ] });
7884
9505
  }
7885
9506
  function EffectsSettings({ preview }) {
7886
9507
  const effects = useMediaEffects();
7887
- const [error, setError] = useState3(null);
7888
- const fileRef = useRef3(null);
9508
+ const [error, setError] = useState4(null);
9509
+ const fileRef = useRef4(null);
7889
9510
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
7890
9511
  const apply = (next) => {
7891
9512
  setError(null);
@@ -7897,9 +9518,9 @@ function EffectsSettings({ preview }) {
7897
9518
  );
7898
9519
  }
7899
9520
  };
7900
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
7901
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7902
- /* @__PURE__ */ jsx3(
9521
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
9522
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9523
+ /* @__PURE__ */ jsx4(
7903
9524
  "input",
7904
9525
  {
7905
9526
  type: "checkbox",
@@ -7908,11 +9529,11 @@ function EffectsSettings({ preview }) {
7908
9529
  }
7909
9530
  ),
7910
9531
  "Noise suppression",
7911
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
9532
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
7912
9533
  ] }),
7913
- supported ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__field", children: [
7914
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Background" }),
7915
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ jsx3(
9534
+ supported ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
9535
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Background" }),
9536
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ jsx4(
7916
9537
  "button",
7917
9538
  {
7918
9539
  type: "button",
@@ -7930,7 +9551,7 @@ function EffectsSettings({ preview }) {
7930
9551
  },
7931
9552
  kind
7932
9553
  )) }),
7933
- /* @__PURE__ */ jsx3(
9554
+ /* @__PURE__ */ jsx4(
7934
9555
  "input",
7935
9556
  {
7936
9557
  ref: fileRef,
@@ -7945,7 +9566,7 @@ function EffectsSettings({ preview }) {
7945
9566
  }
7946
9567
  }
7947
9568
  ),
7948
- error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__error", children: error }) : null
9569
+ error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__error", children: error }) : null
7949
9570
  ] }) : null
7950
9571
  ] });
7951
9572
  }
@@ -8004,8 +9625,8 @@ async function playTestSound(sinkId) {
8004
9625
  await context.close();
8005
9626
  }
8006
9627
  function useMicrophoneStream(deviceId2) {
8007
- const [stream, setStream] = useState3(null);
8008
- useEffect3(() => {
9628
+ const [stream, setStream] = useState4(null);
9629
+ useEffect4(() => {
8009
9630
  if (deviceId2 === "off") return void 0;
8010
9631
  let live = true;
8011
9632
  let opened = null;
@@ -8030,25 +9651,25 @@ function useMicrophoneStream(deviceId2) {
8030
9651
  function LobbyPanel() {
8031
9652
  const lobby = useLobby();
8032
9653
  if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
8033
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
8034
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__lobby-head", children: [
8035
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
8036
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
9654
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
9655
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__lobby-head", children: [
9656
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
9657
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
8037
9658
  ] }),
8038
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__lobby-row", children: [
8039
- /* @__PURE__ */ jsx3(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
8040
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
9659
+ /* @__PURE__ */ jsx4("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__lobby-row", children: [
9660
+ /* @__PURE__ */ jsx4(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
9661
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
8041
9662
  entry.displayName,
8042
- entry.userId === null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" }) : null
9663
+ entry.userId === null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" }) : null
8043
9664
  ] }),
8044
- /* @__PURE__ */ jsx3(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx3(CheckIcon, { width: 16, height: 16 }) }),
8045
- /* @__PURE__ */ jsx3(
9665
+ /* @__PURE__ */ jsx4(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx4(CheckIcon, { width: 16, height: 16 }) }),
9666
+ /* @__PURE__ */ jsx4(
8046
9667
  ControlButton,
8047
9668
  {
8048
9669
  label: `Deny ${entry.displayName}`,
8049
9670
  danger: true,
8050
9671
  onClick: () => void lobby.deny(entry),
8051
- children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 })
9672
+ children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 })
8052
9673
  }
8053
9674
  )
8054
9675
  ] }, entry.identity)) })
@@ -8058,21 +9679,21 @@ function NoteTakerRow() {
8058
9679
  const ai = useMeetAi();
8059
9680
  const status = ai.noteTaker;
8060
9681
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
8061
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
8062
- /* @__PURE__ */ jsxs2("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
8063
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
9682
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
9683
+ /* @__PURE__ */ jsxs3("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
9684
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
8064
9685
  ai.noteTakerLabel
8065
9686
  ] }),
8066
- status.detail !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
8067
- status.refusal !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
8068
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
8069
- status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
9687
+ status.detail !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
9688
+ status.refusal !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
9689
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
9690
+ status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
8070
9691
  ] }) : null,
8071
- ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8072
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8073
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
9692
+ ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
9693
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
9694
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8074
9695
  ] }) : null,
8075
- ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ jsx3(
9696
+ ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ jsx4(
8076
9697
  "button",
8077
9698
  {
8078
9699
  type: "button",
@@ -8080,7 +9701,7 @@ function NoteTakerRow() {
8080
9701
  onClick: () => void ai.stopNoteTaker(),
8081
9702
  children: "Dismiss the note-taker"
8082
9703
  }
8083
- ) : /* @__PURE__ */ jsx3(
9704
+ ) : /* @__PURE__ */ jsx4(
8084
9705
  "button",
8085
9706
  {
8086
9707
  type: "button",
@@ -8096,24 +9717,24 @@ function NoteList({
8096
9717
  notes,
8097
9718
  empty
8098
9719
  }) {
8099
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": title, children: [
8100
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: title }),
8101
- notes.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__note", children: [
9720
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": title, children: [
9721
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: title }),
9722
+ notes.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx4("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
8102
9723
  note.text,
8103
- note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
9724
+ note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
8104
9725
  ] }, note.id)) })
8105
9726
  ] });
8106
9727
  }
8107
9728
  function AiPanel({ onClose }) {
8108
9729
  const ai = useMeetAi();
8109
- const [question, setQuestion] = useState3("");
8110
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Meeting assistant", onClose, children: [
8111
- /* @__PURE__ */ jsx3(NoteTakerRow, {}),
8112
- ai.summary !== null ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
8113
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
8114
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__summary", children: ai.summary.text })
9730
+ const [question, setQuestion] = useState4("");
9731
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Meeting assistant", onClose, children: [
9732
+ /* @__PURE__ */ jsx4(NoteTakerRow, {}),
9733
+ ai.summary !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
9734
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
9735
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__summary", children: ai.summary.text })
8115
9736
  ] }) : null,
8116
- ai.wrapUp !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
9737
+ ai.wrapUp !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
8117
9738
  "The wrap-up is written \u2014 ",
8118
9739
  ai.wrapUp.noteIds.length,
8119
9740
  " ",
@@ -8125,7 +9746,7 @@ function AiPanel({ onClose }) {
8125
9746
  ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
8126
9747
  "."
8127
9748
  ] }) : null,
8128
- /* @__PURE__ */ jsx3(
9749
+ /* @__PURE__ */ jsx4(
8129
9750
  NoteList,
8130
9751
  {
8131
9752
  title: "Notes",
@@ -8133,7 +9754,7 @@ function AiPanel({ onClose }) {
8133
9754
  empty: "Notes appear here as the meeting goes on."
8134
9755
  }
8135
9756
  ),
8136
- /* @__PURE__ */ jsx3(
9757
+ /* @__PURE__ */ jsx4(
8137
9758
  NoteList,
8138
9759
  {
8139
9760
  title: "Decisions",
@@ -8141,7 +9762,7 @@ function AiPanel({ onClose }) {
8141
9762
  empty: "Nothing has been decided yet."
8142
9763
  }
8143
9764
  ),
8144
- /* @__PURE__ */ jsx3(
9765
+ /* @__PURE__ */ jsx4(
8145
9766
  NoteList,
8146
9767
  {
8147
9768
  title: "Action items",
@@ -8149,21 +9770,21 @@ function AiPanel({ onClose }) {
8149
9770
  empty: "No action items yet."
8150
9771
  }
8151
9772
  ),
8152
- ai.transcript.length > 0 ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
8153
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
8154
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs2(
9773
+ ai.transcript.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
9774
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
9775
+ /* @__PURE__ */ jsx4("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs3(
8155
9776
  "li",
8156
9777
  {
8157
9778
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
8158
9779
  children: [
8159
- /* @__PURE__ */ jsx3("strong", { children: line.speaker }),
8160
- /* @__PURE__ */ jsx3("span", { children: line.text })
9780
+ /* @__PURE__ */ jsx4("strong", { children: line.speaker }),
9781
+ /* @__PURE__ */ jsx4("span", { children: line.text })
8161
9782
  ]
8162
9783
  },
8163
9784
  line.id
8164
9785
  )) })
8165
9786
  ] }) : null,
8166
- /* @__PURE__ */ jsxs2(
9787
+ /* @__PURE__ */ jsxs3(
8167
9788
  "form",
8168
9789
  {
8169
9790
  className: "mx-meet__composer",
@@ -8174,7 +9795,7 @@ function AiPanel({ onClose }) {
8174
9795
  void ai.ask(asked);
8175
9796
  },
8176
9797
  children: [
8177
- /* @__PURE__ */ jsx3(
9798
+ /* @__PURE__ */ jsx4(
8178
9799
  "input",
8179
9800
  {
8180
9801
  className: "mx-meet__input",
@@ -8184,13 +9805,13 @@ function AiPanel({ onClose }) {
8184
9805
  "aria-label": "Ask about this meeting"
8185
9806
  }
8186
9807
  ),
8187
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
9808
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
8188
9809
  ]
8189
9810
  }
8190
9811
  ),
8191
- ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
8192
- ai.answer !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__answer", children: ai.answer }) : null,
8193
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__coverage", children: [
9812
+ ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
9813
+ ai.answer !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__answer", children: ai.answer }) : null,
9814
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
8194
9815
  "Answered from ",
8195
9816
  ai.coverage.segmentsUsed,
8196
9817
  " of ",
@@ -8199,48 +9820,56 @@ function AiPanel({ onClose }) {
8199
9820
  ai.coverage.truncated ? " (the oldest were left out)" : "",
8200
9821
  "."
8201
9822
  ] }) : null,
8202
- ai.error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8203
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8204
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
9823
+ ai.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
9824
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
9825
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8205
9826
  ] }) : null
8206
9827
  ] });
8207
9828
  }
8208
9829
  function Captions({ lines = 3 }) {
8209
9830
  const ai = useMeetAi();
8210
9831
  const visible = ai.transcript.slice(-lines);
9832
+ const translation = useCaptionTranslation(visible);
8211
9833
  if (visible.length === 0) return null;
8212
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: visible.map((line) => /* @__PURE__ */ jsxs2(
8213
- "p",
8214
- {
8215
- className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
8216
- children: [
8217
- /* @__PURE__ */ jsx3("strong", { children: line.speaker }),
8218
- " ",
8219
- line.text
8220
- ]
8221
- },
8222
- line.id
8223
- )) });
9834
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: [
9835
+ visible.map((line) => {
9836
+ const translated = translation.language === null ? void 0 : translation.translations[line.id];
9837
+ return /* @__PURE__ */ jsxs3(
9838
+ "p",
9839
+ {
9840
+ className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
9841
+ children: [
9842
+ /* @__PURE__ */ jsx4("strong", { children: line.speaker }),
9843
+ " ",
9844
+ translated ?? line.text,
9845
+ translated !== void 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__caption-original", children: line.text }) : null
9846
+ ]
9847
+ },
9848
+ line.id
9849
+ );
9850
+ }),
9851
+ translation.language !== null && translation.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__caption mx-meet__caption--interim", children: translation.error }) : null
9852
+ ] });
8224
9853
  }
8225
9854
  function ConsentNotice() {
8226
9855
  const notice = useConsentNotice();
8227
9856
  if (notice === null) return null;
8228
- return /* @__PURE__ */ jsx3("p", { className: "mx-meet__consent", role: "status", children: notice });
9857
+ return /* @__PURE__ */ jsx4("p", { className: "mx-meet__consent", role: "status", children: notice });
8229
9858
  }
8230
9859
  function AttendanceNotice() {
8231
9860
  const media = useLocalMedia();
8232
9861
  const notice = listenOnlyNotice(media);
8233
9862
  if (notice === null) return null;
8234
9863
  const refused = media.microphone.unavailable;
8235
- return /* @__PURE__ */ jsxs2("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
9864
+ return /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
8236
9865
  notice,
8237
- refused === null ? null : /* @__PURE__ */ jsx3("span", { className: "mx-meet__remedy", children: refused.remedy })
9866
+ refused === null ? null : /* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: refused.remedy })
8238
9867
  ] });
8239
9868
  }
8240
9869
  function PreJoin(props) {
8241
9870
  const host = useMeetHost();
8242
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting" });
8243
- return /* @__PURE__ */ jsx3(PreJoinBody, { ...props, host });
9871
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" });
9872
+ return /* @__PURE__ */ jsx4(PreJoinBody, { ...props, host });
8244
9873
  }
8245
9874
  function PreJoinBody({
8246
9875
  roomName,
@@ -8254,21 +9883,21 @@ function PreJoinBody({
8254
9883
  const recording = useRecording();
8255
9884
  const effects = useMediaEffects();
8256
9885
  const { notice } = useModerationNotice();
8257
- const [mode, setMode] = useState3("video");
8258
- const [microphone, setMicrophone] = useState3(true);
8259
- const [joining, setJoining] = useState3(false);
9886
+ const [mode, setMode] = useState4("video");
9887
+ const [microphone, setMicrophone] = useState4(true);
9888
+ const [joining, setJoining] = useState4(false);
8260
9889
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
8261
9890
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
8262
9891
  const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
8263
9892
  const micStream = useMicrophoneStream(microphone ? mic : "off");
8264
9893
  const level = useAudioLevel(micStream);
8265
- const [speakerTesting, setSpeakerTesting] = useState3(false);
8266
- useEffect3(() => {
9894
+ const [speakerTesting, setSpeakerTesting] = useState4(false);
9895
+ useEffect4(() => {
8267
9896
  void host.devices.refresh();
8268
9897
  }, [host]);
8269
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin", children: [
8270
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__preview", children: [
8271
- mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx3(
9898
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
9899
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__preview", children: [
9900
+ mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx4(
8272
9901
  "video",
8273
9902
  {
8274
9903
  className: "mx-meet__video mx-meet__video--mirror",
@@ -8279,16 +9908,16 @@ function PreJoinBody({
8279
9908
  if (element !== null) preview.preview?.attach(element);
8280
9909
  }
8281
9910
  }
8282
- ) : /* @__PURE__ */ jsx3("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx3(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
8283
- mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
8284
- microphone && micStream !== null ? /* @__PURE__ */ jsx3("div", { className: "mx-meet__meter mx-meet__meter--preview", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx3("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
9911
+ ) : /* @__PURE__ */ jsx4("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx4(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
9912
+ mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
9913
+ microphone && micStream !== null ? /* @__PURE__ */ jsx4("div", { className: "mx-meet__meter mx-meet__meter--preview", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx4("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
8285
9914
  ] }),
8286
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin-panel", children: [
8287
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
8288
- notice?.kind === "removed" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__warning", children: notice.text }) : null,
8289
- devices?.labelsHidden === true ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
9915
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-panel", children: [
9916
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
9917
+ notice?.kind === "removed" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__warning", children: notice.text }) : null,
9918
+ devices?.labelsHidden === true ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
8290
9919
  "Your browser is hiding device names until you allow camera and microphone access.",
8291
- /* @__PURE__ */ jsx3(
9920
+ /* @__PURE__ */ jsx4(
8292
9921
  "button",
8293
9922
  {
8294
9923
  type: "button",
@@ -8300,11 +9929,11 @@ function PreJoinBody({
8300
9929
  }
8301
9930
  )
8302
9931
  ] }) : null,
8303
- devices?.fallbackNotice != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
8304
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audioinput", label: "Microphone" }),
8305
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__field-row", children: [
8306
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
8307
- /* @__PURE__ */ jsxs2(
9932
+ devices?.fallbackNotice != null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
9933
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audioinput", label: "Microphone" }),
9934
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field-row", children: [
9935
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
9936
+ /* @__PURE__ */ jsxs3(
8308
9937
  "button",
8309
9938
  {
8310
9939
  type: "button",
@@ -8317,19 +9946,19 @@ function PreJoinBody({
8317
9946
  );
8318
9947
  },
8319
9948
  children: [
8320
- /* @__PURE__ */ jsx3(SpeakerIcon, { width: 14, height: 14 }),
9949
+ /* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
8321
9950
  " ",
8322
9951
  speakerTesting ? "Playing\u2026" : "Test"
8323
9952
  ]
8324
9953
  }
8325
9954
  )
8326
9955
  ] }),
8327
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "videoinput", label: "Camera" }),
8328
- /* @__PURE__ */ jsx3(EffectsSettings, { preview: preview.preview }),
8329
- recording.consentNotice !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
8330
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin-actions", children: [
8331
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
8332
- /* @__PURE__ */ jsx3(
9956
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera" }),
9957
+ /* @__PURE__ */ jsx4(EffectsSettings, { preview: preview.preview }),
9958
+ recording.consentNotice !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
9959
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-actions", children: [
9960
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9961
+ /* @__PURE__ */ jsx4(
8333
9962
  "input",
8334
9963
  {
8335
9964
  type: "checkbox",
@@ -8339,8 +9968,8 @@ function PreJoinBody({
8339
9968
  ),
8340
9969
  "Join with video"
8341
9970
  ] }),
8342
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
8343
- /* @__PURE__ */ jsx3(
9971
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9972
+ /* @__PURE__ */ jsx4(
8344
9973
  "input",
8345
9974
  {
8346
9975
  type: "checkbox",
@@ -8350,7 +9979,7 @@ function PreJoinBody({
8350
9979
  ),
8351
9980
  "Join with microphone"
8352
9981
  ] }),
8353
- /* @__PURE__ */ jsx3(
9982
+ /* @__PURE__ */ jsx4(
8354
9983
  "button",
8355
9984
  {
8356
9985
  type: "button",
@@ -8370,20 +9999,20 @@ function PreJoinBody({
8370
9999
  }
8371
10000
  )
8372
10001
  ] }),
8373
- room.failure !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__error", children: [
10002
+ room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
8374
10003
  room.failure.message,
8375
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__remedy", children: room.failure.remedy })
10004
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: room.failure.remedy })
8376
10005
  ] }) : null
8377
10006
  ] })
8378
10007
  ] });
8379
10008
  }
8380
10009
  function useCameraPreview(deviceId2, effects) {
8381
- const [preview, setPreview] = useState3(null);
8382
- const [error, setError] = useState3(null);
8383
- const current = useRef3(null);
8384
- const initialEffect = useRef3(toVideoEffect(effects));
10010
+ const [preview, setPreview] = useState4(null);
10011
+ const [error, setError] = useState4(null);
10012
+ const current = useRef4(null);
10013
+ const initialEffect = useRef4(toVideoEffect(effects));
8385
10014
  initialEffect.current = toVideoEffect(effects);
8386
- useEffect3(() => {
10015
+ useEffect4(() => {
8387
10016
  if (deviceId2 === void 0) return void 0;
8388
10017
  let live = true;
8389
10018
  setError(null);
@@ -8427,9 +10056,9 @@ function DevicePicker({
8427
10056
  const devices = useDeviceSnapshot();
8428
10057
  const list = devices?.devices[kind] ?? [];
8429
10058
  if (list.length === 0) return null;
8430
- return /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8431
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: label }),
8432
- /* @__PURE__ */ jsx3(
10059
+ return /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10060
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: label }),
10061
+ /* @__PURE__ */ jsx4(
8433
10062
  "select",
8434
10063
  {
8435
10064
  className: "mx-meet__select",
@@ -8438,7 +10067,7 @@ function DevicePicker({
8438
10067
  if (onPick !== void 0) onPick(kind, event.target.value);
8439
10068
  else host.devices.select(kind, event.target.value);
8440
10069
  },
8441
- children: list.map((device) => /* @__PURE__ */ jsx3("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
10070
+ children: list.map((device) => /* @__PURE__ */ jsx4("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
8442
10071
  }
8443
10072
  )
8444
10073
  ] });
@@ -8446,9 +10075,9 @@ function DevicePicker({
8446
10075
  function MeetingRoom(props) {
8447
10076
  const host = useMeetHost();
8448
10077
  if (host === null) {
8449
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet", children: /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting" }) });
10078
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" }) });
8450
10079
  }
8451
- return /* @__PURE__ */ jsx3(MeetingRoomBody, { ...props, host });
10080
+ return /* @__PURE__ */ jsx4(MeetingRoomBody, { ...props, host });
8452
10081
  }
8453
10082
  function MeetingRoomBody({
8454
10083
  roomName,
@@ -8463,25 +10092,25 @@ function MeetingRoomBody({
8463
10092
  const isHost = useIsHost();
8464
10093
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
8465
10094
  const phase = snapshot?.phase ?? "idle";
8466
- useEffect3(() => {
10095
+ useEffect4(() => {
8467
10096
  host.meetings.watch(roomName);
8468
10097
  }, [host, roomName]);
8469
- useEffect3(() => {
10098
+ useEffect4(() => {
8470
10099
  if (given === void 0) return;
8471
10100
  if (host.store.snapshot().meeting !== null) return;
8472
10101
  host.store.patch({ meeting: given, locked: given.locked });
8473
10102
  }, [host, given]);
8474
10103
  const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
8475
- useEffect3(() => {
10104
+ useEffect4(() => {
8476
10105
  if (watchedId === null) return;
8477
10106
  host.meetings.watchMeeting(asMeetingId(watchedId));
8478
10107
  }, [host, watchedId]);
8479
10108
  const record = snapshot?.meeting ?? given ?? null;
8480
10109
  if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
8481
- return /* @__PURE__ */ jsx3(MeetingRecordView, { meeting: record });
10110
+ return /* @__PURE__ */ jsx4(MeetingRecordView, { meeting: record });
8482
10111
  }
8483
10112
  if (phase === "idle" || phase === "failed" || phase === "left") {
8484
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet", children: /* @__PURE__ */ jsx3(
10113
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(
8485
10114
  PreJoin,
8486
10115
  {
8487
10116
  roomName,
@@ -8491,42 +10120,42 @@ function MeetingRoomBody({
8491
10120
  ) });
8492
10121
  }
8493
10122
  if (phase === "lobby") {
8494
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx3(WaitingRoom, { roomName, host }) });
8495
- }
8496
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet", children: [
8497
- /* @__PURE__ */ jsx3(ConsentNotice, {}),
8498
- /* @__PURE__ */ jsx3(AttendanceNotice, {}),
8499
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__header", children: [
8500
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
8501
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__meta", children: [
10123
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx4(WaitingRoom, { roomName, host }) });
10124
+ }
10125
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet", children: [
10126
+ /* @__PURE__ */ jsx4(ConsentNotice, {}),
10127
+ /* @__PURE__ */ jsx4(AttendanceNotice, {}),
10128
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__header", children: [
10129
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
10130
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
8502
10131
  participantSummary(snapshot?.participants ?? []),
8503
10132
  elapsed > 0 ? ` \xB7 ${formatDurationMs3(elapsed)}` : ""
8504
10133
  ] }),
8505
- /* @__PURE__ */ jsx3(RecordingIndicator, {}),
8506
- snapshot?.locked === true ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__badge", children: [
8507
- /* @__PURE__ */ jsx3(LockIcon, { width: 12, height: 12 }),
10134
+ /* @__PURE__ */ jsx4(RecordingIndicator, {}),
10135
+ snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
10136
+ /* @__PURE__ */ jsx4(LockIcon, { width: 12, height: 12 }),
8508
10137
  " Locked"
8509
10138
  ] }) : null,
8510
- headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
8511
- isHost ? /* @__PURE__ */ jsx3(HostMenu, {}) : null
10139
+ headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
10140
+ isHost ? /* @__PURE__ */ jsx4(HostMenu, {}) : null
8512
10141
  ] }),
8513
- phase === "reconnecting" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
8514
- /* @__PURE__ */ jsx3(Stage, {}),
8515
- /* @__PURE__ */ jsx3(Captions, {}),
8516
- /* @__PURE__ */ jsx3(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
10142
+ phase === "reconnecting" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
10143
+ /* @__PURE__ */ jsx4(Stage, {}),
10144
+ /* @__PURE__ */ jsx4(Captions, {}),
10145
+ /* @__PURE__ */ jsx4(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
8517
10146
  ] });
8518
10147
  }
8519
10148
  function WaitingRoom({ roomName, host }) {
8520
- const knocked = useRef3(false);
8521
- useEffect3(() => {
10149
+ const knocked = useRef4(false);
10150
+ useEffect4(() => {
8522
10151
  if (knocked.current) return;
8523
10152
  knocked.current = true;
8524
10153
  host.meetings.knock(roomName);
8525
10154
  }, [host, roomName]);
8526
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__waiting", children: [
8527
- /* @__PURE__ */ jsx3(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
8528
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
8529
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__empty-body", children: [
10155
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", children: [
10156
+ /* @__PURE__ */ jsx4(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
10157
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
10158
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-body", children: [
8530
10159
  "You are in the waiting room as ",
8531
10160
  host.identity.displayName,
8532
10161
  ". You will join automatically once you are admitted."
@@ -8537,10 +10166,10 @@ function HostMenu() {
8537
10166
  const host = useRequiredMeetHost();
8538
10167
  const snapshot = useMeetSnapshot();
8539
10168
  const end = useEndMeeting();
8540
- const [confirmingEnd, setConfirmingEnd] = useState3(false);
10169
+ const [confirmingEnd, setConfirmingEnd] = useState4(false);
8541
10170
  const locked = snapshot?.locked === true;
8542
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__host-menu", children: [
8543
- /* @__PURE__ */ jsx3(
10171
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
10172
+ /* @__PURE__ */ jsx4(
8544
10173
  "button",
8545
10174
  {
8546
10175
  type: "button",
@@ -8551,9 +10180,9 @@ function HostMenu() {
8551
10180
  children: locked ? "Unlock meeting" : "Lock meeting"
8552
10181
  }
8553
10182
  ),
8554
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
8555
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__confirm-text", children: "End it for everyone? Every participant is disconnected, the note-taker stops, and the wrap-up is written. Nobody can rejoin this meeting afterwards." }),
8556
- /* @__PURE__ */ jsx3(
10183
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
10184
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__confirm-text", children: "End it for everyone? Every participant is disconnected, the note-taker stops, and the wrap-up is written. Nobody can rejoin this meeting afterwards." }),
10185
+ /* @__PURE__ */ jsx4(
8557
10186
  "button",
8558
10187
  {
8559
10188
  type: "button",
@@ -8565,7 +10194,7 @@ function HostMenu() {
8565
10194
  children: "End it"
8566
10195
  }
8567
10196
  ),
8568
- /* @__PURE__ */ jsx3(
10197
+ /* @__PURE__ */ jsx4(
8569
10198
  "button",
8570
10199
  {
8571
10200
  type: "button",
@@ -8574,7 +10203,7 @@ function HostMenu() {
8574
10203
  children: "Keep it running"
8575
10204
  }
8576
10205
  )
8577
- ] }) : /* @__PURE__ */ jsx3(
10206
+ ] }) : /* @__PURE__ */ jsx4(
8578
10207
  "button",
8579
10208
  {
8580
10209
  type: "button",
@@ -8583,7 +10212,7 @@ function HostMenu() {
8583
10212
  children: end.ending ? "Ending\u2026" : "End meeting for everyone"
8584
10213
  }
8585
10214
  ) : null,
8586
- end.notice !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
10215
+ end.notice !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
8587
10216
  ] });
8588
10217
  }
8589
10218
  function CallButton({
@@ -8593,7 +10222,7 @@ function CallButton({
8593
10222
  }) {
8594
10223
  const calls = useCalls();
8595
10224
  if (!calls.canCall) return null;
8596
- return /* @__PURE__ */ jsx3(
10225
+ return /* @__PURE__ */ jsx4(
8597
10226
  "button",
8598
10227
  {
8599
10228
  type: "button",
@@ -8602,55 +10231,55 @@ function CallButton({
8602
10231
  void calls.call([person.userId], mode);
8603
10232
  },
8604
10233
  "aria-label": `Call ${person.displayName}`,
8605
- children: children ?? /* @__PURE__ */ jsx3(PhoneIcon, { width: 18, height: 18 })
10234
+ children: children ?? /* @__PURE__ */ jsx4(PhoneIcon, { width: 18, height: 18 })
8606
10235
  }
8607
10236
  );
8608
10237
  }
8609
10238
  function IncomingCallHost() {
8610
10239
  const calls = useCalls();
8611
10240
  if (calls.incoming.length === 0) return null;
8612
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx3(IncomingCallCard, { invite }, invite.id)) });
10241
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx4(IncomingCallCard, { invite }, invite.id)) });
8613
10242
  }
8614
10243
  function IncomingCallCard({ invite }) {
8615
10244
  const calls = useCalls();
8616
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
8617
- /* @__PURE__ */ jsx3(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
8618
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__ringing-text", children: [
8619
- /* @__PURE__ */ jsx3("strong", { children: invite.callerName }),
8620
- /* @__PURE__ */ jsx3("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
10245
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
10246
+ /* @__PURE__ */ jsx4(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
10247
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-text", children: [
10248
+ /* @__PURE__ */ jsx4("strong", { children: invite.callerName }),
10249
+ /* @__PURE__ */ jsx4("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
8621
10250
  ] }),
8622
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__ringing-actions", children: [
8623
- /* @__PURE__ */ jsx3(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx3(PhoneOffIcon, {}) }),
8624
- invite.mode === "video" ? /* @__PURE__ */ jsx3(
10251
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-actions", children: [
10252
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx4(PhoneOffIcon, {}) }),
10253
+ invite.mode === "video" ? /* @__PURE__ */ jsx4(
8625
10254
  ControlButton,
8626
10255
  {
8627
10256
  label: "Accept without video",
8628
10257
  onClick: () => void calls.accept({ ...invite, mode: "audio" }),
8629
- children: /* @__PURE__ */ jsx3(CameraOffIcon, {})
10258
+ children: /* @__PURE__ */ jsx4(CameraOffIcon, {})
8630
10259
  }
8631
10260
  ) : null,
8632
- /* @__PURE__ */ jsx3(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx3(PhoneIcon, {}) })
10261
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx4(PhoneIcon, {}) })
8633
10262
  ] })
8634
10263
  ] });
8635
10264
  }
8636
10265
  function ScheduleMeeting(props) {
8637
10266
  const host = useMeetHost();
8638
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "Scheduling a meeting" });
8639
- return /* @__PURE__ */ jsx3(ScheduleMeetingBody, { ...props, host });
10267
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Scheduling a meeting" });
10268
+ return /* @__PURE__ */ jsx4(ScheduleMeetingBody, { ...props, host });
8640
10269
  }
8641
10270
  function ScheduleMeetingBody({
8642
10271
  appBaseUrl,
8643
10272
  onScheduled,
8644
10273
  host
8645
10274
  }) {
8646
- const [title, setTitle] = useState3("");
8647
- const [when2, setWhen] = useState3("");
8648
- const [kind, setKind] = useState3("scheduled");
8649
- const [busy, setBusy] = useState3(false);
8650
- const [link, setLink] = useState3(null);
8651
- const [error, setError] = useState3(null);
10275
+ const [title, setTitle] = useState4("");
10276
+ const [when2, setWhen] = useState4("");
10277
+ const [kind, setKind] = useState4("scheduled");
10278
+ const [busy, setBusy] = useState4(false);
10279
+ const [link, setLink] = useState4(null);
10280
+ const [error, setError] = useState4(null);
8652
10281
  const disabled = useMemo3(() => title.trim().length === 0 || busy, [title, busy]);
8653
- return /* @__PURE__ */ jsxs2(
10282
+ return /* @__PURE__ */ jsxs3(
8654
10283
  "form",
8655
10284
  {
8656
10285
  className: "mx-meet__schedule",
@@ -8675,9 +10304,9 @@ function ScheduleMeetingBody({
8675
10304
  }).finally(() => setBusy(false));
8676
10305
  },
8677
10306
  children: [
8678
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8679
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Title" }),
8680
- /* @__PURE__ */ jsx3(
10307
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10308
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Title" }),
10309
+ /* @__PURE__ */ jsx4(
8681
10310
  "input",
8682
10311
  {
8683
10312
  className: "mx-meet__input",
@@ -8687,9 +10316,9 @@ function ScheduleMeetingBody({
8687
10316
  }
8688
10317
  )
8689
10318
  ] }),
8690
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8691
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "When" }),
8692
- /* @__PURE__ */ jsx3(
10319
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10320
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "When" }),
10321
+ /* @__PURE__ */ jsx4(
8693
10322
  "input",
8694
10323
  {
8695
10324
  className: "mx-meet__input",
@@ -8699,27 +10328,27 @@ function ScheduleMeetingBody({
8699
10328
  }
8700
10329
  )
8701
10330
  ] }),
8702
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8703
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Repeats" }),
8704
- /* @__PURE__ */ jsxs2(
10331
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10332
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Repeats" }),
10333
+ /* @__PURE__ */ jsxs3(
8705
10334
  "select",
8706
10335
  {
8707
10336
  className: "mx-meet__select",
8708
10337
  value: kind,
8709
10338
  onChange: (event) => setKind(event.target.value),
8710
10339
  children: [
8711
- /* @__PURE__ */ jsx3("option", { value: "scheduled", children: "Once" }),
8712
- /* @__PURE__ */ jsx3("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
10340
+ /* @__PURE__ */ jsx4("option", { value: "scheduled", children: "Once" }),
10341
+ /* @__PURE__ */ jsx4("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
8713
10342
  ]
8714
10343
  }
8715
10344
  )
8716
10345
  ] }),
8717
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
8718
- link !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__link-out", children: [
8719
- /* @__PURE__ */ jsx3("span", { children: "Anyone with this link can join \u2014 no account needed." }),
8720
- /* @__PURE__ */ jsx3("code", { children: link })
10346
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
10347
+ link !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__link-out", children: [
10348
+ /* @__PURE__ */ jsx4("span", { children: "Anyone with this link can join \u2014 no account needed." }),
10349
+ /* @__PURE__ */ jsx4("code", { children: link })
8721
10350
  ] }) : null,
8722
- error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__error", children: error }) : null
10351
+ error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__error", children: error }) : null
8723
10352
  ]
8724
10353
  }
8725
10354
  );
@@ -8728,7 +10357,7 @@ function ReactionOverlay({
8728
10357
  reactions
8729
10358
  }) {
8730
10359
  if (reactions.length === 0) return null;
8731
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ jsx3("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
10360
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ jsx4("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
8732
10361
  }
8733
10362
  function GuestRecordAccessControl({
8734
10363
  meeting
@@ -8740,11 +10369,11 @@ function GuestRecordAccessControl({
8740
10369
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
8741
10370
  if (host === null || !isHost) return null;
8742
10371
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
8743
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
8744
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
8745
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8746
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
8747
- /* @__PURE__ */ jsx3(
10372
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
10373
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
10374
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10375
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
10376
+ /* @__PURE__ */ jsx4(
8748
10377
  "select",
8749
10378
  {
8750
10379
  className: "mx-meet__select",
@@ -8755,18 +10384,18 @@ function GuestRecordAccessControl({
8755
10384
  event.target.value
8756
10385
  );
8757
10386
  },
8758
- children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ jsx3("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
10387
+ children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ jsx4("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
8759
10388
  }
8760
10389
  )
8761
10390
  ] }),
8762
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
10391
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
8763
10392
  guestRecordAccessExplanation(access.setting),
8764
10393
  resolved
8765
10394
  ] }),
8766
- access.saving ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
8767
- access.error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
8768
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
8769
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
10395
+ access.saving ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
10396
+ access.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
10397
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
10398
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
8770
10399
  ] }) : null
8771
10400
  ] });
8772
10401
  }
@@ -8776,9 +10405,9 @@ function MeetingRecordView({
8776
10405
  }) {
8777
10406
  const host = useMeetHost();
8778
10407
  if (host === null) {
8779
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting record" }) });
10408
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting record" }) });
8780
10409
  }
8781
- return /* @__PURE__ */ jsx3(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10410
+ return /* @__PURE__ */ jsx4(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
8782
10411
  }
8783
10412
  function MeetingRecordBody({
8784
10413
  meeting,
@@ -8786,19 +10415,19 @@ function MeetingRecordBody({
8786
10415
  }) {
8787
10416
  const host = useRequiredMeetHost();
8788
10417
  const record = useMeetingRecord(meeting);
8789
- const [question, setQuestion] = useState3("");
8790
- const [tab, setTab] = useState3("summary");
10418
+ const [question, setQuestion] = useState4("");
10419
+ const [tab, setTab] = useState4("summary");
8791
10420
  if (record.failure !== null) {
8792
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
8793
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
8794
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: record.failure.message }),
8795
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
10421
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
10422
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
10423
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: record.failure.message }),
10424
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
8796
10425
  ] }) });
8797
10426
  }
8798
10427
  if (record.loading || record.record === null) {
8799
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
8800
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
8801
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
10428
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
10429
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
10430
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
8802
10431
  ] }) });
8803
10432
  }
8804
10433
  const bundle = record.record;
@@ -8817,44 +10446,44 @@ function MeetingRecordBody({
8817
10446
  );
8818
10447
  const entirelyRestricted = everyRecordPartRefused && bundle.attendees.length === 0 && bundle.liveNotes.length === 0 && bundle.transcript.length === 0 && bundle.recording === null && bundle.summary === null && bundle.decisions.length === 0 && bundle.actionItems.length === 0;
8819
10448
  if (entirelyRestricted) {
8820
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet mx-meet--record", children: [
8821
- /* @__PURE__ */ jsx3("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-head-inner", children: [
8822
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
8823
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__record-title", children: meeting.title }),
8824
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
8825
- onRejoin !== void 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10449
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
10450
+ /* @__PURE__ */ jsx4("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
10451
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10452
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__record-title", children: meeting.title }),
10453
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10454
+ onRejoin !== void 0 ? /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
8826
10455
  ] }) }),
8827
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-access", role: "status", children: [
8828
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-title", children: "About this record" }),
8829
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-message", children: notice2.message }),
8830
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10456
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
10457
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10458
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10459
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
8831
10460
  ] }, notice2.parts.join("-"))) })
8832
10461
  ] });
8833
10462
  }
8834
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet mx-meet--record", children: [
8835
- /* @__PURE__ */ jsx3("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-head-inner", children: [
8836
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
8837
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__record-title", children: meeting.title }),
8838
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
8839
- onRejoin !== void 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10463
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
10464
+ /* @__PURE__ */ jsx4("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
10465
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10466
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__record-title", children: meeting.title }),
10467
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10468
+ onRejoin !== void 0 ? /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
8840
10469
  ] }) }),
8841
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-body", children: [
8842
- restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-access", role: "status", children: [
8843
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-title", children: "About this record" }),
8844
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-message", children: notice2.message }),
8845
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10470
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-body", children: [
10471
+ restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
10472
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10473
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10474
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
8846
10475
  ] }, notice2.parts.join("-"))),
8847
10476
  attended.length === 0 ? (
8848
10477
  /* NOT SILENCE. A refused attendance read used to remove the whole
8849
10478
  section, so the reader could not tell "nobody" from "not shown". */
8850
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
8851
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
8852
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
10479
+ /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10480
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10481
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
8853
10482
  ] })
8854
- ) : /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
8855
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
8856
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__record-attendee", children: [
8857
- /* @__PURE__ */ jsx3(
10483
+ ) : /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10484
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10485
+ /* @__PURE__ */ jsx4("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-attendee", children: [
10486
+ /* @__PURE__ */ jsx4(
8858
10487
  Avatar,
8859
10488
  {
8860
10489
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -8862,26 +10491,26 @@ function MeetingRecordBody({
8862
10491
  size: 28
8863
10492
  }
8864
10493
  ),
8865
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
10494
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
8866
10495
  displayNameFor(bundle.names, person.identity, person.displayName),
8867
- person.role === "host" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Host" }) : null,
8868
- person.role === "guest" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" }) : null,
8869
- person.isAgent ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
10496
+ person.role === "host" ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Host" }) : null,
10497
+ person.role === "guest" ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" }) : null,
10498
+ person.isAgent ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
8870
10499
  ] })
8871
10500
  ] }, person.id)) })
8872
10501
  ] }),
8873
- bundle.recording !== null ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
8874
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
8875
- fileId !== null ? /* @__PURE__ */ jsxs2(Fragment, { children: [
8876
- /* @__PURE__ */ jsx3(RecordingPlayer, { fileId }),
8877
- notice !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: notice }) : null
8878
- ] }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
8879
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
8880
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
8881
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
10502
+ bundle.recording !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
10503
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10504
+ fileId !== null ? /* @__PURE__ */ jsxs3(Fragment, { children: [
10505
+ /* @__PURE__ */ jsx4(RecordingPlayer, { fileId }),
10506
+ notice !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: notice }) : null
10507
+ ] }) : /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
10508
+ ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
10509
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10510
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
8882
10511
  ] }) : null,
8883
- /* @__PURE__ */ jsxs2("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
8884
- /* @__PURE__ */ jsx3(
10512
+ /* @__PURE__ */ jsxs3("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
10513
+ /* @__PURE__ */ jsx4(
8885
10514
  "button",
8886
10515
  {
8887
10516
  type: "button",
@@ -8891,7 +10520,7 @@ function MeetingRecordBody({
8891
10520
  children: "Summary & decisions"
8892
10521
  }
8893
10522
  ),
8894
- /* @__PURE__ */ jsx3(
10523
+ /* @__PURE__ */ jsx4(
8895
10524
  "button",
8896
10525
  {
8897
10526
  type: "button",
@@ -8901,7 +10530,7 @@ function MeetingRecordBody({
8901
10530
  children: "Notes as it happened"
8902
10531
  }
8903
10532
  ),
8904
- /* @__PURE__ */ jsx3(
10533
+ /* @__PURE__ */ jsx4(
8905
10534
  "button",
8906
10535
  {
8907
10536
  type: "button",
@@ -8912,15 +10541,15 @@ function MeetingRecordBody({
8912
10541
  }
8913
10542
  )
8914
10543
  ] }),
8915
- tab === "summary" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
8916
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
8917
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
8918
- wrapUp.state === "written" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__panel-note", role: "status", children: [
8919
- /* @__PURE__ */ jsx3("p", { children: wrapUp.message }),
8920
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
8921
- ] }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
10544
+ tab === "summary" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
10545
+ /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
10546
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
10547
+ wrapUp.state === "written" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__panel-note", role: "status", children: [
10548
+ /* @__PURE__ */ jsx4("p", { children: wrapUp.message }),
10549
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
10550
+ ] }) : /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
8922
10551
  ] }),
8923
- /* @__PURE__ */ jsx3(
10552
+ /* @__PURE__ */ jsx4(
8924
10553
  NoteList,
8925
10554
  {
8926
10555
  title: "Decisions",
@@ -8932,7 +10561,7 @@ function MeetingRecordBody({
8932
10561
  )
8933
10562
  }
8934
10563
  ),
8935
- /* @__PURE__ */ jsx3(
10564
+ /* @__PURE__ */ jsx4(
8936
10565
  NoteList,
8937
10566
  {
8938
10567
  title: "Action items",
@@ -8945,42 +10574,42 @@ function MeetingRecordBody({
8945
10574
  }
8946
10575
  )
8947
10576
  ] }) : null,
8948
- tab === "notes" ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
8949
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
8950
- bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: absenceSentence(
10577
+ tab === "notes" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
10578
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
10579
+ bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(
8951
10580
  bundle,
8952
10581
  "notes",
8953
10582
  "No live notes are available for this meeting."
8954
- ) }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__note", children: [
8955
- note.window !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__badge", children: [
10583
+ ) }) : /* @__PURE__ */ jsx4("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
10584
+ note.window !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
8956
10585
  "Window ",
8957
10586
  note.window
8958
10587
  ] }) : null,
8959
10588
  note.text
8960
10589
  ] }, note.id)) })
8961
10590
  ] }) : null,
8962
- tab === "transcript" ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
8963
- /* @__PURE__ */ jsxs2("h2", { className: "mx-meet__record-section-title", children: [
10591
+ tab === "transcript" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
10592
+ /* @__PURE__ */ jsxs3("h2", { className: "mx-meet__record-section-title", children: [
8964
10593
  "Transcript",
8965
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
10594
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
8966
10595
  ] }),
8967
- blocks.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: absenceSentence(
10596
+ blocks.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(
8968
10597
  bundle,
8969
10598
  "transcript",
8970
10599
  "No transcript is available for this meeting."
8971
- ) }) : /* @__PURE__ */ jsx3("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__record-block", children: [
8972
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__record-speaker", children: [
10600
+ ) }) : /* @__PURE__ */ jsx4("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-block", children: [
10601
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__record-speaker", children: [
8973
10602
  block.speaker,
8974
- /* @__PURE__ */ jsx3("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
10603
+ /* @__PURE__ */ jsx4("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
8975
10604
  ] }),
8976
- block.lines.map((line) => /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-line", children: line.text }, line.id))
10605
+ block.lines.map((line) => /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-line", children: line.text }, line.id))
8977
10606
  ] }, block.id)) })
8978
10607
  ] }) : null,
8979
- /* @__PURE__ */ jsx3(GuestRecordAccessControl, { meeting }),
8980
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
8981
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
8982
- guestFinishedMeeting ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
8983
- /* @__PURE__ */ jsxs2(
10608
+ /* @__PURE__ */ jsx4(GuestRecordAccessControl, { meeting }),
10609
+ /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
10610
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
10611
+ guestFinishedMeeting ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
10612
+ /* @__PURE__ */ jsxs3(
8984
10613
  "form",
8985
10614
  {
8986
10615
  className: "mx-meet__composer",
@@ -8991,7 +10620,7 @@ function MeetingRecordBody({
8991
10620
  void record.ask(trimmed);
8992
10621
  },
8993
10622
  children: [
8994
- /* @__PURE__ */ jsx3(
10623
+ /* @__PURE__ */ jsx4(
8995
10624
  "input",
8996
10625
  {
8997
10626
  className: "mx-meet__input",
@@ -9001,7 +10630,7 @@ function MeetingRecordBody({
9001
10630
  "aria-label": "Ask about this meeting"
9002
10631
  }
9003
10632
  ),
9004
- /* @__PURE__ */ jsx3(
10633
+ /* @__PURE__ */ jsx4(
9005
10634
  "button",
9006
10635
  {
9007
10636
  type: "submit",
@@ -9013,8 +10642,8 @@ function MeetingRecordBody({
9013
10642
  ]
9014
10643
  }
9015
10644
  ),
9016
- record.answer !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__answer", children: record.answer }) : null,
9017
- record.coverage !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__coverage", children: [
10645
+ record.answer !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__answer", children: record.answer }) : null,
10646
+ record.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
9018
10647
  "Answered from ",
9019
10648
  record.coverage.segmentsUsed,
9020
10649
  " of ",
@@ -9025,9 +10654,9 @@ function MeetingRecordBody({
9025
10654
  record.coverage.truncated ? " (the oldest were left out)" : "",
9026
10655
  "."
9027
10656
  ] }) : null,
9028
- record.askError !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
9029
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
9030
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
10657
+ record.askError !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
10658
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
10659
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
9031
10660
  ] }) : null
9032
10661
  ] })
9033
10662
  ] })
@@ -9038,21 +10667,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
9038
10667
  var PLAYBACK_RETRY_REMEDY = "Reload the page and try again. If it still will not play, ask a meeting host to check the recording.";
9039
10668
  function RecordingPlayer(props) {
9040
10669
  const host = useMeetHost();
9041
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "This recording" });
9042
- return /* @__PURE__ */ jsx3(RecordingPlayerBody, { ...props, host });
10670
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This recording" });
10671
+ return /* @__PURE__ */ jsx4(RecordingPlayerBody, { ...props, host });
9043
10672
  }
9044
10673
  function RecordingPlayerBody({ fileId, host }) {
9045
- const [media, setMedia] = useState3(null);
9046
- const [loading, setLoading] = useState3(false);
9047
- const [error, setError] = useState3(null);
9048
- useEffect3(() => {
10674
+ const [media, setMedia] = useState4(null);
10675
+ const [loading, setLoading] = useState4(false);
10676
+ const [error, setError] = useState4(null);
10677
+ useEffect4(() => {
9049
10678
  if (media === null || media.kind !== "bytes") return void 0;
9050
10679
  const url = media.url;
9051
10680
  return () => URL.revokeObjectURL(url);
9052
10681
  }, [media]);
9053
10682
  if (media !== null) {
9054
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-section", children: [
9055
- /* @__PURE__ */ jsx3(
10683
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
10684
+ /* @__PURE__ */ jsx4(
9056
10685
  "video",
9057
10686
  {
9058
10687
  className: "mx-meet__record-player",
@@ -9094,15 +10723,15 @@ function RecordingPlayerBody({ fileId, host }) {
9094
10723
  }
9095
10724
  }
9096
10725
  ),
9097
- media.fallbackReason !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
10726
+ media.fallbackReason !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
9098
10727
  ] });
9099
10728
  }
9100
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-section", children: [
9101
- error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
9102
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: error.message }),
9103
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
10729
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
10730
+ error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
10731
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: error.message }),
10732
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
9104
10733
  ] }) : null,
9105
- /* @__PURE__ */ jsx3(
10734
+ /* @__PURE__ */ jsx4(
9106
10735
  "button",
9107
10736
  {
9108
10737
  type: "button",
@@ -9138,35 +10767,35 @@ function clockOf(iso) {
9138
10767
  function MeetingList({ baseUrl }) {
9139
10768
  const host = useMeetHost();
9140
10769
  const list = useMeetings();
9141
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "Your meetings" });
10770
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Your meetings" });
9142
10771
  if (list.failure !== null) {
9143
- return /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
9144
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
9145
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: list.failure.message }),
9146
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
10772
+ return /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
10773
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
10774
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: list.failure.message }),
10775
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
9147
10776
  ] });
9148
10777
  }
9149
10778
  if (list.loading) {
9150
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
10779
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
9151
10780
  }
9152
10781
  if (list.meetings.length === 0) {
9153
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
9154
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
9155
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Create one above. Its link works before, during and after the meeting \u2014 afterwards it opens the record." })
10782
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
10783
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
10784
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Create one above. Its link works before, during and after the meeting \u2014 afterwards it opens the record." })
9156
10785
  ] });
9157
10786
  }
9158
10787
  const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
9159
- return /* @__PURE__ */ jsx3("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
10788
+ return /* @__PURE__ */ jsx4("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
9160
10789
  const ended = meeting.endedAt !== null;
9161
- return /* @__PURE__ */ jsxs2("li", { className: "mx-meet-list__row", children: [
9162
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet-list__main", children: [
9163
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet-list__title", children: [
10790
+ return /* @__PURE__ */ jsxs3("li", { className: "mx-meet-list__row", children: [
10791
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet-list__main", children: [
10792
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet-list__title", children: [
9164
10793
  meeting.title,
9165
- ended ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Ended" }) : null
10794
+ ended ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Ended" }) : null
9166
10795
  ] }),
9167
- /* @__PURE__ */ jsx3("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
10796
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
9168
10797
  ] }),
9169
- /* @__PURE__ */ jsx3("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
10798
+ /* @__PURE__ */ jsx4("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
9170
10799
  ] }, meeting.id);
9171
10800
  }) });
9172
10801
  }
@@ -9323,15 +10952,22 @@ async function pushMeetingToGoogleCalendar(api, meetingId, target) {
9323
10952
  }
9324
10953
  export {
9325
10954
  ATTENDANCE_CSV_HEADER,
10955
+ ActivitiesControl,
10956
+ ActivitiesIcon,
9326
10957
  AiPanel,
9327
10958
  AttendanceNotice,
9328
10959
  Avatar,
10960
+ BreakoutBanner,
10961
+ BreakoutIcon,
10962
+ BreakoutsPanel,
9329
10963
  CALL_INVITE_KIND,
9330
10964
  CALL_INVITE_VERSION,
10965
+ CAPTION_LANGUAGES,
9331
10966
  CONSENT_NOTICE_ATTRIBUTE,
9332
10967
  CallButton,
9333
10968
  CameraIcon,
9334
10969
  CameraOffIcon,
10970
+ CaptionLanguageSettings,
9335
10971
  Captions,
9336
10972
  ChatIcon,
9337
10973
  ChatPanel,
@@ -9344,6 +10980,7 @@ export {
9344
10980
  DATA_TOPICS,
9345
10981
  DEFAULT_EFFECTS,
9346
10982
  DEFAULT_PAGE_SIZE,
10983
+ EMPTY_COLLAB,
9347
10984
  END_MEETING_NOT_SERVED,
9348
10985
  FILE_SESSION_PATH,
9349
10986
  FlagIcon,
@@ -9396,8 +11033,12 @@ export {
9396
11033
  PhoneIcon,
9397
11034
  PhoneOffIcon,
9398
11035
  PinIcon,
11036
+ PollIcon,
11037
+ PollsPanel,
9399
11038
  PreJoin,
11039
+ QaPanel,
9400
11040
  QualityBars,
11041
+ QuestionIcon,
9401
11042
  REACTION_TTL_MS,
9402
11043
  REFUSED_ABSENCE,
9403
11044
  ROLE_RANK,
@@ -9424,10 +11065,13 @@ export {
9424
11065
  TABLES,
9425
11066
  TRANSCRIPTION_ATTRIBUTES,
9426
11067
  TRANSCRIPTION_TOPIC,
11068
+ WhiteboardIcon,
11069
+ WhiteboardPanel,
9427
11070
  WifiLowIcon,
9428
11071
  absenceSentence,
9429
11072
  activeWrapUpSummary,
9430
11073
  announceMeeting,
11074
+ applyCollabPacket,
9431
11075
  applyRoomEvent,
9432
11076
  asCallId,
9433
11077
  asMeetingId,
@@ -9435,10 +11079,13 @@ export {
9435
11079
  asParticipantIdentity,
9436
11080
  asRoomName,
9437
11081
  asUserId,
11082
+ assignedRoom,
9438
11083
  attendanceCsv,
9439
11084
  attendanceReport,
9440
11085
  attendanceTotals,
9441
11086
  attendeeKey,
11087
+ autoAssign,
11088
+ breakoutRemainingMs,
9442
11089
  callInviteAction,
9443
11090
  callInviteText,
9444
11091
  callStateLabel,
@@ -9448,6 +11095,7 @@ export {
9448
11095
  captionSegment,
9449
11096
  changesPatch,
9450
11097
  clockPosition,
11098
+ collabFromState,
9451
11099
  computeStage,
9452
11100
  countLabel,
9453
11101
  createCallCenter,
@@ -9468,6 +11116,7 @@ export {
9468
11116
  createWebDeviceStorage,
9469
11117
  createWebEffectsStorage,
9470
11118
  createWebRoomTokenStorage,
11119
+ defaultCaptionLanguage,
9471
11120
  displayNameFor,
9472
11121
  fileDownloadPath,
9473
11122
  gridColumns,
@@ -9490,6 +11139,7 @@ export {
9490
11139
  listenOnlyNotice,
9491
11140
  loadFollowUpDraft,
9492
11141
  loadGuestMeetingRecord,
11142
+ loadMeetingActivities,
9493
11143
  loadMeetingChat,
9494
11144
  loadMeetingRecord,
9495
11145
  mapConnectionState,
@@ -9544,9 +11194,13 @@ export {
9544
11194
  unavailableFrom,
9545
11195
  uniqueAttendees,
9546
11196
  useAudioLevel,
11197
+ useAvailableActivities,
9547
11198
  useCalls,
9548
11199
  useCanModerate,
9549
11200
  useCanRecord,
11201
+ useCaptionTranslation,
11202
+ useCollab,
11203
+ useCollabPanelRequest,
9550
11204
  useConsentNotice,
9551
11205
  useDeviceSnapshot,
9552
11206
  useElapsed,
@@ -9578,6 +11232,7 @@ export {
9578
11232
  useTrack,
9579
11233
  userTopic,
9580
11234
  wasRefused,
11235
+ withItem,
9581
11236
  wrapUpStatus
9582
11237
  };
9583
11238
  //# sourceMappingURL=react.js.map