@ai-matrx/meet 0.11.43 → 0.11.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -2469,11 +2469,13 @@ function minutesLeft(policy, startedAtMs, nowMs) {
2469
2469
  }
2470
2470
 
2471
2471
  // src/core/attendance.ts
2472
+ var IDLE_PREVIEW = { state: "idle", unavailable: null };
2472
2473
  var IDLE_MEDIA_REGION = {
2473
2474
  permission: { microphone: "unknown", camera: "unknown" },
2474
2475
  audioOutput: "ok",
2475
2476
  notice: null,
2476
- offer: null
2477
+ offer: null,
2478
+ preview: { microphone: IDLE_PREVIEW, camera: IDLE_PREVIEW }
2477
2479
  };
2478
2480
  var IDLE_TRACK = { enabled: false, unavailable: null };
2479
2481
  var IDLE_MEDIA = {
@@ -4830,6 +4832,47 @@ function createMeetSessionIdentity(options) {
4830
4832
  });
4831
4833
  }
4832
4834
 
4835
+ // src/core/capabilities.ts
4836
+ var IN_APP = [
4837
+ [/Instagram/i, "Instagram"],
4838
+ [/FBAN|FBAV|FB_IAB/i, "Facebook"],
4839
+ [/LinkedInApp/i, "LinkedIn"],
4840
+ [/MicroMessenger/i, "WeChat"],
4841
+ [/Snapchat/i, "Snapchat"],
4842
+ [/\bLine\//i, "LINE"],
4843
+ [/Twitter|TwitterAndroid/i, "X"],
4844
+ [/TikTok|musical_ly|BytedanceWebview/i, "TikTok"]
4845
+ ];
4846
+ function isMobileUserAgent(userAgent, maxTouchPoints = 0) {
4847
+ if (/iPhone|iPod|Android|Mobile|iPad/i.test(userAgent)) return true;
4848
+ return /Macintosh/.test(userAgent) && maxTouchPoints > 1;
4849
+ }
4850
+ function detectCapabilities(scope = typeof globalThis === "undefined" ? null : globalThis) {
4851
+ if (scope === null || scope.navigator === void 0) {
4852
+ return { canJoin: true, reason: null, inAppBrowser: null, mobile: false, canShareScreen: false };
4853
+ }
4854
+ const ua = scope.navigator.userAgent ?? "";
4855
+ const webrtc = typeof scope.RTCPeerConnection === "function" || typeof scope.webkitRTCPeerConnection === "function";
4856
+ const mobile = isMobileUserAgent(ua, scope.navigator.maxTouchPoints ?? 0);
4857
+ const inAppBrowser = IN_APP.find(([pattern]) => pattern.test(ua))?.[1] ?? null;
4858
+ return {
4859
+ canJoin: webrtc,
4860
+ reason: webrtc ? null : "no_webrtc",
4861
+ inAppBrowser,
4862
+ mobile,
4863
+ canShareScreen: !mobile && typeof scope.navigator.mediaDevices?.getDisplayMedia === "function"
4864
+ };
4865
+ }
4866
+ function unsupportedWords(capabilities) {
4867
+ if (capabilities.inAppBrowser !== null) {
4868
+ return {
4869
+ title: `${capabilities.inAppBrowser}'s browser can't join calls`,
4870
+ body: "Open this link in Chrome, Safari, Edge or Firefox"
4871
+ };
4872
+ }
4873
+ return { title: "This browser can't join calls", body: "Open this link in Chrome, Safari, Edge or Firefox" };
4874
+ }
4875
+
4833
4876
  // src/core/media-supervisor.ts
4834
4877
  function classifyDeviceFailure(error, permission) {
4835
4878
  if (permission === "denied") return "denied";
@@ -4890,7 +4933,7 @@ function deviceFixSteps(kind, reason, where) {
4890
4933
  case "safari":
4891
4934
  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"];
4892
4935
  default:
4893
- return ["Click the icon left of the web address", `Set ${device} to Allow`, "Press Try again"];
4936
+ return ["Click the site settings icon in the address bar", `Set ${device} to Allow`, "Press Try again"];
4894
4937
  }
4895
4938
  case "blocked_os": {
4896
4939
  const app = where.browser === "chrome" ? "Google Chrome" : where.browser === "edge" ? "Microsoft Edge" : where.browser === "firefox" ? "Firefox" : "your browser";
@@ -4988,7 +5031,7 @@ function createMediaSupervisor(options) {
4988
5031
  function setRegion(next) {
4989
5032
  const current = region();
4990
5033
  const merged = { ...current, ...next };
4991
- if (merged.audioOutput === current.audioOutput && merged.notice === current.notice && merged.offer === current.offer && merged.permission.microphone === current.permission.microphone && merged.permission.camera === current.permission.camera) {
5034
+ if (merged.audioOutput === current.audioOutput && merged.notice === current.notice && merged.offer === current.offer && merged.preview === current.preview && merged.permission.microphone === current.permission.microphone && merged.permission.camera === current.permission.camera) {
4992
5035
  return;
4993
5036
  }
4994
5037
  store.patch({ mediaRegion: merged });
@@ -5084,7 +5127,7 @@ function createMediaSupervisor(options) {
5084
5127
  if (permission !== "unknown") setPermission(kind, permission);
5085
5128
  return unavailableFrom(normalized, classifyDeviceFailure(normalized, permission));
5086
5129
  }
5087
- return {
5130
+ const api = {
5088
5131
  start() {
5089
5132
  if (started || platform === null) return;
5090
5133
  started = true;
@@ -5106,6 +5149,16 @@ function createMediaSupervisor(options) {
5106
5149
  started = false;
5107
5150
  },
5108
5151
  unavailable,
5152
+ async preview(kind, outcome) {
5153
+ api.start();
5154
+ let next;
5155
+ if (typeof outcome === "string") next = { state: outcome, unavailable: null };
5156
+ else next = { state: "unavailable", unavailable: await unavailable(outcome.error, kind, `meet.${kind}Preview`) };
5157
+ const current = region().preview;
5158
+ const was = current[kind];
5159
+ if (was.state === next.state && was.unavailable?.reason === next.unavailable?.reason && was.unavailable?.message === next.unavailable?.message) return;
5160
+ setRegion({ preview: { ...region().preview, [kind]: next } });
5161
+ },
5109
5162
  onAudioPlayback(canPlay) {
5110
5163
  setRegion({ audioOutput: canPlay ? "ok" : "blocked" });
5111
5164
  },
@@ -5164,6 +5217,7 @@ function createMediaSupervisor(options) {
5164
5217
  setRegion({ notice: null });
5165
5218
  }
5166
5219
  };
5220
+ return api;
5167
5221
  }
5168
5222
 
5169
5223
  // src/core/room-events.ts
@@ -5675,7 +5729,8 @@ function createRoomEngine(options) {
5675
5729
  message: normalized.message,
5676
5730
  remedy: normalized.remedy,
5677
5731
  reason: normalized.reason,
5678
- retryAt: normalized.retryAfterSeconds === null ? null : now() + normalized.retryAfterSeconds * 1e3
5732
+ retryAt: normalized.retryAfterSeconds === null ? null : now() + normalized.retryAfterSeconds * 1e3,
5733
+ stage: "join"
5679
5734
  }
5680
5735
  });
5681
5736
  store.dispatch({ type: "join_failed", reason: normalized.reason ?? null });
@@ -6066,6 +6121,10 @@ function createRoomEngine(options) {
6066
6121
  }
6067
6122
  departures.clear();
6068
6123
  liveRoster = list;
6124
+ const localNow = list.find((p) => p.isLocal);
6125
+ if (localNow !== void 0 && !localNow.screenSharing && store.snapshot().share.state === "presenting") {
6126
+ store.patch({ share: NO_SHARE });
6127
+ }
6069
6128
  const merged = mergeGhosts(list, ghosts, at);
6070
6129
  ghosts = merged.kept;
6071
6130
  const people = /* @__PURE__ */ new Map();
@@ -6285,7 +6344,10 @@ function createRoomEngine(options) {
6285
6344
  try {
6286
6345
  await driver.setScreenShareEnabled(enabled);
6287
6346
  ambiguousShareDenials = 0;
6288
- store.patch({ share: { state: enabled ? "presenting" : "none", reason: null, remedy: null, at: now() } });
6347
+ const audio = enabled ? driver?.screenShareHasAudio?.() : void 0;
6348
+ store.patch({
6349
+ share: { state: enabled ? "presenting" : "none", reason: null, remedy: null, at: now(), ...audio !== void 0 ? { audio } : {} }
6350
+ });
6289
6351
  } catch (error) {
6290
6352
  const kind = classifyScreenShareError(error);
6291
6353
  if (kind === "ambiguous") {
@@ -6352,13 +6414,14 @@ function createRoomEngine(options) {
6352
6414
  return driver?.supportsVideoEffects?.() ?? false;
6353
6415
  },
6354
6416
  supportsScreenShare() {
6355
- return driver?.supportsScreenShare?.() ?? true;
6417
+ return driver?.supportsScreenShare?.() ?? detectCapabilities().canShareScreen;
6356
6418
  },
6357
6419
  async switchDevice(kind, deviceId2) {
6358
6420
  if (driver === null) return;
6359
6421
  await driver.switchDevice(kind, deviceId2);
6360
6422
  },
6361
6423
  enableAudio: () => media.enableAudio(),
6424
+ previewDevice: (kind, outcome) => media.preview(kind, outcome),
6362
6425
  acceptDeviceOffer: () => media.acceptOffer(),
6363
6426
  dismissDeviceOffer: () => media.dismissOffer(),
6364
6427
  dismissDeviceNotice: () => media.dismissNotice(),
@@ -6830,7 +6893,15 @@ function createLiveKitDriver(handlers, options = {}) {
6830
6893
  created.on(RoomEvent.ParticipantConnected, roster).on(RoomEvent.ParticipantDisconnected, (participant, reason) => {
6831
6894
  handlers.participantLeft?.(participant.identity, reasonName(reason));
6832
6895
  roster();
6833
- }).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished, roster).on(RoomEvent.LocalTrackUnpublished, roster).on(RoomEvent.ParticipantNameChanged, roster).on(RoomEvent.ParticipantAttributesChanged, roster).on(RoomEvent.ParticipantMetadataChanged, roster).on(RoomEvent.RoomMetadataChanged, (metadata) => {
6896
+ }).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished, (publication) => {
6897
+ if (publication.source === Track.Source.ScreenShare) {
6898
+ const ended = () => {
6899
+ void created.localParticipant.setScreenShareEnabled(false).catch(() => void 0);
6900
+ };
6901
+ publication.track?.mediaStreamTrack.addEventListener("ended", ended, { once: true });
6902
+ }
6903
+ roster();
6904
+ }).on(RoomEvent.LocalTrackUnpublished, roster).on(RoomEvent.ParticipantNameChanged, roster).on(RoomEvent.ParticipantAttributesChanged, roster).on(RoomEvent.ParticipantMetadataChanged, roster).on(RoomEvent.RoomMetadataChanged, (metadata) => {
6834
6905
  handlers.roomMetadata?.(metadata ?? "");
6835
6906
  }).on(RoomEvent.AudioPlaybackStatusChanged, (canPlay) => {
6836
6907
  handlers.audioPlayback?.(canPlay);
@@ -6971,7 +7042,10 @@ function createLiveKitDriver(handlers, options = {}) {
6971
7042
  },
6972
7043
  async setScreenShareEnabled(enabled) {
6973
7044
  try {
6974
- await requireRoom("setScreenShareEnabled").localParticipant.setScreenShareEnabled(enabled);
7045
+ await requireRoom("setScreenShareEnabled").localParticipant.setScreenShareEnabled(
7046
+ enabled,
7047
+ enabled ? { audio: true, systemAudio: "include" } : void 0
7048
+ );
6975
7049
  } catch (error) {
6976
7050
  throw normalizeScreenShareError(error, "meet.setScreenShareEnabled");
6977
7051
  }
@@ -7010,8 +7084,13 @@ function createLiveKitDriver(handlers, options = {}) {
7010
7084
  supportsVideoEffects() {
7011
7085
  return videoEffectsSupported();
7012
7086
  },
7087
+ screenShareHasAudio() {
7088
+ const target = room;
7089
+ if (target === null) return false;
7090
+ return target.localParticipant.getTrackPublications().some((p) => String(p.source) === "screen_share_audio" && p.track !== void 0);
7091
+ },
7013
7092
  supportsScreenShare() {
7014
- return typeof navigator !== "undefined" && typeof navigator.mediaDevices?.getDisplayMedia === "function";
7093
+ return detectCapabilities().canShareScreen;
7015
7094
  },
7016
7095
  attach(identity, kind, element) {
7017
7096
  const target = requireRoom("attach");
@@ -7483,7 +7562,7 @@ function useLocalUserId() {
7483
7562
  }
7484
7563
 
7485
7564
  // src/react/root.tsx
7486
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
7565
+ import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
7487
7566
 
7488
7567
  // src/core/observation.ts
7489
7568
  function observedRole(role, standing) {
@@ -7497,6 +7576,21 @@ function observedDevice(track, permission = "unknown", held = null) {
7497
7576
  const reason = deviceUnavailableReason(track, permission);
7498
7577
  return reason === null ? "muted_by_me" : `unavailable:${reason}`;
7499
7578
  }
7579
+ function observedPreview(preview, permission = "unknown") {
7580
+ if (permission === "denied") return "unavailable:denied";
7581
+ switch (preview.state) {
7582
+ case "on":
7583
+ return "on";
7584
+ case "off":
7585
+ return "muted_by_me";
7586
+ case "prompting":
7587
+ return "prompting";
7588
+ case "unavailable":
7589
+ return `unavailable:${preview.unavailable?.reason ?? "failed"}`;
7590
+ default:
7591
+ return null;
7592
+ }
7593
+ }
7500
7594
  function endedRecord(snapshot, given) {
7501
7595
  const record = snapshot?.meeting ?? given;
7502
7596
  return record !== null && record.endedAt !== null;
@@ -7520,18 +7614,22 @@ function observe(input) {
7520
7614
  const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
7521
7615
  const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
7522
7616
  const deviceInPlay = phase === "joining" || inCall;
7617
+ const region = snapshot?.mediaRegion;
7618
+ const atPrejoin = phase === "prejoin" && region !== void 0;
7523
7619
  return {
7524
7620
  phase,
7525
7621
  reason: phase === "ended" ? snapshot?.reason ?? null : snapshot?.reason ?? reasonOf(phase),
7526
7622
  role,
7527
- connection: snapshot?.connection ?? "stable",
7623
+ // `net-blip`: in the call, a drop shorter than `reconnect_banner_delay_ms` is not something the
7624
+ // person sees — the contract says what is on screen, so it reads `stable` until the banner shows.
7625
+ connection: snapshot === null ? "stable" : inCall && snapshot.connection !== "stable" && !snapshot.connectionBanner ? "stable" : snapshot.connection,
7528
7626
  hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot !== null && isWaitingPhase(snapshot.phase) ? snapshot.waiting?.admittersPresent ?? null : null,
7529
7627
  lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
7530
7628
  recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
7531
7629
  // S6c: the autoplay region is known only inside the room (no remote audio exists elsewhere).
7532
7630
  audioBlocked: inCall && snapshot !== null ? snapshot.mediaRegion.audioOutput === "blocked" : null,
7533
- camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : null,
7534
- microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : null
7631
+ 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,
7632
+ 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
7535
7633
  };
7536
7634
  }
7537
7635
  function lockedFor(snapshot, kind, inCall) {
@@ -7613,7 +7711,7 @@ function microphoneNoticeCode(track, permission = "unknown") {
7613
7711
  }
7614
7712
 
7615
7713
  // src/react/root.tsx
7616
- import { jsx as jsx2 } from "react/jsx-runtime";
7714
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
7617
7715
  function useCoreObservation(options = {}) {
7618
7716
  const snapshot = useMeetSnapshot();
7619
7717
  const { meeting, phase, reason } = options;
@@ -7631,7 +7729,13 @@ function MeetRoot({
7631
7729
  ...options
7632
7730
  }) {
7633
7731
  const snapshot = useMeetSnapshot();
7634
- const observation = useCoreObservation(options);
7732
+ const probed = useCapabilities();
7733
+ const base = useCoreObservation(options);
7734
+ const unsupported = probed !== null && !probed.canJoin;
7735
+ const observation = useMemo2(
7736
+ () => unsupported ? { ...staticObservation("unsupported", probed?.reason ?? null) } : base,
7737
+ [unsupported, probed, base]
7738
+ );
7635
7739
  const attrs = useMemo2(() => rootAttributes(observation), [observation]);
7636
7740
  const latest = useRef2({ observation, storePhase: snapshot?.phase ?? null });
7637
7741
  latest.current = { observation, storePhase: snapshot?.phase ?? null };
@@ -7649,11 +7753,38 @@ function MeetRoot({
7649
7753
  if (target.__matrxMeet === diagnostics) delete target.__matrxMeet;
7650
7754
  };
7651
7755
  }, []);
7652
- return /* @__PURE__ */ jsx2("div", { ...attrs, style: { display: "contents" }, children });
7756
+ return /* @__PURE__ */ jsx2("div", { ...attrs, style: { display: "contents" }, children: unsupported && probed !== null ? /* @__PURE__ */ jsx2(UnsupportedBrowser, { capabilities: probed }) : children });
7757
+ }
7758
+ function useCapabilities() {
7759
+ const [found, setFound] = useState2(null);
7760
+ useEffect2(() => {
7761
+ setFound(detectCapabilities());
7762
+ }, []);
7763
+ return found;
7764
+ }
7765
+ function UnsupportedBrowser({ capabilities }) {
7766
+ const words = unsupportedWords(capabilities);
7767
+ const [copied, setCopied] = useState2(false);
7768
+ const href = typeof window === "undefined" ? "" : window.location.href;
7769
+ return /* @__PURE__ */ jsx2("div", { className: "mx-meet", children: /* @__PURE__ */ jsxs("div", { className: "mx-meet__waiting", "data-meet-exit": "unsupported", children: [
7770
+ /* @__PURE__ */ jsx2("h1", { className: "mx-meet__prejoin-title", children: words.title }),
7771
+ /* @__PURE__ */ jsx2("p", { className: "mx-meet__hint", role: "status", "data-meet-notice": "browser-unsupported", children: words.body }),
7772
+ href.length > 0 ? /* @__PURE__ */ jsx2(
7773
+ "button",
7774
+ {
7775
+ type: "button",
7776
+ className: "mx-meet__primary",
7777
+ onClick: () => {
7778
+ void navigator.clipboard?.writeText(href).then(() => setCopied(true), () => void 0);
7779
+ },
7780
+ children: copied ? "Link copied" : "Copy link"
7781
+ }
7782
+ ) : null
7783
+ ] }) });
7653
7784
  }
7654
7785
 
7655
7786
  // src/react/hooks.ts
7656
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState2, useSyncExternalStore as useSyncExternalStore2 } from "react";
7787
+ import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState3, useSyncExternalStore as useSyncExternalStore2 } from "react";
7657
7788
  import { useRealtimeManager as useRealtimeManager2 } from "@ai-matrx/realtime/react";
7658
7789
 
7659
7790
  // src/core/record.ts
@@ -8349,7 +8480,8 @@ function useRoom() {
8349
8480
  failure: snapshot?.failure ?? null,
8350
8481
  secondDevice: snapshot?.secondDevice ?? null,
8351
8482
  local,
8352
- canShareScreen: engine?.supportsScreenShare() ?? true,
8483
+ // An observer (role `viewer`) publishes nothing: no Share screen to press and be refused (MD-16).
8484
+ canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null),
8353
8485
  join: useCallback2(
8354
8486
  async (request) => requireEngine(engine, "join").join(request),
8355
8487
  [engine]
@@ -8406,7 +8538,7 @@ function useRoom() {
8406
8538
  }
8407
8539
  function useStage(pageSize = DEFAULT_PAGE_SIZE) {
8408
8540
  const snapshot = useMeetSnapshot();
8409
- const [page, setPage] = useState2(0);
8541
+ const [page, setPage] = useState3(0);
8410
8542
  const stage = useMemo3(
8411
8543
  () => computeStage({
8412
8544
  participants: snapshot?.participants ?? [],
@@ -8440,7 +8572,7 @@ function useTrack(identity, kind) {
8440
8572
  function useCalls() {
8441
8573
  const host = useMeetHost();
8442
8574
  const center = host?.calls ?? null;
8443
- const [, force] = useState2(0);
8575
+ const [, force] = useState3(0);
8444
8576
  useEffect3(() => {
8445
8577
  if (center === null) return void 0;
8446
8578
  const timer = setInterval(() => force((value) => value + 1), 1e3);
@@ -8520,7 +8652,7 @@ function useLobby() {
8520
8652
  };
8521
8653
  }
8522
8654
  function useCountdown(untilMs) {
8523
- const [now, setNow] = useState2(() => Date.now());
8655
+ const [now, setNow] = useState3(() => Date.now());
8524
8656
  const active = typeof untilMs === "number" && untilMs > now;
8525
8657
  useEffect3(() => {
8526
8658
  if (!active) return void 0;
@@ -8533,7 +8665,7 @@ function useCountdown(untilMs) {
8533
8665
  }
8534
8666
  function useKnockNotice() {
8535
8667
  const lobby = useLobby();
8536
- const [dismissed, setDismissed] = useState2([]);
8668
+ const [dismissed, setDismissed] = useState3([]);
8537
8669
  const keyOf = (entry) => `${entry.identity}@${entry.knockedAt}`;
8538
8670
  const open = lobby.canAdmit ? lobby.waiting.filter((entry) => !dismissed.includes(keyOf(entry))) : [];
8539
8671
  const knocker = open[0] ?? null;
@@ -8619,11 +8751,11 @@ function useMeetAi() {
8619
8751
  const host = useMeetHost();
8620
8752
  const snapshot = useMeetSnapshot();
8621
8753
  const isHost = useIsHost();
8622
- const [asking, setAsking] = useState2(false);
8623
- const [answer, setAnswer] = useState2(null);
8624
- const [coverage, setCoverage] = useState2(null);
8625
- const [phase, setPhase] = useState2(null);
8626
- const [error, setError] = useState2(null);
8754
+ const [asking, setAsking] = useState3(false);
8755
+ const [answer, setAnswer] = useState3(null);
8756
+ const [coverage, setCoverage] = useState3(null);
8757
+ const [phase, setPhase] = useState3(null);
8758
+ const [error, setError] = useState3(null);
8627
8759
  const ai = host?.ai ?? null;
8628
8760
  const meeting = snapshot?.meeting ?? null;
8629
8761
  const participants = snapshot?.participants ?? [];
@@ -8776,8 +8908,8 @@ function useEndMeeting() {
8776
8908
  const host = useMeetHost();
8777
8909
  const snapshot = useMeetSnapshot();
8778
8910
  const isHost = useIsHost();
8779
- const [ending, setEnding] = useState2(false);
8780
- const [notice, setNotice] = useState2(null);
8911
+ const [ending, setEnding] = useState3(false);
8912
+ const [notice, setNotice] = useState3(null);
8781
8913
  const meeting = snapshot?.meeting ?? null;
8782
8914
  const session = host?.meetings ?? null;
8783
8915
  return {
@@ -8828,6 +8960,12 @@ function useMediaSupervisor() {
8828
8960
  retry: useCallback2(
8829
8961
  async (kind) => kind === "microphone" ? engine?.setMicrophoneEnabled(true) : engine?.setCameraEnabled(true),
8830
8962
  [engine]
8963
+ ),
8964
+ reportPreview: useCallback2(
8965
+ (kind, outcome) => {
8966
+ void engine?.previewDevice(kind, outcome);
8967
+ },
8968
+ [engine]
8831
8969
  )
8832
8970
  };
8833
8971
  }
@@ -8850,7 +8988,7 @@ function useReactions() {
8850
8988
  return snapshot?.reactions ?? [];
8851
8989
  }
8852
8990
  function useElapsed(startedAt) {
8853
- const [now, setNow] = useState2(() => Date.now());
8991
+ const [now, setNow] = useState3(() => Date.now());
8854
8992
  useEffect3(() => {
8855
8993
  if (startedAt === null) return void 0;
8856
8994
  const timer = setInterval(() => setNow(Date.now()), 1e3);
@@ -8875,7 +9013,7 @@ function useHostControls() {
8875
9013
  (participant) => participant.identity === snapshot.localIdentity
8876
9014
  );
8877
9015
  const actor = me === void 0 ? void 0 : { ...me, role };
8878
- const [busy, setBusy] = useState2(false);
9016
+ const [busy, setBusy] = useState3(false);
8879
9017
  const inRoom = host?.inRoom ?? null;
8880
9018
  const store = host?.store ?? null;
8881
9019
  const notice = snapshot?.actionNotice ?? null;
@@ -8958,7 +9096,7 @@ function useModerationNotice() {
8958
9096
  };
8959
9097
  }
8960
9098
  function useAudioLevel(stream) {
8961
- const [level, setLevel] = useState2(0);
9099
+ const [level, setLevel] = useState3(0);
8962
9100
  useEffect3(() => {
8963
9101
  if (stream === null || stream.getAudioTracks().length === 0) {
8964
9102
  setLevel(0);
@@ -9047,10 +9185,10 @@ function useMeetingRecord(meeting) {
9047
9185
  const repository = host?.repository ?? null;
9048
9186
  const ai = host?.ai ?? null;
9049
9187
  const readerId = host?.identity.userId ?? null;
9050
- const [asking, setAsking] = useState2(false);
9051
- const [answer, setAnswer] = useState2(null);
9052
- const [coverage, setCoverage] = useState2(null);
9053
- const [askError, setAskError] = useState2(null);
9188
+ const [asking, setAsking] = useState3(false);
9189
+ const [answer, setAnswer] = useState3(null);
9190
+ const [coverage, setCoverage] = useState3(null);
9191
+ const [askError, setAskError] = useState3(null);
9054
9192
  const meetingId = meeting?.id ?? null;
9055
9193
  const api = host?.api ?? null;
9056
9194
  const tokens = host?.tokens ?? null;
@@ -9195,11 +9333,11 @@ function useMeetings(limit = 25, organizationFilter = null) {
9195
9333
  const host = useMeetHost();
9196
9334
  const repository = host?.repository ?? null;
9197
9335
  const organizationId = organizationFilter;
9198
- const [meetings, setMeetings] = useState2([]);
9199
- const [hasMore, setHasMore] = useState2(false);
9200
- const [loading, setLoading] = useState2(true);
9201
- const [failure, setFailure] = useState2(null);
9202
- const [nonce, setNonce] = useState2(0);
9336
+ const [meetings, setMeetings] = useState3([]);
9337
+ const [hasMore, setHasMore] = useState3(false);
9338
+ const [loading, setLoading] = useState3(true);
9339
+ const [failure, setFailure] = useState3(null);
9340
+ const [nonce, setNonce] = useState3(0);
9203
9341
  useEffect3(() => {
9204
9342
  if (repository === null) return void 0;
9205
9343
  let live = true;
@@ -9234,10 +9372,10 @@ function useGuestRecordAccess(meeting) {
9234
9372
  const host = useMeetHost();
9235
9373
  const api = host?.api ?? null;
9236
9374
  const stored = guestRecordAccessSetting(meeting);
9237
- const [chosen, setChosen] = useState2(null);
9238
- const [effective, setEffective] = useState2(null);
9239
- const [saving, setSaving] = useState2(false);
9240
- const [error, setError] = useState2(null);
9375
+ const [chosen, setChosen] = useState3(null);
9376
+ const [effective, setEffective] = useState3(null);
9377
+ const [saving, setSaving] = useState3(false);
9378
+ const [error, setError] = useState3(null);
9241
9379
  useEffect3(() => {
9242
9380
  setChosen(null);
9243
9381
  }, [stored, meeting?.id]);
@@ -9276,7 +9414,7 @@ function useGuestRecordAccess(meeting) {
9276
9414
  function useLivePolicy() {
9277
9415
  const snapshot = useMeetSnapshot();
9278
9416
  const role = useRole();
9279
- const [now, setNow] = useState2(() => Date.now());
9417
+ const [now, setNow] = useState3(() => Date.now());
9280
9418
  const limited = (snapshot?.livePolicy.timeLimitMinutes ?? 0) > 0;
9281
9419
  useEffect3(() => {
9282
9420
  if (!limited) return void 0;
@@ -9310,7 +9448,7 @@ function useLivePolicy() {
9310
9448
  import { useEffect as useEffect8 } from "react";
9311
9449
 
9312
9450
  // src/skins/meet/components.tsx
9313
- import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState4 } from "react";
9451
+ import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState5 } from "react";
9314
9452
 
9315
9453
  // src/react/facade.ts
9316
9454
  import { useMemo as useMemo5 } from "react";
@@ -9923,6 +10061,39 @@ function useCollabPanelRequest(onRequest) {
9923
10061
  // src/core/reactions.ts
9924
10062
  var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F602}", "\u{1F62E}", "\u{1F622}", "\u{1F914}", "\u{1F44E}"];
9925
10063
 
10064
+ // src/core/speaking-detector.ts
10065
+ function createSpeakingWhileMutedDetector(options = {}) {
10066
+ const threshold = options.threshold ?? 0.06;
10067
+ const holdMs = options.holdMs ?? 600;
10068
+ const gapMs = options.gapMs ?? 400;
10069
+ const cooldownMs = options.cooldownMs ?? 2e4;
10070
+ let speechStart = null;
10071
+ let lastLoud = null;
10072
+ let firedAt = null;
10073
+ return {
10074
+ feed(level, at) {
10075
+ if (level >= threshold) {
10076
+ if (speechStart === null || lastLoud === null || at - lastLoud > gapMs) speechStart = at;
10077
+ lastLoud = at;
10078
+ } else if (lastLoud !== null && at - lastLoud > gapMs) {
10079
+ speechStart = null;
10080
+ lastLoud = null;
10081
+ }
10082
+ if (speechStart === null || at - speechStart < holdMs) return false;
10083
+ if (firedAt !== null && at - firedAt < cooldownMs) return false;
10084
+ firedAt = at;
10085
+ speechStart = null;
10086
+ lastLoud = null;
10087
+ return true;
10088
+ },
10089
+ reset() {
10090
+ speechStart = null;
10091
+ lastLoud = null;
10092
+ firedAt = null;
10093
+ }
10094
+ };
10095
+ }
10096
+
9926
10097
  // src/react/facade.ts
9927
10098
  var NO_ACTIONS = {
9928
10099
  join: async () => void 0,
@@ -9987,10 +10158,10 @@ function useMeetCore() {
9987
10158
  import { Alert, AlertDescription, Button, Checkbox, ErrorBox, Label, SegmentedControl, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ai-matrx/design-system";
9988
10159
 
9989
10160
  // src/skins/meet/collab.tsx
9990
- import { useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
10161
+ import { useEffect as useEffect5, useRef as useRef5, useState as useState4 } from "react";
9991
10162
 
9992
10163
  // src/skins/meet/icons.tsx
9993
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
10164
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
9994
10165
  function Icon({ children, ...props }) {
9995
10166
  return /* @__PURE__ */ jsx4(
9996
10167
  "svg",
@@ -10011,14 +10182,14 @@ function Icon({ children, ...props }) {
10011
10182
  );
10012
10183
  }
10013
10184
  function MicIcon(props) {
10014
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10185
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10015
10186
  /* @__PURE__ */ jsx4("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
10016
10187
  /* @__PURE__ */ jsx4("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
10017
10188
  /* @__PURE__ */ jsx4("path", { d: "M12 19v3" })
10018
10189
  ] });
10019
10190
  }
10020
10191
  function MicOffIcon(props) {
10021
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10192
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10022
10193
  /* @__PURE__ */ jsx4("path", { d: "M2 2l20 20" }),
10023
10194
  /* @__PURE__ */ jsx4("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
10024
10195
  /* @__PURE__ */ jsx4("path", { d: "M15 9.34V5a3 3 0 0 0-5.94-.6" }),
@@ -10027,20 +10198,20 @@ function MicOffIcon(props) {
10027
10198
  ] });
10028
10199
  }
10029
10200
  function CameraIcon(props) {
10030
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10201
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10031
10202
  /* @__PURE__ */ jsx4("path", { d: "m23 7-7 5 7 5V7Z" }),
10032
10203
  /* @__PURE__ */ jsx4("rect", { x: "1", y: "5", width: "15", height: "14", rx: "2" })
10033
10204
  ] });
10034
10205
  }
10035
10206
  function CameraOffIcon(props) {
10036
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10207
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10037
10208
  /* @__PURE__ */ jsx4("path", { d: "M2 2l20 20" }),
10038
10209
  /* @__PURE__ */ jsx4("path", { d: "M10.66 5H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10" }),
10039
10210
  /* @__PURE__ */ jsx4("path", { d: "M16 16a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2" })
10040
10211
  ] });
10041
10212
  }
10042
10213
  function ScreenShareIcon(props) {
10043
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10214
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10044
10215
  /* @__PURE__ */ jsx4("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
10045
10216
  /* @__PURE__ */ jsx4("path", { d: "M8 21h8M12 17v4" }),
10046
10217
  /* @__PURE__ */ jsx4("path", { d: "M12 13V8m0 0-2.5 2.5M12 8l2.5 2.5" })
@@ -10053,7 +10224,7 @@ function PhoneOffIcon(props) {
10053
10224
  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" }) });
10054
10225
  }
10055
10226
  function HandIcon(props) {
10056
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10227
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10057
10228
  /* @__PURE__ */ jsx4("path", { d: "M18 11V6a2 2 0 0 0-4 0v5" }),
10058
10229
  /* @__PURE__ */ jsx4("path", { d: "M14 10V4a2 2 0 0 0-4 0v7" }),
10059
10230
  /* @__PURE__ */ jsx4("path", { d: "M10 10.5V6a2 2 0 0 0-4 0v8" }),
@@ -10064,7 +10235,7 @@ function ChatIcon(props) {
10064
10235
  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" }) });
10065
10236
  }
10066
10237
  function PeopleIcon(props) {
10067
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10238
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10068
10239
  /* @__PURE__ */ jsx4("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
10069
10240
  /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "7", r: "4" }),
10070
10241
  /* @__PURE__ */ jsx4("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" })
@@ -10074,31 +10245,31 @@ function RecordIcon(props) {
10074
10245
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "8", fill: "currentColor", stroke: "none" }) });
10075
10246
  }
10076
10247
  function SparklesIcon(props) {
10077
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10248
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10078
10249
  /* @__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" }),
10079
10250
  /* @__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" })
10080
10251
  ] });
10081
10252
  }
10082
10253
  function CaptionsIcon(props) {
10083
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10254
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10084
10255
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
10085
10256
  /* @__PURE__ */ jsx4("path", { d: "M10 10.5a2 2 0 1 0 0 3M16 10.5a2 2 0 1 0 0 3" })
10086
10257
  ] });
10087
10258
  }
10088
10259
  function NotesIcon(props) {
10089
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10260
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10090
10261
  /* @__PURE__ */ jsx4("path", { d: "M4 20l1-4L16.5 4.5a2.1 2.1 0 0 1 3 3L8 19l-4 1Z" }),
10091
10262
  /* @__PURE__ */ jsx4("path", { d: "M14 7l3 3" })
10092
10263
  ] });
10093
10264
  }
10094
10265
  function LockIcon(props) {
10095
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10266
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10096
10267
  /* @__PURE__ */ jsx4("rect", { x: "4", y: "10", width: "16", height: "11", rx: "2" }),
10097
10268
  /* @__PURE__ */ jsx4("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
10098
10269
  ] });
10099
10270
  }
10100
10271
  function SettingsIcon(props) {
10101
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10272
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10102
10273
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "3" }),
10103
10274
  /* @__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" })
10104
10275
  ] });
@@ -10110,13 +10281,13 @@ function CloseIcon(props) {
10110
10281
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" }) });
10111
10282
  }
10112
10283
  function PinIcon(props) {
10113
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10284
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10114
10285
  /* @__PURE__ */ jsx4("path", { d: "M12 17v5" }),
10115
10286
  /* @__PURE__ */ jsx4("path", { d: "M9 2h6l-1 6 3.5 3.5V14H6.5v-2.5L10 8 9 2Z" })
10116
10287
  ] });
10117
10288
  }
10118
10289
  function SmileIcon(props) {
10119
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10290
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10120
10291
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
10121
10292
  /* @__PURE__ */ jsx4("path", { d: "M8 14s1.5 2 4 2 4-2 4-2" }),
10122
10293
  /* @__PURE__ */ jsx4("line", { x1: "9", x2: "9.01", y1: "9", y2: "9" }),
@@ -10124,20 +10295,20 @@ function SmileIcon(props) {
10124
10295
  ] });
10125
10296
  }
10126
10297
  function MoreIcon(props) {
10127
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10298
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10128
10299
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "1" }),
10129
10300
  /* @__PURE__ */ jsx4("circle", { cx: "19", cy: "12", r: "1" }),
10130
10301
  /* @__PURE__ */ jsx4("circle", { cx: "5", cy: "12", r: "1" })
10131
10302
  ] });
10132
10303
  }
10133
10304
  function SearchIcon(props) {
10134
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10305
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10135
10306
  /* @__PURE__ */ jsx4("circle", { cx: "11", cy: "11", r: "8" }),
10136
10307
  /* @__PURE__ */ jsx4("path", { d: "m21 21-4.3-4.3" })
10137
10308
  ] });
10138
10309
  }
10139
10310
  function KeyboardIcon(props) {
10140
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10311
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10141
10312
  /* @__PURE__ */ jsx4("path", { d: "M10 8h.01M12 12h.01M14 8h.01M16 12h.01M18 8h.01M6 8h.01M7 16h10M8 12h.01" }),
10142
10313
  /* @__PURE__ */ jsx4("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" })
10143
10314
  ] });
@@ -10146,7 +10317,7 @@ function SpotlightIcon(props) {
10146
10317
  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" }) });
10147
10318
  }
10148
10319
  function SignalIcon({ bars, ...props }) {
10149
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10320
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10150
10321
  /* @__PURE__ */ jsx4("path", { d: "M4 20v-2", opacity: bars >= 1 ? 1 : 0.3 }),
10151
10322
  /* @__PURE__ */ jsx4("path", { d: "M10 20v-6", opacity: bars >= 2 ? 1 : 0.3 }),
10152
10323
  /* @__PURE__ */ jsx4("path", { d: "M16 20V9", opacity: bars >= 3 ? 1 : 0.3 }),
@@ -10154,14 +10325,14 @@ function SignalIcon({ bars, ...props }) {
10154
10325
  ] });
10155
10326
  }
10156
10327
  function SpeakerIcon(props) {
10157
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10328
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10158
10329
  /* @__PURE__ */ jsx4("path", { d: "M11 5 6 9H2v6h4l5 4V5Z" }),
10159
10330
  /* @__PURE__ */ jsx4("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" }),
10160
10331
  /* @__PURE__ */ jsx4("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" })
10161
10332
  ] });
10162
10333
  }
10163
10334
  function FlagIcon(props) {
10164
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10335
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10165
10336
  /* @__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" }),
10166
10337
  /* @__PURE__ */ jsx4("line", { x1: "4", x2: "4", y1: "22", y2: "15" })
10167
10338
  ] });
@@ -10170,35 +10341,35 @@ function PencilIcon(props) {
10170
10341
  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" }) });
10171
10342
  }
10172
10343
  function ActivitiesIcon(props) {
10173
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10344
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10174
10345
  /* @__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" }),
10175
10346
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
10176
10347
  /* @__PURE__ */ jsx4("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
10177
10348
  ] });
