@alexkroman1/aai-ui 13.2.0 → 14.0.0

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 (83) hide show
  1. package/README.md +159 -69
  2. package/dist/{_colors-j8XMToi9.js → _colors-CpZO-88A.js} +25 -2
  3. package/dist/{_module-url-C_4gRVL0.js → _module-url-C13kAJ87.js} +1 -1
  4. package/dist/_recover-run.d.ts +13 -7
  5. package/dist/_submission-state.d.ts +92 -0
  6. package/dist/_upload-files.d.ts +2 -2
  7. package/dist/_upload-report.d.ts +26 -0
  8. package/dist/{_utils-B6498_bm.js → _utils-DnQDM9Uy.js} +4 -4
  9. package/dist/_utils.d.ts +3 -3
  10. package/dist/_web-storage.d.ts +43 -0
  11. package/dist/_workflow-files.d.ts +1 -1
  12. package/dist/{aai-logo-CXZGPSIY.js → aai-logo-CFlomZlS.js} +1 -1
  13. package/dist/agent-state-labels.d.ts +60 -0
  14. package/dist/audio.js +21 -15
  15. package/dist/{chat-view-DDTtrh7N.js → chat-view-C_3T7Ln8.js} +100 -33
  16. package/dist/{client-config-BT_kWID5.js → client-config-DJQHnYjm.js} +5 -5
  17. package/dist/client-config.d.ts +4 -4
  18. package/dist/client-dir.d.ts +1 -1
  19. package/dist/client-dir.js +2 -2
  20. package/dist/components/_colors.d.ts +23 -0
  21. package/dist/components/_form-readiness.d.ts +1 -1
  22. package/dist/components/bullet-list.d.ts +74 -0
  23. package/dist/components/button.js +4 -4
  24. package/dist/components/chat-view.js +1 -1
  25. package/dist/components/console-shell.d.ts +16 -20
  26. package/dist/components/controls.js +4 -4
  27. package/dist/components/facts.d.ts +81 -0
  28. package/dist/components/form-fields.d.ts +6 -6
  29. package/dist/components/form-types.d.ts +1 -1
  30. package/dist/components/form.d.ts +1 -1
  31. package/dist/components/message-list.js +1 -1
  32. package/dist/components/session-error-banner.d.ts +69 -0
  33. package/dist/components/sidebar-layout.js +1 -1
  34. package/dist/components/start-screen.js +4 -4
  35. package/dist/components/tool-call-block.js +1 -1
  36. package/dist/components/tool-config-context.d.ts +1 -1
  37. package/dist/components/workflow-progress.d.ts +11 -4
  38. package/dist/context.d.ts +142 -19
  39. package/dist/context.js +156 -18
  40. package/dist/default-client/assets/{audio-BuDICbPf.js → audio-9zQsNc1w.js} +1 -1
  41. package/dist/default-client/assets/index-BTv30Z4F.css +2 -0
  42. package/dist/default-client/assets/index-RAZ-29Sz.js +284 -0
  43. package/dist/default-client/index.html +2 -2
  44. package/dist/default-client.d.ts +1 -1
  45. package/dist/define-client.d.ts +19 -19
  46. package/dist/define-client.js +20 -20
  47. package/dist/{eyebrow-C6ZFuiz6.js → eyebrow-UfmSz9yy.js} +1 -1
  48. package/dist/hooks.d.ts +44 -8
  49. package/dist/hooks.js +20 -14
  50. package/dist/index.d.ts +13 -8
  51. package/dist/index.js +1447 -1160
  52. package/dist/internal.d.ts +2 -2
  53. package/dist/internal.js +5 -5
  54. package/dist/{message-list-BJYyuIcR.js → message-list-CdOnSh5m.js} +23 -16
  55. package/dist/page.d.ts +11 -11
  56. package/dist/session-core-audio-setup.d.ts +1 -1
  57. package/dist/session-core-dial.d.ts +0 -2
  58. package/dist/{session-core-DxBYsfHA.js → session-core-gwePM95B.js} +135 -62
  59. package/dist/session-core-messages.d.ts +2 -2
  60. package/dist/session-core-types.d.ts +58 -1
  61. package/dist/session-core.d.ts +6 -6
  62. package/dist/session-core.js +2 -2
  63. package/dist/session-resume-store.d.ts +3 -3
  64. package/dist/{tool-call-block-tcPQAkcP.js → tool-call-block-C2t_5fpp.js} +30 -12
  65. package/dist/{tool-config-context-DzAofqi_.js → tool-config-context-Es4YUzV2.js} +2 -2
  66. package/dist/types.d.ts +19 -4
  67. package/dist/types.js +3 -3
  68. package/dist/{url-chips-YqhCjWfQ.js → url-chips-BxhzZgk2.js} +5 -5
  69. package/dist/use-conversation.d.ts +1 -1
  70. package/dist/use-run-key.d.ts +44 -10
  71. package/dist/{use-user-transcript-C14qWFu2.js → use-user-transcript-uyHhzy4d.js} +4 -3
  72. package/dist/use-workflow-form.d.ts +64 -91
  73. package/dist/{use-workflow-progress-Cu0SxMyg.js → use-workflow-run-CP2ekKPV.js} +254 -257
  74. package/dist/use-workflow-stream.d.ts +5 -2
  75. package/dist/use-workflows.d.ts +77 -0
  76. package/dist/workflow-client.d.ts +1 -1
  77. package/dist/worklets/capture-processor.js +2 -2
  78. package/dist/worklets/playback-processor.js +2 -2
  79. package/package.json +6 -6
  80. package/styles.css +78 -0
  81. package/dist/default-client/assets/index-B1_ROnTJ.js +0 -284
  82. package/dist/default-client/assets/index-S5fkKi6B.css +0 -2
  83. package/dist/tsdown.config.d.ts +0 -2
