@burdenoff/fe-libs 2026.927.3 → 2026.928.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/chrome/SideNavigation.d.ts.map +1 -1
  2. package/dist/chrome/SideNavigation.js +71 -68
  3. package/dist/chrome/sideNavigation/sideNavEscape.d.ts +41 -0
  4. package/dist/chrome/sideNavigation/sideNavEscape.d.ts.map +1 -0
  5. package/dist/chrome/sideNavigation/sideNavEscape.js +8 -0
  6. package/dist/chrome/sideNavigation/useSideNavigationState.d.ts +8 -1
  7. package/dist/chrome/sideNavigation/useSideNavigationState.d.ts.map +1 -1
  8. package/dist/chrome/sideNavigation/useSideNavigationState.js +35 -23
  9. package/dist/shared/assistant/index.d.ts +1 -0
  10. package/dist/shared/assistant/index.d.ts.map +1 -1
  11. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  12. package/dist/shared/assistant/ui/AIAssistantPanel.js +82 -79
  13. package/dist/shared/assistant/ui/AssistantOverlay.d.ts.map +1 -1
  14. package/dist/shared/assistant/ui/AssistantOverlay.js +98 -96
  15. package/dist/shared/assistant/ui/assistantOverlayState.d.ts +31 -8
  16. package/dist/shared/assistant/ui/assistantOverlayState.d.ts.map +1 -1
  17. package/dist/shared/assistant/ui/assistantOverlayState.js +22 -16
  18. package/dist/shared/assistant/ui/panelOverlays.d.ts +31 -0
  19. package/dist/shared/assistant/ui/panelOverlays.d.ts.map +1 -1
  20. package/dist/shared/assistant/ui/panelOverlays.js +11 -8
  21. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  22. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +82 -72
  23. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -1
  24. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +40 -39
  25. package/dist/shared/assistant/ui/voice/voiceSessionEscape.d.ts +57 -0
  26. package/dist/shared/assistant/ui/voice/voiceSessionEscape.d.ts.map +1 -0
  27. package/dist/shared/assistant/ui/voice/voiceSessionEscape.js +19 -0
  28. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts +3 -1
  29. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts.map +1 -1
  30. package/dist/shared/assistant/useAssistantKeyboardShortcuts.js +25 -25
  31. package/dist/shared/hooks/index.d.ts +1 -0
  32. package/dist/shared/hooks/index.d.ts.map +1 -1
  33. package/dist/shared/hooks/useReturnFocus.d.ts +56 -0
  34. package/dist/shared/hooks/useReturnFocus.d.ts.map +1 -0
  35. package/dist/shared/hooks/useReturnFocus.js +41 -0
  36. package/dist/shared/providers/AppShellProvider.d.ts +12 -1
  37. package/dist/shared/providers/AppShellProvider.d.ts.map +1 -1
  38. package/dist/shared/providers/AppShellProvider.js +175 -161
  39. package/dist/shared-assistant.js +76 -75
  40. package/dist/shared-hooks.js +34 -33
  41. package/dist/shared.js +89 -88
  42. package/dist/ui/modal-shell.d.ts.map +1 -1
  43. package/dist/ui/modal-shell.js +23 -13
  44. package/package.json +1 -1
@@ -1,25 +1,28 @@
1
- import { useAssistantTr as e } from "../../i18n.js";
2
- import { micIsInterrupt as t, showsAssistantCaption as n, voiceStageState as r } from "../../voice/voiceStageState.js";
3
- import { VOICE_THINKING_LABEL as i, composeVoiceStatus as ee, voiceStatusSuffix as te } from "../../voice/voiceStatus.js";
4
- import { spokenSoFar as a } from "../../voice/voiceSession.js";
5
- import { AssistantAttachmentButton as o } from "../composer/AssistantAttachmentButton.js";
6
- import { AssistantAttachmentChips as ne } from "../composer/AssistantAttachmentChips.js";
7
- import { AssistantVoiceOrb as s } from "./AssistantVoiceOrb.js";
8
- import { VoiceMiniController as c } from "./VoiceMiniController.js";
9
- import { VoiceStage as l } from "./VoiceStage.js";
10
- import { VoiceTranscriptDrawer as u } from "./VoiceTranscriptDrawer.js";
1
+ import { useReturnFocus as e } from "../../../hooks/useReturnFocus.js";
2
+ import { useAssistantTr as t } from "../../i18n.js";
3
+ import { micIsInterrupt as n, showsAssistantCaption as r, voiceStageState as i } from "../../voice/voiceStageState.js";
4
+ import { VOICE_THINKING_LABEL as a, composeVoiceStatus as ee, voiceStatusSuffix as te } from "../../voice/voiceStatus.js";
5
+ import { spokenSoFar as o } from "../../voice/voiceSession.js";
6
+ import { ASSISTANT_PANEL_ATTR as ne, ASSISTANT_VOICE_SESSION_ATTR as s } from "../panelOverlays.js";
7
+ import { AssistantAttachmentButton as c } from "../composer/AssistantAttachmentButton.js";
8
+ import { AssistantAttachmentChips as l } from "../composer/AssistantAttachmentChips.js";
9
+ import { AssistantVoiceOrb as u } from "./AssistantVoiceOrb.js";
10
+ import { VoiceMiniController as re } from "./VoiceMiniController.js";
11
+ import { VoiceStage as ie } from "./VoiceStage.js";
12
+ import { VoiceTranscriptDrawer as ae } from "./VoiceTranscriptDrawer.js";
13
+ import { escapeBelongsToLayerAbove as oe, voiceSessionEscapeAction as se } from "./voiceSessionEscape.js";
11
14
  import { useCallback as d, useEffect as f, useRef as p, useState as m } from "react";