10178
10349
  }
10179
10350
  function PollIcon(props) {
10180
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10351
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10181
10352
  /* @__PURE__ */ jsx4("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
10182
10353
  /* @__PURE__ */ jsx4("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
10183
10354
  /* @__PURE__ */ jsx4("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
10184
10355
  ] });
10185
10356
  }
10186
10357
  function QuestionIcon(props) {
10187
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10358
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10188
10359
  /* @__PURE__ */ jsx4("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
10189
10360
  /* @__PURE__ */ jsx4("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
10190
10361
  /* @__PURE__ */ jsx4("path", { d: "M12 17h.01" })
10191
10362
  ] });
10192
10363
  }
10193
10364
  function WhiteboardIcon(props) {
10194
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10365
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10195
10366
  /* @__PURE__ */ jsx4("path", { d: "M2 3h20" }),
10196
10367
  /* @__PURE__ */ jsx4("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
10197
10368
  /* @__PURE__ */ jsx4("path", { d: "m7 21 5-5 5 5" })
10198
10369
  ] });
10199
10370
  }
10200
10371
  function BreakoutIcon(props) {
10201
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10372
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10202
10373
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
10203
10374
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
10204
10375
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
@@ -10208,29 +10379,32 @@ function UpvoteIcon(props) {
10208
10379
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
10209
10380
  }
10210
10381
  function EraserIcon(props) {
10211
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10382
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10212
10383
  /* @__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" }),
10213
10384
  /* @__PURE__ */ jsx4("path", { d: "M22 21H7" }),
10214
10385
  /* @__PURE__ */ jsx4("path", { d: "m5 11 9 9" })
10215
10386
  ] });
