@sage-rsc/talking-head-react 1.0.50 → 1.0.52
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/index.cjs +2 -2
- package/dist/index.js +801 -799
- package/package.json +1 -1
- package/src/components/CurriculumLearning.jsx +46 -9
- package/src/components/TalkingHeadAvatar.jsx +43 -92
- package/src/lib/talkinghead.mjs +4 -4
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
1
|
+
import { jsxs as ke, jsx as se } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as ye, useRef as Z, useState as he, useEffect as ue, useCallback as E, useImperativeHandle as fe, useLayoutEffect as Ee } from "react";
|
|
3
3
|
import * as f from "three";
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
6
|
-
import { DRACOLoader as
|
|
7
|
-
import { FBXLoader as
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let m,
|
|
11
|
-
const A = [0, 0, 0, 0], k = new f.Vector3(),
|
|
4
|
+
import { OrbitControls as Fe } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as Pe } from "three/addons/loaders/GLTFLoader.js";
|
|
6
|
+
import { DRACOLoader as Be } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
+
import { FBXLoader as ve } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
+
import { RoomEnvironment as De } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import Oe from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, Q, K;
|
|
11
|
+
const A = [0, 0, 0, 0], k = new f.Vector3(), ce = new f.Vector3(), X = new f.Vector3(), me = new f.Vector3();
|
|
12
12
|
new f.Plane();
|
|
13
13
|
new f.Ray();
|
|
14
14
|
new f.Euler();
|
|
15
|
-
const Y = new f.Quaternion(),
|
|
15
|
+
const Y = new f.Quaternion(), Ie = new f.Quaternion(), ee = new f.Matrix4(), te = new f.Matrix4();
|
|
16
16
|
new f.Vector3();
|
|
17
|
-
const
|
|
18
|
-
class
|
|
17
|
+
const pe = new f.Vector3(0, 0, 1), Ne = new f.Vector3(1, 0, 0), Ue = new f.Vector3(0, 1, 0), We = new f.Vector3(0, 0, 1);
|
|
18
|
+
class Ve {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -192,7 +192,7 @@ class Xe {
|
|
|
192
192
|
const r = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!r) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const u = {
|
|
196
196
|
bone: r,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class Xe {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((a) => Number.isNaN(a))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
|
|
206
|
-
|
|
206
|
+
u.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
n.excludes.push(
|
|
208
|
+
n.excludes.push(u);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class Xe {
|
|
|
282
282
|
m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const i = /* @__PURE__ */ new WeakSet(), n = (o) => o.parent?.isBone ? [o, ...n(o.parent)] : [o], s = (o) => {
|
|
285
|
-
n(o).forEach((
|
|
286
|
-
i.has(
|
|
285
|
+
n(o).forEach((u) => {
|
|
286
|
+
i.has(u) || (this.objectsUpdate.push(u), i.add(u));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((o) => {
|
|
@@ -308,12 +308,12 @@ class Xe {
|
|
|
308
308
|
n(t?.isScene, "First parameter must be Scene."), this.scene = t, n(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, n(Array.isArray(i), "Third parameter must be an array of bone configs."), this.config = i, this.config.forEach((s, o) => {
|
|
309
309
|
const r = "Config item #" + o + ": ";
|
|
310
310
|
n(s.bone, r + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
n(typeof
|
|
313
|
-
const a = this.armature.getObjectByName(
|
|
314
|
-
n(a, r + "Bone '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const u = s.bone;
|
|
312
|
+
n(typeof u == "string" && u.length > 0, r + "Bone name must be a non-empty string.");
|
|
313
|
+
const a = this.armature.getObjectByName(u);
|
|
314
|
+
n(a, r + "Bone '" + u + "' not found."), n(a.parent?.isBone, r + "Bone must have a parent bone."), n(this.data.every((l) => l.bone !== a), r + "Bone '" + u + "' already exists."), a.updateMatrixWorld(!0);
|
|
315
|
+
const h = {
|
|
316
|
+
name: u,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: a,
|
|
319
319
|
// Bone object
|
|
@@ -338,9 +338,9 @@ class Xe {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
h.boneParent.matrixWorld.decompose(k, Y, X), k.copy(pe).applyQuaternion(Y).setY(0).normalize(), Y.premultiply(Ie.setFromUnitVectors(pe, k).invert()).normalize(), h.qWorldInverseYaw = Y.clone().normalize(), this.data.push(h), this.dict[u] = h;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
|
|
344
344
|
} catch (l) {
|
|
345
345
|
n(!1, r + l);
|
|
346
346
|
}
|
|
@@ -369,9 +369,9 @@ class Xe {
|
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, Y, X), k.copy(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, Y, X), k.copy(pe).applyQuaternion(Y).setY(0).normalize(), Y.premultiply(Ie.setFromUnitVectors(pe, k).invert()).normalize(), o.boneParent.quaternion.multiply(Y.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), Y.setFromAxisAngle(We, -m), o.boneParent.quaternion.multiply(Y)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), Y.setFromAxisAngle(Ne, -m), o.boneParent.quaternion.multiply(Y)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), Y.setFromAxisAngle(Ue, -m), o.boneParent.quaternion.multiply(Y)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (i = 0, s = o.excludes.length; i < s; i++)
|
|
374
|
-
m = o.excludes[i], X.set(0, 0, 0), m.deltaLocal && (X.x += m.deltaLocal[0], X.y += m.deltaLocal[1], X.z += m.deltaLocal[2]), X.applyMatrix4(m.bone.matrixWorld), te.copy(o.boneParent.matrixWorld).invert(), X.applyMatrix4(te), k.copy(o.bone.position), !(k.distanceToSquared(X) >= m.radiusSq) && (K = k.length(),
|
|
374
|
+
m = o.excludes[i], X.set(0, 0, 0), m.deltaLocal && (X.x += m.deltaLocal[0], X.y += m.deltaLocal[1], X.z += m.deltaLocal[2]), X.applyMatrix4(m.bone.matrixWorld), te.copy(o.boneParent.matrixWorld).invert(), X.applyMatrix4(te), k.copy(o.bone.position), !(k.distanceToSquared(X) >= m.radiusSq) && (K = k.length(), Q = X.length(), !(Q > m.radius + K) && (Q < Math.abs(m.radius - K) || (Q = (Q * Q + K * K - m.radiusSq) / (2 * Q), X.normalize(), me.copy(X).multiplyScalar(Q), Q = Math.sqrt(K * K - Q * Q), k.subVectors(k, me).projectOnPlane(X).normalize().multiplyScalar(Q), ce.subVectors(o.vBasis, me).projectOnPlane(X).normalize(), K = ce.dot(k), K < 0 && (K = Math.sqrt(Q * Q - K * K), ce.multiplyScalar(K), k.add(ce)), k.add(me).normalize(), X.copy(o.bone.position).normalize(), Y.setFromUnitVectors(X, k), o.boneParent.quaternion.premultiply(Y), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -408,9 +408,9 @@ class Xe {
|
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new f.BufferGeometry(), i = m.bones.map((
|
|
411
|
+
const e = new f.BufferGeometry(), i = m.bones.map((u) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new f.Float32BufferAttribute(i, 3));
|
|
413
|
-
const n = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((
|
|
413
|
+
const n = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [n.r, n.g, n.b]).flat();
|
|
414
414
|
e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
|
|
415
415
|
const r = new f.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class Xe {
|
|
|
423
423
|
m.object = new f.Points(e, r), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new f.BufferGeometry(), i = m.bones.map((
|
|
426
|
+
const e = new f.BufferGeometry(), i = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new f.Float32BufferAttribute(i, 3));
|
|
428
|
-
const n = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((
|
|
428
|
+
const n = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [n.r, n.g, n.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
|
|
430
430
|
const r = new f.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -489,7 +489,7 @@ class Xe {
|
|
|
489
489
|
this.stop(), this.scene = null, this.armature = null, this.config = [], this.data = [], this.dict = {}, this.objectsUpdate = [], this.timerMs = 0;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
class
|
|
492
|
+
class Ge {
|
|
493
493
|
constructor(t) {
|
|
494
494
|
this.audioContext = t, this.analyzer = null, this.dataArray = null, this.bufferLength = 0;
|
|
495
495
|
}
|
|
@@ -519,13 +519,13 @@ class Ye {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, n = 1024, s = 512, o = Math.floor((t.length - n) / s) + 1;
|
|
521
521
|
for (let r = 0; r < o; r++) {
|
|
522
|
-
const
|
|
522
|
+
const u = r * s, a = Math.min(u + n, t.length), h = t.slice(u, a), l = this.calculateEnergy(h);
|
|
523
523
|
i.energy.push(l);
|
|
524
|
-
const c = this.calculateSpectralCentroid(
|
|
524
|
+
const c = this.calculateSpectralCentroid(h);
|
|
525
525
|
i.spectralCentroid.push(c);
|
|
526
|
-
const d = this.calculateZeroCrossingRate(
|
|
526
|
+
const d = this.calculateZeroCrossingRate(h);
|
|
527
527
|
i.zeroCrossingRate.push(d);
|
|
528
|
-
const g = this.calculateMFCC(
|
|
528
|
+
const g = this.calculateMFCC(h);
|
|
529
529
|
i.mfcc.push(g);
|
|
530
530
|
}
|
|
531
531
|
return i.onsets = this.detectOnsets(i.energy), i.phonemeBoundaries = this.detectPhonemeBoundaries(i), i;
|
|
@@ -597,19 +597,19 @@ class Ye {
|
|
|
597
597
|
for (; s & o; )
|
|
598
598
|
s ^= o, o >>= 1;
|
|
599
599
|
if (s ^= o, n < s) {
|
|
600
|
-
const r = i[n * 2],
|
|
601
|
-
i[n * 2] = i[s * 2], i[n * 2 + 1] = i[s * 2 + 1], i[s * 2] = r, i[s * 2 + 1] =
|
|
600
|
+
const r = i[n * 2], u = i[n * 2 + 1];
|
|
601
|
+
i[n * 2] = i[s * 2], i[n * 2 + 1] = i[s * 2 + 1], i[s * 2] = r, i[s * 2 + 1] = u;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let n = 2; n <= e; n <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / n, o = Math.cos(s), r = Math.sin(s);
|
|
606
|
-
for (let
|
|
607
|
-
let a = 1,
|
|
606
|
+
for (let u = 0; u < e; u += n) {
|
|
607
|
+
let a = 1, h = 0;
|
|
608
608
|
for (let l = 0; l < n / 2; l++) {
|
|
609
|
-
const c = i[(
|
|
610
|
-
i[(
|
|
611
|
-
const x = a * o -
|
|
612
|
-
a = x,
|
|
609
|
+
const c = i[(u + l) * 2], d = i[(u + l) * 2 + 1], g = i[(u + l + n / 2) * 2] * a - i[(u + l + n / 2) * 2 + 1] * h, y = i[(u + l + n / 2) * 2] * h + i[(u + l + n / 2) * 2 + 1] * a;
|
|
610
|
+
i[(u + l) * 2] = c + g, i[(u + l) * 2 + 1] = d + y, i[(u + l + n / 2) * 2] = c - g, i[(u + l + n / 2) * 2 + 1] = d - y;
|
|
611
|
+
const x = a * o - h * r, I = a * r + h * o;
|
|
612
|
+
a = x, h = I;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class Ye {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let o = 1; o < t.length; o++) {
|
|
627
|
-
const r = t[o] - t[o - 1],
|
|
628
|
-
r > 0.1 &&
|
|
627
|
+
const r = t[o] - t[o - 1], u = o * 0.023;
|
|
628
|
+
r > 0.1 && u - s > 0.1 && (e.push(u), s = u);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class Ye {
|
|
|
637
637
|
detectPhonemeBoundaries(t) {
|
|
638
638
|
const e = [], { energy: i, spectralCentroid: n, zeroCrossingRate: s } = t;
|
|
639
639
|
for (let o = 1; o < i.length; o++) {
|
|
640
|
-
const r = o * 0.023,
|
|
641
|
-
|
|
640
|
+
const r = o * 0.023, u = Math.abs(i[o] - i[o - 1]), a = Math.abs(n[o] - n[o - 1]), h = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
u + a * 0.1 + h * 0.5 > 0.2 && e.push(r);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ class Ye {
|
|
|
654
654
|
t.phonemeBoundaries, t.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let o = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const a = n[
|
|
657
|
+
for (let u = 0; u < n.length; u++) {
|
|
658
|
+
const a = n[u], h = this.estimateWordDuration(a, i / n.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: a,
|
|
661
661
|
startTime: o,
|
|
662
|
-
endTime: o +
|
|
663
|
-
duration:
|
|
664
|
-
}), o +=
|
|
662
|
+
endTime: o + h,
|
|
663
|
+
duration: h
|
|
664
|
+
}), o += h;
|
|
665
665
|
}
|
|
666
666
|
const r = this.generateVisemeTimings(t, e, i);
|
|
667
667
|
return {
|
|
@@ -701,27 +701,27 @@ class Ye {
|
|
|
701
701
|
const n = [], s = t.phonemeBoundaries;
|
|
702
702
|
t.onsets;
|
|
703
703
|
const o = this.textToVisemes(e);
|
|
704
|
-
let r = 0,
|
|
704
|
+
let r = 0, u = 0;
|
|
705
705
|
for (let a = 0; a < s.length && r < o.length; a++) {
|
|
706
|
-
const
|
|
706
|
+
const h = s[a], l = o[r], c = t.energy[Math.floor(h / 0.023)] || 0, d = this.calculateVisemeDuration(l, c);
|
|
707
707
|
n.push({
|
|
708
708
|
viseme: l,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
709
|
+
startTime: u,
|
|
710
|
+
endTime: u + d,
|
|
711
711
|
duration: d,
|
|
712
712
|
intensity: Math.min(1, c * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), u += d, r++;
|
|
715
715
|
}
|
|
716
716
|
for (; r < o.length; ) {
|
|
717
|
-
const a = o[r],
|
|
717
|
+
const a = o[r], h = this.calculateVisemeDuration(a, 0.5);
|
|
718
718
|
n.push({
|
|
719
719
|
viseme: a,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: u,
|
|
721
|
+
endTime: u + h,
|
|
722
|
+
duration: h,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), u += h, r++;
|
|
725
725
|
}
|
|
726
726
|
return n;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class Ye {
|
|
|
775
775
|
let o = 0;
|
|
776
776
|
for (; o < s.length; ) {
|
|
777
777
|
let r = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const a = s.substr(o,
|
|
778
|
+
for (let u = 3; u >= 2; u--) {
|
|
779
|
+
const a = s.substr(o, u);
|
|
780
780
|
if (e[a]) {
|
|
781
|
-
i.push(e[a]), o +=
|
|
781
|
+
i.push(e[a]), o += u, r = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!r) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const u = s[o];
|
|
787
|
+
e[u] && i.push(e[u]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -814,7 +814,7 @@ class Ye {
|
|
|
814
814
|
return n * s;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
class
|
|
817
|
+
class Ze {
|
|
818
818
|
/**
|
|
819
819
|
* @constructor
|
|
820
820
|
*/
|
|
@@ -1206,11 +1206,11 @@ class je {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((i) => {
|
|
1209
|
-
const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), r = i.substring(0, n),
|
|
1209
|
+
const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), r = i.substring(0, n), u = i.substring(n + 1, s), a = i.substring(s + 1, o), h = i.substring(o + 1), l = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let c = "";
|
|
1211
1211
|
c += [...r].map((g) => t[g] || g).join("");
|
|
1212
|
-
const d = [...
|
|
1213
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), l.move = d.length, c += [...a].map((g) => t[g] || g).join(""), l.regex = new RegExp(c),
|
|
1212
|
+
const d = [...u];
|
|
1213
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), l.move = d.length, c += [...a].map((g) => t[g] || g).join(""), l.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
|
|
1214
1214
|
l.visemes.push(g);
|
|
1215
1215
|
}), l;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class je {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(t) {
|
|
1326
1326
|
const e = parseInt(t), i = !isNaN(e) && t.length === 2, n = !isNaN(e) && t.length > 2 && e > 0 && e <= 3e3, s = n && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, o = n && !s ? Math.floor(e / 100) : null, r = i || n ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let u = [];
|
|
1328
|
+
return s ? u.push(this.convertNumberToWords(s).trim(), "thousands") : (o && u.push(this.convertNumberToWords(o).trim()), r ? u.push(this.decades[r] || this.convertNumberToWords(r).trim() + "s") : o ? u.push("hundreds") : u.push(t)), u.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class je {
|
|
|
1376
1376
|
const s = n[e.i], o = this.rules[s];
|
|
1377
1377
|
if (o)
|
|
1378
1378
|
for (let r = 0; r < o.length; r++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const u = o[r];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
|
|
1381
|
+
u.visemes.forEach((l) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
|
|
1383
1383
|
const c = 0.7 * (this.visemeDurations[l] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += c, i += c;
|
|
@@ -1386,7 +1386,7 @@ class je {
|
|
|
1386
1386
|
const c = this.visemeDurations[l] || 1;
|
|
1387
1387
|
e.visemes.push(l), e.times.push(i), e.durations.push(c), i += c;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += u.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1396,11 +1396,11 @@ class je {
|
|
|
1396
1396
|
return e;
|
|
1397
1397
|
}
|
|
1398
1398
|
}
|
|
1399
|
-
const
|
|
1399
|
+
const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1400
1400
|
__proto__: null,
|
|
1401
|
-
LipsyncEn:
|
|
1401
|
+
LipsyncEn: Ze
|
|
1402
1402
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1403
|
-
class
|
|
1403
|
+
class Ye {
|
|
1404
1404
|
/**
|
|
1405
1405
|
* @constructor
|
|
1406
1406
|
*/
|
|
@@ -1616,11 +1616,11 @@ class qe {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((i) => {
|
|
1619
|
-
const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), r = i.substring(0, n),
|
|
1619
|
+
const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), r = i.substring(0, n), u = i.substring(n + 1, s), a = i.substring(s + 1, o), h = i.substring(o + 1), l = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let c = "";
|
|
1621
1621
|
c += [...r].map((g) => t[g] || g).join("");
|
|
1622
|
-
const d = [...
|
|
1623
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), l.move = d.length, c += [...a].map((g) => t[g] || g).join(""), l.regex = new RegExp(c),
|
|
1622
|
+
const d = [...u];
|
|
1623
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), l.move = d.length, c += [...a].map((g) => t[g] || g).join(""), l.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
|
|
1624
1624
|
l.visemes.push(g);
|
|
1625
1625
|
}), l;
|
|
1626
1626
|
});
|
|
@@ -1732,8 +1732,8 @@ class qe {
|
|
|
1732
1732
|
const s = n[e.i], o = this.rules[s];
|
|
1733
1733
|
if (o) {
|
|
1734
1734
|
let r = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const a = o[
|
|
1735
|
+
for (let u = 0; u < o.length; u++) {
|
|
1736
|
+
const a = o[u];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
|
|
1738
1738
|
a.visemes.forEach((c) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
|
|
@@ -1754,11 +1754,11 @@ class qe {
|
|
|
1754
1754
|
return e;
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
1757
|
-
const
|
|
1757
|
+
const je = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1758
1758
|
__proto__: null,
|
|
1759
|
-
LipsyncDe:
|
|
1759
|
+
LipsyncDe: Ye
|
|
1760
1760
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1761
|
-
class
|
|
1761
|
+
class Qe {
|
|
1762
1762
|
/**
|
|
1763
1763
|
* @constructor
|
|
1764
1764
|
*/
|
|
@@ -2131,11 +2131,11 @@ class Ke {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((i) => {
|
|
2134
|
-
const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), r = i.substring(0, n),
|
|
2134
|
+
const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), r = i.substring(0, n), u = i.substring(n + 1, s), a = i.substring(s + 1, o), h = i.substring(o + 1), l = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let c = "";
|
|
2136
2136
|
c += [...r].map((g) => t[g] || g).join("");
|
|
2137
|
-
const d = [...
|
|
2138
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), l.move = d.length, c += [...a].map((g) => t[g] || g).join(""), l.regex = new RegExp(c, "i"),
|
|
2137
|
+
const d = [...u];
|
|
2138
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), l.move = d.length, c += [...a].map((g) => t[g] || g).join(""), l.regex = new RegExp(c, "i"), h.length && h.split(" ").forEach((g) => {
|
|
2139
2139
|
g && l.visemes.push(g);
|
|
2140
2140
|
}), l;
|
|
2141
2141
|
});
|
|
@@ -2267,8 +2267,8 @@ class Ke {
|
|
|
2267
2267
|
const s = n[e.i], o = this.rules[s];
|
|
2268
2268
|
if (o) {
|
|
2269
2269
|
let r = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const a = o[
|
|
2270
|
+
for (let u = 0; u < o.length; u++) {
|
|
2271
|
+
const a = o[u];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
|
|
2273
2273
|
a.visemes.forEach((c) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
|
|
@@ -2289,11 +2289,11 @@ class Ke {
|
|
|
2289
2289
|
return e;
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
|
-
const
|
|
2292
|
+
const qe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2293
2293
|
__proto__: null,
|
|
2294
|
-
LipsyncFr:
|
|
2294
|
+
LipsyncFr: Qe
|
|
2295
2295
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2296
|
-
class
|
|
2296
|
+
class _e {
|
|
2297
2297
|
/**
|
|
2298
2298
|
* @constructor
|
|
2299
2299
|
*/
|
|
@@ -2381,10 +2381,10 @@ class $e {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let i = parseFloat(t);
|
|
2383
2383
|
if (i === void 0) return t;
|
|
2384
|
-
let n = (s, o, r,
|
|
2384
|
+
let n = (s, o, r, u, a) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(r + (
|
|
2386
|
+
const h = Math.floor(s / o);
|
|
2387
|
+
return e.push(r + (h === 1 ? u : this.numberToFinnishWords(h.toString()) + a)), s - h * o;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (i < 0 && (e.push("miinus "), i = Math.abs(i)), i = n(i, 1e9, " ", "miljardi", " miljardia"), i = n(i, 1e6, " ", "miljoona", " miljoonaa"), i = n(i, 1e3, "", "tuhat", "tuhatta"), i = n(i, 100, " ", "sata", "sataa"), i > 20 && (i = n(i, 10, "", "", "kymmentä")), i >= 1) {
|
|
2390
2390
|
let s = Math.floor(i);
|
|
@@ -2436,11 +2436,11 @@ class $e {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const Ke = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
|
-
LipsyncFi:
|
|
2441
|
+
LipsyncFi: _e
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class Je {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2559,10 +2559,10 @@ class tt {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let i = parseFloat(t);
|
|
2561
2561
|
if (i === void 0) return t;
|
|
2562
|
-
let n = (s, o, r,
|
|
2562
|
+
let n = (s, o, r, u, a) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
2564
|
+
const h = Math.floor(s / o);
|
|
2565
|
+
return h === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(h.toString())), h % 10 === 1 ? e.push(r) : h % 10 === 0 || h % 100 > 10 && h % 100 < 20 ? e.push(a) : e.push(u), s - h * o;
|
|
2566
2566
|
};
|
|
2567
2567
|
i < 0 && (e.push("minus"), i = Math.abs(i)), i = n(i, 1e9, "milijardas", "milijardai", "milijardų"), i = n(i, 1e6, "milijonas", "milijonai", "milijonų"), i = n(i, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), i = n(i, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class tt {
|
|
|
2608
2608
|
const o = n[s].toLowerCase(), r = this.visemes[o];
|
|
2609
2609
|
if (r)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const u = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += u, i += u;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(r), e.times.push(i), e.durations.push(
|
|
2614
|
+
const u = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(r), e.times.push(i), e.durations.push(u), i += u;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
i += this.pauses[n[s]] || 0;
|
|
@@ -2620,24 +2620,24 @@ class tt {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const $e = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), nt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), we = {
|
|
2627
|
-
en:
|
|
2628
|
-
de:
|
|
2629
|
-
fr:
|
|
2630
|
-
fi:
|
|
2631
|
-
lt:
|
|
2632
|
-
},
|
|
2625
|
+
LipsyncLt: Je
|
|
2626
|
+
}, Symbol.toStringTag, { value: "Module" })), et = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ae = {
|
|
2627
|
+
en: Xe,
|
|
2628
|
+
de: je,
|
|
2629
|
+
fr: qe,
|
|
2630
|
+
fi: Ke,
|
|
2631
|
+
lt: $e
|
|
2632
|
+
}, U = new f.Quaternion(), M = new f.Euler(), ie = new f.Vector3(), oe = new f.Vector3(), Le = new f.Box3();
|
|
2633
2633
|
new f.Matrix4();
|
|
2634
2634
|
new f.Matrix4();
|
|
2635
2635
|
new f.Vector3();
|
|
2636
2636
|
new f.Vector3(0, 0, 1);
|
|
2637
|
-
const
|
|
2637
|
+
const tt = new f.Vector3(1, 0, 0);
|
|
2638
2638
|
new f.Vector3(0, 1, 0);
|
|
2639
2639
|
new f.Vector3(0, 0, 1);
|
|
2640
|
-
class
|
|
2640
|
+
class we {
|
|
2641
2641
|
/**
|
|
2642
2642
|
* Avatar.
|
|
2643
2643
|
* @typedef {Object} Avatar
|
|
@@ -2746,9 +2746,9 @@ class Te {
|
|
|
2746
2746
|
lightSpotDispersion: 1,
|
|
2747
2747
|
avatarMood: "neutral",
|
|
2748
2748
|
avatarMute: !1,
|
|
2749
|
-
avatarIdleEyeContact: 0.
|
|
2749
|
+
avatarIdleEyeContact: 0.6,
|
|
2750
2750
|
avatarIdleHeadMove: 0.5,
|
|
2751
|
-
avatarSpeakingEyeContact: 0.
|
|
2751
|
+
avatarSpeakingEyeContact: 0.8,
|
|
2752
2752
|
avatarSpeakingHeadMove: 0.5,
|
|
2753
2753
|
avatarIgnoreCamera: !1,
|
|
2754
2754
|
listeningSilenceThresholdLevel: 40,
|
|
@@ -2763,7 +2763,7 @@ class Te {
|
|
|
2763
2763
|
avatarOnlyCamera: null,
|
|
2764
2764
|
statsNode: null,
|
|
2765
2765
|
statsStyle: null
|
|
2766
|
-
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new
|
|
2766
|
+
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new Oe(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
|
|
2767
2767
|
side: {
|
|
2768
2768
|
standing: !0,
|
|
2769
2769
|
props: {
|
|
@@ -3569,15 +3569,15 @@ class Te {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((r) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[r +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[r +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
|
|
3573
|
+
this.poseDelta.props[r + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
|
|
3575
|
+
this.poseDelta.props[r + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[r + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[r + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const i = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((r) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(r.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(r.props)).forEach((u) => i.add(u));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((r) => {
|
|
3582
3582
|
i.add(r);
|
|
3583
3583
|
}), this.posePropNames = [...i], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
|
|
@@ -3631,7 +3631,7 @@ class Te {
|
|
|
3631
3631
|
{ delay: [1e3, 4e3, 1, 2], dt: [50, [100, 200], 100, [10, 400, 0], 50, [100, 200], 100], vs: { eyeBlinkLeft: [1, 1, 0, 0, 1, 1, 0], eyeBlinkRight: [1, 1, 0, 0, 1, 1, 0] } }
|
|
3632
3632
|
] }, this.animMoods = {
|
|
3633
3633
|
neutral: {
|
|
3634
|
-
baseline: { eyesLookDown: 0
|
|
3634
|
+
baseline: { eyesLookDown: 0 },
|
|
3635
3635
|
speech: { deltaRate: 0, deltaPitch: 0, deltaVolume: 0 },
|
|
3636
3636
|
anims: [
|
|
3637
3637
|
{ name: "breathing", delay: 1500, dt: [1200, 500, 1e3], vs: { chestInhale: [0.5, 0.5, 0] } },
|
|
@@ -3657,7 +3657,7 @@ class Te {
|
|
|
3657
3657
|
]
|
|
3658
3658
|
},
|
|
3659
3659
|
happy: {
|
|
3660
|
-
baseline: { mouthSmile: 0.2, eyesLookDown: 0
|
|
3660
|
+
baseline: { mouthSmile: 0.2, eyesLookDown: 0 },
|
|
3661
3661
|
speech: { deltaRate: 0, deltaPitch: 0.1, deltaVolume: 0 },
|
|
3662
3662
|
anims: [
|
|
3663
3663
|
{ name: "breathing", delay: 1500, dt: [1200, 500, 1e3], vs: { chestInhale: [0.5, 0.5, 0] } },
|
|
@@ -4062,7 +4062,7 @@ class Te {
|
|
|
4062
4062
|
this.opt.lightSpotDispersion
|
|
4063
4063
|
), this.setLighting(this.opt);
|
|
4064
4064
|
const r = new f.PMREMGenerator(this.renderer);
|
|
4065
|
-
r.compileEquirectangularShader(), this.scene.environment = r.fromScene(new
|
|
4065
|
+
r.compileEquirectangularShader(), this.scene.environment = r.fromScene(new De()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Fe(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4066
4066
|
}
|
|
4067
4067
|
this.ikMesh = new f.SkinnedMesh();
|
|
4068
4068
|
const s = {
|
|
@@ -4077,17 +4077,17 @@ class Te {
|
|
|
4077
4077
|
RightHand: "RightForeArm",
|
|
4078
4078
|
RightHandMiddle1: "RightHand"
|
|
4079
4079
|
}, o = [];
|
|
4080
|
-
Object.entries(s).forEach((r,
|
|
4080
|
+
Object.entries(s).forEach((r, u) => {
|
|
4081
4081
|
const a = new f.Bone();
|
|
4082
4082
|
a.name = r[0], r[1] ? this.ikMesh.getObjectByName(r[1]).add(a) : this.ikMesh.add(a), o.push(a);
|
|
4083
|
-
}), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new
|
|
4083
|
+
}), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new Ve(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
4084
4084
|
}
|
|
4085
4085
|
/**
|
|
4086
4086
|
* Helper that re/creates the audio context and the other nodes.
|
|
4087
4087
|
* @param {number} sampleRate
|
|
4088
4088
|
*/
|
|
4089
4089
|
initAudioGraph(t = null) {
|
|
4090
|
-
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new
|
|
4090
|
+
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new Ge(this.audioCtx), this.audioReverbNode = this.audioCtx.createConvolver(), this.audioBackgroundGainNode.connect(this.audioReverbNode), this.audioAnalyzerNode.connect(this.audioSpeechGainNode), this.audioSpeechGainNode.connect(this.audioReverbNode), this.audioStreamGainNode.connect(this.audioReverbNode), this.audioReverbNode.connect(this.audioCtx.destination), this.setReverb(this.currentReverb || null), this.setMixerGain(
|
|
4091
4091
|
this.opt.mixerGainSpeech,
|
|
4092
4092
|
this.opt.mixerGainBackground
|
|
4093
4093
|
), this.workletLoaded = !1, this.streamWorkletNode) {
|
|
@@ -4126,9 +4126,9 @@ class Te {
|
|
|
4126
4126
|
let e = 3 * t.length / 4;
|
|
4127
4127
|
t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
|
|
4128
4128
|
const i = new ArrayBuffer(e), n = new Uint8Array(i);
|
|
4129
|
-
let s, o = 0, r,
|
|
4129
|
+
let s, o = 0, r, u, a, h;
|
|
4130
4130
|
for (s = 0; s < t.length; s += 4)
|
|
4131
|
-
r = this.b64Lookup[t.charCodeAt(s)],
|
|
4131
|
+
r = this.b64Lookup[t.charCodeAt(s)], u = this.b64Lookup[t.charCodeAt(s + 1)], a = this.b64Lookup[t.charCodeAt(s + 2)], h = this.b64Lookup[t.charCodeAt(s + 3)], n[o++] = r << 2 | u >> 4, n[o++] = (u & 15) << 4 | a >> 2, n[o++] = (a & 3) << 6 | h & 63;
|
|
4132
4132
|
return i;
|
|
4133
4133
|
}
|
|
4134
4134
|
/**
|
|
@@ -4169,8 +4169,8 @@ class Te {
|
|
|
4169
4169
|
const e = {};
|
|
4170
4170
|
for (let [i, n] of Object.entries(t)) {
|
|
4171
4171
|
const s = i.split(".");
|
|
4172
|
-
let o = Array.isArray(n.x) ? this.gaussianRandom(...n.x) : n.x, r = Array.isArray(n.y) ? this.gaussianRandom(...n.y) : n.y,
|
|
4173
|
-
s[1] === "position" || s[1] === "scale" ? e[i] = new f.Vector3(o, r,
|
|
4172
|
+
let o = Array.isArray(n.x) ? this.gaussianRandom(...n.x) : n.x, r = Array.isArray(n.y) ? this.gaussianRandom(...n.y) : n.y, u = Array.isArray(n.z) ? this.gaussianRandom(...n.z) : n.z;
|
|
4173
|
+
s[1] === "position" || s[1] === "scale" ? e[i] = new f.Vector3(o, r, u) : s[1] === "rotation" ? (i = s[0] + ".quaternion", e[i] = new f.Quaternion().setFromEuler(new f.Euler(o, r, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[i] = new f.Quaternion(o, r, u, n.w).normalize());
|
|
4174
4174
|
}
|
|
4175
4175
|
return e;
|
|
4176
4176
|
}
|
|
@@ -4198,23 +4198,23 @@ class Te {
|
|
|
4198
4198
|
t.forEach((s) => {
|
|
4199
4199
|
if (!n && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4200
4200
|
const o = s.geometry;
|
|
4201
|
-
let r = null,
|
|
4202
|
-
for (const [a,
|
|
4201
|
+
let r = null, u = null;
|
|
4202
|
+
for (const [a, h] of Object.entries(i))
|
|
4203
4203
|
if (s.morphTargetDictionary.hasOwnProperty(a)) {
|
|
4204
4204
|
const l = s.morphTargetDictionary[a], c = o.morphAttributes.position[l], d = o.morphAttributes.normal?.[l];
|
|
4205
|
-
r || (r = new f.Float32BufferAttribute(c.count * 3, 3), d && (
|
|
4205
|
+
r || (r = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
|
|
4206
4206
|
for (let g = 0; g < c.count; g++) {
|
|
4207
|
-
const y = r.getX(g) + c.getX(g) *
|
|
4207
|
+
const y = r.getX(g) + c.getX(g) * h, x = r.getY(g) + c.getY(g) * h, I = r.getZ(g) + c.getZ(g) * h;
|
|
4208
4208
|
r.setXYZ(g, y, x, I);
|
|
4209
4209
|
}
|
|
4210
4210
|
if (d)
|
|
4211
4211
|
for (let g = 0; g < c.count; g++) {
|
|
4212
|
-
const y =
|
|
4213
|
-
|
|
4212
|
+
const y = u.getX(g) + d.getX(g) * h, x = u.getY(g) + d.getY(g) * h, I = u.getZ(g) + d.getZ(g) * h;
|
|
4213
|
+
u.setXYZ(g, y, x, I);
|
|
4214
4214
|
}
|
|
4215
4215
|
}
|
|
4216
4216
|
if (r) {
|
|
4217
|
-
o.morphAttributes.position.push(r),
|
|
4217
|
+
o.morphAttributes.position.push(r), u && o.morphAttributes.normal.push(u);
|
|
4218
4218
|
const a = o.morphAttributes.position.length - 1;
|
|
4219
4219
|
s.morphTargetInfluences[a] = 0, s.morphTargetDictionary[e] = a;
|
|
4220
4220
|
}
|
|
@@ -4228,9 +4228,9 @@ class Te {
|
|
|
4228
4228
|
async showAvatar(t, e = null) {
|
|
4229
4229
|
if (!t || !t.hasOwnProperty("url"))
|
|
4230
4230
|
throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
|
|
4231
|
-
const i = new
|
|
4231
|
+
const i = new Pe();
|
|
4232
4232
|
if (this.dracoEnabled) {
|
|
4233
|
-
const a = new
|
|
4233
|
+
const a = new Be();
|
|
4234
4234
|
a.setDecoderPath(this.dracoDecoderPath), i.setDRACOLoader(a);
|
|
4235
4235
|
}
|
|
4236
4236
|
let n = await i.loadAsync(t.url, e);
|
|
@@ -4244,7 +4244,7 @@ class Te {
|
|
|
4244
4244
|
throw new Error("Blend shapes not found");
|
|
4245
4245
|
const o = new Set(this.mtCustoms);
|
|
4246
4246
|
this.morphs.forEach((a) => {
|
|
4247
|
-
Object.keys(a.morphTargetDictionary).forEach((
|
|
4247
|
+
Object.keys(a.morphTargetDictionary).forEach((h) => o.add(h));
|
|
4248
4248
|
}), this.mtExtras.forEach((a) => {
|
|
4249
4249
|
o.has(a.key) || (this.addMixedMorphTarget(this.morphs, a.key, a.mix), o.add(a.key));
|
|
4250
4250
|
});
|
|
@@ -4271,16 +4271,16 @@ class Te {
|
|
|
4271
4271
|
ms: [],
|
|
4272
4272
|
is: []
|
|
4273
4273
|
}, r[a].value = r[a].baseline, r[a].applied = r[a].baseline;
|
|
4274
|
-
const
|
|
4275
|
-
|
|
4276
|
-
r[a][l] =
|
|
4274
|
+
const h = this.mtAvatar[a];
|
|
4275
|
+
h && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((l) => {
|
|
4276
|
+
r[a][l] = h[l];
|
|
4277
4277
|
}), this.morphs.forEach((l) => {
|
|
4278
4278
|
const c = l.morphTargetDictionary[a];
|
|
4279
4279
|
c !== void 0 && (r[a].ms.push(l.morphTargetInfluences), r[a].is.push(c), l.morphTargetInfluences[c] = r[a].applied);
|
|
4280
4280
|
});
|
|
4281
4281
|
}), this.mtAvatar = r, this.poseAvatar = { props: {} }, this.posePropNames.forEach((a) => {
|
|
4282
|
-
const
|
|
4283
|
-
this.poseAvatar.props[a] = l[
|
|
4282
|
+
const h = a.split("."), l = this.armature.getObjectByName(h[0]);
|
|
4283
|
+
this.poseAvatar.props[a] = l[h[1]], this.poseBase.props.hasOwnProperty(a) ? this.poseAvatar.props[a].copy(this.poseBase.props[a]) : this.poseBase.props[a] = this.poseAvatar.props[a].clone(), this.poseDelta.props.hasOwnProperty(a) && !this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a] = this.poseAvatar.props[a].clone()), this.poseTarget.props[a].t = this.animClock, this.poseTarget.props[a].d = 2e3;
|
|
4284
4284
|
}), this.ikMesh.traverse((a) => {
|
|
4285
4285
|
a.isBone && a.position.copy(this.armature.getObjectByName(a.name).position);
|
|
4286
4286
|
}), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(n.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), t.hasOwnProperty("modelDynamicBones"))
|
|
@@ -4290,8 +4290,8 @@ class Te {
|
|
|
4290
4290
|
console.error("Dynamic bones setup failed: " + a);
|
|
4291
4291
|
}
|
|
4292
4292
|
this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
|
|
4293
|
-
const
|
|
4294
|
-
this.objectLeftEye.getWorldPosition(
|
|
4293
|
+
const u = new f.Vector3();
|
|
4294
|
+
this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4295
4295
|
}
|
|
4296
4296
|
/**
|
|
4297
4297
|
* Get view names.
|
|
@@ -4319,22 +4319,22 @@ class Te {
|
|
|
4319
4319
|
return;
|
|
4320
4320
|
}
|
|
4321
4321
|
if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4322
|
-
const i = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, n = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, r = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4323
|
-
let a = -i * Math.tan(
|
|
4322
|
+
const i = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, n = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, r = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
|
|
4323
|
+
let a = -i * Math.tan(u / 2), h = (1 - n) * Math.tan(u / 2), l = s;
|
|
4324
4324
|
switch (this.viewName) {
|
|
4325
4325
|
case "head":
|
|
4326
|
-
l += 2,
|
|
4326
|
+
l += 2, h = h * l + 4 * this.avatarHeight / 5;
|
|
4327
4327
|
break;
|
|
4328
4328
|
case "upper":
|
|
4329
|
-
l += 4.5,
|
|
4329
|
+
l += 4.5, h = h * l + 2 * this.avatarHeight / 3;
|
|
4330
4330
|
break;
|
|
4331
4331
|
case "mid":
|
|
4332
|
-
l += 8,
|
|
4332
|
+
l += 8, h = h * l + this.avatarHeight / 3;
|
|
4333
4333
|
break;
|
|
4334
4334
|
default:
|
|
4335
|
-
l += 12,
|
|
4335
|
+
l += 12, h = h * l;
|
|
4336
4336
|
}
|
|
4337
|
-
a = a * l, this.controlsEnd = new f.Vector3(a,
|
|
4337
|
+
a = a * l, this.controlsEnd = new f.Vector3(a, h, 0), this.cameraEnd = new f.Vector3(a, h, l).applyEuler(new f.Euler(o, r, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
|
|
4338
4338
|
}
|
|
4339
4339
|
/**
|
|
4340
4340
|
* Change light colors and intensities.
|
|
@@ -4376,7 +4376,7 @@ class Te {
|
|
|
4376
4376
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4377
4377
|
M.set(e.x, e.y, e.z);
|
|
4378
4378
|
const i = this.poseAvatar.props[t];
|
|
4379
|
-
i.isQuaternion ? (
|
|
4379
|
+
i.isQuaternion ? (U.setFromEuler(M), i.multiply(U)) : i.isVector3 && i.add(M);
|
|
4380
4380
|
}
|
|
4381
4381
|
}
|
|
4382
4382
|
/**
|
|
@@ -4431,17 +4431,17 @@ class Te {
|
|
|
4431
4431
|
"HandMiddle",
|
|
4432
4432
|
"HandRing",
|
|
4433
4433
|
"HandPinky"
|
|
4434
|
-
].forEach((
|
|
4435
|
-
l === 0 ? (this.poseDelta.props[o +
|
|
4434
|
+
].forEach((h, l) => {
|
|
4435
|
+
l === 0 ? (this.poseDelta.props[o + h + "1.quaternion"].x = 0, this.poseDelta.props[o + h + "2.quaternion"].z = (o === "Left" ? -1 : 1) * i.applied, this.poseDelta.props[o + h + "3.quaternion"].z = (o === "Left" ? -1 : 1) * i.applied) : (this.poseDelta.props[o + h + "1.quaternion"].x = i.applied, this.poseDelta.props[o + h + "2.quaternion"].x = 1.5 * i.applied, this.poseDelta.props[o + h + "3.quaternion"].x = 1.5 * i.applied);
|
|
4436
4436
|
});
|
|
4437
4437
|
break;
|
|
4438
4438
|
case "chestInhale":
|
|
4439
|
-
const r = i.applied / 20,
|
|
4440
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4439
|
+
const r = i.applied / 20, u = { x: r, y: r / 2, z: 3 * r }, a = { x: 1 / (1 + r) - 1, y: 1 / (1 + r / 2) - 1, z: 1 / (1 + 3 * r) - 1 };
|
|
4440
|
+
this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = a, this.poseDelta.props["LeftArm.scale"] = a, this.poseDelta.props["RightArm.scale"] = a;
|
|
4441
4441
|
break;
|
|
4442
4442
|
default:
|
|
4443
|
-
for (let
|
|
4444
|
-
i.ms[
|
|
4443
|
+
for (let h = 0, l = i.ms.length; h < l; h++)
|
|
4444
|
+
i.ms[h][i.is[h]] = i.applied;
|
|
4445
4445
|
}
|
|
4446
4446
|
}
|
|
4447
4447
|
}
|
|
@@ -4456,8 +4456,8 @@ class Te {
|
|
|
4456
4456
|
return Object.entries(t).forEach((n, s) => {
|
|
4457
4457
|
const o = n[0].split(".");
|
|
4458
4458
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4459
|
-
const r = o[1] === "quaternion" ? o[0] + ".rotation" : n[0],
|
|
4460
|
-
i += (s ? ", " : "") + "'" + r + "':{", i += "x:" + Math.round(
|
|
4459
|
+
const r = o[1] === "quaternion" ? o[0] + ".rotation" : n[0], u = n[1].isQuaternion ? new f.Euler().setFromQuaternion(n[1]) : n[1];
|
|
4460
|
+
i += (s ? ", " : "") + "'" + r + "':{", i += "x:" + Math.round(u.x * e) / e, i += ", y:" + Math.round(u.y * e) / e, i += ", z:" + Math.round(u.z * e) / e, i += "}";
|
|
4461
4461
|
}
|
|
4462
4462
|
}), i += "}", i;
|
|
4463
4463
|
}
|
|
@@ -4527,8 +4527,8 @@ class Te {
|
|
|
4527
4527
|
if (i ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4528
4528
|
this.setPoseFromTemplate(t, e);
|
|
4529
4529
|
}, o)) : this.poseCurrentTemplate = t || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, o), this.poseWeightOnLeft = !0, (!n && !s || n && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
|
|
4530
|
-
for (let [r,
|
|
4531
|
-
this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r].copy(
|
|
4530
|
+
for (let [r, u] of Object.entries(this.gesture))
|
|
4531
|
+
this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r].copy(u), this.poseTarget.props[r].t = u.t, this.poseTarget.props[r].d = u.d);
|
|
4532
4532
|
Object.keys(this.poseDelta.props).forEach((r) => {
|
|
4533
4533
|
this.poseTarget.props.hasOwnProperty(r) || (this.poseTarget.props[r] = this.poseBase.props[r].clone(), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = o);
|
|
4534
4534
|
});
|
|
@@ -4973,11 +4973,11 @@ class Te {
|
|
|
4973
4973
|
else if (r.hasOwnProperty("alt")) {
|
|
4974
4974
|
let a = r.alt[0];
|
|
4975
4975
|
if (r.alt.length > 1) {
|
|
4976
|
-
const
|
|
4976
|
+
const h = Math.random();
|
|
4977
4977
|
let l = 0;
|
|
4978
4978
|
for (let c = 0; c < r.alt.length; c++) {
|
|
4979
4979
|
let d = this.valueFn(r.alt[c].p);
|
|
4980
|
-
if (l += d === void 0 ? (1 - l) / (r.alt.length - 1 - c) : d,
|
|
4980
|
+
if (l += d === void 0 ? (1 - l) / (r.alt.length - 1 - c) : d, h < l) {
|
|
4981
4981
|
a = r.alt[c];
|
|
4982
4982
|
break;
|
|
4983
4983
|
}
|
|
@@ -4986,19 +4986,19 @@ class Te {
|
|
|
4986
4986
|
r = a;
|
|
4987
4987
|
} else
|
|
4988
4988
|
break;
|
|
4989
|
-
let
|
|
4990
|
-
if (Array.isArray(
|
|
4991
|
-
r.dt.forEach((a,
|
|
4989
|
+
let u = this.valueFn(r.delay) || 0;
|
|
4990
|
+
if (Array.isArray(u) && (u = this.gaussianRandom(...u)), r.hasOwnProperty("dt"))
|
|
4991
|
+
r.dt.forEach((a, h) => {
|
|
4992
4992
|
let l = this.valueFn(a);
|
|
4993
|
-
Array.isArray(l) && (l = this.gaussianRandom(...l)), o.ts[
|
|
4993
|
+
Array.isArray(l) && (l = this.gaussianRandom(...l)), o.ts[h + 1] = o.ts[h] + l;
|
|
4994
4994
|
});
|
|
4995
4995
|
else {
|
|
4996
|
-
let a = Object.values(r.vs).reduce((
|
|
4996
|
+
let a = Object.values(r.vs).reduce((h, l) => l.length > h ? l.length : h, 0);
|
|
4997
4997
|
o.ts = Array(a + 1).fill(0);
|
|
4998
4998
|
}
|
|
4999
|
-
s ? o.ts = o.ts.map((a) =>
|
|
5000
|
-
for (let [a,
|
|
5001
|
-
const l = this.getBaselineValue(a), c =
|
|
4999
|
+
s ? o.ts = o.ts.map((a) => u + a * i) : o.ts = o.ts.map((a) => this.animClock + u + a * i);
|
|
5000
|
+
for (let [a, h] of Object.entries(r.vs)) {
|
|
5001
|
+
const l = this.getBaselineValue(a), c = h.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? d.slice() : Array.isArray(d) ? a === "gesture" ? d.slice() : (l === void 0 ? 0 : l) + n * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (l === void 0 ? 0 : l) + n * d));
|
|
5002
5002
|
a === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : a === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[a] = [null, ...c];
|
|
5003
5003
|
}
|
|
5004
5004
|
for (let a of Object.keys(o.vs))
|
|
@@ -5080,8 +5080,8 @@ class Te {
|
|
|
5080
5080
|
if (this.isSpeaking)
|
|
5081
5081
|
for (r = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), i = 2, s = 10; i < s; i++)
|
|
5082
5082
|
this.volumeFrequencyData[i] > r && (r = this.volumeFrequencyData[i]);
|
|
5083
|
-
let
|
|
5084
|
-
const
|
|
5083
|
+
let u = null, a = null;
|
|
5084
|
+
const h = [];
|
|
5085
5085
|
for (i = 0, s = this.animQueue.length; i < s; i++) {
|
|
5086
5086
|
const l = this.animQueue[i];
|
|
5087
5087
|
if (!(!l || !l.ts || !l.ts.length || this.animClock < l.ts[0])) {
|
|
@@ -5108,12 +5108,12 @@ class Te {
|
|
|
5108
5108
|
g.newvalue *= 1 + r / 255 - 0.5;
|
|
5109
5109
|
}
|
|
5110
5110
|
g.needsUpdate = !0;
|
|
5111
|
-
} else c === "eyeContact" && d[n] !== null &&
|
|
5111
|
+
} else c === "eyeContact" && d[n] !== null && u !== !1 ? u = !!d[n] : c === "headMove" && d[n] !== null && a !== !1 ? d[n] === 0 ? a = !1 : (Math.random() < d[n] && (a = !0), d[n] = null) : d[n] !== null && (h.push({ mt: c, val: d[n] }), d[n] = null);
|
|
5112
5112
|
n === o ? (l.hasOwnProperty("mood") && this.setMood(l.mood), l.loop ? (o = this.isSpeaking && (l.template.name === "head" || l.template.name === "eyes") ? 4 : 1, this.animQueue[i] = this.animFactory(l.template, l.loop > 0 ? l.loop - 1 : l.loop, 1, 1 / o)) : (this.animQueue.splice(i--, 1), s--)) : l.ndx = n - 1;
|
|
5113
5113
|
}
|
|
5114
5114
|
}
|
|
5115
|
-
for (let l = 0, c =
|
|
5116
|
-
switch (n =
|
|
5115
|
+
for (let l = 0, c = h.length; l < c; l++)
|
|
5116
|
+
switch (n = h[l].val, h[l].mt) {
|
|
5117
5117
|
case "speak":
|
|
5118
5118
|
this.speakText(n);
|
|
5119
5119
|
break;
|
|
@@ -5159,7 +5159,7 @@ class Te {
|
|
|
5159
5159
|
}, n.x ? new f.Vector3(n.x, n.y, n.z) : null, !0, n.d);
|
|
5160
5160
|
break;
|
|
5161
5161
|
}
|
|
5162
|
-
if ((
|
|
5162
|
+
if ((u || a) && (M.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), M.x = Math.max(-0.9, Math.min(0.9, 2 * M.x - 0.5)), M.y = Math.max(-0.9, Math.min(0.9, -2.5 * M.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: M.x < 0 ? -M.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: M.x < 0 ? 0 : M.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: M.y < 0 ? -M.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: M.y < 0 ? 0 : M.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: M.y < 0 ? 0 : M.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: M.y < 0 ? -M.y : 0, needsUpdate: !0 }), a && (i = -this.mtAvatar.bodyRotateY.value, n = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5163
5163
|
name: "headmove",
|
|
5164
5164
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5165
5165
|
vs: {
|
|
@@ -5180,7 +5180,7 @@ class Te {
|
|
|
5180
5180
|
eyeLookOutRight: [null, 0],
|
|
5181
5181
|
eyeContact: [0]
|
|
5182
5182
|
}
|
|
5183
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 0) + (1 + r / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) &&
|
|
5183
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 0) + (1 + r / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? r > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = r) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (U.setFromAxisAngle(tt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(U)), Le.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ie), ie.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(oe), oe.sub(this.armature.position), this.objectHips.position.y -= Le.min.y / 2, this.objectHips.position.x -= (ie.x + oe.x) / 4, this.objectHips.position.z -= (ie.z + oe.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5184
5184
|
this.stats && this.stats.end();
|
|
5185
5185
|
else {
|
|
5186
5186
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5211,8 +5211,8 @@ class Te {
|
|
|
5211
5211
|
if (!this.lipsync.hasOwnProperty(t)) {
|
|
5212
5212
|
const i = t.toLowerCase(), n = "Lipsync" + t.charAt(0).toUpperCase() + t.slice(1);
|
|
5213
5213
|
try {
|
|
5214
|
-
const s =
|
|
5215
|
-
s && s[n] ? (this.lipsync[t] = new s[n](), console.log(`Loaded lip-sync module for ${t}`)) : console.warn(`Lip-sync module for ${t} not found. Available modules:`, Object.keys(
|
|
5214
|
+
const s = Ae[i];
|
|
5215
|
+
s && s[n] ? (this.lipsync[t] = new s[n](), console.log(`Loaded lip-sync module for ${t}`)) : console.warn(`Lip-sync module for ${t} not found. Available modules:`, Object.keys(Ae));
|
|
5216
5216
|
} catch (s) {
|
|
5217
5217
|
console.warn(`Failed to load lip-sync module for ${t}:`, s);
|
|
5218
5218
|
}
|
|
@@ -5247,34 +5247,34 @@ class Te {
|
|
|
5247
5247
|
*/
|
|
5248
5248
|
speakText(t, e = null, i = null, n = null) {
|
|
5249
5249
|
e = e || {};
|
|
5250
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, r = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5251
|
-
let
|
|
5250
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, r = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, a = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5251
|
+
let h = "", l = "", c = 0, d = [], g = [];
|
|
5252
5252
|
const y = Array.from(this.segmenter.segment(t), (x) => x.segment);
|
|
5253
5253
|
for (let x = 0; x < y.length; x++) {
|
|
5254
|
-
const I = x === y.length - 1,
|
|
5254
|
+
const I = x === y.length - 1, F = y[x].match(r);
|
|
5255
5255
|
let p = y[x].match(s);
|
|
5256
|
-
const
|
|
5257
|
-
if (p && !I && !
|
|
5256
|
+
const z = y[x].match(u), C = y[x].match(o);
|
|
5257
|
+
if (p && !I && !z && y[x + 1].match(s) && (p = !1), i && (h += y[x]), F && (!n || n.every((R) => x < R[0] || x > R[1])) && (l += y[x]), (C || p || I) && (l.length && (l = this.lipsyncPreProcessText(l, a), l.length && d.push({
|
|
5258
5258
|
mark: c,
|
|
5259
5259
|
word: l
|
|
5260
|
-
})),
|
|
5260
|
+
})), h.length && (g.push({
|
|
5261
5261
|
mark: c,
|
|
5262
5262
|
template: { name: "subtitles" },
|
|
5263
5263
|
ts: [0],
|
|
5264
5264
|
vs: {
|
|
5265
|
-
subtitles: [
|
|
5265
|
+
subtitles: [h]
|
|
5266
5266
|
}
|
|
5267
|
-
}),
|
|
5268
|
-
const
|
|
5269
|
-
if (
|
|
5270
|
-
const
|
|
5271
|
-
for (let
|
|
5267
|
+
}), h = ""), l.length)) {
|
|
5268
|
+
const R = this.lipsyncWordsToVisemes(l, a);
|
|
5269
|
+
if (R && R.visemes && R.visemes.length) {
|
|
5270
|
+
const W = R.times[R.visemes.length - 1] + R.durations[R.visemes.length - 1];
|
|
5271
|
+
for (let D = 0; D < R.visemes.length; D++)
|
|
5272
5272
|
g.push({
|
|
5273
5273
|
mark: c,
|
|
5274
5274
|
template: { name: "viseme" },
|
|
5275
|
-
ts: [(
|
|
5275
|
+
ts: [(R.times[D] - 0.6) / W, (R.times[D] + 0.5) / W, (R.times[D] + R.durations[D] + 0.5) / W],
|
|
5276
5276
|
vs: {
|
|
5277
|
-
["viseme_" +
|
|
5277
|
+
["viseme_" + R.visemes[D]]: [null, R.visemes[D] === "PP" || R.visemes[D] === "FF" ? 0.9 : 0.6, 0]
|
|
5278
5278
|
}
|
|
5279
5279
|
});
|
|
5280
5280
|
}
|
|
@@ -5282,14 +5282,14 @@ class Te {
|
|
|
5282
5282
|
}
|
|
5283
5283
|
if (p || I) {
|
|
5284
5284
|
if (d.length || I && g.length) {
|
|
5285
|
-
const
|
|
5285
|
+
const R = {
|
|
5286
5286
|
anim: g
|
|
5287
5287
|
};
|
|
5288
|
-
i && (
|
|
5288
|
+
i && (R.onSubtitles = i), d.length && !e.avatarMute && (R.text = d, e.avatarMood && (R.mood = e.avatarMood), e.ttsLang && (R.lang = e.ttsLang), e.ttsVoice && (R.voice = e.ttsVoice), e.ttsRate && (R.rate = e.ttsRate), e.ttsVoice && (R.pitch = e.ttsPitch), e.ttsVolume && (R.volume = e.ttsVolume)), this.speechQueue.push(R), d = [], l = "", c = 0, g = [];
|
|
5289
5289
|
}
|
|
5290
|
-
if (
|
|
5291
|
-
let
|
|
5292
|
-
|
|
5290
|
+
if (z) {
|
|
5291
|
+
let R = this.animEmojis[y[x]];
|
|
5292
|
+
R && R.link && (R = this.animEmojis[R.link]), R && this.speechQueue.push({ emoji: R });
|
|
5293
5293
|
}
|
|
5294
5294
|
this.speechQueue.push({ break: 100 });
|
|
5295
5295
|
}
|
|
@@ -5370,25 +5370,25 @@ class Te {
|
|
|
5370
5370
|
if (t.words) {
|
|
5371
5371
|
let o = [];
|
|
5372
5372
|
for (let r = 0; r < t.words.length; r++) {
|
|
5373
|
-
const
|
|
5374
|
-
let
|
|
5375
|
-
if (
|
|
5373
|
+
const u = t.words[r], a = t.wtimes[r];
|
|
5374
|
+
let h = t.wdurations[r];
|
|
5375
|
+
if (u.length && (i && o.push({
|
|
5376
5376
|
template: { name: "subtitles" },
|
|
5377
5377
|
ts: [a],
|
|
5378
5378
|
vs: {
|
|
5379
|
-
subtitles: [" " +
|
|
5379
|
+
subtitles: [" " + u]
|
|
5380
5380
|
}
|
|
5381
5381
|
}), !t.visemes)) {
|
|
5382
|
-
const l = this.lipsyncPreProcessText(
|
|
5382
|
+
const l = this.lipsyncPreProcessText(u, n), c = this.lipsyncWordsToVisemes(l, n);
|
|
5383
5383
|
if (c && c.visemes && c.visemes.length) {
|
|
5384
|
-
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(
|
|
5385
|
-
let y = 0.6 + this.convertRange(g, [0,
|
|
5386
|
-
if (
|
|
5384
|
+
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(h, Math.max(0, h - c.visemes.length * 150));
|
|
5385
|
+
let y = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
|
|
5386
|
+
if (h = Math.min(h, c.visemes.length * 200), d > 0)
|
|
5387
5387
|
for (let x = 0; x < c.visemes.length; x++) {
|
|
5388
|
-
const I = a + c.times[x] / d *
|
|
5388
|
+
const I = a + c.times[x] / d * h, F = c.durations[x] / d * h;
|
|
5389
5389
|
o.push({
|
|
5390
5390
|
template: { name: "viseme" },
|
|
5391
|
-
ts: [I - Math.min(60, 2 *
|
|
5391
|
+
ts: [I - Math.min(60, 2 * F / 3), I + Math.min(25, F / 2), I + F + Math.min(60, F / 2)],
|
|
5392
5392
|
vs: {
|
|
5393
5393
|
["viseme_" + c.visemes[x]]: [null, c.visemes[x] === "PP" || c.visemes[x] === "FF" ? 0.9 : y, 0]
|
|
5394
5394
|
}
|
|
@@ -5399,22 +5399,22 @@ class Te {
|
|
|
5399
5399
|
}
|
|
5400
5400
|
if (t.visemes)
|
|
5401
5401
|
for (let r = 0; r < t.visemes.length; r++) {
|
|
5402
|
-
const
|
|
5402
|
+
const u = t.visemes[r], a = t.vtimes[r], h = t.vdurations[r];
|
|
5403
5403
|
o.push({
|
|
5404
5404
|
template: { name: "viseme" },
|
|
5405
|
-
ts: [a - 2 *
|
|
5405
|
+
ts: [a - 2 * h / 3, a + h / 2, a + h + h / 2],
|
|
5406
5406
|
vs: {
|
|
5407
|
-
["viseme_" +
|
|
5407
|
+
["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
|
|
5408
5408
|
}
|
|
5409
5409
|
});
|
|
5410
5410
|
}
|
|
5411
5411
|
if (t.markers)
|
|
5412
5412
|
for (let r = 0; r < t.markers.length; r++) {
|
|
5413
|
-
const
|
|
5413
|
+
const u = t.markers[r], a = t.mtimes[r];
|
|
5414
5414
|
o.push({
|
|
5415
5415
|
template: { name: "markers" },
|
|
5416
5416
|
ts: [a],
|
|
5417
|
-
vs: { function: [
|
|
5417
|
+
vs: { function: [u] }
|
|
5418
5418
|
});
|
|
5419
5419
|
}
|
|
5420
5420
|
o.length && (s.anim = o);
|
|
@@ -5434,7 +5434,7 @@ class Te {
|
|
|
5434
5434
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5435
5435
|
const e = this.audioPlaylist.shift();
|
|
5436
5436
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5437
|
-
const s = this.audioCtx.resume(), o = new Promise((r,
|
|
5437
|
+
const s = this.audioCtx.resume(), o = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
|
|
5438
5438
|
try {
|
|
5439
5439
|
await Promise.race([s, o]);
|
|
5440
5440
|
} catch {
|
|
@@ -5466,11 +5466,11 @@ class Te {
|
|
|
5466
5466
|
*/
|
|
5467
5467
|
async synthesizeWithBrowserTTS(t) {
|
|
5468
5468
|
return new Promise((e, i) => {
|
|
5469
|
-
const n = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(n), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", r = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5470
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, r)), s.pitch = Math.max(0, Math.min(2,
|
|
5471
|
-
const
|
|
5472
|
-
if (l &&
|
|
5473
|
-
const p =
|
|
5469
|
+
const n = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(n), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", r = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, a = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5470
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, r)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, a));
|
|
5471
|
+
const h = speechSynthesis.getVoices(), l = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5472
|
+
if (l && h.length > 0) {
|
|
5473
|
+
const p = h.find((z) => z.name.includes(l) || z.lang === o);
|
|
5474
5474
|
p && (s.voice = p);
|
|
5475
5475
|
}
|
|
5476
5476
|
const c = n.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(n, g), x = this.lipsyncWordsToVisemes(y, g);
|
|
@@ -5485,19 +5485,19 @@ class Te {
|
|
|
5485
5485
|
const I = [];
|
|
5486
5486
|
if (x && x.visemes && x.visemes.length > 0) {
|
|
5487
5487
|
const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
|
|
5488
|
-
for (let
|
|
5489
|
-
const
|
|
5488
|
+
for (let z = 0; z < x.visemes.length; z++) {
|
|
5489
|
+
const C = x.visemes[z], R = x.times[z] / p, W = x.durations[z] / p, D = R * c, j = W * c;
|
|
5490
5490
|
I.push({
|
|
5491
5491
|
template: { name: "viseme" },
|
|
5492
|
-
ts: [
|
|
5492
|
+
ts: [D - Math.min(60, 2 * j / 3), D + Math.min(25, j / 2), D + j + Math.min(60, j / 2)],
|
|
5493
5493
|
vs: {
|
|
5494
|
-
["viseme_" +
|
|
5494
|
+
["viseme_" + C]: [null, C === "PP" || C === "FF" ? 0.9 : 0.6, 0]
|
|
5495
5495
|
}
|
|
5496
5496
|
});
|
|
5497
5497
|
}
|
|
5498
5498
|
}
|
|
5499
|
-
const
|
|
5500
|
-
this.audioPlaylist.push({ anim:
|
|
5499
|
+
const F = [...t.anim, ...I];
|
|
5500
|
+
this.audioPlaylist.push({ anim: F, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5501
5501
|
e();
|
|
5502
5502
|
}, s.onerror = (p) => {
|
|
5503
5503
|
console.error("Speech synthesis error:", p.error), i(p.error);
|
|
@@ -5531,15 +5531,15 @@ class Te {
|
|
|
5531
5531
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5532
5532
|
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5533
5533
|
console.log("Using text-based lip-sync for debugging...");
|
|
5534
|
-
const
|
|
5534
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5535
5535
|
let a;
|
|
5536
5536
|
try {
|
|
5537
5537
|
console.log("Lip-sync modules available:", {
|
|
5538
5538
|
hasLipsync: !!this.lipsync,
|
|
5539
5539
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5540
|
-
lipsyncLang:
|
|
5540
|
+
lipsyncLang: u
|
|
5541
5541
|
});
|
|
5542
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5542
|
+
const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
|
|
5543
5543
|
if (console.log("Lip-sync data:", {
|
|
5544
5544
|
processedText: c,
|
|
5545
5545
|
lipsyncData: d,
|
|
@@ -5592,12 +5592,12 @@ class Te {
|
|
|
5592
5592
|
visemes: a.visemes ? a.visemes.slice(0, 3) : []
|
|
5593
5593
|
// Show first 3 visemes for debugging
|
|
5594
5594
|
});
|
|
5595
|
-
const
|
|
5595
|
+
const h = [];
|
|
5596
5596
|
if (a.visemes && a.visemes.length > 0) {
|
|
5597
5597
|
console.log("ElevenLabs: Generating lip-sync animation from", a.visemes.length, "visemes");
|
|
5598
5598
|
for (let c = 0; c < a.visemes.length; c++) {
|
|
5599
5599
|
const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
|
|
5600
|
-
|
|
5600
|
+
h.push({
|
|
5601
5601
|
template: { name: "viseme" },
|
|
5602
5602
|
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5603
5603
|
vs: {
|
|
@@ -5605,11 +5605,11 @@ class Te {
|
|
|
5605
5605
|
}
|
|
5606
5606
|
});
|
|
5607
5607
|
}
|
|
5608
|
-
console.log("ElevenLabs: Generated",
|
|
5608
|
+
console.log("ElevenLabs: Generated", h.length, "lip-sync animation frames");
|
|
5609
5609
|
} else
|
|
5610
5610
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5611
|
-
const l = [...t.anim, ...
|
|
5612
|
-
console.log("ElevenLabs: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5611
|
+
const l = [...t.anim, ...h];
|
|
5612
|
+
console.log("ElevenLabs: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: l, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5613
5613
|
}
|
|
5614
5614
|
/**
|
|
5615
5615
|
* Synthesize speech using Deepgram Aura-2 TTS
|
|
@@ -5629,15 +5629,15 @@ class Te {
|
|
|
5629
5629
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5630
5630
|
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5631
5631
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5632
|
-
const
|
|
5632
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5633
5633
|
let a;
|
|
5634
5634
|
try {
|
|
5635
5635
|
console.log("Lip-sync modules available:", {
|
|
5636
5636
|
hasLipsync: !!this.lipsync,
|
|
5637
5637
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5638
|
-
lipsyncLang:
|
|
5638
|
+
lipsyncLang: u
|
|
5639
5639
|
});
|
|
5640
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5640
|
+
const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
|
|
5641
5641
|
if (console.log("Lip-sync data:", {
|
|
5642
5642
|
processedText: c,
|
|
5643
5643
|
lipsyncData: d,
|
|
@@ -5690,12 +5690,12 @@ class Te {
|
|
|
5690
5690
|
visemes: a.visemes ? a.visemes.slice(0, 3) : []
|
|
5691
5691
|
// Show first 3 visemes for debugging
|
|
5692
5692
|
});
|
|
5693
|
-
const
|
|
5693
|
+
const h = [];
|
|
5694
5694
|
if (a.visemes && a.visemes.length > 0) {
|
|
5695
5695
|
console.log("Deepgram: Generating lip-sync animation from", a.visemes.length, "visemes");
|
|
5696
5696
|
for (let c = 0; c < a.visemes.length; c++) {
|
|
5697
5697
|
const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
|
|
5698
|
-
|
|
5698
|
+
h.push({
|
|
5699
5699
|
template: { name: "viseme" },
|
|
5700
5700
|
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5701
5701
|
vs: {
|
|
@@ -5703,11 +5703,11 @@ class Te {
|
|
|
5703
5703
|
}
|
|
5704
5704
|
});
|
|
5705
5705
|
}
|
|
5706
|
-
console.log("Deepgram: Generated",
|
|
5706
|
+
console.log("Deepgram: Generated", h.length, "lip-sync animation frames");
|
|
5707
5707
|
} else
|
|
5708
5708
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5709
|
-
const l = [...t.anim, ...
|
|
5710
|
-
console.log("Deepgram: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5709
|
+
const l = [...t.anim, ...h];
|
|
5710
|
+
console.log("Deepgram: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: l, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5711
5711
|
}
|
|
5712
5712
|
/**
|
|
5713
5713
|
* Synthesize speech using Azure TTS
|
|
@@ -5733,20 +5733,20 @@ class Te {
|
|
|
5733
5733
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5734
5734
|
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5735
5735
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5736
|
-
const
|
|
5736
|
+
const u = await this.audioAnalyzer.analyzeAudio(r, e);
|
|
5737
5737
|
console.log("Azure TTS Audio Analysis:", {
|
|
5738
5738
|
text: e,
|
|
5739
5739
|
audioDuration: r.duration,
|
|
5740
|
-
visemeCount:
|
|
5741
|
-
wordCount:
|
|
5740
|
+
visemeCount: u.visemes.length,
|
|
5741
|
+
wordCount: u.words.length,
|
|
5742
5742
|
features: {
|
|
5743
|
-
onsets:
|
|
5744
|
-
boundaries:
|
|
5743
|
+
onsets: u.features.onsets.length,
|
|
5744
|
+
boundaries: u.features.phonemeBoundaries.length
|
|
5745
5745
|
}
|
|
5746
5746
|
});
|
|
5747
5747
|
const a = [];
|
|
5748
|
-
for (let l = 0; l <
|
|
5749
|
-
const c =
|
|
5748
|
+
for (let l = 0; l < u.visemes.length; l++) {
|
|
5749
|
+
const c = u.visemes[l], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
|
|
5750
5750
|
a.push({
|
|
5751
5751
|
template: { name: "viseme" },
|
|
5752
5752
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
@@ -5755,8 +5755,8 @@ class Te {
|
|
|
5755
5755
|
}
|
|
5756
5756
|
});
|
|
5757
5757
|
}
|
|
5758
|
-
const
|
|
5759
|
-
this.audioPlaylist.push({ anim:
|
|
5758
|
+
const h = [...t.anim, ...a];
|
|
5759
|
+
this.audioPlaylist.push({ anim: h, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5760
5760
|
}
|
|
5761
5761
|
/**
|
|
5762
5762
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5795,24 +5795,24 @@ class Te {
|
|
|
5795
5795
|
if (n.status === 200 && s && s.audioContent) {
|
|
5796
5796
|
const o = this.b64ToArrayBuffer(s.audioContent), r = await this.audioCtx.decodeAudioData(o);
|
|
5797
5797
|
this.speakWithHands();
|
|
5798
|
-
const
|
|
5798
|
+
const u = [0];
|
|
5799
5799
|
let a = 0;
|
|
5800
5800
|
t.text.forEach((c, d) => {
|
|
5801
5801
|
if (d > 0) {
|
|
5802
|
-
let g =
|
|
5803
|
-
s.timepoints[a] && (g = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + c.mark && a++),
|
|
5802
|
+
let g = u[u.length - 1];
|
|
5803
|
+
s.timepoints[a] && (g = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + c.mark && a++), u.push(g);
|
|
5804
5804
|
}
|
|
5805
5805
|
});
|
|
5806
|
-
const
|
|
5807
|
-
|
|
5806
|
+
const h = [{ mark: 0, time: 0 }];
|
|
5807
|
+
u.forEach((c, d) => {
|
|
5808
5808
|
if (d > 0) {
|
|
5809
|
-
let g = c -
|
|
5810
|
-
|
|
5809
|
+
let g = c - u[d - 1];
|
|
5810
|
+
h[d - 1].duration = g, h.push({ mark: d, time: c });
|
|
5811
5811
|
}
|
|
5812
5812
|
});
|
|
5813
5813
|
let l = 1e3 * r.duration;
|
|
5814
|
-
l > this.opt.ttsTrimEnd && (l = l - this.opt.ttsTrimEnd),
|
|
5815
|
-
const d =
|
|
5814
|
+
l > this.opt.ttsTrimEnd && (l = l - this.opt.ttsTrimEnd), h[h.length - 1].duration = l - h[h.length - 1].time, t.anim.forEach((c) => {
|
|
5815
|
+
const d = h[c.mark];
|
|
5816
5816
|
if (d)
|
|
5817
5817
|
for (let g = 0; g < c.ts.length; g++)
|
|
5818
5818
|
c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
|
|
@@ -5895,10 +5895,10 @@ class Te {
|
|
|
5895
5895
|
}
|
|
5896
5896
|
if (!this.workletLoaded)
|
|
5897
5897
|
try {
|
|
5898
|
-
const r = this.audioCtx.audioWorklet.addModule(
|
|
5899
|
-
(a,
|
|
5898
|
+
const r = this.audioCtx.audioWorklet.addModule(et.href), u = new Promise(
|
|
5899
|
+
(a, h) => setTimeout(() => h(new Error("Worklet loading timed out")), 5e3)
|
|
5900
5900
|
);
|
|
5901
|
-
await Promise.race([r,
|
|
5901
|
+
await Promise.race([r, u]), this.workletLoaded = !0;
|
|
5902
5902
|
} catch (r) {
|
|
5903
5903
|
throw console.error("Failed to load audio worklet:", r), new Error("Failed to initialize streaming speech");
|
|
5904
5904
|
}
|
|
@@ -5911,8 +5911,8 @@ class Te {
|
|
|
5911
5911
|
if (r.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5912
5912
|
try {
|
|
5913
5913
|
this.onAudioStart?.();
|
|
5914
|
-
} catch (
|
|
5915
|
-
console.error(
|
|
5914
|
+
} catch (u) {
|
|
5915
|
+
console.error(u);
|
|
5916
5916
|
}
|
|
5917
5917
|
if (r.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5918
5918
|
try {
|
|
@@ -5932,9 +5932,9 @@ class Te {
|
|
|
5932
5932
|
} catch {
|
|
5933
5933
|
}
|
|
5934
5934
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = n || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5935
|
-
const r = this.audioCtx.resume(),
|
|
5935
|
+
const r = this.audioCtx.resume(), u = new Promise((a, h) => setTimeout(() => h("p2"), 1e3));
|
|
5936
5936
|
try {
|
|
5937
|
-
await Promise.race([r,
|
|
5937
|
+
await Promise.race([r, u]);
|
|
5938
5938
|
} catch {
|
|
5939
5939
|
console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");
|
|
5940
5940
|
return;
|
|
@@ -6031,13 +6031,13 @@ class Te {
|
|
|
6031
6031
|
subtitles: [" " + n]
|
|
6032
6032
|
}
|
|
6033
6033
|
}), this.streamLipsyncType == "words")) {
|
|
6034
|
-
const r = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6034
|
+
const r = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(n, r), a = this.lipsyncWordsToVisemes(u, r);
|
|
6035
6035
|
if (a && a.visemes && a.visemes.length) {
|
|
6036
|
-
const
|
|
6036
|
+
const h = a.times[a.visemes.length - 1] + a.durations[a.visemes.length - 1], l = Math.min(o, Math.max(0, o - a.visemes.length * 150));
|
|
6037
6037
|
let c = 0.6 + this.convertRange(l, [0, o], [0, 0.4]);
|
|
6038
|
-
if (o = Math.min(o, a.visemes.length * 200),
|
|
6038
|
+
if (o = Math.min(o, a.visemes.length * 200), h > 0)
|
|
6039
6039
|
for (let d = 0; d < a.visemes.length; d++) {
|
|
6040
|
-
const g = e + s + a.times[d] /
|
|
6040
|
+
const g = e + s + a.times[d] / h * o, y = a.durations[d] / h * o;
|
|
6041
6041
|
this.animQueue.push({
|
|
6042
6042
|
template: { name: "viseme" },
|
|
6043
6043
|
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
@@ -6146,12 +6146,12 @@ class Te {
|
|
|
6146
6146
|
this.lookAt(null, null, t);
|
|
6147
6147
|
return;
|
|
6148
6148
|
}
|
|
6149
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ie.setFromMatrixPosition(this.objectLeftEye.matrixWorld), oe.setFromMatrixPosition(this.objectRightEye.matrixWorld), ie.add(oe).divideScalar(2),
|
|
6149
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ie.setFromMatrixPosition(this.objectLeftEye.matrixWorld), oe.setFromMatrixPosition(this.objectRightEye.matrixWorld), ie.add(oe).divideScalar(2), U.copy(this.armature.quaternion), U.multiply(this.poseTarget.props["Hips.quaternion"]), U.multiply(this.poseTarget.props["Spine.quaternion"]), U.multiply(this.poseTarget.props["Spine1.quaternion"]), U.multiply(this.poseTarget.props["Spine2.quaternion"]), U.multiply(this.poseTarget.props["Neck.quaternion"]), U.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6150
6150
|
const i = new f.Vector3().subVectors(e, ie).normalize(), n = Math.atan2(i.x, i.z), s = Math.asin(-i.y);
|
|
6151
6151
|
M.set(s, n, 0, "YXZ");
|
|
6152
|
-
const r = new f.Quaternion().setFromEuler(M),
|
|
6153
|
-
M.setFromQuaternion(
|
|
6154
|
-
let a = M.x / (40 / 24) + 0.2,
|
|
6152
|
+
const r = new f.Quaternion().setFromEuler(M), u = new f.Quaternion().copy(r).multiply(U.clone().invert());
|
|
6153
|
+
M.setFromQuaternion(u, "YXZ");
|
|
6154
|
+
let a = M.x / (40 / 24) + 0.2, h = M.y / (9 / 4), l = Math.min(0.6, Math.max(-0.3, a)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6155
6155
|
if (t) {
|
|
6156
6156
|
let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6157
6157
|
y !== -1 && this.animQueue.splice(y, 1);
|
|
@@ -6185,21 +6185,21 @@ class Te {
|
|
|
6185
6185
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6186
6186
|
const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), r = new f.Vector3().addVectors(s, o).divideScalar(2);
|
|
6187
6187
|
r.project(this.camera);
|
|
6188
|
-
let
|
|
6189
|
-
t === null && (t =
|
|
6190
|
-
let
|
|
6188
|
+
let u = (r.x + 1) / 2 * n.width + n.left, a = -(r.y - 1) / 2 * n.height + n.top;
|
|
6189
|
+
t === null && (t = u), e === null && (e = a), U.copy(this.armature.quaternion), U.multiply(this.poseTarget.props["Hips.quaternion"]), U.multiply(this.poseTarget.props["Spine.quaternion"]), U.multiply(this.poseTarget.props["Spine1.quaternion"]), U.multiply(this.poseTarget.props["Spine2.quaternion"]), U.multiply(this.poseTarget.props["Neck.quaternion"]), U.multiply(this.poseTarget.props["Head.quaternion"]), M.setFromQuaternion(U);
|
|
6190
|
+
let h = M.x / (40 / 24), l = M.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), y = Math.max(window.innerHeight - a, a), x = this.convertRange(e, [a - y, a + y], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - l + d;
|
|
6191
6191
|
x = Math.min(0.6, Math.max(-0.3, x)), I = Math.min(0.8, Math.max(-0.8, I));
|
|
6192
|
-
let
|
|
6192
|
+
let F = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6193
6193
|
if (i) {
|
|
6194
|
-
let
|
|
6195
|
-
|
|
6196
|
-
const
|
|
6194
|
+
let z = this.animQueue.findIndex((R) => R.template.name === "lookat");
|
|
6195
|
+
z !== -1 && this.animQueue.splice(z, 1);
|
|
6196
|
+
const C = {
|
|
6197
6197
|
name: "lookat",
|
|
6198
6198
|
dt: [750, i],
|
|
6199
6199
|
vs: {
|
|
6200
|
-
bodyRotateX: [x +
|
|
6200
|
+
bodyRotateX: [x + F],
|
|
6201
6201
|
bodyRotateY: [I + p],
|
|
6202
|
-
eyesRotateX: [-3 *
|
|
6202
|
+
eyesRotateX: [-3 * F + 0.1],
|
|
6203
6203
|
eyesRotateY: [-5 * p],
|
|
6204
6204
|
browInnerUp: [[0, 0.7]],
|
|
6205
6205
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6208,7 +6208,7 @@ class Te {
|
|
|
6208
6208
|
headMove: [0]
|
|
6209
6209
|
}
|
|
6210
6210
|
};
|
|
6211
|
-
this.animQueue.push(this.animFactory(
|
|
6211
|
+
this.animQueue.push(this.animFactory(C));
|
|
6212
6212
|
}
|
|
6213
6213
|
}
|
|
6214
6214
|
/**
|
|
@@ -6226,10 +6226,10 @@ class Te {
|
|
|
6226
6226
|
s.setFromCamera(n, this.camera);
|
|
6227
6227
|
const o = s.intersectObject(this.armature);
|
|
6228
6228
|
if (o.length > 0) {
|
|
6229
|
-
const r = o[0].point,
|
|
6230
|
-
this.objectLeftArm.getWorldPosition(
|
|
6231
|
-
const
|
|
6232
|
-
|
|
6229
|
+
const r = o[0].point, u = new f.Vector3(), a = new f.Vector3();
|
|
6230
|
+
this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(a);
|
|
6231
|
+
const h = u.distanceToSquared(r), l = a.distanceToSquared(r);
|
|
6232
|
+
h < l ? (this.ikSolve({
|
|
6233
6233
|
iterations: 20,
|
|
6234
6234
|
root: "LeftShoulder",
|
|
6235
6235
|
effector: "LeftHandMiddle1",
|
|
@@ -6250,8 +6250,8 @@ class Te {
|
|
|
6250
6250
|
}, r, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6251
6251
|
} else
|
|
6252
6252
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((r) => {
|
|
6253
|
-
let
|
|
6254
|
-
this.poseTarget.props[
|
|
6253
|
+
let u = r + ".quaternion";
|
|
6254
|
+
this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
|
|
6255
6255
|
});
|
|
6256
6256
|
return o.length > 0;
|
|
6257
6257
|
}
|
|
@@ -6370,21 +6370,21 @@ class Te {
|
|
|
6370
6370
|
async playAnimation(t, e = null, i = 10, n = 0, s = 0.01, o = !1) {
|
|
6371
6371
|
if (!this.armature) return;
|
|
6372
6372
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6373
|
-
let r = this.animClips.find((
|
|
6373
|
+
let r = this.animClips.find((u) => u.url === t + "-" + n);
|
|
6374
6374
|
if (r) {
|
|
6375
|
-
let
|
|
6376
|
-
|
|
6375
|
+
let u = this.animQueue.find((l) => l.template.name === "pose");
|
|
6376
|
+
u && (u.ts[0] = 1 / 0), Object.entries(r.pose.props).forEach((l) => {
|
|
6377
6377
|
this.poseBase.props[l[0]] = l[1].clone(), this.poseTarget.props[l[0]] = l[1].clone(), this.poseTarget.props[l[0]].t = 0, this.poseTarget.props[l[0]].d = 1e3;
|
|
6378
6378
|
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6379
|
-
const a = Math.ceil(i / r.clip.duration),
|
|
6380
|
-
|
|
6379
|
+
const a = Math.ceil(i / r.clip.duration), h = this.mixer.clipAction(r.clip);
|
|
6380
|
+
h.setLoop(f.LoopRepeat, a), h.clampWhenFinished = !0, this.currentFBXAction = h;
|
|
6381
6381
|
try {
|
|
6382
|
-
|
|
6382
|
+
h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
|
|
6383
6383
|
} catch (l) {
|
|
6384
6384
|
console.warn("FBX animation failed to start:", l), this.stopAnimation();
|
|
6385
6385
|
return;
|
|
6386
6386
|
}
|
|
6387
|
-
if (
|
|
6387
|
+
if (h.getClip().tracks.length === 0) {
|
|
6388
6388
|
console.warn("FBX animation has no valid tracks, stopping"), this.stopAnimation();
|
|
6389
6389
|
return;
|
|
6390
6390
|
}
|
|
@@ -6403,10 +6403,10 @@ class Te {
|
|
|
6403
6403
|
} catch (c) {
|
|
6404
6404
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
|
|
6405
6405
|
}
|
|
6406
|
-
const
|
|
6406
|
+
const h = new ve();
|
|
6407
6407
|
let l;
|
|
6408
6408
|
try {
|
|
6409
|
-
l = await
|
|
6409
|
+
l = await h.loadAsync(t, e);
|
|
6410
6410
|
} catch (c) {
|
|
6411
6411
|
console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
|
|
6412
6412
|
message: c.message,
|
|
@@ -6472,25 +6472,25 @@ class Te {
|
|
|
6472
6472
|
if (!this.armature) return;
|
|
6473
6473
|
let o = this.poseTemplates[t];
|
|
6474
6474
|
if (!o) {
|
|
6475
|
-
const r = this.animPoses.find((
|
|
6475
|
+
const r = this.animPoses.find((u) => u.url === t + "-" + n);
|
|
6476
6476
|
r && (o = r.pose);
|
|
6477
6477
|
}
|
|
6478
6478
|
if (o) {
|
|
6479
6479
|
this.poseName = t, this.mixer = null;
|
|
6480
|
-
let r = this.animQueue.find((
|
|
6480
|
+
let r = this.animQueue.find((u) => u.template.name === "pose");
|
|
6481
6481
|
r && (r.ts[0] = this.animClock + i * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6482
6482
|
} else {
|
|
6483
|
-
let
|
|
6484
|
-
if (
|
|
6485
|
-
let a =
|
|
6486
|
-
const
|
|
6483
|
+
let u = await new ve().loadAsync(t, e);
|
|
6484
|
+
if (u && u.animations && u.animations[n]) {
|
|
6485
|
+
let a = u.animations[n];
|
|
6486
|
+
const h = {};
|
|
6487
6487
|
a.tracks.forEach((c) => {
|
|
6488
6488
|
c.name = c.name.replaceAll("mixamorig", "");
|
|
6489
6489
|
const d = c.name.split(".");
|
|
6490
|
-
d[1] === "position" ?
|
|
6490
|
+
d[1] === "position" ? h[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
|
|
6491
6491
|
});
|
|
6492
|
-
const l = { props:
|
|
6493
|
-
|
|
6492
|
+
const l = { props: h };
|
|
6493
|
+
h["Hips.position"] && (h["Hips.position"].y < 0.5 ? l.lying = !0 : l.standing = !0), this.animPoses.push({
|
|
6494
6494
|
url: t + "-" + n,
|
|
6495
6495
|
pose: l
|
|
6496
6496
|
}), this.playPose(t, e, i, n, s);
|
|
@@ -6519,10 +6519,10 @@ class Te {
|
|
|
6519
6519
|
let s = this.gestureTemplates[t];
|
|
6520
6520
|
if (s) {
|
|
6521
6521
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6522
|
-
let r = this.animQueue.findIndex((
|
|
6523
|
-
r !== -1 && (this.animQueue[r].ts = this.animQueue[r].ts.map((
|
|
6524
|
-
for (let [
|
|
6525
|
-
a.t = this.animClock, a.d = n, this.poseTarget.props.hasOwnProperty(
|
|
6522
|
+
let r = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
|
|
6523
|
+
r !== -1 && (this.animQueue[r].ts = this.animQueue[r].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), i && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
|
|
6524
|
+
for (let [u, a] of Object.entries(this.gesture))
|
|
6525
|
+
a.t = this.animClock, a.d = n, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(a), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = n);
|
|
6526
6526
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, n), 1e3 * e));
|
|
6527
6527
|
}
|
|
6528
6528
|
let o = this.animEmojis[t];
|
|
@@ -6530,15 +6530,15 @@ class Te {
|
|
|
6530
6530
|
this.lookAtCamera(500);
|
|
6531
6531
|
const r = this.animFactory(o);
|
|
6532
6532
|
if (r.gesture = !0, e && Number.isFinite(e)) {
|
|
6533
|
-
const
|
|
6534
|
-
if (e * 1e3 -
|
|
6533
|
+
const u = r.ts[0], h = r.ts[r.ts.length - 1] - u;
|
|
6534
|
+
if (e * 1e3 - h > 0) {
|
|
6535
6535
|
const c = [];
|
|
6536
6536
|
for (let y = 1; y < r.ts.length; y++) c.push(r.ts[y] - r.ts[y - 1]);
|
|
6537
|
-
const d = o.template?.rescale || c.map((y) => y /
|
|
6538
|
-
r.ts = r.ts.map((y, x, I) => x === 0 ?
|
|
6537
|
+
const d = o.template?.rescale || c.map((y) => y / h), g = e * 1e3 - h;
|
|
6538
|
+
r.ts = r.ts.map((y, x, I) => x === 0 ? u : I[x - 1] + c[x - 1] + d[x - 1] * g);
|
|
6539
6539
|
} else {
|
|
6540
|
-
const c = e * 1e3 /
|
|
6541
|
-
r.ts = r.ts.map((d) =>
|
|
6540
|
+
const c = e * 1e3 / h;
|
|
6541
|
+
r.ts = r.ts.map((d) => u + c * (d - u));
|
|
6542
6542
|
}
|
|
6543
6543
|
}
|
|
6544
6544
|
this.animQueue.push(r);
|
|
@@ -6568,7 +6568,7 @@ class Te {
|
|
|
6568
6568
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6569
6569
|
*/
|
|
6570
6570
|
ikSolve(t, e = null, i = !1, n = null) {
|
|
6571
|
-
const s = new f.Vector3(), o = new f.Vector3(), r = new f.Vector3(),
|
|
6571
|
+
const s = new f.Vector3(), o = new f.Vector3(), r = new f.Vector3(), u = new f.Vector3(), a = new f.Quaternion(), h = new f.Vector3(), l = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
|
|
6572
6572
|
d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && i && e.applyQuaternion(this.armature.quaternion).add(d.position);
|
|
6573
6573
|
const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
|
|
6574
6574
|
y.forEach((I) => {
|
|
@@ -6577,12 +6577,12 @@ class Te {
|
|
|
6577
6577
|
const x = t.iterations || 10;
|
|
6578
6578
|
if (e)
|
|
6579
6579
|
for (let I = 0; I < x; I++) {
|
|
6580
|
-
let
|
|
6581
|
-
for (let p = 0,
|
|
6582
|
-
const
|
|
6583
|
-
|
|
6584
|
-
let
|
|
6585
|
-
|
|
6580
|
+
let F = !1;
|
|
6581
|
+
for (let p = 0, z = y.length; p < z; p++) {
|
|
6582
|
+
const C = y[p].bone;
|
|
6583
|
+
C.matrixWorld.decompose(u, a, h), a.invert(), o.setFromMatrixPosition(g.matrixWorld), r.subVectors(o, u), r.applyQuaternion(a), r.normalize(), s.subVectors(e, u), s.applyQuaternion(a), s.normalize();
|
|
6584
|
+
let R = s.dot(r);
|
|
6585
|
+
R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (y[p].minAngle !== void 0 && R < y[p].minAngle && (R = y[p].minAngle), y[p].maxAngle !== void 0 && R > y[p].maxAngle && (R = y[p].maxAngle), l.crossVectors(r, s), l.normalize(), U.setFromAxisAngle(l, R), C.quaternion.multiply(U), C.rotation.setFromVector3(c.setFromEuler(C.rotation).clamp(new f.Vector3(
|
|
6586
6586
|
y[p].minx !== void 0 ? y[p].minx : -1 / 0,
|
|
6587
6587
|
y[p].miny !== void 0 ? y[p].miny : -1 / 0,
|
|
6588
6588
|
y[p].minz !== void 0 ? y[p].minz : -1 / 0
|
|
@@ -6590,9 +6590,9 @@ class Te {
|
|
|
6590
6590
|
y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
|
|
6591
6591
|
y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
|
|
6592
6592
|
y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
|
|
6593
|
-
))),
|
|
6593
|
+
))), C.updateMatrixWorld(!0), F = !0);
|
|
6594
6594
|
}
|
|
6595
|
-
if (!
|
|
6595
|
+
if (!F) break;
|
|
6596
6596
|
}
|
|
6597
6597
|
n && y.forEach((I) => {
|
|
6598
6598
|
this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = n;
|
|
@@ -6625,7 +6625,7 @@ const le = {
|
|
|
6625
6625
|
josh: "VR6AewLTigWG4xSOukaG"
|
|
6626
6626
|
// Male, American
|
|
6627
6627
|
}
|
|
6628
|
-
},
|
|
6628
|
+
}, Se = {
|
|
6629
6629
|
defaultVoice: "aura-2-thalia-en",
|
|
6630
6630
|
// Thalia (Female, English)
|
|
6631
6631
|
voices: {
|
|
@@ -6645,7 +6645,7 @@ const le = {
|
|
|
6645
6645
|
// Male, English - Powerful
|
|
6646
6646
|
}
|
|
6647
6647
|
};
|
|
6648
|
-
function
|
|
6648
|
+
function xe() {
|
|
6649
6649
|
return {
|
|
6650
6650
|
service: "elevenlabs",
|
|
6651
6651
|
endpoint: le.endpoint,
|
|
@@ -6654,17 +6654,17 @@ function Ie() {
|
|
|
6654
6654
|
voices: le.voices
|
|
6655
6655
|
};
|
|
6656
6656
|
}
|
|
6657
|
-
function
|
|
6658
|
-
const
|
|
6659
|
-
return Object.entries(
|
|
6657
|
+
function mt() {
|
|
6658
|
+
const N = xe(), t = [];
|
|
6659
|
+
return Object.entries(N.voices).forEach(([e, i]) => {
|
|
6660
6660
|
t.push({
|
|
6661
6661
|
value: i,
|
|
6662
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6662
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${N.service})`
|
|
6663
6663
|
});
|
|
6664
6664
|
}), t;
|
|
6665
6665
|
}
|
|
6666
|
-
const
|
|
6667
|
-
avatarUrl:
|
|
6666
|
+
const ze = ye(({
|
|
6667
|
+
avatarUrl: N = "/avatars/brunette.glb",
|
|
6668
6668
|
avatarBody: t = "F",
|
|
6669
6669
|
mood: e = "neutral",
|
|
6670
6670
|
ttsLang: i = "en",
|
|
@@ -6672,9 +6672,9 @@ const Me = Re(({
|
|
|
6672
6672
|
ttsVoice: s = null,
|
|
6673
6673
|
ttsApiKey: o = null,
|
|
6674
6674
|
bodyMovement: r = "idle",
|
|
6675
|
-
movementIntensity:
|
|
6675
|
+
movementIntensity: u = 0.5,
|
|
6676
6676
|
showFullAvatar: a = !0,
|
|
6677
|
-
cameraView:
|
|
6677
|
+
cameraView: h = "upper",
|
|
6678
6678
|
onReady: l = () => {
|
|
6679
6679
|
},
|
|
6680
6680
|
onLoading: c = () => {
|
|
@@ -6685,202 +6685,183 @@ const Me = Re(({
|
|
|
6685
6685
|
style: y = {},
|
|
6686
6686
|
animations: x = {}
|
|
6687
6687
|
}, I) => {
|
|
6688
|
-
const
|
|
6688
|
+
const F = Z(null), p = Z(null), z = Z(a), [C, R] = he(!0), [W, D] = he(null), [j, ae] = he(!1);
|
|
6689
6689
|
ue(() => {
|
|
6690
|
-
|
|
6690
|
+
z.current = a;
|
|
6691
6691
|
}, [a]);
|
|
6692
|
-
const
|
|
6693
|
-
let
|
|
6694
|
-
P === "browser" ?
|
|
6692
|
+
const S = xe(), P = n || S.service;
|
|
6693
|
+
let O;
|
|
6694
|
+
P === "browser" ? O = {
|
|
6695
6695
|
service: "browser",
|
|
6696
6696
|
endpoint: "",
|
|
6697
6697
|
apiKey: null,
|
|
6698
6698
|
defaultVoice: "Google US English"
|
|
6699
|
-
} : P === "elevenlabs" ?
|
|
6699
|
+
} : P === "elevenlabs" ? O = {
|
|
6700
6700
|
service: "elevenlabs",
|
|
6701
6701
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6702
|
-
apiKey: o ||
|
|
6703
|
-
defaultVoice: s ||
|
|
6704
|
-
voices:
|
|
6705
|
-
} : P === "deepgram" ?
|
|
6702
|
+
apiKey: o || S.apiKey,
|
|
6703
|
+
defaultVoice: s || S.defaultVoice || le.defaultVoice,
|
|
6704
|
+
voices: S.voices || le.voices
|
|
6705
|
+
} : P === "deepgram" ? O = {
|
|
6706
6706
|
service: "deepgram",
|
|
6707
6707
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6708
|
-
apiKey: o ||
|
|
6709
|
-
defaultVoice: s ||
|
|
6710
|
-
voices:
|
|
6711
|
-
} :
|
|
6712
|
-
...
|
|
6708
|
+
apiKey: o || S.apiKey,
|
|
6709
|
+
defaultVoice: s || S.defaultVoice || Se.defaultVoice,
|
|
6710
|
+
voices: S.voices || Se.voices
|
|
6711
|
+
} : O = {
|
|
6712
|
+
...S,
|
|
6713
6713
|
// Override API key if provided via props
|
|
6714
|
-
apiKey: o !== null ? o :
|
|
6714
|
+
apiKey: o !== null ? o : S.apiKey
|
|
6715
6715
|
};
|
|
6716
|
-
const
|
|
6717
|
-
url:
|
|
6716
|
+
const V = {
|
|
6717
|
+
url: N,
|
|
6718
6718
|
body: t,
|
|
6719
6719
|
avatarMood: e,
|
|
6720
6720
|
ttsLang: P === "browser" ? "en-US" : i,
|
|
6721
|
-
ttsVoice: s ||
|
|
6721
|
+
ttsVoice: s || O.defaultVoice,
|
|
6722
6722
|
lipsyncLang: "en",
|
|
6723
6723
|
showFullAvatar: a,
|
|
6724
6724
|
bodyMovement: r,
|
|
6725
|
-
movementIntensity:
|
|
6725
|
+
movementIntensity: u
|
|
6726
6726
|
}, J = {
|
|
6727
|
-
ttsEndpoint:
|
|
6728
|
-
ttsApikey:
|
|
6727
|
+
ttsEndpoint: O.endpoint,
|
|
6728
|
+
ttsApikey: O.apiKey,
|
|
6729
6729
|
ttsService: P,
|
|
6730
6730
|
lipsyncModules: ["en"],
|
|
6731
|
-
cameraView:
|
|
6731
|
+
cameraView: h
|
|
6732
6732
|
}, $ = E(async () => {
|
|
6733
|
-
if (!(!
|
|
6733
|
+
if (!(!F.current || p.current))
|
|
6734
6734
|
try {
|
|
6735
|
-
if (
|
|
6736
|
-
if (
|
|
6737
|
-
const
|
|
6738
|
-
c(
|
|
6735
|
+
if (R(!0), D(null), p.current = new we(F.current, J), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(V, (G) => {
|
|
6736
|
+
if (G.lengthComputable) {
|
|
6737
|
+
const T = Math.min(100, Math.round(G.loaded / G.total * 100));
|
|
6738
|
+
c(T);
|
|
6739
6739
|
}
|
|
6740
|
-
}), await new Promise((
|
|
6741
|
-
const
|
|
6742
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6740
|
+
}), await new Promise((G) => {
|
|
6741
|
+
const T = () => {
|
|
6742
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? G() : setTimeout(T, 100);
|
|
6743
6743
|
};
|
|
6744
|
-
|
|
6744
|
+
T();
|
|
6745
6745
|
}), p.current && p.current.setShowFullAvatar)
|
|
6746
6746
|
try {
|
|
6747
6747
|
p.current.setShowFullAvatar(a);
|
|
6748
|
-
} catch (
|
|
6749
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6748
|
+
} catch (G) {
|
|
6749
|
+
console.warn("Error setting full body mode on initialization:", G);
|
|
6750
6750
|
}
|
|
6751
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()),
|
|
6752
|
-
const
|
|
6751
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), R(!1), ae(!0), l(p.current);
|
|
6752
|
+
const B = () => {
|
|
6753
6753
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6754
6754
|
};
|
|
6755
|
-
return document.addEventListener("visibilitychange",
|
|
6756
|
-
document.removeEventListener("visibilitychange",
|
|
6755
|
+
return document.addEventListener("visibilitychange", B), () => {
|
|
6756
|
+
document.removeEventListener("visibilitychange", B);
|
|
6757
6757
|
};
|
|
6758
|
-
} catch (
|
|
6759
|
-
console.error("Error initializing TalkingHead:",
|
|
6758
|
+
} catch (L) {
|
|
6759
|
+
console.error("Error initializing TalkingHead:", L), D(L.message || "Failed to initialize avatar"), R(!1), d(L);
|
|
6760
6760
|
}
|
|
6761
|
-
}, [
|
|
6761
|
+
}, [N, t, e, i, n, s, o, a, r, u, h]);
|
|
6762
6762
|
ue(() => ($(), () => {
|
|
6763
6763
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6764
6764
|
}), [$]), ue(() => {
|
|
6765
|
-
if (!
|
|
6766
|
-
const
|
|
6767
|
-
for (const
|
|
6765
|
+
if (!F.current || !p.current) return;
|
|
6766
|
+
const L = new ResizeObserver((G) => {
|
|
6767
|
+
for (const T of G)
|
|
6768
6768
|
p.current && p.current.onResize && p.current.onResize();
|
|
6769
6769
|
});
|
|
6770
|
-
|
|
6771
|
-
const
|
|
6770
|
+
L.observe(F.current);
|
|
6771
|
+
const B = () => {
|
|
6772
6772
|
p.current && p.current.onResize && p.current.onResize();
|
|
6773
6773
|
};
|
|
6774
|
-
return window.addEventListener("resize",
|
|
6775
|
-
|
|
6774
|
+
return window.addEventListener("resize", B), () => {
|
|
6775
|
+
L.disconnect(), window.removeEventListener("resize", B);
|
|
6776
6776
|
};
|
|
6777
6777
|
}, [j]);
|
|
6778
6778
|
const ne = E(async () => {
|
|
6779
6779
|
if (p.current && p.current.audioCtx)
|
|
6780
6780
|
try {
|
|
6781
6781
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6782
|
-
} catch (
|
|
6783
|
-
console.warn("Failed to resume audio context:",
|
|
6782
|
+
} catch (L) {
|
|
6783
|
+
console.warn("Failed to resume audio context:", L);
|
|
6784
6784
|
}
|
|
6785
|
-
}, []),
|
|
6785
|
+
}, []), ge = E(async (L, B = {}) => {
|
|
6786
6786
|
if (p.current && j)
|
|
6787
6787
|
try {
|
|
6788
6788
|
await ne();
|
|
6789
|
-
const
|
|
6790
|
-
...
|
|
6791
|
-
lipsyncLang:
|
|
6789
|
+
const G = {
|
|
6790
|
+
...B,
|
|
6791
|
+
lipsyncLang: B.lipsyncLang || V.lipsyncLang || "en"
|
|
6792
6792
|
};
|
|
6793
|
-
if (
|
|
6794
|
-
const
|
|
6795
|
-
let
|
|
6796
|
-
const
|
|
6797
|
-
let
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
clearInterval(xe);
|
|
6803
|
-
try {
|
|
6804
|
-
F.onSpeechEnd();
|
|
6805
|
-
} catch (me) {
|
|
6806
|
-
console.error("Error in onSpeechEnd callback:", me);
|
|
6807
|
-
}
|
|
6808
|
-
return;
|
|
6809
|
-
}
|
|
6810
|
-
if (Ae * 50 > Pe) {
|
|
6811
|
-
if (clearInterval(xe), w && w.isSpeaking)
|
|
6812
|
-
de = !0, Q = setInterval(Le, 50);
|
|
6813
|
-
else if (w && !w.isSpeaking && ce && (!w.audioPlaylist || w.audioPlaylist.length === 0) && (!w.isAudioPlaying || w.isAudioPlaying === !1))
|
|
6793
|
+
if (B.onSpeechEnd && p.current) {
|
|
6794
|
+
const T = p.current;
|
|
6795
|
+
let _ = null, re = 0;
|
|
6796
|
+
const be = 1200;
|
|
6797
|
+
let de = !1;
|
|
6798
|
+
_ = setInterval(() => {
|
|
6799
|
+
if (re++, re > be) {
|
|
6800
|
+
if (_ && (clearInterval(_), _ = null), !de) {
|
|
6801
|
+
de = !0;
|
|
6814
6802
|
try {
|
|
6815
|
-
|
|
6816
|
-
} catch (
|
|
6817
|
-
console.error("Error in onSpeechEnd callback:",
|
|
6803
|
+
B.onSpeechEnd();
|
|
6804
|
+
} catch (Re) {
|
|
6805
|
+
console.error("Error in onSpeechEnd callback (timeout):", Re);
|
|
6818
6806
|
}
|
|
6819
|
-
}
|
|
6820
|
-
}, 50), Le = () => {
|
|
6821
|
-
if (re++, re > Fe) {
|
|
6822
|
-
Q && (clearInterval(Q), Q = null);
|
|
6823
|
-
try {
|
|
6824
|
-
F.onSpeechEnd();
|
|
6825
|
-
} catch (be) {
|
|
6826
|
-
console.error("Error in onSpeechEnd callback:", be);
|
|
6827
6807
|
}
|
|
6828
6808
|
return;
|
|
6829
6809
|
}
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6810
|
+
const He = !T.speechQueue || T.speechQueue.length === 0, Te = !T.audioPlaylist || T.audioPlaylist.length === 0;
|
|
6811
|
+
T && T.isSpeaking === !1 && He && Te && T.isAudioPlaying === !1 && !de && setTimeout(() => {
|
|
6812
|
+
if (T && T.isSpeaking === !1 && (!T.speechQueue || T.speechQueue.length === 0) && (!T.audioPlaylist || T.audioPlaylist.length === 0) && T.isAudioPlaying === !1 && !de) {
|
|
6813
|
+
de = !0, _ && (clearInterval(_), _ = null);
|
|
6814
|
+
try {
|
|
6815
|
+
B.onSpeechEnd();
|
|
6816
|
+
} catch (Me) {
|
|
6817
|
+
console.error("Error in onSpeechEnd callback:", Me);
|
|
6818
|
+
}
|
|
6838
6819
|
}
|
|
6839
|
-
},
|
|
6840
|
-
};
|
|
6820
|
+
}, 100);
|
|
6821
|
+
}, 100);
|
|
6841
6822
|
}
|
|
6842
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(
|
|
6843
|
-
await ne(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(
|
|
6823
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, G)) : setTimeout(async () => {
|
|
6824
|
+
await ne(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, G));
|
|
6844
6825
|
}, 100);
|
|
6845
|
-
} catch (
|
|
6846
|
-
console.error("Error speaking text:",
|
|
6826
|
+
} catch (G) {
|
|
6827
|
+
console.error("Error speaking text:", G), D(G.message || "Failed to speak text");
|
|
6847
6828
|
}
|
|
6848
|
-
}, [j, ne,
|
|
6829
|
+
}, [j, ne, V.lipsyncLang]), q = E(() => {
|
|
6849
6830
|
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1));
|
|
6850
|
-
}, []),
|
|
6851
|
-
p.current && p.current.setMood(
|
|
6852
|
-
}, []),
|
|
6853
|
-
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(
|
|
6854
|
-
}, []),
|
|
6831
|
+
}, []), v = E((L) => {
|
|
6832
|
+
p.current && p.current.setMood(L);
|
|
6833
|
+
}, []), b = E((L) => {
|
|
6834
|
+
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
6835
|
+
}, []), w = E((L, B = !1) => {
|
|
6855
6836
|
if (p.current && p.current.playAnimation) {
|
|
6856
|
-
if (x && x[
|
|
6837
|
+
if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
|
|
6857
6838
|
try {
|
|
6858
|
-
p.current.setShowFullAvatar(
|
|
6859
|
-
} catch (
|
|
6860
|
-
console.warn("Error setting full body mode:",
|
|
6839
|
+
p.current.setShowFullAvatar(z.current);
|
|
6840
|
+
} catch (T) {
|
|
6841
|
+
console.warn("Error setting full body mode:", T);
|
|
6861
6842
|
}
|
|
6862
|
-
if (
|
|
6843
|
+
if (L.includes("."))
|
|
6863
6844
|
try {
|
|
6864
|
-
p.current.playAnimation(
|
|
6865
|
-
} catch (
|
|
6866
|
-
console.warn(`Failed to play ${
|
|
6845
|
+
p.current.playAnimation(L, null, 10, 0, 0.01, B);
|
|
6846
|
+
} catch (T) {
|
|
6847
|
+
console.warn(`Failed to play ${L}:`, T);
|
|
6867
6848
|
try {
|
|
6868
6849
|
p.current.setBodyMovement("idle");
|
|
6869
|
-
} catch (
|
|
6870
|
-
console.warn("Fallback animation also failed:",
|
|
6850
|
+
} catch (_) {
|
|
6851
|
+
console.warn("Fallback animation also failed:", _);
|
|
6871
6852
|
}
|
|
6872
6853
|
}
|
|
6873
6854
|
else {
|
|
6874
|
-
const
|
|
6875
|
-
let
|
|
6876
|
-
for (const re of
|
|
6855
|
+
const T = [".fbx", ".glb", ".gltf"];
|
|
6856
|
+
let _ = !1;
|
|
6857
|
+
for (const re of T)
|
|
6877
6858
|
try {
|
|
6878
|
-
p.current.playAnimation(
|
|
6859
|
+
p.current.playAnimation(L + re, null, 10, 0, 0.01, B), _ = !0;
|
|
6879
6860
|
break;
|
|
6880
6861
|
} catch {
|
|
6881
6862
|
}
|
|
6882
|
-
if (!
|
|
6883
|
-
console.warn("Animation not found:",
|
|
6863
|
+
if (!_) {
|
|
6864
|
+
console.warn("Animation not found:", L);
|
|
6884
6865
|
try {
|
|
6885
6866
|
p.current.setBodyMovement("idle");
|
|
6886
6867
|
} catch (re) {
|
|
@@ -6889,77 +6870,77 @@ const Me = Re(({
|
|
|
6889
6870
|
}
|
|
6890
6871
|
}
|
|
6891
6872
|
}
|
|
6892
|
-
}, [x]),
|
|
6873
|
+
}, [x]), H = E(() => {
|
|
6893
6874
|
p.current && p.current.onResize && p.current.onResize();
|
|
6894
6875
|
}, []);
|
|
6895
|
-
return
|
|
6896
|
-
speakText:
|
|
6897
|
-
stopSpeaking:
|
|
6876
|
+
return fe(I, () => ({
|
|
6877
|
+
speakText: ge,
|
|
6878
|
+
stopSpeaking: q,
|
|
6898
6879
|
resumeAudioContext: ne,
|
|
6899
|
-
setMood:
|
|
6900
|
-
setTimingAdjustment:
|
|
6901
|
-
playAnimation:
|
|
6880
|
+
setMood: v,
|
|
6881
|
+
setTimingAdjustment: b,
|
|
6882
|
+
playAnimation: w,
|
|
6902
6883
|
isReady: j,
|
|
6903
6884
|
talkingHead: p.current,
|
|
6904
|
-
handleResize:
|
|
6905
|
-
setBodyMovement: (
|
|
6885
|
+
handleResize: H,
|
|
6886
|
+
setBodyMovement: (L) => {
|
|
6906
6887
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
6907
6888
|
try {
|
|
6908
|
-
p.current.setShowFullAvatar(
|
|
6909
|
-
} catch (
|
|
6910
|
-
console.warn("Error setting body movement:",
|
|
6889
|
+
p.current.setShowFullAvatar(z.current), p.current.setBodyMovement(L);
|
|
6890
|
+
} catch (B) {
|
|
6891
|
+
console.warn("Error setting body movement:", B);
|
|
6911
6892
|
}
|
|
6912
6893
|
},
|
|
6913
|
-
setMovementIntensity: (
|
|
6894
|
+
setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
|
|
6914
6895
|
playRandomDance: () => {
|
|
6915
6896
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
6916
6897
|
try {
|
|
6917
|
-
p.current.setShowFullAvatar(
|
|
6918
|
-
} catch (
|
|
6919
|
-
console.warn("Error playing random dance:",
|
|
6898
|
+
p.current.setShowFullAvatar(z.current), p.current.playRandomDance();
|
|
6899
|
+
} catch (L) {
|
|
6900
|
+
console.warn("Error playing random dance:", L);
|
|
6920
6901
|
}
|
|
6921
6902
|
},
|
|
6922
|
-
playReaction: (
|
|
6903
|
+
playReaction: (L) => {
|
|
6923
6904
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
6924
6905
|
try {
|
|
6925
|
-
p.current.setShowFullAvatar(
|
|
6926
|
-
} catch (
|
|
6927
|
-
console.warn("Error playing reaction:",
|
|
6906
|
+
p.current.setShowFullAvatar(z.current), p.current.playReaction(L);
|
|
6907
|
+
} catch (B) {
|
|
6908
|
+
console.warn("Error playing reaction:", B);
|
|
6928
6909
|
}
|
|
6929
6910
|
},
|
|
6930
6911
|
playCelebration: () => {
|
|
6931
6912
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
6932
6913
|
try {
|
|
6933
|
-
p.current.setShowFullAvatar(
|
|
6934
|
-
} catch (
|
|
6935
|
-
console.warn("Error playing celebration:",
|
|
6914
|
+
p.current.setShowFullAvatar(z.current), p.current.playCelebration();
|
|
6915
|
+
} catch (L) {
|
|
6916
|
+
console.warn("Error playing celebration:", L);
|
|
6936
6917
|
}
|
|
6937
6918
|
},
|
|
6938
|
-
setShowFullAvatar: (
|
|
6919
|
+
setShowFullAvatar: (L) => {
|
|
6939
6920
|
if (p.current && p.current.setShowFullAvatar)
|
|
6940
6921
|
try {
|
|
6941
|
-
|
|
6942
|
-
} catch (
|
|
6943
|
-
console.warn("Error setting showFullAvatar:",
|
|
6922
|
+
z.current = L, p.current.setShowFullAvatar(L);
|
|
6923
|
+
} catch (B) {
|
|
6924
|
+
console.warn("Error setting showFullAvatar:", B);
|
|
6944
6925
|
}
|
|
6945
6926
|
},
|
|
6946
6927
|
lockAvatarPosition: () => {
|
|
6947
6928
|
if (p.current && p.current.lockAvatarPosition)
|
|
6948
6929
|
try {
|
|
6949
6930
|
p.current.lockAvatarPosition();
|
|
6950
|
-
} catch (
|
|
6951
|
-
console.warn("Error locking avatar position:",
|
|
6931
|
+
} catch (L) {
|
|
6932
|
+
console.warn("Error locking avatar position:", L);
|
|
6952
6933
|
}
|
|
6953
6934
|
},
|
|
6954
6935
|
unlockAvatarPosition: () => {
|
|
6955
6936
|
if (p.current && p.current.unlockAvatarPosition)
|
|
6956
6937
|
try {
|
|
6957
6938
|
p.current.unlockAvatarPosition();
|
|
6958
|
-
} catch (
|
|
6959
|
-
console.warn("Error unlocking avatar position:",
|
|
6939
|
+
} catch (L) {
|
|
6940
|
+
console.warn("Error unlocking avatar position:", L);
|
|
6960
6941
|
}
|
|
6961
6942
|
}
|
|
6962
|
-
})), /* @__PURE__ */
|
|
6943
|
+
})), /* @__PURE__ */ ke(
|
|
6963
6944
|
"div",
|
|
6964
6945
|
{
|
|
6965
6946
|
className: `talking-head-avatar ${g}`,
|
|
@@ -6973,7 +6954,7 @@ const Me = Re(({
|
|
|
6973
6954
|
/* @__PURE__ */ se(
|
|
6974
6955
|
"div",
|
|
6975
6956
|
{
|
|
6976
|
-
ref:
|
|
6957
|
+
ref: F,
|
|
6977
6958
|
className: "talking-head-viewer",
|
|
6978
6959
|
style: {
|
|
6979
6960
|
width: "100%",
|
|
@@ -6982,7 +6963,7 @@ const Me = Re(({
|
|
|
6982
6963
|
}
|
|
6983
6964
|
}
|
|
6984
6965
|
),
|
|
6985
|
-
|
|
6966
|
+
C && /* @__PURE__ */ se("div", { className: "loading-overlay", style: {
|
|
6986
6967
|
position: "absolute",
|
|
6987
6968
|
top: "50%",
|
|
6988
6969
|
left: "50%",
|
|
@@ -6991,7 +6972,7 @@ const Me = Re(({
|
|
|
6991
6972
|
fontSize: "18px",
|
|
6992
6973
|
zIndex: 10
|
|
6993
6974
|
}, children: "Loading avatar..." }),
|
|
6994
|
-
|
|
6975
|
+
W && /* @__PURE__ */ se("div", { className: "error-overlay", style: {
|
|
6995
6976
|
position: "absolute",
|
|
6996
6977
|
top: "50%",
|
|
6997
6978
|
left: "50%",
|
|
@@ -7002,14 +6983,14 @@ const Me = Re(({
|
|
|
7002
6983
|
zIndex: 10,
|
|
7003
6984
|
padding: "20px",
|
|
7004
6985
|
borderRadius: "8px"
|
|
7005
|
-
}, children:
|
|
6986
|
+
}, children: W })
|
|
7006
6987
|
]
|
|
7007
6988
|
}
|
|
7008
6989
|
);
|
|
7009
6990
|
});
|
|
7010
|
-
|
|
7011
|
-
const
|
|
7012
|
-
text:
|
|
6991
|
+
ze.displayName = "TalkingHeadAvatar";
|
|
6992
|
+
const it = ye(({
|
|
6993
|
+
text: N = "Hello! I'm a talking avatar. How are you today?",
|
|
7013
6994
|
onLoading: t = () => {
|
|
7014
6995
|
},
|
|
7015
6996
|
onError: e = () => {
|
|
@@ -7020,7 +7001,7 @@ const st = Re(({
|
|
|
7020
7001
|
style: s = {},
|
|
7021
7002
|
avatarConfig: o = {}
|
|
7022
7003
|
}, r) => {
|
|
7023
|
-
const
|
|
7004
|
+
const u = Z(null), a = Z(null), [h, l] = he(!0), [c, d] = he(null), [g, y] = he(!1), x = xe(), I = o.ttsService || x.service, F = I === "browser" ? {
|
|
7024
7005
|
endpoint: "",
|
|
7025
7006
|
apiKey: null,
|
|
7026
7007
|
defaultVoice: "Google US English"
|
|
@@ -7036,7 +7017,7 @@ const st = Re(({
|
|
|
7036
7017
|
body: "F",
|
|
7037
7018
|
avatarMood: "neutral",
|
|
7038
7019
|
ttsLang: I === "browser" ? "en-US" : "en",
|
|
7039
|
-
ttsVoice: o.ttsVoice ||
|
|
7020
|
+
ttsVoice: o.ttsVoice || F.defaultVoice,
|
|
7040
7021
|
lipsyncLang: "en",
|
|
7041
7022
|
// English lip-sync
|
|
7042
7023
|
showFullAvatar: !0,
|
|
@@ -7044,36 +7025,36 @@ const st = Re(({
|
|
|
7044
7025
|
bodyMovement: "idle",
|
|
7045
7026
|
movementIntensity: 0.5,
|
|
7046
7027
|
...o
|
|
7047
|
-
},
|
|
7048
|
-
ttsEndpoint:
|
|
7049
|
-
ttsApikey:
|
|
7028
|
+
}, z = {
|
|
7029
|
+
ttsEndpoint: F.endpoint,
|
|
7030
|
+
ttsApikey: F.apiKey,
|
|
7050
7031
|
ttsService: I,
|
|
7051
7032
|
lipsyncModules: ["en"],
|
|
7052
7033
|
cameraView: "upper"
|
|
7053
|
-
},
|
|
7054
|
-
if (!(!
|
|
7034
|
+
}, C = E(async () => {
|
|
7035
|
+
if (!(!u.current || a.current))
|
|
7055
7036
|
try {
|
|
7056
|
-
if (l(!0), d(null), a.current = new
|
|
7057
|
-
if (
|
|
7058
|
-
const
|
|
7059
|
-
t(
|
|
7037
|
+
if (l(!0), d(null), a.current = new we(u.current, z), await a.current.showAvatar(p, (O) => {
|
|
7038
|
+
if (O.lengthComputable) {
|
|
7039
|
+
const V = Math.min(100, Math.round(O.loaded / O.total * 100));
|
|
7040
|
+
t(V);
|
|
7060
7041
|
}
|
|
7061
7042
|
}), a.current.morphs && a.current.morphs.length > 0) {
|
|
7062
|
-
const
|
|
7063
|
-
console.log("Available morph targets:", Object.keys(
|
|
7064
|
-
const
|
|
7065
|
-
console.log("Viseme morph targets found:",
|
|
7043
|
+
const O = a.current.morphs[0].morphTargetDictionary;
|
|
7044
|
+
console.log("Available morph targets:", Object.keys(O));
|
|
7045
|
+
const V = Object.keys(O).filter((J) => J.startsWith("viseme_"));
|
|
7046
|
+
console.log("Viseme morph targets found:", V), V.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
|
|
7066
7047
|
}
|
|
7067
|
-
if (await new Promise((
|
|
7068
|
-
const
|
|
7069
|
-
a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)),
|
|
7048
|
+
if (await new Promise((O) => {
|
|
7049
|
+
const V = () => {
|
|
7050
|
+
a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), O()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(V, 100));
|
|
7070
7051
|
};
|
|
7071
|
-
|
|
7052
|
+
V();
|
|
7072
7053
|
}), a.current && a.current.setShowFullAvatar)
|
|
7073
7054
|
try {
|
|
7074
7055
|
a.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7075
|
-
} catch (
|
|
7076
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7056
|
+
} catch (O) {
|
|
7057
|
+
console.warn("Error setting full body mode on initialization:", O);
|
|
7077
7058
|
}
|
|
7078
7059
|
l(!1), y(!0), i(a.current);
|
|
7079
7060
|
const P = () => {
|
|
@@ -7082,43 +7063,43 @@ const st = Re(({
|
|
|
7082
7063
|
return document.addEventListener("visibilitychange", P), () => {
|
|
7083
7064
|
document.removeEventListener("visibilitychange", P);
|
|
7084
7065
|
};
|
|
7085
|
-
} catch (
|
|
7086
|
-
console.error("Error initializing TalkingHead:",
|
|
7066
|
+
} catch (S) {
|
|
7067
|
+
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), l(!1), e(S);
|
|
7087
7068
|
}
|
|
7088
7069
|
}, []);
|
|
7089
|
-
ue(() => (
|
|
7070
|
+
ue(() => (C(), () => {
|
|
7090
7071
|
a.current && (a.current.stop(), a.current.dispose(), a.current = null);
|
|
7091
|
-
}), [
|
|
7092
|
-
const
|
|
7072
|
+
}), [C]);
|
|
7073
|
+
const R = E((S) => {
|
|
7093
7074
|
if (a.current && g)
|
|
7094
7075
|
try {
|
|
7095
|
-
console.log("Speaking text:",
|
|
7096
|
-
a.current && a.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(
|
|
7076
|
+
console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", a.current), a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7077
|
+
a.current && a.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
|
|
7097
7078
|
}, 500));
|
|
7098
7079
|
} catch (P) {
|
|
7099
7080
|
console.error("Error speaking text:", P), d(P.message || "Failed to speak text");
|
|
7100
7081
|
}
|
|
7101
7082
|
else
|
|
7102
7083
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!a.current);
|
|
7103
|
-
}, [g, p]),
|
|
7084
|
+
}, [g, p]), W = E(() => {
|
|
7104
7085
|
a.current && (a.current.stopSpeaking(), a.current.setSlowdownRate && (a.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7105
|
-
}, []),
|
|
7106
|
-
a.current && a.current.setMood(
|
|
7107
|
-
}, []), j = E((
|
|
7108
|
-
a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(
|
|
7109
|
-
}, []), ae = E((
|
|
7086
|
+
}, []), D = E((S) => {
|
|
7087
|
+
a.current && a.current.setMood(S);
|
|
7088
|
+
}, []), j = E((S) => {
|
|
7089
|
+
a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
7090
|
+
}, []), ae = E((S, P = !1) => {
|
|
7110
7091
|
if (a.current && a.current.playAnimation) {
|
|
7111
7092
|
if (a.current.setShowFullAvatar)
|
|
7112
7093
|
try {
|
|
7113
7094
|
a.current.setShowFullAvatar(!0);
|
|
7114
|
-
} catch (
|
|
7115
|
-
console.warn("Error setting full body mode:",
|
|
7095
|
+
} catch (V) {
|
|
7096
|
+
console.warn("Error setting full body mode:", V);
|
|
7116
7097
|
}
|
|
7117
|
-
if (
|
|
7098
|
+
if (S.includes("."))
|
|
7118
7099
|
try {
|
|
7119
|
-
a.current.playAnimation(
|
|
7120
|
-
} catch (
|
|
7121
|
-
console.log(`Failed to play ${
|
|
7100
|
+
a.current.playAnimation(S, null, 10, 0, 0.01, P), console.log("Playing animation:", S);
|
|
7101
|
+
} catch (V) {
|
|
7102
|
+
console.log(`Failed to play ${S}:`, V);
|
|
7122
7103
|
try {
|
|
7123
7104
|
a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7124
7105
|
} catch (J) {
|
|
@@ -7126,17 +7107,17 @@ const st = Re(({
|
|
|
7126
7107
|
}
|
|
7127
7108
|
}
|
|
7128
7109
|
else {
|
|
7129
|
-
const
|
|
7110
|
+
const V = [".fbx", ".glb", ".gltf"];
|
|
7130
7111
|
let J = !1;
|
|
7131
|
-
for (const $ of
|
|
7112
|
+
for (const $ of V)
|
|
7132
7113
|
try {
|
|
7133
|
-
a.current.playAnimation(
|
|
7114
|
+
a.current.playAnimation(S + $, null, 10, 0, 0.01, P), console.log("Playing animation:", S + $), J = !0;
|
|
7134
7115
|
break;
|
|
7135
7116
|
} catch {
|
|
7136
|
-
console.log(`Failed to play ${
|
|
7117
|
+
console.log(`Failed to play ${S}${$}, trying next format...`);
|
|
7137
7118
|
}
|
|
7138
7119
|
if (!J) {
|
|
7139
|
-
console.warn("Animation system not available or animation not found:",
|
|
7120
|
+
console.warn("Animation system not available or animation not found:", S);
|
|
7140
7121
|
try {
|
|
7141
7122
|
a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7142
7123
|
} catch ($) {
|
|
@@ -7145,37 +7126,37 @@ const st = Re(({
|
|
|
7145
7126
|
}
|
|
7146
7127
|
}
|
|
7147
7128
|
} else
|
|
7148
|
-
console.warn("Animation system not available or animation not found:",
|
|
7129
|
+
console.warn("Animation system not available or animation not found:", S);
|
|
7149
7130
|
}, []);
|
|
7150
|
-
return
|
|
7151
|
-
speakText:
|
|
7152
|
-
stopSpeaking:
|
|
7153
|
-
setMood:
|
|
7131
|
+
return fe(r, () => ({
|
|
7132
|
+
speakText: R,
|
|
7133
|
+
stopSpeaking: W,
|
|
7134
|
+
setMood: D,
|
|
7154
7135
|
setTimingAdjustment: j,
|
|
7155
7136
|
playAnimation: ae,
|
|
7156
7137
|
isReady: g,
|
|
7157
7138
|
talkingHead: a.current,
|
|
7158
|
-
setBodyMovement: (
|
|
7139
|
+
setBodyMovement: (S) => {
|
|
7159
7140
|
if (a.current && a.current.setShowFullAvatar && a.current.setBodyMovement)
|
|
7160
7141
|
try {
|
|
7161
|
-
a.current.setShowFullAvatar(!0), a.current.setBodyMovement(
|
|
7142
|
+
a.current.setShowFullAvatar(!0), a.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
|
|
7162
7143
|
} catch (P) {
|
|
7163
7144
|
console.warn("Error setting body movement:", P);
|
|
7164
7145
|
}
|
|
7165
7146
|
},
|
|
7166
|
-
setMovementIntensity: (
|
|
7147
|
+
setMovementIntensity: (S) => a.current?.setMovementIntensity(S),
|
|
7167
7148
|
playRandomDance: () => {
|
|
7168
7149
|
if (a.current && a.current.setShowFullAvatar && a.current.playRandomDance)
|
|
7169
7150
|
try {
|
|
7170
7151
|
a.current.setShowFullAvatar(!0), a.current.playRandomDance(), console.log("Random dance played with full body mode");
|
|
7171
|
-
} catch (
|
|
7172
|
-
console.warn("Error playing random dance:",
|
|
7152
|
+
} catch (S) {
|
|
7153
|
+
console.warn("Error playing random dance:", S);
|
|
7173
7154
|
}
|
|
7174
7155
|
},
|
|
7175
|
-
playReaction: (
|
|
7156
|
+
playReaction: (S) => {
|
|
7176
7157
|
if (a.current && a.current.setShowFullAvatar && a.current.playReaction)
|
|
7177
7158
|
try {
|
|
7178
|
-
a.current.setShowFullAvatar(!0), a.current.playReaction(
|
|
7159
|
+
a.current.setShowFullAvatar(!0), a.current.playReaction(S), console.log("Reaction played with full body mode:", S);
|
|
7179
7160
|
} catch (P) {
|
|
7180
7161
|
console.warn("Error playing reaction:", P);
|
|
7181
7162
|
}
|
|
@@ -7184,14 +7165,14 @@ const st = Re(({
|
|
|
7184
7165
|
if (a.current && a.current.setShowFullAvatar && a.current.playCelebration)
|
|
7185
7166
|
try {
|
|
7186
7167
|
a.current.setShowFullAvatar(!0), a.current.playCelebration(), console.log("Celebration played with full body mode");
|
|
7187
|
-
} catch (
|
|
7188
|
-
console.warn("Error playing celebration:",
|
|
7168
|
+
} catch (S) {
|
|
7169
|
+
console.warn("Error playing celebration:", S);
|
|
7189
7170
|
}
|
|
7190
7171
|
},
|
|
7191
|
-
setShowFullAvatar: (
|
|
7172
|
+
setShowFullAvatar: (S) => {
|
|
7192
7173
|
if (a.current && a.current.setShowFullAvatar)
|
|
7193
7174
|
try {
|
|
7194
|
-
a.current.setShowFullAvatar(
|
|
7175
|
+
a.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
|
|
7195
7176
|
} catch (P) {
|
|
7196
7177
|
console.warn("Error setting showFullAvatar:", P);
|
|
7197
7178
|
}
|
|
@@ -7200,23 +7181,23 @@ const st = Re(({
|
|
|
7200
7181
|
if (a.current && a.current.lockAvatarPosition)
|
|
7201
7182
|
try {
|
|
7202
7183
|
a.current.lockAvatarPosition();
|
|
7203
|
-
} catch (
|
|
7204
|
-
console.warn("Error locking avatar position:",
|
|
7184
|
+
} catch (S) {
|
|
7185
|
+
console.warn("Error locking avatar position:", S);
|
|
7205
7186
|
}
|
|
7206
7187
|
},
|
|
7207
7188
|
unlockAvatarPosition: () => {
|
|
7208
7189
|
if (a.current && a.current.unlockAvatarPosition)
|
|
7209
7190
|
try {
|
|
7210
7191
|
a.current.unlockAvatarPosition();
|
|
7211
|
-
} catch (
|
|
7212
|
-
console.warn("Error unlocking avatar position:",
|
|
7192
|
+
} catch (S) {
|
|
7193
|
+
console.warn("Error unlocking avatar position:", S);
|
|
7213
7194
|
}
|
|
7214
7195
|
}
|
|
7215
|
-
})), /* @__PURE__ */
|
|
7196
|
+
})), /* @__PURE__ */ ke("div", { className: `talking-head-container ${n}`, style: s, children: [
|
|
7216
7197
|
/* @__PURE__ */ se(
|
|
7217
7198
|
"div",
|
|
7218
7199
|
{
|
|
7219
|
-
ref:
|
|
7200
|
+
ref: u,
|
|
7220
7201
|
className: "talking-head-viewer",
|
|
7221
7202
|
style: {
|
|
7222
7203
|
width: "100%",
|
|
@@ -7225,7 +7206,7 @@ const st = Re(({
|
|
|
7225
7206
|
}
|
|
7226
7207
|
}
|
|
7227
7208
|
),
|
|
7228
|
-
|
|
7209
|
+
h && /* @__PURE__ */ se("div", { className: "loading-overlay", style: {
|
|
7229
7210
|
position: "absolute",
|
|
7230
7211
|
top: "50%",
|
|
7231
7212
|
left: "50%",
|
|
@@ -7248,9 +7229,9 @@ const st = Re(({
|
|
|
7248
7229
|
}, children: c })
|
|
7249
7230
|
] });
|
|
7250
7231
|
});
|
|
7251
|
-
|
|
7252
|
-
const
|
|
7253
|
-
curriculumData:
|
|
7232
|
+
it.displayName = "TalkingHeadComponent";
|
|
7233
|
+
const nt = ye(({
|
|
7234
|
+
curriculumData: N = null,
|
|
7254
7235
|
avatarConfig: t = {},
|
|
7255
7236
|
animations: e = {},
|
|
7256
7237
|
onLessonStart: i = () => {
|
|
@@ -7263,9 +7244,9 @@ const at = Re(({
|
|
|
7263
7244
|
},
|
|
7264
7245
|
onCustomAction: r = () => {
|
|
7265
7246
|
},
|
|
7266
|
-
autoStart:
|
|
7247
|
+
autoStart: u = !1
|
|
7267
7248
|
}, a) => {
|
|
7268
|
-
const
|
|
7249
|
+
const h = Z(null), l = Z({
|
|
7269
7250
|
currentModuleIndex: 0,
|
|
7270
7251
|
currentLessonIndex: 0,
|
|
7271
7252
|
currentQuestionIndex: 0,
|
|
@@ -7275,18 +7256,18 @@ const at = Re(({
|
|
|
7275
7256
|
curriculumCompleted: !1,
|
|
7276
7257
|
score: 0,
|
|
7277
7258
|
totalQuestions: 0
|
|
7278
|
-
}), c =
|
|
7259
|
+
}), c = Z({
|
|
7279
7260
|
onLessonStart: i,
|
|
7280
7261
|
onLessonComplete: n,
|
|
7281
7262
|
onQuestionAnswer: s,
|
|
7282
7263
|
onCurriculumComplete: o,
|
|
7283
7264
|
onCustomAction: r
|
|
7284
|
-
}), d =
|
|
7265
|
+
}), d = Z(null), g = Z(null), y = Z(null), x = Z(null), I = Z(null), F = Z(null), p = Z(null), z = Z(N?.curriculum || {
|
|
7285
7266
|
title: "Default Curriculum",
|
|
7286
7267
|
description: "No curriculum data provided",
|
|
7287
7268
|
language: "en",
|
|
7288
7269
|
modules: []
|
|
7289
|
-
}),
|
|
7270
|
+
}), C = Z({
|
|
7290
7271
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7291
7272
|
avatarBody: t.avatarBody || "F",
|
|
7292
7273
|
mood: t.mood || "happy",
|
|
@@ -7309,12 +7290,12 @@ const at = Re(({
|
|
|
7309
7290
|
onCustomAction: r
|
|
7310
7291
|
};
|
|
7311
7292
|
}, [i, n, s, o, r]), ue(() => {
|
|
7312
|
-
|
|
7293
|
+
z.current = N?.curriculum || {
|
|
7313
7294
|
title: "Default Curriculum",
|
|
7314
7295
|
description: "No curriculum data provided",
|
|
7315
7296
|
language: "en",
|
|
7316
7297
|
modules: []
|
|
7317
|
-
},
|
|
7298
|
+
}, C.current = {
|
|
7318
7299
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7319
7300
|
avatarBody: t.avatarBody || "F",
|
|
7320
7301
|
mood: t.mood || "happy",
|
|
@@ -7328,34 +7309,34 @@ const at = Re(({
|
|
|
7328
7309
|
animations: e,
|
|
7329
7310
|
lipsyncLang: "en"
|
|
7330
7311
|
};
|
|
7331
|
-
}, [
|
|
7332
|
-
const
|
|
7312
|
+
}, [N, t, e]);
|
|
7313
|
+
const R = E(() => (z.current || { modules: [] }).modules[l.current.currentModuleIndex]?.lessons[l.current.currentLessonIndex], []), W = E(() => R()?.questions[l.current.currentQuestionIndex], [R]), D = E((v, b) => b.type === "multiple_choice" || b.type === "true_false" ? v === b.answer : b.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), j = E(() => {
|
|
7333
7314
|
l.current.lessonCompleted = !0, l.current.isQuestionMode = !1;
|
|
7334
|
-
const
|
|
7335
|
-
let
|
|
7336
|
-
if (l.current.totalQuestions > 0 ?
|
|
7315
|
+
const v = l.current.totalQuestions > 0 ? Math.round(l.current.score / l.current.totalQuestions * 100) : 100;
|
|
7316
|
+
let b = "Congratulations! You've completed this lesson";
|
|
7317
|
+
if (l.current.totalQuestions > 0 ? b += ` with a score of ${l.current.score} out of ${l.current.totalQuestions} (${v}%). ` : b += "! ", v >= 80 ? b += "Excellent work! You have a great understanding of this topic." : v >= 60 ? b += "Good job! You understand most of the concepts." : b += "Keep practicing! You're making progress.", c.current.onLessonComplete({
|
|
7337
7318
|
moduleIndex: l.current.currentModuleIndex,
|
|
7338
7319
|
lessonIndex: l.current.currentLessonIndex,
|
|
7339
7320
|
score: l.current.score,
|
|
7340
7321
|
totalQuestions: l.current.totalQuestions,
|
|
7341
|
-
percentage:
|
|
7322
|
+
percentage: v
|
|
7342
7323
|
}), c.current.onCustomAction({
|
|
7343
7324
|
type: "lessonComplete",
|
|
7344
7325
|
moduleIndex: l.current.currentModuleIndex,
|
|
7345
7326
|
lessonIndex: l.current.currentLessonIndex,
|
|
7346
7327
|
score: l.current.score,
|
|
7347
7328
|
totalQuestions: l.current.totalQuestions,
|
|
7348
|
-
percentage:
|
|
7349
|
-
}),
|
|
7350
|
-
if (
|
|
7329
|
+
percentage: v
|
|
7330
|
+
}), h.current) {
|
|
7331
|
+
if (h.current.setMood("happy"), e.lessonComplete)
|
|
7351
7332
|
try {
|
|
7352
|
-
|
|
7333
|
+
h.current.playAnimation(e.lessonComplete, !0);
|
|
7353
7334
|
} catch {
|
|
7354
|
-
|
|
7335
|
+
h.current.playCelebration();
|
|
7355
7336
|
}
|
|
7356
|
-
const
|
|
7357
|
-
|
|
7358
|
-
lipsyncLang:
|
|
7337
|
+
const w = z.current || { modules: [] }, H = w.modules[l.current.currentModuleIndex], L = l.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, B = l.current.currentModuleIndex < (w.modules?.length || 0) - 1, G = L || B, T = C.current || { lipsyncLang: "en" };
|
|
7338
|
+
h.current.speakText(b, {
|
|
7339
|
+
lipsyncLang: T.lipsyncLang,
|
|
7359
7340
|
onSpeechEnd: () => {
|
|
7360
7341
|
c.current.onCustomAction({
|
|
7361
7342
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7363,84 +7344,105 @@ const at = Re(({
|
|
|
7363
7344
|
lessonIndex: l.current.currentLessonIndex,
|
|
7364
7345
|
score: l.current.score,
|
|
7365
7346
|
totalQuestions: l.current.totalQuestions,
|
|
7366
|
-
percentage:
|
|
7367
|
-
hasNextLesson:
|
|
7347
|
+
percentage: v,
|
|
7348
|
+
hasNextLesson: G
|
|
7368
7349
|
});
|
|
7369
7350
|
}
|
|
7370
7351
|
});
|
|
7371
7352
|
}
|
|
7372
7353
|
}, [e.lessonComplete]), ae = E(() => {
|
|
7373
7354
|
l.current.curriculumCompleted = !0;
|
|
7374
|
-
const
|
|
7355
|
+
const v = z.current || { modules: [] };
|
|
7375
7356
|
if (c.current.onCurriculumComplete({
|
|
7376
|
-
modules:
|
|
7377
|
-
totalLessons:
|
|
7378
|
-
}),
|
|
7379
|
-
if (
|
|
7357
|
+
modules: v.modules.length,
|
|
7358
|
+
totalLessons: v.modules.reduce((b, w) => b + w.lessons.length, 0)
|
|
7359
|
+
}), h.current) {
|
|
7360
|
+
if (h.current.setMood("celebrating"), e.curriculumComplete)
|
|
7380
7361
|
try {
|
|
7381
|
-
|
|
7362
|
+
h.current.playAnimation(e.curriculumComplete, !0);
|
|
7382
7363
|
} catch {
|
|
7383
|
-
|
|
7364
|
+
h.current.playCelebration();
|
|
7384
7365
|
}
|
|
7385
|
-
const
|
|
7386
|
-
|
|
7366
|
+
const b = C.current || { lipsyncLang: "en" };
|
|
7367
|
+
h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: b.lipsyncLang });
|
|
7387
7368
|
}
|
|
7388
|
-
}, [e.curriculumComplete]),
|
|
7389
|
-
const
|
|
7390
|
-
l.current.isQuestionMode = !0, l.current.currentQuestionIndex = 0, l.current.totalQuestions =
|
|
7391
|
-
const
|
|
7392
|
-
|
|
7369
|
+
}, [e.curriculumComplete]), S = E(() => {
|
|
7370
|
+
const v = R();
|
|
7371
|
+
l.current.isQuestionMode = !0, l.current.currentQuestionIndex = 0, l.current.totalQuestions = v?.questions?.length || 0;
|
|
7372
|
+
const b = W();
|
|
7373
|
+
b && c.current.onCustomAction({
|
|
7393
7374
|
type: "questionStart",
|
|
7394
7375
|
moduleIndex: l.current.currentModuleIndex,
|
|
7395
7376
|
lessonIndex: l.current.currentLessonIndex,
|
|
7396
7377
|
questionIndex: l.current.currentQuestionIndex,
|
|
7397
7378
|
totalQuestions: l.current.totalQuestions,
|
|
7398
|
-
question:
|
|
7399
|
-
})
|
|
7400
|
-
|
|
7379
|
+
question: b
|
|
7380
|
+
});
|
|
7381
|
+
const w = () => {
|
|
7382
|
+
if (!h.current || !b) return;
|
|
7383
|
+
if (h.current.setMood("curious"), e.questionStart)
|
|
7401
7384
|
try {
|
|
7402
|
-
|
|
7403
|
-
} catch (
|
|
7404
|
-
console.warn("Failed to play questionStart animation:",
|
|
7385
|
+
h.current.playAnimation(e.questionStart, !0);
|
|
7386
|
+
} catch (L) {
|
|
7387
|
+
console.warn("Failed to play questionStart animation:", L);
|
|
7405
7388
|
}
|
|
7406
|
-
const
|
|
7407
|
-
|
|
7408
|
-
}
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7389
|
+
const H = C.current || { lipsyncLang: "en" };
|
|
7390
|
+
b.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${b.question}`, { lipsyncLang: H.lipsyncLang }) : b.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${b.question}`, { lipsyncLang: H.lipsyncLang }) : b.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${b.question}`, { lipsyncLang: H.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${b.question}`, { lipsyncLang: H.lipsyncLang });
|
|
7391
|
+
};
|
|
7392
|
+
if (h.current && h.current.isReady && b)
|
|
7393
|
+
w();
|
|
7394
|
+
else if (h.current && h.current.isReady) {
|
|
7395
|
+
const H = C.current || { lipsyncLang: "en" };
|
|
7396
|
+
h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7397
|
+
} else {
|
|
7398
|
+
const H = setInterval(() => {
|
|
7399
|
+
h.current && h.current.isReady && (clearInterval(H), b && w());
|
|
7414
7400
|
}, 100);
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7401
|
+
setTimeout(() => {
|
|
7402
|
+
clearInterval(H);
|
|
7403
|
+
}, 5e3);
|
|
7404
|
+
}
|
|
7405
|
+
}, [e.questionStart, R, W]), P = E(() => {
|
|
7406
|
+
const v = R();
|
|
7407
|
+
if (l.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7418
7408
|
l.current.currentQuestionIndex += 1;
|
|
7419
|
-
const
|
|
7420
|
-
|
|
7409
|
+
const b = W();
|
|
7410
|
+
b && c.current.onCustomAction({
|
|
7421
7411
|
type: "nextQuestion",
|
|
7422
7412
|
moduleIndex: l.current.currentModuleIndex,
|
|
7423
7413
|
lessonIndex: l.current.currentLessonIndex,
|
|
7424
7414
|
questionIndex: l.current.currentQuestionIndex,
|
|
7425
7415
|
totalQuestions: l.current.totalQuestions,
|
|
7426
|
-
question:
|
|
7427
|
-
})
|
|
7428
|
-
|
|
7416
|
+
question: b
|
|
7417
|
+
});
|
|
7418
|
+
const w = () => {
|
|
7419
|
+
if (!h.current || !b) return;
|
|
7420
|
+
if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7429
7421
|
try {
|
|
7430
|
-
|
|
7431
|
-
} catch (
|
|
7432
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7422
|
+
h.current.playAnimation(e.nextQuestion, !0);
|
|
7423
|
+
} catch (L) {
|
|
7424
|
+
console.warn("Failed to play nextQuestion animation:", L);
|
|
7433
7425
|
}
|
|
7434
|
-
const
|
|
7435
|
-
|
|
7436
|
-
lipsyncLang:
|
|
7437
|
-
}) :
|
|
7438
|
-
lipsyncLang:
|
|
7439
|
-
}) :
|
|
7440
|
-
lipsyncLang:
|
|
7441
|
-
}) :
|
|
7442
|
-
lipsyncLang:
|
|
7426
|
+
const H = C.current || { lipsyncLang: "en" };
|
|
7427
|
+
b.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${b.question}`, {
|
|
7428
|
+
lipsyncLang: H.lipsyncLang
|
|
7429
|
+
}) : b.type === "multiple_choice" ? h.current.speakText(`Alright! Here's your next question: ${b.question}`, {
|
|
7430
|
+
lipsyncLang: H.lipsyncLang
|
|
7431
|
+
}) : b.type === "true_false" ? h.current.speakText(`Now let's try this one: ${b.question}`, {
|
|
7432
|
+
lipsyncLang: H.lipsyncLang
|
|
7433
|
+
}) : h.current.speakText(`Here's the next question: ${b.question}`, {
|
|
7434
|
+
lipsyncLang: H.lipsyncLang
|
|
7443
7435
|
});
|
|
7436
|
+
};
|
|
7437
|
+
if (h.current && h.current.isReady && b)
|
|
7438
|
+
w();
|
|
7439
|
+
else if (b) {
|
|
7440
|
+
const H = setInterval(() => {
|
|
7441
|
+
h.current && h.current.isReady && (clearInterval(H), w());
|
|
7442
|
+
}, 100);
|
|
7443
|
+
setTimeout(() => {
|
|
7444
|
+
clearInterval(H);
|
|
7445
|
+
}, 5e3);
|
|
7444
7446
|
}
|
|
7445
7447
|
} else
|
|
7446
7448
|
c.current.onCustomAction({
|
|
@@ -7450,87 +7452,87 @@ const at = Re(({
|
|
|
7450
7452
|
totalQuestions: l.current.totalQuestions,
|
|
7451
7453
|
score: l.current.score
|
|
7452
7454
|
});
|
|
7453
|
-
}, [e.nextQuestion,
|
|
7454
|
-
const
|
|
7455
|
-
l.current.currentLessonIndex < (
|
|
7455
|
+
}, [e.nextQuestion, R, W]), O = E(() => {
|
|
7456
|
+
const v = z.current || { modules: [] }, b = v.modules[l.current.currentModuleIndex];
|
|
7457
|
+
l.current.currentLessonIndex < (b?.lessons?.length || 0) - 1 ? (l.current.currentLessonIndex += 1, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7456
7458
|
type: "lessonStart",
|
|
7457
7459
|
moduleIndex: l.current.currentModuleIndex,
|
|
7458
7460
|
lessonIndex: l.current.currentLessonIndex
|
|
7459
7461
|
}), c.current.onLessonStart({
|
|
7460
7462
|
moduleIndex: l.current.currentModuleIndex,
|
|
7461
7463
|
lessonIndex: l.current.currentLessonIndex,
|
|
7462
|
-
lesson:
|
|
7463
|
-
}),
|
|
7464
|
+
lesson: R()
|
|
7465
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"))) : l.current.currentModuleIndex < (v.modules?.length || 0) - 1 ? (l.current.currentModuleIndex += 1, l.current.currentLessonIndex = 0, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7464
7466
|
type: "lessonStart",
|
|
7465
7467
|
moduleIndex: l.current.currentModuleIndex,
|
|
7466
7468
|
lessonIndex: l.current.currentLessonIndex
|
|
7467
7469
|
}), c.current.onLessonStart({
|
|
7468
7470
|
moduleIndex: l.current.currentModuleIndex,
|
|
7469
7471
|
lessonIndex: l.current.currentLessonIndex,
|
|
7470
|
-
lesson:
|
|
7471
|
-
}),
|
|
7472
|
-
}, []),
|
|
7473
|
-
const
|
|
7474
|
-
let
|
|
7475
|
-
if (
|
|
7476
|
-
const
|
|
7477
|
-
|
|
7472
|
+
lesson: R()
|
|
7473
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"))) : I.current && I.current();
|
|
7474
|
+
}, []), V = E(() => {
|
|
7475
|
+
const v = R();
|
|
7476
|
+
let b = null;
|
|
7477
|
+
if (v?.avatar_script && v?.body) {
|
|
7478
|
+
const w = v.avatar_script.trim(), H = v.body.trim(), L = w.match(/[.!?]$/) ? " " : ". ";
|
|
7479
|
+
b = `${w}${L}${H}`;
|
|
7478
7480
|
} else
|
|
7479
|
-
|
|
7480
|
-
if (
|
|
7481
|
-
l.current.isTeaching = !0, l.current.isQuestionMode = !1,
|
|
7482
|
-
let
|
|
7481
|
+
b = v?.avatar_script || v?.body || null;
|
|
7482
|
+
if (h.current && h.current.isReady && b) {
|
|
7483
|
+
l.current.isTeaching = !0, l.current.isQuestionMode = !1, h.current.setMood("happy");
|
|
7484
|
+
let w = !1;
|
|
7483
7485
|
if (e.teaching)
|
|
7484
7486
|
try {
|
|
7485
|
-
|
|
7486
|
-
} catch (
|
|
7487
|
-
console.warn("Failed to play teaching animation:",
|
|
7487
|
+
h.current.playAnimation(e.teaching, !0), w = !0;
|
|
7488
|
+
} catch (L) {
|
|
7489
|
+
console.warn("Failed to play teaching animation:", L);
|
|
7488
7490
|
}
|
|
7489
|
-
|
|
7490
|
-
const
|
|
7491
|
+
w || h.current.setBodyMovement("gesturing");
|
|
7492
|
+
const H = C.current || { lipsyncLang: "en" };
|
|
7491
7493
|
c.current.onLessonStart({
|
|
7492
7494
|
moduleIndex: l.current.currentModuleIndex,
|
|
7493
7495
|
lessonIndex: l.current.currentLessonIndex,
|
|
7494
|
-
lesson:
|
|
7496
|
+
lesson: v
|
|
7495
7497
|
}), c.current.onCustomAction({
|
|
7496
7498
|
type: "teachingStart",
|
|
7497
7499
|
moduleIndex: l.current.currentModuleIndex,
|
|
7498
7500
|
lessonIndex: l.current.currentLessonIndex,
|
|
7499
|
-
lesson:
|
|
7500
|
-
}),
|
|
7501
|
-
lipsyncLang:
|
|
7501
|
+
lesson: v
|
|
7502
|
+
}), h.current.speakText(b, {
|
|
7503
|
+
lipsyncLang: H.lipsyncLang,
|
|
7502
7504
|
onSpeechEnd: () => {
|
|
7503
7505
|
l.current.isTeaching = !1, c.current.onCustomAction({
|
|
7504
7506
|
type: "teachingComplete",
|
|
7505
7507
|
moduleIndex: l.current.currentModuleIndex,
|
|
7506
7508
|
lessonIndex: l.current.currentLessonIndex,
|
|
7507
|
-
lesson:
|
|
7508
|
-
hasQuestions:
|
|
7509
|
+
lesson: v,
|
|
7510
|
+
hasQuestions: v.questions && v.questions.length > 0
|
|
7509
7511
|
});
|
|
7510
7512
|
}
|
|
7511
7513
|
});
|
|
7512
7514
|
}
|
|
7513
|
-
}, [e.teaching,
|
|
7514
|
-
const
|
|
7515
|
-
if (
|
|
7515
|
+
}, [e.teaching, R]), J = E((v) => {
|
|
7516
|
+
const b = W(), w = D(v, b);
|
|
7517
|
+
if (w && (l.current.score += 1), c.current.onQuestionAnswer({
|
|
7516
7518
|
moduleIndex: l.current.currentModuleIndex,
|
|
7517
7519
|
lessonIndex: l.current.currentLessonIndex,
|
|
7518
7520
|
questionIndex: l.current.currentQuestionIndex,
|
|
7519
|
-
answer:
|
|
7520
|
-
isCorrect:
|
|
7521
|
-
question:
|
|
7522
|
-
}),
|
|
7523
|
-
if (
|
|
7524
|
-
if (
|
|
7521
|
+
answer: v,
|
|
7522
|
+
isCorrect: w,
|
|
7523
|
+
question: b
|
|
7524
|
+
}), h.current)
|
|
7525
|
+
if (w) {
|
|
7526
|
+
if (h.current.setMood("happy"), e.correct)
|
|
7525
7527
|
try {
|
|
7526
|
-
|
|
7528
|
+
h.current.playReaction("happy");
|
|
7527
7529
|
} catch {
|
|
7528
|
-
|
|
7530
|
+
h.current.setBodyMovement("happy");
|
|
7529
7531
|
}
|
|
7530
|
-
|
|
7531
|
-
const
|
|
7532
|
-
|
|
7533
|
-
lipsyncLang:
|
|
7532
|
+
h.current.setBodyMovement("gesturing");
|
|
7533
|
+
const H = b.type === "code_test" ? `Great job! Your code passed all the tests! ${b.explanation || ""}` : `Excellent! That's correct! ${b.explanation || ""}`, L = C.current || { lipsyncLang: "en" };
|
|
7534
|
+
h.current.speakText(H, {
|
|
7535
|
+
lipsyncLang: L.lipsyncLang,
|
|
7534
7536
|
onSpeechEnd: () => {
|
|
7535
7537
|
c.current.onCustomAction({
|
|
7536
7538
|
type: "answerFeedbackComplete",
|
|
@@ -7538,21 +7540,21 @@ const at = Re(({
|
|
|
7538
7540
|
lessonIndex: l.current.currentLessonIndex,
|
|
7539
7541
|
questionIndex: l.current.currentQuestionIndex,
|
|
7540
7542
|
isCorrect: !0,
|
|
7541
|
-
hasNextQuestion: l.current.currentQuestionIndex < (
|
|
7543
|
+
hasNextQuestion: l.current.currentQuestionIndex < (R()?.questions?.length || 0) - 1
|
|
7542
7544
|
});
|
|
7543
7545
|
}
|
|
7544
7546
|
});
|
|
7545
7547
|
} else {
|
|
7546
|
-
if (
|
|
7548
|
+
if (h.current.setMood("sad"), e.incorrect)
|
|
7547
7549
|
try {
|
|
7548
|
-
|
|
7550
|
+
h.current.playAnimation(e.incorrect, !0);
|
|
7549
7551
|
} catch {
|
|
7550
|
-
|
|
7552
|
+
h.current.setBodyMovement("idle");
|
|
7551
7553
|
}
|
|
7552
|
-
|
|
7553
|
-
const
|
|
7554
|
-
|
|
7555
|
-
lipsyncLang:
|
|
7554
|
+
h.current.setBodyMovement("gesturing");
|
|
7555
|
+
const H = b.type === "code_test" ? `Your code didn't pass all the tests. ${b.explanation || "Try again!"}` : `Not quite right, but don't worry! ${b.explanation || ""} Let's move on to the next question.`, L = C.current || { lipsyncLang: "en" };
|
|
7556
|
+
h.current.speakText(H, {
|
|
7557
|
+
lipsyncLang: L.lipsyncLang,
|
|
7556
7558
|
onSpeechEnd: () => {
|
|
7557
7559
|
c.current.onCustomAction({
|
|
7558
7560
|
type: "answerFeedbackComplete",
|
|
@@ -7560,7 +7562,7 @@ const at = Re(({
|
|
|
7560
7562
|
lessonIndex: l.current.currentLessonIndex,
|
|
7561
7563
|
questionIndex: l.current.currentQuestionIndex,
|
|
7562
7564
|
isCorrect: !1,
|
|
7563
|
-
hasNextQuestion: l.current.currentQuestionIndex < (
|
|
7565
|
+
hasNextQuestion: l.current.currentQuestionIndex < (R()?.questions?.length || 0) - 1
|
|
7564
7566
|
});
|
|
7565
7567
|
}
|
|
7566
7568
|
});
|
|
@@ -7571,112 +7573,112 @@ const at = Re(({
|
|
|
7571
7573
|
moduleIndex: l.current.currentModuleIndex,
|
|
7572
7574
|
lessonIndex: l.current.currentLessonIndex,
|
|
7573
7575
|
questionIndex: l.current.currentQuestionIndex,
|
|
7574
|
-
isCorrect:
|
|
7575
|
-
hasNextQuestion: l.current.currentQuestionIndex < (
|
|
7576
|
+
isCorrect: w,
|
|
7577
|
+
hasNextQuestion: l.current.currentQuestionIndex < (R()?.questions?.length || 0) - 1,
|
|
7576
7578
|
avatarNotReady: !0
|
|
7577
7579
|
});
|
|
7578
|
-
}, [e.correct, e.incorrect,
|
|
7579
|
-
const
|
|
7580
|
-
if (!
|
|
7580
|
+
}, [e.correct, e.incorrect, W, R, D]), $ = E((v) => {
|
|
7581
|
+
const b = W();
|
|
7582
|
+
if (!v || typeof v != "object") {
|
|
7581
7583
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
7582
7584
|
return;
|
|
7583
7585
|
}
|
|
7584
|
-
if (
|
|
7586
|
+
if (b?.type !== "code_test") {
|
|
7585
7587
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
7586
7588
|
return;
|
|
7587
7589
|
}
|
|
7588
|
-
const
|
|
7589
|
-
passed:
|
|
7590
|
-
results:
|
|
7591
|
-
output:
|
|
7592
|
-
error:
|
|
7593
|
-
executionTime:
|
|
7594
|
-
testCount:
|
|
7595
|
-
passedCount:
|
|
7596
|
-
failedCount:
|
|
7590
|
+
const w = {
|
|
7591
|
+
passed: v.passed === !0,
|
|
7592
|
+
results: v.results || [],
|
|
7593
|
+
output: v.output || "",
|
|
7594
|
+
error: v.error || null,
|
|
7595
|
+
executionTime: v.executionTime || null,
|
|
7596
|
+
testCount: v.testCount || 0,
|
|
7597
|
+
passedCount: v.passedCount || 0,
|
|
7598
|
+
failedCount: v.failedCount || 0
|
|
7597
7599
|
};
|
|
7598
7600
|
c.current.onCustomAction({
|
|
7599
7601
|
type: "codeTestSubmitted",
|
|
7600
7602
|
moduleIndex: l.current.currentModuleIndex,
|
|
7601
7603
|
lessonIndex: l.current.currentLessonIndex,
|
|
7602
7604
|
questionIndex: l.current.currentQuestionIndex,
|
|
7603
|
-
testResult:
|
|
7604
|
-
question:
|
|
7605
|
-
}), p.current && p.current(
|
|
7606
|
-
}, [
|
|
7605
|
+
testResult: w,
|
|
7606
|
+
question: b
|
|
7607
|
+
}), p.current && p.current(w);
|
|
7608
|
+
}, [W, D]), ne = E(() => {
|
|
7607
7609
|
l.current.currentModuleIndex = 0, l.current.currentLessonIndex = 0, l.current.currentQuestionIndex = 0, l.current.isTeaching = !1, l.current.isQuestionMode = !1, l.current.lessonCompleted = !1, l.current.curriculumCompleted = !1, l.current.score = 0, l.current.totalQuestions = 0;
|
|
7608
|
-
}, []),
|
|
7609
|
-
console.log("Avatar is ready!",
|
|
7610
|
-
const
|
|
7611
|
-
|
|
7610
|
+
}, []), ge = E((v) => {
|
|
7611
|
+
console.log("Avatar is ready!", v);
|
|
7612
|
+
const b = R(), w = b?.avatar_script || b?.body;
|
|
7613
|
+
u && w && setTimeout(() => {
|
|
7612
7614
|
d.current && d.current();
|
|
7613
7615
|
}, 10);
|
|
7614
|
-
}, [
|
|
7615
|
-
|
|
7616
|
-
d.current =
|
|
7617
|
-
}),
|
|
7616
|
+
}, [u, R]);
|
|
7617
|
+
Ee(() => {
|
|
7618
|
+
d.current = V, g.current = O, y.current = j, x.current = P, I.current = ae, F.current = S, p.current = J;
|
|
7619
|
+
}), fe(a, () => ({
|
|
7618
7620
|
// Curriculum control methods
|
|
7619
|
-
startTeaching:
|
|
7620
|
-
startQuestions:
|
|
7621
|
+
startTeaching: V,
|
|
7622
|
+
startQuestions: S,
|
|
7621
7623
|
handleAnswerSelect: J,
|
|
7622
7624
|
handleCodeTestResult: $,
|
|
7623
7625
|
nextQuestion: P,
|
|
7624
|
-
nextLesson:
|
|
7626
|
+
nextLesson: O,
|
|
7625
7627
|
completeLesson: j,
|
|
7626
7628
|
completeCurriculum: ae,
|
|
7627
7629
|
resetCurriculum: ne,
|
|
7628
7630
|
getState: () => ({ ...l.current }),
|
|
7629
|
-
getCurrentQuestion: () =>
|
|
7630
|
-
getCurrentLesson: () =>
|
|
7631
|
+
getCurrentQuestion: () => W(),
|
|
7632
|
+
getCurrentLesson: () => R(),
|
|
7631
7633
|
// Direct access to avatar ref (always returns current value)
|
|
7632
|
-
getAvatarRef: () =>
|
|
7634
|
+
getAvatarRef: () => h.current,
|
|
7633
7635
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
7634
|
-
speakText: async (
|
|
7635
|
-
await
|
|
7636
|
-
const
|
|
7637
|
-
|
|
7636
|
+
speakText: async (v, b = {}) => {
|
|
7637
|
+
await h.current?.resumeAudioContext?.();
|
|
7638
|
+
const w = C.current || { lipsyncLang: "en" };
|
|
7639
|
+
h.current?.speakText(v, { ...b, lipsyncLang: b.lipsyncLang || w.lipsyncLang });
|
|
7638
7640
|
},
|
|
7639
7641
|
resumeAudioContext: async () => {
|
|
7640
|
-
if (
|
|
7641
|
-
return await
|
|
7642
|
-
const
|
|
7643
|
-
if (
|
|
7644
|
-
const
|
|
7645
|
-
if (
|
|
7642
|
+
if (h.current?.resumeAudioContext)
|
|
7643
|
+
return await h.current.resumeAudioContext();
|
|
7644
|
+
const v = h.current?.talkingHead;
|
|
7645
|
+
if (v?.audioCtx) {
|
|
7646
|
+
const b = v.audioCtx;
|
|
7647
|
+
if (b.state === "suspended" || b.state === "interrupted")
|
|
7646
7648
|
try {
|
|
7647
|
-
await
|
|
7648
|
-
} catch (
|
|
7649
|
-
console.warn("Failed to resume audio context:",
|
|
7649
|
+
await b.resume(), console.log("Audio context resumed via talkingHead");
|
|
7650
|
+
} catch (w) {
|
|
7651
|
+
console.warn("Failed to resume audio context:", w);
|
|
7650
7652
|
}
|
|
7651
7653
|
} else
|
|
7652
7654
|
console.warn("Audio context not available yet");
|
|
7653
7655
|
},
|
|
7654
|
-
stopSpeaking: () =>
|
|
7655
|
-
setMood: (
|
|
7656
|
-
playAnimation: (
|
|
7657
|
-
setBodyMovement: (
|
|
7658
|
-
setMovementIntensity: (
|
|
7659
|
-
playRandomDance: () =>
|
|
7660
|
-
playReaction: (
|
|
7661
|
-
playCelebration: () =>
|
|
7662
|
-
setShowFullAvatar: (
|
|
7663
|
-
setTimingAdjustment: (
|
|
7664
|
-
lockAvatarPosition: () =>
|
|
7665
|
-
unlockAvatarPosition: () =>
|
|
7656
|
+
stopSpeaking: () => h.current?.stopSpeaking(),
|
|
7657
|
+
setMood: (v) => h.current?.setMood(v),
|
|
7658
|
+
playAnimation: (v, b) => h.current?.playAnimation(v, b),
|
|
7659
|
+
setBodyMovement: (v) => h.current?.setBodyMovement(v),
|
|
7660
|
+
setMovementIntensity: (v) => h.current?.setMovementIntensity(v),
|
|
7661
|
+
playRandomDance: () => h.current?.playRandomDance(),
|
|
7662
|
+
playReaction: (v) => h.current?.playReaction(v),
|
|
7663
|
+
playCelebration: () => h.current?.playCelebration(),
|
|
7664
|
+
setShowFullAvatar: (v) => h.current?.setShowFullAvatar(v),
|
|
7665
|
+
setTimingAdjustment: (v) => h.current?.setTimingAdjustment(v),
|
|
7666
|
+
lockAvatarPosition: () => h.current?.lockAvatarPosition(),
|
|
7667
|
+
unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
|
|
7666
7668
|
// Custom action trigger
|
|
7667
|
-
triggerCustomAction: (
|
|
7669
|
+
triggerCustomAction: (v, b) => {
|
|
7668
7670
|
c.current.onCustomAction({
|
|
7669
|
-
type:
|
|
7670
|
-
...
|
|
7671
|
+
type: v,
|
|
7672
|
+
...b,
|
|
7671
7673
|
state: { ...l.current }
|
|
7672
7674
|
});
|
|
7673
7675
|
},
|
|
7674
7676
|
// Responsive resize handler
|
|
7675
|
-
handleResize: () =>
|
|
7677
|
+
handleResize: () => h.current?.handleResize(),
|
|
7676
7678
|
// Avatar readiness check (always returns current value)
|
|
7677
|
-
isAvatarReady: () =>
|
|
7678
|
-
}), [
|
|
7679
|
-
const
|
|
7679
|
+
isAvatarReady: () => h.current?.isReady || !1
|
|
7680
|
+
}), [V, S, J, $, P, O, j, ae, ne, W, R]);
|
|
7681
|
+
const q = C.current || {
|
|
7680
7682
|
avatarUrl: "/avatars/brunette.glb",
|
|
7681
7683
|
avatarBody: "F",
|
|
7682
7684
|
mood: "happy",
|
|
@@ -7690,32 +7692,32 @@ const at = Re(({
|
|
|
7690
7692
|
animations: e
|
|
7691
7693
|
};
|
|
7692
7694
|
return /* @__PURE__ */ se("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ se(
|
|
7693
|
-
|
|
7695
|
+
ze,
|
|
7694
7696
|
{
|
|
7695
|
-
ref:
|
|
7696
|
-
avatarUrl:
|
|
7697
|
-
avatarBody:
|
|
7698
|
-
mood:
|
|
7699
|
-
ttsLang:
|
|
7700
|
-
ttsService:
|
|
7701
|
-
ttsVoice:
|
|
7702
|
-
ttsApiKey:
|
|
7703
|
-
bodyMovement:
|
|
7704
|
-
movementIntensity:
|
|
7705
|
-
showFullAvatar:
|
|
7697
|
+
ref: h,
|
|
7698
|
+
avatarUrl: q.avatarUrl,
|
|
7699
|
+
avatarBody: q.avatarBody,
|
|
7700
|
+
mood: q.mood,
|
|
7701
|
+
ttsLang: q.ttsLang,
|
|
7702
|
+
ttsService: q.ttsService,
|
|
7703
|
+
ttsVoice: q.ttsVoice,
|
|
7704
|
+
ttsApiKey: q.ttsApiKey,
|
|
7705
|
+
bodyMovement: q.bodyMovement,
|
|
7706
|
+
movementIntensity: q.movementIntensity,
|
|
7707
|
+
showFullAvatar: q.showFullAvatar,
|
|
7706
7708
|
cameraView: "upper",
|
|
7707
|
-
animations:
|
|
7708
|
-
onReady:
|
|
7709
|
+
animations: q.animations,
|
|
7710
|
+
onReady: ge,
|
|
7709
7711
|
onLoading: () => {
|
|
7710
7712
|
},
|
|
7711
|
-
onError: (
|
|
7712
|
-
console.error("Avatar error:",
|
|
7713
|
+
onError: (v) => {
|
|
7714
|
+
console.error("Avatar error:", v);
|
|
7713
7715
|
}
|
|
7714
7716
|
}
|
|
7715
7717
|
) });
|
|
7716
7718
|
});
|
|
7717
|
-
|
|
7718
|
-
const
|
|
7719
|
+
nt.displayName = "CurriculumLearning";
|
|
7720
|
+
const Ce = {
|
|
7719
7721
|
// Code-based dance animations (no FBX required)
|
|
7720
7722
|
dance: {
|
|
7721
7723
|
name: "dance",
|
|
@@ -7818,14 +7820,14 @@ const Ee = {
|
|
|
7818
7820
|
duration: 5e3,
|
|
7819
7821
|
description: "Excited, energetic movement"
|
|
7820
7822
|
}
|
|
7821
|
-
},
|
|
7823
|
+
}, pt = (N) => Ce[N] || null, gt = (N) => Ce.hasOwnProperty(N);
|
|
7822
7824
|
export {
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7825
|
+
nt as CurriculumLearning,
|
|
7826
|
+
ze as TalkingHeadAvatar,
|
|
7827
|
+
it as TalkingHeadComponent,
|
|
7828
|
+
Ce as animations,
|
|
7829
|
+
xe as getActiveTTSConfig,
|
|
7830
|
+
pt as getAnimation,
|
|
7831
|
+
mt as getVoiceOptions,
|
|
7832
|
+
gt as hasAnimation
|
|
7831
7833
|
};
|