@ai-matrx/meet 0.11.43 → 0.11.45

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.
@@ -2,11 +2,38 @@
2
2
  "use client";
3
3
 
4
4
  // src/skins/meet/components.tsx
5
- import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState4 } from "react";
5
+ import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState5 } from "react";
6
6
 
7
7
  // src/react/facade.ts
8
8
  import { useMemo as useMemo5 } from "react";
9
9
 
10
+ // src/core/phase.ts
11
+ var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
12
+ var WAITING_PHASES = /* @__PURE__ */ new Set([
13
+ "waiting:host_not_started",
14
+ "waiting:knocking",
15
+ "denied",
16
+ "knock_expired"
17
+ ]);
18
+ var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
19
+ "refused:locked",
20
+ "refused:too_early",
21
+ "refused:meeting_full",
22
+ "refused:platform_capacity"
23
+ ]);
24
+ function isLivePhase(phase) {
25
+ return LIVE_PHASES.has(phase);
26
+ }
27
+ function isWaitingPhase(phase) {
28
+ return WAITING_PHASES.has(phase);
29
+ }
30
+ function isRefusedPhase(phase) {
31
+ return phase.startsWith("refused:");
32
+ }
33
+ function reasonOf(phase) {
34
+ return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
35
+ }
36
+
10
37
  // src/core/names.ts
11
38
  var CONNECTION_SEPARATOR = "~";
12
39
  function personOf(identity) {
@@ -283,11 +310,13 @@ function minutesLeft(policy, startedAtMs, nowMs) {
283
310
  }
284
311
 
285
312
  // src/core/attendance.ts
313
+ var IDLE_PREVIEW = { state: "idle", unavailable: null };
286
314
  var IDLE_MEDIA_REGION = {
287
315
  permission: { microphone: "unknown", camera: "unknown" },
288
316
  audioOutput: "ok",
289
317
  notice: null,
290
- offer: null
318
+ offer: null,
319
+ preview: { microphone: IDLE_PREVIEW, camera: IDLE_PREVIEW }
291
320
  };
292
321
  var IDLE_TRACK = { enabled: false, unavailable: null };
293
322
  var IDLE_MEDIA = {
@@ -320,27 +349,6 @@ function isObserverRole(role) {
320
349
  return role === "viewer";
321
350
  }
322
351
 
323
- // src/core/phase.ts
324
- var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
325
- var WAITING_PHASES = /* @__PURE__ */ new Set([
326
- "waiting:host_not_started",
327
- "waiting:knocking",
328
- "denied",
329
- "knock_expired"
330
- ]);
331
- function isLivePhase(phase) {
332
- return LIVE_PHASES.has(phase);
333
- }
334
- function isWaitingPhase(phase) {
335
- return WAITING_PHASES.has(phase);
336
- }
337
- function isRefusedPhase(phase) {
338
- return phase.startsWith("refused:");
339
- }
340
- function reasonOf(phase) {
341
- return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
342
- }
343
-
344
352
  // src/core/app-panel.ts
345
353
  function appPanelOf(meeting) {
346
354
  const raw = meeting?.metadata?.["app_panel"];
@@ -446,7 +454,7 @@ function effectiveStanding(snapshot) {
446
454
  var REACTION_TTL_MS = 5e3;
447
455
 
448
456
  // src/react/root.tsx
449
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
457
+ import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
450
458
 
451
459
  // src/core/media-supervisor.ts
452
460
  function classifyDeviceFailure(error, permission) {
@@ -508,7 +516,7 @@ function deviceFixSteps(kind, reason, where) {
508
516
  case "safari":
509
517
  return where.os === "ios" ? [`Settings \u203A Apps \u203A Safari \u203A ${device}`, "Choose Allow", "Return here and press Try again"] : ["Safari \u203A Settings for This Website", `Set ${device} to Allow`, "Press Try again"];
510
518
  default:
511
- return ["Click the icon left of the web address", `Set ${device} to Allow`, "Press Try again"];
519
+ return ["Click the site settings icon in the address bar", `Set ${device} to Allow`, "Press Try again"];
512
520
  }
513
521
  case "blocked_os": {
514
522
  const app = where.browser === "chrome" ? "Google Chrome" : where.browser === "edge" ? "Microsoft Edge" : where.browser === "firefox" ? "Firefox" : "your browser";
@@ -602,6 +610,21 @@ function observedDevice(track, permission = "unknown", held = null) {
602
610
  const reason = deviceUnavailableReason(track, permission);
603
611
  return reason === null ? "muted_by_me" : `unavailable:${reason}`;
604
612
  }
613
+ function observedPreview(preview, permission = "unknown") {
614
+ if (permission === "denied") return "unavailable:denied";
615
+ switch (preview.state) {
616
+ case "on":
617
+ return "on";
618
+ case "off":
619
+ return "muted_by_me";
620
+ case "prompting":
621
+ return "prompting";
622
+ case "unavailable":
623
+ return `unavailable:${preview.unavailable?.reason ?? "failed"}`;
624
+ default:
625
+ return null;
626
+ }
627
+ }
605
628
  function endedRecord(snapshot, given) {
606
629
  const record = snapshot?.meeting ?? given;
607
630
  return record !== null && record.endedAt !== null;
@@ -625,18 +648,22 @@ function observe(input) {
625
648
  const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
626
649
  const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
627
650
  const deviceInPlay = phase === "joining" || inCall;
651
+ const region = snapshot?.mediaRegion;
652
+ const atPrejoin = phase === "prejoin" && region !== void 0;
628
653
  return {
629
654
  phase,
630
655
  reason: phase === "ended" ? snapshot?.reason ?? null : snapshot?.reason ?? reasonOf(phase),
631
656
  role,
632
- connection: snapshot?.connection ?? "stable",
657
+ // `net-blip`: in the call, a drop shorter than `reconnect_banner_delay_ms` is not something the
658
+ // person sees — the contract says what is on screen, so it reads `stable` until the banner shows.
659
+ connection: snapshot === null ? "stable" : inCall && snapshot.connection !== "stable" && !snapshot.connectionBanner ? "stable" : snapshot.connection,
633
660
  hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot !== null && isWaitingPhase(snapshot.phase) ? snapshot.waiting?.admittersPresent ?? null : null,
634
661
  lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
635
662
  recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
636
663
  // S6c: the autoplay region is known only inside the room (no remote audio exists elsewhere).
637
664
  audioBlocked: inCall && snapshot !== null ? snapshot.mediaRegion.audioOutput === "blocked" : null,
638
- camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : null,
639
- microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : null
665
+ camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : atPrejoin ? observedPreview(region.preview.camera, region.permission.camera) : null,
666
+ microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : atPrejoin ? observedPreview(region.preview.microphone, region.permission.microphone) : null
640
667
  };
641
668
  }
642
669
  function lockedFor(snapshot, kind, inCall) {
@@ -890,7 +917,7 @@ function useCanRecord() {
890
917
  }
891
918
 
892
919
  // src/react/root.tsx
893
- import { jsx as jsx2 } from "react/jsx-runtime";
920
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
894
921
  function useCoreObservation(options = {}) {
895
922
  const snapshot = useMeetSnapshot();
896
923
  const { meeting, phase, reason } = options;
@@ -1047,7 +1074,7 @@ function useMeetAppPanel(meeting) {
1047
1074
  }
1048
1075
 
1049
1076
  // src/react/hooks.ts
1050
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState2, useSyncExternalStore as useSyncExternalStore2 } from "react";
1077
+ import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState3, useSyncExternalStore as useSyncExternalStore2 } from "react";
1051
1078
  import { useRealtimeManager as useRealtimeManager2 } from "@ai-matrx/realtime/react";
1052
1079
 
1053
1080
  // src/core/record.ts
@@ -1173,7 +1200,8 @@ function useRoom() {
1173
1200
  failure: snapshot?.failure ?? null,
1174
1201
  secondDevice: snapshot?.secondDevice ?? null,
1175
1202
  local,
1176
- canShareScreen: engine?.supportsScreenShare() ?? true,
1203
+ // An observer (role `viewer`) publishes nothing: no Share screen to press and be refused (MD-16).
1204
+ canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null),
1177
1205
  join: useCallback2(
1178
1206
  async (request) => requireEngine(engine, "join").join(request),
1179
1207
  [engine]
@@ -1230,7 +1258,7 @@ function useRoom() {
1230
1258
  }
1231
1259
  function useStage(pageSize = DEFAULT_PAGE_SIZE) {
1232
1260
  const snapshot = useMeetSnapshot();
1233
- const [page, setPage] = useState2(0);
1261
+ const [page, setPage] = useState3(0);
1234
1262
  const stage = useMemo4(
1235
1263
  () => computeStage({
1236
1264
  participants: snapshot?.participants ?? [],
@@ -1291,7 +1319,7 @@ function useLobby() {
1291
1319
  };
1292
1320
  }
1293
1321
  function useCountdown(untilMs) {
1294
- const [now, setNow] = useState2(() => Date.now());
1322
+ const [now, setNow] = useState3(() => Date.now());
1295
1323
  const active = typeof untilMs === "number" && untilMs > now;
1296
1324
  useEffect3(() => {
1297
1325
  if (!active) return void 0;
@@ -1304,7 +1332,7 @@ function useCountdown(untilMs) {
1304
1332
  }
1305
1333
  function useKnockNotice() {
1306
1334
  const lobby = useLobby();
1307
- const [dismissed, setDismissed] = useState2([]);
1335
+ const [dismissed, setDismissed] = useState3([]);
1308
1336
  const keyOf = (entry) => `${entry.identity}@${entry.knockedAt}`;
1309
1337
  const open = lobby.canAdmit ? lobby.waiting.filter((entry) => !dismissed.includes(keyOf(entry))) : [];
1310
1338
  const knocker = open[0] ?? null;
@@ -1390,11 +1418,11 @@ function useMeetAi() {
1390
1418
  const host = useMeetHost();
1391
1419
  const snapshot = useMeetSnapshot();
1392
1420
  const isHost = useIsHost();
1393
- const [asking, setAsking] = useState2(false);
1394
- const [answer, setAnswer] = useState2(null);
1395
- const [coverage, setCoverage] = useState2(null);
1396
- const [phase, setPhase] = useState2(null);
1397
- const [error, setError] = useState2(null);
1421
+ const [asking, setAsking] = useState3(false);
1422
+ const [answer, setAnswer] = useState3(null);
1423
+ const [coverage, setCoverage] = useState3(null);
1424
+ const [phase, setPhase] = useState3(null);
1425
+ const [error, setError] = useState3(null);
1398
1426
  const ai = host?.ai ?? null;
1399
1427
  const meeting = snapshot?.meeting ?? null;
1400
1428
  const participants = snapshot?.participants ?? [];
@@ -1547,8 +1575,8 @@ function useEndMeeting() {
1547
1575
  const host = useMeetHost();
1548
1576
  const snapshot = useMeetSnapshot();
1549
1577
  const isHost = useIsHost();
1550
- const [ending, setEnding] = useState2(false);
1551
- const [notice, setNotice] = useState2(null);
1578
+ const [ending, setEnding] = useState3(false);
1579
+ const [notice, setNotice] = useState3(null);
1552
1580
  const meeting = snapshot?.meeting ?? null;
1553
1581
  const session = host?.meetings ?? null;
1554
1582
  return {
@@ -1599,6 +1627,12 @@ function useMediaSupervisor() {
1599
1627
  retry: useCallback2(
1600
1628
  async (kind) => kind === "microphone" ? engine?.setMicrophoneEnabled(true) : engine?.setCameraEnabled(true),
1601
1629
  [engine]
1630
+ ),
1631
+ reportPreview: useCallback2(
1632
+ (kind, outcome) => {
1633
+ void engine?.previewDevice(kind, outcome);
1634
+ },
1635
+ [engine]
1602
1636
  )
1603
1637
  };
1604
1638
  }
@@ -1618,7 +1652,7 @@ function useReactions() {
1618
1652
  return snapshot?.reactions ?? [];
1619
1653
  }
1620
1654
  function useElapsed(startedAt) {
1621
- const [now, setNow] = useState2(() => Date.now());
1655
+ const [now, setNow] = useState3(() => Date.now());
1622
1656
  useEffect3(() => {
1623
1657
  if (startedAt === null) return void 0;
1624
1658
  const timer = setInterval(() => setNow(Date.now()), 1e3);
@@ -1635,7 +1669,7 @@ function useHostControls() {
1635
1669
  (participant) => participant.identity === snapshot.localIdentity
1636
1670
  );
1637
1671
  const actor = me === void 0 ? void 0 : { ...me, role };
1638
- const [busy, setBusy] = useState2(false);
1672
+ const [busy, setBusy] = useState3(false);
1639
1673
  const inRoom = host?.inRoom ?? null;
1640
1674
  const store = host?.store ?? null;
1641
1675
  const notice = snapshot?.actionNotice ?? null;
@@ -1718,7 +1752,7 @@ function useModerationNotice() {
1718
1752
  };
1719
1753
  }
1720
1754
  function useAudioLevel(stream) {
1721
- const [level, setLevel] = useState2(0);
1755
+ const [level, setLevel] = useState3(0);
1722
1756
  useEffect3(() => {
1723
1757
  if (stream === null || stream.getAudioTracks().length === 0) {
1724
1758
  setLevel(0);
@@ -1789,10 +1823,10 @@ function useGuestRecordAccess(meeting) {
1789
1823
  const host = useMeetHost();
1790
1824
  const api = host?.api ?? null;
1791
1825
  const stored = guestRecordAccessSetting(meeting);
1792
- const [chosen, setChosen] = useState2(null);
1793
- const [effective, setEffective] = useState2(null);
1794
- const [saving, setSaving] = useState2(false);
1795
- const [error, setError] = useState2(null);
1826
+ const [chosen, setChosen] = useState3(null);
1827
+ const [effective, setEffective] = useState3(null);
1828
+ const [saving, setSaving] = useState3(false);
1829
+ const [error, setError] = useState3(null);
1796
1830
  useEffect3(() => {
1797
1831
  setChosen(null);
1798
1832
  }, [stored, meeting?.id]);
@@ -1831,7 +1865,7 @@ function useGuestRecordAccess(meeting) {
1831
1865
  function useLivePolicy() {
1832
1866
  const snapshot = useMeetSnapshot();
1833
1867
  const role = useRole();
1834
- const [now, setNow] = useState2(() => Date.now());
1868
+ const [now, setNow] = useState3(() => Date.now());
1835
1869
  const limited = (snapshot?.livePolicy.timeLimitMinutes ?? 0) > 0;
1836
1870
  useEffect3(() => {
1837
1871
  if (!limited) return void 0;
@@ -1919,6 +1953,39 @@ function useCollabPanelRequest(onRequest) {
1919
1953
  // src/core/reactions.ts
1920
1954
  var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F602}", "\u{1F62E}", "\u{1F622}", "\u{1F914}", "\u{1F44E}"];
1921
1955
 
1956
+ // src/core/speaking-detector.ts
1957
+ function createSpeakingWhileMutedDetector(options = {}) {
1958
+ const threshold = options.threshold ?? 0.06;
1959
+ const holdMs = options.holdMs ?? 600;
1960
+ const gapMs = options.gapMs ?? 400;
1961
+ const cooldownMs = options.cooldownMs ?? 2e4;
1962
+ let speechStart = null;
1963
+ let lastLoud = null;
1964
+ let firedAt = null;
1965
+ return {
1966
+ feed(level, at) {
1967
+ if (level >= threshold) {
1968
+ if (speechStart === null || lastLoud === null || at - lastLoud > gapMs) speechStart = at;
1969
+ lastLoud = at;
1970
+ } else if (lastLoud !== null && at - lastLoud > gapMs) {
1971
+ speechStart = null;
1972
+ lastLoud = null;
1973
+ }
1974
+ if (speechStart === null || at - speechStart < holdMs) return false;
1975
+ if (firedAt !== null && at - firedAt < cooldownMs) return false;
1976
+ firedAt = at;
1977
+ speechStart = null;
1978
+ lastLoud = null;
1979
+ return true;
1980
+ },
1981
+ reset() {
1982
+ speechStart = null;
1983
+ lastLoud = null;
1984
+ firedAt = null;
1985
+ }
1986
+ };
1987
+ }
1988
+
1922
1989
  // src/react/facade.ts
1923
1990
  var NO_ACTIONS = {
1924
1991
  join: async () => void 0,
@@ -1939,6 +2006,10 @@ function actionsFor(host) {
1939
2006
  leave: () => engine.leave(),
1940
2007
  backToPrejoin: () => engine.backToPrejoin(),
1941
2008
  retry: () => {
2009
+ if (RETRYABLE_REFUSALS.has(store.snapshot().phase)) {
2010
+ void engine.rejoin().catch(() => void 0);
2011
+ return;
2012
+ }
1942
2013
  store.dispatch({ type: "retry", click: true });
1943
2014
  },
1944
2015
  resolved: () => {
@@ -1983,10 +2054,10 @@ function useMeetCore() {
1983
2054
  import { Alert, AlertDescription, Button, Checkbox, ErrorBox, Label, SegmentedControl, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ai-matrx/design-system";
1984
2055
 
1985
2056
  // src/skins/meet/collab.tsx
1986
- import { useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
2057
+ import { useEffect as useEffect5, useRef as useRef5, useState as useState4 } from "react";
1987
2058
 
1988
2059
  // src/skins/meet/icons.tsx
1989
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
2060
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1990
2061
  function Icon({ children, ...props }) {
1991
2062
  return /* @__PURE__ */ jsx4(
1992
2063
  "svg",
@@ -2007,14 +2078,14 @@ function Icon({ children, ...props }) {
2007
2078
  );
2008
2079
  }
2009
2080
  function MicIcon(props) {
2010
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2081
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2011
2082
  /* @__PURE__ */ jsx4("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
2012
2083
  /* @__PURE__ */ jsx4("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2013
2084
  /* @__PURE__ */ jsx4("path", { d: "M12 19v3" })
2014
2085
  ] });
2015
2086
  }
2016
2087
  function MicOffIcon(props) {
2017
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2088
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2018
2089
  /* @__PURE__ */ jsx4("path", { d: "M2 2l20 20" }),
2019
2090
  /* @__PURE__ */ jsx4("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
2020
2091
  /* @__PURE__ */ jsx4("path", { d: "M15 9.34V5a3 3 0 0 0-5.94-.6" }),
@@ -2023,20 +2094,20 @@ function MicOffIcon(props) {
2023
2094
  ] });
2024
2095
  }
2025
2096
  function CameraIcon(props) {
2026
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2097
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2027
2098
  /* @__PURE__ */ jsx4("path", { d: "m23 7-7 5 7 5V7Z" }),
2028
2099
  /* @__PURE__ */ jsx4("rect", { x: "1", y: "5", width: "15", height: "14", rx: "2" })
2029
2100
  ] });
2030
2101
  }
2031
2102
  function CameraOffIcon(props) {
2032
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2103
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2033
2104
  /* @__PURE__ */ jsx4("path", { d: "M2 2l20 20" }),
2034
2105
  /* @__PURE__ */ jsx4("path", { d: "M10.66 5H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10" }),
2035
2106
  /* @__PURE__ */ jsx4("path", { d: "M16 16a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2" })
2036
2107
  ] });
2037
2108
  }
2038
2109
  function ScreenShareIcon(props) {
2039
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2110
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2040
2111
  /* @__PURE__ */ jsx4("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
2041
2112
  /* @__PURE__ */ jsx4("path", { d: "M8 21h8M12 17v4" }),
2042
2113
  /* @__PURE__ */ jsx4("path", { d: "M12 13V8m0 0-2.5 2.5M12 8l2.5 2.5" })
@@ -2049,7 +2120,7 @@ function PhoneOffIcon(props) {
2049
2120
  return /* @__PURE__ */ jsx4(Icon, { fill: "currentColor", stroke: "none", ...props, children: /* @__PURE__ */ jsx4("path", { d: "M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08a.99.99 0 0 1-.29-.7c0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28a11.27 11.27 0 0 0-2.67-1.85.996.996 0 0 1-.56-.9v-3.1C15.15 9.25 13.6 9 12 9Z" }) });
2050
2121
  }
2051
2122
  function HandIcon(props) {
2052
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2123
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2053
2124
  /* @__PURE__ */ jsx4("path", { d: "M18 11V6a2 2 0 0 0-4 0v5" }),
2054
2125
  /* @__PURE__ */ jsx4("path", { d: "M14 10V4a2 2 0 0 0-4 0v7" }),
2055
2126
  /* @__PURE__ */ jsx4("path", { d: "M10 10.5V6a2 2 0 0 0-4 0v8" }),
@@ -2060,7 +2131,7 @@ function ChatIcon(props) {
2060
2131
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z" }) });
2061
2132
  }
2062
2133
  function PeopleIcon(props) {
2063
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2134
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2064
2135
  /* @__PURE__ */ jsx4("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
2065
2136
  /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "7", r: "4" }),
2066
2137
  /* @__PURE__ */ jsx4("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" })
@@ -2070,37 +2141,37 @@ function RecordIcon(props) {
2070
2141
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "8", fill: "currentColor", stroke: "none" }) });
2071
2142
  }
2072
2143
  function SparklesIcon(props) {
2073
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2144
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2074
2145
  /* @__PURE__ */ jsx4("path", { d: "M12 3l1.9 4.6L18.5 9.5l-4.6 1.9L12 16l-1.9-4.6L5.5 9.5l4.6-1.9L12 3Z" }),
2075
2146
  /* @__PURE__ */ jsx4("path", { d: "M19 15l.9 2.1 2.1.9-2.1.9-.9 2.1-.9-2.1-2.1-.9 2.1-.9L19 15Z" })
2076
2147
  ] });
2077
2148
  }
2078
2149
  function CaptionsIcon(props) {
2079
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2150
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2080
2151
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
2081
2152
  /* @__PURE__ */ jsx4("path", { d: "M10 10.5a2 2 0 1 0 0 3M16 10.5a2 2 0 1 0 0 3" })
2082
2153
  ] });
2083
2154
  }
2084
2155
  function NotesIcon(props) {
2085
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2156
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2086
2157
  /* @__PURE__ */ jsx4("path", { d: "M4 20l1-4L16.5 4.5a2.1 2.1 0 0 1 3 3L8 19l-4 1Z" }),
2087
2158
  /* @__PURE__ */ jsx4("path", { d: "M14 7l3 3" })
2088
2159
  ] });
2089
2160
  }
2090
2161
  function LockIcon(props) {
2091
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2162
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2092
2163
  /* @__PURE__ */ jsx4("rect", { x: "4", y: "10", width: "16", height: "11", rx: "2" }),
2093
2164
  /* @__PURE__ */ jsx4("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
2094
2165
  ] });
2095
2166
  }
2096
2167
  function LayoutIcon(props) {
2097
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2168
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2098
2169
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2099
2170
  /* @__PURE__ */ jsx4("path", { d: "M3 9h18M9 21V9" })
2100
2171
  ] });
2101
2172
  }
2102
2173
  function SettingsIcon(props) {
2103
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2174
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2104
2175
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "3" }),
2105
2176
  /* @__PURE__ */ jsx4("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
2106
2177
  ] });
@@ -2112,19 +2183,19 @@ function CloseIcon(props) {
2112
2183
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" }) });
2113
2184
  }
2114
2185
  function PinIcon(props) {
2115
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2186
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2116
2187
  /* @__PURE__ */ jsx4("path", { d: "M12 17v5" }),
2117
2188
  /* @__PURE__ */ jsx4("path", { d: "M9 2h6l-1 6 3.5 3.5V14H6.5v-2.5L10 8 9 2Z" })
2118
2189
  ] });
2119
2190
  }
2120
2191
  function WifiLowIcon(props) {
2121
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2192
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2122
2193
  /* @__PURE__ */ jsx4("path", { d: "M12 20h.01" }),
2123
2194
  /* @__PURE__ */ jsx4("path", { d: "M8.5 16.5a5 5 0 0 1 7 0" })
2124
2195
  ] });
2125
2196
  }
2126
2197
  function SmileIcon(props) {
2127
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2198
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2128
2199
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
2129
2200
  /* @__PURE__ */ jsx4("path", { d: "M8 14s1.5 2 4 2 4-2 4-2" }),
2130
2201
  /* @__PURE__ */ jsx4("line", { x1: "9", x2: "9.01", y1: "9", y2: "9" }),
@@ -2132,20 +2203,20 @@ function SmileIcon(props) {
2132
2203
  ] });
2133
2204
  }
