@seams/voice-capture 0.0.0-stage → 0.67.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 (48) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +174 -2
  3. package/dist/assets/NOTICE.txt +3 -0
  4. package/dist/assets/SILERO_LICENSE.txt +21 -0
  5. package/dist/assets/ort-wasm-simd-threaded.mjs +59 -0
  6. package/dist/assets/ort-wasm-simd-threaded.wasm +0 -0
  7. package/dist/assets/silero-vad.onnx +0 -0
  8. package/dist/assets/voice-activity-worklet.js +21 -0
  9. package/dist/browser/card.js +800 -0
  10. package/dist/browser/chunks/microphone-CU5gQG6w.js +1 -0
  11. package/dist/browser/chunks/ort.wasm.bundle.min-CWqlff_l.js +3 -0
  12. package/dist/browser/index.js +1 -0
  13. package/dist/esm/card/index.js +6 -0
  14. package/dist/esm/card/phraseCard.js +459 -0
  15. package/dist/esm/card/prompt.js +1074 -0
  16. package/dist/esm/card/ribbon.js +489 -0
  17. package/dist/esm/card/surface.js +224 -0
  18. package/dist/esm/card/types.js +0 -0
  19. package/dist/esm/card/visual.js +2 -0
  20. package/dist/esm/chunks/visual-Di3ojTED.js +1520 -0
  21. package/dist/esm/config.js +42 -0
  22. package/dist/esm/index.js +8 -0
  23. package/dist/esm/inference.js +193 -0
  24. package/dist/esm/microphone.js +428 -0
  25. package/dist/esm/microphoneInput.js +117 -0
  26. package/dist/esm/speechPause.js +33 -0
  27. package/dist/esm/voiceActivity.js +69 -0
  28. package/dist/esm/wav.js +36 -0
  29. package/dist/example/example.js +71 -0
  30. package/dist/example/index.html +29 -0
  31. package/dist/hosting.d.mts +4 -0
  32. package/dist/hosting.mjs +26 -0
  33. package/dist/types/card/index.d.ts +6 -0
  34. package/dist/types/card/phraseCard.d.ts +72 -0
  35. package/dist/types/card/prompt.d.ts +122 -0
  36. package/dist/types/card/ribbon.d.ts +62 -0
  37. package/dist/types/card/surface.d.ts +28 -0
  38. package/dist/types/card/types.d.ts +65 -0
  39. package/dist/types/card/visual.d.ts +25 -0
  40. package/dist/types/config.d.ts +47 -0
  41. package/dist/types/index.d.ts +7 -0
  42. package/dist/types/inference.d.ts +47 -0
  43. package/dist/types/microphone.d.ts +81 -0
  44. package/dist/types/microphoneInput.d.ts +19 -0
  45. package/dist/types/speechPause.d.ts +8 -0
  46. package/dist/types/voiceActivity.d.ts +15 -0
  47. package/dist/types/wav.d.ts +9 -0
  48. package/package.json +57 -4