12
- import { Maximize2 as re, Minimize2 as h, ScrollText as g, X as _ } from "lucide-react";
13
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
15
+ import { Maximize2 as ce, Minimize2 as le, ScrollText as ue, X as de } from "lucide-react";
16
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
14
17
  //#region src/shared/assistant/ui/voice/AssistantVoiceSession.tsx
15
- var b = ({ session: b, turns: oe = [], onSaveTranscript: se, onContinueInChat: ce, notice: x = null, spoken: S, onInterrupt: C, onToggleMute: w, attachments: T = [], onAttachFiles: E, onRemoveAttachment: le, onRetryAttachment: ue, canAttachMore: de = !0, preparingAttachments: D = 0, spokenChunks: O = null, onEnd: k, capturing: A = !0, interrupting: fe = !1, awaitingEndpoint: pe = !1 }) => {
16
- let j = e(), { muted: M, error: N } = b, P = p(null), F = p(null), [I, L] = m("mini"), R = I === "full", z = I === "mini", B = I === "mini" ? "panel" : I === "panel" ? "full" : "mini", [V, H] = m(!1), U = p(!1), W = p(w);
17
- W.current = w;
18
+ var _ = ({ session: _, turns: fe = [], onSaveTranscript: pe, onContinueInChat: me, notice: b = null, spoken: x, onInterrupt: he, onToggleMute: S, attachments: C = [], onAttachFiles: w, onRemoveAttachment: ge, onRetryAttachment: _e, canAttachMore: ve = !0, preparingAttachments: T = 0, spokenChunks: E = null, onEnd: D, capturing: O = !0, interrupting: k = !1, awaitingEndpoint: A = !1 }) => {
19
+ let j = t(), { muted: M, error: N } = _, P = p(null), F = p(null), [I, L] = m("mini"), R = I === "full", z = I === "mini", B = I === "mini" ? "panel" : I === "panel" ? "full" : "mini", [V, H] = m(!1), U = p(!1), W = p(S);
20
+ W.current = S;
18
21
  let G = d(() => {
19
- b.phase === "listening" && (M || U.current || a(b) || (U.current = !0, W.current()));
20
- }, [M, b]), K = d(() => {
22
+ _.phase === "listening" && (M || U.current || o(_) || (U.current = !0, W.current()));
23
+ }, [M, _]), K = d(() => {
21
24
  U.current && (U.current = !1, W.current());
22
- }, []), me = G;
25
+ }, []), ye = G;
23
26
  f(() => {
24
27
  let e = () => {
25
28
  document.visibilityState === "hidden" ? G() : K();
@@ -32,14 +35,20 @@ var b = ({ session: b, turns: oe = [], onSaveTranscript: se, onContinueInChat: c
32
35
  };
33
36
  }, []), f(() => {
34
37
  P.current?.focus();
35
- }, []), f(() => {
38
+ }, []), e(F, { fallbackSelector: `[${ne}]` }), f(() => {
36
39
  let e = (e) => {
37
40
  if (e.key === "Escape") {
38
- if (V) {
39
- H(!1);
40
- return;
41
- }
42
- k();
41
+ let t = se({
42
+ defaultPrevented: e.defaultPrevented,
43
+ layerAbove: oe({
44
+ target: e.target,
45
+ session: F.current,
46
+ doc: document
47
+ }),
48
+ transcriptOpen: V
49
+ });
50
+ if (t === "ignore") return;
51
+ e.preventDefault(), t === "close-transcript" ? H(!1) : D();
43
52
  return;
44
53
  }
45
54
  if (e.key !== "Tab" || !R) return;
@@ -50,21 +59,21 @@ var b = ({ session: b, turns: oe = [], onSaveTranscript: se, onContinueInChat: c
50
59
  };
51
60
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
52
61
  }, [
53
- k,
62
+ D,
54
63
  R,
55
64
  V
56
65
  ]);
57
- let q = x !== null && N === null, J = a(b), Y = r({
58
- snapshot: b,
59
- capturing: A,
60
- interrupting: fe,
61
- awaitingEndpoint: pe
66
+ let q = b !== null && N === null, J = o(_), Y = i({
67
+ snapshot: _,
68
+ capturing: O,
69
+ interrupting: k,
70
+ awaitingEndpoint: A
62
71
  }), X = (() => {
63
72
  switch (Y) {
64
73
  case "connecting": return j("voiceSession.connecting", "Starting the microphone…");
65
74
  case "endpoint-grace": return j("voiceSession.endpointGrace", "Still listening — take your time");
66
75
  case "interrupting": return j("voiceSession.interrupting", "Stopped — go ahead");
67
- case "thinking": return j(i.key, i.fallback);
76
+ case "thinking": return j(a.key, a.fallback);
68
77
  case "speaking": return j("voiceSession.speaking", "Speaking — tap to stop");
69
78
  case "mic-error":
70
79
  case "ended": return "";
@@ -77,59 +86,60 @@ var b = ({ session: b, turns: oe = [], onSaveTranscript: se, onContinueInChat: c
77
86
  muted: M,
78
87
  label: X
79
88
  }), Q = ee(X, Z), $ = Y === "thinking";
80
- return /* @__PURE__ */ y("div", {
89
+ return /* @__PURE__ */ g("div", {
81
90
  ref: F,
82
91
  className: `flex flex-col items-center justify-between bg-bg-sunken ${I === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : I === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
83
92
  role: "dialog",
84
93
  "aria-modal": R || void 0,
85
94
  "aria-label": j("voiceSession.title", "Voice conversation"),
86
95
  "data-testid": "assistant-voice-session",
96
+ [s]: "",
87
97
  children: [
88
- /* @__PURE__ */ y("button", {
98
+ /* @__PURE__ */ g("button", {
89
99
  ref: P,
90
100
  type: "button",
91
- onClick: k,
101
+ onClick: D,
92
102
  className: `absolute ${R ? "right-6 top-6 h-14 gap-2 px-5 text-base" : z ? "right-12 top-2 h-8 gap-1.5 px-2.5 text-xs" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
93
103
  title: j("voiceSession.end", "End the voice conversation"),
94
104
  "data-testid": "assistant-voice-end",
95
- children: [/* @__PURE__ */ v(_, {
105
+ children: [/* @__PURE__ */ h(de, {
96
106
  className: R ? "size-6" : z ? "size-4" : "size-5",
97
107
  "aria-hidden": "true"
98
- }), /* @__PURE__ */ v("span", {
108
+ }), /* @__PURE__ */ h("span", {
99
109
  className: `truncate whitespace-nowrap font-medium ${z ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
100
110
  children: j("voiceSession.endShort", "End")
101
111
  })]
102
112
  }),
103
- /* @__PURE__ */ v("div", {
113
+ /* @__PURE__ */ h("div", {
104
114
  className: `flex flex-col items-center ${z ? "px-3" : `min-h-[1.5rem] ${q ? R ? "pt-14" : "pt-10" : ""}`}`,
105
- children: q ? /* @__PURE__ */ v("p", {
115
+ children: q ? /* @__PURE__ */ h("p", {
106
116
  className: "max-w-xs text-center text-xs text-status-warning",
107
117
  "data-testid": "assistant-voice-notice",
108
- children: ie(x, j)
118
+ children: v(b, j)
109
119
  }) : null
110
120
  }),
111
121
  (() => {
112
- let e = /* @__PURE__ */ v(s, {
113
- session: b,
122
+ let e = /* @__PURE__ */ h(u, {
123
+ session: _,
114
124
  compact: z,
115
125
  connecting: Y === "connecting",
116
- onPress: t(Y) ? C : w,
117
- label: t(Y) ? j("voiceSession.interrupt", "Stop the assistant and speak") : M ? j("voiceSession.unmute", "Turn the microphone on") : j("voiceSession.mute", "Turn the microphone off")
118
- }), r = n(Y) ? S : J || null, i = N === null ? null : ae(N, j);
119
- return z ? /* @__PURE__ */ v(c, {
120
- spokenChunks: O,
126
+ onPress: n(Y) ? he : S,
127
+ label: n(Y) ? j("voiceSession.interrupt", "Stop the assistant and speak") : M ? j("voiceSession.unmute", "Turn the microphone on") : j("voiceSession.mute", "Turn the microphone off")
128
+ }), t = r(Y) ? x : J || null, i = N === null ? null : y(N, j);
129
+ return z ? /* @__PURE__ */ h(re, {
130
+ spokenChunks: E,
121
131
  state: Y,
122
- caption: r,
132
+ caption: t,
123
133
  statusText: Q,
124
134
  statusSuffix: Z,
125
135
  rotateStatus: $,
126
136
  errorText: i,
127
137
  control: e
128
- }) : /* @__PURE__ */ v(l, {
138
+ }) : /* @__PURE__ */ h(ie, {
129
139
  state: Y,
130
140
  userCaption: J || null,
131
- spokenChunks: O,
132
- assistantCaption: S,
141
+ spokenChunks: E,
142
+ assistantCaption: x,
133
143
  expanded: R,
134
144
  statusText: Q,
135
145
  statusSuffix: Z,
@@ -138,54 +148,54 @@ var b = ({ session: b, turns: oe = [], onSaveTranscript: se, onContinueInChat: c
138
148
  control: e
139
149
  });
140
150
  })(),
141
- V ? /* @__PURE__ */ v(u, {
142
- turns: oe,
151
+ V ? /* @__PURE__ */ h(ae, {
152
+ turns: fe,
143
153
  onClose: () => H(!1),
144
- onSave: se,
145
- onContinueInChat: ce
154
+ onSave: pe,
155
+ onContinueInChat: me
146
156
  }) : null,
147
- E ? /* @__PURE__ */ v("div", {
157
+ w ? /* @__PURE__ */ h("div", {
148
158
  className: `absolute ${R ? "left-6 top-6" : z ? "left-11 top-2" : "left-3 top-3"}`,
149
- children: /* @__PURE__ */ v(o, {
159
+ children: /* @__PURE__ */ h(c, {
150
160
  onFiles: (e) => {
151
- E(e), L((e) => e === "mini" ? "panel" : e);
161
+ w(e), L((e) => e === "mini" ? "panel" : e);
152
162
  },
153
- onPickerOpen: me,
163
+ onPickerOpen: ye,
154
164
  direction: "down",
155
- canAddMore: de
165
+ canAddMore: ve
156
166
  })
157
167
  }) : null,
158
- (T.length > 0 || D > 0) && !z ? /* @__PURE__ */ v("div", {
168
+ (C.length > 0 || T > 0) && !z ? /* @__PURE__ */ h("div", {
159
169
  className: `absolute ${R ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
160
170
  "data-testid": "assistant-voice-attachments",
161
- children: /* @__PURE__ */ v(ne, {
162
- attachments: T,
163
- onRemove: le ?? (() => void 0),
164
- onRetry: ue ?? (() => void 0),
165
- preparingCount: D
171
+ children: /* @__PURE__ */ h(l, {
172
+ attachments: C,
173
+ onRemove: ge ?? (() => void 0),
174
+ onRetry: _e ?? (() => void 0),
175
+ preparingCount: T
166
176
  })
167
177
  }) : null,
168
- /* @__PURE__ */ v("button", {
178
+ /* @__PURE__ */ h("button", {
169
179
  type: "button",
170
180
  onClick: () => H((e) => !e),
171
181
  className: `absolute ${R ? "bottom-6 right-6 size-14" : z ? "right-2 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
172
182
  "aria-pressed": V,
173
183
  "aria-label": j("voiceSession.transcriptTitle", "Voice transcript"),
174
184
  "data-testid": "assistant-voice-transcript-toggle",
175
- children: /* @__PURE__ */ v(g, { className: R ? "size-6" : z ? "size-4" : "size-5" })
185
+ children: /* @__PURE__ */ h(ue, { className: R ? "size-6" : z ? "size-4" : "size-5" })
176
186
  }),
177
- /* @__PURE__ */ v("button", {
187
+ /* @__PURE__ */ h("button", {
178
188
  type: "button",
179
189
  onClick: () => L(B),
180
190
  className: `absolute ${R ? "bottom-6 left-6 size-14" : z ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
181
191
  "aria-label": B === "panel" ? j("voiceSession.expandPanel", "Show the conversation in the panel") : B === "full" ? j("voiceSession.expand", "Expand the conversation to full screen") : j("voiceSession.collapse", "Shrink to the compact controller"),
182
192
  "data-testid": "assistant-voice-expand",
183
- children: R ? /* @__PURE__ */ v(h, { className: "size-5" }) : /* @__PURE__ */ v(re, { className: z ? "size-4" : "size-5" })
193
+ children: R ? /* @__PURE__ */ h(le, { className: "size-5" }) : /* @__PURE__ */ h(ce, { className: z ? "size-4" : "size-5" })
184
194
  })
185
195
  ]
186
196
  });
187
197
  };
188
- function ie(e, t) {
198
+ function v(e, t) {
189
199
  switch (e) {
190
200
  case "network": return t("voiceSession.noticeNetwork", "Speech recognition lost its connection. Check your network — it will retry.");
191
201
  case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
@@ -194,7 +204,7 @@ function ie(e, t) {
194
204
  default: return e;
195
205
  }
196
206
  }
197
- function ae(e, t) {
207
+ function y(e, t) {
198
208
  switch (e) {
199
209
  case "mic-denied": return t("voiceSession.micDenied", "Microphone access is blocked. Allow it in your browser settings to talk.");
200
210
  case "no-speech-support": return t("voiceSession.noSpeechSupport", "This browser cannot listen. Try a different browser, or type instead.");
@@ -203,4 +213,4 @@ function ae(e, t) {
203
213
  }
204
214
  }
205
215
  //#endregion
206
- export { b as AssistantVoiceSession };
216
+ export { _ as AssistantVoiceSession };
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAMnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CA+I3C,CAAC"}
1
+ {"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAOnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAoJ3C,CAAC"}
@@ -1,70 +1,71 @@
1
- import { useAssistantTr as e } from "../../i18n.js";
2
- import { ASSISTANT_PANEL_ATTR as t, focusIsInsidePanel as n } from "../panelOverlays.js";
3
- import { VoiceConversationView as r } from "./VoiceConversationView.js";
4
- import { AssistantHistoryShowEarlier as i } from "../AssistantHistoryNotices.js";
5
- import { useEffect as a, useRef as o } from "react";
6
- import { ArrowRight as s, Download as c, X as l } from "lucide-react";
7
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
1
+ import { useReturnFocus as e } from "../../../hooks/useReturnFocus.js";
2
+ import { useAssistantTr as t } from "../../i18n.js";
3
+ import { ASSISTANT_PANEL_ATTR as n, focusIsInsidePanel as r } from "../panelOverlays.js";
4
+ import { VoiceConversationView as i } from "./VoiceConversationView.js";
5
+ import { AssistantHistoryShowEarlier as a } from "../AssistantHistoryNotices.js";
6
+ import { useEffect as o, useRef as s } from "react";
7
+ import { ArrowRight as c, Download as l, X as u } from "lucide-react";
8
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
9
  //#region src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx
9
- var f = ({ turns: f, onClose: p, onSave: m, onContinueInChat: h, closeOnEscape: g = !1, onShowEarlier: _, showEarlierDisabled: v = !1 }) => {
10
- let y = e(), b = o(null);
11
- return a(() => {
12
- if (!g) return;
10
+ var p = ({ turns: p, onClose: m, onSave: h, onContinueInChat: g, closeOnEscape: _ = !1, onShowEarlier: v, showEarlierDisabled: y = !1 }) => {
11
+ let b = t(), x = s(null);
12
+ return e(x, { fallbackSelector: `[${n}]` }), o(() => {
13
+ if (!_) return;
13
14
  let e = (e) => {
14
15
  if (e.key !== "Escape" || document.querySelector("[role=\"alertdialog\"]")) return;
15
- let r = b.current?.closest(`[${t}]`), i = document.activeElement;
16
- n(r ?? null, i) && (e.preventDefault(), e.stopPropagation(), p());
16
+ let t = x.current?.closest(`[${n}]`), i = document.activeElement;
17
+ r(t ?? null, i) && (e.preventDefault(), e.stopPropagation(), m());
17
18
  };
18
19
  return document.addEventListener("keydown", e, !0), () => document.removeEventListener("keydown", e, !0);
19
- }, [g, p]), /* @__PURE__ */ d("div", {
20
- ref: b,
20
+ }, [_, m]), /* @__PURE__ */ f("div", {
21
+ ref: x,
21
22
  className: "absolute inset-0 z-30 flex flex-col bg-bg-sunken/95 backdrop-blur-sm",
22
23
  role: "dialog",
23
- "aria-label": y("voiceSession.transcriptTitle", "Voice transcript"),
24
+ "aria-label": b("voiceSession.transcriptTitle", "Voice transcript"),
24
25
  "data-testid": "assistant-voice-transcript",
25
26
  children: [
26
- /* @__PURE__ */ d("div", {
27
+ /* @__PURE__ */ f("div", {
27
28
  className: "flex items-center justify-between border-b border-border-subtle px-4 py-3",
28
- children: [/* @__PURE__ */ d("div", {
29
+ children: [/* @__PURE__ */ f("div", {
29
30
  className: "min-w-0",
30
- children: [/* @__PURE__ */ u("h2", {
31
+ children: [/* @__PURE__ */ d("h2", {
31
32
  className: "text-sm font-semibold text-text-primary",
32
- children: y("voiceSession.transcript", "Voice conversation")
33
- }), /* @__PURE__ */ u("p", {
33
+ children: b("voiceSession.transcript", "Voice conversation")
34
+ }), /* @__PURE__ */ d("p", {
34
35
  className: "truncate text-xs text-text-muted",
35
- children: y("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
36
+ children: b("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
36
37
  })]
37
- }), /* @__PURE__ */ u("button", {
38
+ }), /* @__PURE__ */ d("button", {
38
39
  type: "button",
39
- onClick: p,
40
+ onClick: m,
40
41
  className: "flex size-8 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
41
- "aria-label": y("voiceSession.transcriptClose", "Close the transcript"),
42
+ "aria-label": b("voiceSession.transcriptClose", "Close the transcript"),
42
43
  "data-testid": "assistant-voice-transcript-close",
43
- children: /* @__PURE__ */ u(l, { className: "size-4" })
44
+ children: /* @__PURE__ */ d(u, { className: "size-4" })
44
45
  })]
45
46
  }),
46
- _ ? /* @__PURE__ */ u(i, {
47
- onShowEarlier: _,
48
- disabled: v
47
+ v ? /* @__PURE__ */ d(a, {
48
+ onShowEarlier: v,
49
+ disabled: y
49
50
  }) : null,
50
- /* @__PURE__ */ u(r, { turns: f }),
51
- (m || h) && f.length > 0 ? /* @__PURE__ */ d("div", {
51
+ /* @__PURE__ */ d(i, { turns: p }),
52
+ (h || g) && p.length > 0 ? /* @__PURE__ */ f("div", {
52
53
  className: "flex items-center justify-end gap-2 border-t border-border-subtle px-4 py-3",
53
- children: [m ? /* @__PURE__ */ d("button", {
54
+ children: [h ? /* @__PURE__ */ f("button", {
54
55
  type: "button",
55
- onClick: m,
56
+ onClick: h,
56
57
  className: "flex items-center gap-1.5 rounded-lg border border-border-default px-3 py-1.5 text-xs text-text-secondary transition-colors hover:bg-bg-elevated hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
57
58
  "data-testid": "assistant-voice-save-transcript",
58
- children: [/* @__PURE__ */ u(c, {
59
+ children: [/* @__PURE__ */ d(l, {
59
60
  className: "size-3.5",
60
61
  "aria-hidden": "true"
61
- }), y("voiceSession.save", "Save transcript")]
62
- }) : null, h ? /* @__PURE__ */ d("button", {
62
+ }), b("voiceSession.save", "Save transcript")]
63
+ }) : null, g ? /* @__PURE__ */ f("button", {
63
64
  type: "button",
64
- onClick: h,
65
+ onClick: g,
65
66
  className: "flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-fg transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
66
67
  "data-testid": "assistant-voice-continue-in-chat",
67
- children: [y("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ u(s, {
68
+ children: [b("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ d(c, {
68
69
  className: "size-3.5",
69
70
  "aria-hidden": "true"
70
71
  })]
@@ -74,4 +75,4 @@ var f = ({ turns: f, onClose: p, onSave: m, onContinueInChat: h, closeOnEscape:
74
75
  });
75
76
  };
76
77
  //#endregion
77
- export { f as VoiceTranscriptDrawer };
78
+ export { p as VoiceTranscriptDrawer };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * A layer an Escape can be pressed INSIDE of: a dialog by role (the Radix
3
+ * `Dialog` and `AlertDialog` contents carry it), an open native `<dialog>`, or
4
+ * anything declared modal.
5
+ */
6
+ export declare const VOICE_ESCAPE_LAYER_SELECTOR = "[role=\"dialog\"],[role=\"alertdialog\"],dialog[open],[aria-modal=\"true\"]";
7
+ /**
8
+ * A layer that outranks the voice session wherever focus is.
9
+ *
10
+ * `[role="alertdialog"]` matches the guard the post-session transcript drawer
11
+ * already applies. There is no `dialog[open]` here: a native modal dialog makes
12
+ * everything behind it inert, so focus, and with it the key press, is always
13
+ * inside it, and the layer check already sees that. A NON-modal open
14
+ * `<dialog>` is not a modal, and must not block Escape across the whole page.
15
+ */
16
+ export declare const VOICE_ESCAPE_MODAL_SELECTOR = "[aria-modal=\"true\"],[role=\"alertdialog\"]";
17
+ export type VoiceSessionEscapeAction = "ignore" | "close-transcript" | "end";
18
+ /**
19
+ * What the voice session does with an Escape.
20
+ *
21
+ * Two things outrank it, in this order:
22
+ *
23
+ * - an earlier handler already took the key (`defaultPrevented`). Radix's
24
+ * `DismissableLayer` dismisses in the CAPTURE phase on `document` and calls
25
+ * `preventDefault()` when it does, so by the time the key reaches this
26
+ * listener the dialog it closed can already be out of the DOM, with focus
27
+ * back on `<body>` (measured in VibeControls prod on 2026-09-23: in the
28
+ * bubble phase the dialog was gone and `activeElement` was BODY). This flag
29
+ * is often the only trace left of it;
30
+ * - a layer above the session: see `escapeBelongsToLayerAbove`.
31
+ *
32
+ * Otherwise nothing changes from before: the session's own transcript drawer
33
+ * closes first, and only then does Escape end the conversation.
34
+ */
35
+ export declare function voiceSessionEscapeAction(input: {
36
+ defaultPrevented: boolean;
37
+ layerAbove: boolean;
38
+ transcriptOpen: boolean;
39
+ }): VoiceSessionEscapeAction;
40
+ /**
41
+ * Does this Escape belong to a dialog or modal above the voice session?
42
+ *
43
+ * Yes when:
44
+ * - the key was pressed inside one: the event TARGET's nearest layer is
45
+ * above the session. The target keeps its ancestors even after the dialog
46
+ * has been removed, so this still holds in the bubble phase;
47
+ * - focus is inside one: the same test on `activeElement`;
48
+ * - a modal is open anywhere that is not the session's own.
49
+ *
50
+ * With none of those, the key is the session's, exactly as before.
51
+ */
52
+ export declare function escapeBelongsToLayerAbove(input: {
53
+ target: EventTarget | null;
54
+ session: Element | null;
55
+ doc: Pick<Document, "activeElement" | "querySelectorAll">;
56
+ }): boolean;
57
+ //# sourceMappingURL=voiceSessionEscape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voiceSessionEscape.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/voiceSessionEscape.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,gFAAqD,CAAC;AAE9F;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,iDACI,CAAC;AAE7C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,kBAAkB,GAAG,KAAK,CAAC;AAE7E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,wBAAwB,CAI3B;AAmCD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,kBAAkB,CAAC,CAAC;CAC3D,GAAG,OAAO,CAOV"}
@@ -0,0 +1,19 @@
1
+ import { focusIsInsidePanel as e } from "../panelOverlays.js";
2
+ import { ASSISTANT_DIALOG_SELECTOR as t, closestAround as n } from "../assistantOverlayState.js";
3
+ //#region src/shared/assistant/ui/voice/voiceSessionEscape.ts
4
+ var r = `${t},[aria-modal="true"]`, i = "[aria-modal=\"true\"],[role=\"alertdialog\"]";
5
+ function a(e) {
6
+ return e.defaultPrevented || e.layerAbove ? "ignore" : e.transcriptOpen ? "close-transcript" : "end";
7
+ }
8
+ function o(e) {
9
+ return n(e, r);
10
+ }
11
+ function s(t, n) {
12
+ return !(!t || e(n, t) || n && t.contains(n));
13
+ }
14
+ function c(e) {
15
+ let { target: t, session: n, doc: r } = e;
16
+ return s(o(t), n) || s(o(r.activeElement), n) ? !0 : Array.from(r.querySelectorAll(i)).some((e) => s(e, n));
17
+ }
18
+ //#endregion
19
+ export { r as VOICE_ESCAPE_LAYER_SELECTOR, i as VOICE_ESCAPE_MODAL_SELECTOR, c as escapeBelongsToLayerAbove, a as voiceSessionEscapeAction };
@@ -14,7 +14,9 @@ interface Options {
14
14
  * anyway and were just adding visible "shortcut listed, doesn't work"
15
15
  * inconsistencies. The shortcuts here match the in-app shortcuts modal.
16
16
  *
17
- * - Escape: Close panel
17
+ * - Escape: back out of the topmost layer — a full-surface overlay (history,
18
+ * preview), else nothing here while a live voice session owns the key (it
19
+ * closes its transcript, then ends), else close the panel
18
20
  * - Ctrl/Cmd+Shift+N: New conversation
19
21
  * - Ctrl/Cmd+Shift+E: Export (triggers click on export button)
20
22
  * - /: Focus input (only when no input/textarea is already focused)
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QA+ErF"}
1
+ {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QAyFrF"}
@@ -1,41 +1,41 @@
1
1
  import { useAssistantStore as e } from "./store.js";
2
- import { focusIsInsidePanel as t, panelOwnsEscape as n } from "./ui/panelOverlays.js";
3
- import { useEffect as r } from "react";
2
+ import { focusIsInsidePanel as t, panelOwnsEscape as n, voiceSessionOwnsEscape as r } from "./ui/panelOverlays.js";
3
+ import { useEffect as i } from "react";
4
4
  //#region src/shared/assistant/useAssistantKeyboardShortcuts.ts
5
- function i({ panelRef: i, inputRef: a, onClose: o }) {
6
- r(() => {
7
- let r = (r) => {
8
- let s = i.current;
9
- if (!s) return;
10
- let c = document.activeElement;
11
- if (r.key === "Escape") {
12
- if (!n(s, c, document.body)) return;
13
- r.preventDefault(), o();
5
+ function a({ panelRef: a, inputRef: o, onClose: s }) {
6
+ i(() => {
7
+ let i = (i) => {
8
+ let c = a.current;
9
+ if (!c) return;
10
+ let l = document.activeElement;
11
+ if (i.key === "Escape") {
12
+ if (i.defaultPrevented || !n(c, l, document.body) || r(c)) return;
13
+ i.preventDefault(), s();
14
14
  return;
15
15
  }
16
- if (!t(s, c)) return;
17
- let l = r.ctrlKey || r.metaKey;
18
- if (l && r.shiftKey && (r.key === "N" || r.key === "n")) {
19
- r.preventDefault(), e.getState().createConversation();
16
+ if (!t(c, l)) return;
17
+ let u = i.ctrlKey || i.metaKey;
18
+ if (u && i.shiftKey && (i.key === "N" || i.key === "n")) {
19
+ i.preventDefault(), e.getState().createConversation();
20
20
  return;
21
21
  }
22
- if (l && r.shiftKey && (r.key === "E" || r.key === "e")) {
23
- r.preventDefault();
24
- let e = s.querySelector("[data-testid=\"assistant-more\"]");
22
+ if (u && i.shiftKey && (i.key === "E" || i.key === "e")) {
23
+ i.preventDefault();
24
+ let e = c.querySelector("[data-testid=\"assistant-more\"]");
25
25
  e?.focus(), e?.click();
26
26
  return;
27
27
  }
28
- if (r.key === "/" && !l && !r.shiftKey) {
29
- let e = c?.tagName;
30
- e !== "INPUT" && e !== "TEXTAREA" && (r.preventDefault(), a?.current?.focus());
28
+ if (i.key === "/" && !u && !i.shiftKey) {
29
+ let e = l?.tagName;
30
+ e !== "INPUT" && e !== "TEXTAREA" && (i.preventDefault(), o?.current?.focus());
31
31
  }
32
32
  };
33
- return document.addEventListener("keydown", r), () => document.removeEventListener("keydown", r);
33
+ return document.addEventListener("keydown", i), () => document.removeEventListener("keydown", i);
34
34
  }, [
35
- i,
36
35
  a,
37
- o
36
+ o,
37
+ s
38
38
  ]);
39
39
  }
40
40
  //#endregion
41
- export { i as useAssistantKeyboardShortcuts };
41
+ export { a as useAssistantKeyboardShortcuts };
@@ -16,6 +16,7 @@ export { useOnClickOutside, useOnClickOutsideWithRef } from './useOnClickOutside
16
16
  export { useKeyPress, useKeyboardShortcut } from './useKeyPress';
17
17
  export { useCopyToClipboard } from './useCopyToClipboard';
18
18
  export { useExclusiveMenu } from './useExclusiveMenu';
19
+ export { useReturnFocus, type UseReturnFocusOptions } from './useReturnFocus';
19
20
  export { useLocalStorage } from './useLocalStorage';
20
21
  export { useSessionStorage } from './useSessionStorage';
21
22
  export { usePrevious, usePreviousDistinct, usePreviousHistory } from './usePrevious';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAc,MAAM,OAAO,CAAC;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,oBAAoB,8CAA2D,CAAC;AAE7F;;GAEG;AACH,wBAAgB,uBAAuB,2BAMtC;AAOD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9E,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGjG,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAc,MAAM,OAAO,CAAC;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,oBAAoB,8CAA2D,CAAC;AAE7F;;GAEG;AACH,wBAAgB,uBAAuB,2BAMtC;AAOD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9E,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGjG,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,iCAAiC,CAAC"}