10216
10387
  }
10217
10388
  function HighlighterIcon(props) {
10218
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10389
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10219
10390
  /* @__PURE__ */ jsx4("path", { d: "m9 11-6 6v3h9l3-3" }),
10220
10391
  /* @__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" })
10221
10392
  ] });
10222
10393
  }
10223
10394
  function UndoIcon(props) {
10224
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
10395
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
10225
10396
  /* @__PURE__ */ jsx4("path", { d: "M9 14 4 9l5-5" }),
10226
10397
  /* @__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" })
10227
10398
  ] });
10228
10399
  }
10400
+ function ChevronUpIcon(props) {
10401
+ return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "m6 15 6-6 6 6" }) });
10402
+ }
10229
10403
 
10230
10404
  // src/skins/meet/collab.tsx
10231
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
10405
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
10232
10406
  function useNotice() {
10233
- const [notice, setNotice] = useState3(null);
10407
+ const [notice, setNotice] = useState4(null);
10234
10408
  useEffect5(() => {
10235
10409
  if (notice === null) return void 0;
10236
10410
  const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
@@ -10259,16 +10433,16 @@ function ActivitiesControl({
10259
10433
  active,
10260
10434
  onOpen
10261
10435
  }) {
10262
- const [open, setOpen] = useState3(false);
10436
+ const [open, setOpen] = useState4(false);
10263
10437
  const available = useAvailableActivities();
10264
10438
  const attention = useActivityAttention();
10265
10439
  if (available.length === 0) return null;
10266
- return /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
10267
- /* @__PURE__ */ jsxs2(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
10440
+ return /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
10441
+ /* @__PURE__ */ jsxs3(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
10268
10442
  /* @__PURE__ */ jsx5(ActivitiesIcon, {}),
10269
10443
  attention ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
10270
10444
  ] }),
10271
- 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(
10445
+ 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(
10272
10446
  MenuItem,
10273
10447
  {
10274
10448
  onSelect: () => {
@@ -10287,11 +10461,11 @@ function ActivitiesControl({
10287
10461
  }
10288
10462
  function PollComposer({ maxOptions, onDone }) {
10289
10463
  const { act } = useCollab();
10290
- const [question, setQuestion] = useState3("");
10291
- const [options, setOptions] = useState3(["", ""]);
10292
- const [multiple, setMultiple] = useState3(false);
10293
- const [anonymous, setAnonymous] = useState3(false);
10294
- const [busy, setBusy] = useState3(false);
10464
+ const [question, setQuestion] = useState4("");
10465
+ const [options, setOptions] = useState4(["", ""]);
10466
+ const [multiple, setMultiple] = useState4(false);
10467
+ const [anonymous, setAnonymous] = useState4(false);
10468
+ const [busy, setBusy] = useState4(false);
10295
10469
  const [notice, show] = useNotice();
10296
10470
  const filled = options.map((o) => o.trim()).filter(Boolean);
10297
10471
  const ready = question.trim().length > 0 && filled.length >= 2;
@@ -10314,7 +10488,7 @@ function PollComposer({ maxOptions, onDone }) {
10314
10488
  setBusy(false);
10315
10489
  onDone();
10316
10490
  };
10317
- return /* @__PURE__ */ jsxs2(
10491
+ return /* @__PURE__ */ jsxs3(
10318
10492
  "form",
10319
10493
  {
10320
10494
  className: "mx-meet__collab-card",
@@ -10323,7 +10497,7 @@ function PollComposer({ maxOptions, onDone }) {
10323
10497
  if (ready) void save(true);
10324
10498
  },
10325
10499
  children: [
10326
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
10500
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10327
10501
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Question" }),
10328
10502
  /* @__PURE__ */ jsx5(
10329
10503
  "input",
@@ -10337,7 +10511,7 @@ function PollComposer({ maxOptions, onDone }) {
10337
10511
  }
10338
10512
  )
10339
10513
  ] }),
10340
- options.map((option, index) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
10514
+ options.map((option, index) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
10341
10515
  /* @__PURE__ */ jsx5(
10342
10516
  "input",
10343
10517
  {
@@ -10352,16 +10526,16 @@ function PollComposer({ maxOptions, onDone }) {
10352
10526
  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
10353
10527
  ] }, index)),
10354
10528
  options.length < maxOptions ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
10355
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
10529
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
10356
10530
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
10357
10531
  "People can pick more than one"
10358
10532
  ] }),
10359
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
10533
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
10360
10534
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
10361
10535
  "Anonymous \u2014 nobody sees who picked what"
10362
10536
  ] }),
10363
10537
  /* @__PURE__ */ jsx5(Notice, { notice }),
10364
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
10538
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
10365
10539
  /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
10366
10540
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
10367
10541
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
@@ -10372,7 +10546,7 @@ function PollComposer({ maxOptions, onDone }) {
10372
10546
  }
10373
10547
  function PollCard({ poll }) {
10374
10548
  const { act, isHost } = useCollab();
10375
- const [picked, setPicked] = useState3(poll.myVote.slice());
10549
+ const [picked, setPicked] = useState4(poll.myVote.slice());
10376
10550
  const [notice, show] = useNotice();
10377
10551
  useEffect5(() => setPicked(poll.myVote.slice()), [poll.myVote]);
10378
10552
  const counts = poll.options.some((o) => o.votes !== void 0);
@@ -10384,12 +10558,12 @@ function PollCard({ poll }) {
10384
10558
  if (!canVote) return;
10385
10559
  setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
10386
10560
  };
10387
- return /* @__PURE__ */ jsxs2("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
10388
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__collab-head", children: [
10561
+ return /* @__PURE__ */ jsxs3("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
10562
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__collab-head", children: [
10389
10563
  /* @__PURE__ */ jsx5("strong", { className: "mx-meet__collab-title", children: poll.question }),
10390
10564
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: stateWord })
10391
10565
  ] }),
10392
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
10566
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
10393
10567
  poll.multiple ? "Pick any." : "Pick one.",
10394
10568
  poll.anonymous ? " Anonymous." : "",
10395
10569
  counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