@@ -0,0 +1,1520 @@
1
+ import { styleNonce } from "../config.js";
2
+ import { VoiceRibbon } from "../card/ribbon.js";
3
+ import { createElement, render } from "preact";
4
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
5
+ import { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState } from "preact/compat";
6
+ //#region node_modules/.pnpm/voice-glow@0.2.1_react-dom@19.3.1_react@19.3.1__react@19.3.1/node_modules/voice-glow/dist/index.es.js
7
+ function wa(n) {
8
+ const e = n.trim(), a = e.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
9
+ if (a) {
10
+ const t = a[1].length === 3 ? a[1].split("").map((s) => s + s).join("") : a[1];
11
+ return [
12
+ parseInt(t.slice(0, 2), 16),
13
+ parseInt(t.slice(2, 4), 16),
14
+ parseInt(t.slice(4, 6), 16)
15
+ ];
16
+ }
17
+ const r = e.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);
18
+ return r ? [
19
+ Math.round(+r[1]),
20
+ Math.round(+r[2]),
21
+ Math.round(+r[3])
22
+ ] : null;
23
+ }
24
+ function qa(n) {
25
+ const e = wa(n);
26
+ return e ? `rgb(${e[0]}, ${e[1]}, ${e[2]})` : null;
27
+ }
28
+ function Ne(n) {
29
+ const e = wa(n);
30
+ return e ? `${e[0]}, ${e[1]}, ${e[2]}` : null;
31
+ }
32
+ const Ga = {
33
+ dark: {
34
+ strokeOpacity: 1.16,
35
+ innerOpacity: .47,
36
+ bloomOpacity: .89,
37
+ innerShadow: "rgba(255, 255, 255, 0.1)",
38
+ saturation: 1.2,
39
+ brightness: 1.1
40
+ },
41
+ light: {
42
+ strokeOpacity: 1.2,
43
+ innerOpacity: .85,
44
+ bloomOpacity: .5,
45
+ innerShadow: "rgba(0, 0, 0, 0.08)",
46
+ saturation: 1.6,
47
+ brightness: .95,
48
+ hueRange: 40,
49
+ hueDuration: 8.5,
50
+ hueBase: 5,
51
+ strength: .8,
52
+ bandStrength: 1.7
53
+ }
54
+ }, we = [
55
+ {
56
+ x: 0,
57
+ w: 74,
58
+ h: 46,
59
+ band: 0
60
+ },
61
+ {
62
+ x: -36,
63
+ w: 54,
64
+ h: 40,
65
+ band: 1
66
+ },
67
+ {
68
+ x: 36,
69
+ w: 54,
70
+ h: 40,
71
+ band: 1
72
+ },
73
+ {
74
+ x: -72,
75
+ w: 48,
76
+ h: 32,
77
+ band: 2
78
+ },
79
+ {
80
+ x: 72,
81
+ w: 48,
82
+ h: 32,
83
+ band: 2
84
+ },
85
+ {
86
+ x: -108,
87
+ w: 42,
88
+ h: 26,
89
+ band: 1
90
+ },
91
+ {
92
+ x: 108,
93
+ w: 42,
94
+ h: 26,
95
+ band: 1
96
+ }
97
+ ], Ka = 36 * we.length, Va = {
98
+ colorful: {
99
+ dark: [
100
+ "rgb(255, 70, 120)",
101
+ "rgb(60, 190, 255)",
102
+ "rgb(175, 70, 255)",
103
+ "rgb(60, 220, 130)",
104
+ "rgb(255, 150, 40)",
105
+ "rgb(90, 100, 255)",
106
+ "rgb(40, 200, 190)"
107
+ ],
108
+ light: [
109
+ "rgb(255, 201, 21)",
110
+ "rgb(126, 196, 255)",
111
+ "rgb(180, 40, 230)",
112
+ "rgb(235, 100, 160)",
113
+ "rgb(255, 176, 122)",
114
+ "rgb(154, 160, 255)",
115
+ "rgb(127, 217, 238)"
116
+ ]
117
+ },
118
+ mono: {
119
+ dark: [
120
+ "rgb(215, 215, 215)",
121
+ "rgb(180, 180, 180)",
122
+ "rgb(190, 190, 190)",
123
+ "rgb(160, 160, 160)",
124
+ "rgb(170, 170, 170)",
125
+ "rgb(150, 150, 150)",
126
+ "rgb(155, 155, 155)"
127
+ ],
128
+ light: [
129
+ "rgb(60, 60, 60)",
130
+ "rgb(90, 90, 90)",
131
+ "rgb(85, 85, 85)",
132
+ "rgb(110, 110, 110)",
133
+ "rgb(105, 105, 105)",
134
+ "rgb(125, 125, 125)",
135
+ "rgb(120, 120, 120)"
136
+ ]
137
+ },
138
+ ocean: {
139
+ dark: [
140
+ "rgb(80, 140, 255)",
141
+ "rgb(40, 200, 230)",
142
+ "rgb(120, 90, 255)",
143
+ "rgb(30, 170, 210)",
144
+ "rgb(160, 80, 240)",
145
+ "rgb(60, 110, 255)",
146
+ "rgb(40, 190, 180)"
147
+ ],
148
+ light: [
149
+ "rgb(40, 100, 240)",
150
+ "rgb(20, 160, 200)",
151
+ "rgb(90, 60, 230)",
152
+ "rgb(20, 130, 180)",
153
+ "rgb(130, 50, 220)",
154
+ "rgb(40, 80, 230)",
155
+ "rgb(20, 150, 150)"
156
+ ]
157
+ },
158
+ sunset: {
159
+ dark: [
160
+ "rgb(255, 110, 60)",
161
+ "rgb(255, 180, 40)",
162
+ "rgb(255, 60, 90)",
163
+ "rgb(255, 210, 80)",
164
+ "rgb(240, 70, 140)",
165
+ "rgb(255, 140, 50)",
166
+ "rgb(230, 50, 110)"
167
+ ],
168
+ light: [
169
+ "rgb(235, 80, 30)",
170
+ "rgb(230, 150, 10)",
171
+ "rgb(230, 30, 70)",
172
+ "rgb(225, 175, 30)",
173
+ "rgb(215, 40, 110)",
174
+ "rgb(235, 110, 20)",
175
+ "rgb(205, 30, 90)"
176
+ ]
177
+ },
178
+ forest: {
179
+ dark: [
180
+ "rgb(70, 220, 120)",
181
+ "rgb(40, 200, 180)",
182
+ "rgb(140, 230, 80)",
183
+ "rgb(30, 170, 140)",
184
+ "rgb(190, 235, 70)",
185
+ "rgb(50, 190, 110)",
186
+ "rgb(30, 150, 120)"
187
+ ],
188
+ light: [
189
+ "rgb(30, 170, 80)",
190
+ "rgb(20, 150, 130)",
191
+ "rgb(90, 180, 30)",
192
+ "rgb(20, 130, 100)",
193
+ "rgb(130, 180, 20)",
194
+ "rgb(30, 150, 80)",
195
+ "rgb(20, 120, 90)"
196
+ ]
197
+ },
198
+ candy: {
199
+ dark: [
200
+ "rgb(255, 90, 170)",
201
+ "rgb(255, 120, 220)",
202
+ "rgb(210, 80, 255)",
203
+ "rgb(255, 150, 190)",
204
+ "rgb(180, 110, 255)",
205
+ "rgb(255, 70, 140)",
206
+ "rgb(230, 100, 240)"
207
+ ],
208
+ light: [
209
+ "rgb(235, 40, 140)",
210
+ "rgb(230, 70, 190)",
211
+ "rgb(180, 40, 230)",
212
+ "rgb(235, 100, 160)",
213
+ "rgb(150, 70, 230)",
214
+ "rgb(230, 30, 110)",
215
+ "rgb(200, 60, 210)"
216
+ ]
217
+ },
218
+ ice: {
219
+ dark: [
220
+ "rgb(150, 230, 255)",
221
+ "rgb(90, 200, 255)",
222
+ "rgb(190, 240, 255)",
223
+ "rgb(120, 190, 255)",
224
+ "rgb(160, 220, 250)",
225
+ "rgb(80, 170, 255)",
226
+ "rgb(200, 235, 255)"
227
+ ],
228
+ light: [
229
+ "rgb(30, 160, 220)",
230
+ "rgb(20, 130, 210)",
231
+ "rgb(60, 180, 230)",
232
+ "rgb(40, 120, 220)",
233
+ "rgb(50, 160, 220)",
234
+ "rgb(20, 110, 220)",
235
+ "rgb(70, 170, 230)"
236
+ ]
237
+ },
238
+ gold: {
239
+ dark: [
240
+ "rgb(255, 200, 70)",
241
+ "rgb(255, 170, 40)",
242
+ "rgb(255, 220, 110)",
243
+ "rgb(240, 150, 30)",
244
+ "rgb(255, 235, 140)",
245
+ "rgb(230, 160, 40)",
246
+ "rgb(250, 210, 90)"
247
+ ],
248
+ light: [
249
+ "rgb(200, 140, 10)",
250
+ "rgb(190, 120, 0)",
251
+ "rgb(210, 160, 30)",
252
+ "rgb(180, 110, 0)",
253
+ "rgb(205, 170, 40)",
254
+ "rgb(175, 115, 5)",
255
+ "rgb(195, 150, 20)"
256
+ ]
257
+ }
258
+ };
259
+ function ja(n, e) {
260
+ const a = n.match(/^rgb\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/);
261
+ return a ? `rgba(${a[1]}, ${a[2]}, ${a[3]}, ${e.toFixed(2)})` : n;
262
+ }
263
+ function lt(n, e = 1) {
264
+ return Math.max(.5, Math.round(n * e * 100) / 100);
265
+ }
266
+ function Xa(n, e) {
267
+ return `calc(50% + (var(--vb-cx-${e}) + var(--vb-x${n}-${e})) * var(--vb-w-${e}) * var(--vb-z-${e}, 1))`;
268
+ }
269
+ function dt({ id: n, colors: e, alpha: a, sw: r, sh: t, y: s, fade: o, count: i }) {
270
+ return (i ? we.slice(0, i) : we).map((l, p) => {
271
+ const b = a >= 1 ? e[p % e.length] : ja(e[p % e.length], a), m = `calc(${Math.round(l.w * r)}px * var(--vb-w-${n}) * var(--vb-z-${n}, 1))`, d = `calc(${Math.round(l.h * t)}px * var(--vb-h-${n}) * var(--vb-l${p}-${n}) * var(--vb-z-${n}, 1))`, h = `calc(100% + (${s}px + var(--vb-y${p}-${n})) * var(--vb-z-${n}, 1))`;
272
+ return `radial-gradient(ellipse ${m} ${d} at ${Xa(p, n)} ${h}, ${b} 0%, transparent ${o}%)`;
273
+ }).join(`,
274
+ `);
275
+ }
276
+ function Ya(n) {
277
+ const { id: e, borderRadius: a, borderWidth: r, strokeOpacity: t, innerOpacity: s, bloomOpacity: o, innerShadow: i, colorVariant: u, colors: l, brightness: p, saturation: b, theme: m, hueBase: d = 0, glowSize: h = 1, glowWidth: T = 1, glowHeight: O = 1, strokeScale: L = 1, innerScale: _ = 1, innerHeight: G = 1, bloomScale: U = 1, bloomHeight: E = 1, coreSize: D = 1, coreLight: C = 0, coreLightWidth: z = 1, coreLightHeight: g = 1, rangeWidth: H = 1, rangeHeight: Q = 1, softness: le = 1, distortion: K = !1, scale: W = 1 } = n, R = Math.round(28 * W * 10) / 10, I = Math.round(9 * W * 10) / 10, P = Math.max(0, a - r), v = Math.round(Math.max(40, Math.min(95, 70 * le))), k = ($) => T * $, w = ($) => O * $, S = ($) => Math.round($ * 10) / 10, x = `var(--vb-z-${e}, 1)`, y = ($) => `calc(${S($)}px * ${x})`, oe = m === "dark", re = Va[u][oe ? "dark" : "light"].map(($, A) => {
278
+ const N = l == null ? void 0 : l[A];
279
+ return N && qa(N) || $;
280
+ }), V = u === "mono" ? .6 : 1, Me = (t * V).toFixed(2), ue = (s * V).toFixed(2), f = (o * V).toFixed(2), B = p.toFixed(2), j = b.toFixed(2), Z = `hue-rotate(calc(var(--voice-hue-base, ${d}deg) + var(--vb-hue-${e})))`, ge = K ? ` url(#vb-distort-${e})` : "", Fe = `filter: ${Z} brightness(${B}) saturate(${j});`, Ye = `filter: ${Z} brightness(${B}) saturate(${j})${ge};`, Je = `filter: blur(${y(lt(10, h))}) ${Z} brightness(${B}) saturate(${j});`, Qe = `filter: blur(${y(lt(10, h))}) ${Z} brightness(${B}) saturate(${j})${ge};`, pe = `calc(50% + var(--vb-cx-${e}) * var(--vb-w-${e}) * ${x})`, Re = `calc(100% + (2px + var(--vb-cy-${e})) * ${x})`, Ze = oe ? `radial-gradient(ellipse calc(${S(30 * D)}px * var(--vb-w-${e}) * ${x}) calc(${S(30 * D)}px * var(--vb-h-${e}) * ${x}) at ${pe} ${Re}, rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0.14) 30%, transparent 65%)` : `radial-gradient(ellipse calc(${S(40 * D)}px * var(--vb-w-${e}) * ${x}) calc(${S(30 * D)}px * var(--vb-h-${e}) * ${x}) at ${pe} ${Re}, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.22) 35%, transparent 70%)`, et = dt({
281
+ id: e,
282
+ colors: re,
283
+ alpha: 1,
284
+ sw: k(L),
285
+ sh: w(L),
286
+ y: 2,
287
+ fade: v
288
+ }), tt = dt({
289
+ id: e,
290
+ colors: re,
291
+ alpha: .46,
292
+ sw: k(.9 * _),
293
+ sh: w(.9 * _ * G),
294
+ y: 0,
295
+ fade: v
296
+ }), at = dt({
297
+ id: e,
298
+ colors: re,
299
+ alpha: oe ? .9 : .7,
300
+ sw: k(1.15 * U),
301
+ sh: w(1.5 * U * E),
302
+ y: 0,
303
+ fade: Math.min(95, v + 2)
304
+ }), ie = ($, A, N, ae = 0) => `radial-gradient(ellipse calc(${S($ * H)}px * var(--vb-w-${e}) * var(--vb-mw-${e}) * ${x}) calc((${S(A * Q)}px * var(--vb-h-${e}) + var(--vb-bh-${e})) * ${x}) at ${pe} calc(100% + var(--vb-cy-${e}) * ${x}), white 0%, rgba(255, 255, 255, 0.5) ${N}%${ae > 0 ? `, rgba(255, 255, 255, ${ae}) 85%` : ""}, transparent 100%)`, fe = ($, A) => `opacity: calc(var(--vb-opacity-${e}, 1) * var(--vb-glow-${e}) * ${A} * var(--voice-${$}-opacity, 1) * var(--voice-strength, 1));`, Pe = ($, A, N, ae) => `${$} {
305
+ ${A}
306
+ position: absolute;
307
+ inset: 0;
308
+ border-radius: ${y(a)};
309
+ background: ${tt};
310
+ box-shadow: inset 0 0 ${y(I)} 1px ${i};
311
+ -webkit-mask-image:
312
+ ${ie(170, 64, 45, .3)},
313
+ linear-gradient(white, transparent ${y(R)}, transparent calc(100% - ${R}px * ${x}), white),
314
+ linear-gradient(to right, white, transparent ${y(R)}, transparent calc(100% - ${R}px * ${x}), white);
315
+ -webkit-mask-composite: source-in, source-over;
316
+ mask-image:
317
+ ${ie(170, 64, 45, .3)},
318
+ linear-gradient(white, transparent ${y(R)}, transparent calc(100% - ${R}px * ${x}), white),
319
+ linear-gradient(to right, white, transparent ${y(R)}, transparent calc(100% - ${R}px * ${x}), white);
320
+ mask-composite: intersect, add;
321
+ pointer-events: none;
322
+ /* Its own compositing layer: WebKit otherwise re-rasterizes the
323
+ filtered layer into the parent every frame on the CPU (a phone-sized
324
+ host runs at a sixth of the frame rate without this). */
325
+ will-change: transform;
326
+ z-index: 1;
327
+ ${N}
328
+ ${fe("inner", ue)}
329
+ ${ae}
330
+ }`;
331
+ return `
332
+ @property --vb-opacity-${e} {
333
+ syntax: "<number>";
334
+ initial-value: 0;
335
+ inherits: true;
336
+ }
337
+
338
+ [data-voice-beam="${e}"] {
339
+ position: relative;
340
+ border-radius: ${a}px;
341
+ overflow: hidden;
342
+ --vb-h-${e}: 0.8;
343
+ --vb-w-${e}: 1;
344
+ ${we.map(($, A) => ` --vb-x${A}-${e}: ${$.x}px;
345
+ --vb-l${A}-${e}: 1;
346
+ --vb-y${A}-${e}: 0px;`).join(`
347
+ `)}
348
+ --vb-glow-${e}: 0.4;
349
+ --vb-z-${e}: 1;
350
+ --vb-cx-${e}: 0px;
351
+ --vb-cy-${e}: 0px;
352
+ --vb-bh-${e}: 0px;
353
+ --vb-bendA-${e}: 0;
354
+ --vb-mw-${e}: 1;
355
+ --vb-hue-${e}: 0deg;
356
+ --vb-level-${e}: 0;
357
+ }
358
+
359
+ [data-voice-beam="${e}"][data-active] {
360
+ animation: vb-fade-in-${e} 0.6s ease forwards;
361
+ }
362
+
363
+ [data-voice-beam="${e}"][data-fading] {
364
+ animation: vb-fade-out-${e} 0.5s ease forwards;
365
+ }
366
+
367
+ /* Stroke — the colours painted into the 1px edge ring, masked to the centred ellipse. */
368
+ [data-voice-beam="${e}"][data-active]::after,
369
+ [data-voice-beam="${e}"][data-fading]::after {
370
+ content: "";
371
+ position: absolute;
372
+ inset: 0;
373
+ border-radius: ${y(P)};
374
+ padding: ${y(r)};
375
+ clip-path: inset(0 round ${y(a)});
376
+ background:
377
+ ${Ze},
378
+ ${et};
379
+ -webkit-mask:
380
+ ${ie(170, 64, 45)},
381
+ linear-gradient(#fff 0 0) content-box,
382
+ linear-gradient(#fff 0 0);
383
+ -webkit-mask-composite: source-in, xor;
384
+ mask:
385
+ ${ie(170, 64, 45)},
386
+ linear-gradient(#fff 0 0) content-box,
387
+ linear-gradient(#fff 0 0);
388
+ mask-composite: intersect, exclude;
389
+ pointer-events: none;
390
+ /* Its own compositing layer: WebKit otherwise re-rasterizes the
391
+ filtered layer into the parent every frame on the CPU (a phone-sized
392
+ host runs at a sixth of the frame rate without this). */
393
+ will-change: transform;
394
+ z-index: 2;
395
+ ${fe("stroke", Me)}
396
+ ${Fe}
397
+ }
398
+
399
+ /* Inner glow — soft light inside the element, faded off at the corners.
400
+ With distortion on, this copy is clipped to ABOVE the band line (the
401
+ polygon the driver writes each frame) and a mirror layer below carries
402
+ the displacement filter, so only the glow under the line warps. */
403
+ ${Pe(`[data-voice-beam="${e}"][data-active]::before,
404
+ [data-voice-beam="${e}"][data-fading]::before`, "content: \"\";", K ? `clip-path: var(--vb-clip-above-${e}, inset(0 round ${a}px));` : `clip-path: inset(0 round ${a}px);`, Fe)}
405
+ ${K ? Pe(`[data-voice-beam="${e}"][data-active] [data-voice-beam-warp="inner"],
406
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-warp="inner"]`, "display: block;", `clip-path: var(--vb-clip-below-${e}, inset(0 round ${a}px));`, Ye) : ""}
407
+
408
+ /* Bloom — the blurred halo, tallest of the three, above the content. */
409
+ [data-voice-beam="${e}"] [data-voice-beam-bloom],
410
+ [data-voice-beam="${e}"] [data-voice-beam-warp] {
411
+ display: none;
412
+ position: absolute;
413
+ inset: 0;
414
+ border-radius: ${y(P)};
415
+ pointer-events: none;
416
+ /* Its own compositing layer: WebKit otherwise re-rasterizes the
417
+ filtered layer into the parent every frame on the CPU (a phone-sized
418
+ host runs at a sixth of the frame rate without this). */
419
+ will-change: transform;
420
+ opacity: 0;
421
+ }
422
+
423
+ [data-voice-beam="${e}"] [data-voice-beam-bloom],
424
+ [data-voice-beam="${e}"] [data-voice-beam-warp="bloom"] {
425
+ -webkit-mask: ${ie(200, 130, 35)};
426
+ mask: ${ie(200, 130, 35)};
427
+ background: ${at};
428
+ z-index: 3;
429
+ }
430
+
431
+ [data-voice-beam="${e}"][data-active] [data-voice-beam-bloom],
432
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-bloom] {
433
+ display: block;
434
+ clip-path: ${K ? `var(--vb-clip-above-${e}, inset(0 round ${a}px))` : `inset(0 round ${a}px)`};
435
+ ${fe("bloom", f)}
436
+ ${Je}
437
+ }
438
+ ${K ? `
439
+ [data-voice-beam="${e}"][data-active] [data-voice-beam-warp="bloom"],
440
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-warp="bloom"] {
441
+ display: block;
442
+ clip-path: var(--vb-clip-below-${e}, inset(0 round ${a}px));
443
+ ${fe("bloom", f)}
444
+ ${Qe}
445
+ }
446
+
447
+ /* Processing drops the distortion: the driver marks the wrapper once the
448
+ warp has faded out, the warp layers leave the paint and the base layers
449
+ give up their split at the band line. */
450
+ [data-voice-beam="${e}"][data-voice-warp="off"]::before,
451
+ [data-voice-beam="${e}"][data-voice-warp="off"] [data-voice-beam-bloom] {
452
+ clip-path: inset(0 round ${a}px);
453
+ }
454
+
455
+ [data-voice-beam="${e}"][data-voice-warp="off"] [data-voice-beam-warp] {
456
+ display: none;
457
+ }` : ""}
458
+
459
+ /* Epicentre — a soft white wash at the source, under the band line (the
460
+ driver's clip; unclipped when no line is drawn), sitting above every
461
+ glow layer and the band's halo so the centre reads lighter than the
462
+ band (same z as the band canvases, painted after them). Sized by the voice like the
463
+ other layers; off unless \`coreLight\` is set (the light theme sets it).
464
+ Up to 1 it is the wash's opacity; past 1 the solid white core widens
465
+ too, for a centre that stays lighter than a strong band. It follows the
466
+ glow's presence but not \`strength\`, which would only dim it. */
467
+ ${C > 0 ? (() => {
468
+ const $ = Math.max(0, Math.min(2, C - 1)), A = Math.min(1, $), N = Math.max(0, $ - 1), ae = 1 + .3 * $, nt = S(45 * A + 27 * N), ot = S(40 + 25 * A + 15 * N), rt = Math.min(1, .55 + .35 * A + .1 * N).toFixed(2), Le = S(72 + 14 * A + 8 * N);
469
+ return `[data-voice-beam="${e}"] [data-voice-beam-core] {
470
+ display: none;
471
+ position: absolute;
472
+ inset: 0;
473
+ border-radius: ${y(P)};
474
+ overflow: hidden;
475
+ pointer-events: none;
476
+ /* Its own compositing layer: WebKit otherwise re-rasterizes the
477
+ filtered layer into the parent every frame on the CPU (a phone-sized
478
+ host runs at a sixth of the frame rate without this). */
479
+ will-change: transform;
480
+ /* The blur sits on this wrapper and the band-line clip on the child,
481
+ so the cut edge is blurred too rather than left hard. */
482
+ filter: blur(${y(lt(8, h))});
483
+ z-index: 4;
484
+ }
485
+
486
+ [data-voice-beam="${e}"] [data-voice-beam-core] > div {
487
+ position: absolute;
488
+ inset: 0;
489
+ background: radial-gradient(ellipse calc(${S(120 * z * ae * W)}px * var(--vb-w-${e}) * ${x}) calc((${S(70 * g * ae * W)}px * var(--vb-h-${e}) + var(--vb-bh-${e})) * ${x}) at ${pe} calc(100% + var(--vb-cy-${e}) * ${x}), white 0%, white ${nt}%, rgba(255, 255, 255, ${rt}) ${ot}%, transparent ${Le}%);
490
+ clip-path: var(--vb-clip-below-${e}, none);
491
+ }
492
+
493
+ [data-voice-beam="${e}"][data-active] [data-voice-beam-core],
494
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-core] {
495
+ display: block;
496
+ opacity: calc(var(--vb-opacity-${e}, 1) * min(1, var(--vb-glow-${e}) * ${Math.min(1, C).toFixed(2)} * ${(1.6 + 1.4 * $).toFixed(2)}) * var(--voice-core-light-opacity, 1));
497
+ }
498
+ `;
499
+ })() : ""}
500
+ /* Band — the canvas the driver draws the bend's contour on: an organic
501
+ bell with chromatic fringes. Fades with the root, follows the strength
502
+ and turns with the hue drift like the other layers. */
503
+ [data-voice-beam="${e}"] [data-voice-beam-band],
504
+ [data-voice-beam="${e}"] [data-voice-beam-band-halo] {
505
+ display: none;
506
+ position: absolute;
507
+ inset: 0;
508
+ width: 100%;
509
+ height: 100%;
510
+ pointer-events: none;
511
+ /* Its own compositing layer: WebKit otherwise re-rasterizes the
512
+ filtered layer into the parent every frame on the CPU (a phone-sized
513
+ host runs at a sixth of the frame rate without this). */
514
+ will-change: transform;
515
+ z-index: 4;
516
+ }
517
+
518
+ [data-voice-beam="${e}"][data-active] [data-voice-beam-band],
519
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-band],
520
+ [data-voice-beam="${e}"][data-active] [data-voice-beam-band-halo],
521
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-band-halo] {
522
+ display: block;
523
+ opacity: calc(var(--vb-opacity-${e}, 1) * var(--voice-band-opacity, 1) * var(--voice-strength, 1));
524
+ /* The blur vars are 0 where the canvas blurs its own strokes; where the
525
+ 2D context has no filter (WebKit) the driver sets them and the layers
526
+ are blurred here instead — the ridge on the band canvas, its wider
527
+ halo on the canvas beneath. */
528
+ filter: blur(var(--vb-band-blur-${e}, 0px)) ${Z} brightness(${B}) saturate(${j});
529
+ }
530
+
531
+ [data-voice-beam="${e}"][data-active] [data-voice-beam-band-halo],
532
+ [data-voice-beam="${e}"][data-fading] [data-voice-beam-band-halo] {
533
+ filter: blur(var(--vb-band-halo-blur-${e}, 0px)) ${Z} brightness(${B}) saturate(${j});
534
+ }
535
+
536
+ /* Resolution. The soft layers — inner light and its warp mirror, bloom and
537
+ its mirror, the epicentre — are rastered at half size and scaled back
538
+ up by the compositor: the box is halved, every length inside rides the
539
+ layer's factor \`--vb-z\` at 0.5 (the driver also writes the band-line
540
+ clips at half scale), and the will-change transform is rastered
541
+ pre-scale where the engine does that (Chromium, Safari 18). For blurred
542
+ gradients that is the same picture at a quarter of the raster and
543
+ filter work, which is what a phone at 3x runs out of. The 1px stroke
544
+ stays full-res on every screen: at half size it is half a CSS pixel,
545
+ which a 3x phone rasters into a faint smear instead of the hairline,
546
+ and the layer is cheap (no blur). The component sets
547
+ \`data-voice-halfres\`. */
548
+ [data-voice-beam="${e}"][data-voice-halfres]::before,
549
+ [data-voice-beam="${e}"][data-voice-halfres] [data-voice-beam-warp],
550
+ [data-voice-beam="${e}"][data-voice-halfres] [data-voice-beam-bloom],
551
+ [data-voice-beam="${e}"][data-voice-halfres] [data-voice-beam-core] {
552
+ --vb-z-${e}: 0.5;
553
+ inset: auto;
554
+ left: 0;
555
+ top: 0;
556
+ width: 50%;
557
+ height: 50%;
558
+ transform: translateZ(0) scale(2);
559
+ transform-origin: 0 0;
560
+ }
561
+ ${K ? `[data-voice-beam="${e}"][data-voice-halfres][data-active]::before,
562
+ [data-voice-beam="${e}"][data-voice-halfres][data-fading]::before,
563
+ [data-voice-beam="${e}"][data-voice-halfres][data-active] [data-voice-beam-bloom],
564
+ [data-voice-beam="${e}"][data-voice-halfres][data-fading] [data-voice-beam-bloom] {
565
+ clip-path: var(--vb-clip-above-z-${e}, inset(0 round ${y(a)}));
566
+ }
567
+ [data-voice-beam="${e}"][data-voice-halfres][data-active] [data-voice-beam-warp],
568
+ [data-voice-beam="${e}"][data-voice-halfres][data-fading] [data-voice-beam-warp] {
569
+ clip-path: var(--vb-clip-below-z-${e}, inset(0 round ${y(a)}));
570
+ }
571
+ /* Processing (warp off): the mirrors are gone, so the base layers paint
572
+ the whole box again — this must outweigh the split above. */
573
+ [data-voice-beam="${e}"][data-voice-halfres][data-voice-warp="off"]::before,
574
+ [data-voice-beam="${e}"][data-voice-halfres][data-voice-warp="off"] [data-voice-beam-bloom] {
575
+ clip-path: inset(0 round ${y(a)});
576
+ }` : `[data-voice-beam="${e}"][data-voice-halfres][data-active]::before,
577
+ [data-voice-beam="${e}"][data-voice-halfres][data-fading]::before,
578
+ [data-voice-beam="${e}"][data-voice-halfres][data-active] [data-voice-beam-bloom],
579
+ [data-voice-beam="${e}"][data-voice-halfres][data-fading] [data-voice-beam-bloom] {
580
+ clip-path: inset(0 round ${y(a)});
581
+ }`}
582
+ [data-voice-beam="${e}"][data-voice-halfres] [data-voice-beam-core] > div {
583
+ clip-path: var(--vb-clip-below-z-${e}, none);
584
+ }
585
+ @keyframes vb-fade-in-${e} {
586
+ to { --vb-opacity-${e}: 1; }
587
+ }
588
+
589
+ @keyframes vb-fade-out-${e} {
590
+ from { --vb-opacity-${e}: 1; }
591
+ to { --vb-opacity-${e}: 0; }
592
+ }
593
+
594
+ [data-voice-beam="${e}"][data-paused],
595
+ [data-voice-beam="${e}"][data-paused]::after,
596
+ [data-voice-beam="${e}"][data-paused]::before,
597
+ [data-voice-beam="${e}"][data-paused] [data-voice-beam-bloom] {
598
+ animation-play-state: paused !important;
599
+ }
600
+ `;
601
+ }
602
+ let Ae = null;
603
+ function xa() {
604
+ if (typeof window > "u") return null;
605
+ const n = window;
606
+ return n.AudioContext ?? n.webkitAudioContext ?? null;
607
+ }
608
+ function ya() {
609
+ const n = xa();
610
+ return n ? (Ae || (Ae = new n()), Ae.state === "suspended" && Ae.resume().catch(() => {}), Ae) : null;
611
+ }
612
+ const ht = /* @__PURE__ */ new WeakMap();
613
+ function Ja(n) {
614
+ const e = ya();
615
+ if (!e || n.getAudioTracks().length === 0) return null;
616
+ let a = ht.get(n);
617
+ a || (a = {
618
+ node: e.createMediaStreamSource(n),
619
+ refs: 0
620
+ }, ht.set(n, a)), a.refs += 1;
621
+ const r = e.createAnalyser();
622
+ r.fftSize = 1024, r.smoothingTimeConstant = .5, a.node.connect(r);
623
+ let t = !1;
624
+ return {
625
+ analyser: r,
626
+ release: () => {
627
+ if (!t) {
628
+ t = !0;
629
+ try {
630
+ a.node.disconnect(r);
631
+ } catch {}
632
+ if (a.refs -= 1, a.refs <= 0) {
633
+ try {
634
+ a.node.disconnect();
635
+ } catch {}
636
+ ht.delete(n);
637
+ }
638
+ }
639
+ }
640
+ };
641
+ }
642
+ const ua = /* @__PURE__ */ new WeakMap();
643
+ function Qa(n) {
644
+ let e = ua.get(n);
645
+ return e || (e = {
646
+ level: 0,
647
+ bands: [
648
+ 0,
649
+ 0,
650
+ 0
651
+ ],
652
+ phase: 0,
653
+ scanA: 0,
654
+ scanT: 0,
655
+ t: 0,
656
+ lastTs: 0,
657
+ warp: 1
658
+ }, ua.set(n, e)), e;
659
+ }
660
+ const Xe = /* @__PURE__ */ new Set();
661
+ let $e = null, ut = 0;
662
+ const Za = 1e3 / 60 - 2, en = 22, tn = 500, an = 4e3;
663
+ let Ve = 0, bt = !1, qe = !1, me = 0, ga = 0;
664
+ const Ma = Math.PI * 2, nn = 5, on = 1.7, rn = [
665
+ [80, 300],
666
+ [300, 2e3],
667
+ [2e3, 6e3]
668
+ ];
669
+ function Sa(n) {
670
+ return n < 0 ? 0 : n > 1 ? 1 : n;
671
+ }
672
+ function sn(n, e) {
673
+ const a = e / 2;
674
+ return ((n + a) % e + e) % e - a;
675
+ }
676
+ function cn(n, e) {
677
+ const a = n / (e / 2 + 4);
678
+ return Math.max(0, 1 - a * a);
679
+ }
680
+ function pa(n, e) {
681
+ if (n <= e) return 0;
682
+ const a = (n - e) / Math.max(.001, 1 - e);
683
+ return Sa((1 - Math.exp(-3 * a)) / (1 - Math.exp(-3)));
684
+ }
685
+ function Ge(n, e, a, r, t) {
686
+ const s = e > n ? r : t, o = 1 - Math.exp(-a / Math.max(.001, s));
687
+ return n + (e - n) * o;
688
+ }
689
+ const ln = 2, dn = .06, hn = .35, bn = .03, un = !(typeof navigator < "u" && /AppleWebKit/.test(navigator.userAgent) && !/Chrome\/|Chromium\/|Edg\/|OPR\//.test(navigator.userAgent)), fa = .05, gn = 6, pn = 12, fn = .1, va = .1, vn = 170, mn = 64, ma = 56;
690
+ function $n(n, e, a, r) {
691
+ const t = n < 0 ? 1 - r : 1 + r, s = Math.max(.05, a * t), o = Math.exp(-Math.pow(Math.abs(n) / s, e)), i = Math.exp(-Math.pow(1 / s, e));
692
+ return Math.max(0, (o - i) / (1 - i));
693
+ }
694
+ function wn(n, e, a, r, t) {
695
+ if (a <= 0 || e <= 0) return 0;
696
+ const s = e * Math.max(0, Math.min(.98, r));
697
+ if (n <= s) return 0;
698
+ const o = Math.min(1, (n - s) / Math.max(1, e - s));
699
+ return a * Math.pow(o, Math.max(.5, t));
700
+ }
701
+ function Ta(n, e, a) {
702
+ return Math.max(0, Math.min(n, e / 2, a / 2));
703
+ }
704
+ function gt(n, e, a, r = 0) {
705
+ if (a <= 0) return 0;
706
+ const t = Math.min(n, e - n) - r;
707
+ if (t >= a) return 0;
708
+ if (t <= 0) return a;
709
+ const s = a - t;
710
+ return a - Math.sqrt(Math.max(0, a * a - s * s));
711
+ }
712
+ function xn(n, e, a, r) {
713
+ const t = a / 2 + e.cx * e.w, s = vn * n.rangeWidth * e.w * e.mw, o = r * .82 * Math.min(1, n.scale), i = Math.min(o, (mn * n.rangeHeight * e.h + e.lift) * n.bandPosition), u = r - n.bandOffset, l = Math.min(1, e.corner * 4), p = n.bandTail * (1 - l * l * (3 - 2 * l)), b = p > .001, m = b ? n.bandTailOverflow : 0, d = b ? -m : t - s, h = b ? a + m : t + s, T = [];
714
+ for (let O = 0; O <= ma; O++) {
715
+ const L = d + (h - d) * O / ma, _ = Math.max(-1, Math.min(1, (L - t) / Math.max(1, s))), G = (L < t ? t : a - t) + m, U = $n(_, n.bandCurve, n.bandSpread, n.bandSkew) + wn(Math.abs(L - t), G, p, n.bandTailPosition, n.bandTailCurve), E = e.corner > 0 ? gt(L, a, Ta(n.radius, a, r)) * e.corner : 0;
716
+ T.push([L, u - i * U - E]);
717
+ }
718
+ return T;
719
+ }
720
+ function yn(n, e, a, r, t) {
721
+ for (const [s, o] of [["", 1], ["-z", .5]]) {
722
+ const i = (b) => (b * o).toFixed(1) + "px", u = a.map(([b, m]) => `${i(b)} ${i(m)}`), l = `polygon(0 ${i(t)}, ${u.join(", ")}, ${i(r)} ${i(t)})`, p = `polygon(0 0, ${i(r)} 0, ${i(r)} ${i(t)}, ${u.slice().reverse().join(", ")}, 0 ${i(t)})`;
723
+ n.style.setProperty(`--vb-clip-below${s}-${e}`, l), n.style.setProperty(`--vb-clip-above${s}-${e}`, p);
724
+ }
725
+ }
726
+ function Mn(n, e, a) {
727
+ let r = a;
728
+ for (let i = 0; i < e.length; i++) e[i][1] < r && (r = e[i][1]);
729
+ const t = Math.max(0, Math.min(.9, Math.floor((r - gn) / a / fa) * fa));
730
+ if (t === n.filterTop) return;
731
+ n.filterTop = t;
732
+ const s = 1 + Math.max(fn, pn / a), o = n.filter;
733
+ o.setAttribute("x", `${-va * 100}%`), o.setAttribute("width", `${(1 + 2 * va) * 100}%`), o.setAttribute("y", `${(t * 100).toFixed(0)}%`), o.setAttribute("height", `${((s - t) * 100).toFixed(1)}%`);
734
+ }
735
+ function Sn(n, e, a) {
736
+ const { canvas: r, ctx: t, el: s, config: o } = n;
737
+ if (!r || !t) return;
738
+ const i = s.clientWidth, u = s.clientHeight;
739
+ if (!i || !u) return;
740
+ const l = Math.min(ln, typeof window < "u" && window.devicePixelRatio || 1), p = Math.round(i * l), b = Math.round(u * l);
741
+ (r.width !== p || r.height !== b) && (r.width = p, r.height = b), t.setTransform(l, 0, 0, l, 0, 0), t.clearRect(0, 0, i, u);
742
+ const m = n.haloCanvas, d = n.haloCtx;
743
+ m && d && ((m.width !== p || m.height !== b) && (m.width = p, m.height = b), d.setTransform(l, 0, 0, l, 0, 0), d.clearRect(0, 0, i, u));
744
+ const h = Math.min(1, .6 * o.bandStrength * e.strength);
745
+ if (h < .005 || o.bandWidth <= 0) return;
746
+ const T = o.theme === "dark", O = o.bandWidth * (1 + .35 * e.level), L = o.bandAberration * (.35 + .65 * e.level), _ = (4 + 12 * L) * o.scale, G = 4 * L * o.scale, U = (v, k) => {
747
+ t.beginPath(), t.moveTo(a[0][0] + v, a[0][1] + k);
748
+ for (let w = 1; w < a.length; w++) t.lineTo(a[w][0] + v, a[w][1] + k);
749
+ }, E = {
750
+ r: o.bandColors.above,
751
+ g: o.bandColors.mid,
752
+ c: o.bandColors.core,
753
+ b: o.bandColors.below
754
+ }, D = (T ? .42 : .4) * h, C = 14 * O, z = 3.5 * o.bandWidth / 2, g = z * l, H = typeof t.filter == "string", Q = H ? "0px" : `${z.toFixed(2)}px`;
755
+ n.cssBlur !== Q && (s.style.setProperty(`--vb-band-blur-${o.id}`, Q), s.style.setProperty(`--vb-band-halo-blur-${o.id}`, H ? "0px" : `${(z * 3).toFixed(2)}px`), n.cssBlur = Q);
756
+ const le = [
757
+ [1, .16],
758
+ [.72, .2],
759
+ [.46, .26],
760
+ [.22, .34]
761
+ ], K = [
762
+ {
763
+ rgb: E.r,
764
+ a: 1,
765
+ ox: G,
766
+ oy: -_
767
+ },
768
+ {
769
+ rgb: E.g,
770
+ a: .55,
771
+ ox: G * .35,
772
+ oy: -_ * .35
773
+ },
774
+ {
775
+ rgb: E.b,
776
+ a: 1,
777
+ ox: -G,
778
+ oy: _
779
+ },
780
+ {
781
+ rgb: E.c,
782
+ a: .9,
783
+ ox: 0,
784
+ oy: 0
785
+ }
786
+ ];
787
+ t.lineCap = "round", t.lineJoin = "round", t.globalCompositeOperation = "source-over";
788
+ const W = a[0][0], R = a[a.length - 1][0], I = (v, k) => {
789
+ const w = t.createLinearGradient(W, 0, R, 0), S = o.bandTail > 0 ? .015 : .18;
790
+ return w.addColorStop(0, `rgba(${v}, 0)`), w.addColorStop(S, `rgba(${v}, ${k.toFixed(3)})`), w.addColorStop(1 - S, `rgba(${v}, ${k.toFixed(3)})`), w.addColorStop(1, `rgba(${v}, 0)`), w;
791
+ }, P = !H && d ? d : t;
792
+ H && (t.filter = `blur(${(g * 3).toFixed(1)}px)`), P.lineCap = "round", P.lineJoin = "round", P.strokeStyle = I(E.c, D * .3), P.lineWidth = C * 2.2, P.beginPath(), P.moveTo(a[0][0], a[0][1]);
793
+ for (let v = 1; v < a.length; v++) P.lineTo(a[v][0], a[v][1]);
794
+ P.stroke(), H && (t.filter = `blur(${g.toFixed(1)}px)`);
795
+ for (const v of K) for (const [k, w] of le) t.strokeStyle = I(v.rgb, D * v.a * w), t.lineWidth = Math.max(.6, C * k), U(v.ox, v.oy), t.stroke();
796
+ H && (t.filter = "none"), t.globalCompositeOperation = "source-over";
797
+ }
798
+ function Tn(n) {
799
+ return (1 - Math.cos(Ma * n)) / 2;
800
+ }
801
+ function kn(n, e) {
802
+ const a = n.analyser, r = n.time, t = n.freq;
803
+ a.getFloatTimeDomainData(r);
804
+ let s = 0;
805
+ for (let i = 0; i < r.length; i++) s += r[i] * r[i];
806
+ e.level = Math.sqrt(s / r.length) * nn * n.config.sensitivity, a.getByteFrequencyData(t);
807
+ const o = a.context.sampleRate / a.fftSize;
808
+ for (let i = 0; i < 3; i++) {
809
+ const [u, l] = rn[i], p = Math.max(0, Math.floor(u / o)), b = Math.min(t.length - 1, Math.ceil(l / o));
810
+ let m = 0;
811
+ for (let h = p; h <= b; h++) m += t[h];
812
+ const d = b >= p ? m / (b - p + 1) / 255 : 0;
813
+ e.bands[i] = d * on * n.config.sensitivity;
814
+ }
815
+ }
816
+ const be = {
817
+ level: 0,
818
+ bands: [
819
+ 0,
820
+ 0,
821
+ 0
822
+ ]
823
+ };
824
+ function ka(n) {
825
+ $e = requestAnimationFrame(ka);
826
+ const e = Ve ? n - Ve : 0;
827
+ if (Ve = n, bt) {
828
+ if (qe = !qe, qe) return;
829
+ n >= ga && (bt = !1, me = 0);
830
+ } else e > en ? me ? n - me > tn && (bt = !0, qe = !1, ga = n + an) : me = n : me = 0;
831
+ n - ut < Za || (ut = n, Xe.forEach((a) => {
832
+ var ue;
833
+ const { el: r, config: t, source: s, s: o } = a, i = t.paused;
834
+ if (i && a.paintedConfig === t) return;
835
+ const u = i ? 0 : o.lastTs ? Math.min(.05, (n - o.lastTs) / 1e3) : 1 / 60;
836
+ o.lastTs = n, o.t += u;
837
+ const l = o.t;
838
+ if (!i) if (a.analyser) kn(a, be);
839
+ else {
840
+ const f = s.getLevel ? Sa(s.getLevel()) : 0;
841
+ be.level = f, be.bands[0] = f, be.bands[1] = f * (.72 + .28 * Math.sin(l * 9.1)), be.bands[2] = f * (.6 + .4 * Math.sin(l * 13.7 + 2));
842
+ }
843
+ const p = pa(be.level, t.threshold);
844
+ o.level = Ge(o.level, p, u, t.attack, t.release);
845
+ for (let f = 0; f < 3; f++) {
846
+ const B = pa(be.bands[f], t.threshold * .6);
847
+ o.bands[f] = Ge(o.bands[f], B, u, t.attack, t.release * 1.15);
848
+ }
849
+ const b = Ka * t.lobeSpacing;
850
+ t.processing && o.scanA < .001 && o.scanT === 0 && (o.scanT = Math.max(.05, t.processingDuration) / 2);
851
+ const d = Math.max(.05, t.processingEase);
852
+ o.scanA = Ge(o.scanA, t.processing ? 1 : 0, u, d * .9, d * .8), t.processing ? o.scanT += u : o.scanA < .001 && (o.scanT = 0);
853
+ const h = o.scanA * o.scanA * (3 - 2 * o.scanA), T = r.clientWidth, O = r.clientHeight, L = b / 2 * t.processingTravel, _ = o.scanT / Math.max(.05, t.processingDuration), G = Math.floor(_), U = _ - G, E = Math.max(1, t.processingCurve), D = U < .5 ? .5 * Math.pow(2 * U, E) : 1 - .5 * Math.pow(2 - 2 * U, E), C = t.reducedMotion ? 0 : G % 2 === 0 ? 2 * D - 1 : 1 - 2 * D, z = h * L * C, g = 1 - h * .6, H = 1 - h * .45, Q = 1 + h * .3 * (1 - C * C), le = t.reducedMotion ? .5 : .5 + .5 * Math.sin(Ma * l / t.breatheDuration), K = o.level + (1 - o.level) * t.idle * le, W = Math.max(0, Math.min(1, (h - .25) / .75)), R = W * W * (3 - 2 * W), I = Math.max(K, t.processingLevel * R), P = .15 + .85 * I, v = .5 + t.reach * I, k = (.85 + t.spread * I) * Q;
854
+ t.flow !== 0 && !t.reducedMotion && (o.phase = ((o.phase + t.flow * I * u) % b + b) % b), r.style.setProperty(`--vb-level-${t.id}`, o.level.toFixed(3)), r.style.setProperty(`--vb-cx-${t.id}`, `${z.toFixed(1)}px`), r.style.setProperty(`--vb-mw-${t.id}`, H.toFixed(3));
855
+ const w = t.bend * I;
856
+ r.style.setProperty(`--vb-bh-${t.id}`, `${Math.max(0, w).toFixed(1)}px`);
857
+ const S = t.bend > 0 ? Math.min(1, w / t.bend) : 0;
858
+ r.style.setProperty(`--vb-bendA-${t.id}`, S.toFixed(3));
859
+ const x = {
860
+ cx: z,
861
+ w: k,
862
+ h: v,
863
+ mw: H,
864
+ lift: w,
865
+ strength: S,
866
+ level: o.level,
867
+ corner: h
868
+ }, y = T / 2 + z * k, oe = 30 * t.scale * k, xe = Ta(t.radius, T, O), re = h * t.cornerFollow;
869
+ r.style.setProperty(`--vb-cy-${t.id}`, `${(-gt(y, T, xe, oe * 1.4) * re).toFixed(1)}px`), o.warp = Ge(o.warp, t.processing ? 0 : 1, u, hn, dn);
870
+ const ye = o.warp, V = a.displace != null && ye < bn;
871
+ if (V !== a.warpOff && (a.warpOff = V, V ? r.setAttribute("data-voice-warp", "off") : r.removeAttribute("data-voice-warp")), T && O && (a.ctx || a.displace)) {
872
+ const f = xn(t, x, T, O);
873
+ (a.displace && !V || t.coreLight > 0) && yn(r, t.id, f, T, O), a.filter && !V && un && Mn(a, f, O), a.ctx && Sn(a, x, f);
874
+ }
875
+ if (a.displace && !V) {
876
+ const f = t.reducedMotion ? 0 : t.distortion * 120 * t.scale * (.15 + .85 * I) * ye;
877
+ a.displace.scale.baseVal = f, a.noiseShift && (a.noiseShift.dx.baseVal = 8 * t.scale * Math.sin(l * .9), a.noiseShift.dy.baseVal = 4 * t.scale * Math.sin(l * .6 + 1.3));
878
+ }
879
+ r.style.setProperty(`--vb-glow-${t.id}`, P.toFixed(3)), r.style.setProperty(`--vb-h-${t.id}`, v.toFixed(3)), r.style.setProperty(`--vb-w-${t.id}`, k.toFixed(3));
880
+ for (let f = 0; f < we.length; f++) {
881
+ const B = we[f], j = sn(B.x * t.lobeSpacing + o.phase, b), Z = t.bands ? .6 + .7 * o.bands[B.band] : 1;
882
+ r.style.setProperty(`--vb-x${f}-${t.id}`, `${(j * g).toFixed(1)}px`), r.style.setProperty(`--vb-l${f}-${t.id}`, (Z * cn(j, b)).toFixed(3));
883
+ const ge = T / 2 + (z + j * g) * k;
884
+ r.style.setProperty(`--vb-y${f}-${t.id}`, `${(-gt(ge, T, xe, oe) * re).toFixed(1)}px`);
885
+ }
886
+ const Me = t.staticColors || t.reducedMotion || t.hueRange === 0 ? 0 : -t.hueRange + 2 * t.hueRange * Tn(l / t.hueDuration);
887
+ r.style.setProperty(`--vb-hue-${t.id}`, `${Me.toFixed(2)}deg`), (ue = a.onLevel) == null || ue.call(a, o.level), a.paintedConfig = t;
888
+ }));
889
+ }
890
+ function An() {
891
+ $e ?? (ut = 0, Ve = 0, me = 0, $e = requestAnimationFrame(ka));
892
+ }
893
+ function On() {
894
+ Xe.size === 0 && $e != null && (cancelAnimationFrame($e), $e = null);
895
+ }
896
+ function Fn(n, e, a, r) {
897
+ const t = {
898
+ el: n,
899
+ config: e,
900
+ source: a,
901
+ onLevel: r,
902
+ analyser: null,
903
+ releaseAnalyser: null,
904
+ time: null,
905
+ freq: null,
906
+ canvas: null,
907
+ ctx: null,
908
+ haloCanvas: null,
909
+ haloCtx: null,
910
+ displace: null,
911
+ noiseShift: null,
912
+ filter: null,
913
+ filterTop: -1,
914
+ s: Qa(n),
915
+ paintedConfig: null,
916
+ cssBlur: null,
917
+ warpOff: n.hasAttribute("data-voice-warp")
918
+ };
919
+ e.distortion > 0 && (t.displace = n.querySelector(":scope > svg feDisplacementMap"), t.noiseShift = n.querySelector(":scope > svg feOffset"), t.filter = n.querySelector(":scope > svg filter"));
920
+ const s = n.querySelector(":scope > [data-voice-beam-band]");
921
+ if (s) {
922
+ t.canvas = s, t.ctx = s.getContext("2d");
923
+ const o = n.querySelector(":scope > [data-voice-beam-band-halo]");
924
+ o && (t.haloCanvas = o, t.haloCtx = o.getContext("2d"));
925
+ }
926
+ if (t.s.lastTs = 0, a.stream) {
927
+ const o = Ja(a.stream);
928
+ o && (t.analyser = o.analyser, t.releaseAnalyser = o.release, t.time = new Float32Array(o.analyser.fftSize), t.freq = new Uint8Array(o.analyser.frequencyBinCount));
929
+ }
930
+ return Xe.add(t), An(), () => {
931
+ var o;
932
+ Xe.delete(t), (o = t.releaseAnalyser) == null || o.call(t), On();
933
+ };
934
+ }
935
+ const Rn = {
936
+ scale: 1,
937
+ glowSize: 1,
938
+ processingDuration: 1.1,
939
+ processingLevel: .55,
940
+ processingTravel: 1.55,
941
+ processingCurve: 2.1,
942
+ cornerFollow: .45,
943
+ strokeOpacity: 1,
944
+ innerOpacity: 1,
945
+ bloomOpacity: 1,
946
+ idle: .18,
947
+ reach: 1.2,
948
+ spread: 1.05,
949
+ flow: 48,
950
+ bend: 60,
951
+ bandStrength: 1.55,
952
+ bandWidth: 2.15,
953
+ bandPosition: .35,
954
+ bandCurve: 1.75,
955
+ bandSpread: .87,
956
+ bandSkew: .12,
957
+ bandOffset: -27,
958
+ bandTail: .59,
959
+ bandTailPosition: .67,
960
+ bandTailCurve: 2.4,
961
+ bandTailOverflow: 15,
962
+ bandAberration: .89,
963
+ distortion: .62,
964
+ distortionDetail: 2.3,
965
+ glowWidth: .65,
966
+ glowHeight: 1.25,
967
+ lobeSpacing: .85,
968
+ rangeWidth: .75,
969
+ rangeHeight: 1,
970
+ softness: 1.07,
971
+ coreSize: 1,
972
+ coreLight: 0,
973
+ coreLightWidth: 1,
974
+ coreLightHeight: 1,
975
+ strokeScale: 1,
976
+ innerScale: 1,
977
+ innerHeight: 1,
978
+ bloomScale: 1,
979
+ bloomHeight: 1
980
+ }, Pn = {
981
+ default: {},
982
+ pill: {
983
+ scale: .45,
984
+ glowSize: .95,
985
+ strokeOpacity: 1.2,
986
+ innerOpacity: .85,
987
+ reach: 1.35,
988
+ spread: 1.1,
989
+ flow: 0,
990
+ bend: 23,
991
+ bandStrength: 1.55,
992
+ bandWidth: 1.85,
993
+ bandCurve: 1.95,
994
+ bandSpread: .38,
995
+ bandOffset: -16,
996
+ bandTail: 0,
997
+ processingTravel: 2,
998
+ cornerFollow: 0,
999
+ distortion: .45,
1000
+ distortionDetail: 3,
1001
+ glowWidth: .65,
1002
+ glowHeight: .95,
1003
+ lobeSpacing: .45,
1004
+ rangeWidth: .8,
1005
+ rangeHeight: .7,
1006
+ softness: .88,
1007
+ coreSize: .25,
1008
+ strokeScale: 1.25,
1009
+ innerScale: .95,
1010
+ bloomScale: 1.05,
1011
+ bloomHeight: 2.25
1012
+ },
1013
+ mobile: {
1014
+ scale: 1.25,
1015
+ spread: .45,
1016
+ reach: 3,
1017
+ flow: 60,
1018
+ bend: 70,
1019
+ bandWidth: 2.4,
1020
+ bandCurve: 1.55,
1021
+ bandSpread: .9,
1022
+ bandOffset: -50,
1023
+ bandTail: .62,
1024
+ bandTailPosition: .42,
1025
+ bandTailCurve: 2.7,
1026
+ bandTailOverflow: 22,
1027
+ processingDuration: 1.05,
1028
+ processingLevel: .35,
1029
+ processingTravel: 1,
1030
+ cornerFollow: .4,
1031
+ bandStrength: 1.8,
1032
+ distortionDetail: 2,
1033
+ glowWidth: 1.15,
1034
+ glowHeight: 2.1,
1035
+ lobeSpacing: 1.35,
1036
+ rangeWidth: 1.25,
1037
+ rangeHeight: 1.2,
1038
+ softness: 1.1
1039
+ }
1040
+ }, Ln = {
1041
+ default: { brightness: 1.15 },
1042
+ pill: {
1043
+ brightness: 1.35,
1044
+ saturation: 1.5
1045
+ },
1046
+ mobile: {
1047
+ strength: 1,
1048
+ brightness: 1.2,
1049
+ saturation: 1.5
1050
+ }
1051
+ }, Cn = {
1052
+ default: {},
1053
+ pill: {},
1054
+ mobile: { strength: 1 }
1055
+ };
1056
+ function Wn(n = "default", e = "dark") {
1057
+ return (e === "light" ? Cn[n] : void 0) ?? Ln[n];
1058
+ }
1059
+ const In = {
1060
+ default: { bandStrength: 1.7 },
1061
+ pill: { bandStrength: 2 },
1062
+ mobile: { bandStrength: 1.7 }
1063
+ };
1064
+ function En(n = "default", e = "dark") {
1065
+ const a = Pn[n], r = {};
1066
+ return e === "light" && (a.reach === void 0 && (r.reach = 1.8), a.spread === void 0 && (r.spread = .8), a.coreLight === void 0 && (r.coreLight = 1.8)), {
1067
+ ...Rn,
1068
+ ...r,
1069
+ ...a,
1070
+ ...e === "light" ? In[n] : void 0
1071
+ };
1072
+ }
1073
+ const Ue = {
1074
+ dark: {
1075
+ core: "255, 255, 255",
1076
+ above: "255, 70, 80",
1077
+ mid: "90, 255, 150",
1078
+ below: "80, 140, 255"
1079
+ },
1080
+ light: {
1081
+ core: "197, 139, 255",
1082
+ above: "255, 122, 182",
1083
+ mid: "126, 196, 255",
1084
+ below: "45, 255, 171"
1085
+ }
1086
+ }, zn = 1, _n = 16, Dn = 6e4, $a = typeof navigator < "u" && /AppleWebKit/.test(navigator.userAgent) && !/Chrome\/|Chromium\/|Edg\/|OPR\//.test(navigator.userAgent), Hn = (() => {
1087
+ if (typeof document > "u") return !0;
1088
+ const n = document.createElement("canvas").getContext("2d");
1089
+ return !!n && typeof n.filter == "string";
1090
+ })();
1091
+ function Bn() {
1092
+ const [n, e] = useState(() => typeof window > "u" || window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
1093
+ return useEffect(() => {
1094
+ if (typeof window > "u") return;
1095
+ const a = window.matchMedia("(prefers-color-scheme: dark)"), r = (t) => e(t.matches ? "dark" : "light");
1096
+ return a.addEventListener("change", r), () => a.removeEventListener("change", r);
1097
+ }, []), n;
1098
+ }
1099
+ function Nn() {
1100
+ const [n, e] = useState(() => typeof window > "u" || !window.matchMedia ? !1 : window.matchMedia("(prefers-reduced-motion: reduce)").matches);
1101
+ return useEffect(() => {
1102
+ if (typeof window > "u" || !window.matchMedia) return;
1103
+ const a = window.matchMedia("(prefers-reduced-motion: reduce)"), r = (t) => e(t.matches);
1104
+ return a.addEventListener("change", r), () => a.removeEventListener("change", r);
1105
+ }, []), n;
1106
+ }
1107
+ function qn(n, e) {
1108
+ return n === "auto" ? e : n;
1109
+ }
1110
+ //#endregion
1111
+ //#region src/card/visual.ts
1112
+ const VoiceBeamView = forwardRef(function({ children: e, type: a = "default", scale: r, stream: t = null, level: s = 0, sensitivity: o = 3.1, threshold: i = .015, attack: u = .325, release: l = .86, idle: p, breatheDuration: b = 5.2, reach: m, spread: d, bands: h = !0, flow: T, processing: O = !1, processingDuration: L, processingLevel: _, processingTravel: G, processingCurve: U, cornerFollow: E, processingEase: D = .6, colorVariant: C = "colorful", colors: z, bandColors: g, theme: H = "dark", staticColors: Q = !1, hueRange: le, hueDuration: K, active: W = !0, paused: R = !1, borderRadius: I, brightness: P, saturation: v, glowSize: k, strokeOpacity: w, innerOpacity: S, bloomOpacity: x, bend: y, bandStrength: oe, bandWidth: xe, bandPosition: re, bandCurve: ye, bandSpread: V, bandSkew: Me, bandOffset: ue, bandTail: f, bandTailPosition: B, bandTailCurve: j, bandTailOverflow: Z, bandAberration: ge, distortion: Fe, distortionDetail: Ye, glowWidth: Je, glowHeight: Qe, lobeSpacing: pe, rangeWidth: Re, rangeHeight: Ze, softness: et, coreSize: tt, coreLight: at, coreLightWidth: ie, coreLightHeight: fe, strokeScale: Pe, innerScale: $, innerHeight: A, bloomScale: N, bloomHeight: ae, strength: nt, className: ot, style: rt, css: Le, onLevel: pt, onActivate: Ce, onDeactivate: We, onAnimationEnd: Ie, ...Aa }, Se) {
1113
+ const de = useId().replace(/:/g, "-"), Y = qn(H, Bn()), Fa = z ? z.join("|") : "", Ra = g ? [
1114
+ g.core,
1115
+ g.above,
1116
+ g.mid,
1117
+ g.below
1118
+ ].join("|") : "", c = En(a, Y), F = Math.max(.05, r ?? c.scale), ft = k ?? c.glowSize, vt = w ?? c.strokeOpacity, mt = S ?? c.innerOpacity, $t = x ?? c.bloomOpacity, wt = L ?? c.processingDuration, xt = _ ?? c.processingLevel, yt = G ?? c.processingTravel, Mt = U ?? c.processingCurve, St = E ?? c.cornerFollow, Tt = p ?? c.idle, kt = m ?? c.reach, At = d ?? c.spread, Ot = (T ?? c.flow) * F, Ft = (y ?? c.bend) * F, Rt = oe ?? c.bandStrength, Pt = (xe ?? c.bandWidth) * F, Lt = re ?? c.bandPosition, Ct = ye ?? c.bandCurve, Wt = V ?? c.bandSpread, It = Me ?? c.bandSkew, Et = (ue ?? c.bandOffset) * F, zt = f ?? c.bandTail, _t = B ?? c.bandTailPosition, Dt = j ?? c.bandTailCurve, Ht = (Z ?? c.bandTailOverflow) * F, Bt = ge ?? c.bandAberration, Pa = Fe ?? c.distortion, Nt = (Ye ?? c.distortionDetail) / F, qt = (Je ?? c.glowWidth) * F, Gt = (Qe ?? c.glowHeight) * F, Ut = (pe ?? c.lobeSpacing) * F, Ee = (Re ?? c.rangeWidth) * F, ze = (Ze ?? c.rangeHeight) * F, Kt = et ?? c.softness, Vt = (tt ?? c.coreSize) * F, Te = Math.max(0, Math.min(3, at ?? c.coreLight)), jt = ie ?? c.coreLightWidth, Xt = fe ?? c.coreLightHeight, Yt = Pe ?? c.strokeScale, Jt = $ ?? c.innerScale, Qt = A ?? c.innerHeight, Zt = N ?? c.bloomScale, ea = ae ?? c.bloomHeight, ta = Nn(), ke = useRef(null), [he, aa] = useState(W), [se, na] = useState(!1), [it, La] = useState(!0), [Ca, Wa] = useState(null), [Ia, Ea] = useState(0);
1119
+ useEffect(() => {
1120
+ if (!$a) return;
1121
+ const M = ke.current;
1122
+ if (!M) return;
1123
+ const X = () => Ea(M.clientWidth * M.clientHeight);
1124
+ if (X(), typeof ResizeObserver > "u") return;
1125
+ const ce = new ResizeObserver(X);
1126
+ return ce.observe(M), () => ce.disconnect();
1127
+ }, []);
1128
+ const ve = $a && Ia > Dn ? 0 : Pa;
1129
+ useEffect(() => {
1130
+ if (I != null) return;
1131
+ const M = ke.current;
1132
+ if (!M) return;
1133
+ const X = () => {
1134
+ const ee = M.firstElementChild;
1135
+ if (!ee) return;
1136
+ const He = getComputedStyle(ee), ct = parseFloat(He.borderTopLeftRadius);
1137
+ !isNaN(ct) && ct > 0 && Wa(ct);
1138
+ };
1139
+ X();
1140
+ const ce = new MutationObserver(X);
1141
+ return ce.observe(M, {
1142
+ childList: !0,
1143
+ subtree: !1
1144
+ }), () => ce.disconnect();
1145
+ }, [I, e]), useEffect(() => {
1146
+ W && !he && !se ? aa(!0) : !W && he && !se && na(!0);
1147
+ }, [
1148
+ W,
1149
+ he,
1150
+ se
1151
+ ]), useEffect(() => {
1152
+ const M = ke.current;
1153
+ if (!M || typeof IntersectionObserver > "u") return;
1154
+ const X = new IntersectionObserver((ce) => {
1155
+ for (const ee of ce) La(ee.isIntersecting);
1156
+ }, { rootMargin: "256px" });
1157
+ return X.observe(M), () => X.disconnect();
1158
+ }, []);
1159
+ const za = useCallback((M) => {
1160
+ const X = M.animationName;
1161
+ X.includes("fade-out") ? (aa(!1), na(!1), We?.()) : X.includes("fade-in") && Ce?.(), Ie?.(M);
1162
+ }, [
1163
+ Ce,
1164
+ We,
1165
+ Ie
1166
+ ]), J = Ga[Y], _e = I ?? Ca ?? _n, st = Wn(a, Y), _a = nt ?? st.strength ?? J.strength ?? 1, oa = le ?? J.hueRange ?? 24, ra = K ?? J.hueDuration ?? 12, ia = P ?? st.brightness ?? J.brightness, sa = v ?? st.saturation ?? J.saturation, ca = useMemo(() => Ya({
1167
+ id: de,
1168
+ borderRadius: _e,
1169
+ borderWidth: zn,
1170
+ strokeOpacity: J.strokeOpacity * vt,
1171
+ innerOpacity: J.innerOpacity * mt,
1172
+ bloomOpacity: J.bloomOpacity * $t,
1173
+ innerShadow: J.innerShadow,
1174
+ colorVariant: C,
1175
+ colors: z,
1176
+ brightness: ia,
1177
+ saturation: sa,
1178
+ theme: Y,
1179
+ hueBase: J.hueBase ?? 0,
1180
+ glowSize: ft * F,
1181
+ glowWidth: qt,
1182
+ glowHeight: Gt,
1183
+ strokeScale: Yt,
1184
+ innerScale: Jt,
1185
+ innerHeight: Qt,
1186
+ bloomScale: Zt,
1187
+ bloomHeight: ea,
1188
+ coreSize: Vt,
1189
+ coreLight: Te,
1190
+ coreLightWidth: jt,
1191
+ coreLightHeight: Xt,
1192
+ rangeWidth: Ee,
1193
+ rangeHeight: ze,
1194
+ softness: Kt,
1195
+ distortion: ve > 0,
1196
+ scale: F
1197
+ }), [
1198
+ de,
1199
+ _e,
1200
+ J,
1201
+ C,
1202
+ Fa,
1203
+ ia,
1204
+ sa,
1205
+ Y,
1206
+ c,
1207
+ ft,
1208
+ vt,
1209
+ mt,
1210
+ $t,
1211
+ F,
1212
+ qt,
1213
+ Gt,
1214
+ Yt,
1215
+ Jt,
1216
+ Qt,
1217
+ Zt,
1218
+ ea,
1219
+ Vt,
1220
+ Te,
1221
+ jt,
1222
+ Xt,
1223
+ Ee,
1224
+ ze,
1225
+ Kt,
1226
+ ve > 0
1227
+ ]), la = useMemo(() => ({
1228
+ id: de,
1229
+ sensitivity: Math.max(0, o),
1230
+ threshold: Math.max(0, Math.min(.95, i)),
1231
+ attack: Math.max(0, u),
1232
+ release: Math.max(0, l),
1233
+ idle: Math.max(0, Math.min(1, Tt)),
1234
+ breatheDuration: Math.max(.2, b),
1235
+ reach: Math.max(0, kt),
1236
+ spread: Math.max(0, At),
1237
+ bands: h,
1238
+ flow: Ot,
1239
+ lobeSpacing: Math.max(.1, Ut),
1240
+ bend: Math.max(0, Ft),
1241
+ bandStrength: Math.max(0, Rt),
1242
+ bandWidth: Math.max(0, Pt),
1243
+ bandPosition: Math.max(0, Lt),
1244
+ bandCurve: Math.max(.3, Ct),
1245
+ bandSpread: Math.max(.05, Wt),
1246
+ bandSkew: Math.max(-.9, Math.min(.9, It)),
1247
+ bandOffset: Et,
1248
+ bandTail: Math.max(0, Math.min(1.5, zt)),
1249
+ bandTailPosition: Math.max(0, Math.min(.98, _t)),
1250
+ bandTailCurve: Math.max(.5, Dt),
1251
+ bandTailOverflow: Math.max(0, Ht),
1252
+ bandAberration: Math.max(0, Math.min(1, Bt)),
1253
+ rangeWidth: Ee,
1254
+ rangeHeight: ze,
1255
+ theme: Y,
1256
+ bandColors: {
1257
+ core: (g == null ? void 0 : g.core) && Ne(g.core) || Ue[Y].core,
1258
+ above: (g == null ? void 0 : g.above) && Ne(g.above) || Ue[Y].above,
1259
+ mid: (g == null ? void 0 : g.mid) && Ne(g.mid) || Ue[Y].mid,
1260
+ below: (g == null ? void 0 : g.below) && Ne(g.below) || Ue[Y].below
1261
+ },
1262
+ distortion: Math.max(0, Math.min(1, ve)),
1263
+ coreLight: Te,
1264
+ scale: F,
1265
+ radius: _e,
1266
+ processing: O,
1267
+ processingDuration: Math.max(.05, wt),
1268
+ processingLevel: Math.max(0, Math.min(1, xt)),
1269
+ processingEase: Math.max(.05, D),
1270
+ processingTravel: Math.max(0, yt),
1271
+ processingCurve: Math.max(1, Mt),
1272
+ cornerFollow: Math.max(0, Math.min(1, St)),
1273
+ hueRange: Math.max(0, oa),
1274
+ hueDuration: Math.max(.5, ra),
1275
+ staticColors: C === "mono" ? !0 : Q,
1276
+ reducedMotion: ta,
1277
+ paused: R
1278
+ }), [
1279
+ de,
1280
+ o,
1281
+ i,
1282
+ u,
1283
+ l,
1284
+ Tt,
1285
+ b,
1286
+ kt,
1287
+ At,
1288
+ h,
1289
+ Ot,
1290
+ Ut,
1291
+ Ft,
1292
+ Rt,
1293
+ Pt,
1294
+ Lt,
1295
+ Ct,
1296
+ Wt,
1297
+ It,
1298
+ Et,
1299
+ zt,
1300
+ _t,
1301
+ Dt,
1302
+ Ht,
1303
+ Bt,
1304
+ Ee,
1305
+ ze,
1306
+ Y,
1307
+ Ra,
1308
+ ve,
1309
+ Te,
1310
+ F,
1311
+ _e,
1312
+ O,
1313
+ wt,
1314
+ xt,
1315
+ D,
1316
+ yt,
1317
+ Mt,
1318
+ St,
1319
+ oa,
1320
+ ra,
1321
+ Q,
1322
+ C,
1323
+ ta,
1324
+ R
1325
+ ]), da = useRef(s);
1326
+ da.current = s;
1327
+ const De = useRef(pt);
1328
+ De.current = pt, useEffect(() => {
1329
+ if (!(he || se) || !it) return;
1330
+ const M = ke.current;
1331
+ return M ? Fn(M, la, {
1332
+ stream: t,
1333
+ getLevel: () => {
1334
+ const ee = da.current;
1335
+ return typeof ee == "function" ? ee() : ee;
1336
+ }
1337
+ }, (ee) => {
1338
+ var He;
1339
+ return (He = De.current) == null ? void 0 : He.call(De, ee);
1340
+ }) : void 0;
1341
+ }, [
1342
+ la,
1343
+ t,
1344
+ he,
1345
+ se,
1346
+ it
1347
+ ]);
1348
+ const Da = useCallback((M) => {
1349
+ ke.current = M, typeof Se == "function" ? Se(M) : Se && (Se.current = M);
1350
+ }, [Se]), Ha = {
1351
+ ...rt ?? {},
1352
+ "--voice-strength": Math.max(0, Math.min(1, _a))
1353
+ };
1354
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("style", { children: Le ? `${ca}
1355
+ ${Le.split("{id}").join(de)}` : ca }), /* @__PURE__ */ jsxs("div", {
1356
+ ...Aa,
1357
+ ref: Da,
1358
+ "data-voice-beam": de,
1359
+ "data-voice-type": a,
1360
+ "data-voice-halfres": "",
1361
+ "data-active": he && !se ? "" : void 0,
1362
+ "data-fading": se ? "" : void 0,
1363
+ "data-paused": he && !se && (!it || R) ? "" : void 0,
1364
+ "data-listening": t ? "" : void 0,
1365
+ "data-processing": O ? "" : void 0,
1366
+ className: ot,
1367
+ style: Ha,
1368
+ onAnimationEnd: za,
1369
+ children: [
1370
+ e,
1371
+ /* @__PURE__ */ jsx("div", { "data-voice-beam-bloom": !0 }),
1372
+ ve > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { "data-voice-beam-warp": "inner" }), /* @__PURE__ */ jsx("div", { "data-voice-beam-warp": "bloom" })] }),
1373
+ !Hn && /* @__PURE__ */ jsx("canvas", {
1374
+ "data-voice-beam-band-halo": !0,
1375
+ "aria-hidden": "true"
1376
+ }),
1377
+ /* @__PURE__ */ jsx("canvas", {
1378
+ "data-voice-beam-band": !0,
1379
+ "aria-hidden": "true"
1380
+ }),
1381
+ Te > 0 && /* @__PURE__ */ jsx("div", {
1382
+ "data-voice-beam-core": !0,
1383
+ children: /* @__PURE__ */ jsx("div", {})
1384
+ }),
1385
+ ve > 0 && /* @__PURE__ */ jsx("svg", {
1386
+ "aria-hidden": "true",
1387
+ width: "0",
1388
+ height: "0",
1389
+ style: {
1390
+ position: "absolute",
1391
+ pointerEvents: "none"
1392
+ },
1393
+ children: /* @__PURE__ */ jsxs("filter", {
1394
+ id: `vb-distort-${de}`,
1395
+ x: "-20%",
1396
+ y: "-20%",
1397
+ width: "140%",
1398
+ height: "140%",
1399
+ colorInterpolationFilters: "sRGB",
1400
+ children: [
1401
+ /* @__PURE__ */ jsx("feTurbulence", {
1402
+ type: "fractalNoise",
1403
+ baseFrequency: `${(.012 * Nt).toFixed(4)} ${(.05 * Nt).toFixed(4)}`,
1404
+ numOctaves: 2,
1405
+ seed: 7,
1406
+ result: "noise"
1407
+ }),
1408
+ /* @__PURE__ */ jsx("feOffset", {
1409
+ in: "noise",
1410
+ dx: "0",
1411
+ dy: "0",
1412
+ result: "moved"
1413
+ }),
1414
+ /* @__PURE__ */ jsx("feColorMatrix", {
1415
+ in: "moved",
1416
+ type: "matrix",
1417
+ values: "1 0 0 0 0 0 0 0 0 0.5 0 0 0 0 0 0 0 0 0 1",
1418
+ result: "map"
1419
+ }),
1420
+ /* @__PURE__ */ jsx("feDisplacementMap", {
1421
+ in: "SourceGraphic",
1422
+ in2: "map",
1423
+ scale: 0,
1424
+ xChannelSelector: "R",
1425
+ yChannelSelector: "G"
1426
+ })
1427
+ ]
1428
+ })
1429
+ })
1430
+ ]
1431
+ })] });
1432
+ });
1433
+ /** Shared by enrollment, unlock and signing. The recorder remains the only audio owner. */
1434
+ var VoiceVisual = class {
1435
+ element;
1436
+ glow;
1437
+ ribbon;
1438
+ prompt;
1439
+ themeObserver;
1440
+ phase = "idle";
1441
+ disposed = false;
1442
+ constructor(document, prompt, checking) {
1443
+ this.prompt = prompt;
1444
+ this.ribbon = new VoiceRibbon(document, checking);
1445
+ this.element = this.ribbon.element;
1446
+ this.glow = document.createElement("div");
1447
+ this.glow.className = "seams-voiceid-glow";
1448
+ this.glow.setAttribute("aria-hidden", "true");
1449
+ this.render();
1450
+ const nonce = styleNonce();
1451
+ if (nonce) for (const style of this.glow.querySelectorAll("style")) style.nonce = nonce;
1452
+ this.themeObserver = new MutationObserver(this.render);
1453
+ this.themeObserver.observe(document.documentElement, {
1454
+ attributes: true,
1455
+ attributeFilter: ["data-theme"]
1456
+ });
1457
+ this.themeObserver.observe(document.body, {
1458
+ attributes: true,
1459
+ attributeFilter: ["data-theme"]
1460
+ });
1461
+ }
1462
+ listen() {
1463
+ this.setPhase("listening");
1464
+ }
1465
+ add(event) {
1466
+ this.ribbon.add(event);
1467
+ }
1468
+ checking() {
1469
+ this.setPhase("processing");
1470
+ }
1471
+ accept() {
1472
+ this.setPhase("idle");
1473
+ }
1474
+ /** The glow keeps working while the line rests flat, for a status line that takes its place. */
1475
+ flatten() {
1476
+ if (this.disposed) return;
1477
+ this.phase = "processing";
1478
+ this.ribbon.setPhase("idle");
1479
+ this.render();
1480
+ }
1481
+ ready() {
1482
+ this.setPhase("idle");
1483
+ }
1484
+ /** The glow settles while the ribbon closes into the success seal; resolves when the check is drawn. */
1485
+ succeed(begin) {
1486
+ if (this.disposed) return Promise.resolve();
1487
+ this.phase = "idle";
1488
+ this.render();
1489
+ return this.ribbon.succeed(begin);
1490
+ }
1491
+ stop() {
1492
+ if (this.disposed) return;
1493
+ this.disposed = true;
1494
+ this.themeObserver.disconnect();
1495
+ this.ribbon.dispose();
1496
+ render(null, this.glow);
1497
+ }
1498
+ setPhase(phase) {
1499
+ if (this.disposed) return;
1500
+ this.phase = phase;
1501
+ this.ribbon.setPhase(phase);
1502
+ this.render();
1503
+ }
1504
+ render = () => {
1505
+ if (this.disposed) return;
1506
+ render(createElement(VoiceBeamView, {
1507
+ className: "seams-voiceid-beam",
1508
+ theme: (this.prompt.closest("[data-theme]")?.getAttribute("data-theme") ?? this.prompt.ownerDocument.documentElement.getAttribute("data-theme")) === "light" ? "light" : "dark",
1509
+ level: this.ribbon.readLevel,
1510
+ processing: this.phase === "processing",
1511
+ active: this.phase !== "idle",
1512
+ staticColors: true,
1513
+ colorVariant: "ocean",
1514
+ borderRadius: Number.parseFloat(getComputedStyle(this.prompt).borderRadius) || 16,
1515
+ children: null
1516
+ }), this.glow);
1517
+ };
1518
+ };
1519
+ //#endregion
1520
+ export { VoiceVisual as t };