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