package/dist/context.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createContext, createElement, useContext, useEffect, useMemo, useSyncExternalStore } from "react";
2
2
  import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector";
3
- //#region context.ts
3
+ //#region src/context.ts
4
4
  const DEFAULT_THEME = {
5
5
  bg: "#FBF8F2",
6
6
  primary: "#3F2BC1",
@@ -10,9 +10,9 @@ const DEFAULT_THEME = {
10
10
  };
11
11
  const SessionCtx = createContext(null);
12
12
  /**
13
- * Provides the {@link SessionCore} the session hooks read. `client()`
13
+ * Provides the {@link BrowserSession} the session hooks read. `mountClient()`
14
14
  * installs it automatically; a custom tree only needs it when bypassing
15
- * `client()` and mounting React itself.
15
+ * `mountClient()` and mounting React itself.
16
16
  *
17
17
  * @internal
18
18
  */
@@ -20,7 +20,7 @@ function SessionProvider({ value, children }) {
20
20
  return createElement(SessionCtx.Provider, { value }, children);
21
21
  }
22
22
  /**
23
- * Return the raw {@link SessionCore} from context without subscribing to
23
+ * Return the raw {@link BrowserSession} from context without subscribing to
24
24
  * snapshot changes. Useful for accessing stable methods (`start`, `toggle`,
25
25
  * `reset`, …) from components that select narrow state via
26
26
  * {@link useSessionSelector}.
@@ -34,13 +34,83 @@ function useSessionCore() {
34
34
  return core;
35
35
  }
36
36
  /**
37
+ * The session's control methods — `start`, `cancel`, `resetState`, `reset`,
38
+ * `restart`, `disconnect`, `toggle`, `end` — with **no snapshot
39
+ * subscription**.
40
+ *
41
+ * This is the narrow half of {@link useSession}, and it is the half a custom
42
+ * chrome could not reach. `<Controls>` and `<StartScreen>` in this package pair
43
+ * a one-field `useSessionSelector` with this package's own `useSessionCore`
44
+ * (`context.ts`, unpublished); a `client.tsx`
45
+ * could not, because that hook is not published — so a footer needing `start`
46
+ * and `toggle` held a WHOLE-SNAPSHOT `useSession()`, and `session-core.ts`
47
+ * rebuilds the snapshot object on every change. Measured consequence: four
48
+ * components across three templates re-rendered on every STT partial and every
49
+ * streaming delta, in files whose every other component is narrowly subscribed
50
+ * on purpose. One of them (`infocom-adventure`'s `TitleScreen`) reads nothing
51
+ * from the snapshot at all and subscribes to all of it for `session.start`.
52
+ *
53
+ * **Why publishing this does not reopen what `/internal` closed.**
54
+ * `useSessionCore` hands back the STORE — `subscribe`, `getSnapshot`,
55
+ * `connect`, `Symbol.dispose` — which is the framework's own plumbing, the same
56
+ * category as the providers and `buildAgentUrl` that live on
57
+ * `@alexkroman1/aai-ui/internal`. A client that holds it can subscribe out of
58
+ * band of React, dial a socket the mount did not, and dispose the session under
59
+ * the tree that is rendering it. What comes back from here is the SAME eight
60
+ * methods `useSession()` already publishes on its result, built into a fresh
61
+ * object rather than passed through, so the store is not reachable from it.
62
+ * There is no new capability here — only the existing one without the
63
+ * subscription tax.
64
+ *
65
+ * Identity-stable per core, so it is safe in a dependency array and in a
66
+ * `memo()` child's props: the methods are closures created once by
67
+ * `createBrowserSession`, and the object wrapping them is memoized on the core.
68
+ *
69
+ * Throws outside the provider `mountClient()` installs, like every session hook.
70
+ *
71
+ * @example A footer that acts on the session without re-rendering with it
72
+ * ```tsx
73
+ * import { useSessionActions, useSessionSelector } from "@alexkroman1/aai-ui";
74
+ *
75
+ * function Footer() {
76
+ * // Two narrow subscriptions and no snapshot read: this row re-renders when
77
+ * // `running` flips, and not on every transcript delta.
78
+ * const running = useSessionSelector((s) => s.running);
79
+ * const { toggle, end } = useSessionActions();
80
+ * return (
81
+ * <>
82
+ * <button onClick={toggle}>{running ? "Pause" : "Resume"}</button>
83
+ * <button onClick={end}>Hang up</button>
84
+ * </>
85
+ * );
86
+ * }
87
+ * ```
88
+ *
89
+ * @returns The eight control methods — see {@link SessionActions}.
90
+ *
91
+ * @public
92
+ */
93
+ function useSessionActions() {
94
+ const core = useSessionCore();
95
+ return useMemo(() => ({
96
+ start: core.start,
97
+ cancel: core.cancel,
98
+ resetState: core.resetState,
99
+ reset: core.reset,
100
+ restart: core.restart,
101
+ disconnect: core.disconnect,
102
+ toggle: core.toggle,
103
+ end: core.end
104
+ }), [core]);
105
+ }
106
+ /**
37
107
  * Return the live {@link Session}: the current snapshot fields plus the
38
108
  * control methods (`start`, `toggle`, `reset`, `resetState`, `disconnect`,
39
109
  * `cancel`, `end`).
40
110
  *
41
- * Throws if used outside the provider `client()` installs (the error names
111
+ * Throws if used outside the provider `mountClient()` installs (the error names
42
112
  * `<SessionProvider>` — you only mount that yourself when bypassing
43
- * `client()`). Re-renders the component on *every* snapshot change; for a
113
+ * `mountClient()`). Re-renders the component on *every* snapshot change; for a
44
114
  * component that reads one field, prefer {@link useSessionSelector} for a
45
115
  * targeted subscription.
46
116
  *
@@ -60,16 +130,11 @@ function useSessionCore() {
60
130
  function useSession() {
61
131
  const core = useSessionCore();
62
132
  const snapshot = useSyncExternalStore(core.subscribe, core.getSnapshot);
133
+ const actions = useSessionActions();
63
134
  return useMemo(() => ({
64
135
  ...snapshot,
65
- start: core.start,
66
- cancel: core.cancel,
67
- resetState: core.resetState,
68
- reset: core.reset,
69
- disconnect: core.disconnect,
70
- toggle: core.toggle,
71
- end: core.end
72
- }), [snapshot, core]);
136
+ ...actions
137
+ }), [snapshot, actions]);
73
138
  }
74
139
  /**
75
140
  * Subscribe to a narrow slice of the session snapshot.
@@ -105,11 +170,84 @@ function useSessionSelector(selector, isEqual = Object.is) {
105
170
  const core = useSessionCore();
106
171
  return useSyncExternalStoreWithSelector(core.subscribe, core.getSnapshot, core.getSnapshot, selector, isEqual);
107
172
  }
173
+ /**
174
+ * The two selectors below are MODULE-SCOPE functions, and that is load-bearing
175
+ * rather than tidy.
176
+ *
177
+ * `useSyncExternalStoreWithSelector` caches its selection keyed on the selector
178
+ * it was handed: a fresh arrow per render invalidates that memo every render,
179
+ * so the selector re-runs and the `isEqual` short-circuit protects only the
180
+ * re-RENDER, never the work. Hoisting them means the two fields more than one
181
+ * chrome ever reads are selected by one stable function for the life of the
182
+ * program — which is also the thing a caller writing the arrow inline cannot
183
+ * do for themselves, and the reason these two are hooks at all rather than a
184
+ * documented one-liner.
185
+ */
186
+ const selectState = (s) => s.state;
187
+ const selectError = (s) => s.error;
188
+ /**
189
+ * The agent's live {@link AgentState} — `disconnected`, `connecting`, `ready`,
190
+ * `listening`, `thinking`, `speaking`, `error` — on its own narrow
191
+ * subscription.
192
+ *
193
+ * `useSessionSelector((s) => s.state)` spelled once. It is one of exactly two
194
+ * snapshot fields that more than one custom chrome ever selects (the other is
195
+ * {@link useSessionError}), and it had been written inline at eight sites —
196
+ * including inside this package and, worse, in `ConsoleShell`'s own `@example`,
197
+ * which taught the inline form to everyone who read it.
198
+ *
199
+ * **Named `useSessionStatus`, not `useSessionState`.** `useAgentState` is the
200
+ * SLOT hook — the agent's own synced application state, whatever a
201
+ * `sessionSlot()` projects — and `AgentState` here is the phase of the CALL.
202
+ * Two different concepts one letter apart, so the shorter-sounding name is the
203
+ * one deliberately not taken.
204
+ *
205
+ * Pair it with {@link AGENT_STATE_LABELS} for a rendered word; the raw member
206
+ * is a wire value, not a label.
207
+ *
208
+ * @example
209
+ * ```tsx
210
+ * import { AGENT_STATE_LABELS, useSessionStatus } from "@alexkroman1/aai-ui";
211
+ *
212
+ * function StatusDot() {
213
+ * const status = useSessionStatus();
214
+ * return <span data-state={status}>{AGENT_STATE_LABELS[status]}</span>;
215
+ * }
216
+ * ```
217
+ *
218
+ * @returns The current agent state.
219
+ *
220
+ * @public
221
+ */
222
+ function useSessionStatus() {
223
+ return useSessionSelector(selectState);
224
+ }
225
+ /**
226
+ * The session's current {@link SessionError}, or `null` when there is none, on
227
+ * its own narrow subscription.
228
+ *
229
+ * The other half of {@link useSessionStatus} — the second of the two fields a
230
+ * custom chrome reads over and over, and the one whose absence is invisible:
231
+ * per the `fatalError` latch in `session-core.ts` the error is the ONLY
232
+ * remaining signal that a session died, since the state beside it goes back to
233
+ * reading like a live one.
234
+ *
235
+ * A chrome rendering it owes `role="alert"` — which is what
236
+ * {@link SessionErrorBanner} is for, and why reaching for that beats reaching
237
+ * for this.
238
+ *
239
+ * @returns The current error, or `null`.
240
+ *
241
+ * @public
242
+ */
243
+ function useSessionError() {
244
+ return useSessionSelector(selectError);
245
+ }
108
246
  const ThemeCtx = createContext(DEFAULT_THEME);
109
247
  /**
110
- * Provides the theme the components read via `useTheme`. `client()` installs
248
+ * Provides the theme the components read via `useTheme`. `mountClient()` installs
111
249
  * it automatically (from `ClientConfig.theme`); a custom tree only needs it
112
- * when bypassing `client()` and mounting React itself.
250
+ * when bypassing `mountClient()` and mounting React itself.
113
251
  *
114
252
  * @internal
115
253
  */
@@ -208,7 +346,7 @@ function useThemeStyles(theme) {
208
346
  * provider is present, so components can call it unconditionally.
209
347
  *
210
348
  * This is how a custom component stays on the agent's palette: a
211
- * `client({ theme })` override reaches it here, where a hardcoded colour or a
349
+ * `mountClient({ theme })` override reaches it here, where a hardcoded colour or a
212
350
  * Tailwind class cannot see it.
213
351
  *
214
352
  * @example
@@ -233,4 +371,4 @@ function useTheme() {
233
371
  return useContext(ThemeCtx);
234
372
  }
235
373
  //#endregion
236
- export { SessionProvider, ThemeProvider, useSession, useSessionCore, useSessionSelector, useTheme };
374
+ export { SessionProvider, ThemeProvider, useSession, useSessionActions, useSessionCore, useSessionError, useSessionSelector, useSessionStatus, useTheme };
@@ -1 +1 @@
1
- import{a as e,o as t}from"./client-audio-constants-CP13UQZt.js";var n={echoCancellation:!0,noiseSuppression:!1,autoGainControl:!1,voiceIsolation:!1};function r(e,t,n){if(e!==t)throw Error(`Browser refused the ${n} sample rate: asked for ${t} Hz, got ${e} Hz`)}function i(e){let t=Error(`Audio ${e} worklet crashed`);return console.error(`[aai-ui]`,t.message),t}function a(e){e.then(e=>{for(let t of e.getTracks())t.stop()}).catch(()=>{})}function o(e,t,n){let r=new AudioWorkletNode(e,`capture-processor`,{channelCount:1,channelCountMode:`explicit`}),i=null;return r.port.onmessage=e=>{let r=e.data;r.event===`chunk`&&r.buffer?t(r.buffer):r.event===`silent`?n?.():r.event===`stopped`&&(i?.(),i=null)},{node:r,start(){r.port.postMessage({event:`start`})},stop(){let{promise:e,resolve:t}=Promise.withResolvers(),n=setTimeout(t,250);return i=()=>{clearTimeout(n),t()},r.port.postMessage({event:`stop`}),e}}}async function s(s){let{sttSampleRate:c,ttsSampleRate:l,captureWorkletSrc:u,playbackWorkletSrc:d,onMicData:f,onError:p,onPlaybackStats:m,onPlaybackProgress:h,onMicSilent:g}=s,_=new AudioContext({sampleRate:l,latencyHint:`playback`}),v=c===l,y=v?_:new AudioContext({sampleRate:c,latencyHint:`interactive`});async function b(){let e=v?[_]:[_,y];await Promise.all(e.map(e=>e.close().catch(e=>{console.warn(`AudioContext close failed:`,e)})))}let x=navigator.mediaDevices.getUserMedia({audio:{deviceId:{ideal:`default`},...n}}),S;try{[S]=await Promise.all([x,_.resume(),y.resume(),y.audioWorklet.addModule(u),_.audioWorklet.addModule(d)]),r(y.sampleRate,c,`capture`),r(_.sampleRate,l,`playback`)}catch(e){throw a(x),await b(),e}let C=y.createMediaStreamSource(S),w=o(y,f,g);C.connect(w.node),w.node.onprocessorerror=()=>p?.(i(`capture`)),w.start();let T=null,E=null,D=0,O=null,k=new AbortController;function A(){E?.(),E=null,O=null}function j(e){e.stats&&e.stats.concealedSamples>0&&m?.(e.stats),e.reason!==`interrupt`&&(O===null||e.turn===O)&&A()}function M(){if(T)return T;let e=new AudioWorkletNode(_,`playback-processor`);return e.connect(_.destination),e.port.onmessage=e=>{e.data.event===`stop`?j(e.data):e.data.event===`progress`&&h?.(e.data.bufferedMs)},e.onprocessorerror=()=>{let e=i(`playback`);A(),p?.(e)},T=e,e}let N={enqueue(e){k.signal.aborted||e.byteLength!==0&&M().port.postMessage({event:`write`,buffer:new Uint8Array(e)},[e])},done(){if(!T)return Promise.resolve();let n=++D;if(T.port.postMessage({event:`done`,turn:n}),_.state!==`running`)return O=null,Promise.resolve();let{promise:r,resolve:i}=Promise.withResolvers();E?.();let a=()=>{clearInterval(o),clearTimeout(s),E===a&&(E=null,O=null),i()},o=setInterval(()=>{_.state!==`running`&&a()},t),s=setTimeout(a,e);return E=a,O=n,r},flush(){T&&(A(),T.port.postMessage({event:`interrupt`}))},async close(){if(!k.signal.aborted){k.abort(),await w.stop(),C.disconnect(),w.node.disconnect(),T&&T.disconnect();for(let e of S.getTracks())e.stop();await b()}},async[Symbol.asyncDispose](){await N.close()}};return N}export{s as createVoiceIO};
1
+ import{a as e,o as t}from"./client-audio-constants-CP13UQZt.js";var n={echoCancellation:!0,noiseSuppression:!1,autoGainControl:!1,voiceIsolation:!1};function r(e,t,n){if(e!==t)throw Error(`Browser refused the ${n} sample rate: asked for ${t} Hz, got ${e} Hz`)}function i(e){let t=Error(`Audio ${e} worklet crashed`);return console.error(`[aai-ui]`,t.message),t}function a(e){e.then(e=>{for(let t of e.getTracks())t.stop()}).catch(()=>{})}function o(e,t,n){let r=new AudioWorkletNode(e,`capture-processor`,{channelCount:1,channelCountMode:`explicit`}),i=null;return r.port.onmessage=e=>{let r=e.data;r.event===`chunk`&&r.buffer?t(r.buffer):r.event===`silent`?n?.():r.event===`stopped`&&(i?.(),i=null)},{node:r,start(){r.port.postMessage({event:`start`})},stop(){let{promise:e,resolve:t}=Promise.withResolvers(),n=setTimeout(t,250);return i=()=>{clearTimeout(n),t()},r.port.postMessage({event:`stop`}),e}}}async function s(s){let{sttSampleRate:c,ttsSampleRate:l,captureWorkletSrc:u,playbackWorkletSrc:d,onMicData:f,onError:p,onPlaybackStats:m,onPlaybackProgress:h,onMicSilent:g}=s,_=new AudioContext({sampleRate:l,latencyHint:`playback`}),v=c===l,y=v?_:new AudioContext({sampleRate:c,latencyHint:`interactive`});async function b(){let e=v?[_]:[_,y];await Promise.all(e.map(e=>e.close().catch(e=>{console.warn(`AudioContext close failed:`,e)})))}let x=navigator.mediaDevices.getUserMedia({audio:{deviceId:{ideal:`default`},...n}}),S;try{[S]=await Promise.all([x,_.resume(),y.resume(),y.audioWorklet.addModule(u),_.audioWorklet.addModule(d)]),r(y.sampleRate,c,`capture`),r(_.sampleRate,l,`playback`)}catch(e){throw a(x),await b(),e}let C=y.createMediaStreamSource(S),w=o(y,f,g);C.connect(w.node),w.node.onprocessorerror=()=>p?.(i(`capture`)),w.start();let T=null,E=0,D=null,O=new AbortController;function k(){let e=D;D=null,e?.settle()}function A(e){e.stats&&e.stats.concealedSamples>0&&m?.(e.stats),e.reason!==`interrupt`&&(D===null||e.turn===D.turn)&&k()}function j(){if(T)return T;let e=new AudioWorkletNode(_,`playback-processor`);return e.connect(_.destination),e.port.onmessage=e=>{e.data.event===`stop`?A(e.data):e.data.event===`progress`&&h?.(e.data.bufferedMs)},e.onprocessorerror=()=>{let e=i(`playback`);k(),p?.(e)},T=e,e}let M={enqueue(e){O.signal.aborted||e.byteLength!==0&&j().port.postMessage({event:`write`,buffer:new Uint8Array(e)},[e])},done(){if(!T)return Promise.resolve();let n=++E;if(T.port.postMessage({event:`done`,turn:n}),_.state!==`running`)return k(),Promise.resolve();let{promise:r,resolve:i}=Promise.withResolvers();k();let a=()=>{clearInterval(o),clearTimeout(s),D?.settle===a&&(D=null),i()},o=setInterval(()=>{_.state!==`running`&&a()},t),s=setTimeout(a,e);return D={turn:n,settle:a},r},flush(){T&&(k(),T.port.postMessage({event:`interrupt`}))},async close(){if(!O.signal.aborted){O.abort(),await w.stop(),C.disconnect(),w.node.disconnect(),T&&T.disconnect();for(let e of S.getTracks())e.stop();await b()}},async[Symbol.asyncDispose](){await M.close()}};return M}export{s as createVoiceIO};
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-600:oklch(57.7% .245 27.325);--spacing:.25rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-aai-surface:var(--aai-surface,#fff);--color-aai-text:var(--aai-text,#1b1a18);--color-aai-border:var(--aai-border,#dcd7cc);--font-aai:"Monument Grotesk", "ABC Monument Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif;--font-aai-serif:"Source Serif 4", "Source Serif Pro", Charter, "Iowan Old Style", Georgia, serif;--font-aai-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-aai:4px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}html,body{margin:0;padding:0}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.order-last{order:9999}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.box-border{box-sizing:border-box}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-\[7px\]{height:7px}.h-full{height:100%}.h-screen{height:100vh}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[40vh\]{max-height:40vh}.min-h-0{min-height:0}.min-h-5{min-height:calc(var(--spacing) * 5)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-\[7px\]{width:7px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-75{max-width:calc(var(--spacing) * 75)}.max-w-105{max-width:calc(var(--spacing) * 105)}.max-w-190{max-width:calc(var(--spacing) * 190)}.max-w-\[82\%\]{max-width:82%}.max-w-\[min\(78\%\,64ch\)\]{max-width:min(78%,64ch)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.basis-full{flex-basis:100%}.border-collapse{border-collapse:collapse}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.\[scrollbar-width\:none\]{scrollbar-width:none}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-\[1fr_320px\]{grid-template-columns:1fr 320px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-aai{border-radius:var(--radius-aai)}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\(--aai-btn-bd\){border-color:var(--aai-btn-bd)}.border-aai-border{border-color:var(--color-aai-border)}.bg-\(--aai-btn-bg\){background-color:var(--aai-btn-bg)}.bg-aai-surface{background-color:var(--color-aai-surface)}.bg-transparent{background-color:#0000}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-7{padding:calc(var(--spacing) * 7)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-aai{font-family:var(--font-aai)}.font-aai-mono{font-family:var(--font-aai-mono)}.font-aai-serif{font-family:var(--font-aai-serif)}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[22px\]{font-size:22px}.text-\[32px\]{font-size:32px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-\[23px\]{--tw-leading:23px;line-height:23px}.leading-\[130\%\]{--tw-leading:130%;line-height:130%}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.2px\]{--tw-tracking:-.2px;letter-spacing:-.2px}.tracking-\[1\.2px\]{--tw-tracking:1.2px;letter-spacing:1.2px}.tracking-\[1\.4px\]{--tw-tracking:1.4px;letter-spacing:1.4px}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-balance{text-wrap:balance}.wrap-break-word{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\(--aai-btn-fg\){color:var(--aai-btn-fg)}.text-aai-text{color:var(--color-aai-text)}.text-red-600{color:var(--color-red-600)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.file\:mr-3::file-selector-button{margin-right:calc(var(--spacing) * 3)}.file\:cursor-pointer::file-selector-button{cursor:pointer}.file\:rounded-aai::file-selector-button{border-radius:var(--radius-aai)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:px-3::file-selector-button{padding-inline:calc(var(--spacing) * 3)}.file\:py-1\.5::file-selector-button{padding-block:calc(var(--spacing) * 1.5)}.file\:font-aai::file-selector-button{font-family:var(--font-aai)}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:\[color\:var\(--aai-file-button-fg\)\]::file-selector-button{color:var(--aai-file-button-fg)}.file\:\[background\:var\(--aai-file-button-bg\)\]::file-selector-button{background:var(--aai-file-button-bg)}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.focus-visible\:\[outline\:2px_solid\]:focus-visible{outline:2px solid}.focus-visible\:\[outline-offset\:2px\]:focus-visible{outline-offset:2px}@media (hover:hover){.enabled\:hover\:border-\(--aai-btn-bd-hover\):enabled:hover{border-color:var(--aai-btn-bd-hover)}.enabled\:hover\:bg-\(--aai-btn-bg-hover\):enabled:hover{background-color:var(--aai-btn-bg-hover)}.enabled\:hover\:text-\(--aai-btn-fg-hover\):enabled:hover{color:var(--aai-btn-fg-hover)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:ml-auto{margin-left:auto}.sm\:max-w-\[60\%\]{max-width:60%}.sm\:basis-auto{flex-basis:auto}.sm\:px-16{padding-inline:calc(var(--spacing) * 16)}.sm\:py-14{padding-block:calc(var(--spacing) * 14)}}@media (width>=48rem){.md\:order-none{order:0}.md\:h-screen{height:100vh}.md\:max-h-none{max-height:none}.md\:w-\(--aai-sidebar-w\){width:var(--aai-sidebar-w)}.md\:flex-row{flex-direction:row}.md\:border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.md\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.md\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.md\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}}}@keyframes aai-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.82)}}@keyframes aai-bounce{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}@keyframes aai-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.tool-shimmer{-webkit-text-fill-color:transparent;background:linear-gradient(90deg,currentColor 25%,#0000 50%,currentColor 75%) 0 0/200% 100%;-webkit-background-clip:text;background-clip:text;animation:2s infinite aai-shimmer}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}