@streamoji/avatar-widget 0.2.3 → 0.2.5

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.
@@ -1,96 +1,100 @@
1
- import { jsx as u, jsxs as ne } from "react/jsx-runtime";
2
- import { useGLTF as Qe, Environment as Et } from "@react-three/drei";
3
- import { useFrame as Tt, Canvas as It, useThree as Ct } from "@react-three/fiber";
4
- import { memo as Dt, useMemo as et, useRef as o, useState as y, useEffect as z, useCallback as $e, useLayoutEffect as Ot, Suspense as Ft } from "react";
5
- import * as Fe from "three";
6
- import { GLTFLoader as Ut } from "three/examples/jsm/loaders/GLTFLoader.js";
7
- const B = (...d) => {
8
- }, Nt = (...d) => {
9
- }, ut = ({ analyser: d }) => {
10
- const x = o(null), w = o(null);
11
- return z(() => {
12
- const p = x.current;
13
- if (!p) return;
14
- const D = p.getContext("2d", { alpha: !0 });
15
- if (!D) return;
16
- let E, L = null;
17
- d && (d.fftSize = 128, L = new Uint8Array(d.frequencyBinCount));
18
- const he = () => {
19
- E = requestAnimationFrame(he), (p.width !== p.offsetWidth || p.height !== p.offsetHeight) && (p.width = p.offsetWidth, p.height = p.offsetHeight);
20
- const re = p.width, O = p.height;
21
- if (re === 0 || O === 0) return;
22
- const k = O / 2;
23
- D.clearRect(0, 0, re, O), D.fillStyle = "#1e293b";
24
- const Q = 2, M = Q + 2, ce = re * 0.95, g = Math.floor(ce / M);
25
- (!w.current || w.current.length !== g) && (w.current = new Float32Array(g).fill(2));
26
- const ke = g * M, Z = (re - ke) / 2;
27
- d && L && d.getByteFrequencyData(L);
28
- const pe = L ? L.length : 0, J = Math.floor(pe * 0.7) / g, I = new Float32Array(g);
29
- for (let m = 0; m < g; m++) {
30
- let $ = 0;
31
- if (L && J > 0) {
32
- const b = Math.floor(m * J), K = Math.floor((m + 1) * J);
33
- for (let q = b; q < K; q++) {
34
- const le = L[q] || 0;
35
- le > $ && ($ = le);
1
+ import { jsx as l, jsxs as se } from "react/jsx-runtime";
2
+ import { useGLTF as at, Environment as jt } from "@react-three/drei";
3
+ import { useFrame as Jt, Canvas as qt, useThree as Gt } from "@react-three/fiber";
4
+ import { memo as zt, useMemo as ut, useRef as c, useState as _, useEffect as P, useCallback as Ye, useLayoutEffect as Yt, Suspense as Qt } from "react";
5
+ import * as We from "three";
6
+ import { GLTFLoader as Xt } from "three/examples/jsm/loaders/GLTFLoader.js";
7
+ const ct = "https://ai.streamoji.com", U = (...f) => {
8
+ }, Kt = (...f) => {
9
+ }, At = ({ analyser: f }) => {
10
+ const L = c(null), w = c(null);
11
+ return P(() => {
12
+ const g = L.current;
13
+ if (!g) return;
14
+ const T = g.getContext("2d", { alpha: !0 });
15
+ if (!T) return;
16
+ let W, E = null;
17
+ f && (f.fftSize = 128, E = new Uint8Array(f.frequencyBinCount));
18
+ const Z = () => {
19
+ W = requestAnimationFrame(Z), (g.width !== g.offsetWidth || g.height !== g.offsetHeight) && (g.width = g.offsetWidth, g.height = g.offsetHeight);
20
+ const ie = g.width, F = g.height;
21
+ if (ie === 0 || F === 0) return;
22
+ const H = F / 2;
23
+ T.clearRect(0, 0, ie, F), T.fillStyle = "#1e293b";
24
+ const b = 2, p = b + 2, Y = ie * 0.95, $ = Math.floor(Y / p);
25
+ (!w.current || w.current.length !== $) && (w.current = new Float32Array($).fill(2));
26
+ const he = $ * p, k = (ie - he) / 2;
27
+ f && E && f.getByteFrequencyData(E);
28
+ const Ve = E ? E.length : 0, q = Math.floor(Ve * 0.7) / $, pe = new Float32Array($);
29
+ for (let I = 0; I < $; I++) {
30
+ let C = 0;
31
+ if (E && q > 0) {
32
+ const me = Math.floor(I * q), R = Math.floor((I + 1) * q);
33
+ for (let v = me; v < R; v++) {
34
+ const y = E[v] || 0;
35
+ y > C && (C = y);
36
36
  }
37
37
  }
38
- $ < 10 && ($ = 0);
39
- const R = $ / 255, v = $ > 0 ? Math.max(2, Math.pow(R, 1.4) * O * 0.25) : 2;
40
- I[m] = v;
38
+ C < 10 && (C = 0);
39
+ const B = C / 255, M = C > 0 ? Math.max(2, Math.pow(B, 1.4) * F * 0.25) : 2;
40
+ pe[I] = M;
41
41
  }
42
- for (let m = 0; m < g; m++) {
43
- const $ = g - 1 - m, R = Math.max(I[m], I[$]), v = w.current[m] + (R - w.current[m]) * 0.3;
44
- w.current[m] = v;
45
- const b = Z + m * M, K = k - v / 2;
46
- D.beginPath(), D.roundRect ? D.roundRect(b, K, Q, v, 4) : D.fillRect(b, K, Q, v), D.fill();
42
+ for (let I = 0; I < $; I++) {
43
+ const C = $ - 1 - I, B = Math.max(pe[I], pe[C]), M = w.current[I] + (B - w.current[I]) * 0.3;
44
+ w.current[I] = M;
45
+ const me = k + I * p, R = H - M / 2;
46
+ T.beginPath(), T.roundRect ? T.roundRect(me, R, b, M, 4) : T.fillRect(me, R, b, M), T.fill();
47
47
  }
48
48
  };
49
- return he(), () => {
50
- cancelAnimationFrame(E);
49
+ return Z(), () => {
50
+ cancelAnimationFrame(W);
51
51
  };
52
- }, [d]), /* @__PURE__ */ u(
52
+ }, [f]), /* @__PURE__ */ l(
53
53
  "canvas",
54
54
  {
55
- ref: x,
55
+ ref: L,
56
56
  style: { width: "100%", height: "100%", display: "block" }
57
57
  }
58
58
  );
59
- }, dt = "https://ai.streamoji.com", Wt = "https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev", ft = "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";
60
- async function Pt(d) {
61
- const x = await crypto.subtle.digest(
59
+ }, Zt = "https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev", Lt = "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";
60
+ async function en(f) {
61
+ const L = await crypto.subtle.digest(
62
62
  "SHA-256",
63
- new TextEncoder().encode(d)
63
+ new TextEncoder().encode(f)
64
64
  );
65
- return Array.from(new Uint8Array(x)).map((w) => w.toString(16).padStart(2, "0")).join("");
65
+ return Array.from(new Uint8Array(L)).map((w) => w.toString(16).padStart(2, "0")).join("");
66
66
  }
67
- function Vt(d) {
68
- const [x, w] = y(null);
69
- return z(() => {
70
- if (!d) {
67
+ function tn(f) {
68
+ const [L, w] = _(null);
69
+ return P(() => {
70
+ if (!f) {
71
71
  w(null);
72
72
  return;
73
73
  }
74
- let p = !1;
75
- return Pt(d).then((D) => {
76
- if (p) return;
77
- const E = `${Wt}/${D}.glb`;
78
- fetch(E, { method: "HEAD" }).then((L) => {
79
- p || w(L.ok ? E : ft);
74
+ let g = !1;
75
+ return en(f).then((T) => {
76
+ if (g) return;
77
+ const W = `${Zt}/${T}.glb`;
78
+ fetch(W, { method: "HEAD" }).then((E) => {
79
+ g || w(E.ok ? W : Lt);
80
80
  }).catch(() => {
81
- p || w(ft);
81
+ g || w(Lt);
82
82
  });
83
83
  }), () => {
84
- p = !0;
84
+ g = !0;
85
85
  };
86
- }, [d]), x;
86
+ }, [f]), L;
87
87
  }
88
- const Bt = [
88
+ const nn = [
89
89
  "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_001.glb",
90
90
  "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_002.glb",
91
91
  "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_002.glb",
92
92
  "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_005.glb"
93
- ], $t = [
93
+ ], rn = [
94
+ "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_001.glb",
95
+ "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb",
96
+ "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb"
97
+ ], sn = [
94
98
  {
95
99
  id: "m_expr_01",
96
100
  name: "Friendly Wave",
@@ -256,17 +260,17 @@ const Bt = [
256
260
  name: "Take It Easy",
257
261
  url: "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_006.glb"
258
262
  }
259
- ], Ht = [
263
+ ], on = [
260
264
  "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb",
261
265
  "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"
262
- ], jt = {
266
+ ], an = {
263
267
  zoom: 0.85,
264
268
  position: [0.15, -0.8, 0],
265
269
  scale: 1.5,
266
270
  rotation: [0.15, 0.02, 0]
267
- }, Jt = [-0.45, 1.9, 0.1], qt = {
271
+ }, cn = [-0.45, 1.9, 0.1], ln = {
268
272
  browInnerUp: 0.2
269
- }, Ze = 0.18, Gt = 1, He = {
273
+ }, lt = 0.18, un = 1, Qe = {
270
274
  neutral: { eyeLookDownLeft: 0.1, eyeLookDownRight: 0.1 },
271
275
  happy: {
272
276
  mouthSmileLeft: 0.2,
@@ -348,7 +352,7 @@ const Bt = [
348
352
  mouthUpperUpLeft: 0.1,
349
353
  mouthUpperUpRight: 0.1
350
354
  }
351
- }, zt = [
355
+ }, dn = [
352
356
  { key: "viseme_aa", mix: { jawOpen: 0.6 } },
353
357
  {
354
358
  key: "viseme_E",
@@ -444,7 +448,7 @@ const Bt = [
444
448
  }
445
449
  },
446
450
  { key: "viseme_sil", mix: {} }
447
- ], Yt = {
451
+ ], fn = {
448
452
  aei: [
449
453
  { v: "E", w: 0.8 },
450
454
  { v: "I", w: 0.2 }
@@ -473,303 +477,321 @@ const Bt = [
473
477
  ],
474
478
  sil: [{ v: "sil", w: 1 }]
475
479
  };
476
- function Xt(d) {
477
- if (!d) return [{ v: "sil", w: 1 }];
478
- const x = d.toLowerCase();
479
- return Yt[x] ?? [{ v: "sil", w: 1 }];
480
+ function hn(f) {
481
+ if (!f) return [{ v: "sil", w: 1 }];
482
+ const L = f.toLowerCase();
483
+ return fn[L] ?? [{ v: "sil", w: 1 }];
480
484
  }
481
- function Kt({ target: d }) {
482
- const { camera: x } = Ct();
483
- return z(() => {
484
- x.lookAt(...d);
485
- }, [x, d]), null;
485
+ function pn({ target: f }) {
486
+ const { camera: L } = Gt();
487
+ return P(() => {
488
+ L.lookAt(...f);
489
+ }, [L, f]), null;
486
490
  }
487
- function G(d, x, w) {
488
- if (!d || !d.morphTargetDictionary)
491
+ function z(f, L, w) {
492
+ if (!f || !f.morphTargetDictionary)
489
493
  return;
490
- const p = d, D = p.morphTargetDictionary, E = p.morphTargetInfluences;
491
- if (E)
492
- for (const L in D)
493
- L.toLowerCase() === x.toLowerCase() && (E[D[L]] = w);
494
+ const g = f, T = g.morphTargetDictionary, W = g.morphTargetInfluences;
495
+ if (W)
496
+ for (const E in T)
497
+ E.toLowerCase() === L.toLowerCase() && (W[T[E]] = w);
494
498
  }
495
- function ht(d, x = 0.97) {
496
- if (!d) return;
497
- const w = d;
499
+ function Rt(f, L = 0.97) {
500
+ if (!f) return;
501
+ const w = f;
498
502
  if (w.morphTargetInfluences)
499
- for (let p = 0; p < w.morphTargetInfluences.length; p++)
500
- w.morphTargetInfluences[p] *= x;
503
+ for (let g = 0; g < w.morphTargetInfluences.length; g++)
504
+ w.morphTargetInfluences[g] *= L;
501
505
  }
502
- const Qt = Dt(
506
+ const mn = zt(
503
507
  ({
504
- avatarUrl: d,
505
- isPlayingRef: x,
508
+ avatarUrl: f,
509
+ isPlayingRef: L,
506
510
  visemeQueueRef: w,
507
- audioContextRef: p,
508
- responseAudioStartTimeRef: D,
509
- adjustments: E,
510
- mood: L,
511
- expression: he,
512
- agentResponse: re,
513
- isSpeaking: O,
514
- nextStartTimeRef: k,
515
- stopPlayback: Q,
516
- setIsSpeaking: U,
517
- expressionUrl: M,
518
- onExpressionFinished: ce
511
+ audioContextRef: g,
512
+ responseAudioStartTimeRef: T,
513
+ adjustments: W,
514
+ mood: E,
515
+ expression: Z,
516
+ agentResponse: ie,
517
+ isSpeaking: F,
518
+ nextStartTimeRef: H,
519
+ stopPlayback: b,
520
+ setIsSpeaking: oe,
521
+ expressionUrl: p,
522
+ onExpressionFinished: Y,
523
+ isNudgeResponse: $,
524
+ avatarGender: he
519
525
  }) => {
520
- const { scene: g } = Qe(d), ke = Qe(Bt), Z = et(
521
- () => ke.flatMap((f) => f.animations),
522
- [ke]
523
- ), pe = Qe(Ht), se = et(
524
- () => pe.flatMap((f) => f.animations),
526
+ const { scene: k } = at(f), ye = at(he === "female" ? rn : nn), q = ut(
527
+ () => ye.flatMap((d) => d.animations),
528
+ [ye]
529
+ ), pe = at(on), I = ut(
530
+ () => pe.flatMap((d) => d.animations),
525
531
  [pe]
526
- ), J = o(null), I = o(null), m = o(null), $ = o([]), [R] = y(() => new Fe.AnimationMixer(g)), v = o({}), b = o(null), K = o(0), q = o(!1), le = o(0), ee = o(null);
527
- z(() => {
528
- if (!(!Z || !g)) {
529
- if (Z.forEach((f, c) => {
530
- const s = `idle_${c}`;
531
- if (!v.current[s]) {
532
- const n = R.clipAction(f, g);
533
- n.name = s, n.setLoop(Fe.LoopOnce, 1), n.clampWhenFinished = !0, v.current[s] = n;
532
+ ), C = c(null), B = c(null), M = c(null), me = c([]), [R] = _(() => new We.AnimationMixer(k)), v = c({}), y = c(null), ge = c(0), Te = c(!1), be = c(0), ae = c(null);
533
+ P(() => {
534
+ if (!(!q || !k)) {
535
+ if (q.forEach((d, u) => {
536
+ const i = `idle_${u}`;
537
+ if (!v.current[i]) {
538
+ const r = R.clipAction(d, k);
539
+ r.name = i, r.setLoop(We.LoopOnce, 1), r.clampWhenFinished = !0, v.current[i] = r;
534
540
  }
535
- }), se.forEach((f, c) => {
536
- const s = `talk_${c}`;
537
- if (!v.current[s]) {
538
- const n = R.clipAction(f, g);
539
- n.name = s, n.setLoop(Fe.LoopOnce, 1), n.clampWhenFinished = !0, v.current[s] = n;
541
+ }), I.forEach((d, u) => {
542
+ const i = `talk_${u}`;
543
+ if (!v.current[i]) {
544
+ const r = R.clipAction(d, k);
545
+ r.name = i, r.setLoop(We.LoopOnce, 1), r.clampWhenFinished = !0, v.current[i] = r;
540
546
  }
541
- }), Z.length > 0) {
542
- const f = v.current.idle_0, c = b.current && R.existingAction(b.current.getClip());
543
- f && !c && (f.reset().fadeIn(0.5).play(), b.current = f);
547
+ }), q.length > 0) {
548
+ const d = v.current.idle_0, u = y.current && R.existingAction(y.current.getClip());
549
+ d && !u && (d.reset().fadeIn(0.5).play(), y.current = d);
544
550
  }
545
551
  return () => {
546
- R.stopAllAction(), v.current = {}, b.current = null;
552
+ R.stopAllAction(), v.current = {}, y.current = null;
547
553
  };
548
554
  }
549
- }, [Z, se, g, R]);
550
- const Re = o("");
551
- z(() => {
552
- if (!M || !g || M === Re.current) return;
553
- Re.current = M, ee.current = M, new Ut().load(
554
- M,
555
- (c) => {
556
- if (c.animations && c.animations.length > 0) {
557
- const s = c.animations[0], n = R.clipAction(s, g);
558
- if (n.name = `EXPR_${M}`, n.setLoop(Fe.LoopOnce, 1), n.clampWhenFinished = !0, v.current[`EXPR_${M}`] = n, O && ee.current === M) {
559
- const h = b.current;
560
- n.reset().fadeIn(0.3).play(), h && h !== n && h.crossFadeTo(n, 0.3, !0), b.current = n, ee.current = null;
555
+ }, [q, I, k, R]);
556
+ const _e = c("");
557
+ P(() => {
558
+ if (!p || !k || p === _e.current) return;
559
+ _e.current = p, ae.current = p, new Xt().load(
560
+ p,
561
+ (u) => {
562
+ if (u.animations && u.animations.length > 0) {
563
+ const i = u.animations[0], r = R.clipAction(i, k);
564
+ if (r.name = `EXPR_${p}`, r.setLoop(We.LoopOnce, 1), r.clampWhenFinished = !0, v.current[`EXPR_${p}`] = r, F && ae.current === p) {
565
+ const h = y.current;
566
+ r.reset().fadeIn(0.3).play(), h && h !== r && h.crossFadeTo(r, 0.3, !0), y.current = r, ae.current = null;
561
567
  }
562
568
  }
563
569
  },
564
570
  void 0,
565
- (c) => {
566
- console.error(`[ANIMATION] Failed to load ${M}`, c);
571
+ (u) => {
572
+ console.error(`[ANIMATION] Failed to load ${p}`, u);
567
573
  }
568
574
  );
569
- }, [M, g, R, O]), z(() => {
570
- const f = (c) => {
571
- const s = c.action, n = s.name || "";
572
- if (n.startsWith("idle_")) {
573
- const H = (parseInt(n.split("_")[1]) + 1) % Z.length, Y = v.current[`idle_${H}`];
574
- Y && (Y.reset().fadeIn(0.5).play(), s.crossFadeTo(Y, 0.5, !0), b.current = Y);
575
- } else if (n.startsWith("EXPR_")) {
576
- if (O) {
575
+ }, [p, k, R, F]), P(() => {
576
+ const d = (u) => {
577
+ const i = u.action, r = i.name || "";
578
+ if (r.startsWith("idle_")) {
579
+ const G = (parseInt(r.split("_")[1]) + 1) % q.length, Q = v.current[`idle_${G}`];
580
+ Q && (Q.reset().fadeIn(0.5).play(), i.crossFadeTo(Q, 0.5, !0), y.current = Q);
581
+ } else if (r.startsWith("EXPR_")) {
582
+ if (F) {
577
583
  const h = v.current.talk_0;
578
- h && (h.reset().fadeIn(0.5).play(), s.crossFadeTo(h, 0.5, !0), b.current = h);
584
+ h && (h.reset().fadeIn(0.5).play(), i.crossFadeTo(h, 0.5, !0), y.current = h);
579
585
  } else {
580
586
  const h = v.current.idle_0;
581
- h && (h.reset().fadeIn(0.5).play(), s.crossFadeTo(h, 0.5, !0), b.current = h);
587
+ h && (h.reset().fadeIn(0.5).play(), i.crossFadeTo(h, 0.5, !0), y.current = h);
582
588
  }
583
- ce && ce();
584
- } else if (n.startsWith("talk_"))
585
- if (O) {
586
- const H = (parseInt(n.split("_")[1]) + 1) % se.length, Y = v.current[`talk_${H}`];
587
- Y && (Y.reset().fadeIn(0.3).play(), s.crossFadeTo(Y, 0.3, !0), b.current = Y);
589
+ Y && Y();
590
+ } else if (r.startsWith("talk_"))
591
+ if (F && !$) {
592
+ const G = (parseInt(r.split("_")[1]) + 1) % I.length, Q = v.current[`talk_${G}`];
593
+ Q && (Q.reset().fadeIn(0.3).play(), i.crossFadeTo(Q, 0.3, !0), y.current = Q);
588
594
  } else {
589
595
  const h = v.current.idle_0;
590
- h && (h.reset().fadeIn(0.5).play(), s.crossFadeTo(h, 0.5, !0), b.current = h);
596
+ h && (h.reset().fadeIn(0.5).play(), i.crossFadeTo(h, 0.5, !0), y.current = h);
591
597
  }
592
598
  };
593
- return R.addEventListener("finished", f), () => R.removeEventListener("finished", f);
599
+ return R.addEventListener("finished", d), () => R.removeEventListener("finished", d);
594
600
  }, [
595
601
  R,
596
- Z,
597
- se,
598
- O,
599
- ce
600
- ]), z(() => {
601
- if (O && g) {
602
- const f = b.current, c = f?.name || "";
603
- if (c.startsWith("idle_") || c.startsWith("talk_") || c === "") {
604
- const s = ee.current;
605
- if (s) {
606
- const n = v.current[`EXPR_${s}`];
607
- if (n) {
608
- n.reset().fadeIn(0.3).play(), f && f !== n && f.crossFadeTo(n, 0.3, !0), b.current = n, ee.current = null;
602
+ q,
603
+ I,
604
+ F,
605
+ $,
606
+ Y
607
+ ]), P(() => {
608
+ if (F && k) {
609
+ const d = y.current, u = d?.name || "";
610
+ if (u.startsWith("idle_") || u.startsWith("talk_") || u === "") {
611
+ const i = ae.current;
612
+ if (i) {
613
+ const r = v.current[`EXPR_${i}`];
614
+ if (r) {
615
+ r.reset().fadeIn(0.3).play(), d && d !== r && d.crossFadeTo(r, 0.3, !0), y.current = r, ae.current = null;
609
616
  return;
610
617
  }
611
618
  }
612
- if (c.startsWith("idle_") || c === "") {
613
- const n = v.current.talk_0;
614
- n && (n.reset().fadeIn(0.5).play(), f && f.crossFadeTo(n, 0.5, !0), b.current = n);
619
+ if (u.startsWith("idle_") || u === "") {
620
+ const r = v.current.talk_0;
621
+ r && (r.reset().fadeIn(0.5).play(), d && d.crossFadeTo(r, 0.5, !0), y.current = r);
615
622
  }
616
623
  }
617
- } else if (!O && g) {
618
- const f = b.current, c = f?.name || "";
619
- if (c.startsWith("talk_") || c.startsWith("EXPR_")) {
620
- const s = v.current.idle_0;
621
- s && (s.reset().fadeIn(0.5).play(), f && f.crossFadeTo(s, 0.5, !0), b.current = s);
624
+ } else if (!F && k) {
625
+ const d = y.current, u = d?.name || "";
626
+ if (u.startsWith("talk_") || u.startsWith("EXPR_")) {
627
+ const i = v.current.idle_0;
628
+ i && (i.reset().fadeIn(0.5).play(), d && d.crossFadeTo(i, 0.5, !0), y.current = i);
622
629
  }
623
630
  }
624
- }, [O, g, M]), z(() => {
625
- if (!g) return;
626
- g.traverse((s) => {
627
- if (s.isMesh && s.morphTargetDictionary) {
628
- const n = s.name.toLowerCase();
629
- (n.includes("head") || n.includes("avatar")) && (I.current = s, B(`[ANIMATION] Found head mesh: ${s.name}`)), n.includes("teeth") && (m.current = s, B(`[ANIMATION] Found teeth mesh: ${s.name}`));
631
+ }, [F, k, p]), P(() => {
632
+ if (!k) return;
633
+ k.traverse((i) => {
634
+ if (i.isMesh && i.morphTargetDictionary) {
635
+ const r = i.name.toLowerCase();
636
+ (r.includes("head") || r.includes("avatar")) && (B.current = i, U(`[ANIMATION] Found head mesh: ${i.name}`)), r.includes("teeth") && (M.current = i, U(`[ANIMATION] Found teeth mesh: ${i.name}`));
630
637
  }
631
638
  });
632
- const f = I.current?.morphTargetDictionary;
633
- f && Object.keys(f).filter(
634
- (s) => s.toLowerCase().includes("brow")
639
+ const d = B.current?.morphTargetDictionary;
640
+ d && Object.keys(d).filter(
641
+ (i) => i.toLowerCase().includes("brow")
635
642
  );
636
- const c = [];
637
- g.traverse((s) => {
638
- if (s.isMesh) {
639
- const h = s.morphTargetDictionary;
640
- h && Object.keys(h).some((H) => H.toLowerCase().includes("brow")) && c.push(s);
643
+ const u = [];
644
+ k.traverse((i) => {
645
+ if (i.isMesh) {
646
+ const h = i.morphTargetDictionary;
647
+ h && Object.keys(h).some((G) => G.toLowerCase().includes("brow")) && u.push(i);
641
648
  }
642
- }), $.current = c, c.length > 0 && B("[ANIMATION] Meshes with brow morphs:", c.length);
643
- }, [g]);
644
- const Ue = (f, c = 1) => {
645
- const s = `viseme_${f}`.toLowerCase(), n = zt.find((h) => h.key.toLowerCase() === s);
646
- if (n)
647
- for (const h in n.mix) {
648
- const H = n.mix[h] * c;
649
- G(I.current, h, H), G(m.current, h, H);
649
+ }), me.current = u, u.length > 0 && U("[ANIMATION] Meshes with brow morphs:", u.length);
650
+ }, [k]);
651
+ const Ne = (d, u = 1) => {
652
+ const i = `viseme_${d}`.toLowerCase(), r = dn.find((h) => h.key.toLowerCase() === i);
653
+ if (r)
654
+ for (const h in r.mix) {
655
+ const G = r.mix[h] * u;
656
+ z(B.current, h, G), z(M.current, h, G);
650
657
  }
651
- }, Ce = (f) => {
652
- const c = He[f] ?? He.neutral;
653
- for (const s in c)
654
- G(I.current, s, c[s]), G(m.current, s, c[s]);
658
+ }, Se = (d) => {
659
+ const u = Qe[d] ?? Qe.neutral;
660
+ for (const i in u)
661
+ z(B.current, i, u[i]), z(M.current, i, u[i]);
655
662
  };
656
- return Tt((f, c) => {
657
- const s = Math.pow(0.88, 60 * c);
658
- ht(I.current, s), ht(m.current, s), Ce(L);
659
- const n = f.clock.elapsedTime;
663
+ return Jt((d, u) => {
664
+ const i = Math.pow(0.88, 60 * u);
665
+ Rt(B.current, i), Rt(M.current, i), Se(E);
666
+ const r = d.clock.elapsedTime;
660
667
  let h = 0;
661
- if (Math.floor(n) % 5 === 0 && Math.floor((n - c) % 5) !== 0) {
662
- let j = null;
663
- g.traverse((W) => {
664
- W.name.toLowerCase().includes("hips") && (j = W);
668
+ if (Math.floor(r) % 5 === 0 && Math.floor((r - u) % 5) !== 0) {
669
+ let J = null;
670
+ k.traverse((te) => {
671
+ te.name.toLowerCase().includes("hips") && (J = te);
665
672
  });
666
- const ie = j ? `Hips Y: ${j.position.y.toFixed(4)}` : "Hips not found";
667
- B(`[ANIMATION] Mixer Time: ${R.time.toFixed(2)}, ${ie}`);
673
+ const ve = J ? `Hips Y: ${J.position.y.toFixed(4)}` : "Hips not found";
674
+ U(`[ANIMATION] Mixer Time: ${R.time.toFixed(2)}, ${ve}`);
668
675
  }
669
- if (R.update(c), n > K.current && !q.current && (q.current = !0, le.current = n), q.current) {
670
- const ie = (n - le.current) / 0.3;
671
- if (ie >= 1)
672
- q.current = !1, K.current = n + 2 + Math.random() * 5;
676
+ if (R.update(u), r > ge.current && !Te.current && (Te.current = !0, be.current = r), Te.current) {
677
+ const ve = (r - be.current) / 0.3;
678
+ if (ve >= 1)
679
+ Te.current = !1, ge.current = r + 2 + Math.random() * 5;
673
680
  else {
674
- const W = ie < 0.5 ? ie * 2 : (1 - ie) * 2;
675
- G(I.current, "eyeBlinkLeft", W), G(I.current, "eyeBlinkRight", W), G(m.current, "eyeBlinkLeft", W), G(m.current, "eyeBlinkRight", W), h = W * qt.browInnerUp;
681
+ const te = ve < 0.5 ? ve * 2 : (1 - ve) * 2;
682
+ z(B.current, "eyeBlinkLeft", te), z(B.current, "eyeBlinkRight", te), z(M.current, "eyeBlinkLeft", te), z(M.current, "eyeBlinkRight", te), h = te * ln.browInnerUp;
676
683
  }
677
684
  }
678
- const H = He[L] ?? He.neutral, Y = H.browInnerUp ?? 0, be = H.browOuterUpLeft ?? 0, me = H.browOuterUpRight ?? 0, Ae = n * Gt, ge = Ze * Math.sin(Ae), _e = Ze * 0.7 * Math.sin(Ae + 0.7), De = Ze * 0.7 * Math.sin(Ae + 1.3), we = (j) => Math.max(0, Math.min(1, j)), Oe = we(Y + ge), Le = we(be + _e), je = we(me + De), Ne = we(Oe + h);
679
- if (G(I.current, "browInnerUp", Ne), G(m.current, "browInnerUp", Ne), G(I.current, "browOuterUpLeft", Le), G(m.current, "browOuterUpLeft", Le), G(I.current, "browOuterUpRight", je), G(m.current, "browOuterUpRight", je), J.current) {
680
- const j = x.current ? 0 : E.rotation[1];
681
- J.current.rotation.y = Fe.MathUtils.lerp(
682
- J.current.rotation.y,
683
- j,
685
+ const G = Qe[E] ?? Qe.neutral, Q = G.browInnerUp ?? 0, Xe = G.browOuterUpLeft ?? 0, He = G.browOuterUpRight ?? 0, Fe = r * un, xe = lt * Math.sin(Fe), we = lt * 0.7 * Math.sin(Fe + 0.7), $e = lt * 0.7 * Math.sin(Fe + 1.3), ee = (J) => Math.max(0, Math.min(1, J)), ke = ee(Q + xe), Ae = ee(Xe + we), Ue = ee(He + $e), Ee = ee(ke + h);
686
+ if (z(B.current, "browInnerUp", Ee), z(M.current, "browInnerUp", Ee), z(B.current, "browOuterUpLeft", Ae), z(M.current, "browOuterUpLeft", Ae), z(B.current, "browOuterUpRight", Ue), z(M.current, "browOuterUpRight", Ue), C.current) {
687
+ const J = L.current ? 0 : W.rotation[1];
688
+ C.current.rotation.y = We.MathUtils.lerp(
689
+ C.current.rotation.y,
690
+ J,
684
691
  0.1
685
- ), J.current.position.set(...E.position), J.current.scale.setScalar(E.scale), J.current.rotation.x = E.rotation[0], J.current.rotation.z = E.rotation[2];
692
+ ), C.current.position.set(...W.position), C.current.scale.setScalar(W.scale), C.current.rotation.x = W.rotation[0], C.current.rotation.z = W.rotation[2];
686
693
  }
687
- if (x.current && p.current) {
688
- const j = p.current.currentTime, ve = (j - D.current) * 1e3 - -150;
689
- for (let Me = 0; Me < w.current.length; Me++) {
690
- const Se = w.current[Me];
691
- ve >= Se.vtime && ve < Se.vtime + Se.vduration && Ue(Se.viseme, Se.weight ?? 1);
694
+ if (L.current && g.current) {
695
+ const J = g.current.currentTime, Ie = (J - T.current) * 1e3 - -150;
696
+ for (let K = 0; K < w.current.length; K++) {
697
+ const ce = w.current[K];
698
+ Ie >= ce.vtime && Ie < ce.vtime + ce.vduration && Ne(ce.viseme, ce.weight ?? 1);
692
699
  }
693
- j > k.current + 0.5 && (Q(), U(!1));
700
+ J > H.current + 0.5 && (b(), oe(!1));
694
701
  }
695
- }), /* @__PURE__ */ u("group", { ref: J, children: /* @__PURE__ */ u("primitive", { object: g }) });
702
+ }), /* @__PURE__ */ l("group", { ref: C, children: /* @__PURE__ */ l("primitive", { object: k }) });
696
703
  }
697
704
  );
698
- function Zt(d) {
699
- return d ? d.charAt(0).toUpperCase() + d.slice(1).toLowerCase() : "";
705
+ function gn(f) {
706
+ return f ? f.charAt(0).toUpperCase() + f.slice(1).toLowerCase() : "";
700
707
  }
701
- const en = ({
702
- token: d,
703
- agentToken: x,
704
- onNavigationRequested: w
708
+ const bn = ({
709
+ token: f,
710
+ agentToken: L,
711
+ onNavigationRequested: w,
712
+ avatarGender: g
705
713
  } = {}) => {
706
- const p = d ?? x ?? "", D = Vt(p || void 0), [E, L] = y(""), [he, re] = y(""), [O, k] = y("Ready"), [Q, U] = y(!1), [M, ce] = y(!1), [g, ke] = y(
714
+ const T = f ?? L ?? "", W = tn(T || void 0), [E, Z] = _(""), [ie, F] = _(""), [H, b] = _("Ready"), [oe, p] = _(!1), [Y, $] = _(!1), [he, k] = _([]), [Ve, ye] = _(""), q = c(null), [pe, I] = _(
707
715
  () => typeof window < "u" ? window.matchMedia("(max-width: 480px)").matches : !1
708
716
  );
709
- z(() => {
710
- const e = window.matchMedia("(max-width: 480px)"), t = () => ke(e.matches);
717
+ P(() => {
718
+ const e = window.matchMedia("(max-width: 480px)"), t = () => I(e.matches);
711
719
  return e.addEventListener("change", t), () => e.removeEventListener("change", t);
712
720
  }, []);
713
- const Z = g ? 80 : 600, pe = o(!1), se = o([]), J = o(0), I = o(!1), m = o([]), $ = o(null), R = o([]);
714
- o([]);
715
- const v = o([]), b = o(0), K = o(0), q = o(0), le = o(0), ee = o(!1), [Re, Ue] = y(
721
+ const C = pe ? 80 : 600, B = c(!1), M = c([]), me = c(0), R = c(!1), v = c([]), y = c(null), ge = c([]);
722
+ c([]);
723
+ const Te = c([]), be = c(0), ae = c(0), _e = c(0), Ne = c(0), Se = c(!1), [d, u] = _(
716
724
  null
717
- ), Ce = o(null), [f, c] = y("neutral"), [s, n] = y(""), [h, H] = y(""), [Y, be] = y("Chat with us"), [me, Ae] = y(
725
+ ), i = c(null), [r, h] = _("neutral"), [G, Q] = _(""), [Xe, He] = _(""), [Fe, xe] = _("Chat with us"), [we, $e] = _(
718
726
  null
719
- ), [ge, _e] = y("hidden"), [De, we] = y(""), Oe = o(null), Le = o(ge);
720
- Le.current = ge;
721
- const [je, Ne] = y(null), j = o(null), ie = o(null), [W, ve] = y("hidden"), [Me, Se] = y(""), Je = o(W);
722
- Je.current = W;
723
- const ue = o(""), Ee = o(!1), Te = o(""), Ie = et(() => O === "Thinking..." || O === "Processing Voice..." ? O : me != null && me !== "" && me !== "none" && me !== "<none>" ? `Enter ${Zt(me)}` : null, [O, me]), We = Ie != null && Ie !== "";
724
- z(() => {
725
- const e = Le.current;
727
+ ), [ee, ke] = _("hidden"), [Ae, Ue] = _(""), Ee = c(null), J = c(ee);
728
+ J.current = ee;
729
+ const [ve, te] = _(null), Ie = c(null), K = c(null), [ce, dt] = _(!1), ft = c(null), [Me, je] = _("hidden"), [ht, Tt] = _(""), Ke = c(Me);
730
+ Ke.current = Me;
731
+ const de = c(""), De = c(!1), Ce = c(""), pt = c(Date.now()), Ze = c([]), Be = c(!1), [et, Pe] = _(!1), mt = "__branding__", Oe = ut(() => ce ? "Try again" : H === "Busy" ? "Busy" : H === "Thinking..." || H === "Processing Voice..." ? H : we != null && we !== "" && we !== "none" && we !== "<none>" ? `Enter ${gn(we)}` : mt, [H, we, ce]), Je = Oe != null && Oe !== "";
732
+ P(() => {
733
+ const e = J.current;
726
734
  if (!(e === "exiting" || e === "entering")) {
727
735
  if (e === "hidden") {
728
- We && (we(Ie ?? ""), _e("entering"));
736
+ Je && (Ue(Oe ?? ""), ke("entering"));
729
737
  return;
730
738
  }
731
- e === "visible" && (!We || Ie !== De) && (Oe.current = We ? Ie : null, _e("exiting"));
739
+ e === "visible" && (!Je || Oe !== Ae) && (Ee.current = Je ? Oe : null, ke("exiting"));
732
740
  }
733
741
  }, [
734
- We,
735
- Ie,
736
- ge,
737
- De
738
- ]);
739
- const pt = $e(() => {
740
- const e = Le.current;
742
+ Je,
743
+ Oe,
744
+ ee,
745
+ Ae
746
+ ]), P(() => {
747
+ if (H !== "Busy") {
748
+ K.current != null && (clearTimeout(K.current), K.current = null);
749
+ return;
750
+ }
751
+ return K.current = setTimeout(() => {
752
+ K.current = null, b("Ready"), dt(!0);
753
+ }, 12e3), () => {
754
+ K.current != null && (clearTimeout(K.current), K.current = null);
755
+ };
756
+ }, [H]), P(() => {
757
+ if (!ce) return;
758
+ const e = setTimeout(() => dt(!1), 2500);
759
+ return () => clearTimeout(e);
760
+ }, [ce]);
761
+ const Et = Ye(() => {
762
+ const e = J.current;
741
763
  if (e === "exiting") {
742
- _e("hidden");
743
- const t = Oe.current;
744
- Oe.current = null, t != null && t !== "" && (we(t), _e("entering"));
745
- } else e === "entering" && _e("visible");
746
- }, []), mt = (e) => {
764
+ ke("hidden");
765
+ const t = Ee.current;
766
+ Ee.current = null, t != null && t !== "" && (Ue(t), ke("entering"));
767
+ } else e === "entering" && ke("visible");
768
+ }, []), It = (e) => {
747
769
  if (!e) return;
748
770
  if (e.mood != null) {
749
- const r = String(e.mood).toLowerCase();
750
- c(r);
771
+ const n = String(e.mood).toLowerCase();
772
+ h(n);
751
773
  }
752
774
  if (e.expression != null) {
753
- const r = String(e.expression).trim();
754
- n(r);
755
- const l = $t.find(
756
- (_) => _.name.toLowerCase() === r.toLowerCase()
775
+ const n = String(e.expression).trim();
776
+ Q(n);
777
+ const a = sn.find(
778
+ (m) => m.name.toLowerCase() === n.toLowerCase()
757
779
  );
758
- B(
759
- `[STREAM] Animation match for "${r}": ${l ? l.name : "NONE"}`
760
- ), H(l?.url ?? "");
780
+ U(
781
+ `[STREAM] Animation match for "${n}": ${a ? a.name : "NONE"}`
782
+ ), He(a?.url ?? "");
761
783
  }
762
784
  if (e.navigation != null) {
763
- const r = String(e.navigation).trim();
764
- r !== "" && (w ? w(r) : window.open(r, "_blank"));
785
+ const n = String(e.navigation).trim();
786
+ n !== "" && (w ? w(n) : window.open(n, "_blank"));
765
787
  }
766
- const t = e.ask_for || e.lead_capture?.ask_for, i = t ? String(t).trim().toLowerCase() : "", a = i === "none" || i === "<none>";
767
- if (t && !a) {
768
- const r = i;
769
- Ae(r || null), be(r === "email" ? "Enter your email" : r === "name" ? "Enter your name" : r === "phone" ? "Enter your phone number" : "Chat with us");
770
- } else (a || e.ask_for === null || e.lead_capture && e.lead_capture.ask_for === null || e.ask_for === "none") && (Ae(null), Y !== "Chat with us" && be("Chat with us"));
788
+ const t = e.ask_for || e.lead_capture?.ask_for, s = t ? String(t).trim().toLowerCase() : "", o = s === "none" || s === "<none>";
789
+ if (t && !o) {
790
+ const n = s;
791
+ $e(n || null), xe(n === "email" ? "Enter your email" : n === "name" ? "Enter your name" : n === "phone" ? "Enter your phone number" : "Chat with us");
792
+ } else (o || e.ask_for === null || e.lead_capture && e.lead_capture.ask_for === null || e.ask_for === "none") && ($e(null), Fe !== "Chat with us" && xe("Chat with us"));
771
793
  e.collected, e.valid;
772
- }, gt = (e) => {
794
+ }, Mt = (e) => {
773
795
  const t = e.trim();
774
796
  if (!t) return null;
775
797
  if (t.startsWith("{"))
@@ -779,50 +801,50 @@ const en = ({
779
801
  return null;
780
802
  }
781
803
  if (t.includes(":")) {
782
- const i = t.split(":"), a = i[0].trim().toLowerCase(), r = i.slice(1).join(":").trim();
783
- return { [a]: r };
804
+ const s = t.split(":"), o = s[0].trim().toLowerCase(), n = s.slice(1).join(":").trim();
805
+ return { [o]: n };
784
806
  }
785
807
  return null;
786
- }, bt = $e(() => {
787
- }, []), tt = (e) => {
788
- if (Ee.current)
789
- e === "§" ? Ee.current = !1 : (Te.current += e, re((t) => t + e));
808
+ }, Dt = Ye(() => {
809
+ }, []), gt = (e) => {
810
+ if (De.current)
811
+ e === "§" ? De.current = !1 : (Ce.current += e, F((t) => t + e));
790
812
  else if (e === "§") {
791
- Ee.current = !0;
813
+ De.current = !0;
792
814
  return;
793
815
  } else
794
- for (ue.current += e; ue.current.includes(`
816
+ for (de.current += e; de.current.includes(`
795
817
  `); ) {
796
- const t = ue.current.indexOf(`
797
- `), i = ue.current.slice(0, t).trim();
798
- ue.current = ue.current.slice(t + 1);
799
- const a = gt(i);
800
- a && mt(a);
818
+ const t = de.current.indexOf(`
819
+ `), s = de.current.slice(0, t).trim();
820
+ de.current = de.current.slice(t + 1);
821
+ const o = Mt(s);
822
+ o && It(o);
801
823
  }
802
824
  };
803
- z(() => {
825
+ P(() => {
804
826
  (async () => {
805
827
  if (!sessionStorage.getItem(
806
828
  "STREAMOJI_LEADS_SESSION_LEAD_ID"
807
829
  )) {
808
- const i = "secret", a = Math.floor(Date.now() / 1e3).toString();
830
+ const s = "secret", o = Math.floor(Date.now() / 1e3).toString();
809
831
  try {
810
- const r = new TextEncoder(), l = await crypto.subtle.importKey(
832
+ const n = new TextEncoder(), a = await crypto.subtle.importKey(
811
833
  "raw",
812
- r.encode(i),
834
+ n.encode(s),
813
835
  { name: "HMAC", hash: "SHA-256" },
814
836
  !1,
815
837
  ["sign"]
816
- ), _ = await crypto.subtle.sign(
838
+ ), m = await crypto.subtle.sign(
817
839
  "HMAC",
818
- l,
819
- r.encode(a)
820
- ), P = Array.from(new Uint8Array(_)).map((S) => S.toString(16).padStart(2, "0")).join("");
821
- sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", P), B("[SESSION] New HMAC UID generated and saved:", P);
822
- } catch (r) {
823
- console.error("[SESSION] HMAC generation failed:", r);
824
- const l = Math.random().toString(36) + Date.now().toString();
825
- sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", l);
840
+ a,
841
+ n.encode(o)
842
+ ), S = Array.from(new Uint8Array(m)).map((x) => x.toString(16).padStart(2, "0")).join("");
843
+ sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", S), U("[SESSION] New HMAC UID generated and saved:", S);
844
+ } catch (n) {
845
+ console.error("[SESSION] HMAC generation failed:", n);
846
+ const a = Math.random().toString(36) + Date.now().toString();
847
+ sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", a);
826
848
  }
827
849
  }
828
850
  sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES") || sessionStorage.setItem(
@@ -830,8 +852,57 @@ const en = ({
830
852
  JSON.stringify([])
831
853
  );
832
854
  })();
833
- }, []);
834
- const nt = () => {
855
+ }, []), P(() => {
856
+ const e = () => {
857
+ pt.current = Date.now(), Be.current && (Be.current = !1, Pe(!1), k([]), ye(""), F(""), $(!1));
858
+ };
859
+ window.addEventListener("mousemove", e), window.addEventListener("keydown", e), window.addEventListener("mousedown", e), window.addEventListener("touchstart", e);
860
+ const t = setInterval(async () => {
861
+ if (Date.now() - pt.current >= 3e4 && !Y && !oe && H === "Ready" && !Be.current)
862
+ if (Be.current = !0, Ze.current.length > 0)
863
+ Pe(!0), k(Ze.current);
864
+ else
865
+ try {
866
+ const n = `${ct}/nudgeUser`, a = {
867
+ navigationUrl: window.location.href,
868
+ token: T
869
+ }, m = await fetch(n, {
870
+ method: "POST",
871
+ headers: {
872
+ "Content-Type": "application/json"
873
+ },
874
+ body: JSON.stringify(a)
875
+ });
876
+ if (m.ok) {
877
+ const S = (await m.json()).nudge_questions;
878
+ S && S.length > 0 && (U("[NUDGE] Received nudge questions from API:", S), Ze.current = S, Pe(!0), k(S));
879
+ }
880
+ } catch (n) {
881
+ console.error("[NUDGE] Error calling /nudgeUser:", n), Be.current = !1;
882
+ }
883
+ }, 1e3);
884
+ return () => {
885
+ window.removeEventListener("mousemove", e), window.removeEventListener("keydown", e), window.removeEventListener("mousedown", e), window.removeEventListener("touchstart", e), clearInterval(t);
886
+ };
887
+ }, [T, Y, oe, H]), P(() => {
888
+ if (he.length === 0) return;
889
+ let e = 0, t = 0, s = !1, o = 100;
890
+ const n = () => {
891
+ const a = he[e];
892
+ if (s) {
893
+ const m = a.substring(0, t - 1);
894
+ ye(m), t--, o = 50;
895
+ } else {
896
+ const m = a.substring(0, t + 1);
897
+ ye(m), t++, o = 100;
898
+ }
899
+ !s && t === a.length ? (s = !0, o = 3e3) : s && t === 0 && (s = !1, e = (e + 1) % he.length, o = 500), q.current = setTimeout(n, o);
900
+ };
901
+ return n(), () => {
902
+ q.current && clearTimeout(q.current);
903
+ };
904
+ }, [he]);
905
+ const bt = () => {
835
906
  try {
836
907
  return JSON.parse(
837
908
  sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES") || "[]"
@@ -839,223 +910,232 @@ const en = ({
839
910
  } catch {
840
911
  return [];
841
912
  }
842
- }, _t = (e) => {
913
+ }, Ct = (e) => {
843
914
  sessionStorage.setItem(
844
915
  "STREAMOJI_LEADS_SESSION_MESSAGES",
845
916
  JSON.stringify(e)
846
917
  );
847
- }, [qe, Ge] = y(!1), [rt, ze] = y(0), oe = o(null), Pe = o([]), st = o(0), [it, wt] = y(
918
+ }, [tt, nt] = _(!1), [_t, rt] = _(0), le = c(null), qe = c([]), wt = c(0), [vt, Ot] = _(
848
919
  null
849
- ), [vt, Ye] = y(
920
+ ), [Nt, st] = _(
850
921
  null
851
- ), de = o(null), ye = o(
922
+ ), fe = c(null), Le = c(
852
923
  null
853
- ), Ve = $e((e = !1) => {
854
- e && (ee.current = !0, U(!1), k("Ready")), m.current = [], se.current = [], I.current = !1, ce(!1), b.current = 0, K.current = 0, q.current = 0, R.current.forEach((t) => {
924
+ ), Ge = Ye((e = !1) => {
925
+ e && (Se.current = !0, p(!1), b("Ready")), v.current = [], M.current = [], R.current = !1, $(!1), be.current = 0, ae.current = 0, _e.current = 0, ge.current.forEach((t) => {
855
926
  try {
856
927
  t.stop();
857
928
  } catch {
858
929
  }
859
- }), j.current && (clearTimeout(j.current), j.current = null), Ne(null), H(""), R.current = [];
860
- }, []), St = async () => {
930
+ }), Ie.current && (clearTimeout(Ie.current), Ie.current = null), te(null), He(""), ge.current = [];
931
+ }, []), Ft = async () => {
861
932
  try {
862
- const e = await navigator.mediaDevices.getUserMedia({ audio: !0 }), t = window.AudioContext || window.webkitAudioContext, i = new t(), a = i.createMediaStreamSource(e), r = i.createAnalyser();
863
- r.fftSize = 64, a.connect(r), de.current = i, ye.current = a, Ye(r);
864
- const l = new MediaRecorder(e);
865
- oe.current = l, Pe.current = [], l.ondataavailable = (_) => {
866
- _.data.size > 0 && Pe.current.push(_.data);
867
- }, l.onstop = async () => {
868
- const _ = Date.now() - st.current;
869
- if (Ye(null), ye.current && (ye.current.disconnect(), ye.current = null), de.current && de.current.state !== "closed" && (de.current.close(), de.current = null), _ < 1e3) {
870
- k("Recording too short. Hold or click longer."), U(!1);
933
+ const e = await navigator.mediaDevices.getUserMedia({ audio: !0 }), t = window.AudioContext || window.webkitAudioContext, s = new t(), o = s.createMediaStreamSource(e), n = s.createAnalyser();
934
+ n.fftSize = 64, o.connect(n), fe.current = s, Le.current = o, st(n);
935
+ const a = new MediaRecorder(e);
936
+ le.current = a, qe.current = [], a.ondataavailable = (m) => {
937
+ m.data.size > 0 && qe.current.push(m.data);
938
+ }, a.onstop = async () => {
939
+ const m = Date.now() - wt.current;
940
+ if (st(null), Le.current && (Le.current.disconnect(), Le.current = null), fe.current && fe.current.state !== "closed" && (fe.current.close(), fe.current = null), m < 1e3) {
941
+ b("Recording too short. Hold or click longer."), p(!1);
871
942
  return;
872
943
  }
873
- const A = new Blob(Pe.current, {
944
+ const A = new Blob(qe.current, {
874
945
  type: "audio/wav"
875
946
  });
876
- await Rt(A);
877
- }, st.current = Date.now(), l.start(100), Ge(!0), k("Listening...");
947
+ await Wt(A);
948
+ }, wt.current = Date.now(), a.start(100), nt(!0), b("Listening...");
878
949
  } catch (e) {
879
- console.error("Error accessing microphone:", e), k("Mic Access Error");
950
+ console.error("Error accessing microphone:", e), b("Mic Access Error");
880
951
  }
881
- }, yt = () => {
882
- oe.current && oe.current.state !== "inactive" && (oe.current.stop(), oe.current.stream.getTracks().forEach((e) => e.stop()), Ge(!1));
883
- }, xt = () => {
884
- oe.current && oe.current.state !== "inactive" && (oe.current.onstop = null, oe.current.stop(), oe.current.stream.getTracks().forEach((e) => e.stop()), Ye(null), ye.current && (ye.current.disconnect(), ye.current = null), de.current && de.current.state !== "closed" && (de.current.close(), de.current = null), Ge(!1), Pe.current = [], k("Ready"));
952
+ }, Ut = () => {
953
+ le.current && le.current.state !== "inactive" && (le.current.stop(), le.current.stream.getTracks().forEach((e) => e.stop()), nt(!1));
954
+ }, Bt = () => {
955
+ le.current && le.current.state !== "inactive" && (le.current.onstop = null, le.current.stop(), le.current.stream.getTracks().forEach((e) => e.stop()), st(null), Le.current && (Le.current.disconnect(), Le.current = null), fe.current && fe.current.state !== "closed" && (fe.current.close(), fe.current = null), nt(!1), qe.current = [], b("Ready"));
885
956
  };
886
- z(() => {
887
- if (!M) return;
957
+ P(() => {
958
+ if (!Y) return;
888
959
  const e = () => {
889
- const t = q.current;
960
+ const t = _e.current;
890
961
  if (t <= 0) return;
891
- const i = $.current, a = b.current;
892
- if (!i) return;
893
- const r = i.currentTime - a, l = Math.min(Math.max(0, r), t), _ = he.trim().length;
894
- if (_ <= 0) return;
962
+ const s = y.current, o = be.current;
963
+ if (!s) return;
964
+ const n = s.currentTime - o, a = Math.min(Math.max(0, n), t), m = ie.trim().length;
965
+ if (m <= 0) return;
895
966
  const A = Math.min(
896
- Math.round(l / t * _),
897
- _
967
+ Math.round(a / t * m),
968
+ m
898
969
  );
899
- Ue(A);
970
+ u(A);
900
971
  };
901
- return clearInterval(Ce.current ?? void 0), Ce.current = setInterval(e, 90), () => clearInterval(Ce.current ?? void 0);
902
- }, [M, he, q.current]), z(() => {
972
+ return clearInterval(i.current ?? void 0), i.current = setInterval(e, 90), () => clearInterval(i.current ?? void 0);
973
+ }, [Y, ie, _e.current]), P(() => {
903
974
  let e;
904
- return qe ? (ze(0), e = window.setInterval(() => {
905
- ze((t) => t + 1);
906
- }, 1e3)) : ze(0), () => clearInterval(e);
907
- }, [qe]);
908
- const kt = (e) => {
909
- const t = e.numberOfChannels, i = e.length * t * 2 + 44, a = new ArrayBuffer(i), r = new DataView(a);
910
- let l = 0;
911
- const _ = (F) => {
912
- r.setUint16(l, F, !0), l += 2;
913
- }, A = (F) => {
914
- r.setUint32(l, F, !0), l += 4;
975
+ return tt ? (rt(0), e = window.setInterval(() => {
976
+ rt((t) => t + 1);
977
+ }, 1e3)) : rt(0), () => clearInterval(e);
978
+ }, [tt]);
979
+ const Pt = (e) => {
980
+ const t = e.numberOfChannels, s = e.length * t * 2 + 44, o = new ArrayBuffer(s), n = new DataView(o);
981
+ let a = 0;
982
+ const m = (O) => {
983
+ n.setUint16(a, O, !0), a += 2;
984
+ }, A = (O) => {
985
+ n.setUint32(a, O, !0), a += 4;
915
986
  };
916
- A(1179011410), A(i - 8), A(1163280727), A(544501094), A(16), _(1), _(t), A(e.sampleRate), A(e.sampleRate * 2 * t), _(t * 2), _(16), A(1635017060), A(i - l - 4);
917
- const P = [];
918
- for (let F = 0; F < t; F++) P.push(e.getChannelData(F));
919
- let S = 0;
920
- for (; l < i; ) {
921
- for (let F = 0; F < t; F++) {
922
- let N = Math.max(-1, Math.min(1, P[F][S]));
923
- N = N < 0 ? N * 32768 : N * 32767, r.setInt16(l, N, !0), l += 2;
987
+ A(1179011410), A(s - 8), A(1163280727), A(544501094), A(16), m(1), m(t), A(e.sampleRate), A(e.sampleRate * 2 * t), m(t * 2), m(16), A(1635017060), A(s - a - 4);
988
+ const S = [];
989
+ for (let O = 0; O < t; O++) S.push(e.getChannelData(O));
990
+ let x = 0;
991
+ for (; a < s; ) {
992
+ for (let O = 0; O < t; O++) {
993
+ let V = Math.max(-1, Math.min(1, S[O][x]));
994
+ V = V < 0 ? V * 32768 : V * 32767, n.setInt16(a, V, !0), a += 2;
924
995
  }
925
- S++;
996
+ x++;
926
997
  }
927
- return new Blob([a], { type: "audio/wav" });
928
- }, Xe = async (e, t, i = !1) => {
929
- if (!ee.current) {
930
- if (pe.current) {
931
- se.current.push({
998
+ return new Blob([o], { type: "audio/wav" });
999
+ }, it = async (e, t, s = !1) => {
1000
+ if (!Se.current) {
1001
+ if (B.current) {
1002
+ M.current.push({
932
1003
  audio: e,
933
1004
  visemes: t,
934
- isNewSegment: i
1005
+ isNewSegment: s
935
1006
  });
936
1007
  return;
937
1008
  }
938
- pe.current = !0;
1009
+ B.current = !0;
939
1010
  try {
940
- const a = window.AudioContext || window.webkitAudioContext, r = $.current ?? new a();
941
- r.state === "suspended" && await r.resume(), $.current = r;
942
- const l = window.atob(e), _ = new Uint8Array(l.length);
943
- for (let T = 0; T < l.length; T++)
944
- _[T] = l.charCodeAt(T);
945
- const A = await r.decodeAudioData(_.buffer.slice(0));
946
- q.current += A.duration;
947
- const P = r.currentTime;
948
- let S = K.current;
949
- const F = !I.current;
950
- S < P && (S = P + 0.1), K.current = S + A.duration;
951
- const N = r.createBufferSource();
952
- N.buffer = A;
953
- let V = it;
954
- if ((!V || V.context !== r) && (V = r.createAnalyser(), V.fftSize = 64, V.connect(r.destination), wt(V)), N.connect(V), R.current.push(N), ee.current) {
955
- R.current = R.current.filter((T) => T !== N);
1011
+ const o = window.AudioContext || window.webkitAudioContext, n = y.current ?? new o();
1012
+ n.state === "suspended" && await n.resume(), y.current = n;
1013
+ const a = window.atob(e), m = new Uint8Array(a.length);
1014
+ for (let N = 0; N < a.length; N++)
1015
+ m[N] = a.charCodeAt(N);
1016
+ const A = await n.decodeAudioData(m.buffer.slice(0));
1017
+ _e.current += A.duration;
1018
+ const S = n.currentTime;
1019
+ let x = ae.current;
1020
+ const O = !R.current;
1021
+ x < S && (x = S + 0.1), ae.current = x + A.duration;
1022
+ const V = n.createBufferSource();
1023
+ V.buffer = A;
1024
+ let j = vt;
1025
+ if ((!j || j.context !== n) && (j = n.createAnalyser(), j.fftSize = 64, j.connect(n.destination), Ot(j)), V.connect(j), ge.current.push(V), Se.current) {
1026
+ ge.current = ge.current.filter((N) => N !== V);
956
1027
  return;
957
1028
  }
958
- if (F) {
959
- I.current = !0, ce(!0), B(
960
- `[AUDIO] setIsSpeaking(true) - First chunk starting at ${S.toFixed(
1029
+ if (O) {
1030
+ R.current = !0, $(!0), U(
1031
+ `[AUDIO] setIsSpeaking(true) - First chunk starting at ${x.toFixed(
961
1032
  3
962
1033
  )}`
963
- ), b.current = S;
964
- const T = (S - P) * 1e3;
965
- J.current = performance.now() + T, B(
966
- `[AUDIO] Response started. Initial startTime: ${S.toFixed(
1034
+ ), be.current = x;
1035
+ const N = (x - S) * 1e3;
1036
+ me.current = performance.now() + N, U(
1037
+ `[AUDIO] Response started. Initial startTime: ${x.toFixed(
967
1038
  3
968
- )}, CT: ${P.toFixed(3)}`
1039
+ )}, CT: ${S.toFixed(3)}`
969
1040
  );
970
1041
  }
971
- N.start(S);
972
- const X = (S - b.current) * 1e3;
973
- i && (le.current = X, B(
1042
+ V.start(x);
1043
+ const X = (x - be.current) * 1e3;
1044
+ s && (Ne.current = X, U(
974
1045
  `[AUDIO] New segment detected at +${X.toFixed(
975
1046
  0
976
1047
  )}ms. Resetting segment offset.`
977
- )), t.forEach((T, fe) => {
978
- const C = T.symbol ?? "";
979
- if (C) {
980
- const te = Xt(C), ae = Math.round(T.start * 1e3), xe = Math.round((T.duration ?? 0) * 1e3), ct = le.current + ae;
981
- fe < 3 && B(
982
- `[AUDIO] Viseme "${C}": segment_relative=${ae}ms, segment_offset=${le.current.toFixed(
1048
+ )), t.forEach((N, ne) => {
1049
+ const D = N.symbol ?? "";
1050
+ if (D) {
1051
+ const re = hn(D), ue = Math.round(N.start * 1e3), Re = Math.round((N.duration ?? 0) * 1e3), xt = Ne.current + ue;
1052
+ ne < 3 && U(
1053
+ `[AUDIO] Viseme "${D}": segment_relative=${ue}ms, segment_offset=${Ne.current.toFixed(
983
1054
  0
984
- )}ms => vtime=${ct}ms`
985
- ), te.forEach((lt) => {
986
- m.current.push({
987
- viseme: lt.v,
988
- weight: lt.w,
989
- vtime: ct,
990
- vduration: xe
1055
+ )}ms => vtime=${xt}ms`
1056
+ ), re.forEach((kt) => {
1057
+ v.current.push({
1058
+ viseme: kt.v,
1059
+ weight: kt.w,
1060
+ vtime: xt,
1061
+ vduration: Re
991
1062
  });
992
1063
  });
993
1064
  }
994
- }), k("Speaking...");
1065
+ }), b("Speaking...");
995
1066
  } finally {
996
- if (pe.current = !1, se.current.length > 0) {
997
- const a = se.current.shift();
998
- a && Xe(a.audio, a.visemes, a.isNewSegment);
1067
+ if (B.current = !1, M.current.length > 0) {
1068
+ const o = M.current.shift();
1069
+ o && it(o.audio, o.visemes, o.isNewSegment);
999
1070
  }
1000
1071
  }
1001
1072
  }
1002
- }, Rt = async (e) => {
1073
+ }, Wt = async (e) => {
1003
1074
  try {
1004
- U(!0), Te.current = "", re(""), k("Processing Voice...");
1005
- const t = await e.arrayBuffer(), a = await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(t), r = kt(a), l = new FileReader();
1006
- l.readAsDataURL(r), l.onloadend = async () => {
1007
- const _ = l.result.split(",")[1];
1008
- Ve(), L(""), ue.current = "", Ee.current = !1;
1009
- const A = `${dt}/stt?token=${encodeURIComponent(
1010
- p
1011
- )}`, P = await fetch(A, {
1075
+ p(!0), Pe(!1), Ce.current = "", F(""), b("Processing Voice...");
1076
+ const t = await e.arrayBuffer(), o = await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(t), n = Pt(o), a = new FileReader();
1077
+ a.readAsDataURL(n), a.onloadend = async () => {
1078
+ const m = a.result.split(",")[1];
1079
+ Ge(), Z(""), de.current = "", De.current = !1;
1080
+ const A = `${ct}/stt?token=${encodeURIComponent(
1081
+ T
1082
+ )}`, S = await fetch(A, {
1012
1083
  method: "POST",
1013
1084
  headers: { "Content-Type": "application/json" },
1014
1085
  body: JSON.stringify({
1015
- audio_base64: _,
1086
+ audio_base64: m,
1016
1087
  audio_format: "wav"
1017
1088
  })
1018
1089
  });
1019
- if (!P.ok) {
1020
- const fe = await P.text();
1021
- let C = "STT Failed";
1090
+ if (S.status === 429) {
1022
1091
  try {
1023
- C = JSON.parse(fe).error || C;
1092
+ const ne = await S.text(), D = JSON.parse(ne);
1093
+ U("[STT] 429 agent at capacity:", D?.detail);
1024
1094
  } catch {
1025
- fe && (C = fe.slice(0, 200));
1026
1095
  }
1027
- throw new Error(C);
1096
+ Z(""), b("Busy"), p(!1);
1097
+ return;
1028
1098
  }
1029
- const S = P.body;
1030
- if (B("this is body" + S), !S) {
1031
- k("STT Failed"), U(!1);
1099
+ if (!S.ok) {
1100
+ const ne = await S.text();
1101
+ let D = "STT Failed";
1102
+ try {
1103
+ D = JSON.parse(ne).error || D;
1104
+ } catch {
1105
+ ne && (D = ne.slice(0, 200));
1106
+ }
1107
+ throw new Error(D);
1108
+ }
1109
+ const x = S.body;
1110
+ if (U("this is body" + x), !x) {
1111
+ b("STT Failed"), p(!1);
1032
1112
  return;
1033
1113
  }
1034
- const F = S.getReader();
1035
- ee.current = !1;
1036
- const N = new TextDecoder();
1037
- let V = "", X = !1;
1038
- const T = async (fe, C) => {
1039
- switch (fe) {
1114
+ const O = x.getReader();
1115
+ Se.current = !1;
1116
+ const V = new TextDecoder();
1117
+ let j = "", X = !1;
1118
+ const N = async (ne, D) => {
1119
+ switch (ne) {
1040
1120
  case "transcript":
1041
- C.transcript != null && L(String(C.transcript));
1121
+ D.transcript != null && Z(String(D.transcript));
1042
1122
  break;
1043
1123
  case "text": {
1044
- const te = C.delta ?? C.text ?? "";
1045
- te && tt(te);
1124
+ const re = D.delta ?? D.text ?? "";
1125
+ re && gt(re);
1046
1126
  break;
1047
1127
  }
1048
1128
  case "audio": {
1049
- const te = C.chunk, ae = C.visemes ?? [], xe = !!C.is_new_segment;
1050
- te && await Xe(te, ae, xe);
1129
+ const re = D.chunk, ue = D.visemes ?? [], Re = !!D.is_new_segment;
1130
+ re && await it(re, ue, Re);
1051
1131
  break;
1052
1132
  }
1053
1133
  case "done": {
1054
- X = !0, k("Ready"), U(!1);
1134
+ X = !0, b("Ready"), p(!1);
1055
1135
  break;
1056
1136
  }
1057
1137
  case "error": {
1058
- X = !0, k("STT Failed"), U(!1);
1138
+ X = !0, b("STT Failed"), p(!1);
1059
1139
  break;
1060
1140
  }
1061
1141
  default:
@@ -1063,163 +1143,180 @@ const en = ({
1063
1143
  }
1064
1144
  };
1065
1145
  for (; ; ) {
1066
- const { done: fe, value: C } = await F.read();
1067
- C && (V += N.decode(C, { stream: !0 }));
1068
- const te = V.split(`
1146
+ const { done: ne, value: D } = await O.read();
1147
+ D && (j += V.decode(D, { stream: !0 }));
1148
+ const re = j.split(`
1069
1149
 
1070
1150
  `);
1071
- V = te.pop() ?? "";
1072
- for (const ae of te) {
1073
- const xe = Be(ae);
1074
- xe && await T(xe.event, xe.data);
1151
+ j = re.pop() ?? "";
1152
+ for (const ue of re) {
1153
+ const Re = ze(ue);
1154
+ Re && await N(Re.event, Re.data);
1075
1155
  }
1076
- if (fe) {
1077
- if (V.trim()) {
1078
- const ae = Be(V.trim());
1079
- ae && await T(ae.event, ae.data);
1156
+ if (ne) {
1157
+ if (j.trim()) {
1158
+ const ue = ze(j.trim());
1159
+ ue && await N(ue.event, ue.data);
1080
1160
  }
1081
- X || (k("Ready"), U(!1));
1161
+ X || (b("Ready"), p(!1));
1082
1162
  break;
1083
1163
  }
1084
1164
  }
1085
1165
  };
1086
1166
  } catch (t) {
1087
- console.error("Audio Submission Error:", t), k("STT Failed"), U(!1);
1167
+ console.error("Audio Submission Error:", t), b("STT Failed"), p(!1);
1088
1168
  }
1089
- }, At = async (e) => {
1090
- e && e.preventDefault(), Te.current = "", re(""), !(!E || Q) && await Lt(E);
1091
- }, Be = (e) => {
1169
+ }, Vt = async (e) => {
1170
+ e && e.preventDefault(), Pe(!1), Ce.current = "", F(""), !(!E || oe) && await Ht(E);
1171
+ }, ze = (e) => {
1092
1172
  const t = e.split(/\r?\n/);
1093
- let i = "", a = "";
1094
- for (const l of t)
1095
- l.startsWith("event:") ? i = l.slice(6).trim() : l.startsWith("data:") && (a = l.slice(5).trim());
1096
- if (!i) return null;
1097
- let r = {};
1098
- if (a)
1173
+ let s = "", o = "";
1174
+ for (const a of t)
1175
+ a.startsWith("event:") ? s = a.slice(6).trim() : a.startsWith("data:") && (o = a.slice(5).trim());
1176
+ if (!s) return null;
1177
+ let n = {};
1178
+ if (o)
1099
1179
  try {
1100
- r = JSON.parse(a);
1180
+ n = JSON.parse(o);
1101
1181
  } catch {
1102
- r = { raw: a };
1182
+ n = { raw: o };
1103
1183
  }
1104
- return { event: i, data: r };
1105
- }, ot = (e, t) => {
1184
+ return { event: s, data: n };
1185
+ }, yt = (e, t) => {
1106
1186
  switch (e) {
1107
1187
  case "connected":
1108
- ue.current = "", Ee.current = !1;
1188
+ de.current = "", De.current = !1;
1109
1189
  break;
1110
1190
  case "text": {
1111
- const i = t.delta ?? "";
1112
- i && tt(i);
1191
+ const s = t.delta ?? "";
1192
+ s && gt(s);
1113
1193
  break;
1114
1194
  }
1115
1195
  case "audio": {
1116
- const i = t.chunk, a = t.visemes ?? [];
1117
- i && Xe(i, a);
1196
+ const s = t.chunk, o = t.visemes ?? [];
1197
+ s && it(s, o);
1118
1198
  break;
1119
1199
  }
1120
1200
  case "done": {
1121
- const i = nt(), a = Te.current.trim(), r = [
1122
- ...i,
1201
+ const s = bt(), o = Ce.current.trim(), n = [
1202
+ ...s,
1123
1203
  { role: "user", content: E || "..." },
1124
- { role: "assistant", content: a }
1204
+ { role: "assistant", content: o }
1125
1205
  ];
1126
- _t(r), v.current = [...m.current], k("Ready"), U(!1), L("");
1206
+ Ct(n), Te.current = [...v.current], b("Ready"), p(!1), Z("");
1127
1207
  break;
1128
1208
  }
1129
1209
  case "error": {
1130
- const i = t.message ?? "Unknown error";
1131
- Te.current = i, re(i), k("Agent Failed"), U(!1);
1210
+ const s = t.message ?? "Unknown error";
1211
+ Ce.current = s, F(s), b("Agent Failed"), p(!1);
1132
1212
  break;
1133
1213
  }
1134
1214
  }
1135
- }, Lt = async (e) => {
1136
- U(!0), k("Thinking..."), Te.current = "", ue.current = "", Ee.current = !1, Ve(), q.current = 0, Ue(0);
1137
- const t = `${dt}/agent/chat?token=${encodeURIComponent(
1138
- p
1215
+ }, Ht = async (e) => {
1216
+ p(!0), b("Thinking..."), Ce.current = "", de.current = "", De.current = !1, Ge(), _e.current = 0, u(0);
1217
+ const t = `${ct}/agent/chat?token=${encodeURIComponent(
1218
+ T
1139
1219
  )}`;
1140
1220
  try {
1141
- const i = nt();
1142
- let a = sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");
1143
- a || (Nt(
1221
+ const s = bt();
1222
+ let o = sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");
1223
+ o || (Kt(
1144
1224
  "[CHAT] Session UID missing at send time! Generating emergency backup."
1145
- ), a = "emergency-" + Math.random().toString(36).substring(7), sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", a));
1146
- const r = {
1147
- history: i,
1225
+ ), o = "emergency-" + Math.random().toString(36).substring(7), sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID", o));
1226
+ const n = {
1227
+ history: s,
1148
1228
  question: e,
1149
- lead_id: a
1229
+ lead_id: o
1150
1230
  };
1151
- B("[CHAT] Sending payload:", r);
1152
- const l = await fetch(t, {
1231
+ U("[CHAT] Sending payload:", n);
1232
+ const a = await fetch(t, {
1153
1233
  method: "POST",
1154
1234
  headers: {
1155
1235
  "Content-Type": "application/json"
1156
1236
  },
1157
- body: JSON.stringify(r),
1237
+ body: JSON.stringify(n),
1158
1238
  cache: "default"
1159
1239
  });
1160
- if (!l.ok)
1240
+ if (a.status === 429) {
1241
+ try {
1242
+ const O = await a.json();
1243
+ U("[CHAT] 429 agent at capacity:", O?.detail);
1244
+ } catch {
1245
+ }
1246
+ Z(""), b("Busy"), p(!1);
1247
+ return;
1248
+ }
1249
+ if (!a.ok)
1161
1250
  throw new Error("Agent request failed");
1162
- const _ = l.body;
1163
- if (!_) {
1164
- k("Agent Failed"), U(!1);
1251
+ const m = a.body;
1252
+ if (!m) {
1253
+ b("Agent Failed"), p(!1);
1165
1254
  return;
1166
1255
  }
1167
- const A = _.getReader();
1168
- ee.current = !1;
1169
- const P = new TextDecoder();
1170
- let S = "";
1256
+ const A = m.getReader();
1257
+ Se.current = !1;
1258
+ const S = new TextDecoder();
1259
+ let x = "";
1171
1260
  for (; ; ) {
1172
- const { done: F, value: N } = await A.read();
1173
- B(
1174
- `[SSE] Chunk received. done=${F}, length=${N?.length || 0}`
1175
- ), N && (S += P.decode(N, { stream: !0 }));
1176
- const V = S.split(`
1261
+ const { done: O, value: V } = await A.read();
1262
+ U(
1263
+ `[SSE] Chunk received. done=${O}, length=${V?.length || 0}`
1264
+ ), V && (x += S.decode(V, { stream: !0 }));
1265
+ const j = x.split(`
1177
1266
 
1178
1267
  `);
1179
- S = V.pop() ?? "";
1180
- for (const X of V) {
1181
- B(`[SSE] Processing block: ${X.slice(0, 50)}...`);
1182
- const T = Be(X);
1183
- T && (B(`[SSE] Event: ${T.event}`), ot(T.event, T.data));
1268
+ x = j.pop() ?? "";
1269
+ for (const X of j) {
1270
+ U(`[SSE] Processing block: ${X.slice(0, 50)}...`);
1271
+ const N = ze(X);
1272
+ N && (U(`[SSE] Event: ${N.event}`), yt(N.event, N.data));
1184
1273
  }
1185
- if (F) {
1186
- if (B("[SSE] Stream finished"), S.trim()) {
1187
- const X = Be(S.trim());
1188
- X && ot(X.event, X.data);
1274
+ if (O) {
1275
+ if (U("[SSE] Stream finished"), x.trim()) {
1276
+ const X = ze(x.trim());
1277
+ X && yt(X.event, X.data);
1189
1278
  }
1190
- k("Ready"), U(!1), L("");
1279
+ b("Ready"), p(!1), Z("");
1191
1280
  break;
1192
1281
  }
1193
1282
  }
1194
- } catch (i) {
1195
- console.error("Chat Error:", i), k("Agent Failed"), U(!1);
1283
+ } catch (s) {
1284
+ console.error("Chat Error:", s), b("Agent Failed"), p(!1);
1196
1285
  }
1197
- }, at = he.trim(), Ke = at && M ? at.slice(
1286
+ }, St = ie.trim(), ot = St && Y ? St.slice(
1198
1287
  0,
1199
- Re != null && Re > 0 ? Re : 0
1288
+ d != null && d > 0 ? d : 0
1200
1289
  ) : "";
1201
- z(() => {
1202
- const e = Je.current;
1203
- e !== "exiting" && (Ke ? (Se(Ke), e === "hidden" && ve("entering")) : (e === "visible" || e === "entering") && ve("exiting"));
1204
- }, [Ke, W]);
1205
- const Mt = $e(() => {
1206
- const e = Je.current;
1207
- e === "entering" ? ve("visible") : e === "exiting" && ve("hidden");
1290
+ P(() => {
1291
+ const e = Ke.current;
1292
+ e !== "exiting" && (ot ? (Tt(ot), e === "hidden" && je("entering")) : (e === "visible" || e === "entering") && je("exiting"));
1293
+ }, [ot, Me]);
1294
+ const $t = Ye(() => {
1295
+ const e = Ke.current;
1296
+ e === "entering" ? je("visible") : e === "exiting" && je("hidden");
1208
1297
  }, []);
1209
- return Ot(() => {
1210
- const e = ie.current;
1298
+ return Yt(() => {
1299
+ const e = ft.current;
1211
1300
  e && (e.scrollTop = e.scrollHeight);
1212
- }, [Me]), /* @__PURE__ */ ne("div", { className: "avatar-widget-container", children: [
1213
- /* @__PURE__ */ ne("div", { className: "avatar-input-area", children: [
1214
- ge !== "hidden" ? /* @__PURE__ */ u(
1301
+ }, [ht]), /* @__PURE__ */ se("div", { className: "avatar-widget-container", children: [
1302
+ /* @__PURE__ */ se("div", { className: "avatar-input-area", children: [
1303
+ ee !== "hidden" ? /* @__PURE__ */ l(
1215
1304
  "div",
1216
1305
  {
1217
- className: `avatar-thinking-tab${ge === "exiting" ? " avatar-thinking-tab--exiting" : ge === "entering" ? " avatar-thinking-tab--entering" : ""}`,
1218
- onAnimationEnd: pt,
1219
- children: De
1306
+ className: `avatar-thinking-tab${ee === "exiting" ? " avatar-thinking-tab--exiting" : ee === "entering" ? " avatar-thinking-tab--entering" : ""}`,
1307
+ onAnimationEnd: Et,
1308
+ children: Ae === mt ? /* @__PURE__ */ l(
1309
+ "a",
1310
+ {
1311
+ href: "https://leads.streamoji.com",
1312
+ target: "_blank",
1313
+ rel: "noopener noreferrer",
1314
+ children: "Made by Streamoji Leads"
1315
+ }
1316
+ ) : Ae
1220
1317
  }
1221
1318
  ) : null,
1222
- /* @__PURE__ */ u("div", { className: "avatar-input-container", children: /* @__PURE__ */ u(
1319
+ /* @__PURE__ */ l("div", { className: "avatar-input-container", children: /* @__PURE__ */ l(
1223
1320
  "div",
1224
1321
  {
1225
1322
  style: {
@@ -1228,15 +1325,15 @@ const en = ({
1228
1325
  width: "100%",
1229
1326
  height: "100%"
1230
1327
  },
1231
- children: qe ? /* @__PURE__ */ ne("div", { className: "avatar-input-recording", children: [
1232
- /* @__PURE__ */ u(
1328
+ children: tt ? /* @__PURE__ */ se("div", { className: "avatar-input-recording", children: [
1329
+ /* @__PURE__ */ l(
1233
1330
  "button",
1234
1331
  {
1235
1332
  type: "button",
1236
1333
  className: "avatar-recording-cancel",
1237
- onClick: xt,
1334
+ onClick: Bt,
1238
1335
  title: "Cancel",
1239
- children: /* @__PURE__ */ ne(
1336
+ children: /* @__PURE__ */ se(
1240
1337
  "svg",
1241
1338
  {
1242
1339
  width: "18",
@@ -1249,14 +1346,14 @@ const en = ({
1249
1346
  strokeLinejoin: "round",
1250
1347
  style: { display: "block" },
1251
1348
  children: [
1252
- /* @__PURE__ */ u("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1253
- /* @__PURE__ */ u("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1349
+ /* @__PURE__ */ l("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1350
+ /* @__PURE__ */ l("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1254
1351
  ]
1255
1352
  }
1256
1353
  )
1257
1354
  }
1258
1355
  ),
1259
- /* @__PURE__ */ ne(
1356
+ /* @__PURE__ */ se(
1260
1357
  "div",
1261
1358
  {
1262
1359
  style: {
@@ -1268,8 +1365,8 @@ const en = ({
1268
1365
  minWidth: 0
1269
1366
  },
1270
1367
  children: [
1271
- /* @__PURE__ */ u("div", { style: { flex: 1, height: "100%" }, children: /* @__PURE__ */ u(ut, { analyser: vt }) }),
1272
- /* @__PURE__ */ ne(
1368
+ /* @__PURE__ */ l("div", { style: { flex: 1, height: "100%" }, children: /* @__PURE__ */ l(At, { analyser: Nt }) }),
1369
+ /* @__PURE__ */ se(
1273
1370
  "span",
1274
1371
  {
1275
1372
  style: {
@@ -1282,23 +1379,23 @@ const en = ({
1282
1379
  fontVariantNumeric: "tabular-nums"
1283
1380
  },
1284
1381
  children: [
1285
- Math.floor(rt / 60),
1382
+ Math.floor(_t / 60),
1286
1383
  ":",
1287
- String(rt % 60).padStart(2, "0")
1384
+ String(_t % 60).padStart(2, "0")
1288
1385
  ]
1289
1386
  }
1290
1387
  )
1291
1388
  ]
1292
1389
  }
1293
1390
  ),
1294
- /* @__PURE__ */ u(
1391
+ /* @__PURE__ */ l(
1295
1392
  "button",
1296
1393
  {
1297
1394
  type: "button",
1298
1395
  className: "avatar-recording-confirm",
1299
- onClick: yt,
1396
+ onClick: Ut,
1300
1397
  title: "Send",
1301
- children: /* @__PURE__ */ u(
1398
+ children: /* @__PURE__ */ l(
1302
1399
  "svg",
1303
1400
  {
1304
1401
  width: "18",
@@ -1310,13 +1407,13 @@ const en = ({
1310
1407
  strokeLinecap: "round",
1311
1408
  strokeLinejoin: "round",
1312
1409
  style: { display: "block" },
1313
- children: /* @__PURE__ */ u("polyline", { points: "20 6 9 17 4 12" })
1410
+ children: /* @__PURE__ */ l("polyline", { points: "20 6 9 17 4 12" })
1314
1411
  }
1315
1412
  )
1316
1413
  }
1317
1414
  )
1318
- ] }) : M ? /* @__PURE__ */ ne("div", { className: "avatar-input-speaking", children: [
1319
- /* @__PURE__ */ u(
1415
+ ] }) : Y && !et ? /* @__PURE__ */ se("div", { className: "avatar-input-speaking", children: [
1416
+ /* @__PURE__ */ l(
1320
1417
  "div",
1321
1418
  {
1322
1419
  style: {
@@ -1326,20 +1423,20 @@ const en = ({
1326
1423
  alignItems: "center",
1327
1424
  paddingRight: "8px"
1328
1425
  },
1329
- children: /* @__PURE__ */ u(ut, { analyser: it })
1426
+ children: /* @__PURE__ */ l(At, { analyser: vt })
1330
1427
  }
1331
1428
  ),
1332
- /* @__PURE__ */ u(
1429
+ /* @__PURE__ */ l(
1333
1430
  "button",
1334
1431
  {
1335
1432
  type: "button",
1336
1433
  className: "avatar-speaking-stop",
1337
- onClick: () => Ve(!0),
1434
+ onClick: () => Ge(!0),
1338
1435
  title: "Stop",
1339
- children: /* @__PURE__ */ u("span", { className: "avatar-speaking-stop__icon", "aria-hidden": !0 })
1436
+ children: /* @__PURE__ */ l("span", { className: "avatar-speaking-stop__icon", "aria-hidden": !0 })
1340
1437
  }
1341
1438
  )
1342
- ] }) : Q ? /* @__PURE__ */ u(
1439
+ ] }) : oe ? /* @__PURE__ */ l(
1343
1440
  "div",
1344
1441
  {
1345
1442
  style: {
@@ -1349,12 +1446,12 @@ const en = ({
1349
1446
  alignItems: "center",
1350
1447
  justifyContent: "center"
1351
1448
  },
1352
- children: /* @__PURE__ */ u("div", { className: "avatar-input-loader" })
1449
+ children: /* @__PURE__ */ l("div", { className: "avatar-input-loader" })
1353
1450
  }
1354
- ) : /* @__PURE__ */ ne(
1451
+ ) : /* @__PURE__ */ se(
1355
1452
  "form",
1356
1453
  {
1357
- onSubmit: At,
1454
+ onSubmit: Vt,
1358
1455
  style: {
1359
1456
  flex: 1,
1360
1457
  display: "flex",
@@ -1362,28 +1459,55 @@ const en = ({
1362
1459
  alignItems: "center"
1363
1460
  },
1364
1461
  children: [
1365
- /* @__PURE__ */ u(
1462
+ /* @__PURE__ */ l(
1366
1463
  "input",
1367
1464
  {
1368
1465
  id: "avatar-text-input",
1369
1466
  type: "text",
1370
1467
  value: E,
1371
- onChange: (e) => L(e.target.value),
1372
- placeholder: "Ask me anything",
1373
- disabled: Q,
1468
+ onChange: (e) => Z(e.target.value),
1469
+ placeholder: H === "Busy" ? "Assisting another user" : Ve || "Ask me anything",
1470
+ disabled: oe || H === "Busy",
1374
1471
  autoComplete: "off",
1375
1472
  style: { width: "100%", height: "100%" }
1376
1473
  }
1377
1474
  ),
1378
- E.trim() === "" ? /* @__PURE__ */ u(
1475
+ H === "Busy" ? /* @__PURE__ */ l(
1476
+ "button",
1477
+ {
1478
+ type: "button",
1479
+ className: "mic-button",
1480
+ disabled: !0,
1481
+ style: { backgroundColor: "#1e4a5e" },
1482
+ title: "Agent at capacity",
1483
+ children: /* @__PURE__ */ l(
1484
+ "svg",
1485
+ {
1486
+ width: "24",
1487
+ height: "24",
1488
+ viewBox: "0 0 24 24",
1489
+ fill: "none",
1490
+ xmlns: "http://www.w3.org/2000/svg",
1491
+ "aria-hidden": "true",
1492
+ children: /* @__PURE__ */ l(
1493
+ "path",
1494
+ {
1495
+ d: "M4 2L20 2L12 10L4 2z M12 14L4 22L20 22L12 14z",
1496
+ fill: "white"
1497
+ }
1498
+ )
1499
+ }
1500
+ )
1501
+ }
1502
+ ) : E.trim() === "" ? /* @__PURE__ */ l(
1379
1503
  "button",
1380
1504
  {
1381
1505
  type: "button",
1382
1506
  className: "mic-button",
1383
- onClick: St,
1384
- disabled: Q,
1507
+ onClick: Ft,
1508
+ disabled: oe,
1385
1509
  style: { backgroundColor: "#1e4a5e" },
1386
- children: /* @__PURE__ */ ne(
1510
+ children: /* @__PURE__ */ se(
1387
1511
  "svg",
1388
1512
  {
1389
1513
  width: "28",
@@ -1392,14 +1516,14 @@ const en = ({
1392
1516
  fill: "none",
1393
1517
  xmlns: "http://www.w3.org/2000/svg",
1394
1518
  children: [
1395
- /* @__PURE__ */ u(
1519
+ /* @__PURE__ */ l(
1396
1520
  "path",
1397
1521
  {
1398
1522
  d: "M12 14C13.66 14 15 12.66 15 11V5C15 3.34 13.66 2 12 2C10.34 2 9 3.34 9 5V11C9 12.66 10.34 14 12 14Z",
1399
1523
  fill: "white"
1400
1524
  }
1401
1525
  ),
1402
- /* @__PURE__ */ u(
1526
+ /* @__PURE__ */ l(
1403
1527
  "path",
1404
1528
  {
1405
1529
  d: "M17 11C17 13.76 14.76 16 12 16C9.24 16 7 13.76 7 11H5C5 14.53 7.61 17.43 11 17.93V21H13V17.93C16.39 17.43 19 14.53 19 11H17Z",
@@ -1410,15 +1534,15 @@ const en = ({
1410
1534
  }
1411
1535
  )
1412
1536
  }
1413
- ) : /* @__PURE__ */ u(
1537
+ ) : /* @__PURE__ */ l(
1414
1538
  "button",
1415
1539
  {
1416
1540
  type: "submit",
1417
1541
  className: "mic-button",
1418
- disabled: Q,
1542
+ disabled: oe,
1419
1543
  style: { backgroundColor: "#1e4a5e" },
1420
1544
  title: "Send",
1421
- children: /* @__PURE__ */ u(
1545
+ children: /* @__PURE__ */ l(
1422
1546
  "svg",
1423
1547
  {
1424
1548
  width: 24,
@@ -1426,7 +1550,7 @@ const en = ({
1426
1550
  viewBox: "0 0 24 24",
1427
1551
  fill: "none",
1428
1552
  "aria-hidden": "true",
1429
- children: /* @__PURE__ */ u(
1553
+ children: /* @__PURE__ */ l(
1430
1554
  "path",
1431
1555
  {
1432
1556
  d: "M19 12H5M19 12L14 17M19 12L14 7",
@@ -1446,22 +1570,22 @@ const en = ({
1446
1570
  }
1447
1571
  ) })
1448
1572
  ] }),
1449
- /* @__PURE__ */ u("div", { className: "avatar-wrapper", children: /* @__PURE__ */ ne("div", { className: "avatar-scene-wrapper", children: [
1450
- W !== "hidden" && /* @__PURE__ */ u(
1573
+ /* @__PURE__ */ l("div", { className: "avatar-wrapper", children: /* @__PURE__ */ se("div", { className: "avatar-scene-wrapper", children: [
1574
+ Me !== "hidden" && /* @__PURE__ */ l(
1451
1575
  "div",
1452
1576
  {
1453
- className: `avatar-bubble${W === "entering" ? " avatar-bubble--entering" : W === "exiting" ? " avatar-bubble--exiting" : ""}`,
1454
- onAnimationEnd: Mt,
1455
- children: /* @__PURE__ */ u("div", { ref: ie, className: "avatar-bubble__content", children: Me })
1577
+ className: `avatar-bubble${Me === "entering" ? " avatar-bubble--entering" : Me === "exiting" ? " avatar-bubble--exiting" : ""}`,
1578
+ onAnimationEnd: $t,
1579
+ children: /* @__PURE__ */ l("div", { ref: ft, className: `avatar-bubble__content${et ? " avatar-bubble__content--nudge" : ""}`, children: ht })
1456
1580
  }
1457
1581
  ),
1458
- /* @__PURE__ */ u(
1582
+ /* @__PURE__ */ l(
1459
1583
  "div",
1460
1584
  {
1461
1585
  className: "avatar-canvas-layer",
1462
- style: { width: Z, height: Z },
1463
- children: /* @__PURE__ */ ne(
1464
- It,
1586
+ style: { width: C, height: C },
1587
+ children: /* @__PURE__ */ se(
1588
+ qt,
1465
1589
  {
1466
1590
  shadows: !0,
1467
1591
  camera: { position: [0.2, 1.4, 3], fov: 42 },
@@ -1469,28 +1593,30 @@ const en = ({
1469
1593
  dpr: 1.8,
1470
1594
  style: { pointerEvents: "none", width: "100%", height: "100%" },
1471
1595
  children: [
1472
- /* @__PURE__ */ u(Kt, { target: Jt }),
1473
- /* @__PURE__ */ u("ambientLight", { intensity: 0.7 }),
1474
- /* @__PURE__ */ u("directionalLight", { position: [0, 2, 2], intensity: 1 }),
1475
- /* @__PURE__ */ u(Et, { preset: "city" }),
1476
- /* @__PURE__ */ u(Ft, { fallback: null, children: D !== null && /* @__PURE__ */ u(
1477
- Qt,
1596
+ /* @__PURE__ */ l(pn, { target: cn }),
1597
+ /* @__PURE__ */ l("ambientLight", { intensity: 0.7 }),
1598
+ /* @__PURE__ */ l("directionalLight", { position: [0, 2, 2], intensity: 1 }),
1599
+ /* @__PURE__ */ l(jt, { preset: "city" }),
1600
+ /* @__PURE__ */ l(Qt, { fallback: null, children: W !== null && /* @__PURE__ */ l(
1601
+ mn,
1478
1602
  {
1479
- avatarUrl: D,
1480
- isPlayingRef: I,
1481
- visemeQueueRef: m,
1482
- audioContextRef: $,
1483
- responseAudioStartTimeRef: b,
1484
- adjustments: jt,
1485
- mood: f,
1486
- expression: s,
1487
- agentResponse: he,
1488
- isSpeaking: M,
1489
- nextStartTimeRef: K,
1490
- stopPlayback: Ve,
1491
- setIsSpeaking: ce,
1492
- expressionUrl: h,
1493
- onExpressionFinished: bt
1603
+ avatarUrl: W,
1604
+ isPlayingRef: R,
1605
+ visemeQueueRef: v,
1606
+ audioContextRef: y,
1607
+ responseAudioStartTimeRef: be,
1608
+ adjustments: an,
1609
+ mood: r,
1610
+ expression: G,
1611
+ agentResponse: ie,
1612
+ isSpeaking: Y,
1613
+ nextStartTimeRef: ae,
1614
+ stopPlayback: Ge,
1615
+ setIsSpeaking: $,
1616
+ expressionUrl: Xe,
1617
+ onExpressionFinished: Dt,
1618
+ isNudgeResponse: et,
1619
+ avatarGender: g
1494
1620
  }
1495
1621
  ) })
1496
1622
  ]
@@ -1500,17 +1626,17 @@ const en = ({
1500
1626
  )
1501
1627
  ] }) })
1502
1628
  ] });
1503
- }, an = ({
1504
- token: d,
1505
- onNavigationRequested: x
1506
- }) => /* @__PURE__ */ u(
1507
- en,
1629
+ }, xn = ({
1630
+ token: f,
1631
+ onNavigationRequested: L
1632
+ }) => /* @__PURE__ */ l(
1633
+ bn,
1508
1634
  {
1509
- token: d,
1510
- onNavigationRequested: x
1635
+ token: f,
1636
+ onNavigationRequested: L
1511
1637
  }
1512
1638
  );
1513
1639
  export {
1514
- an as AvatarWidget
1640
+ xn as AvatarWidget
1515
1641
  };
1516
1642
  //# sourceMappingURL=avatar-widget.js.map