@@ -10398,8 +10572,8 @@ function PollCard({ poll }) {
10398
10572
  /* @__PURE__ */ jsx5("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
10399
10573
  const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
10400
10574
  const chosen = picked.includes(option.id);
10401
- return /* @__PURE__ */ jsxs2("li", { children: [
10402
- /* @__PURE__ */ jsxs2(
10575
+ return /* @__PURE__ */ jsxs3("li", { children: [
10576
+ /* @__PURE__ */ jsxs3(
10403
10577
  "button",
10404
10578
  {
10405
10579
  type: "button",
@@ -10410,7 +10584,7 @@ function PollCard({ poll }) {
10410
10584
  children: [
10411
10585
  counts ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
10412
10586
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__poll-text", children: option.text }),
10413
- counts ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__poll-count", children: [
10587
+ counts ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__poll-count", children: [
10414
10588
  option.votes ?? 0,
10415
10589
  " \xB7 ",
10416
10590
  share,
@@ -10423,7 +10597,7 @@ function PollCard({ poll }) {
10423
10597
  ] }, option.id);
10424
10598
  }) }),
10425
10599
  /* @__PURE__ */ jsx5(Notice, { notice }),
10426
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
10600
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
10427
10601
  canVote ? /* @__PURE__ */ jsx5(
10428
10602
  "button",
10429
10603
  {
@@ -10443,11 +10617,11 @@ function PollCard({ poll }) {
10443
10617
  }
10444
10618
  function PollsPanel({ onClose }) {
10445
10619
  const { collab, isHost } = useCollab();
10446
- const [composing, setComposing] = useState3(false);
10620
+ const [composing, setComposing] = useState4(false);
10447
10621
  const polls = collab?.polls ?? [];
10448
10622
  const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
10449
10623
  const ordered = [...polls].reverse();
10450
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Polls", onClose, children: [
10624
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Polls", onClose, children: [
10451
10625
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
10452
10626
  isHost && !composing ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
10453
10627
  isHost && composing ? /* @__PURE__ */ jsx5(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
@@ -10457,12 +10631,12 @@ function PollsPanel({ onClose }) {
10457
10631
  }
10458
10632
  function QuestionCard({ question }) {
10459
10633
  const { act, isHost } = useCollab();
10460
- const [answering, setAnswering] = useState3(false);
10461
- const [reply, setReply] = useState3("");
10634
+ const [answering, setAnswering] = useState4(false);
10635
+ const [reply, setReply] = useState4("");
10462
10636
  const [notice, show] = useNotice();
10463
- return /* @__PURE__ */ jsxs2("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
10464
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-row", children: [
10465
- /* @__PURE__ */ jsxs2(
10637
+ return /* @__PURE__ */ jsxs3("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
10638
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__question-row", children: [
10639
+ /* @__PURE__ */ jsxs3(
10466
10640
  "button",
10467
10641
  {
10468
10642
  type: "button",
@@ -10477,15 +10651,15 @@ function QuestionCard({ question }) {
10477
10651
  ]
10478
10652
  }
10479
10653
  ),
10480
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-body", children: [
10481
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
10654
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__question-body", children: [
10655
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
10482
10656
  /* @__PURE__ */ jsx5("strong", { children: question.mine ? "You" : question.askerName }),
10483
10657
  question.mine && question.anonymous ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
10484
10658
  question.state !== "open" ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
10485
10659
  ] }),
10486
10660
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__chat-text", children: question.text }),
10487
- question.answer !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__question-answer", children: [
10488
- /* @__PURE__ */ jsxs2("strong", { children: [
10661
+ question.answer !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__question-answer", children: [
10662
+ /* @__PURE__ */ jsxs3("strong", { children: [
10489
10663
  question.answeredByName ?? "Host",
10490
10664
  ":"
10491
10665
  ] }),
@@ -10494,7 +10668,7 @@ function QuestionCard({ question }) {
10494
10668
  ] }) : null
10495
10669
  ] })
10496
10670
  ] }),
10497
- answering ? /* @__PURE__ */ jsxs2(
10671
+ answering ? /* @__PURE__ */ jsxs3(
10498
10672
  "form",
10499
10673
  {
10500
10674
  className: "mx-meet__composer-row",
@@ -10526,7 +10700,7 @@ function QuestionCard({ question }) {
10526
10700
  }
10527
10701
  ) : null,
10528
10702
  /* @__PURE__ */ jsx5(Notice, { notice }),
10529
- isHost || question.mine ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
10703
+ isHost || question.mine ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
10530
10704
  isHost && question.state === "open" && !answering ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
10531
10705
  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,
10532
10706
  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,
@@ -10536,9 +10710,9 @@ function QuestionCard({ question }) {
10536
10710
  }
10537
10711
  function QaPanel({ onClose }) {
10538
10712
  const { collab, act } = useCollab();
10539
- const [draft, setDraft] = useState3("");
10540
- const [anonymous, setAnonymous] = useState3(false);
10541
- const [order, setOrder] = useState3("popular");
10713
+ const [draft, setDraft] = useState4("");
10714
+ const [anonymous, setAnonymous] = useState4(false);
10715
+ const [order, setOrder] = useState4("popular");
10542
10716
  const [notice, show] = useNotice();
10543
10717
  const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
10544
10718
  const questions = [...collab?.questions ?? []];
@@ -10546,9 +10720,9 @@ function QaPanel({ onClose }) {
10546
10720
  questions.sort(
10547
10721
  (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 ?? "")
10548
10722
  );
10549
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Q&A", onClose, children: [
10723
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Q&A", onClose, children: [
10550
10724
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
10551
- /* @__PURE__ */ jsxs2(
10725
+ /* @__PURE__ */ jsxs3(
10552
10726
  "form",
10553
10727
  {
10554
10728
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -10562,7 +10736,7 @@ function QaPanel({ onClose }) {
10562
10736
  });
10563
10737
  },
10564
10738
  children: [
10565
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
10739
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
10566
10740
  /* @__PURE__ */ jsx5(
10567
10741
  "input",
10568
10742
  {
@@ -10576,7 +10750,7 @@ function QaPanel({ onClose }) {
10576
10750
  ),
10577
10751
  /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
10578
10752
  ] }),
10579
- allowAnonymous ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
10753
+ allowAnonymous ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
10580
10754
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
10581
10755
  "Ask anonymously"
10582
10756
  ] }) : null
@@ -10627,10 +10801,10 @@ function StrokeView({ stroke, onPick }) {
10627
10801
  }
10628
10802
  function WhiteboardPanel({ onClose }) {
10629
10803
  const { collab, act, isHost, localIdentity } = useCollab();
10630
- const [tool, setTool] = useState3("pen");
10631
- const [color, setColor] = useState3(INK[0]);
10632
- const [drawing, setDrawing] = useState3(null);
10633
- const [pending, setPending] = useState3([]);
10804
+ const [tool, setTool] = useState4("pen");
10805
+ const [color, setColor] = useState4(INK[0]);
10806
+ const [drawing, setDrawing] = useState4(null);
10807
+ const [pending, setPending] = useState4([]);
10634
10808
  const [notice, show] = useNotice();
10635
10809
  const svgRef = useRef5(null);
10636
10810
  const strokes = collab?.strokes ?? [];
@@ -10664,8 +10838,8 @@ function WhiteboardPanel({ onClose }) {
10664
10838
  if (!result.ok) show(result);
10665
10839
  });
10666
10840
  };
10667
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
10668
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__whiteboard-bar", children: [
10841
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
10842
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__whiteboard-bar", children: [
10669
10843
  /* @__PURE__ */ jsx5("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
10670
10844
  /* @__PURE__ */ jsx5("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
10671
10845
  ["pen", "Pen", /* @__PURE__ */ jsx5(PencilIcon, { width: 16, height: 16 }, "p")],
@@ -10715,7 +10889,7 @@ function WhiteboardPanel({ onClose }) {
10715
10889
  /* @__PURE__ */ jsx5(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ jsx5(CloseIcon, { width: 16, height: 16 }) })
10716
10890
  ] }),
10717
10891
  /* @__PURE__ */ jsx5(Notice, { notice }),
10718
- /* @__PURE__ */ jsxs2(
10892
+ /* @__PURE__ */ jsxs3(
10719
10893
  "svg",
10720
10894
  {
10721
10895
  ref: svgRef,
@@ -10773,7 +10947,7 @@ function clock(ms2) {
10773
10947
  }
10774
10948
  var BREAKOUT_EXPIRE_RETRY_MS = 5e3;
10775
10949
  function useNow(active) {
10776
- const [now, setNow] = useState3(() => Date.now());
10950
+ const [now, setNow] = useState4(() => Date.now());
10777
10951
  useEffect5(() => {
10778
10952
  if (!active) return void 0;
10779
10953
  const timer = setInterval(() => setNow(Date.now()), 1e3);
@@ -10788,11 +10962,11 @@ function BreakoutSetup() {
10788
10962
  const people = (snapshot?.participants ?? []).filter(
10789
10963
  (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
10790
10964
  );
10791
- const [count2, setCount] = useState3(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
10792
- const [mode, setMode] = useState3("auto");
10793
- const [minutes, setMinutes] = useState3(settings?.breakoutDefaultMinutes ?? 15);
10794
- const [manual, setManual] = useState3({});
10795
- const [busy, setBusy] = useState3(false);
10965
+ const [count2, setCount] = useState4(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
10966
+ const [mode, setMode] = useState4("auto");
10967
+ const [minutes, setMinutes] = useState4(settings?.breakoutDefaultMinutes ?? 15);
10968
+ const [manual, setManual] = useState4({});
10969
+ const [busy, setBusy] = useState4(false);
10796
10970
  const [notice, show] = useNotice();
10797
10971
  const max = settings?.breakoutMaxRooms ?? 20;
10798
10972
  const rooms = Math.min(Math.max(1, count2), max);
@@ -10804,8 +10978,8 @@ function BreakoutSetup() {
10804
10978
  (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
10805
10979
  ) : Array.from({ length: rooms }, () => []);
10806
10980
  const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
10807
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
10808
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
10981
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-card", children: [
10982
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10809
10983
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Rooms" }),
10810
10984
  /* @__PURE__ */ jsx5(
10811
10985
  "input",
@@ -10834,7 +11008,7 @@ function BreakoutSetup() {
10834
11008
  },
10835
11009
  value
10836
11010
  )) }),
10837
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
11011
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10838
11012
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
10839
11013
  /* @__PURE__ */ jsx5(
10840
11014
  "input",
@@ -10848,9 +11022,9 @@ function BreakoutSetup() {
10848
11022
  }
10849
11023
  )
10850
11024
  ] }),
10851
- 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: [
11025
+ 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: [
10852
11026
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__person-name", children: person.displayName }),
10853
- /* @__PURE__ */ jsxs2(
11027
+ /* @__PURE__ */ jsxs3(
10854
11028
  "select",
10855
11029
  {
10856
11030
  className: "mx-meet__select mx-meet__select--compact",
@@ -10859,15 +11033,15 @@ function BreakoutSetup() {
10859
11033
  onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
10860
11034
  children: [
10861
11035
  /* @__PURE__ */ jsx5("option", { value: -1, children: "Main room" }),
10862
- Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs2("option", { value: index, children: [
11036
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs3("option", { value: index, children: [
10863
11037
  "Room ",
10864
11038
  index + 1
10865
11039
  ] }, index))
10866
11040
  ]
10867
11041
  }
10868
11042
  )
10869
- ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs2("li", { children: [
10870
- /* @__PURE__ */ jsxs2("strong", { children: [
11043
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs3("li", { children: [
11044
+ /* @__PURE__ */ jsxs3("strong", { children: [
10871
11045
  "Room ",
10872
11046
  index + 1
10873
11047
  ] }),
@@ -10875,7 +11049,7 @@ function BreakoutSetup() {
10875
11049
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
10876
11050
  ] }, index)) }) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
10877
11051
  /* @__PURE__ */ jsx5(Notice, { notice }),
10878
- /* @__PURE__ */ jsxs2(
11052
+ /* @__PURE__ */ jsxs3(
10879
11053
  "button",
10880
11054
  {
10881
11055
  type: "button",
@@ -10908,7 +11082,7 @@ function BreakoutRun({ plan }) {
10908
11082
  const snapshot = useMeetSnapshot();
10909
11083
  const now = useNow(plan.endsAt !== null);
10910
11084
  const remaining = breakoutRemainingMs(plan, now);
10911
- const [broadcast, setBroadcast] = useState3("");
11085
+ const [broadcast, setBroadcast] = useState4("");
10912
11086
  const [notice, show] = useNotice();
10913
11087
  const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
10914
11088
  const mine = assignedRoom(plan, localIdentity);
@@ -10920,8 +11094,8 @@ function BreakoutRun({ plan }) {
10920
11094
  }
10921
11095
  show(await moveTo(roomId));
10922
11096
  };
10923
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
10924
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
11097
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-card", children: [
11098
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
10925
11099
  plan.rooms.length,
10926
11100
  " room",
10927
11101
  plan.rooms.length === 1 ? "" : "s",
@@ -10932,15 +11106,15 @@ function BreakoutRun({ plan }) {
10932
11106
  /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
10933
11107
  const here = breakoutRoomId === room.id;
10934
11108
  const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
10935
- return /* @__PURE__ */ jsxs2("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
10936
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-head", children: [
11109
+ return /* @__PURE__ */ jsxs3("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
11110
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-head", children: [
10937
11111
  /* @__PURE__ */ jsx5("strong", { children: room.name }),
10938
11112
  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
10939
11113
  ] }),
10940
11114
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
10941
- 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: [
11115
+ 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: [
10942
11116
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
10943
- /* @__PURE__ */ jsxs2(
11117
+ /* @__PURE__ */ jsxs3(
10944
11118
  "select",
10945
11119
  {
10946
11120
  className: "mx-meet__select mx-meet__select--compact",
@@ -10961,7 +11135,7 @@ function BreakoutRun({ plan }) {
10961
11135
  ] }, room.id);
10962
11136
  }) }),
10963
11137
  breakoutRoomId !== null ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
10964
- isHost ? /* @__PURE__ */ jsxs2(
11138
+ isHost ? /* @__PURE__ */ jsxs3(
10965
11139
  "form",
10966
11140
  {
10967
11141
  className: "mx-meet__composer-row",
@@ -11005,7 +11179,7 @@ function BreakoutRun({ plan }) {
11005
11179
  function BreakoutsPanel({ onClose }) {
11006
11180
  const { collab, isHost } = useCollab();
11007
11181
  const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
11008
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Breakout rooms", onClose, children: [
11182
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Breakout rooms", onClose, children: [
11009
11183
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
11010
11184
  plan !== null ? /* @__PURE__ */ jsx5(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ jsx5(BreakoutSetup, {}) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
11011
11185
  ] });
@@ -11019,12 +11193,12 @@ function BreakoutBanner() {
11019
11193
  const remaining = breakoutRemainingMs(open, now);
11020
11194
  const closing = breakoutClosingMs(open, now);
11021
11195
  const assigned = assignedRoom(open, localIdentity);
11022
- const [later, setLater] = useState3(null);
11023
- const [autoSince, setAutoSince] = useState3(null);
11196
+ const [later, setLater] = useState4(null);
11197
+ const [autoSince, setAutoSince] = useState4(null);
11024
11198
  const AUTO_MOVE_MS = 1e4;
11025
11199
  const autoLeft = open?.moveMode === "auto" && assigned !== null && autoSince?.id === open.id && later !== open.id ? Math.max(0, AUTO_MOVE_MS - (now - autoSince.at)) : null;
11026
- const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
11027
- const [failure, setFailure] = useState3(null);
11200
+ const [dismissedBroadcast, setDismissedBroadcast] = useState4(null);
11201
+ const [failure, setFailure] = useState4(null);
11028
11202
  const expireAsked = useRef5(null);
11029
11203
  const moveAt = collab?.moveRequest?.at ?? null;
11030
11204
  useEffect5(() => {
@@ -11059,29 +11233,29 @@ function BreakoutBanner() {
11059
11233
  const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
11060
11234
  const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
11061
11235
  if (open === null && failure === null) return null;
11062
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__breakout-banner", role: "status", children: [
11236
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__breakout-banner", role: "status", children: [
11063
11237
  failure !== null ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-error", children: failure }) : null,
11064
- closing !== null ? /* @__PURE__ */ jsxs2("span", { role: "status", "data-meet-notice": "breakout-closing", children: [
11238
+ closing !== null ? /* @__PURE__ */ jsxs3("span", { role: "status", "data-meet-notice": "breakout-closing", children: [
11065
11239
  "Rooms closing in ",
11066
11240
  Math.ceil(closing / 1e3),
11067
11241
  room !== null ? " \u2014 you return to the main meeting" : ""
11068
11242
  ] }) : null,
11069
- room !== null ? /* @__PURE__ */ jsxs2("span", { children: [
11243
+ room !== null ? /* @__PURE__ */ jsxs3("span", { children: [
11070
11244
  /* @__PURE__ */ jsx5("strong", { children: room.name }),
11071
11245
  remaining !== null && closing === null ? ` \xB7 ${clock(remaining)} left` : "",
11072
11246
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
11073
- ] }) : assigned !== null && later !== open?.id ? /* @__PURE__ */ jsxs2("span", { children: [
11247
+ ] }) : assigned !== null && later !== open?.id ? /* @__PURE__ */ jsxs3("span", { children: [
11074
11248
  autoLeft !== null ? `You're being moved to ${assigned.name} in ${Math.ceil(autoLeft / 1e3)} s` : `You're invited to ${assigned.name}`,
11075
11249
  remaining !== null && closing === null ? ` \xB7 ${clock(remaining)} left` : "",
11076
11250
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void joinAssigned(), children: "Join room" }),
11077
11251
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => setLater(open?.id ?? null), children: "Later" })
11078
- ] }) : assigned !== null ? /* @__PURE__ */ jsxs2("span", { children: [
11252
+ ] }) : assigned !== null ? /* @__PURE__ */ jsxs3("span", { children: [
11079
11253
  assigned.name,
11080
11254
  " is open",
11081
11255
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void joinAssigned(), children: "Join room" })
11082
11256
  ] }) : open?.allowChoose ? /* @__PURE__ */ jsx5("span", { children: "Rooms are open \u2014 pick one under Activities." }) : null,
11083
- showBroadcast ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__breakout-broadcast", children: [
11084
- /* @__PURE__ */ jsxs2("strong", { children: [
11257
+ showBroadcast ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__breakout-broadcast", children: [
11258
+ /* @__PURE__ */ jsxs3("strong", { children: [
11085
11259
  broadcast.by,
11086
11260
  ":"
11087
11261
  ] }),
@@ -11101,10 +11275,10 @@ function CaptionLanguageSettings() {
11101
11275
  const preferred = defaultCaptionLanguage(settings, viewer);
11102
11276
  const current = collab?.captionLanguage ?? "";
11103
11277
  const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
11104
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
11105
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
11278
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
11279
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
11106
11280
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
11107
- /* @__PURE__ */ jsxs2(
11281
+ /* @__PURE__ */ jsxs3(
11108
11282
  "select",
11109
11283
  {
11110
11284
  className: "mx-meet__select",
@@ -11115,7 +11289,7 @@ function CaptionLanguageSettings() {
11115
11289
  },
11116
11290
  children: [
11117
11291
  /* @__PURE__ */ jsx5("option", { value: "", children: "Off \u2014 as spoken" }),
11118
- current === "" ? /* @__PURE__ */ jsxs2("option", { value: preferred, children: [
11292
+ current === "" ? /* @__PURE__ */ jsxs3("option", { value: preferred, children: [
11119
11293
  choices.find((c) => c.tag === preferred)?.name ?? preferred,
11120
11294
  " (yours)"
11121
11295
  ] }) : null,
@@ -11156,10 +11330,10 @@ function TakeNotesControl() {
11156
11330
  }
11157
11331
 
11158
11332
  // src/skins/meet/components.tsx
11159
- import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
11333
+ import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
11160
11334
  function InertNotice({ what }) {
11161
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
11162
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-title", children: [
11335
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__empty", role: "status", children: [
11336
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__empty-title", children: [
11163
11337
  what,
11164
11338
  " is not ready yet"
11165
11339
  ] }),
@@ -11229,7 +11403,7 @@ function RecordingIndicator() {
11229
11403
  const { state, label, canStart } = useRecording();
11230
11404
  const snapshot = useMeetSnapshot();
11231
11405
  const previous = useRef6(state);
11232
- const [stoppedAt, setStoppedAt] = useState4(null);
11406
+ const [stoppedAt, setStoppedAt] = useState5(null);
11233
11407
  useEffect6(() => {
11234
11408
  const was = previous.current;
11235
11409
  previous.current = state;
@@ -11242,8 +11416,8 @@ function RecordingIndicator() {
11242
11416
  }, [state]);
11243
11417
  const meetingId = snapshot?.meeting?.id ?? null;
11244
11418
  if (label === null && stoppedAt === null) return null;
11245
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
11246
- label !== null ? /* @__PURE__ */ jsxs3(
11419
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
11420
+ label !== null ? /* @__PURE__ */ jsxs4(
11247
11421
  "span",
11248
11422
  {
11249
11423
  className: `mx-meet__recording mx-meet__recording--${state}`,
@@ -11280,7 +11454,7 @@ function ParticipantTile({
11280
11454
  const host = useMeetHost();
11281
11455
  const snapshot = useMeetSnapshot();
11282
11456
  const queue = useHandQueue();
11283
- const [menu, setMenu] = useState4(false);
11457
+ const [menu, setMenu] = useState5(false);
11284
11458
  const videoRef = useTrack(
11285
11459
  participant.identity,
11286
11460
  participant.screenSharing ? "screen" : "camera"
@@ -11290,7 +11464,7 @@ function ParticipantTile({
11290
11464
  const spotlit = snapshot?.spotlight === participant.identity;
11291
11465
  const presenting = snapshot?.presenter === participant.identity;
11292
11466
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
11293
- return /* @__PURE__ */ jsxs3(
11467
+ return /* @__PURE__ */ jsxs4(
11294
11468
  "div",
11295
11469
  {
11296
11470
  className: [
@@ -11313,12 +11487,12 @@ function ParticipantTile({
11313
11487
  }
11314
11488
  ) : /* @__PURE__ */ jsx6("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
11315
11489
  presenting ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__tile-presenting", role: "status", children: participant.isLocal ? "You are presenting" : `${participant.displayName} is presenting` }) : null,
11316
- participant.handRaised ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
11490
+ participant.handRaised ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
11317
11491
  /* @__PURE__ */ jsx6(HandIcon, { width: 14, height: 14 }),
11318
11492
  handPosition > 0 ? handPosition : null
11319
11493
  ] }) : null,
11320
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__tile-bar", children: [
11321
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-name", children: [
11494
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__tile-bar", children: [
11495
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__tile-name", children: [
11322
11496
  spotlit ? /* @__PURE__ */ jsx6("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx6(SpotlightIcon, { width: 12, height: 12 }) }) : null,
11323
11497
  participant.displayName,
11324
11498
  participant.isLocal ? " (you)" : "",
@@ -11329,7 +11503,7 @@ function ParticipantTile({
11329
11503
  !participant.micEnabled ? /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }) : null,
11330
11504
  /* @__PURE__ */ jsx6(QualityBars, { quality: participant.quality })
11331
11505
  ] }),
11332
- /* @__PURE__ */ jsxs3("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
11506
+ /* @__PURE__ */ jsxs4("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
11333
11507
  /* @__PURE__ */ jsx6(
11334
11508
  ControlButton,
11335
11509
  {
@@ -11339,7 +11513,7 @@ function ParticipantTile({
11339
11513
  children: /* @__PURE__ */ jsx6(PinIcon, { width: 16, height: 16 })
11340
11514
  }
11341
11515
  ),
11342
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
11516
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
11343
11517
  /* @__PURE__ */ jsx6(
11344
11518
  ControlButton,
11345
11519
  {
@@ -11377,12 +11551,12 @@ function Stage({ pageSize }) {
11377
11551
  const stage = useStage(pageSize);
11378
11552
  const columns = gridColumns(stage.tiles.length);
11379
11553
  if (stage.feature === null && stage.tiles.length === 0) {
11380
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
11554
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
11381
11555
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
11382
11556
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
11383
11557
  ] });
11384
11558
  }
11385
- return /* @__PURE__ */ jsxs3("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
11559
+ return /* @__PURE__ */ jsxs4("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
11386
11560
  stage.feature !== null ? /* @__PURE__ */ jsx6(ParticipantTile, { participant: stage.feature, featured: true }) : null,
11387
11561
  /* @__PURE__ */ jsx6(
11388
11562
  "div",
@@ -11392,7 +11566,7 @@ function Stage({ pageSize }) {
11392
11566
  children: stage.tiles.map((participant) => /* @__PURE__ */ jsx6(ParticipantTile, { participant }, participant.identity))
11393
11567
  }
11394
11568
  ),
11395
- stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
11569
+ stage.overflow > 0 ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__overflow", children: [
11396
11570
  "+",
11397
11571
  stage.overflow,
11398
11572
  " more ",
@@ -11404,10 +11578,10 @@ function Stage({ pageSize }) {
11404
11578
  function ControlBar({ onLeave }) {
11405
11579
  const room = useRoom();
11406
11580
  const recording = useRecording();
11407
- const [panel, setPanel] = useState4("none");
11408
- const [chatTo, setChatTo] = useState4(null);
11409
- const [popover, setPopover] = useState4("none");
11410
- const [shortcuts, setShortcuts] = useState4(false);
11581
+ const [panel, setPanel] = useState5("none");
11582
+ const [chatTo, setChatTo] = useState5(null);
11583
+ const [popover, setPopover] = useState5("none");
11584
+ const [shortcuts, setShortcuts] = useState5(false);
11411
11585
  const snapshot = useMeetSnapshot();
11412
11586
  const lobby = useLobby();
11413
11587
  const controls = useHostControls();
@@ -11415,7 +11589,7 @@ function ControlBar({ onLeave }) {
11415
11589
  const micUnavailable = useLocalMedia().microphone.unavailable;
11416
11590
  const live = useLivePolicy();
11417
11591
  const unread = useUnreadChat(panel === "chat");
11418
- const [whiteboard, setWhiteboard] = useState4(false);
11592
+ const [whiteboard, setWhiteboard] = useState5(false);
11419
11593
  const app = useMeetAppPanel();
11420
11594
  const appOpened = useRef6(false);
11421
11595
  useEffect6(() => {
@@ -11449,7 +11623,7 @@ function ControlBar({ onLeave }) {
11449
11623
  help: () => setShortcuts(true)
11450
11624
  });
11451
11625
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
11452
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
11626
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
11453
11627
  /* @__PURE__ */ jsx6(MeetingOverlays, {}),
11454
11628
  shortcuts ? /* @__PURE__ */ jsx6(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
11455
11629
  panel === "chat" ? /* @__PURE__ */ jsx6(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
@@ -11479,8 +11653,9 @@ function ControlBar({ onLeave }) {
11479
11653
  ) }) }) : null,
11480
11654
  /* @__PURE__ */ jsx6(BreakoutBanner, {}),
11481
11655
  panel !== "people" ? /* @__PURE__ */ jsx6(KnockNotice, { onView: () => setPanel("people") }) : null,
11656
+ /* @__PURE__ */ jsx6(SpeakingWhileMutedNudge, {}),
11482
11657
  controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx6(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
11483
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__controls", children: [
11658
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__controls", children: [
11484
11659
  live.micLocked ? null : /* @__PURE__ */ jsx6(
11485
11660
  ControlButton,
11486
11661
  {
@@ -11490,6 +11665,7 @@ function ControlBar({ onLeave }) {
11490
11665
  children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx6(MicIcon, {}) : /* @__PURE__ */ jsx6(MicOffIcon, {})
11491
11666
  }
11492
11667
  ),
11668
+ /* @__PURE__ */ jsx6(AudioSettingsControl, {}),
11493
11669
  live.cameraLocked ? null : /* @__PURE__ */ jsx6(
11494
11670
  ControlButton,
11495
11671
  {
@@ -11509,7 +11685,7 @@ function ControlBar({ onLeave }) {
11509
11685
  children: /* @__PURE__ */ jsx6(ScreenShareIcon, {})
11510
11686
  }
11511
11687
  ) : null,
11512
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
11688
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
11513
11689
  /* @__PURE__ */ jsx6(
11514
11690
  ControlButton,
11515
11691
  {
@@ -11541,11 +11717,11 @@ function ControlBar({ onLeave }) {
11541
11717
  }
11542
11718
  ),
11543
11719
  app !== null ? /* @__PURE__ */ jsx6(ControlButton, { label: app.title, active: panel === "app", onClick: () => toggle("app"), children: /* @__PURE__ */ jsx6(FlagIcon, {}) }) : null,
11544
- /* @__PURE__ */ jsxs3(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
11720
+ /* @__PURE__ */ jsxs4(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
11545
11721
  /* @__PURE__ */ jsx6(ChatIcon, {}),
11546
11722
  unread > 0 ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
11547
11723
  ] }),
11548
- /* @__PURE__ */ jsxs3(
11724
+ /* @__PURE__ */ jsxs4(
11549
11725
  ControlButton,
11550
11726
  {
11551
11727
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
@@ -11568,7 +11744,7 @@ function ControlBar({ onLeave }) {
11568
11744
  /* @__PURE__ */ jsx6(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
11569
11745
  recording.canStart ? /* @__PURE__ */ jsx6(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx6(RecordIcon, {}) }) : null,
11570
11746
  recording.canStop ? /* @__PURE__ */ jsx6(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx6(RecordIcon, {}) }) : null,
11571
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
11747
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
11572
11748
  /* @__PURE__ */ jsx6(
11573
11749
  ControlButton,
11574
11750
  {
@@ -11578,8 +11754,8 @@ function ControlBar({ onLeave }) {
11578
11754
  children: /* @__PURE__ */ jsx6(MoreIcon, {})
11579
11755
  }
11580
11756
  ),
11581
- popover === "more" ? /* @__PURE__ */ jsx6(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
11582
- /* @__PURE__ */ jsxs3(
11757
+ popover === "more" ? /* @__PURE__ */ jsx6(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", role: "menu", children: [
11758
+ /* @__PURE__ */ jsxs4(
11583
11759
  MenuItem,
11584
11760
  {
11585
11761
  onSelect: () => {
@@ -11592,7 +11768,7 @@ function ControlBar({ onLeave }) {
11592
11768
  ]
11593
11769
  }
11594
11770
  ),
11595
- /* @__PURE__ */ jsxs3(
11771
+ /* @__PURE__ */ jsxs4(
11596
11772
  MenuItem,
11597
11773
  {
11598
11774
  onSelect: () => {
@@ -11605,9 +11781,16 @@ function ControlBar({ onLeave }) {
11605
11781
  ]
11606
11782
  }
11607
11783
  ),
11608
- controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
11784
+ !room.canShareScreen && room.local?.screenSharing !== true ? (
11785
+ // `share-unsupported-mobile`: the control is absent; the menu says where it lives.
11786
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__menu-note", role: "note", "data-meet-notice": "share-unsupported", children: [
11787
+ /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
11788
+ " Present from a computer"
11789
+ ] })
11790
+ ) : null,
11791
+ controls.isHost ? /* @__PURE__ */ jsxs4(Fragment, { children: [
11609
11792
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu-sep", role: "separator" }),
11610
- /* @__PURE__ */ jsxs3(
11793
+ /* @__PURE__ */ jsxs4(
11611
11794
  MenuItem,
11612
11795
  {
11613
11796
  onSelect: () => {
@@ -11620,7 +11803,7 @@ function ControlBar({ onLeave }) {
11620
11803
  ]
11621
11804
  }
11622
11805
  ),
11623
- /* @__PURE__ */ jsxs3(
11806
+ /* @__PURE__ */ jsxs4(
11624
11807
  MenuItem,
11625
11808
  {
11626
11809
  onSelect: () => {
@@ -11637,7 +11820,7 @@ function ControlBar({ onLeave }) {
11637
11820
  ]
11638
11821
  }
11639
11822
  ),
11640
- /* @__PURE__ */ jsxs3(
11823
+ /* @__PURE__ */ jsxs4(
11641
11824
  MenuItem,
11642
11825
  {
11643
11826
  onSelect: () => {
@@ -11650,7 +11833,7 @@ function ControlBar({ onLeave }) {
11650
11833
  ]
11651
11834
  }
11652
11835
  ),
11653
- queue.length > 0 ? /* @__PURE__ */ jsxs3(
11836
+ queue.length > 0 ? /* @__PURE__ */ jsxs4(
11654
11837
  MenuItem,
11655
11838
  {
11656
11839
  onSelect: () => {
@@ -11665,7 +11848,7 @@ function ControlBar({ onLeave }) {
11665
11848
  ]
11666
11849
  }
11667
11850
  ) : null,
11668
- hasSpotlight ? /* @__PURE__ */ jsxs3(
11851
+ hasSpotlight ? /* @__PURE__ */ jsxs4(
11669
11852
  MenuItem,
11670
11853
  {
11671
11854
  onSelect: () => {
@@ -11692,8 +11875,8 @@ var LEAVE_WORDS = {
11692
11875
  };
11693
11876
  function LeaveControl({ onLeave }) {
11694
11877
  const leave = useLeave();
11695
- const [open, setOpen] = useState4("none");
11696
- const [failure, setFailure] = useState4(null);
11878
+ const [open, setOpen] = useState5("none");
11879
+ const [failure, setFailure] = useState5(null);
11697
11880
  const words = LEAVE_WORDS[leave.policy.hostLeavePrompt];
11698
11881
  const run = (work, leaving) => {
11699
11882
  setFailure(null);
@@ -11704,7 +11887,7 @@ function LeaveControl({ onLeave }) {
11704
11887
  };
11705
11888
  const leaveNow = () => run(leave.leave, true);
11706
11889
  const endNow = () => run(leave.endForAll, false);
11707
- return /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
11890
+ return /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
11708
11891
  /* @__PURE__ */ jsx6(
11709
11892
  ControlButton,
11710
11893
  {
@@ -11718,7 +11901,7 @@ function LeaveControl({ onLeave }) {
11718
11901
  children: /* @__PURE__ */ jsx6(PhoneOffIcon, {})
11719
11902
  }
11720
11903
  ),
11721
- 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: [
11904
+ 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: [
11722
11905
  open === "menu" ? leave.choices.map((choice) => /* @__PURE__ */ jsx6(
11723
11906
  "button",
11724
11907
  {
@@ -11744,7 +11927,7 @@ function LeaveControl({ onLeave }) {
11744
11927
  },
11745
11928
  String(person.identity)
11746
11929
  )) : null,
11747
- open === "confirm" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
11930
+ open === "confirm" ? /* @__PURE__ */ jsxs4(Fragment, { children: [
11748
11931
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__menu-item mx-meet__menu-item--danger", onClick: endNow, children: words.end_for_all }),
11749
11932
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__menu-item", onClick: () => setOpen("menu"), children: "Cancel" })
11750
11933
  ] }) : null,
@@ -11765,12 +11948,12 @@ function useUnreadChat(open) {
11765
11948
  const snapshot = useMeetSnapshot();
11766
11949
  const chat = snapshot?.chat ?? [];
11767
11950
  const local = snapshot?.localIdentity ?? null;
11768
- const [seen, setSeen] = useState4(0);
11951
+ const [seen, setSeen] = useState5(0);
11769
11952
  useEffect6(() => {
11770
11953
  if (open) setSeen(chat.length);
11771
11954
  }, [open, chat.length]);
11772
11955
  const loaded = snapshot?.chatLoaded === true;
11773
- const [baseline, setBaseline] = useState4(null);
11956
+ const [baseline, setBaseline] = useState5(null);
11774
11957
  useEffect6(() => {
11775
11958
  if (loaded && baseline === null) setBaseline(chat.length);
11776
11959
  }, [loaded, baseline, chat.length]);
@@ -11785,7 +11968,7 @@ function Popover({
11785
11968
  placement = "up"
11786
11969
  }) {
11787
11970
  const ref = useRef6(null);
11788
- const [style, setStyle] = useState4({
11971
+ const [style, setStyle] = useState5({
11789
11972
  position: "fixed",
11790
11973
  top: 0,
11791
11974
  left: 0,
@@ -11874,15 +12057,103 @@ function Toast({ text: text3, failed, onDone }) {
11874
12057
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
11875
12058
  return () => clearTimeout(timer);
11876
12059
  }, [text3, failed, onDone]);
11877
- return /* @__PURE__ */ jsxs3("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
12060
+ return /* @__PURE__ */ jsxs4("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
11878
12061
  /* @__PURE__ */ jsx6("span", { children: text3 }),
11879
12062
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
11880
12063
  ] });
11881
12064
  }
12065
+ function AudioSettingsControl() {
12066
+ const host = useMeetHost();
12067
+ const devices = useDeviceSnapshot();
12068
+ const [open, setOpen] = useState5(false);
12069
+ const list = (devices?.devices.audioinput ?? []).filter((device) => device.deviceId.length > 0);
12070
+ if (host === null || list.length < 2) return null;
12071
+ const current = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
12072
+ return /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
12073
+ /* @__PURE__ */ jsx6(
12074
+ ControlButton,
12075
+ {
12076
+ label: "Audio settings",
12077
+ active: open,
12078
+ onClick: () => {
12079
+ if (!open) void host.devices.refresh();
12080
+ setOpen(!open);
12081
+ },
12082
+ children: /* @__PURE__ */ jsx6(ChevronUpIcon, {})
12083
+ }
12084
+ ),
12085
+ 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(
12086
+ "button",
12087
+ {
12088
+ type: "button",
12089
+ role: "menuitemradio",
12090
+ "aria-checked": device.deviceId === current,
12091
+ className: "mx-meet__menu-item",
12092
+ onClick: () => {
12093
+ setOpen(false);
12094
+ host.devices.select("audioinput", device.deviceId);
12095
+ void host.engine.switchDevice("audioinput", device.deviceId).catch(() => void 0);
12096
+ },
12097
+ children: [
12098
+ device.deviceId === current ? /* @__PURE__ */ jsx6(CheckIcon, { width: 16, height: 16 }) : /* @__PURE__ */ jsx6("span", { className: "mx-meet__menu-gap" }),
12099
+ device.label.length > 0 ? device.label : "Microphone"
12100
+ ]
12101
+ },
12102
+ device.deviceId
12103
+ )) }) }) : null
12104
+ ] });
12105
+ }
12106
+ function SpeakingWhileMutedNudge() {
12107
+ const room = useRoom();
12108
+ const host = useMeetHost();
12109
+ const devices = useDeviceSnapshot();
12110
+ const microphone = useLocalMedia().microphone;
12111
+ const mutedByMe = host !== null && room.local != null && room.local.micEnabled !== true && microphone.unavailable === null;
12112
+ const mic = devices?.selected.audioinput ?? host?.devices.resolve("audioinput") ?? null;
12113
+ const stream = useMicrophoneStream(mutedByMe ? mic : "off");
12114
+ const level = useAudioLevel(stream);
12115
+ const latest = useRef6(0);
12116
+ latest.current = level;
12117
+ const [shown, setShown] = useState5(false);
12118
+ const [detector] = useState5(() => createSpeakingWhileMutedDetector());
12119
+ useEffect6(() => {
12120
+ if (!mutedByMe) {
12121
+ detector.reset();
12122
+ setShown(false);
12123
+ return void 0;
12124
+ }
12125
+ const timer = setInterval(() => {
12126
+ if (detector.feed(latest.current, Date.now())) setShown(true);
12127
+ }, 150);
12128
+ return () => clearInterval(timer);
12129
+ }, [mutedByMe, detector]);
12130
+ useEffect6(() => {
12131
+ if (!shown) return void 0;
12132
+ const timer = setTimeout(() => setShown(false), 8e3);
12133
+ return () => clearTimeout(timer);
12134
+ }, [shown]);
12135
+ if (!shown || !mutedByMe) return null;
12136
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "speaking-while-muted", children: [
12137
+ /* @__PURE__ */ jsx6(MicOffIcon, { width: 16, height: 16 }),
12138
+ /* @__PURE__ */ jsx6("span", { children: "You're muted" }),
12139
+ /* @__PURE__ */ jsx6(
12140
+ "button",
12141
+ {
12142
+ type: "button",
12143
+ className: "mx-meet__primary mx-meet__primary--small",
12144
+ onClick: () => {
12145
+ setShown(false);
12146
+ void room.toggleMicrophone();
12147
+ },
12148
+ children: "Unmute"
12149
+ }
12150
+ )
12151
+ ] });
12152
+ }
11882
12153
  function MediaNotices() {
11883
12154
  const media = useLocalMedia();
11884
12155
  const { region, where, enableAudio, acceptOffer, dismissOffer, dismissNotice, retry } = useMediaSupervisor();
11885
- const [fixing, setFixing] = useState4(null);
12156
+ const [fixing, setFixing] = useState5(null);
11886
12157
  const chips = ["microphone", "camera"].flatMap((kind) => {
11887
12158
  const reason = deviceUnavailableReason(media[kind], region.permission[kind]);
11888
12159
  return reason === null ? [] : [{ kind, reason }];
@@ -11892,8 +12163,8 @@ function MediaNotices() {
11892
12163
  const offer = region.offer;
11893
12164
  const name = (kind) => kind === "microphone" ? "Microphone" : "Camera";
11894
12165
  if (chips.length === 0 && region.audioOutput !== "blocked" && notice === null && offer === null) return null;
11895
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-notices", children: [
11896
- region.audioOutput === "blocked" ? /* @__PURE__ */ jsxs3(
12166
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-notices", children: [
12167
+ region.audioOutput === "blocked" ? /* @__PURE__ */ jsxs4(
11897
12168
  ErrorBox,
11898
12169
  {
11899
12170
  as: "div",
@@ -11908,7 +12179,7 @@ function MediaNotices() {
11908
12179
  ]
11909
12180
  }
11910
12181
  ) : null,
11911
- chips.map(({ kind, reason }) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
12182
+ chips.map(({ kind, reason }) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
11912
12183
  /* @__PURE__ */ jsx6("span", { children: deviceChipLabel(kind, reason) }),
11913
12184
  /* @__PURE__ */ jsx6(
11914
12185
  "button",
@@ -11922,9 +12193,9 @@ function MediaNotices() {
11922
12193
  }
11923
12194
  )
11924
12195
  ] }, kind)),
11925
- fixing !== null && fixReason !== null ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
12196
+ fixing !== null && fixReason !== null ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
11926
12197
  /* @__PURE__ */ jsx6("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(fixing, fixReason, where).map((step) => /* @__PURE__ */ jsx6("li", { children: step }, step)) }),
11927
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__fix-actions", children: [
12198
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__fix-actions", children: [
11928
12199
  /* @__PURE__ */ jsx6(
11929
12200
  "button",
11930
12201
  {
@@ -11941,7 +12212,7 @@ function MediaNotices() {
11941
12212
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Close", onClick: () => setFixing(null), children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
11942
12213
  ] })
11943
12214
  ] }) : null,
11944
- notice !== null ? /* @__PURE__ */ jsxs3(
12215
+ notice !== null ? /* @__PURE__ */ jsxs4(
11945
12216
  "div",
11946
12217
  {
11947
12218
  className: "mx-meet__media-pill",
@@ -11953,7 +12224,7 @@ function MediaNotices() {
11953
12224
  ]
11954
12225
  }
11955
12226
  ) : null,
11956
- offer !== null ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-pill", role: "status", children: [
12227
+ offer !== null ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-pill", role: "status", children: [
11957
12228
  /* @__PURE__ */ jsx6("span", { children: `New ${offer.kind}: ${offer.label || name(offer.kind)}` }),
11958
12229
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void acceptOffer(), children: "Use it" }),
11959
12230
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismissOffer, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
@@ -11968,22 +12239,22 @@ function MeetingOverlays() {
11968
12239
  const snapshot = useMeetSnapshot();
11969
12240
  const controls = useHostControls();
11970
12241
  const isHostNow = useRole() === "host";
11971
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
12242
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
11972
12243
  /* @__PURE__ */ jsx6(ReactionOverlay, { reactions }),
11973
12244
  /* @__PURE__ */ jsx6(MediaNotices, {}),
11974
12245
  snapshot !== null && snapshot.phase === "in_call" && snapshot.participants.length >= 2 && !snapshot.participants.some((p) => p.role === "host" || p.role === "cohost") ? (
11975
12246
  // meeting-without-host: the call goes on; host-only controls are simply not on screen.
11976
12247
  /* @__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." })
11977
12248
  ) : null,
11978
- 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: [
12249
+ 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: [
11979
12250
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: "This meeting is being recorded" }),
11980
12251
  /* @__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." }),
11981
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
12252
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
11982
12253
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__send", onClick: live.agree, children: live.consent === "ok_or_leave" ? "OK" : "I agree" }),
11983
12254
  live.consent === "ok_or_leave" ? /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => void room.leave(), children: "Leave meeting" }) : null
11984
12255
  ] })
11985
12256
  ] }) }) : null,
11986
- snapshot?.canReclaim === true && !isHostNow ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "host-reclaim", children: [
12257
+ snapshot?.canReclaim === true && !isHostNow ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "host-reclaim", children: [
11987
12258
  /* @__PURE__ */ jsx6("span", { children: "You started this meeting. Take back the host?" }),
11988
12259
  /* @__PURE__ */ jsx6(
11989
12260
  "button",
@@ -11996,7 +12267,7 @@ function MeetingOverlays() {
11996
12267
  )
11997
12268
  ] }) : null,
11998
12269
  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,
11999
- live.timeWarning && live.minutesLeft !== null && live.minutesLeft > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "time-warning", children: [
12270
+ live.timeWarning && live.minutesLeft !== null && live.minutesLeft > 0 ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "time-warning", children: [
12000
12271
  "This meeting will end in ",
12001
12272
  live.minutesLeft,
12002
12273
  " ",
@@ -12007,7 +12278,7 @@ function MeetingOverlays() {
12007
12278
  // A host's request ("the host is asking you to unmute"), not an error:
12008
12279
  // an assertive status, so it is announced at once without being filed
12009
12280
  // as a failure (design-system error-box census).
12010
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
12281
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
12011
12282
  /* @__PURE__ */ jsx6("span", { children: notice.text }),
12012
12283
  notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx6(
12013
12284
  "button",
@@ -12034,7 +12305,7 @@ function ShortcutsSheet({ onClose }) {
12034
12305
  window.addEventListener("keydown", onKey);
12035
12306
  return () => window.removeEventListener("keydown", onKey);
12036
12307
  }, [onClose]);
12037
- return /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
12308
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs4(
12038
12309
  "div",
12039
12310
  {
12040
12311
  className: "mx-meet__sheet",
@@ -12042,11 +12313,11 @@ function ShortcutsSheet({ onClose }) {
12042
12313
  "aria-label": "Keyboard shortcuts",
12043
12314
  onClick: (event) => event.stopPropagation(),
12044
12315
  children: [
12045
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
12316
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__panel-head", children: [
12046
12317
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
12047
12318
  /* @__PURE__ */ jsx6(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }) })
12048
12319
  ] }),
12049
- /* @__PURE__ */ jsx6("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__shortcut", children: [
12320
+ /* @__PURE__ */ jsx6("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__shortcut", children: [
12050
12321
  /* @__PURE__ */ jsx6("dt", { children: shortcut.label }),
12051
12322
  /* @__PURE__ */ jsx6("dd", { children: /* @__PURE__ */ jsx6("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
12052
12323
  ] }, shortcut.id)) })
@@ -12078,8 +12349,8 @@ function PanelShell({
12078
12349
  observer.observe(header);
12079
12350
  return () => observer.disconnect();
12080
12351
  }, []);
12081
- return /* @__PURE__ */ jsxs3("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
12082
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
12352
+ return /* @__PURE__ */ jsxs4("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
12353
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__panel-head", children: [
12083
12354
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: title }),
12084
12355
  /* @__PURE__ */ jsx6(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }) })
12085
12356
  ] }),
@@ -12094,8 +12365,8 @@ function ChatPanel({
12094
12365
  const snapshot = useMeetSnapshot();
12095
12366
  const room = useRoom();
12096
12367
  const live = useLivePolicy();
12097
- const [draft, setDraft] = useState4("");
12098
- const [recipient, setRecipient] = useState4(to);
12368
+ const [draft, setDraft] = useState5("");
12369
+ const [recipient, setRecipient] = useState5(to);
12099
12370
  const listRef = useRef6(null);
12100
12371
  const messages = snapshot?.chat ?? [];
12101
12372
  const local = snapshot?.localIdentity ?? null;
@@ -12112,13 +12383,13 @@ function ChatPanel({
12112
12383
  setRecipient(next);
12113
12384
  onTo?.(next);
12114
12385
  };
12115
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Chat", onClose, children: [
12116
- /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__chat", ref: listRef, children: [
12386
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Chat", onClose, children: [
12387
+ /* @__PURE__ */ jsxs4("ul", { className: "mx-meet__chat", ref: listRef, children: [
12117
12388
  snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
12118
12389
  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,
12119
12390
  messages.map((message) => /* @__PURE__ */ jsx6(ChatLine, { message, local, people }, message.id))
12120
12391
  ] }),
12121
- !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(
12392
+ !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(
12122
12393
  "form",
12123
12394
  {
12124
12395
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -12131,7 +12402,7 @@ function ChatPanel({
12131
12402
  else void room.sendPrivateChat(recipient, text3);
12132
12403
  },
12133
12404
  children: [
12134
- people.length > 0 ? /* @__PURE__ */ jsxs3(
12405
+ people.length > 0 ? /* @__PURE__ */ jsxs4(
12135
12406
  "select",
12136
12407
  {
12137
12408
  className: "mx-meet__select mx-meet__select--compact",
@@ -12140,14 +12411,14 @@ function ChatPanel({
12140
12411
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
12141
12412
  children: [
12142
12413
  /* @__PURE__ */ jsx6("option", { value: "", children: "Everyone" }),
12143
- people.map((participant) => /* @__PURE__ */ jsxs3("option", { value: participant.identity, children: [
12414
+ people.map((participant) => /* @__PURE__ */ jsxs4("option", { value: participant.identity, children: [
12144
12415
  participant.displayName,
12145
12416
  " (private)"
12146
12417
  ] }, participant.identity))
12147
12418
  ]
12148
12419
  }
12149
12420
  ) : null,
12150
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
12421
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__composer-row", children: [
12151
12422
  /* @__PURE__ */ jsx6(
12152
12423
  "input",
12153
12424
  {
@@ -12161,7 +12432,7 @@ function ChatPanel({
12161
12432
  ),
12162
12433
  /* @__PURE__ */ jsx6("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
12163
12434
  ] }),
12164
- recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
12435
+ recipientName !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
12165
12436
  "Only ",
12166
12437
  recipientName,
12167
12438
  " sees this. Private messages are not saved."
@@ -12179,7 +12450,7 @@ function ChatLine({
12179
12450
  const mine = message.identity === local;
12180
12451
  const privateTo = message.to ?? null;
12181
12452
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
12182
- return /* @__PURE__ */ jsxs3(
12453
+ return /* @__PURE__ */ jsxs4(
12183
12454
  "li",
12184
12455
  {
12185
12456
  className: [
@@ -12188,9 +12459,9 @@ function ChatLine({
12188
12459
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
12189
12460
  ].filter(Boolean).join(" "),
12190
12461
  children: [
12191
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
12462
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__chat-meta", children: [
12192
12463
  /* @__PURE__ */ jsx6("strong", { children: mine ? "You" : message.displayName }),
12193
- counterpart !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-private", children: [
12464
+ counterpart !== null ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__chat-private", children: [
12194
12465
  "to ",
12195
12466
  counterpart,
12196
12467
  " \xB7 private"
@@ -12210,8 +12481,8 @@ function PeoplePanel({
12210
12481
  const snapshot = useMeetSnapshot();
12211
12482
  const controls = useHostControls();
12212
12483
  const queue = useHandQueue();
12213
- const [query, setQuery] = useState4("");
12214
- const [menuFor, setMenuFor] = useState4(null);
12484
+ const [query, setQuery] = useState5("");
12485
+ const [menuFor, setMenuFor] = useState5(null);
12215
12486
  const myRole = useRole();
12216
12487
  const local = snapshot?.localIdentity ?? null;
12217
12488
  const observersHidden = snapshot?.grants.observersVisibleTo === "hosts" && !controls.isHost;
@@ -12220,11 +12491,11 @@ function PeoplePanel({
12220
12491
  );
12221
12492
  const needle = query.trim().toLowerCase();
12222
12493
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
12223
- return /* @__PURE__ */ jsxs3(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
12494
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
12224
12495
  /* @__PURE__ */ jsx6(LobbyPanel, {}),
12225
- queue.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
12226
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__section-head", children: [
12227
- /* @__PURE__ */ jsxs3("h3", { className: "mx-meet__section-title", children: [
12496
+ queue.length > 0 ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
12497
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__section-head", children: [
12498
+ /* @__PURE__ */ jsxs4("h3", { className: "mx-meet__section-title", children: [
12228
12499
  "Raised hands \xB7 ",
12229
12500
  queue.length
12230
12501
  ] }),
@@ -12238,9 +12509,9 @@ function PeoplePanel({
12238
12509
  }
12239
12510
  ) : null
12240
12511
  ] }),
12241
- /* @__PURE__ */ jsx6("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
12512
+ /* @__PURE__ */ jsx6("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__person", children: [
12242
12513
  /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
12243
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
12514
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
12244
12515
  participant.displayName,
12245
12516
  participant.identity === local ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__you", children: " (you)" }) : null
12246
12517
  ] }),
@@ -12255,12 +12526,12 @@ function PeoplePanel({
12255
12526
  ) : null
12256
12527
  ] }, participant.identity)) })
12257
12528
  ] }) : null,
12258
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__bulk", children: [
12259
- /* @__PURE__ */ jsxs3("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
12529
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__bulk", children: [
12530
+ /* @__PURE__ */ jsxs4("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
12260
12531
  /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }),
12261
12532
  " Mute all"
12262
12533
  ] }),
12263
- /* @__PURE__ */ jsxs3(
12534
+ /* @__PURE__ */ jsxs4(
12264
12535
  "button",
12265
12536
  {
12266
12537
  type: "button",
@@ -12273,7 +12544,7 @@ function PeoplePanel({
12273
12544
  }
12274
12545
  )
12275
12546
  ] }) : null,
12276
- everyone.length > 4 ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__search", children: [
12547
+ everyone.length > 4 ? /* @__PURE__ */ jsxs4("label", { className: "mx-meet__search", children: [
12277
12548
  /* @__PURE__ */ jsx6(SearchIcon, { width: 16, height: 16 }),
12278
12549
  /* @__PURE__ */ jsx6(
12279
12550
  "input",
@@ -12287,10 +12558,10 @@ function PeoplePanel({
12287
12558
  )
12288
12559
  ] }) : null,
12289
12560
  controls.notice !== null ? /* @__PURE__ */ jsx6("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
12290
- /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__people", children: [
12291
- shown.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
12561
+ /* @__PURE__ */ jsxs4("ul", { className: "mx-meet__people", children: [
12562
+ shown.map((participant) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__person", children: [
12292
12563
  /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
12293
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
12564
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
12294
12565
  participant.displayName,
12295
12566
  participant.identity === local ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__you", children: " (you)" }) : null,
12296
12567
  /* @__PURE__ */ jsx6(
@@ -12307,7 +12578,7 @@ function PeoplePanel({
12307
12578
  participant.handRaised ? /* @__PURE__ */ jsx6(HandIcon, { width: 14, height: 14 }) : null,
12308
12579
  !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }) : null,
12309
12580
  /* @__PURE__ */ jsx6(QualityBars, { quality: participant.quality }),
12310
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
12581
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
12311
12582
  /* @__PURE__ */ jsx6(
12312
12583
  ControlButton,
12313
12584
  {
@@ -12328,7 +12599,7 @@ function PeoplePanel({
12328
12599
  ) : null
12329
12600
  ] })
12330
12601
  ] }, participant.identity)),
12331
- shown.length === 0 ? /* @__PURE__ */ jsxs3("li", { className: "mx-meet__panel-note", children: [
12602
+ shown.length === 0 ? /* @__PURE__ */ jsxs4("li", { className: "mx-meet__panel-note", children: [
12332
12603
  "Nobody matches \u201C",
12333
12604
  query,
12334
12605
  "\u201D."
@@ -12346,14 +12617,14 @@ function PersonMenu({
12346
12617
  const host = useMeetHost();
12347
12618
  const snapshot = useMeetSnapshot();
12348
12619
  const controls = useHostControls();
12349
- const [mode, setMode] = useState4("menu");
12350
- const [text3, setText] = useState4("");
12620
+ const [mode, setMode] = useState5("menu");
12621
+ const [text3, setText] = useState5("");
12351
12622
  const self = participant.identity === snapshot?.localIdentity;
12352
12623
  const moderate = controls.canModerate(participant);
12353
12624
  const pinned = snapshot?.pinned === participant.identity;
12354
12625
  const spotlit = snapshot?.spotlight === participant.identity;
12355
12626
  const hasAccount = participant.userId !== null;
12356
- const [refused, setRefused] = useState4(false);
12627
+ const [refused, setRefused] = useState5(false);
12357
12628
  const act = (request) => {
12358
12629
  setRefused(false);
12359
12630
  void controls.run(request).then((result) => {
@@ -12364,7 +12635,7 @@ function PersonMenu({
12364
12635
  const refusal2 = 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;
12365
12636
  if (mode === "rename" || mode === "report") {
12366
12637
  const renaming = mode === "rename";
12367
- return /* @__PURE__ */ jsx6(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs3(
12638
+ return /* @__PURE__ */ jsx6(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs4(
12368
12639
  "form",
12369
12640
  {
12370
12641
  className: "mx-meet__menu-form",
@@ -12376,7 +12647,7 @@ function PersonMenu({
12376
12647
  );
12377
12648
  },
12378
12649
  children: [
12379
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
12650
+ /* @__PURE__ */ jsxs4("label", { className: "mx-meet__field", children: [
12380
12651
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
12381
12652
  renaming ? /* @__PURE__ */ jsx6(
12382
12653
  "input",
@@ -12400,7 +12671,7 @@ function PersonMenu({
12400
12671
  )
12401
12672
  ] }),
12402
12673
  refusal2,
12403
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
12674
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
12404
12675
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
12405
12676
  /* @__PURE__ */ jsx6("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
12406
12677
  ] })
@@ -12410,10 +12681,10 @@ function PersonMenu({
12410
12681
  }
12411
12682
  if (mode === "remove" || mode === "transfer") {
12412
12683
  const removing = mode === "remove";
12413
- return /* @__PURE__ */ jsx6(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-form", children: [
12684
+ return /* @__PURE__ */ jsx6(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-form", children: [
12414
12685
  /* @__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.` }),
12415
12686
  refusal2,
12416
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
12687
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
12417
12688
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
12418
12689
  /* @__PURE__ */ jsx6(
12419
12690
  "button",
@@ -12428,8 +12699,8 @@ function PersonMenu({
12428
12699
  ] })
12429
12700
  ] }) });
12430
12701
  }
12431
- return /* @__PURE__ */ jsx6(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
12432
- /* @__PURE__ */ jsxs3(
12702
+ return /* @__PURE__ */ jsx6(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", role: "menu", children: [
12703
+ /* @__PURE__ */ jsxs4(
12433
12704
  MenuItem,
12434
12705
  {
12435
12706
  onSelect: () => {
@@ -12443,7 +12714,7 @@ function PersonMenu({
12443
12714
  ]
12444
12715
  }
12445
12716
  ),
12446
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
12717
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs4(
12447
12718
  MenuItem,
12448
12719
  {
12449
12720
  onSelect: () => {
@@ -12460,44 +12731,44 @@ function PersonMenu({
12460
12731
  ]
12461
12732
  }
12462
12733
  ) : null,
12463
- controls.isHost ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
12734
+ controls.isHost ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
12464
12735
  /* @__PURE__ */ jsx6(SpotlightIcon, { width: 16, height: 16 }),
12465
12736
  " ",
12466
12737
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
12467
12738
  ] }) : null,
12468
- moderate ? /* @__PURE__ */ jsxs3(Fragment, { children: [
12739
+ moderate ? /* @__PURE__ */ jsxs4(Fragment, { children: [
12469
12740
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu-sep", role: "separator" }),
12470
- participant.micEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
12741
+ participant.micEnabled ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
12471
12742
  /* @__PURE__ */ jsx6(MicOffIcon, { width: 16, height: 16 }),
12472
12743
  " Mute"
12473
- ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
12744
+ ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
12474
12745
  /* @__PURE__ */ jsx6(MicIcon, { width: 16, height: 16 }),
12475
12746
  " Ask to unmute"
12476
12747
  ] }) : null,
12477
- participant.cameraEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
12748
+ participant.cameraEnabled ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
12478
12749
  /* @__PURE__ */ jsx6(CameraOffIcon, { width: 16, height: 16 }),
12479
12750
  " Stop video"
12480
12751
  ] }) : null,
12481
- participant.screenSharing ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
12752
+ participant.screenSharing ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
12482
12753
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
12483
12754
  " Stop screen share"
12484
12755
  ] }) : null,
12485
- participant.handRaised ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
12756
+ participant.handRaised ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
12486
12757
  /* @__PURE__ */ jsx6(HandIcon, { width: 16, height: 16 }),
12487
12758
  " Lower hand"
12488
12759
  ] }) : null,
12489
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
12760
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
12490
12761
  /* @__PURE__ */ jsx6(PeopleIcon, { width: 16, height: 16 }),
12491
12762
  " Make co-host"
12492
12763
  ] }) : null,
12493
- !participant.isAgent && participant.role !== "cohost" && participant.role !== "host" ? participant.role === "presenter" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_presenter", identity: participant.identity }), children: [
12764
+ !participant.isAgent && participant.role !== "cohost" && participant.role !== "host" ? participant.role === "presenter" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "revoke_presenter", identity: participant.identity }), children: [
12494
12765
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
12495
12766
  " Remove presenter"
12496
- ] }) : /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_presenter", identity: participant.identity }), children: [
12767
+ ] }) : /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "make_presenter", identity: participant.identity }), children: [
12497
12768
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
12498
12769
  " Make presenter"
12499
12770
  ] }) : null,
12500
- !participant.isAgent ? /* @__PURE__ */ jsxs3(
12771
+ !participant.isAgent ? /* @__PURE__ */ jsxs4(
12501
12772
  MenuItem,
12502
12773
  {
12503
12774
  onSelect: () => {
@@ -12511,15 +12782,15 @@ function PersonMenu({
12511
12782
  }
12512
12783
  ) : null
12513
12784
  ] }) : null,
12514
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
12785
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
12515
12786
  /* @__PURE__ */ jsx6(PeopleIcon, { width: 16, height: 16 }),
12516
12787
  " Remove co-host"
12517
12788
  ] }) : null,
12518
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => setMode("transfer"), children: [
12789
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => setMode("transfer"), children: [
12519
12790
  /* @__PURE__ */ jsx6(SpotlightIcon, { width: 16, height: 16 }),
12520
12791
  " Make host"
12521
12792
  ] }) : null,
12522
- self ? /* @__PURE__ */ jsxs3(
12793
+ self ? /* @__PURE__ */ jsxs4(
12523
12794
  MenuItem,
12524
12795
  {
12525
12796
  onSelect: () => {
@@ -12532,7 +12803,7 @@ function PersonMenu({
12532
12803
  ]
12533
12804
  }
12534
12805
  ) : null,
12535
- !self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
12806
+ !self && !participant.isAgent ? /* @__PURE__ */ jsxs4(
12536
12807
  MenuItem,
12537
12808
  {
12538
12809
  onSelect: () => {
@@ -12545,7 +12816,7 @@ function PersonMenu({
12545
12816
  ]
12546
12817
  }
12547
12818
  ) : null,
12548
- moderate && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
12819
+ moderate && !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
12549
12820
  /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }),
12550
12821
  " Remove from meeting"
12551
12822
  ] }) : null
@@ -12553,7 +12824,7 @@ function PersonMenu({
12553
12824
  }
12554
12825
  function SettingsPanel({ onClose }) {
12555
12826
  const host = useRequiredMeetHost();
12556
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
12827
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Settings", onClose, children: [
12557
12828
  /* @__PURE__ */ jsx6(
12558
12829
  DeviceSettings,
12559
12830
  {
@@ -12576,15 +12847,15 @@ function DeviceSettings({
12576
12847
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
12577
12848
  const stream = useMicrophoneStream(microphone);
12578
12849
  const level = useAudioLevel(stream);
12579
- const [testing, setTesting] = useState4(false);
12850
+ const [testing, setTesting] = useState5(false);
12580
12851
  useEffect6(() => {
12581
12852
  void host.devices.refresh();
12582
12853
  }, [host]);
12583
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
12854
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
12584
12855
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
12585
12856
  /* @__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))}%` } }) }),
12586
12857
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
12587
- /* @__PURE__ */ jsxs3(
12858
+ /* @__PURE__ */ jsxs4(
12588
12859
  "button",
12589
12860
  {
12590
12861
  type: "button",
@@ -12606,7 +12877,7 @@ function DeviceSettings({
12606
12877
  }
12607
12878
  function EffectsSettings({ preview }) {
12608
12879
  const effects = useMediaEffects();
12609
- const [error, setError] = useState4(null);
12880
+ const [error, setError] = useState5(null);
12610
12881
  const fileRef = useRef6(null);
12611
12882
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
12612
12883
  const apply = (next) => {
@@ -12619,8 +12890,8 @@ function EffectsSettings({ preview }) {
12619
12890
  );
12620
12891
  }
12621
12892
  };
12622
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
12623
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
12893
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
12894
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
12624
12895
  /* @__PURE__ */ jsx6(
12625
12896
  Checkbox,
12626
12897
  {
@@ -12629,12 +12900,12 @@ function EffectsSettings({ preview }) {
12629
12900
  onCheckedChange: (checked) => apply({ noiseSuppression: checked === true })
12630
12901
  }
12631
12902
  ),
12632
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check-text", children: [
12903
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check-text", children: [
12633
12904
  /* @__PURE__ */ jsx6(Label, { htmlFor: "mx-meet-noise", children: "Noise suppression" }),
12634
12905
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
12635
12906
  ] })
12636
12907
  ] }),
12637
- supported ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
12908
+ supported ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field", children: [
12638
12909
  /* @__PURE__ */ jsx6(Label, { children: "Background" }),
12639
12910
  /* @__PURE__ */ jsx6(
12640
12911
  SegmentedControl,
@@ -12728,14 +12999,20 @@ async function playTestSound(sinkId) {
12728
12999
  audio.pause();
12729
13000
  await context.close();
12730
13001
  }
12731
- function useMicrophoneStream(deviceId2) {
12732
- const [stream, setStream] = useState4(null);
13002
+ function useMicrophoneStream(deviceId2, report, attempt = 0) {
13003
+ const [stream, setStream] = useState5(null);
13004
+ const reportRef = useRef6(report);
13005
+ reportRef.current = report;
12733
13006
  useEffect6(() => {
12734
- if (deviceId2 === "off") return void 0;
13007
+ if (deviceId2 === "off") {
13008
+ reportRef.current?.("off");
13009
+ return void 0;
13010
+ }
12735
13011
  let live = true;
12736
13012
  let opened = null;
12737
13013
  const media = globalThis.navigator?.mediaDevices;
12738
13014
  if (media === void 0) return void 0;
13015
+ reportRef.current?.("prompting");
12739
13016
  void media.getUserMedia({ audio: deviceId2 === null ? true : { deviceId: { exact: deviceId2 } } }).then((next) => {
12740
13017
  if (!live) {
12741
13018
  next.getTracks().forEach((track) => track.stop());
@@ -12743,20 +13020,54 @@ function useMicrophoneStream(deviceId2) {
12743
13020
  }
12744
13021
  opened = next;
12745
13022
  setStream(next);
12746
- }).catch(() => setStream(null));
13023
+ reportRef.current?.("on");
13024
+ }).catch((thrown) => {
13025
+ setStream(null);
13026
+ if (live) reportRef.current?.({ error: thrown });
13027
+ });
12747
13028
  return () => {
12748
13029
  live = false;
12749
13030
  opened?.getTracks().forEach((track) => track.stop());
12750
13031
  setStream(null);
12751
13032
  };
12752
- }, [deviceId2]);
13033
+ }, [deviceId2, attempt]);
12753
13034
  return stream;
12754
13035
  }
13036
+ function PreviewStatus({ onRetry }) {
13037
+ const { region, where } = useMediaSupervisor();
13038
+ const [waited, setWaited] = useState5(false);
13039
+ const prompting = region.preview.microphone.state === "prompting" || region.preview.camera.state === "prompting";
13040
+ useEffect6(() => {
13041
+ if (!prompting) {
13042
+ setWaited(false);
13043
+ return void 0;
13044
+ }
13045
+ const timer = setTimeout(() => setWaited(true), 800);
13046
+ return () => clearTimeout(timer);
13047
+ }, [prompting]);
13048
+ const refused = ["microphone", "camera"].flatMap((kind) => {
13049
+ const preview = region.preview[kind];
13050
+ const reason = region.permission[kind] === "denied" ? "denied" : preview.state === "unavailable" ? preview.unavailable?.reason ?? "failed" : null;
13051
+ return reason === null ? [] : [{ kind, reason }];
13052
+ });
13053
+ if (refused.length === 0) {
13054
+ if (!prompting || !waited) return null;
13055
+ 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" });
13056
+ }
13057
+ const first = refused[0];
13058
+ const both = refused.length === 2 && refused[0].reason === refused[1].reason;
13059
+ const label = both ? deviceChipLabel("camera", first.reason).replace(/^Camera/, "Camera and mic") : refused.map((r) => deviceChipLabel(r.kind, r.reason)).join(" \xB7 ");
13060
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__warning", role: "status", "data-meet-notice": deviceNoticeCode(first.kind, first.reason), children: [
13061
+ /* @__PURE__ */ jsx6("strong", { children: label }),
13062
+ /* @__PURE__ */ jsx6("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(first.kind, first.reason, where).map((step) => /* @__PURE__ */ jsx6("li", { children: step }, step)) }),
13063
+ /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", size: "sm", onClick: onRetry, children: "Try again" })
13064
+ ] });
13065
+ }
12755
13066
  function KnockNotice({ onView }) {
12756
13067
  const { knocker, others, admit, dismiss } = useKnockNotice();
12757
13068
  if (knocker === null) return null;
12758
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "knock-received", "data-meet-participant-name": knocker.displayName, children: [
12759
- /* @__PURE__ */ jsxs3("span", { children: [
13069
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "knock-received", "data-meet-participant-name": knocker.displayName, children: [
13070
+ /* @__PURE__ */ jsxs4("span", { children: [
12760
13071
  knocker.displayName,
12761
13072
  " wants to join",
12762
13073
  others > 0 ? ` (+${others} more)` : ""
@@ -12780,15 +13091,15 @@ function KnockNotice({ onView }) {
12780
13091
  function LobbyPanel() {
12781
13092
  const lobby = useLobby();
12782
13093
  if (!lobby.canAdmit || lobby.waiting.length === 0 && lobby.declined.length === 0) return null;
12783
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
13094
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
12784
13095
  lobby.waiting.length > 0 ? /* @__PURE__ */ jsx6(WaitingList, { lobby }) : null,
12785
13096
  lobby.declined.length > 0 ? /* @__PURE__ */ jsx6(DeclinedList, { lobby }) : null
12786
13097
  ] });
12787
13098
  }
12788
13099
  function DeclinedList({ lobby }) {
12789
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Declined requests", "data-meet-declined": "", children: [
13100
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__lobby", "aria-label": "Declined requests", "data-meet-declined": "", children: [
12790
13101
  /* @__PURE__ */ jsx6("header", { className: "mx-meet__lobby-head", children: /* @__PURE__ */ jsx6("h3", { className: "mx-meet__lobby-title", children: "Declined" }) }),
12791
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.declined.map((entry) => /* @__PURE__ */ jsxs3(
13102
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.declined.map((entry) => /* @__PURE__ */ jsxs4(
12792
13103
  "li",
12793
13104
  {
12794
13105
  className: "mx-meet__lobby-row",
@@ -12814,12 +13125,12 @@ function DeclinedList({ lobby }) {
12814
13125
  ] });
12815
13126
  }
12816
13127
  function WaitingList({ lobby }) {
12817
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
12818
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__lobby-head", children: [
13128
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
13129
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__lobby-head", children: [
12819
13130
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
12820
13131
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
12821
13132
  ] }),
12822
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs3(
13133
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs4(
12823
13134
  "li",
12824
13135
  {
12825
13136
  className: "mx-meet__lobby-row",
@@ -12827,7 +13138,7 @@ function WaitingList({ lobby }) {
12827
13138
  "data-meet-participant-name": entry.displayName,
12828
13139
  children: [
12829
13140
  /* @__PURE__ */ jsx6(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
12830
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
13141
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
12831
13142
  entry.displayName,
12832
13143
  entry.userId === null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null
12833
13144
  ] }),
@@ -12851,17 +13162,17 @@ function NoteTakerRow() {
12851
13162
  const ai = useMeetAi();
12852
13163
  const status = ai.noteTaker;
12853
13164
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
12854
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
12855
- /* @__PURE__ */ jsxs3("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
13165
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
13166
+ /* @__PURE__ */ jsxs4("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
12856
13167
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
12857
13168
  ai.noteTakerLabel
12858
13169
  ] }),
12859
13170
  status.detail !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
12860
- status.refusal !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
13171
+ status.refusal !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
12861
13172
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
12862
13173
  status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
12863
13174
  ] }) : null,
12864
- 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: [
13175
+ 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: [
12865
13176
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
12866
13177
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
12867
13178
  ] }) : null,
@@ -12889,9 +13200,9 @@ function NoteList({
12889
13200
  notes,
12890
13201
  empty
12891
13202
  }) {
12892
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": title, children: [
13203
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": title, children: [
12893
13204
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: title }),
12894
- 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: [
13205
+ 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: [
12895
13206
  note.text,
12896
13207
  note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
12897
13208
  ] }, note.id)) })
@@ -12899,14 +13210,14 @@ function NoteList({
12899
13210
  }
12900
13211
  function AiPanel({ onClose }) {
12901
13212
  const ai = useMeetAi();
12902
- const [question, setQuestion] = useState4("");
12903
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Meeting assistant", onClose, children: [
13213
+ const [question, setQuestion] = useState5("");
13214
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Meeting assistant", onClose, children: [
12904
13215
  /* @__PURE__ */ jsx6(NoteTakerRow, {}),
12905
- ai.summary !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
13216
+ ai.summary !== null ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
12906
13217
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
12907
13218
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__summary", children: ai.summary.text })
12908
13219
  ] }) : null,
12909
- ai.wrapUp !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
13220
+ ai.wrapUp !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
12910
13221
  "The wrap-up is written \u2014 ",
12911
13222
  ai.wrapUp.noteIds.length,
12912
13223
  " ",
@@ -12942,9 +13253,9 @@ function AiPanel({ onClose }) {
12942
13253
  empty: "No action items yet."
12943
13254
  }
12944
13255
  ),
12945
- ai.transcript.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
13256
+ ai.transcript.length > 0 ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
12946
13257
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
12947
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs3(
13258
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs4(
12948
13259
  "li",
12949
13260
  {
12950
13261
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
@@ -12956,7 +13267,7 @@ function AiPanel({ onClose }) {
12956
13267
  line.id
12957
13268
  )) })
12958
13269
  ] }) : null,
12959
- /* @__PURE__ */ jsxs3(
13270
+ /* @__PURE__ */ jsxs4(
12960
13271
  "form",
12961
13272
  {
12962
13273
  className: "mx-meet__composer",
@@ -12983,7 +13294,7 @@ function AiPanel({ onClose }) {
12983
13294
  ),
12984
13295
  ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
12985
13296
  ai.answer !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__answer", children: ai.answer }) : null,
12986
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
13297
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__coverage", children: [
12987
13298
  "Answered from ",
12988
13299
  ai.coverage.segmentsUsed,
12989
13300
  " of ",
@@ -12992,7 +13303,7 @@ function AiPanel({ onClose }) {
12992
13303
  ai.coverage.truncated ? " (the oldest were left out)" : "",
12993
13304
  "."
12994
13305
  ] }) : null,
12995
- ai.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
13306
+ ai.error !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
12996
13307
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
12997
13308
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
12998
13309
  ] }) : null
@@ -13005,7 +13316,7 @@ function Captions({ lines = 3 }) {
13005
13316
  const captions = useCaptions();
13006
13317
  if (!captions.on) return null;
13007
13318
  if (captions.state === "unavailable") {
13008
- return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: /* @__PURE__ */ jsxs3("p", { className: "mx-meet__caption", children: [
13319
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: /* @__PURE__ */ jsxs4("p", { className: "mx-meet__caption", children: [
13009
13320
  "Captions are unavailable. ",
13010
13321
  captions.reason,
13011
13322
  captions.remedy !== null ? ` ${captions.remedy}` : ""
@@ -13014,10 +13325,10 @@ function Captions({ lines = 3 }) {
13014
13325
  if (visible.length === 0) {
13015
13326
  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." }) });
13016
13327
  }
13017
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": "live", children: [
13328
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": "live", children: [
13018
13329
  visible.map((line) => {
13019
13330
  const translated = translation.language === null ? void 0 : translation.translations[line.id];
13020
- return /* @__PURE__ */ jsxs3(
13331
+ return /* @__PURE__ */ jsxs4(
13021
13332
  "p",
13022
13333
  {
13023
13334
  className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
@@ -13045,7 +13356,7 @@ function AttendanceNotice() {
13045
13356
  if (notice === null) return null;
13046
13357
  const refused = media.microphone.unavailable;
13047
13358
  const code = microphoneNoticeCode(media.microphone);
13048
- return /* @__PURE__ */ jsxs3(
13359
+ return /* @__PURE__ */ jsxs4(
13049
13360
  "p",
13050
13361
  {
13051
13362
  className: "mx-meet__banner mx-meet__banner--attendance",
@@ -13076,15 +13387,22 @@ function PreJoinBody({
13076
13387
  const recording = useRecording();
13077
13388
  const effects = useMediaEffects();
13078
13389
  const { notice } = useModerationNotice();
13079
- const [mode, setMode] = useState4("video");
13080
- const [microphone, setMicrophone] = useState4(true);
13081
- const [joining, setJoining] = useState4(false);
13390
+ const [mode, setMode] = useState5("video");
13391
+ const [microphone, setMicrophone] = useState5(true);
13392
+ const [joining, setJoining] = useState5(false);
13082
13393
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
13083
13394
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
13084
- const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
13085
- const micStream = useMicrophoneStream(microphone ? mic : "off");
13395
+ const { reportPreview } = useMediaSupervisor();
13396
+ const [attempt, setAttempt] = useState5(0);
13397
+ const preview = useCameraPreview(
13398
+ mode === "video" ? camera : void 0,
13399
+ effects.effects,
13400
+ (outcome) => reportPreview("camera", outcome),
13401
+ attempt
13402
+ );
13403
+ const micStream = useMicrophoneStream(microphone ? mic : "off", (outcome) => reportPreview("microphone", outcome), attempt);
13086
13404
  const level = useAudioLevel(micStream);
13087
- const [speakerTesting, setSpeakerTesting] = useState4(false);
13405
+ const [speakerTesting, setSpeakerTesting] = useState5(false);
13088
13406
  useEffect6(() => {
13089
13407
  void host.devices.refresh();
13090
13408
  }, [host]);
@@ -13107,8 +13425,8 @@ function PreJoinBody({
13107
13425
  ...secondDevice !== void 0 ? { secondDevice } : {}
13108
13426
  }).then(() => onJoined?.()).catch(() => void 0).finally(() => setJoining(false));
13109
13427
  };
13110
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
13111
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__preview", children: [
13428
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin", children: [
13429
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__preview", children: [
13112
13430
  mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx6(
13113
13431
  "video",
13114
13432
  {
@@ -13124,10 +13442,11 @@ function PreJoinBody({
13124
13442
  mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
13125
13443
  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
13126
13444
  ] }),
13127
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-panel", children: [
13445
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin-panel", children: [
13128
13446
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
13447
+ /* @__PURE__ */ jsx6(PreviewStatus, { onRetry: () => setAttempt((n) => n + 1) }),
13129
13448
  notice?.kind === "removed" ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__warning", children: notice.text }) : null,
13130
- devices?.labelsHidden === true ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
13449
+ devices?.labelsHidden === true ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
13131
13450
  "Your browser is hiding device names until you allow camera and microphone access.",
13132
13451
  /* @__PURE__ */ jsx6(
13133
13452
  "button",
@@ -13143,9 +13462,9 @@ function PreJoinBody({
13143
13462
  ] }) : null,
13144
13463
  devices?.fallbackNotice != null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
13145
13464
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audioinput", label: "Microphone" }),
13146
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field-row", children: [
13465
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field-row", children: [
13147
13466
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
13148
- /* @__PURE__ */ jsxs3(
13467
+ /* @__PURE__ */ jsxs4(
13149
13468
  Button,
13150
13469
  {
13151
13470
  type: "button",
@@ -13168,8 +13487,8 @@ function PreJoinBody({
13168
13487
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "videoinput", label: "Camera" }),
13169
13488
  /* @__PURE__ */ jsx6(EffectsSettings, { preview: preview.preview }),
13170
13489
  recording.consentNotice !== null ? /* @__PURE__ */ jsx6(Alert, { variant: "info", children: /* @__PURE__ */ jsx6(AlertDescription, { children: recording.consentNotice }) }) : null,
13171
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-actions", children: [
13172
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
13490
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin-actions", children: [
13491
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
13173
13492
  /* @__PURE__ */ jsx6(
13174
13493
  Checkbox,
13175
13494
  {
@@ -13180,7 +13499,7 @@ function PreJoinBody({
13180
13499
  ),
13181
13500
  /* @__PURE__ */ jsx6(Label, { htmlFor: "mx-meet-join-video", children: "Join with video" })
13182
13501
  ] }),
13183
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
13502
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
13184
13503
  /* @__PURE__ */ jsx6(
13185
13504
  Checkbox,
13186
13505
  {
@@ -13194,7 +13513,7 @@ function PreJoinBody({
13194
13513
  room.secondDevice === null ? /* @__PURE__ */ jsx6(Button, { type: "button", className: "mx-meet__join", disabled: joining, onClick: () => joinWith(), children: joining ? "Joining\u2026" : observe2 ? "Observe" : "Join now" }) : (
13195
13514
  // S7: ALREADY IN THIS MEETING on another tab or device — the meeting's choice
13196
13515
  // (Meet: Switch here / Join here too; Teams: Transfer here / Add this device).
13197
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__second-device", "data-meet-region": "second-device", children: [
13516
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__second-device", "data-meet-region": "second-device", children: [
13198
13517
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__hint", children: "You're in this meeting on another device" }),
13199
13518
  /* @__PURE__ */ jsx6(
13200
13519
  Button,
@@ -13221,23 +13540,29 @@ function PreJoinBody({
13221
13540
  ] })
13222
13541
  )
13223
13542
  ] }),
13224
- room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
13543
+ room.failure !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__error", children: [
13225
13544
  room.failure.message,
13226
13545
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: room.failure.remedy })
13227
13546
  ] }) : null
13228
13547
  ] })
13229
13548
  ] });
13230
13549
  }
13231
- function useCameraPreview(deviceId2, effects) {
13232
- const [preview, setPreview] = useState4(null);
13233
- const [error, setError] = useState4(null);
13550
+ function useCameraPreview(deviceId2, effects, report, attempt = 0) {
13551
+ const reportRef = useRef6(report);
13552
+ reportRef.current = report;
13553
+ const [preview, setPreview] = useState5(null);
13554
+ const [error, setError] = useState5(null);
13234
13555
  const current = useRef6(null);
13235
13556
  const initialEffect = useRef6(toVideoEffect(effects));
13236
13557
  initialEffect.current = toVideoEffect(effects);
13237
13558
  useEffect6(() => {
13238
- if (deviceId2 === void 0) return void 0;
13559
+ if (deviceId2 === void 0) {
13560
+ reportRef.current?.("off");
13561
+ return void 0;
13562
+ }
13239
13563
  let live = true;
13240
13564
  setError(null);
13565
+ reportRef.current?.("prompting");
13241
13566
  void createCameraPreview(deviceId2, initialEffect.current).then((created) => {
13242
13567
  if (!live) {
13243
13568
  created.stop();
@@ -13245,8 +13570,10 @@ function useCameraPreview(deviceId2, effects) {
13245
13570
  }
13246
13571
  current.current = created;
13247
13572
  setPreview(created);
13573
+ reportRef.current?.("on");
13248
13574
  }).catch((thrown) => {
13249
13575
  if (!live) return;
13576
+ reportRef.current?.({ error: thrown });
13250
13577
  const failure = thrown;
13251
13578
  const message = (failure.message ?? "").replace(/^meet\.[A-Za-z.()]+:\s*/, "");
13252
13579
  const sentence = message.length > 0 ? message.charAt(0).toUpperCase() + message.slice(1) : "";
@@ -13258,7 +13585,7 @@ function useCameraPreview(deviceId2, effects) {
13258
13585
  current.current = null;
13259
13586
  setPreview(null);
13260
13587
  };
13261
- }, [deviceId2]);
13588
+ }, [deviceId2, attempt]);
13262
13589
  return {
13263
13590
  preview,
13264
13591
  error,
@@ -13281,9 +13608,9 @@ function DevicePicker({
13281
13608
  const triggerId = `mx-meet-device-${kind}`;
13282
13609
  const valueOf = (deviceId2) => deviceId2.length > 0 ? deviceId2 : "default";
13283
13610
  const current = devices?.selected[kind] ?? host.devices.resolve(kind) ?? "";
13284
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
13611
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field", children: [
13285
13612
  /* @__PURE__ */ jsx6(Label, { htmlFor: triggerId, children: label }),
13286
- /* @__PURE__ */ jsxs3(
13613
+ /* @__PURE__ */ jsxs4(
13287
13614
  Select,
13288
13615
  {
13289
13616
  ...current.length > 0 ? { value: valueOf(current) } : {},
@@ -13370,19 +13697,19 @@ function MeetSkinRoom({
13370
13697
  if (screen === "refused" || screen === "exit") {
13371
13698
  return /* @__PURE__ */ jsx6("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx6(ExitScreen, { ...onLeave !== void 0 ? { onLeave } : {} }) });
13372
13699
  }
13373
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet", children: [
13700
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet", children: [
13374
13701
  /* @__PURE__ */ jsx6(ConsentNotice, {}),
13375
13702
  /* @__PURE__ */ jsx6(AttendanceNotice, {}),
13376
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__header", children: [
13703
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__header", children: [
13377
13704
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
13378
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
13705
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__meta", children: [
13379
13706
  participantSummary(snapshot?.participants ?? []),
13380
13707
  elapsed > 0 ? ` \xB7 ${formatDurationMs3(elapsed)}` : ""
13381
13708
  ] }),
13382
13709
  /* @__PURE__ */ jsx6(RecordingIndicator, {}),
13383
13710
  captureHeldOf(snapshot?.meeting) ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", "data-meet-capture-held": "", children: "Confidential \xB7 not recorded" }) : null,
13384
13711
  isObserverRole(snapshot?.grants.role) ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", "data-meet-observing": "self", children: "Observing" }) : null,
13385
- snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
13712
+ snapshot?.locked === true ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__badge", children: [
13386
13713
  /* @__PURE__ */ jsx6(LockIcon, { width: 12, height: 12 }),
13387
13714
  " Locked"
13388
13715
  ] }) : null,
@@ -13398,9 +13725,17 @@ function MeetSkinRoom({
13398
13725
  }
13399
13726
  function ShareNotice() {
13400
13727
  const { share, actions } = useMeetCore();
13728
+ const [soundHintClosed, setSoundHintClosed] = useState5(null);
13729
+ if (share.state === "presenting" && share.audio === false && soundHintClosed !== share.at) {
13730
+ return /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-audio-missing", children: [
13731
+ "Sound not shared",
13732
+ /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: "To include sound, share a tab and turn on Also share tab audio" }),
13733
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setSoundHintClosed(share.at), children: "Dismiss" })
13734
+ ] });
13735
+ }
13401
13736
  if (share.state !== "refused") return null;
13402
13737
  const text3 = 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";
13403
- return /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
13738
+ return /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
13404
13739
  text3,
13405
13740
  share.remedy !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: share.remedy }) : null,
13406
13741
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: actions.dismissShareNotice, children: "Dismiss" })
@@ -13428,7 +13763,7 @@ function clockText(ms2) {
13428
13763
  }
13429
13764
  function ExitScreen({ onLeave }) {
13430
13765
  const { phase, reason, host, snapshot, actions, call, connection } = useMeetCore();
13431
- const [busy, setBusy] = useState4(false);
13766
+ const [busy, setBusy] = useState5(false);
13432
13767
  const failure = snapshot?.failure ?? null;
13433
13768
  const retryLeft = useCountdown(phase === "refused:lobby_rejects" ? failure?.retryAt ?? null : null);
13434
13769
  const rejoin = /* @__PURE__ */ jsx6(
@@ -13469,7 +13804,7 @@ function ExitScreen({ onLeave }) {
13469
13804
  const code = phase.slice("refused:".length);
13470
13805
  title = REFUSED_TITLES[code] ?? "You can't join this meeting";
13471
13806
  line = code === "too_early" || code === "registration_required" || code === "cancelled" ? failure?.remedy ?? null : null;
13472
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
13807
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13473
13808
  /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", onClick: actions.retry, children: "Try again" }),
13474
13809
  home
13475
13810
  ] });
@@ -13480,7 +13815,7 @@ function ExitScreen({ onLeave }) {
13480
13815
  actionsNode = home;
13481
13816
  } else if (retryLeft === 0) {
13482
13817
  line = "You can ask to join again";
13483
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
13818
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13484
13819
  /* @__PURE__ */ jsx6(
13485
13820
  Button,
13486
13821
  {
@@ -13504,16 +13839,37 @@ function ExitScreen({ onLeave }) {
13504
13839
  switch (phase) {
13505
13840
  case "left":
13506
13841
  title = "You left the meeting";
13507
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
13842
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13508
13843
  rejoin,
13509
13844
  home
13510
13845
  ] });
13511
13846
  break;
13512
13847
  case "disconnected":
13848
+ if (failure?.stage === "join" && (failure.reason ?? null) === null) {
13849
+ title = "Can't connect to the meeting";
13850
+ line = connection === "offline" ? "You're offline. Check your internet connection." : "Check your network. A VPN, firewall or proxy may be blocking the call.";
13851
+ notice = "cannot-connect";
13852
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13853
+ /* @__PURE__ */ jsx6(
13854
+ Button,
13855
+ {
13856
+ type: "button",
13857
+ disabled: busy,
13858
+ onClick: () => {
13859
+ setBusy(true);
13860
+ void actions.rejoin().catch(() => void 0).finally(() => setBusy(false));
13861
+ },
13862
+ children: "Try again"
13863
+ }
13864
+ ),
13865
+ home
13866
+ ] });
13867
+ break;
13868
+ }
13513
13869
  title = "You lost your connection to the meeting";
13514
13870
  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.";
13515
13871
  notice = "disconnected";
13516
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
13872
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13517
13873
  rejoin,
13518
13874
  home
13519
13875
  ] });
@@ -13526,14 +13882,14 @@ function ExitScreen({ onLeave }) {
13526
13882
  title = "You joined from another tab or device";
13527
13883
  line = "This screen left the meeting so you aren't in it twice.";
13528
13884
  notice = "displaced";
13529
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
13885
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13530
13886
  rejoin,
13531
13887
  home
13532
13888
  ] });
13533
13889
  break;
13534
13890
  case "inactive":
13535
13891
  title = "You left the meeting because this tab was inactive";
13536
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
13892
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
13537
13893
  rejoin,
13538
13894
  home
13539
13895
  ] });
@@ -13556,7 +13912,7 @@ function ExitScreen({ onLeave }) {
13556
13912
  break;
13557
13913
  }
13558
13914
  }
13559
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", "data-meet-exit": phase, children: [
13915
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__waiting", "data-meet-exit": phase, children: [
13560
13916
  /* @__PURE__ */ jsx6(Avatar, { name: host?.identity.displayName ?? "", url: host?.identity.avatarUrl ?? null, size: 72 }),
13561
13917
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: title }),
13562
13918
  line !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: line }) : null,
@@ -13567,7 +13923,7 @@ function ExitScreen({ onLeave }) {
13567
13923
  function WaitingRoom({ host, onLeave }) {
13568
13924
  const { waiting, withdraw, askAgain } = useWaiting();
13569
13925
  const { phaseNotice } = useMeetCore();
13570
- const [busy, setBusy] = useState4(false);
13926
+ const [busy, setBusy] = useState5(false);
13571
13927
  const admission = waiting?.admission ?? "knocking";
13572
13928
  const reknockLeft = useCountdown(admission === "denied" ? waiting?.reknockAt ?? null : null);
13573
13929
  const run = (action) => () => {
@@ -13590,21 +13946,21 @@ function WaitingRoom({ host, onLeave }) {
13590
13946
  line = `You can ask again in ${clockText(reknockLeft)}`;
13591
13947
  cooldownNotice = true;
13592
13948
  }
13593
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
13949
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
13594
13950
  waiting?.reknockAllowed === true || waiting?.reknockAt != null && reknockLeft === 0 ? /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Ask to join again" }) : null,
13595
13951
  home
13596
13952
  ] });
13597
13953
  break;
13598
13954
  case "expired":
13599
13955
  title = "No one responded";
13600
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
13956
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
13601
13957
  /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Ask again" }),
13602
13958
  home
13603
13959
  ] });
13604
13960
  break;
13605
13961
  case "withdrawn":
13606
13962
  title = "You left the waiting room";
13607
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
13963
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
13608
13964
  /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Rejoin" }),
13609
13965
  home
13610
13966
  ] });
@@ -13618,7 +13974,7 @@ function WaitingRoom({ host, onLeave }) {
13618
13974
  line = waiting?.admittersPresent === false ? "The host isn't here yet" : null;
13619
13975
  actions = /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", disabled: busy, onClick: run(withdraw), children: "Cancel request" });
13620
13976
  }
13621
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", children: [
13977
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__waiting", children: [
13622
13978
  /* @__PURE__ */ jsx6(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
13623
13979
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: title }),
13624
13980
  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,
@@ -13638,9 +13994,9 @@ function HostMenu() {
13638
13994
  const host = useRequiredMeetHost();
13639
13995
  const snapshot = useMeetSnapshot();
13640
13996
  const end = useEndMeeting();
13641
- const [confirmingEnd, setConfirmingEnd] = useState4(false);
13997
+ const [confirmingEnd, setConfirmingEnd] = useState5(false);
13642
13998
  const locked = snapshot?.locked === true;
13643
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
13999
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__host-menu", children: [
13644
14000
  /* @__PURE__ */ jsx6(
13645
14001
  "button",
13646
14002
  {
@@ -13652,7 +14008,7 @@ function HostMenu() {
13652
14008
  children: locked ? "Unlock meeting" : "Lock meeting"
13653
14009
  }
13654
14010
  ),
13655
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
14011
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
13656
14012
  /* @__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." }),
13657
14013
  /* @__PURE__ */ jsx6(
13658
14014
  "button",
@@ -13708,9 +14064,9 @@ function GuestRecordAccessControl({
13708
14064
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
13709
14065
  if (host === null || !isHost) return null;
13710
14066
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
13711
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
14067
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
13712
14068
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
13713
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
14069
+ /* @__PURE__ */ jsxs4("label", { className: "mx-meet__field", children: [
13714
14070
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
13715
14071
  /* @__PURE__ */ jsx6(
13716
14072
  "select",
@@ -13727,12 +14083,12 @@ function GuestRecordAccessControl({
13727
14083
  }
13728
14084
  )
13729
14085
  ] }),
13730
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
14086
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
13731
14087
  guestRecordAccessExplanation(access.setting),
13732
14088
  resolved
13733
14089
  ] }),
13734
14090
  access.saving ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
13735
- access.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
14091
+ access.error !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
13736
14092
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
13737
14093
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
13738
14094
  ] }) : null
@@ -13740,9 +14096,9 @@ function GuestRecordAccessControl({
13740
14096
  }
13741
14097
 
13742
14098
  // src/react/record.tsx
13743
- import { useEffect as useEffect7, useState as useState5 } from "react";
14099
+ import { useEffect as useEffect7, useState as useState6 } from "react";
13744
14100
  import { ErrorBox as ErrorBox2 } from "@ai-matrx/design-system";
13745
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
14101
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
13746
14102
  function MeetingRecordView({
13747
14103
  meeting,
13748
14104
  onRejoin
@@ -13759,17 +14115,17 @@ function MeetingRecordBody({
13759
14115
  }) {
13760
14116
  const host = useRequiredMeetHost();
13761
14117
  const record = useMeetingRecord(meeting);
13762
- const [question, setQuestion] = useState5("");
13763
- const [tab, setTab] = useState5("summary");
14118
+ const [question, setQuestion] = useState6("");
14119
+ const [tab, setTab] = useState6("summary");
13764
14120
  if (record.failure !== null) {
13765
- return /* @__PURE__ */ jsx7("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs4(ErrorBox2, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
14121
+ return /* @__PURE__ */ jsx7("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs5(ErrorBox2, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
13766
14122
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
13767
14123
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__empty-body", children: record.failure.message }),
13768
14124
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
13769
14125
  ] }) });
13770
14126
  }
13771
14127
  if (record.loading || record.record === null) {
13772
- return /* @__PURE__ */ jsx7("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__empty", role: "status", children: [
14128
+ return /* @__PURE__ */ jsx7("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs5("div", { className: "mx-meet__empty", role: "status", children: [
13773
14129
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
13774
14130
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
13775
14131
  ] }) });
@@ -13790,29 +14146,29 @@ function MeetingRecordBody({
13790
14146
  );
13791
14147
  const entirelyRestricted = everyRecordPartRefused && bundle.attendees.length === 0 && bundle.liveNotes.length === 0 && bundle.transcript.length === 0 && bundle.recording === null && bundle.summary === null && bundle.decisions.length === 0 && bundle.actionItems.length === 0;
13792
14148
  if (entirelyRestricted) {
13793
- return /* @__PURE__ */ jsxs4("div", { className: "mx-meet mx-meet--record", children: [
13794
- /* @__PURE__ */ jsx7("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-head-inner", children: [
14149
+ return /* @__PURE__ */ jsxs5("div", { className: "mx-meet mx-meet--record", children: [
14150
+ /* @__PURE__ */ jsx7("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-head-inner", children: [
13795
14151
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
13796
14152
  /* @__PURE__ */ jsx7("h1", { className: "mx-meet__record-title", children: meeting.title }),
13797
14153
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
13798
14154
  onRejoin !== void 0 ? /* @__PURE__ */ jsx7("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
13799
14155
  ] }) }),
13800
- /* @__PURE__ */ jsx7("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-access", role: "status", children: [
14156
+ /* @__PURE__ */ jsx7("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-access", role: "status", children: [
13801
14157
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-access-title", children: "About this record" }),
13802
14158
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-access-message", children: notice2.message }),
13803
14159
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
13804
14160
  ] }, notice2.parts.join("-"))) })
13805
14161
  ] });
13806
14162
  }
13807
- return /* @__PURE__ */ jsxs4("div", { className: "mx-meet mx-meet--record", children: [
13808
- /* @__PURE__ */ jsx7("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-head-inner", children: [
14163
+ return /* @__PURE__ */ jsxs5("div", { className: "mx-meet mx-meet--record", children: [
14164
+ /* @__PURE__ */ jsx7("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-head-inner", children: [
13809
14165
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
13810
14166
  /* @__PURE__ */ jsx7("h1", { className: "mx-meet__record-title", children: meeting.title }),
13811
14167
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
13812
14168
  onRejoin !== void 0 ? /* @__PURE__ */ jsx7("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
13813
14169
  ] }) }),
13814
- /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-body", children: [
13815
- restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-access", role: "status", children: [
14170
+ /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-body", children: [
14171
+ restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-access", role: "status", children: [
13816
14172
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-access-title", children: "About this record" }),
13817
14173
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-access-message", children: notice2.message }),
13818
14174
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
@@ -13820,13 +14176,13 @@ function MeetingRecordBody({
13820
14176
  attended.length === 0 ? (
13821
14177
  /* NOT SILENCE. A refused attendance read used to remove the whole
13822
14178
  section, so the reader could not tell "nobody" from "not shown". */
13823
- /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
14179
+ /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
13824
14180
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
13825
14181
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
13826
14182
  ] })
13827
- ) : /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
14183
+ ) : /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
13828
14184
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
13829
- /* @__PURE__ */ jsx7("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__record-attendee", children: [
14185
+ /* @__PURE__ */ jsx7("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs5("li", { className: "mx-meet__record-attendee", children: [
13830
14186
  /* @__PURE__ */ jsx7(
13831
14187
  Avatar,
13832
14188
  {
@@ -13835,7 +14191,7 @@ function MeetingRecordBody({
13835
14191
  size: 28
13836
14192
  }
13837
14193
  ),
13838
- /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
14194
+ /* @__PURE__ */ jsxs5("span", { className: "mx-meet__person-name", children: [
13839
14195
  displayNameFor(bundle.names, person.identity, person.displayName),
13840
14196
  person.role === "host" ? /* @__PURE__ */ jsx7("span", { className: "mx-meet__badge", children: "Host" }) : null,
13841
14197
  person.userId === null && !person.isAgent ? /* @__PURE__ */ jsx7("span", { className: "mx-meet__badge", children: "Guest" }) : null,
@@ -13843,17 +14199,17 @@ function MeetingRecordBody({
13843
14199
  ] })
13844
14200
  ] }, person.id)) })
13845
14201
  ] }),
13846
- bundle.recording !== null ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
14202
+ bundle.recording !== null ? /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
13847
14203
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
13848
- fileId !== null ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
14204
+ fileId !== null ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
13849
14205
  /* @__PURE__ */ jsx7(RecordingPlayer, { fileId }),
13850
14206
  notice !== null ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: notice }) : null
13851
14207
  ] }) : /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
13852
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
14208
+ ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
13853
14209
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
13854
14210
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
13855
14211
  ] }) : null,
13856
- /* @__PURE__ */ jsxs4("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
14212
+ /* @__PURE__ */ jsxs5("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
13857
14213
  /* @__PURE__ */ jsx7(
13858
14214
  "button",
13859
14215
  {
@@ -13885,10 +14241,10 @@ function MeetingRecordBody({
13885
14241
  }
13886
14242
  )
13887
14243
  ] }),
13888
- tab === "summary" ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
13889
- /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
14244
+ tab === "summary" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
14245
+ /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
13890
14246
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
13891
- wrapUp.state === "written" ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__panel-note", role: "status", children: [
14247
+ wrapUp.state === "written" ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs5("div", { className: "mx-meet__panel-note", role: "status", children: [
13892
14248
  /* @__PURE__ */ jsx7("p", { children: wrapUp.message }),
13893
14249
  /* @__PURE__ */ jsx7("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
13894
14250
  ] }) : /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
@@ -13918,22 +14274,22 @@ function MeetingRecordBody({
13918
14274
  }
13919
14275
  )
13920
14276
  ] }) : null,
13921
- tab === "notes" ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
14277
+ tab === "notes" ? /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
13922
14278
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
13923
14279
  bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: absenceSentence(
13924
14280
  bundle,
13925
14281
  "notes",
13926
14282
  "No live notes are available for this meeting."
13927
- ) }) : /* @__PURE__ */ jsx7("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__note", children: [
13928
- note.window !== null ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__badge", children: [
14283
+ ) }) : /* @__PURE__ */ jsx7("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs5("li", { className: "mx-meet__note", children: [
14284
+ note.window !== null ? /* @__PURE__ */ jsxs5("span", { className: "mx-meet__badge", children: [
13929
14285
  "Window ",
13930
14286
  note.window
13931
14287
  ] }) : null,
13932
14288
  note.text
13933
14289
  ] }, note.id)) })
13934
14290
  ] }) : null,
13935
- tab === "transcript" ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
13936
- /* @__PURE__ */ jsxs4("h2", { className: "mx-meet__record-section-title", children: [
14291
+ tab === "transcript" ? /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
14292
+ /* @__PURE__ */ jsxs5("h2", { className: "mx-meet__record-section-title", children: [
13937
14293
  "Transcript",
13938
14294
  /* @__PURE__ */ jsx7("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
13939
14295
  ] }),
@@ -13941,8 +14297,8 @@ function MeetingRecordBody({
13941
14297
  bundle,
13942
14298
  "transcript",
13943
14299
  "No transcript is available for this meeting."
13944
- ) }) : /* @__PURE__ */ jsx7("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__record-block", children: [
13945
- /* @__PURE__ */ jsxs4("p", { className: "mx-meet__record-speaker", children: [
14300
+ ) }) : /* @__PURE__ */ jsx7("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs5("li", { className: "mx-meet__record-block", children: [
14301
+ /* @__PURE__ */ jsxs5("p", { className: "mx-meet__record-speaker", children: [
13946
14302
  block.speaker,
13947
14303
  /* @__PURE__ */ jsx7("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
13948
14304
  ] }),
@@ -13950,10 +14306,10 @@ function MeetingRecordBody({
13950
14306
  ] }, block.id)) })
13951
14307
  ] }) : null,
13952
14308
  /* @__PURE__ */ jsx7(GuestRecordAccessControl, { meeting }),
13953
- /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
14309
+ /* @__PURE__ */ jsxs5("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
13954
14310
  /* @__PURE__ */ jsx7("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
13955
- guestFinishedMeeting ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
13956
- /* @__PURE__ */ jsxs4(
14311
+ guestFinishedMeeting ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
14312
+ /* @__PURE__ */ jsxs5(
13957
14313
  "form",
13958
14314
  {
13959
14315
  className: "mx-meet__composer",
@@ -13987,7 +14343,7 @@ function MeetingRecordBody({
13987
14343
  }
13988
14344
  ),
13989
14345
  record.answer !== null ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__answer", children: record.answer }) : null,
13990
- record.coverage !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__coverage", children: [
14346
+ record.coverage !== null ? /* @__PURE__ */ jsxs5("p", { className: "mx-meet__coverage", children: [
13991
14347
  "Answered from ",
13992
14348
  record.coverage.segmentsUsed,
13993
14349
  " of ",
@@ -13998,7 +14354,7 @@ function MeetingRecordBody({
13998
14354
  record.coverage.truncated ? " (the oldest were left out)" : "",
13999
14355
  "."
14000
14356
  ] }) : null,
14001
- record.askError !== null ? /* @__PURE__ */ jsxs4(ErrorBox2, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
14357
+ record.askError !== null ? /* @__PURE__ */ jsxs5(ErrorBox2, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
14002
14358
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
14003
14359
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
14004
14360
  ] }) : null
@@ -14015,16 +14371,16 @@ function RecordingPlayer(props) {
14015
14371
  return /* @__PURE__ */ jsx7(RecordingPlayerBody, { ...props, host });
14016
14372
  }
14017
14373
  function RecordingPlayerBody({ fileId, host }) {
14018
- const [media, setMedia] = useState5(null);
14019
- const [loading, setLoading] = useState5(false);
14020
- const [error, setError] = useState5(null);
14374
+ const [media, setMedia] = useState6(null);
14375
+ const [loading, setLoading] = useState6(false);
14376
+ const [error, setError] = useState6(null);
14021
14377
  useEffect7(() => {
14022
14378
  if (media === null || media.kind !== "bytes") return void 0;
14023
14379
  const url = media.url;
14024
14380
  return () => URL.revokeObjectURL(url);
14025
14381
  }, [media]);
14026
14382
  if (media !== null) {
14027
- return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-section", children: [
14383
+ return /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-section", children: [
14028
14384
  /* @__PURE__ */ jsx7(
14029
14385
  "video",
14030
14386
  {
@@ -14070,8 +14426,8 @@ function RecordingPlayerBody({ fileId, host }) {
14070
14426
  media.fallbackReason !== null ? /* @__PURE__ */ jsx7("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
14071
14427
  ] });
14072
14428
  }
14073
- return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-section", children: [
14074
- error !== null ? /* @__PURE__ */ jsxs4(ErrorBox2, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
14429
+ return /* @__PURE__ */ jsxs5("div", { className: "mx-meet__record-section", children: [
14430
+ error !== null ? /* @__PURE__ */ jsxs5(ErrorBox2, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
14075
14431
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__refusal-reason", children: error.message }),
14076
14432
  /* @__PURE__ */ jsx7("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
14077
14433
  ] }) : null,
@@ -14197,7 +14553,7 @@ function linkRunWords(run) {
14197
14553
 
14198
14554
  // src/react/calls-ui.tsx
14199
14555
  import { useEffect as useEffect9 } from "react";
14200
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
14556
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
14201
14557
  function IncomingCallHost() {
14202
14558
  const calls = useCalls();
14203
14559
  const { call, phase, actions } = useMeetCore();
@@ -14211,9 +14567,9 @@ function IncomingCallHost() {
14211
14567
  return () => clearTimeout(timer);
14212
14568
  }, [outcome, actions]);
14213
14569
  const inCall = call !== null && (phase === "joining" || phase === "in_call" || phase === "disconnected" || phase === "removed" || phase === "superseded");
14214
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
14570
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
14215
14571
  inCall && call !== null ? /* @__PURE__ */ jsx9("div", { className: "mx-meet__call-overlay", "data-meet-call": call.invite.id, children: /* @__PURE__ */ jsx9(MeetRoot, { children: /* @__PURE__ */ jsx9(MeetSkinRoom, { roomName: call.invite.roomName, onLeave: actions.dismissCall }) }) }) : null,
14216
- calls.incoming.length > 0 || call !== null && (phase === "ringing_out" || outcome) ? /* @__PURE__ */ jsxs5("div", { className: "mx-meet__ringing-stack", children: [
14572
+ calls.incoming.length > 0 || call !== null && (phase === "ringing_out" || outcome) ? /* @__PURE__ */ jsxs6("div", { className: "mx-meet__ringing-stack", children: [
14217
14573
  call !== null && phase === "ringing_out" ? /* @__PURE__ */ jsx9(OutgoingCallCard, { invite: call.invite }) : null,
14218
14574
  outcome && call !== null ? /* @__PURE__ */ jsx9(CallOutcomeCard, { invite: call.invite }) : null,
14219
14575
  calls.incoming.map((invite) => /* @__PURE__ */ jsx9(IncomingCallCard, { invite }, invite.id))
@@ -14222,9 +14578,9 @@ function IncomingCallHost() {
14222
14578
  }
14223
14579
  function OutgoingCallCard({ invite }) {
14224
14580
  const calls = useCalls();
14225
- return /* @__PURE__ */ jsxs5("section", { className: "mx-meet__ringing", role: "status", "aria-label": "Calling", "data-meet-notice": "ringing-out", children: [
14581
+ return /* @__PURE__ */ jsxs6("section", { className: "mx-meet__ringing", role: "status", "aria-label": "Calling", "data-meet-notice": "ringing-out", children: [
14226
14582
  /* @__PURE__ */ jsx9(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
14227
- /* @__PURE__ */ jsxs5("div", { className: "mx-meet__ringing-text", children: [
14583
+ /* @__PURE__ */ jsxs6("div", { className: "mx-meet__ringing-text", children: [
14228
14584
  /* @__PURE__ */ jsx9("strong", { children: "Calling\u2026" }),
14229
14585
  /* @__PURE__ */ jsx9("span", { children: invite.mode === "video" ? "Video call" : "Voice call" })
14230
14586
  ] }),
@@ -14235,20 +14591,20 @@ function CallOutcomeCard({ invite }) {
14235
14591
  const { phase, actions, call } = useMeetCore();
14236
14592
  const outgoing = call?.direction === "outgoing";
14237
14593
  const text3 = phase === "call_declined" ? "Call declined" : phase === "call_busy" ? "They're on another call" : phase === "answered_elsewhere" ? "Answered on another device" : outgoing ? "No answer" : `Missed call from ${invite.callerName}`;
14238
- return /* @__PURE__ */ jsxs5("section", { className: "mx-meet__ringing", role: "status", "aria-label": text3, "data-meet-call-outcome": phase, children: [
14594
+ return /* @__PURE__ */ jsxs6("section", { className: "mx-meet__ringing", role: "status", "aria-label": text3, "data-meet-call-outcome": phase, children: [
14239
14595
  /* @__PURE__ */ jsx9("div", { className: "mx-meet__ringing-text", children: /* @__PURE__ */ jsx9("strong", { children: text3 }) }),
14240
14596
  /* @__PURE__ */ jsx9("div", { className: "mx-meet__ringing-actions", children: /* @__PURE__ */ jsx9(ControlButton, { label: "Close", onClick: actions.dismissCall, children: /* @__PURE__ */ jsx9(PhoneOffIcon, {}) }) })
14241
14597
  ] });
14242
14598
  }
14243
14599
  function IncomingCallCard({ invite }) {
14244
14600
  const calls = useCalls();
14245
- return /* @__PURE__ */ jsxs5("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
14601
+ return /* @__PURE__ */ jsxs6("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
14246
14602
  /* @__PURE__ */ jsx9(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
14247
- /* @__PURE__ */ jsxs5("div", { className: "mx-meet__ringing-text", children: [
14603
+ /* @__PURE__ */ jsxs6("div", { className: "mx-meet__ringing-text", children: [
14248
14604
  /* @__PURE__ */ jsx9("strong", { children: invite.callerName }),
14249
14605
  /* @__PURE__ */ jsx9("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
14250
14606
  ] }),
14251
- /* @__PURE__ */ jsxs5("div", { className: "mx-meet__ringing-actions", children: [
14607
+ /* @__PURE__ */ jsxs6("div", { className: "mx-meet__ringing-actions", children: [
14252
14608
  /* @__PURE__ */ jsx9(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx9(PhoneOffIcon, {}) }),
14253
14609
  invite.mode === "video" ? /* @__PURE__ */ jsx9(
14254
14610
  ControlButton,
@@ -14540,6 +14896,7 @@ export {
14540
14896
  createReconnectPolicy,
14541
14897
  createRecordingController,
14542
14898
  createRoomEngine,
14899
+ createSpeakingWhileMutedDetector,
14543
14900
  createTokenClient,
14544
14901
  createWebDeviceStorage,
14545
14902
  createWebEffectsStorage,
@@ -14548,6 +14905,7 @@ export {
14548
14905
  createWebRoomTokenStorage,
14549
14906
  defaultCaptionLanguage,
14550
14907
  detectBrowser,
14908
+ detectCapabilities,
14551
14909
  detectOs,
14552
14910
  deviceChipLabel,
14553
14911
  deviceFixSteps,
@@ -14572,6 +14930,7 @@ export {
14572
14930
  isLinkFollower,
14573
14931
  isListenOnly,
14574
14932
  isLivePhase,
14933
+ isMobileUserAgent,
14575
14934
  isNoteTaker,
14576
14935
  isObserverRole,
14577
14936
  isRealName,
@@ -14664,6 +15023,7 @@ export {
14664
15023
  transcriptDocument,
14665
15024
  unavailableFrom,
14666
15025
  uniqueAttendees,
15026
+ unsupportedWords,
14667
15027
  untranslatedLines,
14668
15028
  useActivityAttention,
14669
15029
  useAudioLevel,