2134
2205
  function MoreIcon(props) {
2135
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2206
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2136
2207
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "1" }),
2137
2208
  /* @__PURE__ */ jsx4("circle", { cx: "19", cy: "12", r: "1" }),
2138
2209
  /* @__PURE__ */ jsx4("circle", { cx: "5", cy: "12", r: "1" })
2139
2210
  ] });
2140
2211
  }
2141
2212
  function SearchIcon(props) {
2142
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2213
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2143
2214
  /* @__PURE__ */ jsx4("circle", { cx: "11", cy: "11", r: "8" }),
2144
2215
  /* @__PURE__ */ jsx4("path", { d: "m21 21-4.3-4.3" })
2145
2216
  ] });
2146
2217
  }
2147
2218
  function KeyboardIcon(props) {
2148
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2219
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2149
2220
  /* @__PURE__ */ jsx4("path", { d: "M10 8h.01M12 12h.01M14 8h.01M16 12h.01M18 8h.01M6 8h.01M7 16h10M8 12h.01" }),
2150
2221
  /* @__PURE__ */ jsx4("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" })
2151
2222
  ] });
@@ -2154,7 +2225,7 @@ function SpotlightIcon(props) {
2154
2225
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M12 2 15 8.5 22 9.3 17 14 18.2 21 12 17.6 5.8 21 7 14 2 9.3 9 8.5Z" }) });
2155
2226
  }
2156
2227
  function SignalIcon({ bars, ...props }) {
2157
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2228
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2158
2229
  /* @__PURE__ */ jsx4("path", { d: "M4 20v-2", opacity: bars >= 1 ? 1 : 0.3 }),
2159
2230
  /* @__PURE__ */ jsx4("path", { d: "M10 20v-6", opacity: bars >= 2 ? 1 : 0.3 }),
2160
2231
  /* @__PURE__ */ jsx4("path", { d: "M16 20V9", opacity: bars >= 3 ? 1 : 0.3 }),
@@ -2162,14 +2233,14 @@ function SignalIcon({ bars, ...props }) {
2162
2233
  ] });
2163
2234
  }
2164
2235
  function SpeakerIcon(props) {
2165
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2236
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2166
2237
  /* @__PURE__ */ jsx4("path", { d: "M11 5 6 9H2v6h4l5 4V5Z" }),
2167
2238
  /* @__PURE__ */ jsx4("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" }),
2168
2239
  /* @__PURE__ */ jsx4("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" })
2169
2240
  ] });
2170
2241
  }
2171
2242
  function FlagIcon(props) {
2172
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2243
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2173
2244
  /* @__PURE__ */ jsx4("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2174
2245
  /* @__PURE__ */ jsx4("line", { x1: "4", x2: "4", y1: "22", y2: "15" })
2175
2246
  ] });
@@ -2178,35 +2249,35 @@ function PencilIcon(props) {
2178
2249
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
2179
2250
  }
2180
2251
  function ActivitiesIcon(props) {
2181
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2252
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2182
2253
  /* @__PURE__ */ jsx4("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" }),
2183
2254
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
2184
2255
  /* @__PURE__ */ jsx4("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
2185
2256
  ] });
2186
2257
  }
2187
2258
  function PollIcon(props) {
2188
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2259
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2189
2260
  /* @__PURE__ */ jsx4("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
2190
2261
  /* @__PURE__ */ jsx4("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
2191
2262
  /* @__PURE__ */ jsx4("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
2192
2263
  ] });
2193
2264
  }
2194
2265
  function QuestionIcon(props) {
2195
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2266
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2196
2267
  /* @__PURE__ */ jsx4("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
2197
2268
  /* @__PURE__ */ jsx4("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
2198
2269
  /* @__PURE__ */ jsx4("path", { d: "M12 17h.01" })
2199
2270
  ] });
2200
2271
  }
2201
2272
  function WhiteboardIcon(props) {
2202
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2273
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2203
2274
  /* @__PURE__ */ jsx4("path", { d: "M2 3h20" }),
2204
2275
  /* @__PURE__ */ jsx4("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
2205
2276
  /* @__PURE__ */ jsx4("path", { d: "m7 21 5-5 5 5" })
2206
2277
  ] });
2207
2278
  }
2208
2279
  function BreakoutIcon(props) {
2209
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2280
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2210
2281
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
2211
2282
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
2212
2283
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
@@ -2216,29 +2287,32 @@ function UpvoteIcon(props) {
2216
2287
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
2217
2288
  }
2218
2289
  function EraserIcon(props) {
2219
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2290
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2220
2291
  /* @__PURE__ */ jsx4("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" }),
2221
2292
  /* @__PURE__ */ jsx4("path", { d: "M22 21H7" }),
2222
2293
  /* @__PURE__ */ jsx4("path", { d: "m5 11 9 9" })
2223
2294
  ] });
2224
2295
  }
2225
2296
  function HighlighterIcon(props) {
2226
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2297
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2227
2298
  /* @__PURE__ */ jsx4("path", { d: "m9 11-6 6v3h9l3-3" }),
2228
2299
  /* @__PURE__ */ jsx4("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" })
2229
2300
  ] });
2230
2301
  }
2231
2302
  function UndoIcon(props) {
2232
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2303
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2233
2304
  /* @__PURE__ */ jsx4("path", { d: "M9 14 4 9l5-5" }),
2234
2305
  /* @__PURE__ */ jsx4("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" })
2235
2306
  ] });
2236
2307
  }
2308
+ function ChevronUpIcon(props) {
2309
+ return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "m6 15 6-6 6 6" }) });
2310
+ }
2237
2311
 
2238
2312
  // src/skins/meet/collab.tsx
