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