2239
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
2313
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
2240
2314
  function useNotice() {
2241
- const [notice, setNotice] = useState3(null);
2315
+ const [notice, setNotice] = useState4(null);
2242
2316
  useEffect5(() => {
2243
2317
  if (notice === null) return void 0;
2244
2318
  const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
@@ -2267,16 +2341,16 @@ function ActivitiesControl({
2267
2341
  active,
2268
2342
  onOpen
2269
2343
  }) {
2270
- const [open, setOpen] = useState3(false);
2344
+ const [open, setOpen] = useState4(false);
2271
2345
  const available = useAvailableActivities();
2272
2346
  const attention = useActivityAttention();
2273
2347
  if (available.length === 0) return null;
2274
- return /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
2275
- /* @__PURE__ */ jsxs2(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
2348
+ return /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
2349
+ /* @__PURE__ */ jsxs3(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
2276
2350
  /* @__PURE__ */ jsx5(ActivitiesIcon, {}),
2277
2351
  attention ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
2278
2352
  ] }),
2279
- open ? /* @__PURE__ */ jsx5(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx5("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs2(
2353
+ open ? /* @__PURE__ */ jsx5(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx5("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs3(
2280
2354
  MenuItem,
2281
2355
  {
2282
2356
  onSelect: () => {
@@ -2295,11 +2369,11 @@ function ActivitiesControl({
2295
2369
  }
2296
2370
  function PollComposer({ maxOptions, onDone }) {
2297
2371
  const { act } = useCollab();
2298
- const [question, setQuestion] = useState3("");
2299
- const [options, setOptions] = useState3(["", ""]);
2300
- const [multiple, setMultiple] = useState3(false);
2301
- const [anonymous, setAnonymous] = useState3(false);
2302
- const [busy, setBusy] = useState3(false);
2372
+ const [question, setQuestion] = useState4("");
2373
+ const [options, setOptions] = useState4(["", ""]);
2374
+ const [multiple, setMultiple] = useState4(false);
2375
+ const [anonymous, setAnonymous] = useState4(false);
2376
+ const [busy, setBusy] = useState4(false);
2303
2377
  const [notice, show] = useNotice();
2304
2378
  const filled = options.map((o) => o.trim()).filter(Boolean);
2305
2379
  const ready = question.trim().length > 0 && filled.length >= 2;
@@ -2322,7 +2396,7 @@ function PollComposer({ maxOptions, onDone }) {
2322
2396
  setBusy(false);
2323
2397
  onDone();
2324
2398
  };
2325
- return /* @__PURE__ */ jsxs2(
2399
+ return /* @__PURE__ */ jsxs3(
2326
2400
  "form",
2327
2401
  {
2328
2402
  className: "mx-meet__collab-card",
@@ -2331,7 +2405,7 @@ function PollComposer({ maxOptions, onDone }) {
2331
2405
  if (ready) void save(true);
2332
2406
  },
2333
2407
  children: [
2334
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
2408
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
2335
2409
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Question" }),
2336
2410
  /* @__PURE__ */ jsx5(
2337
2411
  "input",
@@ -2345,7 +2419,7 @@ function PollComposer({ maxOptions, onDone }) {
2345
2419
  }
2346
2420
  )
2347
2421
  ] }),
2348
- options.map((option, index) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
2422
+ options.map((option, index) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
2349
2423
  /* @__PURE__ */ jsx5(
2350
2424
  "input",
2351
2425
  {
@@ -2360,16 +2434,16 @@ function PollComposer({ maxOptions, onDone }) {
2360
2434
  options.length > 2 ? /* @__PURE__ */ jsx5(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ jsx5(CloseIcon, { width: 14, height: 14 }) }) : null
2361
2435
  ] }, index)),
2362
2436
  options.length < maxOptions ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
2363
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
2437
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
2364
2438
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
2365
2439
  "People can pick more than one"
2366
2440
  ] }),
2367
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
2441
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
2368
2442
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
2369
2443
  "Anonymous \u2014 nobody sees who picked what"
2370
2444
  ] }),
2371
2445
  /* @__PURE__ */ jsx5(Notice, { notice }),
2372
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
2446
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
2373
2447
  /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
2374
2448
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
2375
2449
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
@@ -2380,7 +2454,7 @@ function PollComposer({ maxOptions, onDone }) {
2380
2454
  }
2381
2455
  function PollCard({ poll }) {
2382
2456
  const { act, isHost } = useCollab();
2383
- const [picked, setPicked] = useState3(poll.myVote.slice());
2457
+ const [picked, setPicked] = useState4(poll.myVote.slice());
2384
2458
  const [notice, show] = useNotice();
2385
2459
  useEffect5(() => setPicked(poll.myVote.slice()), [poll.myVote]);
2386
2460
  const counts = poll.options.some((o) => o.votes !== void 0);
@@ -2392,12 +2466,12 @@ function PollCard({ poll }) {
2392
2466
  if (!canVote) return;
2393
2467
  setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
2394
2468
  };
2395
- return /* @__PURE__ */ jsxs2("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
2396
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__collab-head", children: [
2469
+ return /* @__PURE__ */ jsxs3("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
2470
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__collab-head", children: [
2397
2471
  /* @__PURE__ */ jsx5("strong", { className: "mx-meet__collab-title", children: poll.question }),
2398
2472
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: stateWord })
2399
2473
  ] }),
2400
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
2474
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
2401
2475
  poll.multiple ? "Pick any." : "Pick one.",
2402
2476
  poll.anonymous ? " Anonymous." : "",
2403
2477
  counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
@@ -2406,8 +2480,8 @@ function PollCard({ poll }) {
2406
2480
  /* @__PURE__ */ jsx5("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
2407
2481
  const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
2408
2482
  const chosen = picked.includes(option.id);
2409
- return /* @__PURE__ */ jsxs2("li", { children: [
2410
- /* @__PURE__ */ jsxs2(
2483
+ return /* @__PURE__ */ jsxs3("li", { children: [
2484
+ /* @__PURE__ */ jsxs3(
2411
2485
  "button",
2412
2486
  {
2413
2487
  type: "button",
@@ -2418,7 +2492,7 @@ function PollCard({ poll }) {
2418
2492
  children: [
2419
2493
  counts ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
2420
2494
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__poll-text", children: option.text }),
2421
- counts ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__poll-count", children: [
2495
+ counts ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__poll-count", children: [
2422
2496
  option.votes ?? 0,
2423
2497
  " \xB7 ",
2424
2498
  share,
@@ -2431,7 +2505,7 @@ function PollCard({ poll }) {
2431
2505
  ] }, option.id);
2432
2506
  }) }),
2433
2507
  /* @__PURE__ */ jsx5(Notice, { notice }),
2434
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
2508
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
2435
2509
  canVote ? /* @__PURE__ */ jsx5(
2436
2510
  "button",
2437
2511
  {
@@ -2451,11 +2525,11 @@ function PollCard({ poll }) {
2451
2525
  }
2452
2526
  function PollsPanel({ onClose }) {
2453
2527
  const { collab, isHost } = useCollab();
2454
- const [composing, setComposing] = useState3(false);
2528
+ const [composing, setComposing] = useState4(false);
2455
2529
  const polls = collab?.polls ?? [];
2456
2530
  const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
2457
2531
  const ordered = [...polls].reverse();
2458
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Polls", onClose, children: [
2532
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Polls", onClose, children: [
2459
2533
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
2460
2534
  isHost && !composing ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
2461
2535
  isHost && composing ? /* @__PURE__ */ jsx5(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
@@ -2465,12 +2539,12 @@ function PollsPanel({ onClose }) {
2465
2539
  }
2466
2540
  function QuestionCard({ question }) {
2467
2541
  const { act, isHost } = useCollab();
2468
- const [answering, setAnswering] = useState3(false);
2469
- const [reply, setReply] = useState3("");
2542
+ const [answering, setAnswering] = useState4(false);
2543
+ const [reply, setReply] = useState4("");
2470
2544
  const [notice, show] = useNotice();
2471
- return /* @__PURE__ */ jsxs2("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
2472
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-row", children: [
2473
- /* @__PURE__ */ jsxs2(
2545
+ return /* @__PURE__ */ jsxs3("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
2546
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__question-row", children: [
2547
+ /* @__PURE__ */ jsxs3(
2474
2548
  "button",
2475
2549
  {
2476
2550
  type: "button",
@@ -2485,15 +2559,15 @@ function QuestionCard({ question }) {
2485
2559
  ]
2486
2560
  }
2487
2561
  ),
2488
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-body", children: [
2489
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
2562
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__question-body", children: [
2563
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
2490
2564
  /* @__PURE__ */ jsx5("strong", { children: question.mine ? "You" : question.askerName }),
2491
2565
  question.mine && question.anonymous ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
2492
2566
  question.state !== "open" ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
2493
2567
  ] }),
2494
2568
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__chat-text", children: question.text }),
2495
- question.answer !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__question-answer", children: [
2496
- /* @__PURE__ */ jsxs2("strong", { children: [
2569
+ question.answer !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__question-answer", children: [
2570
+ /* @__PURE__ */ jsxs3("strong", { children: [
2497
2571
  question.answeredByName ?? "Host",
2498
2572
  ":"
2499
2573
  ] }),
@@ -2502,7 +2576,7 @@ function QuestionCard({ question }) {
2502
2576
  ] }) : null
2503
2577
  ] })
2504
2578
  ] }),
2505
- answering ? /* @__PURE__ */ jsxs2(
2579
+ answering ? /* @__PURE__ */ jsxs3(
2506
2580
  "form",
2507
2581
  {
2508
2582
  className: "mx-meet__composer-row",
@@ -2534,7 +2608,7 @@ function QuestionCard({ question }) {
2534
2608
  }
2535
2609
  ) : null,
2536
2610
  /* @__PURE__ */ jsx5(Notice, { notice }),
2537
- isHost || question.mine ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
2611
+ isHost || question.mine ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
2538
2612
  isHost && question.state === "open" && !answering ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
2539
2613
  isHost && question.state === "open" ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
2540
2614
  isHost && question.state !== "open" ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
@@ -2544,9 +2618,9 @@ function QuestionCard({ question }) {
2544
2618
  }
2545
2619
  function QaPanel({ onClose }) {
2546
2620
  const { collab, act } = useCollab();
2547
- const [draft, setDraft] = useState3("");
2548
- const [anonymous, setAnonymous] = useState3(false);
2549
- const [order, setOrder] = useState3("popular");
2621
+ const [draft, setDraft] = useState4("");
2622
+ const [anonymous, setAnonymous] = useState4(false);
2623
+ const [order, setOrder] = useState4("popular");
2550
2624
  const [notice, show] = useNotice();
2551
2625
  const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
2552
2626
  const questions = [...collab?.questions ?? []];
@@ -2554,9 +2628,9 @@ function QaPanel({ onClose }) {
2554
2628
  questions.sort(
2555
2629
  (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 ?? "")
2556
2630
  );
2557
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Q&A", onClose, children: [
2631
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Q&A", onClose, children: [
2558
2632
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
2559
- /* @__PURE__ */ jsxs2(
2633
+ /* @__PURE__ */ jsxs3(
2560
2634
  "form",
2561
2635
  {
2562
2636
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -2570,7 +2644,7 @@ function QaPanel({ onClose }) {
2570
2644
  });
2571
2645
  },
2572
2646
  children: [
2573
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
2647
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
2574
2648
  /* @__PURE__ */ jsx5(
2575
2649
  "input",
2576
2650
  {
@@ -2584,7 +2658,7 @@ function QaPanel({ onClose }) {
2584
2658
  ),
2585
2659
  /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
2586
2660
  ] }),
2587
- allowAnonymous ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
2661
+ allowAnonymous ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
2588
2662
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
2589
2663
  "Ask anonymously"
2590
2664
  ] }) : null
@@ -2635,10 +2709,10 @@ function StrokeView({ stroke, onPick }) {
2635
2709
  }
2636
2710
  function WhiteboardPanel({ onClose }) {
2637
2711
  const { collab, act, isHost, localIdentity } = useCollab();
2638
- const [tool, setTool] = useState3("pen");
2639
- const [color, setColor] = useState3(INK[0]);
2640
- const [drawing, setDrawing] = useState3(null);
2641
- const [pending, setPending] = useState3([]);
2712
+ const [tool, setTool] = useState4("pen");
2713
+ const [color, setColor] = useState4(INK[0]);
2714
+ const [drawing, setDrawing] = useState4(null);
2715
+ const [pending, setPending] = useState4([]);
2642
2716
  const [notice, show] = useNotice();
2643
2717
  const svgRef = useRef5(null);
2644
2718
  const strokes = collab?.strokes ?? [];
@@ -2672,8 +2746,8 @@ function WhiteboardPanel({ onClose }) {
2672
2746
  if (!result.ok) show(result);
2673
2747
  });
2674
2748
  };
2675
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
2676
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__whiteboard-bar", children: [
2749
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
2750
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__whiteboard-bar", children: [
2677
2751
  /* @__PURE__ */ jsx5("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
2678
2752
  /* @__PURE__ */ jsx5("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
2679
2753
  ["pen", "Pen", /* @__PURE__ */ jsx5(PencilIcon, { width: 16, height: 16 }, "p")],
@@ -2723,7 +2797,7 @@ function WhiteboardPanel({ onClose }) {
2723
2797
  /* @__PURE__ */ jsx5(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ jsx5(CloseIcon, { width: 16, height: 16 }) })
2724
2798
  ] }),
2725
2799
  /* @__PURE__ */ jsx5(Notice, { notice }),
2726
- /* @__PURE__ */ jsxs2(
2800
+ /* @__PURE__ */ jsxs3(
2727
2801
  "svg",
2728
2802
  {
2729
2803
  ref: svgRef,
@@ -2781,7 +2855,7 @@ function clock(ms) {
2781
2855
  }
2782
2856
  var BREAKOUT_EXPIRE_RETRY_MS = 5e3;
2783
2857
  function useNow(active) {
2784
- const [now, setNow] = useState3(() => Date.now());
2858
+ const [now, setNow] = useState4(() => Date.now());
2785
2859
  useEffect5(() => {
2786
2860
  if (!active) return void 0;
2787
2861
  const timer = setInterval(() => setNow(Date.now()), 1e3);
@@ -2796,11 +2870,11 @@ function BreakoutSetup() {
2796
2870
  const people = (snapshot?.participants ?? []).filter(
2797
2871
  (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
2798
2872
  );
2799
- const [count, setCount] = useState3(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
2800
- const [mode, setMode] = useState3("auto");
2801
- const [minutes, setMinutes] = useState3(settings?.breakoutDefaultMinutes ?? 15);
2802
- const [manual, setManual] = useState3({});
2803
- const [busy, setBusy] = useState3(false);
2873
+ const [count, setCount] = useState4(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
2874
+ const [mode, setMode] = useState4("auto");
2875
+ const [minutes, setMinutes] = useState4(settings?.breakoutDefaultMinutes ?? 15);
2876
+ const [manual, setManual] = useState4({});
2877
+ const [busy, setBusy] = useState4(false);
2804
2878
  const [notice, show] = useNotice();
2805
2879
  const max = settings?.breakoutMaxRooms ?? 20;
2806
2880
  const rooms = Math.min(Math.max(1, count), max);
@@ -2812,8 +2886,8 @@ function BreakoutSetup() {
2812
2886
  (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
2813
2887
  ) : Array.from({ length: rooms }, () => []);
2814
2888
  const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
2815
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
2816
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
2889
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-card", children: [
2890
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
2817
2891
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Rooms" }),
2818
2892
  /* @__PURE__ */ jsx5(
2819
2893
  "input",
@@ -2842,7 +2916,7 @@ function BreakoutSetup() {
2842
2916
  },
2843
2917
  value
2844
2918
  )) }),
2845
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
2919
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
2846
2920
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
2847
2921
  /* @__PURE__ */ jsx5(
2848
2922
  "input",
@@ -2856,9 +2930,9 @@ function BreakoutSetup() {
2856
2930
  }
2857
2931
  )
2858
2932
  ] }),
2859
- mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
2933
+ mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
2860
2934
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__person-name", children: person.displayName }),
2861
- /* @__PURE__ */ jsxs2(
2935
+ /* @__PURE__ */ jsxs3(
2862
2936
  "select",
2863
2937
  {
2864
2938
  className: "mx-meet__select mx-meet__select--compact",
@@ -2867,15 +2941,15 @@ function BreakoutSetup() {
2867
2941
  onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
2868
2942
  children: [
2869
2943
  /* @__PURE__ */ jsx5("option", { value: -1, children: "Main room" }),
2870
- Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs2("option", { value: index, children: [
2944
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs3("option", { value: index, children: [
2871
2945
  "Room ",
2872
2946
  index + 1
2873
2947
  ] }, index))
2874
2948
  ]
2875
2949
  }
2876
2950
  )
2877
- ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs2("li", { children: [
2878
- /* @__PURE__ */ jsxs2("strong", { children: [
2951
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs3("li", { children: [
2952
+ /* @__PURE__ */ jsxs3("strong", { children: [
2879
2953
  "Room ",
2880
2954
  index + 1
2881
2955
  ] }),
@@ -2883,7 +2957,7 @@ function BreakoutSetup() {
2883
2957
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
2884
2958
  ] }, index)) }) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
2885
2959
  /* @__PURE__ */ jsx5(Notice, { notice }),
2886
- /* @__PURE__ */ jsxs2(
2960
+ /* @__PURE__ */ jsxs3(
2887
2961
  "button",
2888
2962
  {
2889
2963
  type: "button",
@@ -2916,7 +2990,7 @@ function BreakoutRun({ plan }) {
2916
2990
  const snapshot = useMeetSnapshot();
2917
2991
  const now = useNow(plan.endsAt !== null);
2918
2992
  const remaining = breakoutRemainingMs(plan, now);
2919
- const [broadcast, setBroadcast] = useState3("");
2993
+ const [broadcast, setBroadcast] = useState4("");
2920
2994
  const [notice, show] = useNotice();
2921
2995
  const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
2922
2996
  const mine = assignedRoom(plan, localIdentity);
@@ -2928,8 +3002,8 @@ function BreakoutRun({ plan }) {
2928
3002
  }
2929
3003
  show(await moveTo(roomId));
2930
3004
  };
2931
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
2932
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
3005
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-card", children: [
3006
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
2933
3007
  plan.rooms.length,
2934
3008
  " room",
2935
3009
  plan.rooms.length === 1 ? "" : "s",
@@ -2940,15 +3014,15 @@ function BreakoutRun({ plan }) {
2940
3014
  /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
2941
3015
  const here = breakoutRoomId === room.id;
2942
3016
  const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
2943
- return /* @__PURE__ */ jsxs2("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
2944
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-head", children: [
3017
+ return /* @__PURE__ */ jsxs3("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
3018
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-head", children: [
2945
3019
  /* @__PURE__ */ jsx5("strong", { children: room.name }),
2946
3020
  here ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
2947
3021
  ] }),
2948
3022
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
2949
- isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
3023
+ isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
2950
3024
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
2951
- /* @__PURE__ */ jsxs2(
3025
+ /* @__PURE__ */ jsxs3(
2952
3026
  "select",
2953
3027
  {
2954
3028
  className: "mx-meet__select mx-meet__select--compact",
@@ -2969,7 +3043,7 @@ function BreakoutRun({ plan }) {
2969
3043
  ] }, room.id);
2970
3044
  }) }),
2971
3045
  breakoutRoomId !== null ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
2972
- isHost ? /* @__PURE__ */ jsxs2(
3046
+ isHost ? /* @__PURE__ */ jsxs3(
2973
3047
  "form",
2974
3048
  {
2975
3049
  className: "mx-meet__composer-row",
@@ -3013,7 +3087,7 @@ function BreakoutRun({ plan }) {
3013
3087
  function BreakoutsPanel({ onClose }) {
3014
3088
  const { collab, isHost } = useCollab();
3015
3089
  const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
3016
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Breakout rooms", onClose, children: [
3090
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Breakout rooms", onClose, children: [
3017
3091
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
3018
3092
  plan !== null ? /* @__PURE__ */ jsx5(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ jsx5(BreakoutSetup, {}) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
3019
3093
  ] });
@@ -3027,12 +3101,12 @@ function BreakoutBanner() {
3027
3101
  const remaining = breakoutRemainingMs(open, now);
3028
3102
  const closing = breakoutClosingMs(open, now);
3029
3103
  const assigned = assignedRoom(open, localIdentity);
3030
- const [later, setLater] = useState3(null);
3031
- const [autoSince, setAutoSince] = useState3(null);
3104
+ const [later, setLater] = useState4(null);
3105
+ const [autoSince, setAutoSince] = useState4(null);
3032
3106
  const AUTO_MOVE_MS = 1e4;
3033
3107
  const autoLeft = open?.moveMode === "auto" && assigned !== null && autoSince?.id === open.id && later !== open.id ? Math.max(0, AUTO_MOVE_MS - (now - autoSince.at)) : null;
3034
- const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
3035
- const [failure, setFailure] = useState3(null);
3108
+ const [dismissedBroadcast, setDismissedBroadcast] = useState4(null);
3109
+ const [failure, setFailure] = useState4(null);
3036
3110
  const expireAsked = useRef5(null);
3037
3111
  const moveAt = collab?.moveRequest?.at ?? null;
3038
3112
  useEffect5(() => {
@@ -3067,29 +3141,29 @@ function BreakoutBanner() {
3067
3141
  const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
3068
3142
  const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
3069
3143
  if (open === null && failure === null) return null;
3070
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__breakout-banner", role: "status", children: [
3144
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__breakout-banner", role: "status", children: [
3071
3145
  failure !== null ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-error", children: failure }) : null,
3072
- closing !== null ? /* @__PURE__ */ jsxs2("span", { role: "status", "data-meet-notice": "breakout-closing", children: [
3146
+ closing !== null ? /* @__PURE__ */ jsxs3("span", { role: "status", "data-meet-notice": "breakout-closing", children: [
3073
3147
  "Rooms closing in ",
3074
3148
  Math.ceil(closing / 1e3),
3075
3149
  room !== null ? " \u2014 you return to the main meeting" : ""
3076
3150
  ] }) : null,
3077
- room !== null ? /* @__PURE__ */ jsxs2("span", { children: [
3151
+ room !== null ? /* @__PURE__ */ jsxs3("span", { children: [
3078
3152
  /* @__PURE__ */ jsx5("strong", { children: room.name }),
3079
3153
  remaining !== null && closing === null ? ` \xB7 ${clock(remaining)} left` : "",
3080
3154
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
3081
- ] }) : assigned !== null && later !== open?.id ? /* @__PURE__ */ jsxs2("span", { children: [
3155
+ ] }) : assigned !== null && later !== open?.id ? /* @__PURE__ */ jsxs3("span", { children: [
3082
3156
  autoLeft !== null ? `You're being moved to ${assigned.name} in ${Math.ceil(autoLeft / 1e3)} s` : `You're invited to ${assigned.name}`,
3083
3157
  remaining !== null && closing === null ? ` \xB7 ${clock(remaining)} left` : "",
3084
3158
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void joinAssigned(), children: "Join room" }),
3085
3159
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => setLater(open?.id ?? null), children: "Later" })
3086
- ] }) : assigned !== null ? /* @__PURE__ */ jsxs2("span", { children: [
3160
+ ] }) : assigned !== null ? /* @__PURE__ */ jsxs3("span", { children: [
3087
3161
  assigned.name,
3088
3162
  " is open",
3089
3163
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void joinAssigned(), children: "Join room" })
3090
3164
  ] }) : open?.allowChoose ? /* @__PURE__ */ jsx5("span", { children: "Rooms are open \u2014 pick one under Activities." }) : null,
3091
- showBroadcast ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__breakout-broadcast", children: [
3092
- /* @__PURE__ */ jsxs2("strong", { children: [
3165
+ showBroadcast ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__breakout-broadcast", children: [
3166
+ /* @__PURE__ */ jsxs3("strong", { children: [
3093
3167
  broadcast.by,
3094
3168
  ":"
3095
3169
  ] }),
@@ -3109,10 +3183,10 @@ function CaptionLanguageSettings() {
3109
3183
  const preferred = defaultCaptionLanguage(settings, viewer);
3110
3184
  const current = collab?.captionLanguage ?? "";
3111
3185
  const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
3112
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
3113
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
3186
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
3187
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
3114
3188
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
3115
- /* @__PURE__ */ jsxs2(
3189
+ /* @__PURE__ */ jsxs3(
3116
3190
  "select",
3117
3191
  {
3118
3192
  className: "mx-meet__select",
@@ -3123,7 +3197,7 @@ function CaptionLanguageSettings() {
3123
3197
  },
3124
3198
  children: [
3125
3199
  /* @__PURE__ */ jsx5("option", { value: "", children: "Off \u2014 as spoken" }),
3126
- current === "" ? /* @__PURE__ */ jsxs2("option", { value: preferred, children: [
3200
+ current === "" ? /* @__PURE__ */ jsxs3("option", { value: preferred, children: [
3127
3201
  choices.find((c) => c.tag === preferred)?.name ?? preferred,
3128
3202
  " (yours)"
3129
3203
  ] }) : null,
@@ -3164,10 +3238,10 @@ function TakeNotesControl() {
3164
3238
  }
3165
3239
 
3166
3240
  // src/skins/meet/components.tsx
3167
- import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
3241
+ import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
3168
3242
  function InertNotice({ what }) {
3169
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
3170
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-title", children: [
3243
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__empty", role: "status", children: [
3244
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__empty-title", children: [
3171
3245
  what,
3172
3246
  " is not ready yet"
3173
3247
  ] }),
@@ -3237,7 +3311,7 @@ function RecordingIndicator() {
3237
3311
  const { state, label, canStart } = useRecording();
3238
3312
  const snapshot = useMeetSnapshot();
3239
3313
  const previous = useRef6(state);
3240
- const [stoppedAt, setStoppedAt] = useState4(null);
3314
+ const [stoppedAt, setStoppedAt] = useState5(null);
3241
3315
  useEffect6(() => {
3242
3316
  const was = previous.current;
3243
3317
  previous.current = state;
@@ -3250,8 +3324,8 @@ function RecordingIndicator() {
3250
3324
  }, [state]);
3251
3325
  const meetingId = snapshot?.meeting?.id ?? null;
3252
3326
  if (label === null && stoppedAt === null) return null;
3253
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
3254
- label !== null ? /* @__PURE__ */ jsxs3(
3327
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3328
+ label !== null ? /* @__PURE__ */ jsxs4(
3255
3329
  "span",
3256
3330
  {
3257
3331
  className: `mx-meet__recording mx-meet__recording--${state}`,
@@ -3292,7 +3366,7 @@ function ParticipantTile({
3292
3366
  const host = useMeetHost();
3293
3367
  const snapshot = useMeetSnapshot();
3294
3368
  const queue = useHandQueue();
3295
- const [menu, setMenu] = useState4(false);
3369
+ const [menu, setMenu] = useState5(false);
3296
3370
  const videoRef = useTrack(
3297
3371
  participant.identity,
3298
3372
  participant.screenSharing ? "screen" : "camera"
@@ -3302,7 +3376,7 @@ function ParticipantTile({
3302
3376
  const spotlit = snapshot?.spotlight === participant.identity;
3303
3377
  const presenting = snapshot?.presenter === participant.identity;
3304
3378
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
3305
- return /* @__PURE__ */ jsxs3(
3379
+ return /* @__PURE__ */ jsxs4(
3306
3380
  "div",
3307
3381
  {
3308
3382
  className: [
@@ -3325,12 +3399,12 @@ function ParticipantTile({
3325
3399
  }
3326
3400
  ) : /* @__PURE__ */ jsx6("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
3327
3401
  presenting ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__tile-presenting", role: "status", children: participant.isLocal ? "You are presenting" : `${participant.displayName} is presenting` }) : null,
3328
- participant.handRaised ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
3402
+ participant.handRaised ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
3329
3403
  /* @__PURE__ */ jsx6(HandIcon, { width: 14, height: 14 }),
3330
3404
  handPosition > 0 ? handPosition : null
3331
3405
  ] }) : null,
3332
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__tile-bar", children: [
3333
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-name", children: [
3406
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__tile-bar", children: [
3407
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__tile-name", children: [
3334
3408
  spotlit ? /* @__PURE__ */ jsx6("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx6(SpotlightIcon, { width: 12, height: 12 }) }) : null,
3335
3409
  participant.displayName,
3336
3410
  participant.isLocal ? " (you)" : "",
@@ -3341,7 +3415,7 @@ function ParticipantTile({
3341
3415
  !participant.micEnabled ? /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }) : null,
3342
3416
  /* @__PURE__ */ jsx6(QualityBars, { quality: participant.quality })
3343
3417
  ] }),
3344
- /* @__PURE__ */ jsxs3("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
3418
+ /* @__PURE__ */ jsxs4("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
3345
3419
  /* @__PURE__ */ jsx6(
3346
3420
  ControlButton,
3347
3421
  {
@@ -3351,7 +3425,7 @@ function ParticipantTile({
3351
3425
  children: /* @__PURE__ */ jsx6(PinIcon, { width: 16, height: 16 })
3352
3426
  }
3353
3427
  ),
3354
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3428
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3355
3429
  /* @__PURE__ */ jsx6(
3356
3430
  ControlButton,
3357
3431
  {
@@ -3389,12 +3463,12 @@ function Stage({ pageSize }) {
3389
3463
  const stage = useStage(pageSize);
3390
3464
  const columns = gridColumns(stage.tiles.length);
3391
3465
  if (stage.feature === null && stage.tiles.length === 0) {
3392
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
3466
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
3393
3467
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
3394
3468
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
3395
3469
  ] });
3396
3470
  }
3397
- return /* @__PURE__ */ jsxs3("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
3471
+ return /* @__PURE__ */ jsxs4("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
3398
3472
  stage.feature !== null ? /* @__PURE__ */ jsx6(ParticipantTile, { participant: stage.feature, featured: true }) : null,
3399
3473
  /* @__PURE__ */ jsx6(
3400
3474
  "div",
@@ -3404,7 +3478,7 @@ function Stage({ pageSize }) {
3404
3478
  children: stage.tiles.map((participant) => /* @__PURE__ */ jsx6(ParticipantTile, { participant }, participant.identity))
3405
3479
  }
3406
3480
  ),
3407
- stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
3481
+ stage.overflow > 0 ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__overflow", children: [
3408
3482
  "+",
3409
3483
  stage.overflow,
3410
3484
  " more ",
@@ -3416,10 +3490,10 @@ function Stage({ pageSize }) {
3416
3490
  function ControlBar({ onLeave }) {
3417
3491
  const room = useRoom();
3418
3492
  const recording = useRecording();
3419
- const [panel, setPanel] = useState4("none");
3420
- const [chatTo, setChatTo] = useState4(null);
3421
- const [popover, setPopover] = useState4("none");
3422
- const [shortcuts, setShortcuts] = useState4(false);
3493
+ const [panel, setPanel] = useState5("none");
3494
+ const [chatTo, setChatTo] = useState5(null);
3495
+ const [popover, setPopover] = useState5("none");
3496
+ const [shortcuts, setShortcuts] = useState5(false);
3423
3497
  const snapshot = useMeetSnapshot();
3424
3498
  const lobby = useLobby();
3425
3499
  const controls = useHostControls();
@@ -3427,7 +3501,7 @@ function ControlBar({ onLeave }) {
3427
3501
  const micUnavailable = useLocalMedia().microphone.unavailable;
3428
3502
  const live = useLivePolicy();
3429
3503
  const unread = useUnreadChat(panel === "chat");
3430
- const [whiteboard, setWhiteboard] = useState4(false);
3504
+ const [whiteboard, setWhiteboard] = useState5(false);
3431
3505
  const app = useMeetAppPanel();
3432
3506
  const appOpened = useRef6(false);
3433
3507
  useEffect6(() => {
@@ -3461,7 +3535,7 @@ function ControlBar({ onLeave }) {
3461
3535
  help: () => setShortcuts(true)
3462
3536
  });
3463
3537
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
3464
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
3538
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3465
3539
  /* @__PURE__ */ jsx6(MeetingOverlays, {}),
3466
3540
  shortcuts ? /* @__PURE__ */ jsx6(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
3467
3541
  panel === "chat" ? /* @__PURE__ */ jsx6(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
@@ -3491,8 +3565,9 @@ function ControlBar({ onLeave }) {
3491
3565
  ) }) }) : null,
3492
3566
  /* @__PURE__ */ jsx6(BreakoutBanner, {}),
3493
3567
  panel !== "people" ? /* @__PURE__ */ jsx6(KnockNotice, { onView: () => setPanel("people") }) : null,
3568
+ /* @__PURE__ */ jsx6(SpeakingWhileMutedNudge, {}),
3494
3569
  controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx6(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
3495
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__controls", children: [
3570
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__controls", children: [
3496
3571
  live.micLocked ? null : /* @__PURE__ */ jsx6(
3497
3572
  ControlButton,
3498
3573
  {
@@ -3502,6 +3577,7 @@ function ControlBar({ onLeave }) {
3502
3577
  children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx6(MicIcon, {}) : /* @__PURE__ */ jsx6(MicOffIcon, {})
3503
3578
  }
3504
3579
  ),
3580
+ /* @__PURE__ */ jsx6(AudioSettingsControl, {}),
3505
3581
  live.cameraLocked ? null : /* @__PURE__ */ jsx6(
3506
3582
  ControlButton,
3507
3583
  {
@@ -3521,7 +3597,7 @@ function ControlBar({ onLeave }) {
3521
3597
  children: /* @__PURE__ */ jsx6(ScreenShareIcon, {})
3522
3598
  }
3523
3599
  ) : null,
3524
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3600
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3525
3601
  /* @__PURE__ */ jsx6(
3526
3602
  ControlButton,
3527
3603
  {
@@ -3553,11 +3629,11 @@ function ControlBar({ onLeave }) {
3553
3629
  }
3554
3630
  ),
3555
3631
  app !== null ? /* @__PURE__ */ jsx6(ControlButton, { label: app.title, active: panel === "app", onClick: () => toggle("app"), children: /* @__PURE__ */ jsx6(FlagIcon, {}) }) : null,
3556
- /* @__PURE__ */ jsxs3(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
3632
+ /* @__PURE__ */ jsxs4(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
3557
3633
  /* @__PURE__ */ jsx6(ChatIcon, {}),
3558
3634
  unread > 0 ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
3559
3635
  ] }),
3560
- /* @__PURE__ */ jsxs3(
3636
+ /* @__PURE__ */ jsxs4(
3561
3637
  ControlButton,
3562
3638
  {
3563
3639
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
@@ -3580,7 +3656,7 @@ function ControlBar({ onLeave }) {
3580
3656
  /* @__PURE__ */ jsx6(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
3581
3657
  recording.canStart ? /* @__PURE__ */ jsx6(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx6(RecordIcon, {}) }) : null,
3582
3658
  recording.canStop ? /* @__PURE__ */ jsx6(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx6(RecordIcon, {}) }) : null,
3583
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3659
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3584
3660
  /* @__PURE__ */ jsx6(
3585
3661
  ControlButton,
3586
3662
  {
@@ -3590,8 +3666,8 @@ function ControlBar({ onLeave }) {
3590
3666
  children: /* @__PURE__ */ jsx6(MoreIcon, {})
3591
3667
  }
3592
3668
  ),
3593
- popover === "more" ? /* @__PURE__ */ jsx6(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
3594
- /* @__PURE__ */ jsxs3(
3669
+ popover === "more" ? /* @__PURE__ */ jsx6(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", role: "menu", children: [
3670
+ /* @__PURE__ */ jsxs4(
3595
3671
  MenuItem,
3596
3672
  {
3597
3673
  onSelect: () => {
@@ -3604,7 +3680,7 @@ function ControlBar({ onLeave }) {
3604
3680
  ]
3605
3681
  }
3606
3682
  ),
3607
- /* @__PURE__ */ jsxs3(
3683
+ /* @__PURE__ */ jsxs4(
3608
3684
  MenuItem,
3609
3685
  {
3610
3686
  onSelect: () => {
@@ -3617,9 +3693,16 @@ function ControlBar({ onLeave }) {
3617
3693
  ]
3618
3694
  }
3619
3695
  ),
3620
- controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
3696
+ !room.canShareScreen && room.local?.screenSharing !== true ? (
3697
+ // `share-unsupported-mobile`: the control is absent; the menu says where it lives.
3698
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__menu-note", role: "note", "data-meet-notice": "share-unsupported", children: [
3699
+ /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
3700
+ " Present from a computer"
3701
+ ] })
3702
+ ) : null,
3703
+ controls.isHost ? /* @__PURE__ */ jsxs4(Fragment, { children: [
3621
3704
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu-sep", role: "separator" }),
3622
- /* @__PURE__ */ jsxs3(
3705
+ /* @__PURE__ */ jsxs4(
3623
3706
  MenuItem,
3624
3707
  {
3625
3708
  onSelect: () => {
@@ -3632,7 +3715,7 @@ function ControlBar({ onLeave }) {
3632
3715
  ]
3633
3716
  }
3634
3717
  ),
3635
- /* @__PURE__ */ jsxs3(
3718
+ /* @__PURE__ */ jsxs4(
3636
3719
  MenuItem,
3637
3720
  {
3638
3721
  onSelect: () => {
@@ -3649,7 +3732,7 @@ function ControlBar({ onLeave }) {
3649
3732
  ]
3650
3733
  }
3651
3734
  ),
3652
- /* @__PURE__ */ jsxs3(
3735
+ /* @__PURE__ */ jsxs4(
3653
3736
  MenuItem,
3654
3737
  {
3655
3738
  onSelect: () => {
@@ -3662,7 +3745,8 @@ function ControlBar({ onLeave }) {
3662
3745
  ]
3663
3746
  }
3664
3747
  ),
3665
- queue.length > 0 ? /* @__PURE__ */ jsxs3(
3748
+ /* @__PURE__ */ jsx6(WaitingRoomRule, {}),
3749
+ queue.length > 0 ? /* @__PURE__ */ jsxs4(
3666
3750
  MenuItem,
3667
3751
  {
3668
3752
  onSelect: () => {
@@ -3677,7 +3761,7 @@ function ControlBar({ onLeave }) {
3677
3761
  ]
3678
3762
  }
3679
3763
  ) : null,
3680
- hasSpotlight ? /* @__PURE__ */ jsxs3(
3764
+ hasSpotlight ? /* @__PURE__ */ jsxs4(
3681
3765
  MenuItem,
3682
3766
  {
3683
3767
  onSelect: () => {
@@ -3704,8 +3788,8 @@ var LEAVE_WORDS = {
3704
3788
  };
3705
3789
  function LeaveControl({ onLeave }) {
3706
3790
  const leave = useLeave();
3707
- const [open, setOpen] = useState4("none");
3708
- const [failure, setFailure] = useState4(null);
3791
+ const [open, setOpen] = useState5("none");
3792
+ const [failure, setFailure] = useState5(null);
3709
3793
  const words = LEAVE_WORDS[leave.policy.hostLeavePrompt];
3710
3794
  const run = (work, leaving) => {
3711
3795
  setFailure(null);
@@ -3716,7 +3800,7 @@ function LeaveControl({ onLeave }) {
3716
3800
  };
3717
3801
  const leaveNow = () => run(leave.leave, true);
3718
3802
  const endNow = () => run(leave.endForAll, false);
3719
- return /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3803
+ return /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3720
3804
  /* @__PURE__ */ jsx6(
3721
3805
  ControlButton,
3722
3806
  {
@@ -3730,7 +3814,7 @@ function LeaveControl({ onLeave }) {
3730
3814
  children: /* @__PURE__ */ jsx6(PhoneOffIcon, {})
3731
3815
  }
3732
3816
  ),
3733
- open !== "none" ? /* @__PURE__ */ jsx6(Popover, { label: open === "assign" ? words.assign_and_leave : "Leave", onClose: () => setOpen("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", "data-meet-leave-menu": leave.policy.hostLeavePrompt, children: [
3817
+ open !== "none" ? /* @__PURE__ */ jsx6(Popover, { label: open === "assign" ? words.assign_and_leave : "Leave", onClose: () => setOpen("none"), children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", "data-meet-leave-menu": leave.policy.hostLeavePrompt, children: [
3734
3818
  open === "menu" ? leave.choices.map((choice) => /* @__PURE__ */ jsx6(
3735
3819
  "button",
3736
3820
  {
@@ -3756,7 +3840,7 @@ function LeaveControl({ onLeave }) {
3756
3840
  },
3757
3841
  String(person.identity)
3758
3842
  )) : null,
3759
- open === "confirm" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
3843
+ open === "confirm" ? /* @__PURE__ */ jsxs4(Fragment, { children: [
3760
3844
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__menu-item mx-meet__menu-item--danger", onClick: endNow, children: words.end_for_all }),
3761
3845
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__menu-item", onClick: () => setOpen("menu"), children: "Cancel" })
3762
3846
  ] }) : null,
@@ -3777,12 +3861,12 @@ function useUnreadChat(open) {
3777
3861
  const snapshot = useMeetSnapshot();
3778
3862
  const chat = snapshot?.chat ?? [];
3779
3863
  const local = snapshot?.localIdentity ?? null;
3780
- const [seen, setSeen] = useState4(0);
3864
+ const [seen, setSeen] = useState5(0);
3781
3865
  useEffect6(() => {
3782
3866
  if (open) setSeen(chat.length);
3783
3867
  }, [open, chat.length]);
3784
3868
  const loaded = snapshot?.chatLoaded === true;
3785
- const [baseline, setBaseline] = useState4(null);
3869
+ const [baseline, setBaseline] = useState5(null);
3786
3870
  useEffect6(() => {
3787
3871
  if (loaded && baseline === null) setBaseline(chat.length);
3788
3872
  }, [loaded, baseline, chat.length]);
@@ -3797,7 +3881,7 @@ function Popover({
3797
3881
  placement = "up"
3798
3882
  }) {
3799
3883
  const ref = useRef6(null);
3800
- const [style, setStyle] = useState4({
3884
+ const [style, setStyle] = useState5({
3801
3885
  position: "fixed",
3802
3886
  top: 0,
3803
3887
  left: 0,
@@ -3881,20 +3965,160 @@ function MenuItem({
3881
3965
  }
3882
3966
  );
3883
3967
  }
3968
+ var LOBBY_BYPASS_CHOICES = [
3969
+ { value: "everyone", label: "Everyone" },
3970
+ { value: "org_and_invited", label: "Your organization and invited people" },
3971
+ { value: "org", label: "Your organization" },
3972
+ { value: "invited", label: "Invited people" },
3973
+ { value: "host_only", label: "Only hosts" }
3974
+ ];
3975
+ function WaitingRoomRule() {
3976
+ const host = useRequiredMeetHost();
3977
+ const [open, setOpen] = useState5(false);
3978
+ const [value, setValue] = useState5(null);
3979
+ const [notice, setNotice] = useState5(null);
3980
+ useEffect6(() => {
3981
+ let live = true;
3982
+ void host.meetings.meetingRule("lobby_bypass").then((rule) => {
3983
+ if (live) setValue(typeof rule === "string" ? rule : null);
3984
+ }).catch(() => void 0);
3985
+ return () => {
3986
+ live = false;
3987
+ };
3988
+ }, [host]);
3989
+ const current = LOBBY_BYPASS_CHOICES.find((choice) => choice.value === value)?.label ?? null;
3990
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3991
+ /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => setOpen(!open), children: [
3992
+ /* @__PURE__ */ jsx6(LockIcon, { width: 16, height: 16 }),
3993
+ " Who can skip the waiting room",
3994
+ current !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__menu-value", children: current }) : null
3995
+ ] }),
3996
+ open ? /* @__PURE__ */ jsxs4("div", { role: "group", "aria-label": "Who can skip the waiting room", "data-meet-rule": "lobby_bypass", children: [
3997
+ LOBBY_BYPASS_CHOICES.map((choice) => /* @__PURE__ */ jsxs4(
3998
+ "button",
3999
+ {
4000
+ type: "button",
4001
+ role: "menuitemradio",
4002
+ "aria-checked": choice.value === value,
4003
+ className: "mx-meet__menu-item mx-meet__menu-item--sub",
4004
+ onClick: () => {
4005
+ setNotice(null);
4006
+ void host.meetings.setMeetingRule("lobby_bypass", choice.value).then(() => setValue(choice.value)).catch((error) => setNotice(error instanceof Error ? error.message : String(error)));
4007
+ },
4008
+ children: [
4009
+ choice.value === value ? /* @__PURE__ */ jsx6(CheckIcon, { width: 14, height: 14 }) : null,
4010
+ " ",
4011
+ choice.label
4012
+ ]
4013
+ },
4014
+ choice.value
4015
+ )),
4016
+ notice !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__menu-note", role: "status", children: notice }) : null
4017
+ ] }) : null
4018
+ ] });
4019
+ }
3884
4020
  function Toast({ text, failed, onDone }) {
3885
4021
  useEffect6(() => {
3886
4022
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
3887
4023
  return () => clearTimeout(timer);
3888
4024
  }, [text, failed, onDone]);
3889
- return /* @__PURE__ */ jsxs3("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
4025
+ return /* @__PURE__ */ jsxs4("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
3890
4026
  /* @__PURE__ */ jsx6("span", { children: text }),
3891
4027
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
3892
4028
  ] });
3893
4029
  }
4030
+ function AudioSettingsControl() {
4031
+ const host = useMeetHost();
4032
+ const devices = useDeviceSnapshot();
4033
+ const [open, setOpen] = useState5(false);
4034
+ const list = (devices?.devices.audioinput ?? []).filter((device) => device.deviceId.length > 0);
4035
+ if (host === null || list.length < 2) return null;
4036
+ const current = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
4037
+ return /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
4038
+ /* @__PURE__ */ jsx6(
4039
+ ControlButton,
4040
+ {
4041
+ label: "Audio settings",
4042
+ active: open,
4043
+ onClick: () => {
4044
+ if (!open) void host.devices.refresh();
4045
+ setOpen(!open);
4046
+ },
4047
+ children: /* @__PURE__ */ jsx6(ChevronUpIcon, {})
4048
+ }
4049
+ ),
4050
+ open ? /* @__PURE__ */ jsx6(Popover, { label: "Microphone", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu", role: "menu", "aria-label": "Microphone", children: list.map((device) => /* @__PURE__ */ jsxs4(
4051
+ "button",
4052
+ {
4053
+ type: "button",
4054
+ role: "menuitemradio",
4055
+ "aria-checked": device.deviceId === current,
4056
+ className: "mx-meet__menu-item",
4057
+ onClick: () => {
4058
+ setOpen(false);
4059
+ host.devices.select("audioinput", device.deviceId);
4060
+ void host.engine.switchDevice("audioinput", device.deviceId).catch(() => void 0);
4061
+ },
4062
+ children: [
4063
+ device.deviceId === current ? /* @__PURE__ */ jsx6(CheckIcon, { width: 16, height: 16 }) : /* @__PURE__ */ jsx6("span", { className: "mx-meet__menu-gap" }),
4064
+ device.label.length > 0 ? device.label : "Microphone"
4065
+ ]
4066
+ },
4067
+ device.deviceId
4068
+ )) }) }) : null
4069
+ ] });
4070
+ }
4071
+ function SpeakingWhileMutedNudge() {
4072
+ const room = useRoom();
4073
+ const host = useMeetHost();
4074
+ const devices = useDeviceSnapshot();
4075
+ const microphone = useLocalMedia().microphone;
4076
+ const mutedByMe = host !== null && room.local != null && room.local.micEnabled !== true && microphone.unavailable === null;
4077
+ const mic = devices?.selected.audioinput ?? host?.devices.resolve("audioinput") ?? null;
4078
+ const stream = useMicrophoneStream(mutedByMe ? mic : "off");
4079
+ const level = useAudioLevel(stream);
4080
+ const latest = useRef6(0);
4081
+ latest.current = level;
4082
+ const [shown, setShown] = useState5(false);
4083
+ const [detector] = useState5(() => createSpeakingWhileMutedDetector());
4084
+ useEffect6(() => {
4085
+ if (!mutedByMe) {
4086
+ detector.reset();
4087
+ setShown(false);
4088
+ return void 0;
4089
+ }
4090
+ const timer = setInterval(() => {
4091
+ if (detector.feed(latest.current, Date.now())) setShown(true);
4092
+ }, 150);
4093
+ return () => clearInterval(timer);
4094
+ }, [mutedByMe, detector]);
4095
+ useEffect6(() => {
4096
+ if (!shown) return void 0;
4097
+ const timer = setTimeout(() => setShown(false), 8e3);
4098
+ return () => clearTimeout(timer);
4099
+ }, [shown]);
4100
+ if (!shown || !mutedByMe) return null;
4101
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "speaking-while-muted", children: [
4102
+ /* @__PURE__ */ jsx6(MicOffIcon, { width: 16, height: 16 }),
4103
+ /* @__PURE__ */ jsx6("span", { children: "You're muted" }),
4104
+ /* @__PURE__ */ jsx6(
4105
+ "button",
4106
+ {
4107
+ type: "button",
4108
+ className: "mx-meet__primary mx-meet__primary--small",
4109
+ onClick: () => {
4110
+ setShown(false);
4111
+ void room.toggleMicrophone();
4112
+ },
4113
+ children: "Unmute"
4114
+ }
4115
+ )
4116
+ ] });
4117
+ }
3894
4118
  function MediaNotices() {
3895
4119
  const media = useLocalMedia();
3896
4120
  const { region, where, enableAudio, acceptOffer, dismissOffer, dismissNotice, retry } = useMediaSupervisor();
3897
- const [fixing, setFixing] = useState4(null);
4121
+ const [fixing, setFixing] = useState5(null);
3898
4122
  const chips = ["microphone", "camera"].flatMap((kind) => {
3899
4123
  const reason = deviceUnavailableReason(media[kind], region.permission[kind]);
3900
4124
  return reason === null ? [] : [{ kind, reason }];
@@ -3904,8 +4128,8 @@ function MediaNotices() {
3904
4128
  const offer = region.offer;
3905
4129
  const name = (kind) => kind === "microphone" ? "Microphone" : "Camera";
3906
4130
  if (chips.length === 0 && region.audioOutput !== "blocked" && notice === null && offer === null) return null;
3907
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-notices", children: [
3908
- region.audioOutput === "blocked" ? /* @__PURE__ */ jsxs3(
4131
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-notices", children: [
4132
+ region.audioOutput === "blocked" ? /* @__PURE__ */ jsxs4(
3909
4133
  ErrorBox,
3910
4134
  {
3911
4135
  as: "div",
@@ -3920,7 +4144,7 @@ function MediaNotices() {
3920
4144
  ]
3921
4145
  }
3922
4146
  ) : null,
3923
- chips.map(({ kind, reason }) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
4147
+ chips.map(({ kind, reason }) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
3924
4148
  /* @__PURE__ */ jsx6("span", { children: deviceChipLabel(kind, reason) }),
3925
4149
  /* @__PURE__ */ jsx6(
3926
4150
  "button",
@@ -3934,9 +4158,9 @@ function MediaNotices() {
3934
4158
  }
3935
4159
  )
3936
4160
  ] }, kind)),
3937
- fixing !== null && fixReason !== null ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
4161
+ fixing !== null && fixReason !== null ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
3938
4162
  /* @__PURE__ */ jsx6("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(fixing, fixReason, where).map((step) => /* @__PURE__ */ jsx6("li", { children: step }, step)) }),
3939
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__fix-actions", children: [
4163
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__fix-actions", children: [
3940
4164
  /* @__PURE__ */ jsx6(
3941
4165
  "button",
3942
4166
  {
@@ -3953,7 +4177,7 @@ function MediaNotices() {
3953
4177
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Close", onClick: () => setFixing(null), children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
3954
4178
  ] })
3955
4179
  ] }) : null,
3956
- notice !== null ? /* @__PURE__ */ jsxs3(
4180
+ notice !== null ? /* @__PURE__ */ jsxs4(
3957
4181
  "div",
3958
4182
  {
3959
4183
  className: "mx-meet__media-pill",
@@ -3965,7 +4189,7 @@ function MediaNotices() {
3965
4189
  ]
3966
4190
  }
3967
4191
  ) : null,
3968
- offer !== null ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-pill", role: "status", children: [
4192
+ offer !== null ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-pill", role: "status", children: [
3969
4193
  /* @__PURE__ */ jsx6("span", { children: `New ${offer.kind}: ${offer.label || name(offer.kind)}` }),
3970
4194
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void acceptOffer(), children: "Use it" }),
3971
4195
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismissOffer, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
@@ -3980,22 +4204,22 @@ function MeetingOverlays() {
3980
4204
  const snapshot = useMeetSnapshot();
3981
4205
  const controls = useHostControls();
3982
4206
  const isHostNow = useRole() === "host";
3983
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
4207
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3984
4208
  /* @__PURE__ */ jsx6(ReactionOverlay, { reactions }),
3985
4209
  /* @__PURE__ */ jsx6(MediaNotices, {}),
3986
4210
  snapshot !== null && snapshot.phase === "in_call" && snapshot.participants.length >= 2 && !snapshot.participants.some((p) => p.role === "host" || p.role === "cohost") ? (
3987
4211
  // meeting-without-host: the call goes on; host-only controls are simply not on screen.
3988
4212
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "host-absent", children: "The host has left the meeting. Host controls are not available until a host is back." })
3989
4213
  ) : null,
3990
- live.consent !== null ? /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__sheet", role: "alertdialog", "aria-label": "This meeting is being recorded", "data-meet-notice": "recording-consent", children: [
4214
+ live.consent !== null ? /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__sheet", role: "alertdialog", "aria-label": "This meeting is being recorded", "data-meet-notice": "recording-consent", children: [
3991
4215
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: "This meeting is being recorded" }),
3992
4216
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__confirm-text", children: live.consent === "ok_or_leave" ? "By staying you agree to be recorded. You can leave now if you do not agree." : "Until you agree to the recording you can watch and listen, but not use your microphone or camera." }),
3993
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
4217
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
3994
4218
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__send", onClick: live.agree, children: live.consent === "ok_or_leave" ? "OK" : "I agree" }),
3995
4219
  live.consent === "ok_or_leave" ? /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => void room.leave(), children: "Leave meeting" }) : null
3996
4220
  ] })
3997
4221
  ] }) }) : null,
3998
- snapshot?.canReclaim === true && !isHostNow ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "host-reclaim", children: [
4222
+ snapshot?.canReclaim === true && !isHostNow ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "host-reclaim", children: [
3999
4223
  /* @__PURE__ */ jsx6("span", { children: "You started this meeting. Take back the host?" }),
4000
4224
  /* @__PURE__ */ jsx6(
4001
4225
  "button",
@@ -4008,7 +4232,7 @@ function MeetingOverlays() {
4008
4232
  )
4009
4233
  ] }) : null,
4010
4234
  live.micLocked || live.cameraLocked ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "mic-locked", children: live.micLocked && live.cameraLocked ? "Your microphone and camera are turned off by the organizer." : live.micLocked ? "Your microphone is turned off by the organizer." : "Your camera is turned off by the organizer." }) : null,
4011
- live.timeWarning && live.minutesLeft !== null && live.minutesLeft > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "time-warning", children: [
4235
+ live.timeWarning && live.minutesLeft !== null && live.minutesLeft > 0 ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "time-warning", children: [
4012
4236
  "This meeting will end in ",
4013
4237
  live.minutesLeft,
4014
4238
  " ",
@@ -4019,7 +4243,7 @@ function MeetingOverlays() {
4019
4243
  // A host's request ("the host is asking you to unmute"), not an error:
4020
4244
  // an assertive status, so it is announced at once without being filed
4021
4245
  // as a failure (design-system error-box census).
4022
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
4246
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
4023
4247
  /* @__PURE__ */ jsx6("span", { children: notice.text }),
4024
4248
  notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx6(
4025
4249
  "button",
@@ -4046,7 +4270,7 @@ function ShortcutsSheet({ onClose }) {
4046
4270
  window.addEventListener("keydown", onKey);
4047
4271
  return () => window.removeEventListener("keydown", onKey);
4048
4272
  }, [onClose]);
4049
- return /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
4273
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs4(
4050
4274
  "div",
4051
4275
  {
4052
4276
  className: "mx-meet__sheet",
@@ -4054,11 +4278,11 @@ function ShortcutsSheet({ onClose }) {
4054
4278
  "aria-label": "Keyboard shortcuts",
4055
4279
  onClick: (event) => event.stopPropagation(),
4056
4280
  children: [
4057
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
4281
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__panel-head", children: [
4058
4282
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
4059
4283
  /* @__PURE__ */ jsx6(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }) })
4060
4284
  ] }),
4061
- /* @__PURE__ */ jsx6("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__shortcut", children: [
4285
+ /* @__PURE__ */ jsx6("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__shortcut", children: [
4062
4286
  /* @__PURE__ */ jsx6("dt", { children: shortcut.label }),
4063
4287
  /* @__PURE__ */ jsx6("dd", { children: /* @__PURE__ */ jsx6("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
4064
4288
  ] }, shortcut.id)) })
@@ -4090,8 +4314,8 @@ function PanelShell({
4090
4314
  observer.observe(header);
4091
4315
  return () => observer.disconnect();
4092
4316
  }, []);
4093
- return /* @__PURE__ */ jsxs3("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
4094
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
4317
+ return /* @__PURE__ */ jsxs4("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
4318
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__panel-head", children: [
4095
4319
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: title }),
4096
4320
  /* @__PURE__ */ jsx6(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }) })
4097
4321
  ] }),
@@ -4106,8 +4330,8 @@ function ChatPanel({
4106
4330
  const snapshot = useMeetSnapshot();
4107
4331
  const room = useRoom();
4108
4332
  const live = useLivePolicy();
4109
- const [draft, setDraft] = useState4("");
4110
- const [recipient, setRecipient] = useState4(to);
4333
+ const [draft, setDraft] = useState5("");
4334
+ const [recipient, setRecipient] = useState5(to);
4111
4335
  const listRef = useRef6(null);
4112
4336
  const messages = snapshot?.chat ?? [];
4113
4337
  const local = snapshot?.localIdentity ?? null;
@@ -4124,13 +4348,13 @@ function ChatPanel({
4124
4348
  setRecipient(next);
4125
4349
  onTo?.(next);
4126
4350
  };
4127
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Chat", onClose, children: [
4128
- /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__chat", ref: listRef, children: [
4351
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Chat", onClose, children: [
4352
+ /* @__PURE__ */ jsxs4("ul", { className: "mx-meet__chat", ref: listRef, children: [
4129
4353
  snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
4130
4354
  snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx6("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,
4131
4355
  messages.map((message) => /* @__PURE__ */ jsx6(ChatLine, { message, local, people }, message.id))
4132
4356
  ] }),
4133
- !live.canChat ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "chat-restricted", children: live.chatMode === "off" ? "Chat is turned off for this meeting." : "Chat is limited to the host and co-hosts in this meeting." }) : /* @__PURE__ */ jsxs3(
4357
+ !live.canChat ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "chat-restricted", children: live.chatMode === "off" ? "Chat is turned off for this meeting." : "Chat is limited to the host and co-hosts in this meeting." }) : /* @__PURE__ */ jsxs4(
4134
4358
  "form",
4135
4359
  {
4136
4360
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -4143,7 +4367,7 @@ function ChatPanel({
4143
4367
  else void room.sendPrivateChat(recipient, text);
4144
4368
  },
4145
4369
  children: [
4146
- people.length > 0 ? /* @__PURE__ */ jsxs3(
4370
+ people.length > 0 ? /* @__PURE__ */ jsxs4(
4147
4371
  "select",
4148
4372
  {
4149
4373
  className: "mx-meet__select mx-meet__select--compact",
@@ -4152,14 +4376,14 @@ function ChatPanel({
4152
4376
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
4153
4377
  children: [
4154
4378
  /* @__PURE__ */ jsx6("option", { value: "", children: "Everyone" }),
4155
- people.map((participant) => /* @__PURE__ */ jsxs3("option", { value: participant.identity, children: [
4379
+ people.map((participant) => /* @__PURE__ */ jsxs4("option", { value: participant.identity, children: [
4156
4380
  participant.displayName,
4157
4381
  " (private)"
4158
4382
  ] }, participant.identity))
4159
4383
  ]
4160
4384
  }
4161
4385
  ) : null,
4162
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
4386
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__composer-row", children: [
4163
4387
  /* @__PURE__ */ jsx6(
4164
4388
  "input",
4165
4389
  {
@@ -4173,7 +4397,7 @@ function ChatPanel({
4173
4397
  ),
4174
4398
  /* @__PURE__ */ jsx6("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
4175
4399
  ] }),
4176
- recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
4400
+ recipientName !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
4177
4401
  "Only ",
4178
4402
  recipientName,
4179
4403
  " sees this. Private messages are not saved."
@@ -4191,7 +4415,7 @@ function ChatLine({
4191
4415
  const mine = message.identity === local;
4192
4416
  const privateTo = message.to ?? null;
4193
4417
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
4194
- return /* @__PURE__ */ jsxs3(
4418
+ return /* @__PURE__ */ jsxs4(
4195
4419
  "li",
4196
4420
  {
4197
4421
  className: [
@@ -4200,9 +4424,9 @@ function ChatLine({
4200
4424
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
4201
4425
  ].filter(Boolean).join(" "),
4202
4426
  children: [
4203
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
4427
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__chat-meta", children: [
4204
4428
  /* @__PURE__ */ jsx6("strong", { children: mine ? "You" : message.displayName }),
4205
- counterpart !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-private", children: [
4429
+ counterpart !== null ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__chat-private", children: [
4206
4430
  "to ",
4207
4431
  counterpart,
4208
4432
  " \xB7 private"
@@ -4222,8 +4446,8 @@ function PeoplePanel({
4222
4446
  const snapshot = useMeetSnapshot();
4223
4447
  const controls = useHostControls();
4224
4448
  const queue = useHandQueue();
4225
- const [query, setQuery] = useState4("");
4226
- const [menuFor, setMenuFor] = useState4(null);
4449
+ const [query, setQuery] = useState5("");
4450
+ const [menuFor, setMenuFor] = useState5(null);
4227
4451
  const myRole = useRole();
4228
4452
  const local = snapshot?.localIdentity ?? null;
4229
4453
  const observersHidden = snapshot?.grants.observersVisibleTo === "hosts" && !controls.isHost;
@@ -4232,11 +4456,11 @@ function PeoplePanel({
4232
4456
  );
4233
4457
  const needle = query.trim().toLowerCase();
4234
4458
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
4235
- return /* @__PURE__ */ jsxs3(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
4459
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
4236
4460
  /* @__PURE__ */ jsx6(LobbyPanel, {}),
4237
- queue.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
4238
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__section-head", children: [
4239
- /* @__PURE__ */ jsxs3("h3", { className: "mx-meet__section-title", children: [
4461
+ queue.length > 0 ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
4462
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__section-head", children: [
4463
+ /* @__PURE__ */ jsxs4("h3", { className: "mx-meet__section-title", children: [
4240
4464
  "Raised hands \xB7 ",
4241
4465
  queue.length
4242
4466
  ] }),
@@ -4250,9 +4474,9 @@ function PeoplePanel({
4250
4474
  }
4251
4475
  ) : null
4252
4476
  ] }),
4253
- /* @__PURE__ */ jsx6("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
4477
+ /* @__PURE__ */ jsx6("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__person", children: [
4254
4478
  /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
4255
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
4479
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
4256
4480
  participant.displayName,
4257
4481
  participant.identity === local ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__you", children: " (you)" }) : null
4258
4482
  ] }),
@@ -4267,12 +4491,12 @@ function PeoplePanel({
4267
4491
  ) : null
4268
4492
  ] }, participant.identity)) })
4269
4493
  ] }) : null,
4270
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__bulk", children: [
4271
- /* @__PURE__ */ jsxs3("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
4494
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__bulk", children: [
4495
+ /* @__PURE__ */ jsxs4("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
4272
4496
  /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }),
4273
4497
  " Mute all"
4274
4498
  ] }),
4275
- /* @__PURE__ */ jsxs3(
4499
+ /* @__PURE__ */ jsxs4(
4276
4500
  "button",
4277
4501
  {
4278
4502
  type: "button",
@@ -4285,7 +4509,7 @@ function PeoplePanel({
4285
4509
  }
4286
4510
  )
4287
4511
  ] }) : null,
4288
- everyone.length > 4 ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__search", children: [
4512
+ everyone.length > 4 ? /* @__PURE__ */ jsxs4("label", { className: "mx-meet__search", children: [
4289
4513
  /* @__PURE__ */ jsx6(SearchIcon, { width: 16, height: 16 }),
4290
4514
  /* @__PURE__ */ jsx6(
4291
4515
  "input",
@@ -4299,10 +4523,10 @@ function PeoplePanel({
4299
4523
  )
4300
4524
  ] }) : null,
4301
4525
  controls.notice !== null ? /* @__PURE__ */ jsx6("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
4302
- /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__people", children: [
4303
- shown.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
4526
+ /* @__PURE__ */ jsxs4("ul", { className: "mx-meet__people", children: [
4527
+ shown.map((participant) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__person", children: [
4304
4528
  /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
4305
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
4529
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
4306
4530
  participant.displayName,
4307
4531
  participant.identity === local ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__you", children: " (you)" }) : null,
4308
4532
  /* @__PURE__ */ jsx6(
@@ -4319,7 +4543,7 @@ function PeoplePanel({
4319
4543
  participant.handRaised ? /* @__PURE__ */ jsx6(HandIcon, { width: 14, height: 14 }) : null,
4320
4544
  !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }) : null,
4321
4545
  /* @__PURE__ */ jsx6(QualityBars, { quality: participant.quality }),
4322
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
4546
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
4323
4547
  /* @__PURE__ */ jsx6(
4324
4548
  ControlButton,
4325
4549
  {
@@ -4340,7 +4564,7 @@ function PeoplePanel({
4340
4564
  ) : null
4341
4565
  ] })
4342
4566
  ] }, participant.identity)),
4343
- shown.length === 0 ? /* @__PURE__ */ jsxs3("li", { className: "mx-meet__panel-note", children: [
4567
+ shown.length === 0 ? /* @__PURE__ */ jsxs4("li", { className: "mx-meet__panel-note", children: [
4344
4568
  "Nobody matches \u201C",
4345
4569
  query,
4346
4570
  "\u201D."
@@ -4358,14 +4582,14 @@ function PersonMenu({
4358
4582
  const host = useMeetHost();
4359
4583
  const snapshot = useMeetSnapshot();
4360
4584
  const controls = useHostControls();
4361
- const [mode, setMode] = useState4("menu");
4362
- const [text, setText] = useState4("");
4585
+ const [mode, setMode] = useState5("menu");
4586
+ const [text, setText] = useState5("");
4363
4587
  const self = participant.identity === snapshot?.localIdentity;
4364
4588
  const moderate = controls.canModerate(participant);
4365
4589
  const pinned = snapshot?.pinned === participant.identity;
4366
4590
  const spotlit = snapshot?.spotlight === participant.identity;
4367
4591
  const hasAccount = participant.userId !== null;
4368
- const [refused, setRefused] = useState4(false);
4592
+ const [refused, setRefused] = useState5(false);
4369
4593
  const act = (request) => {
4370
4594
  setRefused(false);
4371
4595
  void controls.run(request).then((result) => {
@@ -4376,7 +4600,7 @@ function PersonMenu({
4376
4600
  const refusal = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx6(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
4377
4601
  if (mode === "rename" || mode === "report") {
4378
4602
  const renaming = mode === "rename";
4379
- return /* @__PURE__ */ jsx6(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs3(
4603
+ return /* @__PURE__ */ jsx6(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs4(
4380
4604
  "form",
4381
4605
  {
4382
4606
  className: "mx-meet__menu-form",
@@ -4388,7 +4612,7 @@ function PersonMenu({
4388
4612
  );
4389
4613
  },
4390
4614
  children: [
4391
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
4615
+ /* @__PURE__ */ jsxs4("label", { className: "mx-meet__field", children: [
4392
4616
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
4393
4617
  renaming ? /* @__PURE__ */ jsx6(
4394
4618
  "input",
@@ -4412,7 +4636,7 @@ function PersonMenu({
4412
4636
  )
4413
4637
  ] }),
4414
4638
  refusal,
4415
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
4639
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
4416
4640
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
4417
4641
  /* @__PURE__ */ jsx6("button", { type: "submit", className: "mx-meet__send", disabled: text.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
4418
4642
  ] })
@@ -4422,10 +4646,10 @@ function PersonMenu({
4422
4646
  }
4423
4647
  if (mode === "remove" || mode === "transfer") {
4424
4648
  const removing = mode === "remove";
4425
- return /* @__PURE__ */ jsx6(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-form", children: [
4649
+ return /* @__PURE__ */ jsx6(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-form", children: [
4426
4650
  /* @__PURE__ */ jsx6("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.` }),
4427
4651
  refusal,
4428
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
4652
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
4429
4653
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
4430
4654
  /* @__PURE__ */ jsx6(
4431
4655
  "button",
@@ -4440,8 +4664,8 @@ function PersonMenu({
4440
4664
  ] })
4441
4665
  ] }) });
4442
4666
  }
4443
- return /* @__PURE__ */ jsx6(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
4444
- /* @__PURE__ */ jsxs3(
4667
+ return /* @__PURE__ */ jsx6(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", role: "menu", children: [
4668
+ /* @__PURE__ */ jsxs4(
4445
4669
  MenuItem,
4446
4670
  {
4447
4671
  onSelect: () => {
@@ -4455,7 +4679,7 @@ function PersonMenu({
4455
4679
  ]
4456
4680
  }
4457
4681
  ),
4458
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
4682
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs4(
4459
4683
  MenuItem,
4460
4684
  {
4461
4685
  onSelect: () => {
@@ -4472,44 +4696,44 @@ function PersonMenu({
4472
4696
  ]
4473
4697
  }
4474
4698
  ) : null,
4475
- controls.isHost ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
4699
+ controls.isHost ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
4476
4700
  /* @__PURE__ */ jsx6(SpotlightIcon, { width: 16, height: 16 }),
4477
4701
  " ",
4478
4702
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
4479
4703
  ] }) : null,
4480
- moderate ? /* @__PURE__ */ jsxs3(Fragment, { children: [
4704
+ moderate ? /* @__PURE__ */ jsxs4(Fragment, { children: [
4481
4705
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu-sep", role: "separator" }),
4482
- participant.micEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
4706
+ participant.micEnabled ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
4483
4707
  /* @__PURE__ */ jsx6(MicOffIcon, { width: 16, height: 16 }),
4484
4708
  " Mute"
4485
- ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
4709
+ ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
4486
4710
  /* @__PURE__ */ jsx6(MicIcon, { width: 16, height: 16 }),
4487
4711
  " Ask to unmute"
4488
4712
  ] }) : null,
4489
- participant.cameraEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
4713
+ participant.cameraEnabled ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
4490
4714
  /* @__PURE__ */ jsx6(CameraOffIcon, { width: 16, height: 16 }),
4491
4715
  " Stop video"
4492
4716
  ] }) : null,
4493
- participant.screenSharing ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
4717
+ participant.screenSharing ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
4494
4718
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
4495
4719
  " Stop screen share"
4496
4720
  ] }) : null,
4497
- participant.handRaised ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
4721
+ participant.handRaised ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
4498
4722
  /* @__PURE__ */ jsx6(HandIcon, { width: 16, height: 16 }),
4499
4723
  " Lower hand"
4500
4724
  ] }) : null,
4501
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
4725
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
4502
4726
  /* @__PURE__ */ jsx6(PeopleIcon, { width: 16, height: 16 }),
4503
4727
  " Make co-host"
4504
4728
  ] }) : null,
4505
- !participant.isAgent && participant.role !== "cohost" && participant.role !== "host" ? participant.role === "presenter" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_presenter", identity: participant.identity }), children: [
4729
+ !participant.isAgent && participant.role !== "cohost" && participant.role !== "host" ? participant.role === "presenter" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "revoke_presenter", identity: participant.identity }), children: [
4506
4730
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
4507
4731
  " Remove presenter"
4508
- ] }) : /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_presenter", identity: participant.identity }), children: [
4732
+ ] }) : /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "make_presenter", identity: participant.identity }), children: [
4509
4733
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
4510
4734
  " Make presenter"
4511
4735
  ] }) : null,
4512
- !participant.isAgent ? /* @__PURE__ */ jsxs3(
4736
+ !participant.isAgent ? /* @__PURE__ */ jsxs4(
4513
4737
  MenuItem,
4514
4738
  {
4515
4739
  onSelect: () => {
@@ -4523,15 +4747,15 @@ function PersonMenu({
4523
4747
  }
4524
4748
  ) : null
4525
4749
  ] }) : null,
4526
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
4750
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
4527
4751
  /* @__PURE__ */ jsx6(PeopleIcon, { width: 16, height: 16 }),
4528
4752
  " Remove co-host"
4529
4753
  ] }) : null,
4530
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => setMode("transfer"), children: [
4754
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => setMode("transfer"), children: [
4531
4755
  /* @__PURE__ */ jsx6(SpotlightIcon, { width: 16, height: 16 }),
4532
4756
  " Make host"
4533
4757
  ] }) : null,
4534
- self ? /* @__PURE__ */ jsxs3(
4758
+ self ? /* @__PURE__ */ jsxs4(
4535
4759
  MenuItem,
4536
4760
  {
4537
4761
  onSelect: () => {
@@ -4544,7 +4768,7 @@ function PersonMenu({
4544
4768
  ]
4545
4769
  }
4546
4770
  ) : null,
4547
- !self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
4771
+ !self && !participant.isAgent ? /* @__PURE__ */ jsxs4(
4548
4772
  MenuItem,
4549
4773
  {
4550
4774
  onSelect: () => {
@@ -4557,7 +4781,7 @@ function PersonMenu({
4557
4781
  ]
4558
4782
  }
4559
4783
  ) : null,
4560
- moderate && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
4784
+ moderate && !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
4561
4785
  /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }),
4562
4786
  " Remove from meeting"
4563
4787
  ] }) : null
@@ -4565,7 +4789,7 @@ function PersonMenu({
4565
4789
  }
4566
4790
  function SettingsPanel({ onClose }) {
4567
4791
  const host = useRequiredMeetHost();
4568
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
4792
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Settings", onClose, children: [
4569
4793
  /* @__PURE__ */ jsx6(
4570
4794
  DeviceSettings,
4571
4795
  {
@@ -4588,15 +4812,15 @@ function DeviceSettings({
4588
4812
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
4589
4813
  const stream = useMicrophoneStream(microphone);
4590
4814
  const level = useAudioLevel(stream);
4591
- const [testing, setTesting] = useState4(false);
4815
+ const [testing, setTesting] = useState5(false);
4592
4816
  useEffect6(() => {
4593
4817
  void host.devices.refresh();
4594
4818
  }, [host]);
4595
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
4819
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
4596
4820
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
4597
4821
  /* @__PURE__ */ jsx6("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__ */ jsx6("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
4598
4822
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
4599
- /* @__PURE__ */ jsxs3(
4823
+ /* @__PURE__ */ jsxs4(
4600
4824
  "button",
4601
4825
  {
4602
4826
  type: "button",
@@ -4618,7 +4842,7 @@ function DeviceSettings({
4618
4842
  }
4619
4843
  function EffectsSettings({ preview }) {
4620
4844
  const effects = useMediaEffects();
4621
- const [error, setError] = useState4(null);
4845
+ const [error, setError] = useState5(null);
4622
4846
  const fileRef = useRef6(null);
4623
4847
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
4624
4848
  const apply = (next) => {
@@ -4631,8 +4855,8 @@ function EffectsSettings({ preview }) {
4631
4855
  );
4632
4856
  }
4633
4857
  };
4634
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
4635
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
4858
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
4859
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
4636
4860
  /* @__PURE__ */ jsx6(
4637
4861
  Checkbox,
4638
4862
  {
@@ -4641,12 +4865,12 @@ function EffectsSettings({ preview }) {
4641
4865
  onCheckedChange: (checked) => apply({ noiseSuppression: checked === true })
4642
4866
  }
4643
4867
  ),
4644
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check-text", children: [
4868
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check-text", children: [
4645
4869
  /* @__PURE__ */ jsx6(Label, { htmlFor: "mx-meet-noise", children: "Noise suppression" }),
4646
4870
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
4647
4871
  ] })
4648
4872
  ] }),
4649
- supported ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
4873
+ supported ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field", children: [
4650
4874
  /* @__PURE__ */ jsx6(Label, { children: "Background" }),
4651
4875
  /* @__PURE__ */ jsx6(
4652
4876
  SegmentedControl,
@@ -4740,14 +4964,20 @@ async function playTestSound(sinkId) {
4740
4964
  audio.pause();
4741
4965
  await context.close();
4742
4966
  }
4743
- function useMicrophoneStream(deviceId) {
4744
- const [stream, setStream] = useState4(null);
4967
+ function useMicrophoneStream(deviceId, report, attempt = 0) {
4968
+ const [stream, setStream] = useState5(null);
4969
+ const reportRef = useRef6(report);
4970
+ reportRef.current = report;
4745
4971
  useEffect6(() => {
4746
- if (deviceId === "off") return void 0;
4972
+ if (deviceId === "off") {
4973
+ reportRef.current?.("off");
4974
+ return void 0;
4975
+ }
4747
4976
  let live = true;
4748
4977
  let opened = null;
4749
4978
  const media = globalThis.navigator?.mediaDevices;
4750
4979
  if (media === void 0) return void 0;
4980
+ reportRef.current?.("prompting");
4751
4981
  void media.getUserMedia({ audio: deviceId === null ? true : { deviceId: { exact: deviceId } } }).then((next) => {
4752
4982
  if (!live) {
4753
4983
  next.getTracks().forEach((track) => track.stop());
@@ -4755,20 +4985,54 @@ function useMicrophoneStream(deviceId) {
4755
4985
  }
4756
4986
  opened = next;
4757
4987
  setStream(next);
4758
- }).catch(() => setStream(null));
4988
+ reportRef.current?.("on");
4989
+ }).catch((thrown) => {
4990
+ setStream(null);
4991
+ if (live) reportRef.current?.({ error: thrown });
4992
+ });
4759
4993
  return () => {
4760
4994
  live = false;
4761
4995
  opened?.getTracks().forEach((track) => track.stop());
4762
4996
  setStream(null);
4763
4997
  };
4764
- }, [deviceId]);
4998
+ }, [deviceId, attempt]);
4765
4999
  return stream;
4766
5000
  }
5001
+ function PreviewStatus({ onRetry }) {
5002
+ const { region, where } = useMediaSupervisor();
5003
+ const [waited, setWaited] = useState5(false);
5004
+ const prompting = region.preview.microphone.state === "prompting" || region.preview.camera.state === "prompting";
5005
+ useEffect6(() => {
5006
+ if (!prompting) {
5007
+ setWaited(false);
5008
+ return void 0;
5009
+ }
5010
+ const timer = setTimeout(() => setWaited(true), 800);
5011
+ return () => clearTimeout(timer);
5012
+ }, [prompting]);
5013
+ const refused = ["microphone", "camera"].flatMap((kind) => {
5014
+ const preview = region.preview[kind];
5015
+ const reason = region.permission[kind] === "denied" ? "denied" : preview.state === "unavailable" ? preview.unavailable?.reason ?? "failed" : null;
5016
+ return reason === null ? [] : [{ kind, reason }];
5017
+ });
5018
+ if (refused.length === 0) {
5019
+ if (!prompting || !waited) return null;
5020
+ return /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "permission-prompt", children: "Allow camera and microphone when your browser asks" });
5021
+ }
5022
+ const first = refused[0];
5023
+ const both = refused.length === 2 && refused[0].reason === refused[1].reason;
5024
+ const label = both ? deviceChipLabel("camera", first.reason).replace(/^Camera/, "Camera and mic") : refused.map((r) => deviceChipLabel(r.kind, r.reason)).join(" \xB7 ");
5025
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__warning", role: "status", "data-meet-notice": deviceNoticeCode(first.kind, first.reason), children: [
5026
+ /* @__PURE__ */ jsx6("strong", { children: label }),
5027
+ /* @__PURE__ */ jsx6("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(first.kind, first.reason, where).map((step) => /* @__PURE__ */ jsx6("li", { children: step }, step)) }),
5028
+ /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", size: "sm", onClick: onRetry, children: "Try again" })
5029
+ ] });
5030
+ }
4767
5031
  function KnockNotice({ onView }) {
4768
5032
  const { knocker, others, admit, dismiss } = useKnockNotice();
4769
5033
  if (knocker === null) return null;
4770
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "knock-received", "data-meet-participant-name": knocker.displayName, children: [
4771
- /* @__PURE__ */ jsxs3("span", { children: [
5034
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "knock-received", "data-meet-participant-name": knocker.displayName, children: [
5035
+ /* @__PURE__ */ jsxs4("span", { children: [
4772
5036
  knocker.displayName,
4773
5037
  " wants to join",
4774
5038
  others > 0 ? ` (+${others} more)` : ""
@@ -4792,15 +5056,15 @@ function KnockNotice({ onView }) {
4792
5056
  function LobbyPanel() {
4793
5057
  const lobby = useLobby();
4794
5058
  if (!lobby.canAdmit || lobby.waiting.length === 0 && lobby.declined.length === 0) return null;
4795
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
5059
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
4796
5060
  lobby.waiting.length > 0 ? /* @__PURE__ */ jsx6(WaitingList, { lobby }) : null,
4797
5061
  lobby.declined.length > 0 ? /* @__PURE__ */ jsx6(DeclinedList, { lobby }) : null
4798
5062
  ] });
4799
5063
  }
4800
5064
  function DeclinedList({ lobby }) {
4801
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Declined requests", "data-meet-declined": "", children: [
5065
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__lobby", "aria-label": "Declined requests", "data-meet-declined": "", children: [
4802
5066
  /* @__PURE__ */ jsx6("header", { className: "mx-meet__lobby-head", children: /* @__PURE__ */ jsx6("h3", { className: "mx-meet__lobby-title", children: "Declined" }) }),
4803
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.declined.map((entry) => /* @__PURE__ */ jsxs3(
5067
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.declined.map((entry) => /* @__PURE__ */ jsxs4(
4804
5068
  "li",
4805
5069
  {
4806
5070
  className: "mx-meet__lobby-row",
@@ -4826,12 +5090,12 @@ function DeclinedList({ lobby }) {
4826
5090
  ] });
4827
5091
  }
4828
5092
  function WaitingList({ lobby }) {
4829
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
4830
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__lobby-head", children: [
5093
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
5094
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__lobby-head", children: [
4831
5095
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
4832
5096
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
4833
5097
  ] }),
4834
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs3(
5098
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs4(
4835
5099
  "li",
4836
5100
  {
4837
5101
  className: "mx-meet__lobby-row",
@@ -4839,9 +5103,13 @@ function WaitingList({ lobby }) {
4839
5103
  "data-meet-participant-name": entry.displayName,
4840
5104
  children: [
4841
5105
  /* @__PURE__ */ jsx6(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
4842
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
5106
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
4843
5107
  entry.displayName,
4844
- entry.userId === null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null
5108
+ entry.userId === null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null,
5109
+ entry.flag === "previously_removed" ? (
5110
+ // `mod-removed-bypass`: advice for the host, never a block — Admit stays.
5111
+ /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge mx-meet__badge--warn", "data-meet-notice": "knock-flagged", children: "Previously removed" })
5112
+ ) : null
4845
5113
  ] }),
4846
5114
  /* @__PURE__ */ jsx6(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx6(CheckIcon, { width: 16, height: 16 }) }),
4847
5115
  /* @__PURE__ */ jsx6(
@@ -4863,17 +5131,17 @@ function NoteTakerRow() {
4863
5131
  const ai = useMeetAi();
4864
5132
  const status = ai.noteTaker;
4865
5133
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
4866
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
4867
- /* @__PURE__ */ jsxs3("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
5134
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
5135
+ /* @__PURE__ */ jsxs4("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
4868
5136
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
4869
5137
  ai.noteTakerLabel
4870
5138
  ] }),
4871
5139
  status.detail !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
4872
- status.refusal !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
5140
+ status.refusal !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
4873
5141
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
4874
5142
  status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
4875
5143
  ] }) : null,
4876
- 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: [
5144
+ ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
4877
5145
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
4878
5146
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
4879
5147
  ] }) : null,
@@ -4901,9 +5169,9 @@ function NoteList({
4901
5169
  notes,
4902
5170
  empty
4903
5171
  }) {
4904
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": title, children: [
5172
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": title, children: [
4905
5173
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: title }),
4906
- notes.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx6("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
5174
+ notes.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx6("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__note", children: [
4907
5175
  note.text,
4908
5176
  note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
4909
5177
  ] }, note.id)) })
@@ -4911,14 +5179,14 @@ function NoteList({
4911
5179
  }
4912
5180
  function AiPanel({ onClose }) {
4913
5181
  const ai = useMeetAi();
4914
- const [question, setQuestion] = useState4("");
4915
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Meeting assistant", onClose, children: [
5182
+ const [question, setQuestion] = useState5("");
5183
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Meeting assistant", onClose, children: [
4916
5184
  /* @__PURE__ */ jsx6(NoteTakerRow, {}),
4917
- ai.summary !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
5185
+ ai.summary !== null ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
4918
5186
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
4919
5187
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__summary", children: ai.summary.text })
4920
5188
  ] }) : null,
4921
- ai.wrapUp !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
5189
+ ai.wrapUp !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
4922
5190
  "The wrap-up is written \u2014 ",
4923
5191
  ai.wrapUp.noteIds.length,
4924
5192
  " ",
@@ -4954,9 +5222,9 @@ function AiPanel({ onClose }) {
4954
5222
  empty: "No action items yet."
4955
5223
  }
4956
5224
  ),
4957
- ai.transcript.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
5225
+ ai.transcript.length > 0 ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
4958
5226
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
4959
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs3(
5227
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs4(
4960
5228
  "li",
4961
5229
  {
4962
5230
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
@@ -4968,7 +5236,7 @@ function AiPanel({ onClose }) {
4968
5236
  line.id
4969
5237
  )) })
4970
5238
  ] }) : null,
4971
- /* @__PURE__ */ jsxs3(
5239
+ /* @__PURE__ */ jsxs4(
4972
5240
  "form",
4973
5241
  {
4974
5242
  className: "mx-meet__composer",
@@ -4995,7 +5263,7 @@ function AiPanel({ onClose }) {
4995
5263
  ),
4996
5264
  ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
4997
5265
  ai.answer !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__answer", children: ai.answer }) : null,
4998
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
5266
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__coverage", children: [
4999
5267
  "Answered from ",
5000
5268
  ai.coverage.segmentsUsed,
5001
5269
  " of ",
@@ -5004,7 +5272,7 @@ function AiPanel({ onClose }) {
5004
5272
  ai.coverage.truncated ? " (the oldest were left out)" : "",
5005
5273
  "."
5006
5274
  ] }) : null,
5007
- ai.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
5275
+ ai.error !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
5008
5276
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
5009
5277
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
5010
5278
  ] }) : null
@@ -5017,7 +5285,7 @@ function Captions({ lines = 3 }) {
5017
5285
  const captions = useCaptions();
5018
5286
  if (!captions.on) return null;
5019
5287
  if (captions.state === "unavailable") {
5020
- return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: /* @__PURE__ */ jsxs3("p", { className: "mx-meet__caption", children: [
5288
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: /* @__PURE__ */ jsxs4("p", { className: "mx-meet__caption", children: [
5021
5289
  "Captions are unavailable. ",
5022
5290
  captions.reason,
5023
5291
  captions.remedy !== null ? ` ${captions.remedy}` : ""
@@ -5026,10 +5294,10 @@ function Captions({ lines = 3 }) {
5026
5294
  if (visible.length === 0) {
5027
5295
  return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": captions.state, children: /* @__PURE__ */ jsx6("p", { className: "mx-meet__caption mx-meet__caption--interim", children: captions.state === "starting" ? "Starting captions. They appear as people speak." : "Captions are on. They appear as people speak." }) });
5028
5296
  }
5029
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": "live", children: [
5297
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": "live", children: [
5030
5298
  visible.map((line) => {
5031
5299
  const translated = translation.language === null ? void 0 : translation.translations[line.id];
5032
- return /* @__PURE__ */ jsxs3(
5300
+ return /* @__PURE__ */ jsxs4(
5033
5301
  "p",
5034
5302
  {
5035
5303
  className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
@@ -5057,7 +5325,7 @@ function AttendanceNotice() {
5057
5325
  if (notice === null) return null;
5058
5326
  const refused = media.microphone.unavailable;
5059
5327
  const code = microphoneNoticeCode(media.microphone);
5060
- return /* @__PURE__ */ jsxs3(
5328
+ return /* @__PURE__ */ jsxs4(
5061
5329
  "p",
5062
5330
  {
5063
5331
  className: "mx-meet__banner mx-meet__banner--attendance",
@@ -5088,15 +5356,22 @@ function PreJoinBody({
5088
5356
  const recording = useRecording();
5089
5357
  const effects = useMediaEffects();
5090
5358
  const { notice } = useModerationNotice();
5091
- const [mode, setMode] = useState4("video");
5092
- const [microphone, setMicrophone] = useState4(true);
5093
- const [joining, setJoining] = useState4(false);
5359
+ const [mode, setMode] = useState5("video");
5360
+ const [microphone, setMicrophone] = useState5(true);
5361
+ const [joining, setJoining] = useState5(false);
5094
5362
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
5095
5363
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
5096
- const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
5097
- const micStream = useMicrophoneStream(microphone ? mic : "off");
5364
+ const { reportPreview } = useMediaSupervisor();
5365
+ const [attempt, setAttempt] = useState5(0);
5366
+ const preview = useCameraPreview(
5367
+ mode === "video" ? camera : void 0,
5368
+ effects.effects,
5369
+ (outcome) => reportPreview("camera", outcome),
5370
+ attempt
5371
+ );
5372
+ const micStream = useMicrophoneStream(microphone ? mic : "off", (outcome) => reportPreview("microphone", outcome), attempt);
5098
5373
  const level = useAudioLevel(micStream);
5099
- const [speakerTesting, setSpeakerTesting] = useState4(false);
5374
+ const [speakerTesting, setSpeakerTesting] = useState5(false);
5100
5375
  useEffect6(() => {
5101
5376
  void host.devices.refresh();
5102
5377
  }, [host]);
@@ -5119,8 +5394,8 @@ function PreJoinBody({
5119
5394
  ...secondDevice !== void 0 ? { secondDevice } : {}
5120
5395
  }).then(() => onJoined?.()).catch(() => void 0).finally(() => setJoining(false));
5121
5396
  };
5122
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
5123
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__preview", children: [
5397
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin", children: [
5398
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__preview", children: [
5124
5399
  mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx6(
5125
5400
  "video",
5126
5401
  {
@@ -5136,10 +5411,11 @@ function PreJoinBody({
5136
5411
  mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
5137
5412
  microphone && micStream !== null ? /* @__PURE__ */ jsx6("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__ */ jsx6("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
5138
5413
  ] }),
5139
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-panel", children: [
5414
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin-panel", children: [
5140
5415
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
5416
+ /* @__PURE__ */ jsx6(PreviewStatus, { onRetry: () => setAttempt((n) => n + 1) }),
5141
5417
  notice?.kind === "removed" ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__warning", children: notice.text }) : null,
5142
- devices?.labelsHidden === true ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
5418
+ devices?.labelsHidden === true ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
5143
5419
  "Your browser is hiding device names until you allow camera and microphone access.",
5144
5420
  /* @__PURE__ */ jsx6(
5145
5421
  "button",
@@ -5155,9 +5431,9 @@ function PreJoinBody({
5155
5431
  ] }) : null,
5156
5432
  devices?.fallbackNotice != null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
5157
5433
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audioinput", label: "Microphone" }),
5158
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field-row", children: [
5434
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field-row", children: [
5159
5435
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
5160
- /* @__PURE__ */ jsxs3(
5436
+ /* @__PURE__ */ jsxs4(
5161
5437
  Button,
5162
5438
  {
5163
5439
  type: "button",
@@ -5180,8 +5456,8 @@ function PreJoinBody({
5180
5456
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "videoinput", label: "Camera" }),
5181
5457
  /* @__PURE__ */ jsx6(EffectsSettings, { preview: preview.preview }),
5182
5458
  recording.consentNotice !== null ? /* @__PURE__ */ jsx6(Alert, { variant: "info", children: /* @__PURE__ */ jsx6(AlertDescription, { children: recording.consentNotice }) }) : null,
5183
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-actions", children: [
5184
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
5459
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin-actions", children: [
5460
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
5185
5461
  /* @__PURE__ */ jsx6(
5186
5462
  Checkbox,
5187
5463
  {
@@ -5192,7 +5468,7 @@ function PreJoinBody({
5192
5468
  ),
5193
5469
  /* @__PURE__ */ jsx6(Label, { htmlFor: "mx-meet-join-video", children: "Join with video" })
5194
5470
  ] }),
5195
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
5471
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
5196
5472
  /* @__PURE__ */ jsx6(
5197
5473
  Checkbox,
5198
5474
  {
@@ -5206,7 +5482,7 @@ function PreJoinBody({
5206
5482
  room.secondDevice === null ? /* @__PURE__ */ jsx6(Button, { type: "button", className: "mx-meet__join", disabled: joining, onClick: () => joinWith(), children: joining ? "Joining\u2026" : observe2 ? "Observe" : "Join now" }) : (
5207
5483
  // S7: ALREADY IN THIS MEETING on another tab or device — the meeting's choice
5208
5484
  // (Meet: Switch here / Join here too; Teams: Transfer here / Add this device).
5209
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__second-device", "data-meet-region": "second-device", children: [
5485
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__second-device", "data-meet-region": "second-device", children: [
5210
5486
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__hint", children: "You're in this meeting on another device" }),
5211
5487
  /* @__PURE__ */ jsx6(
5212
5488
  Button,
@@ -5233,23 +5509,29 @@ function PreJoinBody({
5233
5509
  ] })
5234
5510
  )
5235
5511
  ] }),
5236
- room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
5512
+ room.failure !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__error", children: [
5237
5513
  room.failure.message,
5238
5514
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: room.failure.remedy })
5239
5515
  ] }) : null
5240
5516
  ] })
5241
5517
  ] });
5242
5518
  }
5243
- function useCameraPreview(deviceId, effects) {
5244
- const [preview, setPreview] = useState4(null);
5245
- const [error, setError] = useState4(null);
5519
+ function useCameraPreview(deviceId, effects, report, attempt = 0) {
5520
+ const reportRef = useRef6(report);
5521
+ reportRef.current = report;
5522
+ const [preview, setPreview] = useState5(null);
5523
+ const [error, setError] = useState5(null);
5246
5524
  const current = useRef6(null);
5247
5525
  const initialEffect = useRef6(toVideoEffect(effects));
5248
5526
  initialEffect.current = toVideoEffect(effects);
5249
5527
  useEffect6(() => {
5250
- if (deviceId === void 0) return void 0;
5528
+ if (deviceId === void 0) {
5529
+ reportRef.current?.("off");
5530
+ return void 0;
5531
+ }
5251
5532
  let live = true;
5252
5533
  setError(null);
5534
+ reportRef.current?.("prompting");
5253
5535
  void createCameraPreview(deviceId, initialEffect.current).then((created) => {
5254
5536
  if (!live) {
5255
5537
  created.stop();
@@ -5257,8 +5539,10 @@ function useCameraPreview(deviceId, effects) {
5257
5539
  }
5258
5540
  current.current = created;
5259
5541
  setPreview(created);
5542
+ reportRef.current?.("on");
5260
5543
  }).catch((thrown) => {
5261
5544
  if (!live) return;
5545
+ reportRef.current?.({ error: thrown });
5262
5546
  const failure = thrown;
5263
5547
  const message = (failure.message ?? "").replace(/^meet\.[A-Za-z.()]+:\s*/, "");
5264
5548
  const sentence = message.length > 0 ? message.charAt(0).toUpperCase() + message.slice(1) : "";
@@ -5270,7 +5554,7 @@ function useCameraPreview(deviceId, effects) {
5270
5554
  current.current = null;
5271
5555
  setPreview(null);
5272
5556
  };
5273
- }, [deviceId]);
5557
+ }, [deviceId, attempt]);
5274
5558
  return {
5275
5559
  preview,
5276
5560
  error,
@@ -5293,9 +5577,9 @@ function DevicePicker({
5293
5577
  const triggerId = `mx-meet-device-${kind}`;
5294
5578
  const valueOf = (deviceId) => deviceId.length > 0 ? deviceId : "default";
5295
5579
  const current = devices?.selected[kind] ?? host.devices.resolve(kind) ?? "";
5296
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
5580
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field", children: [
5297
5581
  /* @__PURE__ */ jsx6(Label, { htmlFor: triggerId, children: label }),
5298
- /* @__PURE__ */ jsxs3(
5582
+ /* @__PURE__ */ jsxs4(
5299
5583
  Select,
5300
5584
  {
5301
5585
  ...current.length > 0 ? { value: valueOf(current) } : {},
@@ -5382,19 +5666,19 @@ function MeetSkinRoom({
5382
5666
  if (screen === "refused" || screen === "exit") {
5383
5667
  return /* @__PURE__ */ jsx6("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx6(ExitScreen, { ...onLeave !== void 0 ? { onLeave } : {} }) });
5384
5668
  }
5385
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet", children: [
5669
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet", children: [
5386
5670
  /* @__PURE__ */ jsx6(ConsentNotice, {}),
5387
5671
  /* @__PURE__ */ jsx6(AttendanceNotice, {}),
5388
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__header", children: [
5672
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__header", children: [
5389
5673
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
5390
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
5674
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__meta", children: [
5391
5675
  participantSummary(snapshot?.participants ?? []),
5392
5676
  elapsed > 0 ? ` \xB7 ${formatDurationMs2(elapsed)}` : ""
5393
5677
  ] }),
5394
5678
  /* @__PURE__ */ jsx6(RecordingIndicator, {}),
5395
5679
  captureHeldOf(snapshot?.meeting) ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", "data-meet-capture-held": "", children: "Confidential \xB7 not recorded" }) : null,
5396
5680
  isObserverRole(snapshot?.grants.role) ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", "data-meet-observing": "self", children: "Observing" }) : null,
5397
- snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
5681
+ snapshot?.locked === true ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__badge", children: [
5398
5682
  /* @__PURE__ */ jsx6(LockIcon, { width: 12, height: 12 }),
5399
5683
  " Locked"
5400
5684
  ] }) : null,
@@ -5410,9 +5694,17 @@ function MeetSkinRoom({
5410
5694
  }
5411
5695
  function ShareNotice() {
5412
5696
  const { share, actions } = useMeetCore();
5697
+ const [soundHintClosed, setSoundHintClosed] = useState5(null);
5698
+ if (share.state === "presenting" && share.audio === false && soundHintClosed !== share.at) {
5699
+ return /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-audio-missing", children: [
5700
+ "Sound not shared",
5701
+ /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: "To include sound, share a tab and turn on Also share tab audio" }),
5702
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setSoundHintClosed(share.at), children: "Dismiss" })
5703
+ ] });
5704
+ }
5413
5705
  if (share.state !== "refused") return null;
5414
5706
  const text = share.reason === "unsupported" ? "You can't share your screen from this browser" : share.reason === "blocked" ? "Screen sharing is blocked" : "Couldn't start sharing your screen";
5415
- return /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
5707
+ return /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
5416
5708
  text,
5417
5709
  share.remedy !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: share.remedy }) : null,
5418
5710
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: actions.dismissShareNotice, children: "Dismiss" })
@@ -5440,9 +5732,22 @@ function clockText(ms) {
5440
5732
  }
5441
5733
  function ExitScreen({ onLeave }) {
5442
5734
  const { phase, reason, host, snapshot, actions, call, connection } = useMeetCore();
5443
- const [busy, setBusy] = useState4(false);
5735
+ const [busy, setBusy] = useState5(false);
5444
5736
  const failure = snapshot?.failure ?? null;
5445
- const retryLeft = useCountdown(phase === "refused:lobby_rejects" ? failure?.retryAt ?? null : null);
5737
+ const retryLeft = useCountdown(
5738
+ phase === "refused:lobby_rejects" || phase === "refused:too_early" ? failure?.retryAt ?? null : null
5739
+ );
5740
+ const reaskedAtZero = useRef6(false);
5741
+ useEffect6(() => {
5742
+ if (phase !== "refused:too_early") {
5743
+ reaskedAtZero.current = false;
5744
+ return;
5745
+ }
5746
+ if (retryLeft === 0 && !reaskedAtZero.current) {
5747
+ reaskedAtZero.current = true;
5748
+ actions.retry();
5749
+ }
5750
+ }, [phase, retryLeft, actions]);
5446
5751
  const rejoin = /* @__PURE__ */ jsx6(
5447
5752
  Button,
5448
5753
  {
@@ -5480,11 +5785,19 @@ function ExitScreen({ onLeave }) {
5480
5785
  if (phase.startsWith("refused:")) {
5481
5786
  const code = phase.slice("refused:".length);
5482
5787
  title = REFUSED_TITLES[code] ?? "You can't join this meeting";
5483
- line = code === "too_early" || code === "registration_required" || code === "cancelled" ? failure?.remedy ?? null : null;
5484
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5788
+ line = code === "too_early" || code === "registration_required" || code === "cancelled" || code === "wrong_account" ? failure?.remedy ?? null : null;
5789
+ if (code === "too_early" && retryLeft !== null && retryLeft > 0) line = `Opens in ${clockText(retryLeft)}`;
5790
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5485
5791
  /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", onClick: actions.retry, children: "Try again" }),
5486
5792
  home
5487
5793
  ] });
5794
+ if (code === "sign_in_required" || code === "wrong_account") {
5795
+ const back = typeof window === "undefined" ? "/" : `${window.location.pathname}${window.location.search}`;
5796
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5797
+ /* @__PURE__ */ jsx6(Button, { asChild: true, children: /* @__PURE__ */ jsx6("a", { href: `/login?redirectTo=${encodeURIComponent(back)}`, children: code === "sign_in_required" ? "Sign in" : "Switch account" }) }),
5798
+ home
5799
+ ] });
5800
+ }
5488
5801
  if (code === "lobby_rejects") {
5489
5802
  if (retryLeft !== null && retryLeft > 0) {
5490
5803
  line = `You can ask again in ${clockText(retryLeft)}`;
@@ -5492,7 +5805,7 @@ function ExitScreen({ onLeave }) {
5492
5805
  actionsNode = home;
5493
5806
  } else if (retryLeft === 0) {
5494
5807
  line = "You can ask to join again";
5495
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5808
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5496
5809
  /* @__PURE__ */ jsx6(
5497
5810
  Button,
5498
5811
  {
@@ -5516,16 +5829,37 @@ function ExitScreen({ onLeave }) {
5516
5829
  switch (phase) {
5517
5830
  case "left":
5518
5831
  title = "You left the meeting";
5519
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5832
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5520
5833
  rejoin,
5521
5834
  home
5522
5835
  ] });
5523
5836
  break;
5524
5837
  case "disconnected":
5838
+ if (failure?.stage === "join" && (failure.reason ?? null) === null) {
5839
+ title = "Can't connect to the meeting";
5840
+ line = connection === "offline" ? "You're offline. Check your internet connection." : "Check your network. A VPN, firewall or proxy may be blocking the call.";
5841
+ notice = "cannot-connect";
5842
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5843
+ /* @__PURE__ */ jsx6(
5844
+ Button,
5845
+ {
5846
+ type: "button",
5847
+ disabled: busy,
5848
+ onClick: () => {
5849
+ setBusy(true);
5850
+ void actions.rejoin().catch(() => void 0).finally(() => setBusy(false));
5851
+ },
5852
+ children: "Try again"
5853
+ }
5854
+ ),
5855
+ home
5856
+ ] });
5857
+ break;
5858
+ }
5525
5859
  title = "You lost your connection to the meeting";
5526
5860
  line = connection === "offline" ? "You're offline. You'll rejoin automatically when your internet is back." : connection === "server_unreachable" ? "Can't reach the meeting server. You'll rejoin automatically when it answers." : failure?.remedy ?? "Check your internet connection, then rejoin.";
5527
5861
  notice = "disconnected";
5528
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5862
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5529
5863
  rejoin,
5530
5864
  home
5531
5865
  ] });
@@ -5538,14 +5872,14 @@ function ExitScreen({ onLeave }) {
5538
5872
  title = "You joined from another tab or device";
5539
5873
  line = "This screen left the meeting so you aren't in it twice.";
5540
5874
  notice = "displaced";
5541
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5875
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5542
5876
  rejoin,
5543
5877
  home
5544
5878
  ] });
5545
5879
  break;
5546
5880
  case "inactive":
5547
5881
  title = "You left the meeting because this tab was inactive";
5548
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5882
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5549
5883
  rejoin,
5550
5884
  home
5551
5885
  ] });
@@ -5568,7 +5902,7 @@ function ExitScreen({ onLeave }) {
5568
5902
  break;
5569
5903
  }
5570
5904
  }
5571
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", "data-meet-exit": phase, children: [
5905
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__waiting", "data-meet-exit": phase, children: [
5572
5906
  /* @__PURE__ */ jsx6(Avatar, { name: host?.identity.displayName ?? "", url: host?.identity.avatarUrl ?? null, size: 72 }),
5573
5907
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: title }),
5574
5908
  line !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: line }) : null,
@@ -5579,7 +5913,7 @@ function ExitScreen({ onLeave }) {
5579
5913
  function WaitingRoom({ host, onLeave }) {
5580
5914
  const { waiting, withdraw, askAgain } = useWaiting();
5581
5915
  const { phaseNotice } = useMeetCore();
5582
- const [busy, setBusy] = useState4(false);
5916
+ const [busy, setBusy] = useState5(false);
5583
5917
  const admission = waiting?.admission ?? "knocking";
5584
5918
  const reknockLeft = useCountdown(admission === "denied" ? waiting?.reknockAt ?? null : null);
5585
5919
  const run = (action) => () => {
@@ -5602,21 +5936,21 @@ function WaitingRoom({ host, onLeave }) {
5602
5936
  line = `You can ask again in ${clockText(reknockLeft)}`;
5603
5937
  cooldownNotice = true;
5604
5938
  }
5605
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
5939
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
5606
5940
  waiting?.reknockAllowed === true || waiting?.reknockAt != null && reknockLeft === 0 ? /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Ask to join again" }) : null,
5607
5941
  home
5608
5942
  ] });
5609
5943
  break;
5610
5944
  case "expired":
5611
5945
  title = "No one responded";
5612
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
5946
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
5613
5947
  /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Ask again" }),
5614
5948
  home
5615
5949
  ] });
5616
5950
  break;
5617
5951
  case "withdrawn":
5618
5952
  title = "You left the waiting room";
5619
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
5953
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
5620
5954
  /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Rejoin" }),
5621
5955
  home
5622
5956
  ] });
@@ -5630,7 +5964,7 @@ function WaitingRoom({ host, onLeave }) {
5630
5964
  line = waiting?.admittersPresent === false ? "The host isn't here yet" : null;
5631
5965
  actions = /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", disabled: busy, onClick: run(withdraw), children: "Cancel request" });
5632
5966
  }
5633
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", children: [
5967
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__waiting", children: [
5634
5968
  /* @__PURE__ */ jsx6(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
5635
5969
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: title }),
5636
5970
  phaseNotice === "sent-to-waiting" ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", role: "status", "data-meet-notice": "sent-to-waiting", children: "The host moved you back to the waiting room" }) : null,
@@ -5650,9 +5984,9 @@ function HostMenu() {
5650
5984
  const host = useRequiredMeetHost();
5651
5985
  const snapshot = useMeetSnapshot();
5652
5986
  const end = useEndMeeting();
5653
- const [confirmingEnd, setConfirmingEnd] = useState4(false);
5987
+ const [confirmingEnd, setConfirmingEnd] = useState5(false);
5654
5988
  const locked = snapshot?.locked === true;
5655
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
5989
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__host-menu", children: [
5656
5990
  /* @__PURE__ */ jsx6(
5657
5991
  "button",
5658
5992
  {
@@ -5664,7 +5998,7 @@ function HostMenu() {
5664
5998
  children: locked ? "Unlock meeting" : "Lock meeting"
5665
5999
  }
5666
6000
  ),
5667
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
6001
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
5668
6002
  /* @__PURE__ */ jsx6("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." }),
5669
6003
  /* @__PURE__ */ jsx6(
5670
6004
  "button",
@@ -5720,9 +6054,9 @@ function GuestRecordAccessControl({
5720
6054
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
5721
6055
  if (host === null || !isHost) return null;
5722
6056
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
5723
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
6057
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
5724
6058
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
5725
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
6059
+ /* @__PURE__ */ jsxs4("label", { className: "mx-meet__field", children: [
5726
6060
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
5727
6061
  /* @__PURE__ */ jsx6(
5728
6062
  "select",
@@ -5739,12 +6073,12 @@ function GuestRecordAccessControl({
5739
6073
  }
5740
6074
  )
5741
6075
  ] }),
5742
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
6076
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
5743
6077
  guestRecordAccessExplanation(access.setting),
5744
6078
  resolved
5745
6079
  ] }),
5746
6080
  access.saving ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
5747
- access.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
6081
+ access.error !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
5748
6082
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
5749
6083
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
5750
6084
  ] }) : null
@@ -5767,6 +6101,7 @@ export {
5767
6101
  ChatIcon,
5768
6102
  ChatPanel,
5769
6103
  CheckIcon,
6104
+ ChevronUpIcon,
5770
6105
  CloseIcon,
5771
6106
  ConnectionDot,
5772
6107
  ConsentNotice,