@sage-rsc/talking-head-react 1.8.1 → 1.8.2
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 +450 -450
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +4 -0
- package/src/lib/talkinghead.mjs +10 -2
package/dist/index.js
CHANGED
|
@@ -192,7 +192,7 @@ class It {
|
|
|
192
192
|
const a = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!a) throw new Error("Bone '" + s.bone + "' not found in #" + i + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + i + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const u = {
|
|
196
196
|
bone: a,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class It {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((l) => Number.isNaN(l))) throw new Error("deltaLocal must be an array of three numbers in #" + i + " exclude.");
|
|
206
|
-
|
|
206
|
+
u.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
o.excludes.push(
|
|
208
|
+
o.excludes.push(u);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class It {
|
|
|
282
282
|
p = this.dict[i.boneParent.name], p && (p.children || (p.children = []), p.children.push(i));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const t = /* @__PURE__ */ new WeakSet(), o = (i) => i.parent?.isBone ? [i, ...o(i.parent)] : [i], s = (i) => {
|
|
285
|
-
o(i).forEach((
|
|
286
|
-
t.has(
|
|
285
|
+
o(i).forEach((u) => {
|
|
286
|
+
t.has(u) || (this.objectsUpdate.push(u), t.add(u));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((i) => {
|
|
@@ -308,12 +308,12 @@ class It {
|
|
|
308
308
|
o(n?.isScene, "First parameter must be Scene."), this.scene = n, o(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, o(Array.isArray(t), "Third parameter must be an array of bone configs."), this.config = t, this.config.forEach((s, i) => {
|
|
309
309
|
const a = "Config item #" + i + ": ";
|
|
310
310
|
o(s.bone, a + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
o(typeof
|
|
313
|
-
const l = this.armature.getObjectByName(
|
|
314
|
-
o(l, a + "Bone '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const u = s.bone;
|
|
312
|
+
o(typeof u == "string" && u.length > 0, a + "Bone name must be a non-empty string.");
|
|
313
|
+
const l = this.armature.getObjectByName(u);
|
|
314
|
+
o(l, a + "Bone '" + u + "' not found."), o(l.parent?.isBone, a + "Bone must have a parent bone."), o(this.data.every((r) => r.bone !== l), a + "Bone '" + u + "' already exists."), l.updateMatrixWorld(!0);
|
|
315
|
+
const c = {
|
|
316
|
+
name: u,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: l,
|
|
319
319
|
// Bone object
|
|
@@ -338,9 +338,9 @@ class It {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
c.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), c.qWorldInverseYaw = be.clone().normalize(), this.data.push(c), this.dict[u] = c;
|
|
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 (r) {
|
|
345
345
|
o(!1, a + r);
|
|
346
346
|
}
|
|
@@ -408,9 +408,9 @@ class It {
|
|
|
408
408
|
);
|
|
409
409
|
}), p = this.helpers.points, p.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new b.BufferGeometry(), t = p.bones.map((
|
|
411
|
+
const e = new b.BufferGeometry(), t = p.bones.map((u) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new b.Float32BufferAttribute(t, 3));
|
|
413
|
-
const o = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), i = p.pivots.map((
|
|
413
|
+
const o = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), i = p.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [o.r, o.g, o.b]).flat();
|
|
414
414
|
e.setAttribute("color", new b.Float32BufferAttribute(i, 3));
|
|
415
415
|
const a = new b.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class It {
|
|
|
423
423
|
p.object = new b.Points(e, a), p.object.renderOrder = 998, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
|
|
424
424
|
}
|
|
425
425
|
if (p = this.helpers.lines, p.bones.length) {
|
|
426
|
-
const e = new b.BufferGeometry(), t = p.bones.map((
|
|
426
|
+
const e = new b.BufferGeometry(), t = p.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new b.Float32BufferAttribute(t, 3));
|
|
428
|
-
const o = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), i = p.bones.map((
|
|
428
|
+
const o = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), i = p.bones.map((u) => [o.r, o.g, o.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new b.Float32BufferAttribute(i, 3));
|
|
430
430
|
const a = new b.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -519,13 +519,13 @@ class Lt {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, o = 1024, s = 512, i = Math.floor((n.length - o) / s) + 1;
|
|
521
521
|
for (let a = 0; a < i; a++) {
|
|
522
|
-
const
|
|
522
|
+
const u = a * s, l = Math.min(u + o, n.length), c = n.slice(u, l), r = this.calculateEnergy(c);
|
|
523
523
|
t.energy.push(r);
|
|
524
|
-
const h = this.calculateSpectralCentroid(
|
|
524
|
+
const h = this.calculateSpectralCentroid(c);
|
|
525
525
|
t.spectralCentroid.push(h);
|
|
526
|
-
const d = this.calculateZeroCrossingRate(
|
|
526
|
+
const d = this.calculateZeroCrossingRate(c);
|
|
527
527
|
t.zeroCrossingRate.push(d);
|
|
528
|
-
const g = this.calculateMFCC(
|
|
528
|
+
const g = this.calculateMFCC(c);
|
|
529
529
|
t.mfcc.push(g);
|
|
530
530
|
}
|
|
531
531
|
return t.onsets = this.detectOnsets(t.energy), t.phonemeBoundaries = this.detectPhonemeBoundaries(t), t;
|
|
@@ -597,19 +597,19 @@ class Lt {
|
|
|
597
597
|
for (; s & i; )
|
|
598
598
|
s ^= i, i >>= 1;
|
|
599
599
|
if (s ^= i, o < s) {
|
|
600
|
-
const a = t[o * 2],
|
|
601
|
-
t[o * 2] = t[s * 2], t[o * 2 + 1] = t[s * 2 + 1], t[s * 2] = a, t[s * 2 + 1] =
|
|
600
|
+
const a = t[o * 2], u = t[o * 2 + 1];
|
|
601
|
+
t[o * 2] = t[s * 2], t[o * 2 + 1] = t[s * 2 + 1], t[s * 2] = a, t[s * 2 + 1] = u;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let o = 2; o <= e; o <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / o, i = Math.cos(s), a = Math.sin(s);
|
|
606
|
-
for (let
|
|
607
|
-
let l = 1,
|
|
606
|
+
for (let u = 0; u < e; u += o) {
|
|
607
|
+
let l = 1, c = 0;
|
|
608
608
|
for (let r = 0; r < o / 2; r++) {
|
|
609
|
-
const h = t[(
|
|
610
|
-
t[(
|
|
611
|
-
const x = l * i -
|
|
612
|
-
l = x,
|
|
609
|
+
const h = t[(u + r) * 2], d = t[(u + r) * 2 + 1], g = t[(u + r + o / 2) * 2] * l - t[(u + r + o / 2) * 2 + 1] * c, R = t[(u + r + o / 2) * 2] * c + t[(u + r + o / 2) * 2 + 1] * l;
|
|
610
|
+
t[(u + r) * 2] = h + g, t[(u + r) * 2 + 1] = d + R, t[(u + r + o / 2) * 2] = h - g, t[(u + r + o / 2) * 2 + 1] = d - R;
|
|
611
|
+
const x = l * i - c * a, k = l * a + c * i;
|
|
612
|
+
l = x, c = k;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class Lt {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let i = 1; i < n.length; i++) {
|
|
627
|
-
const a = n[i] - n[i - 1],
|
|
628
|
-
a > 0.1 &&
|
|
627
|
+
const a = n[i] - n[i - 1], u = i * 0.023;
|
|
628
|
+
a > 0.1 && u - s > 0.1 && (e.push(u), s = u);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class Lt {
|
|
|
637
637
|
detectPhonemeBoundaries(n) {
|
|
638
638
|
const e = [], { energy: t, spectralCentroid: o, zeroCrossingRate: s } = n;
|
|
639
639
|
for (let i = 1; i < t.length; i++) {
|
|
640
|
-
const a = i * 0.023,
|
|
641
|
-
|
|
640
|
+
const a = i * 0.023, u = Math.abs(t[i] - t[i - 1]), l = Math.abs(o[i] - o[i - 1]), c = Math.abs(s[i] - s[i - 1]);
|
|
641
|
+
u + l * 0.1 + c * 0.5 > 0.2 && e.push(a);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ class Lt {
|
|
|
654
654
|
n.phonemeBoundaries, n.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let i = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const l = o[
|
|
657
|
+
for (let u = 0; u < o.length; u++) {
|
|
658
|
+
const l = o[u], c = this.estimateWordDuration(l, t / o.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: l,
|
|
661
661
|
startTime: i,
|
|
662
|
-
endTime: i +
|
|
663
|
-
duration:
|
|
664
|
-
}), i +=
|
|
662
|
+
endTime: i + c,
|
|
663
|
+
duration: c
|
|
664
|
+
}), i += c;
|
|
665
665
|
}
|
|
666
666
|
const a = this.generateVisemeTimings(n, e, t);
|
|
667
667
|
return {
|
|
@@ -701,27 +701,27 @@ class Lt {
|
|
|
701
701
|
const o = [], s = n.phonemeBoundaries;
|
|
702
702
|
n.onsets;
|
|
703
703
|
const i = this.textToVisemes(e);
|
|
704
|
-
let a = 0,
|
|
704
|
+
let a = 0, u = 0;
|
|
705
705
|
for (let l = 0; l < s.length && a < i.length; l++) {
|
|
706
|
-
const
|
|
706
|
+
const c = s[l], r = i[a], h = n.energy[Math.floor(c / 0.023)] || 0, d = this.calculateVisemeDuration(r, h);
|
|
707
707
|
o.push({
|
|
708
708
|
viseme: r,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
709
|
+
startTime: u,
|
|
710
|
+
endTime: u + d,
|
|
711
711
|
duration: d,
|
|
712
712
|
intensity: Math.min(1, h * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), u += d, a++;
|
|
715
715
|
}
|
|
716
716
|
for (; a < i.length; ) {
|
|
717
|
-
const l = i[a],
|
|
717
|
+
const l = i[a], c = this.calculateVisemeDuration(l, 0.5);
|
|
718
718
|
o.push({
|
|
719
719
|
viseme: l,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: u,
|
|
721
|
+
endTime: u + c,
|
|
722
|
+
duration: c,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), u += c, a++;
|
|
725
725
|
}
|
|
726
726
|
return o;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class Lt {
|
|
|
775
775
|
let i = 0;
|
|
776
776
|
for (; i < s.length; ) {
|
|
777
777
|
let a = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const l = s.substr(i,
|
|
778
|
+
for (let u = 3; u >= 2; u--) {
|
|
779
|
+
const l = s.substr(i, u);
|
|
780
780
|
if (e[l]) {
|
|
781
|
-
t.push(e[l]), i +=
|
|
781
|
+
t.push(e[l]), i += u, a = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!a) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const u = s[i];
|
|
787
|
+
e[u] && t.push(e[u]), i++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -1206,11 +1206,11 @@ class St {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((t) => {
|
|
1209
|
-
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o),
|
|
1209
|
+
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let h = "";
|
|
1211
1211
|
h += [...a].map((g) => n[g] || g).join("");
|
|
1212
|
-
const d = [...
|
|
1213
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h),
|
|
1212
|
+
const d = [...u];
|
|
1213
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((g) => {
|
|
1214
1214
|
r.visemes.push(g);
|
|
1215
1215
|
}), r;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class St {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(n) {
|
|
1326
1326
|
const e = parseInt(n), t = !isNaN(e) && n.length === 2, o = !isNaN(e) && n.length > 2 && e > 0 && e <= 3e3, s = o && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, i = o && !s ? Math.floor(e / 100) : null, a = t || o ? 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") : (i && u.push(this.convertNumberToWords(i).trim()), a ? u.push(this.decades[a] || this.convertNumberToWords(a).trim() + "s") : i ? u.push("hundreds") : u.push(n)), u.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class St {
|
|
|
1376
1376
|
const s = o[e.i], i = this.rules[s];
|
|
1377
1377
|
if (i)
|
|
1378
1378
|
for (let a = 0; a < i.length; a++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const u = i[a];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
|
|
1381
|
+
u.visemes.forEach((r) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
|
|
1383
1383
|
const h = 0.7 * (this.visemeDurations[r] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += h, t += h;
|
|
@@ -1386,7 +1386,7 @@ class St {
|
|
|
1386
1386
|
const h = this.visemeDurations[r] || 1;
|
|
1387
1387
|
e.visemes.push(r), e.times.push(t), e.durations.push(h), t += h;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += u.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1616,11 +1616,11 @@ class wt {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((t) => {
|
|
1619
|
-
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o),
|
|
1619
|
+
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let h = "";
|
|
1621
1621
|
h += [...a].map((g) => n[g] || g).join("");
|
|
1622
|
-
const d = [...
|
|
1623
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h),
|
|
1622
|
+
const d = [...u];
|
|
1623
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((g) => {
|
|
1624
1624
|
r.visemes.push(g);
|
|
1625
1625
|
}), r;
|
|
1626
1626
|
});
|
|
@@ -1732,8 +1732,8 @@ class wt {
|
|
|
1732
1732
|
const s = o[e.i], i = this.rules[s];
|
|
1733
1733
|
if (i) {
|
|
1734
1734
|
let a = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const l = i[
|
|
1735
|
+
for (let u = 0; u < i.length; u++) {
|
|
1736
|
+
const l = i[u];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(l.regex)) {
|
|
1738
1738
|
l.visemes.forEach((h) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === h) {
|
|
@@ -2131,11 +2131,11 @@ class zt {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((t) => {
|
|
2134
|
-
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o),
|
|
2134
|
+
const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let h = "";
|
|
2136
2136
|
h += [...a].map((g) => n[g] || g).join("");
|
|
2137
|
-
const d = [...
|
|
2138
|
-
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h, "i"),
|
|
2137
|
+
const d = [...u];
|
|
2138
|
+
return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h, "i"), c.length && c.split(" ").forEach((g) => {
|
|
2139
2139
|
g && r.visemes.push(g);
|
|
2140
2140
|
}), r;
|
|
2141
2141
|
});
|
|
@@ -2267,8 +2267,8 @@ class zt {
|
|
|
2267
2267
|
const s = o[e.i], i = this.rules[s];
|
|
2268
2268
|
if (i) {
|
|
2269
2269
|
let a = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const l = i[
|
|
2270
|
+
for (let u = 0; u < i.length; u++) {
|
|
2271
|
+
const l = i[u];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(l.regex)) {
|
|
2273
2273
|
l.visemes.forEach((h) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === h) {
|
|
@@ -2381,10 +2381,10 @@ class Tt {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let t = parseFloat(n);
|
|
2383
2383
|
if (t === void 0) return n;
|
|
2384
|
-
let o = (s, i, a,
|
|
2384
|
+
let o = (s, i, a, u, l) => {
|
|
2385
2385
|
if (s < i) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(a + (
|
|
2386
|
+
const c = Math.floor(s / i);
|
|
2387
|
+
return e.push(a + (c === 1 ? u : this.numberToFinnishWords(c.toString()) + l)), s - c * i;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (t < 0 && (e.push("miinus "), t = Math.abs(t)), t = o(t, 1e9, " ", "miljardi", " miljardia"), t = o(t, 1e6, " ", "miljoona", " miljoonaa"), t = o(t, 1e3, "", "tuhat", "tuhatta"), t = o(t, 100, " ", "sata", "sataa"), t > 20 && (t = o(t, 10, "", "", "kymmentä")), t >= 1) {
|
|
2390
2390
|
let s = Math.floor(t);
|
|
@@ -2559,10 +2559,10 @@ class Ft {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let t = parseFloat(n);
|
|
2561
2561
|
if (t === void 0) return n;
|
|
2562
|
-
let o = (s, i, a,
|
|
2562
|
+
let o = (s, i, a, u, l) => {
|
|
2563
2563
|
if (s < i) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
2564
|
+
const c = Math.floor(s / i);
|
|
2565
|
+
return c === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(c.toString())), c % 10 === 1 ? e.push(a) : c % 10 === 0 || c % 100 > 10 && c % 100 < 20 ? e.push(l) : e.push(u), s - c * i;
|
|
2566
2566
|
};
|
|
2567
2567
|
t < 0 && (e.push("minus"), t = Math.abs(t)), t = o(t, 1e9, "milijardas", "milijardai", "milijardų"), t = o(t, 1e6, "milijonas", "milijonai", "milijonų"), t = o(t, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), t = o(t, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class Ft {
|
|
|
2608
2608
|
const i = o[s].toLowerCase(), a = this.visemes[i];
|
|
2609
2609
|
if (a)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const u = 0.7 * (this.durations[i] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += u, t += u;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(a), e.times.push(t), e.durations.push(
|
|
2614
|
+
const u = this.durations[i] || 1;
|
|
2615
|
+
e.visemes.push(a), e.times.push(t), e.durations.push(u), t += u;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
t += this.pauses[o[s]] || 0;
|
|
@@ -2629,7 +2629,7 @@ const Et = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
2629
2629
|
fr: Ht,
|
|
2630
2630
|
fi: Mt,
|
|
2631
2631
|
lt: Et
|
|
2632
|
-
},
|
|
2632
|
+
}, ue = new b.Quaternion(), oe = new b.Euler(), Ue = new b.Vector3(), Xe = new b.Vector3(), at = new b.Box3();
|
|
2633
2633
|
new b.Matrix4();
|
|
2634
2634
|
new b.Matrix4();
|
|
2635
2635
|
new b.Vector3();
|
|
@@ -3569,15 +3569,15 @@ class nt {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((a) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[a +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[a +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
|
|
3573
|
+
this.poseDelta.props[a + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
|
|
3575
|
+
this.poseDelta.props[a + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const t = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((a) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(a.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(a.props)).forEach((u) => t.add(u));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((a) => {
|
|
3582
3582
|
t.add(a);
|
|
3583
3583
|
}), this.posePropNames = [...t], 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 = {
|
|
@@ -4101,7 +4101,7 @@ class nt {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, i = [];
|
|
4104
|
-
Object.entries(s).forEach((a,
|
|
4104
|
+
Object.entries(s).forEach((a, u) => {
|
|
4105
4105
|
const l = new b.Bone();
|
|
4106
4106
|
l.name = a[0], a[1] ? this.ikMesh.getObjectByName(a[1]).add(l) : this.ikMesh.add(l), i.push(l);
|
|
4107
4107
|
}), this.ikMesh.bind(new b.Skeleton(i)), this.dynamicbones = new It(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
@@ -4150,9 +4150,9 @@ class nt {
|
|
|
4150
4150
|
let e = 3 * n.length / 4;
|
|
4151
4151
|
n[n.length - 1] === "=" && (e--, n[n.length - 2] === "=" && e--);
|
|
4152
4152
|
const t = new ArrayBuffer(e), o = new Uint8Array(t);
|
|
4153
|
-
let s, i = 0, a,
|
|
4153
|
+
let s, i = 0, a, u, l, c;
|
|
4154
4154
|
for (s = 0; s < n.length; s += 4)
|
|
4155
|
-
a = this.b64Lookup[n.charCodeAt(s)],
|
|
4155
|
+
a = this.b64Lookup[n.charCodeAt(s)], u = this.b64Lookup[n.charCodeAt(s + 1)], l = this.b64Lookup[n.charCodeAt(s + 2)], c = this.b64Lookup[n.charCodeAt(s + 3)], o[i++] = a << 2 | u >> 4, o[i++] = (u & 15) << 4 | l >> 2, o[i++] = (l & 3) << 6 | c & 63;
|
|
4156
4156
|
return t;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class nt {
|
|
|
4193
4193
|
const e = {};
|
|
4194
4194
|
for (let [t, o] of Object.entries(n)) {
|
|
4195
4195
|
const s = t.split(".");
|
|
4196
|
-
let i = Array.isArray(o.x) ? this.gaussianRandom(...o.x) : o.x, a = Array.isArray(o.y) ? this.gaussianRandom(...o.y) : o.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[t] = new b.Vector3(i, a,
|
|
4196
|
+
let i = Array.isArray(o.x) ? this.gaussianRandom(...o.x) : o.x, a = Array.isArray(o.y) ? this.gaussianRandom(...o.y) : o.y, u = Array.isArray(o.z) ? this.gaussianRandom(...o.z) : o.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[t] = new b.Vector3(i, a, u) : s[1] === "rotation" ? (t = s[0] + ".quaternion", e[t] = new b.Quaternion().setFromEuler(new b.Euler(i, a, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[t] = new b.Quaternion(i, a, u, o.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class nt {
|
|
|
4222
4222
|
n.forEach((s) => {
|
|
4223
4223
|
if (!o && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const i = s.geometry;
|
|
4225
|
-
let a = null,
|
|
4226
|
-
for (const [l,
|
|
4225
|
+
let a = null, u = null;
|
|
4226
|
+
for (const [l, c] of Object.entries(t))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(l)) {
|
|
4228
4228
|
const r = s.morphTargetDictionary[l], h = i.morphAttributes.position[r], d = i.morphAttributes.normal?.[r];
|
|
4229
|
-
a || (a = new b.Float32BufferAttribute(h.count * 3, 3), d && (
|
|
4229
|
+
a || (a = new b.Float32BufferAttribute(h.count * 3, 3), d && (u = new b.Float32BufferAttribute(h.count * 3, 3)));
|
|
4230
4230
|
for (let g = 0; g < h.count; g++) {
|
|
4231
|
-
const R = a.getX(g) + h.getX(g) *
|
|
4231
|
+
const R = a.getX(g) + h.getX(g) * c, x = a.getY(g) + h.getY(g) * c, k = a.getZ(g) + h.getZ(g) * c;
|
|
4232
4232
|
a.setXYZ(g, R, x, k);
|
|
4233
4233
|
}
|
|
4234
4234
|
if (d)
|
|
4235
4235
|
for (let g = 0; g < h.count; g++) {
|
|
4236
|
-
const R =
|
|
4237
|
-
|
|
4236
|
+
const R = u.getX(g) + d.getX(g) * c, x = u.getY(g) + d.getY(g) * c, k = u.getZ(g) + d.getZ(g) * c;
|
|
4237
|
+
u.setXYZ(g, R, x, k);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (a) {
|
|
4241
|
-
i.morphAttributes.position.push(a),
|
|
4241
|
+
i.morphAttributes.position.push(a), u && i.morphAttributes.normal.push(u);
|
|
4242
4242
|
const l = i.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[l] = 0, s.morphTargetDictionary[e] = l;
|
|
4244
4244
|
}
|
|
@@ -4268,7 +4268,7 @@ class nt {
|
|
|
4268
4268
|
throw new Error("Blend shapes not found");
|
|
4269
4269
|
const i = new Set(this.mtCustoms);
|
|
4270
4270
|
this.morphs.forEach((l) => {
|
|
4271
|
-
Object.keys(l.morphTargetDictionary).forEach((
|
|
4271
|
+
Object.keys(l.morphTargetDictionary).forEach((c) => i.add(c));
|
|
4272
4272
|
}), this.mtExtras.forEach((l) => {
|
|
4273
4273
|
i.has(l.key) || (this.addMixedMorphTarget(this.morphs, l.key, l.mix), i.add(l.key));
|
|
4274
4274
|
});
|
|
@@ -4295,16 +4295,16 @@ class nt {
|
|
|
4295
4295
|
ms: [],
|
|
4296
4296
|
is: []
|
|
4297
4297
|
}, a[l].value = a[l].baseline, a[l].applied = a[l].baseline;
|
|
4298
|
-
const
|
|
4299
|
-
|
|
4300
|
-
a[l][r] =
|
|
4298
|
+
const c = this.mtAvatar[l];
|
|
4299
|
+
c && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((r) => {
|
|
4300
|
+
a[l][r] = c[r];
|
|
4301
4301
|
}), this.morphs.forEach((r) => {
|
|
4302
4302
|
const h = r.morphTargetDictionary[l];
|
|
4303
4303
|
h !== void 0 && (a[l].ms.push(r.morphTargetInfluences), a[l].is.push(h), r.morphTargetInfluences[h] = a[l].applied);
|
|
4304
4304
|
});
|
|
4305
4305
|
}), this.mtAvatar = a, this.poseAvatar = { props: {} }, this.posePropNames.forEach((l) => {
|
|
4306
|
-
const
|
|
4307
|
-
this.poseAvatar.props[l] = r[
|
|
4306
|
+
const c = l.split("."), r = this.armature.getObjectByName(c[0]);
|
|
4307
|
+
this.poseAvatar.props[l] = r[c[1]], this.poseBase.props.hasOwnProperty(l) ? this.poseAvatar.props[l].copy(this.poseBase.props[l]) : this.poseBase.props[l] = this.poseAvatar.props[l].clone(), this.poseDelta.props.hasOwnProperty(l) && !this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l] = this.poseAvatar.props[l].clone()), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = 2e3;
|
|
4308
4308
|
}), this.ikMesh.traverse((l) => {
|
|
4309
4309
|
l.isBone && l.position.copy(this.armature.getObjectByName(l.name).position);
|
|
4310
4310
|
}), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(o.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), n.hasOwnProperty("modelDynamicBones"))
|
|
@@ -4314,8 +4314,8 @@ class nt {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + l);
|
|
4315
4315
|
}
|
|
4316
4316
|
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");
|
|
4317
|
-
const
|
|
4318
|
-
this.objectLeftEye.getWorldPosition(
|
|
4317
|
+
const u = new b.Vector3();
|
|
4318
|
+
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.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0)), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4319
4319
|
}
|
|
4320
4320
|
/**
|
|
4321
4321
|
* Get view names.
|
|
@@ -4343,22 +4343,22 @@ class nt {
|
|
|
4343
4343
|
return;
|
|
4344
4344
|
}
|
|
4345
4345
|
if (this.viewName = n || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4346
|
-
const t = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, o = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, i = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, a = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let l = -t * Math.tan(
|
|
4346
|
+
const t = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, o = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, i = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, a = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let l = -t * Math.tan(u / 2), c = (1 - o) * Math.tan(u / 2), r = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
|
-
r += 2,
|
|
4350
|
+
r += 2, c = c * r + 4 * this.avatarHeight / 5;
|
|
4351
4351
|
break;
|
|
4352
4352
|
case "upper":
|
|
4353
|
-
r += 4.5,
|
|
4353
|
+
r += 4.5, c = c * r + 2 * this.avatarHeight / 3;
|
|
4354
4354
|
break;
|
|
4355
4355
|
case "mid":
|
|
4356
|
-
r += 8,
|
|
4356
|
+
r += 8, c = c * r + this.avatarHeight / 3;
|
|
4357
4357
|
break;
|
|
4358
4358
|
default:
|
|
4359
|
-
r += 12,
|
|
4359
|
+
r += 12, c = c * r;
|
|
4360
4360
|
}
|
|
4361
|
-
l = l * r, this.controlsEnd = new b.Vector3(l,
|
|
4361
|
+
l = l * r, this.controlsEnd = new b.Vector3(l, c, 0), this.cameraEnd = new b.Vector3(l, c, r).applyEuler(new b.Euler(i, a, 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;
|
|
4362
4362
|
}
|
|
4363
4363
|
/**
|
|
4364
4364
|
* Change light colors and intensities.
|
|
@@ -4414,7 +4414,7 @@ class nt {
|
|
|
4414
4414
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4415
4415
|
oe.set(e.x, e.y, e.z);
|
|
4416
4416
|
const t = this.poseAvatar.props[n];
|
|
4417
|
-
t.isQuaternion ? (
|
|
4417
|
+
t.isQuaternion ? (ue.setFromEuler(oe), t.multiply(ue)) : t.isVector3 && t.add(oe);
|
|
4418
4418
|
}
|
|
4419
4419
|
}
|
|
4420
4420
|
/**
|
|
@@ -4469,17 +4469,17 @@ class nt {
|
|
|
4469
4469
|
"HandMiddle",
|
|
4470
4470
|
"HandRing",
|
|
4471
4471
|
"HandPinky"
|
|
4472
|
-
].forEach((
|
|
4473
|
-
r === 0 ? (this.poseDelta.props[i +
|
|
4472
|
+
].forEach((c, r) => {
|
|
4473
|
+
r === 0 ? (this.poseDelta.props[i + c + "1.quaternion"].x = 0, this.poseDelta.props[i + c + "2.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied, this.poseDelta.props[i + c + "3.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied) : (this.poseDelta.props[i + c + "1.quaternion"].x = t.applied, this.poseDelta.props[i + c + "2.quaternion"].x = 1.5 * t.applied, this.poseDelta.props[i + c + "3.quaternion"].x = 1.5 * t.applied);
|
|
4474
4474
|
});
|
|
4475
4475
|
break;
|
|
4476
4476
|
case "chestInhale":
|
|
4477
|
-
const a = t.applied / 20,
|
|
4478
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4477
|
+
const a = t.applied / 20, u = { x: a, y: a / 2, z: 3 * a }, l = { x: 1 / (1 + a) - 1, y: 1 / (1 + a / 2) - 1, z: 1 / (1 + 3 * a) - 1 };
|
|
4478
|
+
this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = l, this.poseDelta.props["LeftArm.scale"] = l, this.poseDelta.props["RightArm.scale"] = l;
|
|
4479
4479
|
break;
|
|
4480
4480
|
default:
|
|
4481
|
-
for (let
|
|
4482
|
-
t.ms[
|
|
4481
|
+
for (let c = 0, r = t.ms.length; c < r; c++)
|
|
4482
|
+
t.ms[c][t.is[c]] = t.applied;
|
|
4483
4483
|
}
|
|
4484
4484
|
}
|
|
4485
4485
|
}
|
|
@@ -4494,8 +4494,8 @@ class nt {
|
|
|
4494
4494
|
return Object.entries(n).forEach((o, s) => {
|
|
4495
4495
|
const i = o[0].split(".");
|
|
4496
4496
|
if (i[1] === "position" || i[1] === "rotation" || i[1] === "quaternion") {
|
|
4497
|
-
const a = i[1] === "quaternion" ? i[0] + ".rotation" : o[0],
|
|
4498
|
-
t += (s ? ", " : "") + "'" + a + "':{", t += "x:" + Math.round(
|
|
4497
|
+
const a = i[1] === "quaternion" ? i[0] + ".rotation" : o[0], u = o[1].isQuaternion ? new b.Euler().setFromQuaternion(o[1]) : o[1];
|
|
4498
|
+
t += (s ? ", " : "") + "'" + a + "':{", t += "x:" + Math.round(u.x * e) / e, t += ", y:" + Math.round(u.y * e) / e, t += ", z:" + Math.round(u.z * e) / e, t += "}";
|
|
4499
4499
|
}
|
|
4500
4500
|
}), t += "}", t;
|
|
4501
4501
|
}
|
|
@@ -4565,8 +4565,8 @@ class nt {
|
|
|
4565
4565
|
if (t ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4566
4566
|
this.setPoseFromTemplate(n, e);
|
|
4567
4567
|
}, i)) : this.poseCurrentTemplate = n || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, i), this.poseWeightOnLeft = !0, (!o && !s || o && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
|
|
4568
|
-
for (let [a,
|
|
4569
|
-
this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a].copy(
|
|
4568
|
+
for (let [a, u] of Object.entries(this.gesture))
|
|
4569
|
+
this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a].copy(u), this.poseTarget.props[a].t = u.t, this.poseTarget.props[a].d = u.d);
|
|
4570
4570
|
Object.keys(this.poseDelta.props).forEach((a) => {
|
|
4571
4571
|
this.poseTarget.props.hasOwnProperty(a) || (this.poseTarget.props[a] = this.poseBase.props[a].clone(), this.poseTarget.props[a].t = this.animClock, this.poseTarget.props[a].d = i);
|
|
4572
4572
|
});
|
|
@@ -4992,11 +4992,11 @@ class nt {
|
|
|
4992
4992
|
else if (a.hasOwnProperty("alt")) {
|
|
4993
4993
|
let l = a.alt[0];
|
|
4994
4994
|
if (a.alt.length > 1) {
|
|
4995
|
-
const
|
|
4995
|
+
const c = Math.random();
|
|
4996
4996
|
let r = 0;
|
|
4997
4997
|
for (let h = 0; h < a.alt.length; h++) {
|
|
4998
4998
|
let d = this.valueFn(a.alt[h].p);
|
|
4999
|
-
if (r += d === void 0 ? (1 - r) / (a.alt.length - 1 - h) : d,
|
|
4999
|
+
if (r += d === void 0 ? (1 - r) / (a.alt.length - 1 - h) : d, c < r) {
|
|
5000
5000
|
l = a.alt[h];
|
|
5001
5001
|
break;
|
|
5002
5002
|
}
|
|
@@ -5006,19 +5006,19 @@ class nt {
|
|
|
5006
5006
|
continue;
|
|
5007
5007
|
} else
|
|
5008
5008
|
break;
|
|
5009
|
-
let
|
|
5010
|
-
if (Array.isArray(
|
|
5011
|
-
a.dt.forEach((l,
|
|
5009
|
+
let u = this.valueFn(a.delay) || 0;
|
|
5010
|
+
if (Array.isArray(u) && (u = this.gaussianRandom(...u)), a.hasOwnProperty("dt"))
|
|
5011
|
+
a.dt.forEach((l, c) => {
|
|
5012
5012
|
let r = this.valueFn(l);
|
|
5013
|
-
Array.isArray(r) && (r = this.gaussianRandom(...r)), i.ts[
|
|
5013
|
+
Array.isArray(r) && (r = this.gaussianRandom(...r)), i.ts[c + 1] = i.ts[c] + r;
|
|
5014
5014
|
});
|
|
5015
5015
|
else {
|
|
5016
|
-
let l = Object.values(a.vs).reduce((
|
|
5016
|
+
let l = Object.values(a.vs).reduce((c, r) => r.length > c ? r.length : c, 0);
|
|
5017
5017
|
i.ts = Array(l + 1).fill(0);
|
|
5018
5018
|
}
|
|
5019
|
-
s ? i.ts = i.ts.map((l) =>
|
|
5020
|
-
for (let [l,
|
|
5021
|
-
const r = this.getBaselineValue(l), h =
|
|
5019
|
+
s ? i.ts = i.ts.map((l) => u + l * t) : i.ts = i.ts.map((l) => this.animClock + u + l * t), a.vs && a.vs.pose;
|
|
5020
|
+
for (let [l, c] of Object.entries(a.vs)) {
|
|
5021
|
+
const r = this.getBaselineValue(l), h = c.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? l === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? "wide" : d.slice() : Array.isArray(d) ? l === "gesture" ? d.slice() : (r === void 0 ? 0 : r) + o * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (r === void 0 ? 0 : r) + o * d));
|
|
5022
5022
|
l === "eyesRotateY" ? (i.vs.eyeLookOutLeft = [null, ...h.map((d) => d > 0 ? d : 0)], i.vs.eyeLookInLeft = [null, ...h.map((d) => d > 0 ? 0 : -d)], i.vs.eyeLookOutRight = [null, ...h.map((d) => d > 0 ? 0 : -d)], i.vs.eyeLookInRight = [null, ...h.map((d) => d > 0 ? d : 0)]) : l === "eyesRotateX" ? (i.vs.eyesLookDown = [null, ...h.map((d) => d > 0 ? d : 0)], i.vs.eyesLookUp = [null, ...h.map((d) => d > 0 ? 0 : -d)]) : i.vs[l] = [null, ...h];
|
|
5023
5023
|
}
|
|
5024
5024
|
for (let l of Object.keys(i.vs))
|
|
@@ -5100,8 +5100,8 @@ class nt {
|
|
|
5100
5100
|
if (this.isSpeaking)
|
|
5101
5101
|
for (a = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), t = 2, s = 10; t < s; t++)
|
|
5102
5102
|
this.volumeFrequencyData[t] > a && (a = this.volumeFrequencyData[t]);
|
|
5103
|
-
let
|
|
5104
|
-
const
|
|
5103
|
+
let u = null, l = null;
|
|
5104
|
+
const c = [];
|
|
5105
5105
|
for (t = 0, s = this.animQueue.length; t < s; t++) {
|
|
5106
5106
|
const r = this.animQueue[t];
|
|
5107
5107
|
if (!(!r || !r.ts || !r.ts.length || this.animClock < r.ts[0])) {
|
|
@@ -5128,12 +5128,12 @@ class nt {
|
|
|
5128
5128
|
g.newvalue *= 1 + a / 255 - 0.5;
|
|
5129
5129
|
}
|
|
5130
5130
|
g.needsUpdate = !0;
|
|
5131
|
-
} else h === "eyeContact" && d[o] !== null &&
|
|
5131
|
+
} else h === "eyeContact" && d[o] !== null && u !== !1 ? u = !!d[o] : h === "headMove" && d[o] !== null && l !== !1 ? d[o] === 0 ? l = !1 : (Math.random() < d[o] && (l = !0), d[o] = null) : d[o] !== null && (c.push({ mt: h, val: d[o] }), d[o] = null);
|
|
5132
5132
|
o === i ? (r.hasOwnProperty("mood") && this.setMood(r.mood), r.loop ? (i = this.isSpeaking && (r.template.name === "head" || r.template.name === "eyes") ? 4 : 1, this.animQueue[t] = this.animFactory(r.template, r.loop > 0 ? r.loop - 1 : r.loop, 1, 1 / i)) : (this.animQueue.splice(t--, 1), s--)) : r.ndx = o - 1;
|
|
5133
5133
|
}
|
|
5134
5134
|
}
|
|
5135
|
-
for (let r = 0, h =
|
|
5136
|
-
switch (o =
|
|
5135
|
+
for (let r = 0, h = c.length; r < h; r++)
|
|
5136
|
+
switch (o = c[r].val, c[r].mt) {
|
|
5137
5137
|
case "speak":
|
|
5138
5138
|
this.speakText(o);
|
|
5139
5139
|
break;
|
|
@@ -5179,7 +5179,7 @@ class nt {
|
|
|
5179
5179
|
}, o.x ? new b.Vector3(o.x, o.y, o.z) : null, !0, o.d);
|
|
5180
5180
|
break;
|
|
5181
5181
|
}
|
|
5182
|
-
if ((
|
|
5182
|
+
if ((u || l) && (oe.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), oe.x = Math.max(-0.9, Math.min(0.9, 2 * oe.x - 0.5)), oe.y = Math.max(-0.9, Math.min(0.9, -2.5 * oe.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: oe.x < 0 ? -oe.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: oe.x < 0 ? 0 : oe.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), l && (t = -this.mtAvatar.bodyRotateY.value, o = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5183
5183
|
name: "headmove",
|
|
5184
5184
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5185
5185
|
vs: {
|
|
@@ -5200,11 +5200,11 @@ class nt {
|
|
|
5200
5200
|
eyeLookOutRight: [null, 0],
|
|
5201
5201
|
eyeContact: [0]
|
|
5202
5202
|
}
|
|
5203
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (t = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], o = this.mtAvatar[t], o.needsUpdate || Object.assign(o, { base: (this.mood.baseline[t] || 0) + (1 + a / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && (this.mixer.update(e / 1e3 * this.mixer.timeScale), this.currentFBXActionForCallback && this.currentFBXActionForCallback.isRunning() && this.
|
|
5203
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (t = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], o = this.mtAvatar[t], o.needsUpdate || Object.assign(o, { base: (this.mood.baseline[t] || 0) + (1 + a / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && (this.mixer.update(e / 1e3 * this.mixer.timeScale), this.currentFBXActionForCallback && this.currentFBXActionForCallback.isRunning() && this.currentFBXActionClipDuration)) {
|
|
5204
5204
|
const r = this.currentFBXActionForCallback.time, h = this.currentFBXActionClipDuration;
|
|
5205
|
-
r >= h - 0.
|
|
5205
|
+
(r >= h - 0.05 || r > 0 && !this.currentFBXActionForCallback.paused && r >= h - 0.1) && (this.currentFBXActionCallback && (this.currentFBXActionCallback(), this.currentFBXActionCallback = null), this.currentFBXActionForCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null);
|
|
5206
5206
|
}
|
|
5207
|
-
if (this.updatePoseDelta(), (this.isSpeaking || this.isListening) &&
|
|
5207
|
+
if (this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? a > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = a) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), t = this.volumeHeadTarget - this.volumeHeadCurrent, o = Math.abs(t), o > 1e-4 && (i = o * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / o) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(t) * Math.min(o, i)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (ue.setFromAxisAngle(Bt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(ue)), at.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Ue), Ue.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Xe), Xe.sub(this.armature.position), this.objectHips.position.y -= at.min.y / 2, this.objectHips.position.x -= (Ue.x + Xe.x) / 4, this.objectHips.position.z -= (Ue.z + Xe.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5208
5208
|
this.stats && this.stats.end();
|
|
5209
5209
|
else {
|
|
5210
5210
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5271,24 +5271,24 @@ class nt {
|
|
|
5271
5271
|
*/
|
|
5272
5272
|
speakText(n, e = null, t = null, o = null) {
|
|
5273
5273
|
e = e || {};
|
|
5274
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, i = /[ ]/ug, a = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5275
|
-
let
|
|
5274
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, i = /[ ]/ug, a = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, l = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5275
|
+
let c = "", r = "", h = 0, d = [], g = [];
|
|
5276
5276
|
const R = Array.from(this.segmenter.segment(n), (x) => x.segment);
|
|
5277
5277
|
for (let x = 0; x < R.length; x++) {
|
|
5278
5278
|
const k = x === R.length - 1, G = R[x].match(a);
|
|
5279
5279
|
let m = R[x].match(s);
|
|
5280
|
-
const D = R[x].match(
|
|
5281
|
-
if (m && !k && !D && R[x + 1].match(s) && (m = !1), t && (
|
|
5280
|
+
const D = R[x].match(u), E = R[x].match(i);
|
|
5281
|
+
if (m && !k && !D && R[x + 1].match(s) && (m = !1), t && (c += R[x]), G && (!o || o.every((y) => x < y[0] || x > y[1])) && (r += R[x]), (E || m || k) && (r.length && (r = this.lipsyncPreProcessText(r, l), r.length && d.push({
|
|
5282
5282
|
mark: h,
|
|
5283
5283
|
word: r
|
|
5284
|
-
})),
|
|
5284
|
+
})), c.length && (g.push({
|
|
5285
5285
|
mark: h,
|
|
5286
5286
|
template: { name: "subtitles" },
|
|
5287
5287
|
ts: [0],
|
|
5288
5288
|
vs: {
|
|
5289
|
-
subtitles: [
|
|
5289
|
+
subtitles: [c]
|
|
5290
5290
|
}
|
|
5291
|
-
}),
|
|
5291
|
+
}), c = ""), r.length)) {
|
|
5292
5292
|
const y = this.lipsyncWordsToVisemes(r, l);
|
|
5293
5293
|
if (y && y.visemes && y.visemes.length) {
|
|
5294
5294
|
const P = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
@@ -5394,22 +5394,22 @@ class nt {
|
|
|
5394
5394
|
if (n.words) {
|
|
5395
5395
|
let i = [];
|
|
5396
5396
|
for (let a = 0; a < n.words.length; a++) {
|
|
5397
|
-
const
|
|
5398
|
-
let
|
|
5399
|
-
if (
|
|
5397
|
+
const u = n.words[a], l = n.wtimes[a];
|
|
5398
|
+
let c = n.wdurations[a];
|
|
5399
|
+
if (u.length && (t && i.push({
|
|
5400
5400
|
template: { name: "subtitles" },
|
|
5401
5401
|
ts: [l],
|
|
5402
5402
|
vs: {
|
|
5403
|
-
subtitles: [" " +
|
|
5403
|
+
subtitles: [" " + u]
|
|
5404
5404
|
}
|
|
5405
5405
|
}), !n.visemes)) {
|
|
5406
|
-
const r = this.lipsyncPreProcessText(
|
|
5406
|
+
const r = this.lipsyncPreProcessText(u, o), h = this.lipsyncWordsToVisemes(r, o);
|
|
5407
5407
|
if (h && h.visemes && h.visemes.length) {
|
|
5408
|
-
const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], g = Math.min(
|
|
5409
|
-
let R = 0.6 + this.convertRange(g, [0,
|
|
5410
|
-
if (
|
|
5408
|
+
const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], g = Math.min(c, Math.max(0, c - h.visemes.length * 150));
|
|
5409
|
+
let R = 0.6 + this.convertRange(g, [0, c], [0, 0.4]);
|
|
5410
|
+
if (c = Math.min(c, h.visemes.length * 200), d > 0)
|
|
5411
5411
|
for (let x = 0; x < h.visemes.length; x++) {
|
|
5412
|
-
const k = l + h.times[x] / d *
|
|
5412
|
+
const k = l + h.times[x] / d * c, G = h.durations[x] / d * c;
|
|
5413
5413
|
i.push({
|
|
5414
5414
|
template: { name: "viseme" },
|
|
5415
5415
|
ts: [k - Math.min(60, 2 * G / 3), k + Math.min(25, G / 2), k + G + Math.min(60, G / 2)],
|
|
@@ -5423,22 +5423,22 @@ class nt {
|
|
|
5423
5423
|
}
|
|
5424
5424
|
if (n.visemes)
|
|
5425
5425
|
for (let a = 0; a < n.visemes.length; a++) {
|
|
5426
|
-
const
|
|
5426
|
+
const u = n.visemes[a], l = n.vtimes[a], c = n.vdurations[a];
|
|
5427
5427
|
i.push({
|
|
5428
5428
|
template: { name: "viseme" },
|
|
5429
|
-
ts: [l - 2 *
|
|
5429
|
+
ts: [l - 2 * c / 3, l + c / 2, l + c + c / 2],
|
|
5430
5430
|
vs: {
|
|
5431
|
-
["viseme_" +
|
|
5431
|
+
["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
|
|
5432
5432
|
}
|
|
5433
5433
|
});
|
|
5434
5434
|
}
|
|
5435
5435
|
if (n.markers)
|
|
5436
5436
|
for (let a = 0; a < n.markers.length; a++) {
|
|
5437
|
-
const
|
|
5437
|
+
const u = n.markers[a], l = n.mtimes[a];
|
|
5438
5438
|
i.push({
|
|
5439
5439
|
template: { name: "markers" },
|
|
5440
5440
|
ts: [l],
|
|
5441
|
-
vs: { function: [
|
|
5441
|
+
vs: { function: [u] }
|
|
5442
5442
|
});
|
|
5443
5443
|
}
|
|
5444
5444
|
i.length && (s.anim = i);
|
|
@@ -5464,7 +5464,7 @@ class nt {
|
|
|
5464
5464
|
delay: e.delay || 0
|
|
5465
5465
|
};
|
|
5466
5466
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5467
|
-
const s = this.audioCtx.resume(), i = new Promise((a,
|
|
5467
|
+
const s = this.audioCtx.resume(), i = new Promise((a, u) => setTimeout(() => u("p2"), 1e3));
|
|
5468
5468
|
try {
|
|
5469
5469
|
await Promise.race([s, i]);
|
|
5470
5470
|
} catch {
|
|
@@ -5489,7 +5489,7 @@ class nt {
|
|
|
5489
5489
|
template: i.template,
|
|
5490
5490
|
// Trimmed timestamps are relative (ms), add base clock to make absolute
|
|
5491
5491
|
// This ensures lip-sync continues from the exact resume point
|
|
5492
|
-
ts: i.ts.map((
|
|
5492
|
+
ts: i.ts.map((u) => s + u),
|
|
5493
5493
|
vs: i.vs
|
|
5494
5494
|
};
|
|
5495
5495
|
this.animQueue.push(a);
|
|
@@ -5502,9 +5502,9 @@ class nt {
|
|
|
5502
5502
|
if (this.audioPlaylist.length) {
|
|
5503
5503
|
const t = this.audioPlaylist.shift();
|
|
5504
5504
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5505
|
-
const a = this.audioCtx.resume(),
|
|
5505
|
+
const a = this.audioCtx.resume(), u = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
|
|
5506
5506
|
try {
|
|
5507
|
-
await Promise.race([a,
|
|
5507
|
+
await Promise.race([a, u]);
|
|
5508
5508
|
} catch {
|
|
5509
5509
|
console.log("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."), this.playAudio(!0);
|
|
5510
5510
|
return;
|
|
@@ -5529,8 +5529,8 @@ class nt {
|
|
|
5529
5529
|
this.audioStartTime = this.audioCtx.currentTime + i, this.audioSpeechSource.addEventListener("ended", () => {
|
|
5530
5530
|
this.audioSpeechSource.disconnect(), this.audioStartTime = null, this.currentAudioItem = null, this.isSpeaking = !0, this.playAudio(!0);
|
|
5531
5531
|
}, { once: !0 }), t.anim && t.anim.forEach((a) => {
|
|
5532
|
-
for (let
|
|
5533
|
-
a.ts[
|
|
5532
|
+
for (let u = 0; u < a.ts.length; u++)
|
|
5533
|
+
a.ts[u] = this.animClock + a.ts[u] + s;
|
|
5534
5534
|
this.animQueue.push(a);
|
|
5535
5535
|
}), this.audioSpeechSource.start(i);
|
|
5536
5536
|
} else
|
|
@@ -5543,11 +5543,11 @@ class nt {
|
|
|
5543
5543
|
*/
|
|
5544
5544
|
async synthesizeWithBrowserTTS(n) {
|
|
5545
5545
|
return new Promise((e, t) => {
|
|
5546
|
-
const o = Array.isArray(n.text) ? n.text.map((m) => m.word).join(" ") : typeof n.text == "string" ? n.text : "", s = new SpeechSynthesisUtterance(o), i = n.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", a = (n.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5547
|
-
s.lang = i, s.rate = Math.max(0.1, Math.min(10, a)), s.pitch = Math.max(0, Math.min(2,
|
|
5548
|
-
const
|
|
5549
|
-
if (r &&
|
|
5550
|
-
const m =
|
|
5546
|
+
const o = Array.isArray(n.text) ? n.text.map((m) => m.word).join(" ") : typeof n.text == "string" ? n.text : "", s = new SpeechSynthesisUtterance(o), i = n.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", a = (n.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (n.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, l = (n.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5547
|
+
s.lang = i, s.rate = Math.max(0.1, Math.min(10, a)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, l));
|
|
5548
|
+
const c = speechSynthesis.getVoices(), r = n.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5549
|
+
if (r && c.length > 0) {
|
|
5550
|
+
const m = c.find((D) => D.name.includes(r) || D.lang === i);
|
|
5551
5551
|
m && (s.voice = m);
|
|
5552
5552
|
}
|
|
5553
5553
|
const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g), k = [];
|
|
@@ -5597,15 +5597,15 @@ class nt {
|
|
|
5597
5597
|
});
|
|
5598
5598
|
if (!s.ok)
|
|
5599
5599
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5600
|
-
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i),
|
|
5600
|
+
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5601
5601
|
let l;
|
|
5602
5602
|
try {
|
|
5603
5603
|
console.log("Lip-sync modules available:", {
|
|
5604
5604
|
hasLipsync: !!this.lipsync,
|
|
5605
5605
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5606
|
-
lipsyncLang:
|
|
5606
|
+
lipsyncLang: u
|
|
5607
5607
|
});
|
|
5608
|
-
const h = this.lipsyncPreProcessText(e,
|
|
5608
|
+
const h = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(h, u);
|
|
5609
5609
|
if (console.log("Lip-sync data:", {
|
|
5610
5610
|
processedText: h,
|
|
5611
5611
|
lipsyncData: d,
|
|
@@ -5646,11 +5646,11 @@ class nt {
|
|
|
5646
5646
|
features: { onsets: [], boundaries: [] }
|
|
5647
5647
|
};
|
|
5648
5648
|
}
|
|
5649
|
-
const
|
|
5649
|
+
const c = [];
|
|
5650
5650
|
if (l.visemes && l.visemes.length > 0)
|
|
5651
5651
|
for (let h = 0; h < l.visemes.length; h++) {
|
|
5652
5652
|
const d = l.visemes[h], g = d.startTime * 1e3, R = d.duration * 1e3, x = d.intensity;
|
|
5653
|
-
|
|
5653
|
+
c.push({
|
|
5654
5654
|
template: { name: "viseme" },
|
|
5655
5655
|
ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
|
|
5656
5656
|
vs: {
|
|
@@ -5660,7 +5660,7 @@ class nt {
|
|
|
5660
5660
|
}
|
|
5661
5661
|
else
|
|
5662
5662
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5663
|
-
const r = [...n.anim, ...
|
|
5663
|
+
const r = [...n.anim, ...c];
|
|
5664
5664
|
this.audioPlaylist.push({ anim: r, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5665
5665
|
}
|
|
5666
5666
|
/**
|
|
@@ -5679,15 +5679,15 @@ class nt {
|
|
|
5679
5679
|
});
|
|
5680
5680
|
if (!s.ok)
|
|
5681
5681
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5682
|
-
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i),
|
|
5682
|
+
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5683
5683
|
let l;
|
|
5684
5684
|
try {
|
|
5685
5685
|
console.log("Lip-sync modules available:", {
|
|
5686
5686
|
hasLipsync: !!this.lipsync,
|
|
5687
5687
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5688
|
-
lipsyncLang:
|
|
5688
|
+
lipsyncLang: u
|
|
5689
5689
|
});
|
|
5690
|
-
const h = this.lipsyncPreProcessText(e,
|
|
5690
|
+
const h = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(h, u);
|
|
5691
5691
|
if (console.log("Lip-sync data:", {
|
|
5692
5692
|
processedText: h,
|
|
5693
5693
|
lipsyncData: d,
|
|
@@ -5728,11 +5728,11 @@ class nt {
|
|
|
5728
5728
|
features: { onsets: [], boundaries: [] }
|
|
5729
5729
|
};
|
|
5730
5730
|
}
|
|
5731
|
-
const
|
|
5731
|
+
const c = [];
|
|
5732
5732
|
if (l.visemes && l.visemes.length > 0)
|
|
5733
5733
|
for (let h = 0; h < l.visemes.length; h++) {
|
|
5734
5734
|
const d = l.visemes[h], g = d.startTime * 1e3, R = d.duration * 1e3, x = d.intensity;
|
|
5735
|
-
|
|
5735
|
+
c.push({
|
|
5736
5736
|
template: { name: "viseme" },
|
|
5737
5737
|
ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
|
|
5738
5738
|
vs: {
|
|
@@ -5742,7 +5742,7 @@ class nt {
|
|
|
5742
5742
|
}
|
|
5743
5743
|
else
|
|
5744
5744
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5745
|
-
const r = [...n.anim, ...
|
|
5745
|
+
const r = [...n.anim, ...c];
|
|
5746
5746
|
this.audioPlaylist.push({ anim: r, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5747
5747
|
}
|
|
5748
5748
|
/**
|
|
@@ -5767,9 +5767,9 @@ class nt {
|
|
|
5767
5767
|
});
|
|
5768
5768
|
if (!s.ok)
|
|
5769
5769
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5770
|
-
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i),
|
|
5771
|
-
for (let r = 0; r <
|
|
5772
|
-
const h =
|
|
5770
|
+
const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = await this.audioAnalyzer.analyzeAudio(a, e), l = [];
|
|
5771
|
+
for (let r = 0; r < u.visemes.length; r++) {
|
|
5772
|
+
const h = u.visemes[r], d = h.startTime * 1e3, g = h.duration * 1e3, R = h.intensity;
|
|
5773
5773
|
l.push({
|
|
5774
5774
|
template: { name: "viseme" },
|
|
5775
5775
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
@@ -5778,8 +5778,8 @@ class nt {
|
|
|
5778
5778
|
}
|
|
5779
5779
|
});
|
|
5780
5780
|
}
|
|
5781
|
-
const
|
|
5782
|
-
this.audioPlaylist.push({ anim:
|
|
5781
|
+
const c = [...n.anim, ...l];
|
|
5782
|
+
this.audioPlaylist.push({ anim: c, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
|
|
5783
5783
|
}
|
|
5784
5784
|
/**
|
|
5785
5785
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5818,24 +5818,24 @@ class nt {
|
|
|
5818
5818
|
if (o.status === 200 && s && s.audioContent) {
|
|
5819
5819
|
const i = this.b64ToArrayBuffer(s.audioContent), a = await this.audioCtx.decodeAudioData(i);
|
|
5820
5820
|
this.speakWithHands();
|
|
5821
|
-
const
|
|
5821
|
+
const u = [0];
|
|
5822
5822
|
let l = 0;
|
|
5823
5823
|
n.text.forEach((h, d) => {
|
|
5824
5824
|
if (d > 0) {
|
|
5825
|
-
let g =
|
|
5826
|
-
s.timepoints[l] && (g = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++),
|
|
5825
|
+
let g = u[u.length - 1];
|
|
5826
|
+
s.timepoints[l] && (g = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++), u.push(g);
|
|
5827
5827
|
}
|
|
5828
5828
|
});
|
|
5829
|
-
const
|
|
5830
|
-
|
|
5829
|
+
const c = [{ mark: 0, time: 0 }];
|
|
5830
|
+
u.forEach((h, d) => {
|
|
5831
5831
|
if (d > 0) {
|
|
5832
|
-
let g = h -
|
|
5833
|
-
|
|
5832
|
+
let g = h - u[d - 1];
|
|
5833
|
+
c[d - 1].duration = g, c.push({ mark: d, time: h });
|
|
5834
5834
|
}
|
|
5835
5835
|
});
|
|
5836
5836
|
let r = 1e3 * a.duration;
|
|
5837
|
-
r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd),
|
|
5838
|
-
const d =
|
|
5837
|
+
r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), c[c.length - 1].duration = r - c[c.length - 1].time, n.anim.forEach((h) => {
|
|
5838
|
+
const d = c[h.mark];
|
|
5839
5839
|
if (d)
|
|
5840
5840
|
for (let g = 0; g < h.ts.length; g++)
|
|
5841
5841
|
h.ts[g] = d.time + h.ts[g] * d.duration + this.opt.ttsTrimStart;
|
|
@@ -5883,17 +5883,17 @@ class nt {
|
|
|
5883
5883
|
let n = null;
|
|
5884
5884
|
if (this.audioSpeechSource && this.currentAudioItem && this.audioStartTime !== null)
|
|
5885
5885
|
try {
|
|
5886
|
-
const e = this.audioCtx.currentTime, t = Math.max(0, e - this.audioStartTime), o = this.audioSpeechSource.playbackRate.value, s = t * o, i = this.currentAudioItem.audio, a = i.sampleRate,
|
|
5887
|
-
if (
|
|
5888
|
-
const l = i.length -
|
|
5886
|
+
const e = this.audioCtx.currentTime, t = Math.max(0, e - this.audioStartTime), o = this.audioSpeechSource.playbackRate.value, s = t * o, i = this.currentAudioItem.audio, a = i.sampleRate, u = Math.floor(s * a);
|
|
5887
|
+
if (u < i.length) {
|
|
5888
|
+
const l = i.length - u, c = this.audioCtx.createBuffer(
|
|
5889
5889
|
i.numberOfChannels,
|
|
5890
5890
|
l,
|
|
5891
5891
|
a
|
|
5892
5892
|
);
|
|
5893
5893
|
for (let h = 0; h < i.numberOfChannels; h++) {
|
|
5894
|
-
const d = i.getChannelData(h), g =
|
|
5894
|
+
const d = i.getChannelData(h), g = c.getChannelData(h);
|
|
5895
5895
|
for (let R = 0; R < l; R++)
|
|
5896
|
-
g[R] = d[
|
|
5896
|
+
g[R] = d[u + R];
|
|
5897
5897
|
}
|
|
5898
5898
|
let r = null;
|
|
5899
5899
|
if (this.currentAudioItem.anim) {
|
|
@@ -5915,7 +5915,7 @@ class nt {
|
|
|
5915
5915
|
}).filter((R) => R !== null);
|
|
5916
5916
|
}
|
|
5917
5917
|
n = {
|
|
5918
|
-
audio:
|
|
5918
|
+
audio: c,
|
|
5919
5919
|
anim: r,
|
|
5920
5920
|
text: this.currentAudioItem.text,
|
|
5921
5921
|
delay: 0,
|
|
@@ -5967,10 +5967,10 @@ class nt {
|
|
|
5967
5967
|
}
|
|
5968
5968
|
if (!this.workletLoaded)
|
|
5969
5969
|
try {
|
|
5970
|
-
const a = this.audioCtx.audioWorklet.addModule(Pt.href),
|
|
5971
|
-
(l,
|
|
5970
|
+
const a = this.audioCtx.audioWorklet.addModule(Pt.href), u = new Promise(
|
|
5971
|
+
(l, c) => setTimeout(() => c(new Error("Worklet loading timed out")), 5e3)
|
|
5972
5972
|
);
|
|
5973
|
-
await Promise.race([a,
|
|
5973
|
+
await Promise.race([a, u]), this.workletLoaded = !0;
|
|
5974
5974
|
} catch (a) {
|
|
5975
5975
|
throw console.error("Failed to load audio worklet:", a), new Error("Failed to initialize streaming speech");
|
|
5976
5976
|
}
|
|
@@ -5983,8 +5983,8 @@ class nt {
|
|
|
5983
5983
|
if (a.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5984
5984
|
try {
|
|
5985
5985
|
this.onAudioStart?.();
|
|
5986
|
-
} catch (
|
|
5987
|
-
console.error(
|
|
5986
|
+
} catch (u) {
|
|
5987
|
+
console.error(u);
|
|
5988
5988
|
}
|
|
5989
5989
|
if (a.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5990
5990
|
try {
|
|
@@ -6004,9 +6004,9 @@ class nt {
|
|
|
6004
6004
|
} catch {
|
|
6005
6005
|
}
|
|
6006
6006
|
if (this.resetLips(), this.lookAtCamera(500), n.mood && this.setMood(n.mood), this.onSubtitles = o || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
6007
|
-
const a = this.audioCtx.resume(),
|
|
6007
|
+
const a = this.audioCtx.resume(), u = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
|
|
6008
6008
|
try {
|
|
6009
|
-
await Promise.race([a,
|
|
6009
|
+
await Promise.race([a, u]);
|
|
6010
6010
|
} catch {
|
|
6011
6011
|
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.");
|
|
6012
6012
|
return;
|
|
@@ -6103,13 +6103,13 @@ class nt {
|
|
|
6103
6103
|
subtitles: [" " + o]
|
|
6104
6104
|
}
|
|
6105
6105
|
}), this.streamLipsyncType == "words")) {
|
|
6106
|
-
const a = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6106
|
+
const a = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(o, a), l = this.lipsyncWordsToVisemes(u, a);
|
|
6107
6107
|
if (l && l.visemes && l.visemes.length) {
|
|
6108
|
-
const
|
|
6108
|
+
const c = l.times[l.visemes.length - 1] + l.durations[l.visemes.length - 1], r = Math.min(i, Math.max(0, i - l.visemes.length * 150));
|
|
6109
6109
|
let h = 0.6 + this.convertRange(r, [0, i], [0, 0.4]);
|
|
6110
|
-
if (i = Math.min(i, l.visemes.length * 200),
|
|
6110
|
+
if (i = Math.min(i, l.visemes.length * 200), c > 0)
|
|
6111
6111
|
for (let d = 0; d < l.visemes.length; d++) {
|
|
6112
|
-
const g = e + s + l.times[d] /
|
|
6112
|
+
const g = e + s + l.times[d] / c * i, R = l.durations[d] / c * i;
|
|
6113
6113
|
this.animQueue.push({
|
|
6114
6114
|
template: { name: "viseme" },
|
|
6115
6115
|
ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
|
|
@@ -6218,12 +6218,12 @@ class nt {
|
|
|
6218
6218
|
this.lookAt(null, null, n);
|
|
6219
6219
|
return;
|
|
6220
6220
|
}
|
|
6221
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Xe.setFromMatrixPosition(this.objectRightEye.matrixWorld), Ue.add(Xe).divideScalar(2),
|
|
6221
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Xe.setFromMatrixPosition(this.objectRightEye.matrixWorld), Ue.add(Xe).divideScalar(2), ue.copy(this.armature.quaternion), ue.multiply(this.poseTarget.props["Hips.quaternion"]), ue.multiply(this.poseTarget.props["Spine.quaternion"]), ue.multiply(this.poseTarget.props["Spine1.quaternion"]), ue.multiply(this.poseTarget.props["Spine2.quaternion"]), ue.multiply(this.poseTarget.props["Neck.quaternion"]), ue.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6222
6222
|
const t = new b.Vector3().subVectors(e, Ue).normalize(), o = Math.atan2(t.x, t.z), s = Math.asin(-t.y);
|
|
6223
6223
|
oe.set(s, o, 0, "YXZ");
|
|
6224
|
-
const a = new b.Quaternion().setFromEuler(oe),
|
|
6225
|
-
oe.setFromQuaternion(
|
|
6226
|
-
let l = oe.x / (40 / 24) + 0.2,
|
|
6224
|
+
const a = new b.Quaternion().setFromEuler(oe), u = new b.Quaternion().copy(a).multiply(ue.clone().invert());
|
|
6225
|
+
oe.setFromQuaternion(u, "YXZ");
|
|
6226
|
+
let l = oe.x / (40 / 24) + 0.2, c = oe.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, l)), h = Math.min(0.8, Math.max(-0.8, c)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6227
6227
|
if (n) {
|
|
6228
6228
|
let R = this.animQueue.findIndex((k) => k.template.name === "lookat");
|
|
6229
6229
|
R !== -1 && this.animQueue.splice(R, 1);
|
|
@@ -6257,9 +6257,9 @@ class nt {
|
|
|
6257
6257
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6258
6258
|
const s = new b.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), i = new b.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), a = new b.Vector3().addVectors(s, i).divideScalar(2);
|
|
6259
6259
|
a.project(this.camera);
|
|
6260
|
-
let
|
|
6261
|
-
n === null && (n =
|
|
6262
|
-
let
|
|
6260
|
+
let u = (a.x + 1) / 2 * o.width + o.left, l = -(a.y - 1) / 2 * o.height + o.top;
|
|
6261
|
+
n === null && (n = u), e === null && (e = l), ue.copy(this.armature.quaternion), ue.multiply(this.poseTarget.props["Hips.quaternion"]), ue.multiply(this.poseTarget.props["Spine.quaternion"]), ue.multiply(this.poseTarget.props["Spine1.quaternion"]), ue.multiply(this.poseTarget.props["Spine2.quaternion"]), ue.multiply(this.poseTarget.props["Neck.quaternion"]), ue.multiply(this.poseTarget.props["Head.quaternion"]), oe.setFromQuaternion(ue);
|
|
6262
|
+
let c = oe.x / (40 / 24), r = oe.y / (9 / 4), h = 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), R = Math.max(window.innerHeight - l, l), x = this.convertRange(e, [l - R, l + R], [-0.3, 0.6]) - c + h, k = this.convertRange(n, [u - g, u + g], [-0.8, 0.8]) - r + d;
|
|
6263
6263
|
x = Math.min(0.6, Math.max(-0.3, x)), k = Math.min(0.8, Math.max(-0.8, k));
|
|
6264
6264
|
let G = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
|
|
6265
6265
|
if (t) {
|
|
@@ -6298,10 +6298,10 @@ class nt {
|
|
|
6298
6298
|
s.setFromCamera(o, this.camera);
|
|
6299
6299
|
const i = s.intersectObject(this.armature);
|
|
6300
6300
|
if (i.length > 0) {
|
|
6301
|
-
const a = i[0].point,
|
|
6302
|
-
this.objectLeftArm.getWorldPosition(
|
|
6303
|
-
const
|
|
6304
|
-
|
|
6301
|
+
const a = i[0].point, u = new b.Vector3(), l = new b.Vector3();
|
|
6302
|
+
this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(l);
|
|
6303
|
+
const c = u.distanceToSquared(a), r = l.distanceToSquared(a);
|
|
6304
|
+
c < r ? (this.ikSolve({
|
|
6305
6305
|
iterations: 20,
|
|
6306
6306
|
root: "LeftShoulder",
|
|
6307
6307
|
effector: "LeftHandMiddle1",
|
|
@@ -6322,8 +6322,8 @@ class nt {
|
|
|
6322
6322
|
}, a, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6323
6323
|
} else
|
|
6324
6324
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((a) => {
|
|
6325
|
-
let
|
|
6326
|
-
this.poseTarget.props[
|
|
6325
|
+
let u = a + ".quaternion";
|
|
6326
|
+
this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
|
|
6327
6327
|
});
|
|
6328
6328
|
return i.length > 0;
|
|
6329
6329
|
}
|
|
@@ -6442,24 +6442,24 @@ class nt {
|
|
|
6442
6442
|
async playAnimation(n, e = null, t = 10, o = 0, s = 0.01, i = !1, a = null) {
|
|
6443
6443
|
if (!this.armature) return;
|
|
6444
6444
|
this.positionWasLocked = !i, i || this.lockAvatarPosition();
|
|
6445
|
-
let
|
|
6446
|
-
if (
|
|
6445
|
+
let u = this.animClips.find((l) => l.url === n + "-" + o);
|
|
6446
|
+
if (u) {
|
|
6447
6447
|
let l = this.animQueue.find((h) => h.template.name === "pose");
|
|
6448
|
-
l && (l.ts[0] = 1 / 0), Object.entries(
|
|
6448
|
+
l && (l.ts[0] = 1 / 0), Object.entries(u.pose.props).forEach((h) => {
|
|
6449
6449
|
this.poseBase.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]].t = 0, this.poseTarget.props[h[0]].d = 1e3;
|
|
6450
6450
|
}), this.mixer || (this.mixer = new b.AnimationMixer(this.armature)), this.animationFinishedCallback = a;
|
|
6451
|
-
const
|
|
6451
|
+
const c = () => {
|
|
6452
6452
|
this.animationFinishedCallback && (this.animationFinishedCallback(), this.animationFinishedCallback = null), this.stopAnimation();
|
|
6453
|
-
}, r = this.mixer.clipAction(
|
|
6453
|
+
}, r = this.mixer.clipAction(u.clip);
|
|
6454
6454
|
if (t <= 0)
|
|
6455
6455
|
r.setLoop(b.LoopOnce, 1);
|
|
6456
6456
|
else {
|
|
6457
|
-
const h = Math.ceil(t /
|
|
6457
|
+
const h = Math.ceil(t / u.clip.duration);
|
|
6458
6458
|
r.setLoop(b.LoopRepeat, h);
|
|
6459
6459
|
}
|
|
6460
|
-
if (r.clampWhenFinished = !0, this.mixer.addEventListener("finished",
|
|
6460
|
+
if (r.clampWhenFinished = !0, this.mixer.addEventListener("finished", c, { once: !0 }), this.currentFBXActionForCallback = r, this.currentFBXActionCallback = c, this.currentFBXActionClipDuration = u.clip.duration, this.currentFBXActionStartTime = null, this.currentFBXAction && this.currentFBXAction.isRunning()) {
|
|
6461
6461
|
this.currentFBXAction.fadeOut(0.3), setTimeout(() => {
|
|
6462
|
-
this.currentFBXAction = r, this.currentFBXActionStartTime = this.mixer.time;
|
|
6462
|
+
this.currentFBXAction = r, this.currentFBXActionForCallback = r, this.currentFBXActionCallback = c, this.currentFBXActionClipDuration = u.clip.duration, this.currentFBXActionStartTime = this.mixer.time;
|
|
6463
6463
|
try {
|
|
6464
6464
|
r.fadeIn(0.5).play(), console.log("FBX animation started successfully (with fade transition):", n);
|
|
6465
6465
|
} catch (h) {
|
|
@@ -6484,10 +6484,10 @@ class nt {
|
|
|
6484
6484
|
console.error(`Invalid file type for FBX animation: ${n}. Expected .fbx file.`);
|
|
6485
6485
|
return;
|
|
6486
6486
|
}
|
|
6487
|
-
let
|
|
6487
|
+
let c = !1;
|
|
6488
6488
|
try {
|
|
6489
6489
|
const d = await fetch(n, { method: "HEAD" });
|
|
6490
|
-
if (
|
|
6490
|
+
if (c = d.ok, !c) {
|
|
6491
6491
|
console.error(`FBX file not found at ${n}. Status: ${d.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
|
|
6492
6492
|
return;
|
|
6493
6493
|
}
|
|
@@ -6669,25 +6669,25 @@ class nt {
|
|
|
6669
6669
|
if (!this.armature) return;
|
|
6670
6670
|
let i = this.poseTemplates[n];
|
|
6671
6671
|
if (!i) {
|
|
6672
|
-
const a = this.animPoses.find((
|
|
6672
|
+
const a = this.animPoses.find((u) => u.url === n + "-" + o);
|
|
6673
6673
|
a && (i = a.pose);
|
|
6674
6674
|
}
|
|
6675
6675
|
if (i) {
|
|
6676
6676
|
this.poseName = n, this.mixer = null;
|
|
6677
|
-
let a = this.animQueue.find((
|
|
6677
|
+
let a = this.animQueue.find((u) => u.template.name === "pose");
|
|
6678
6678
|
a && (a.ts[0] = this.animClock + t * 1e3 + 2e3), this.setPoseFromTemplate(i);
|
|
6679
6679
|
} else {
|
|
6680
|
-
let
|
|
6681
|
-
if (
|
|
6682
|
-
let l =
|
|
6683
|
-
const
|
|
6680
|
+
let u = await new ot().loadAsync(n, e);
|
|
6681
|
+
if (u && u.animations && u.animations[o]) {
|
|
6682
|
+
let l = u.animations[o];
|
|
6683
|
+
const c = {};
|
|
6684
6684
|
l.tracks.forEach((h) => {
|
|
6685
6685
|
h.name = h.name.replaceAll("mixamorig", "");
|
|
6686
6686
|
const d = h.name.split(".");
|
|
6687
|
-
d[1] === "position" ?
|
|
6687
|
+
d[1] === "position" ? c[h.name] = new b.Vector3(h.values[0] * s, h.values[1] * s, h.values[2] * s) : d[1] === "quaternion" ? c[h.name] = new b.Quaternion(h.values[0], h.values[1], h.values[2], h.values[3]) : d[1] === "rotation" && (c[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(h.values[0], h.values[1], h.values[2], "XYZ")).normalize());
|
|
6688
6688
|
});
|
|
6689
|
-
const r = { props:
|
|
6690
|
-
|
|
6689
|
+
const r = { props: c };
|
|
6690
|
+
c["Hips.position"] && (c["Hips.position"].y < 0.5 ? r.lying = !0 : r.standing = !0), this.animPoses.push({
|
|
6691
6691
|
url: n + "-" + o,
|
|
6692
6692
|
pose: r
|
|
6693
6693
|
}), this.playPose(n, e, t, o, s);
|
|
@@ -6716,10 +6716,10 @@ class nt {
|
|
|
6716
6716
|
let s = this.gestureTemplates[n];
|
|
6717
6717
|
if (s) {
|
|
6718
6718
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6719
|
-
let a = this.animQueue.findIndex((
|
|
6720
|
-
a !== -1 && (this.animQueue[a].ts = this.animQueue[a].ts.map((
|
|
6721
|
-
for (let [
|
|
6722
|
-
l.t = this.animClock, l.d = o, this.poseTarget.props.hasOwnProperty(
|
|
6719
|
+
let a = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
|
|
6720
|
+
a !== -1 && (this.animQueue[a].ts = this.animQueue[a].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), t && (this.gesture = this.mirrorPose(this.gesture)), n === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
|
|
6721
|
+
for (let [u, l] of Object.entries(this.gesture))
|
|
6722
|
+
l.t = this.animClock, l.d = o, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(l), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = o);
|
|
6723
6723
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, o), 1e3 * e));
|
|
6724
6724
|
}
|
|
6725
6725
|
let i = this.animEmojis[n];
|
|
@@ -6727,15 +6727,15 @@ class nt {
|
|
|
6727
6727
|
this.lookAtCamera(500);
|
|
6728
6728
|
const a = this.animFactory(i);
|
|
6729
6729
|
if (a.gesture = !0, e && Number.isFinite(e)) {
|
|
6730
|
-
const
|
|
6731
|
-
if (e * 1e3 -
|
|
6730
|
+
const u = a.ts[0], c = a.ts[a.ts.length - 1] - u;
|
|
6731
|
+
if (e * 1e3 - c > 0) {
|
|
6732
6732
|
const h = [];
|
|
6733
6733
|
for (let R = 1; R < a.ts.length; R++) h.push(a.ts[R] - a.ts[R - 1]);
|
|
6734
|
-
const d = i.template?.rescale || h.map((R) => R /
|
|
6735
|
-
a.ts = a.ts.map((R, x, k) => x === 0 ?
|
|
6734
|
+
const d = i.template?.rescale || h.map((R) => R / c), g = e * 1e3 - c;
|
|
6735
|
+
a.ts = a.ts.map((R, x, k) => x === 0 ? u : k[x - 1] + h[x - 1] + d[x - 1] * g);
|
|
6736
6736
|
} else {
|
|
6737
|
-
const h = e * 1e3 /
|
|
6738
|
-
a.ts = a.ts.map((d) =>
|
|
6737
|
+
const h = e * 1e3 / c;
|
|
6738
|
+
a.ts = a.ts.map((d) => u + h * (d - u));
|
|
6739
6739
|
}
|
|
6740
6740
|
}
|
|
6741
6741
|
this.animQueue.push(a);
|
|
@@ -6765,7 +6765,7 @@ class nt {
|
|
|
6765
6765
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6766
6766
|
*/
|
|
6767
6767
|
ikSolve(n, e = null, t = !1, o = null) {
|
|
6768
|
-
const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(),
|
|
6768
|
+
const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(), u = new b.Vector3(), l = new b.Quaternion(), c = new b.Vector3(), r = new b.Vector3(), h = new b.Vector3(), d = this.ikMesh.getObjectByName(n.root);
|
|
6769
6769
|
d.position.setFromMatrixPosition(this.armature.getObjectByName(n.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(n.root).matrixWorld), e && t && e.applyQuaternion(this.armature.quaternion).add(d.position);
|
|
6770
6770
|
const g = this.ikMesh.getObjectByName(n.effector), R = n.links;
|
|
6771
6771
|
R.forEach((k) => {
|
|
@@ -6777,9 +6777,9 @@ class nt {
|
|
|
6777
6777
|
let G = !1;
|
|
6778
6778
|
for (let m = 0, D = R.length; m < D; m++) {
|
|
6779
6779
|
const E = R[m].bone;
|
|
6780
|
-
E.matrixWorld.decompose(
|
|
6780
|
+
E.matrixWorld.decompose(u, l, c), l.invert(), i.setFromMatrixPosition(g.matrixWorld), a.subVectors(i, u), a.applyQuaternion(l), a.normalize(), s.subVectors(e, u), s.applyQuaternion(l), s.normalize();
|
|
6781
6781
|
let y = s.dot(a);
|
|
6782
|
-
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (R[m].minAngle !== void 0 && y < R[m].minAngle && (y = R[m].minAngle), R[m].maxAngle !== void 0 && y > R[m].maxAngle && (y = R[m].maxAngle), r.crossVectors(a, s), r.normalize(),
|
|
6782
|
+
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (R[m].minAngle !== void 0 && y < R[m].minAngle && (y = R[m].minAngle), R[m].maxAngle !== void 0 && y > R[m].maxAngle && (y = R[m].maxAngle), r.crossVectors(a, s), r.normalize(), ue.setFromAxisAngle(r, y), E.quaternion.multiply(ue), E.rotation.setFromVector3(h.setFromEuler(E.rotation).clamp(new b.Vector3(
|
|
6783
6783
|
R[m].minx !== void 0 ? R[m].minx : -1 / 0,
|
|
6784
6784
|
R[m].miny !== void 0 ? R[m].miny : -1 / 0,
|
|
6785
6785
|
R[m].minz !== void 0 ? R[m].minz : -1 / 0
|
|
@@ -6860,7 +6860,7 @@ function qt() {
|
|
|
6860
6860
|
});
|
|
6861
6861
|
}), n;
|
|
6862
6862
|
}
|
|
6863
|
-
const
|
|
6863
|
+
const ct = Ke(({
|
|
6864
6864
|
avatarUrl: Z = "/avatars/brunette.glb",
|
|
6865
6865
|
avatarBody: n = "F",
|
|
6866
6866
|
mood: e = "neutral",
|
|
@@ -6869,9 +6869,9 @@ const ut = Ke(({
|
|
|
6869
6869
|
ttsVoice: s = null,
|
|
6870
6870
|
ttsApiKey: i = null,
|
|
6871
6871
|
bodyMovement: a = "idle",
|
|
6872
|
-
movementIntensity:
|
|
6872
|
+
movementIntensity: u = 0.5,
|
|
6873
6873
|
showFullAvatar: l = !0,
|
|
6874
|
-
cameraView:
|
|
6874
|
+
cameraView: c = "upper",
|
|
6875
6875
|
onReady: r = () => {
|
|
6876
6876
|
},
|
|
6877
6877
|
onLoading: h = () => {
|
|
@@ -6921,13 +6921,13 @@ const ut = Ke(({
|
|
|
6921
6921
|
lipsyncLang: "en",
|
|
6922
6922
|
showFullAvatar: l,
|
|
6923
6923
|
bodyMovement: a,
|
|
6924
|
-
movementIntensity:
|
|
6924
|
+
movementIntensity: u
|
|
6925
6925
|
}, v = {
|
|
6926
6926
|
ttsEndpoint: he.endpoint,
|
|
6927
6927
|
ttsApikey: he.apiKey,
|
|
6928
6928
|
ttsService: Re,
|
|
6929
6929
|
lipsyncModules: ["en"],
|
|
6930
|
-
cameraView:
|
|
6930
|
+
cameraView: c
|
|
6931
6931
|
}, T = U(async () => {
|
|
6932
6932
|
if (!(!G.current || m.current))
|
|
6933
6933
|
try {
|
|
@@ -6957,7 +6957,7 @@ const ut = Ke(({
|
|
|
6957
6957
|
} catch (C) {
|
|
6958
6958
|
console.error("Error initializing TalkingHead:", C), Q(C.message || "Failed to initialize avatar"), F(!1), d(C);
|
|
6959
6959
|
}
|
|
6960
|
-
}, [Z, n, e, t, o, s, i, l, a,
|
|
6960
|
+
}, [Z, n, e, t, o, s, i, l, a, u, c]);
|
|
6961
6961
|
Se(() => (T(), () => {
|
|
6962
6962
|
m.current && (m.current.stop(), m.current.dispose(), m.current = null);
|
|
6963
6963
|
}), [T]), Se(() => {
|
|
@@ -7029,7 +7029,7 @@ const ut = Ke(({
|
|
|
7029
7029
|
} catch (ne) {
|
|
7030
7030
|
console.error("Error speaking text:", ne), Q(ne.message || "Failed to speak text");
|
|
7031
7031
|
}
|
|
7032
|
-
}, [_, O, A.lipsyncLang]),
|
|
7032
|
+
}, [_, O, A.lipsyncLang]), K = U(() => {
|
|
7033
7033
|
m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), E.current = null, Fe(!1));
|
|
7034
7034
|
}, []), q = U(() => {
|
|
7035
7035
|
if (m.current && m.current.pauseSpeaking) {
|
|
@@ -7120,7 +7120,7 @@ const ut = Ke(({
|
|
|
7120
7120
|
}, []);
|
|
7121
7121
|
return Je(k, () => ({
|
|
7122
7122
|
speakText: Y,
|
|
7123
|
-
stopSpeaking:
|
|
7123
|
+
stopSpeaking: K,
|
|
7124
7124
|
pauseSpeaking: q,
|
|
7125
7125
|
resumeSpeaking: te,
|
|
7126
7126
|
resumeAudioContext: O,
|
|
@@ -7236,7 +7236,7 @@ const ut = Ke(({
|
|
|
7236
7236
|
}
|
|
7237
7237
|
);
|
|
7238
7238
|
});
|
|
7239
|
-
|
|
7239
|
+
ct.displayName = "TalkingHeadAvatar";
|
|
7240
7240
|
const Ot = Ke(({
|
|
7241
7241
|
text: Z = "Hello! I'm a talking avatar. How are you today?",
|
|
7242
7242
|
onLoading: n = () => {
|
|
@@ -7249,7 +7249,7 @@ const Ot = Ke(({
|
|
|
7249
7249
|
style: s = {},
|
|
7250
7250
|
avatarConfig: i = {}
|
|
7251
7251
|
}, a) => {
|
|
7252
|
-
const
|
|
7252
|
+
const u = V(null), l = V(null), [c, r] = pe(!0), [h, d] = pe(null), [g, R] = pe(!1), x = $e(), k = i.ttsService || x.service, G = k === "browser" ? {
|
|
7253
7253
|
endpoint: "",
|
|
7254
7254
|
apiKey: null,
|
|
7255
7255
|
defaultVoice: "Google US English"
|
|
@@ -7280,9 +7280,9 @@ const Ot = Ke(({
|
|
|
7280
7280
|
lipsyncModules: ["en"],
|
|
7281
7281
|
cameraView: "upper"
|
|
7282
7282
|
}, E = U(async () => {
|
|
7283
|
-
if (!(!
|
|
7283
|
+
if (!(!u.current || l.current))
|
|
7284
7284
|
try {
|
|
7285
|
-
if (r(!0), d(null), l.current = new nt(
|
|
7285
|
+
if (r(!0), d(null), l.current = new nt(u.current, D), await l.current.showAvatar(m, (B) => {
|
|
7286
7286
|
if (B.lengthComputable) {
|
|
7287
7287
|
const Q = Math.min(100, Math.round(B.loaded / B.total * 100));
|
|
7288
7288
|
n(Q);
|
|
@@ -7445,7 +7445,7 @@ const Ot = Ke(({
|
|
|
7445
7445
|
/* @__PURE__ */ ae(
|
|
7446
7446
|
"div",
|
|
7447
7447
|
{
|
|
7448
|
-
ref:
|
|
7448
|
+
ref: u,
|
|
7449
7449
|
className: "talking-head-viewer",
|
|
7450
7450
|
style: {
|
|
7451
7451
|
width: "100%",
|
|
@@ -7454,7 +7454,7 @@ const Ot = Ke(({
|
|
|
7454
7454
|
}
|
|
7455
7455
|
}
|
|
7456
7456
|
),
|
|
7457
|
-
|
|
7457
|
+
c && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
|
|
7458
7458
|
position: "absolute",
|
|
7459
7459
|
top: "50%",
|
|
7460
7460
|
left: "50%",
|
|
@@ -7508,9 +7508,9 @@ async function Dt(Z, n = "F") {
|
|
|
7508
7508
|
];
|
|
7509
7509
|
for (const a of i)
|
|
7510
7510
|
try {
|
|
7511
|
-
const
|
|
7512
|
-
if (
|
|
7513
|
-
const l = await
|
|
7511
|
+
const u = await fetch(a);
|
|
7512
|
+
if (u.ok) {
|
|
7513
|
+
const l = await u.json(), r = (Array.isArray(l) ? l : l.files || []).filter((h) => typeof h == "string" && h.toLowerCase().endsWith(".fbx")).map((h) => h.startsWith("/") ? h : `${t}/${h}`);
|
|
7514
7514
|
if (r.length > 0)
|
|
7515
7515
|
return r;
|
|
7516
7516
|
}
|
|
@@ -7529,10 +7529,10 @@ async function Dt(Z, n = "F") {
|
|
|
7529
7529
|
o === "M" ? s.push(`${t}/male`, `${t}/m`) : s.push(`${t}/female`, `${t}/f`), s.push(`${t}/shared`);
|
|
7530
7530
|
for (const i of s)
|
|
7531
7531
|
try {
|
|
7532
|
-
const a = `${i}/.list.json`,
|
|
7533
|
-
if (
|
|
7534
|
-
const l = await
|
|
7535
|
-
|
|
7532
|
+
const a = `${i}/.list.json`, u = await fetch(a);
|
|
7533
|
+
if (u.ok) {
|
|
7534
|
+
const l = await u.json(), c = (Array.isArray(l) ? l : l.files || []).filter((r) => typeof r == "string" && r.toLowerCase().endsWith(".fbx")).map((r) => r.startsWith("/") ? r : `${i}/${r}`);
|
|
7535
|
+
c.length > 0 && e.push(...c);
|
|
7536
7536
|
}
|
|
7537
7537
|
} catch {
|
|
7538
7538
|
continue;
|
|
@@ -7559,9 +7559,9 @@ const Nt = Ke(({
|
|
|
7559
7559
|
ttsService: s = null,
|
|
7560
7560
|
ttsVoice: i = null,
|
|
7561
7561
|
ttsApiKey: a = null,
|
|
7562
|
-
bodyMovement:
|
|
7562
|
+
bodyMovement: u = "idle",
|
|
7563
7563
|
movementIntensity: l = 0.5,
|
|
7564
|
-
showFullAvatar:
|
|
7564
|
+
showFullAvatar: c = !1,
|
|
7565
7565
|
cameraView: r = "upper",
|
|
7566
7566
|
onReady: h = () => {
|
|
7567
7567
|
},
|
|
@@ -7582,7 +7582,7 @@ const Nt = Ke(({
|
|
|
7582
7582
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7583
7583
|
autoSpeak: y = !1
|
|
7584
7584
|
}, P) => {
|
|
7585
|
-
const L = V(null), f = V(null), M = V(
|
|
7585
|
+
const L = V(null), f = V(null), M = V(c), I = V(null), F = V(null), B = V(!1), Q = V({ remainingText: null, originalText: null, options: null }), _ = V([]), [ve, me] = pe(!0), [Fe, ye] = pe(null), [Re, he] = pe(!1), [A, v] = pe(!1), [T, O] = pe(m), Y = V(null), K = V(!1), q = V(null), te = V(!1), fe = V([]), Ie = V([]), et = V(0), ke = V(null);
|
|
7586
7586
|
Se(() => {
|
|
7587
7587
|
B.current = A;
|
|
7588
7588
|
}, [A]);
|
|
@@ -7615,17 +7615,17 @@ const Nt = Ke(({
|
|
|
7615
7615
|
} catch {
|
|
7616
7616
|
}
|
|
7617
7617
|
if (typeof m.auto == "string") {
|
|
7618
|
-
const H = m.auto,
|
|
7618
|
+
const H = m.auto, J = {
|
|
7619
7619
|
talking: `${H}/talking`,
|
|
7620
7620
|
idle: `${H}/idle`
|
|
7621
7621
|
}, W = C(e);
|
|
7622
|
-
|
|
7623
|
-
const ie = await lt(
|
|
7622
|
+
J[`${W}_talking`] = `${H}/${W}/talking`, J[`${W}_idle`] = `${H}/${W}/idle`, J.shared_talking = `${H}/shared/talking`, J.shared_idle = `${H}/shared/idle`;
|
|
7623
|
+
const ie = await lt(J, e);
|
|
7624
7624
|
if (!Object.values(ie).some((j) => Array.isArray(j) && j.length > 0) && w) {
|
|
7625
7625
|
O(w);
|
|
7626
7626
|
return;
|
|
7627
7627
|
}
|
|
7628
|
-
const
|
|
7628
|
+
const ce = {
|
|
7629
7629
|
_genderSpecific: {
|
|
7630
7630
|
[W]: {},
|
|
7631
7631
|
shared: {}
|
|
@@ -7634,19 +7634,19 @@ const Nt = Ke(({
|
|
|
7634
7634
|
Object.entries(ie).forEach(([j, $]) => {
|
|
7635
7635
|
if (j.includes("_")) {
|
|
7636
7636
|
const [ee, ...ge] = j.split("_"), de = ge.join("_");
|
|
7637
|
-
ee === "shared" ? (
|
|
7637
|
+
ee === "shared" ? (ce._genderSpecific.shared[de] || (ce._genderSpecific.shared[de] = []), ce._genderSpecific.shared[de].push(...$)) : ee === W && (ce._genderSpecific[W][de] || (ce._genderSpecific[W][de] = []), ce._genderSpecific[W][de].push(...$));
|
|
7638
7638
|
} else
|
|
7639
|
-
|
|
7639
|
+
ce[j] = $;
|
|
7640
7640
|
}), w && (w._genderSpecific && Object.keys(w._genderSpecific).forEach((j) => {
|
|
7641
|
-
|
|
7642
|
-
|
|
7641
|
+
ce._genderSpecific[j] || (ce._genderSpecific[j] = {}), Object.entries(w._genderSpecific[j]).forEach(([$, ee]) => {
|
|
7642
|
+
ce._genderSpecific[j][$] || (ce._genderSpecific[j][$] = ee);
|
|
7643
7643
|
});
|
|
7644
7644
|
}), Object.entries(w).forEach(([j, $]) => {
|
|
7645
|
-
j !== "_genderSpecific" && !
|
|
7646
|
-
})), O(
|
|
7645
|
+
j !== "_genderSpecific" && !ce[j] && (ce[j] = $);
|
|
7646
|
+
})), O(ce);
|
|
7647
7647
|
} else if (typeof m.auto == "object") {
|
|
7648
|
-
const H = await lt(m.auto, e),
|
|
7649
|
-
O(!
|
|
7648
|
+
const H = await lt(m.auto, e), J = Object.values(H).some((W) => Array.isArray(W) && W.length > 0);
|
|
7649
|
+
O(!J && w ? w : H);
|
|
7650
7650
|
}
|
|
7651
7651
|
} catch (w) {
|
|
7652
7652
|
if (console.error("Failed to auto-discover animations:", w), m.manifest)
|
|
@@ -7663,8 +7663,8 @@ const Nt = Ke(({
|
|
|
7663
7663
|
O(m);
|
|
7664
7664
|
})();
|
|
7665
7665
|
}, [m, e, C]), Se(() => {
|
|
7666
|
-
M.current =
|
|
7667
|
-
}, [
|
|
7666
|
+
M.current = c;
|
|
7667
|
+
}, [c]);
|
|
7668
7668
|
const X = $e(), ne = s || X.service;
|
|
7669
7669
|
let se;
|
|
7670
7670
|
ne === "browser" ? se = {
|
|
@@ -7695,8 +7695,8 @@ const Nt = Ke(({
|
|
|
7695
7695
|
ttsLang: ne === "browser" ? "en-US" : o,
|
|
7696
7696
|
ttsVoice: i || se.defaultVoice,
|
|
7697
7697
|
lipsyncLang: "en",
|
|
7698
|
-
showFullAvatar:
|
|
7699
|
-
bodyMovement:
|
|
7698
|
+
showFullAvatar: c,
|
|
7699
|
+
bodyMovement: u,
|
|
7700
7700
|
movementIntensity: l
|
|
7701
7701
|
}, re = {
|
|
7702
7702
|
ttsEndpoint: se.endpoint,
|
|
@@ -7739,8 +7739,8 @@ const Nt = Ke(({
|
|
|
7739
7739
|
return [];
|
|
7740
7740
|
let w = null;
|
|
7741
7741
|
if (T._genderSpecific) {
|
|
7742
|
-
const H = C(e),
|
|
7743
|
-
if (
|
|
7742
|
+
const H = C(e), J = T._genderSpecific[H];
|
|
7743
|
+
if (J && J[S] && Array.isArray(J[S]) && J[S].length > 0 && (w = J[S]), !w && T._genderSpecific.shared && T._genderSpecific.shared[S]) {
|
|
7744
7744
|
const W = T._genderSpecific.shared[S];
|
|
7745
7745
|
Array.isArray(W) && W.length > 0 && (w = W);
|
|
7746
7746
|
}
|
|
@@ -7753,8 +7753,8 @@ const Nt = Ke(({
|
|
|
7753
7753
|
}, [T, e, C]), He = U((S) => {
|
|
7754
7754
|
const w = [...S];
|
|
7755
7755
|
for (let H = w.length - 1; H > 0; H--) {
|
|
7756
|
-
const
|
|
7757
|
-
[w[H], w[
|
|
7756
|
+
const J = Math.floor(Math.random() * (H + 1));
|
|
7757
|
+
[w[H], w[J]] = [w[J], w[H]];
|
|
7758
7758
|
}
|
|
7759
7759
|
return w;
|
|
7760
7760
|
}, []), we = U((S) => {
|
|
@@ -7767,25 +7767,25 @@ const Nt = Ke(({
|
|
|
7767
7767
|
const w = Ie.current.shift();
|
|
7768
7768
|
return w && fe.current.push(w), w;
|
|
7769
7769
|
}, [Be, He]), We = U((S) => S ? S.split("/").pop().replace(".fbx", "").replace(/[-_]/g, " ") : "Unknown", []), Oe = U((S, w = !1, H = null) => {
|
|
7770
|
-
if (!f.current || !
|
|
7770
|
+
if (!f.current || !K.current || q.current !== S)
|
|
7771
7771
|
return null;
|
|
7772
|
-
const
|
|
7773
|
-
if (
|
|
7772
|
+
const J = we(S);
|
|
7773
|
+
if (J)
|
|
7774
7774
|
try {
|
|
7775
|
-
const W = We(
|
|
7775
|
+
const W = We(J);
|
|
7776
7776
|
console.log(`🎬 Playing animation: "${W}"`);
|
|
7777
7777
|
const ie = () => {
|
|
7778
7778
|
console.log("🎬 Animation finished, checking if should continue...");
|
|
7779
7779
|
const le = () => {
|
|
7780
7780
|
if (!f.current)
|
|
7781
7781
|
return console.log("🎬 No talkingHeadRef, stopping animations"), !1;
|
|
7782
|
-
if (!
|
|
7782
|
+
if (!K.current)
|
|
7783
7783
|
return console.log("🎬 isSpeakingRef is false, stopping animations"), !1;
|
|
7784
7784
|
if (q.current !== S)
|
|
7785
7785
|
return console.log(`🎬 Animation group mismatch (${q.current} !== ${S}), stopping animations`), !1;
|
|
7786
7786
|
const j = f.current, $ = j.isAudioPlaying === !0, ee = j.audioPlaylist && j.audioPlaylist.length > 0, ge = j.speechQueue && j.speechQueue.length > 0, de = j.isSpeaking === !0, Ge = de || $ || ee || ge;
|
|
7787
7787
|
return console.log("🎬 Still speaking check:", {
|
|
7788
|
-
isSpeakingRef:
|
|
7788
|
+
isSpeakingRef: K.current,
|
|
7789
7789
|
isTalkingHeadSpeaking: de,
|
|
7790
7790
|
hasAudioPlaying: $,
|
|
7791
7791
|
hasAudioInPlaylist: ee,
|
|
@@ -7794,21 +7794,21 @@ const Nt = Ke(({
|
|
|
7794
7794
|
}), Ge;
|
|
7795
7795
|
};
|
|
7796
7796
|
le() ? (console.log("🎬 Still speaking, continuing to next animation..."), requestAnimationFrame(() => {
|
|
7797
|
-
le() ? (console.log("🎬 Playing next animation..."), Oe(S, w, H)) : (console.log("🎬 Speech ended, stopping animations"),
|
|
7798
|
-
})) : (console.log("🎬 Speech has ended, stopping animations"),
|
|
7797
|
+
le() ? (console.log("🎬 Playing next animation..."), Oe(S, w, H)) : (console.log("🎬 Speech ended, stopping animations"), K.current = !1, q.current = null, H && H());
|
|
7798
|
+
})) : (console.log("🎬 Speech has ended, stopping animations"), K.current = !1, q.current = null, H && H());
|
|
7799
7799
|
};
|
|
7800
|
-
return f.current.playAnimation(
|
|
7800
|
+
return f.current.playAnimation(J, null, 0, 0, 0.01, w, ie), J;
|
|
7801
7801
|
} catch (W) {
|
|
7802
7802
|
return console.error("Failed to play animation:", W), null;
|
|
7803
7803
|
}
|
|
7804
7804
|
else {
|
|
7805
7805
|
const W = () => {
|
|
7806
|
-
if (!f.current || !
|
|
7806
|
+
if (!f.current || !K.current || q.current !== S)
|
|
7807
7807
|
return !1;
|
|
7808
|
-
const le = f.current,
|
|
7809
|
-
return le.isSpeaking === !0 ||
|
|
7808
|
+
const le = f.current, ce = le.isAudioPlaying === !0, j = le.audioPlaylist && le.audioPlaylist.length > 0, $ = le.speechQueue && le.speechQueue.length > 0;
|
|
7809
|
+
return le.isSpeaking === !0 || ce || j || $;
|
|
7810
7810
|
};
|
|
7811
|
-
W() && (Ie.current = [], fe.current = [], W() ? Oe(S, w, H) : (
|
|
7811
|
+
W() && (Ie.current = [], fe.current = [], W() ? Oe(S, w, H) : (K.current = !1, q.current = null));
|
|
7812
7812
|
}
|
|
7813
7813
|
return null;
|
|
7814
7814
|
}, [we, We]), Ve = U(async (S, w = {}) => {
|
|
@@ -7816,29 +7816,29 @@ const Nt = Ke(({
|
|
|
7816
7816
|
return;
|
|
7817
7817
|
await Ee();
|
|
7818
7818
|
const H = w.animationGroup || D;
|
|
7819
|
-
H && !w.skipAnimation && (
|
|
7819
|
+
H && !w.skipAnimation && (K.current = !0, q.current = H, Ie.current = [], fe.current = [], Oe(H));
|
|
7820
7820
|
try {
|
|
7821
7821
|
R(S), w.onSpeechStart && w.onSpeechStart(S);
|
|
7822
7822
|
} catch (ie) {
|
|
7823
7823
|
console.warn("Error in onSpeechStart callback:", ie);
|
|
7824
7824
|
}
|
|
7825
7825
|
Q.current = { remainingText: null, originalText: null, options: null }, _.current = [], I.current = { text: S, options: w }, F.current && (clearInterval(F.current), F.current = null), v(!1), B.current = !1, te.current = !1;
|
|
7826
|
-
const
|
|
7827
|
-
_.current =
|
|
7826
|
+
const J = S.split(/[.!?]+/).filter((ie) => ie.trim().length > 0);
|
|
7827
|
+
_.current = J, et.current = 0;
|
|
7828
7828
|
const W = {
|
|
7829
7829
|
lipsyncLang: w.lipsyncLang || "en"
|
|
7830
7830
|
};
|
|
7831
7831
|
if (f.current) {
|
|
7832
7832
|
const ie = f.current;
|
|
7833
7833
|
let le = 0;
|
|
7834
|
-
const
|
|
7834
|
+
const ce = 1200;
|
|
7835
7835
|
F.current && (clearInterval(F.current), F.current = null);
|
|
7836
7836
|
const j = { current: !1 }, $ = setInterval(() => {
|
|
7837
7837
|
if (le++, B.current)
|
|
7838
7838
|
return;
|
|
7839
|
-
if (le >
|
|
7839
|
+
if (le > ce) {
|
|
7840
7840
|
if ($ && (clearInterval($), F.current = null), !j.current && !B.current) {
|
|
7841
|
-
j.current = !0,
|
|
7841
|
+
j.current = !0, K.current = !1, q.current = null, Ie.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
|
|
7842
7842
|
try {
|
|
7843
7843
|
w.onSpeechEnd && w.onSpeechEnd(), x();
|
|
7844
7844
|
} catch (Te) {
|
|
@@ -7852,7 +7852,7 @@ const Nt = Ke(({
|
|
|
7852
7852
|
const Te = f.current;
|
|
7853
7853
|
if (!Te)
|
|
7854
7854
|
return;
|
|
7855
|
-
!B.current && (!Te.speechQueue || Te.speechQueue.length === 0) && (!Te.audioPlaylist || Te.audioPlaylist.length === 0) && Te.isAudioPlaying === !1 && Te.isSpeaking === !1 && !j.current && !B.current && (j.current = !0, $ && (clearInterval($), F.current = null),
|
|
7855
|
+
!B.current && (!Te.speechQueue || Te.speechQueue.length === 0) && (!Te.audioPlaylist || Te.audioPlaylist.length === 0) && Te.isAudioPlaying === !1 && Te.isSpeaking === !1 && !j.current && !B.current && (j.current = !0, $ && (clearInterval($), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], te.current = !0, Te && (Te.isSpeaking = !1), setTimeout(() => {
|
|
7856
7856
|
try {
|
|
7857
7857
|
w.onSpeechEnd && w.onSpeechEnd(), x(), setTimeout(() => {
|
|
7858
7858
|
te.current = !1;
|
|
@@ -7884,7 +7884,7 @@ const Nt = Ke(({
|
|
|
7884
7884
|
Y.current && (clearInterval(Y.current), Y.current = null);
|
|
7885
7885
|
};
|
|
7886
7886
|
}, [Re, E, Oe]), Se(() => {
|
|
7887
|
-
Re && Z && y && f.current && !
|
|
7887
|
+
Re && Z && y && f.current && !K.current && !B.current && !te.current && Ve(Z);
|
|
7888
7888
|
}, [Re, Z, y, Ve]);
|
|
7889
7889
|
const tt = U(() => {
|
|
7890
7890
|
if (f.current)
|
|
@@ -7892,12 +7892,12 @@ const Nt = Ke(({
|
|
|
7892
7892
|
const S = f.current.isSpeaking || !1, w = [...f.current.audioPlaylist || []], H = [...f.current.speechQueue || []];
|
|
7893
7893
|
if (S || w.length > 0 || H.length > 0) {
|
|
7894
7894
|
F.current && (clearInterval(F.current), F.current = null);
|
|
7895
|
-
const
|
|
7895
|
+
const J = _.current;
|
|
7896
7896
|
let W = [];
|
|
7897
7897
|
const ie = f.current.isAudioPlaying || !1;
|
|
7898
|
-
if (
|
|
7899
|
-
const ee = w.length + H.length, ge = ie ? 1 : 0, de =
|
|
7900
|
-
Ge <
|
|
7898
|
+
if (J.length > 0) {
|
|
7899
|
+
const ee = w.length + H.length, ge = ie ? 1 : 0, de = J.length - ee - ge, Ge = ie ? de : de + ge;
|
|
7900
|
+
Ge < J.length && (W = J.slice(Ge));
|
|
7901
7901
|
} else
|
|
7902
7902
|
w.length > 0 && w.forEach((ee) => {
|
|
7903
7903
|
if (ee.text)
|
|
@@ -7923,7 +7923,7 @@ const Nt = Ke(({
|
|
|
7923
7923
|
const j = f.current.isAudioPlaying || !1 ? [...f.current.speechQueue || []] : null;
|
|
7924
7924
|
f.current.speechQueue.length = 0;
|
|
7925
7925
|
const $ = f.current.pauseSpeaking();
|
|
7926
|
-
f.current.isSpeaking = !1, $ && $.audio && j ? (ke.current = $, ke.current.savedSpeechQueue = j) : ke.current = $, v(!0), B.current = !0;
|
|
7926
|
+
f.current.isSpeaking = !1, K.current = !1, q.current = null, $ && $.audio && j ? (ke.current = $, ke.current.savedSpeechQueue = j) : ke.current = $, v(!0), B.current = !0;
|
|
7927
7927
|
}
|
|
7928
7928
|
} catch (S) {
|
|
7929
7929
|
console.warn("Error pausing speech:", S);
|
|
@@ -7932,19 +7932,19 @@ const Nt = Ke(({
|
|
|
7932
7932
|
if (!(!f.current || !A))
|
|
7933
7933
|
try {
|
|
7934
7934
|
if (await Ee(), v(!1), B.current = !1, ke.current && ke.current.audio) {
|
|
7935
|
-
|
|
7935
|
+
K.current = !0;
|
|
7936
7936
|
const W = Q.current?.options || I.current?.options || {}, ie = W.animationGroup || D;
|
|
7937
7937
|
if (ie && (q.current = ie), ke.current.savedSpeechQueue && (f.current.speechQueue.length = 0, f.current.speechQueue.push(...ke.current.savedSpeechQueue)), f.current.isSpeaking = !0, f.current) {
|
|
7938
7938
|
const le = f.current;
|
|
7939
|
-
let
|
|
7939
|
+
let ce = 0;
|
|
7940
7940
|
const j = 1200, $ = { current: !1 };
|
|
7941
7941
|
F.current && (clearInterval(F.current), F.current = null);
|
|
7942
7942
|
const ee = setInterval(() => {
|
|
7943
|
-
if (
|
|
7943
|
+
if (ce++, B.current)
|
|
7944
7944
|
return;
|
|
7945
|
-
if (
|
|
7945
|
+
if (ce > j) {
|
|
7946
7946
|
if (ee && (clearInterval(ee), F.current = null), !$.current && !B.current) {
|
|
7947
|
-
$.current = !0,
|
|
7947
|
+
$.current = !0, K.current = !1, q.current = null, Ie.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
|
|
7948
7948
|
try {
|
|
7949
7949
|
W.onSpeechEnd && W.onSpeechEnd(), x();
|
|
7950
7950
|
} catch (Me) {
|
|
@@ -7957,7 +7957,7 @@ const Nt = Ke(({
|
|
|
7957
7957
|
le && !B.current && ge && de && Ge && le.isSpeaking === !1 && !$.current && !B.current && setTimeout(() => {
|
|
7958
7958
|
const Me = f.current;
|
|
7959
7959
|
if (!Me) return;
|
|
7960
|
-
!B.current && (!Me.speechQueue || Me.speechQueue.length === 0) && (!Me.audioPlaylist || Me.audioPlaylist.length === 0) && Me.isAudioPlaying === !1 && Me.isSpeaking === !1 && !$.current && !B.current && ($.current = !0, ee && (clearInterval(ee), F.current = null),
|
|
7960
|
+
!B.current && (!Me.speechQueue || Me.speechQueue.length === 0) && (!Me.audioPlaylist || Me.audioPlaylist.length === 0) && Me.isAudioPlaying === !1 && Me.isSpeaking === !1 && !$.current && !B.current && ($.current = !0, ee && (clearInterval(ee), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], te.current = !0, Me && (Me.isSpeaking = !1), setTimeout(() => {
|
|
7961
7961
|
try {
|
|
7962
7962
|
W.onSpeechEnd && W.onSpeechEnd(), x(), setTimeout(() => {
|
|
7963
7963
|
te.current = !1;
|
|
@@ -7973,14 +7973,14 @@ const Nt = Ke(({
|
|
|
7973
7973
|
await f.current.playAudio(!1, ke.current), ie && !W.skipAnimation && (Ie.current = [], fe.current = [], Oe(ie)), ke.current = null;
|
|
7974
7974
|
return;
|
|
7975
7975
|
}
|
|
7976
|
-
const S = Q.current?.remainingText, w = Q.current?.originalText || I.current?.text, H = Q.current?.options || I.current?.options || {},
|
|
7977
|
-
|
|
7976
|
+
const S = Q.current?.remainingText, w = Q.current?.originalText || I.current?.text, H = Q.current?.options || I.current?.options || {}, J = S || w;
|
|
7977
|
+
J && Ve(J, H), ke.current = null;
|
|
7978
7978
|
} catch (S) {
|
|
7979
7979
|
console.warn("Error resuming speech:", S), v(!1), B.current = !1, ke.current = null;
|
|
7980
7980
|
}
|
|
7981
7981
|
}, [A, Ve, Ee, D, Oe]), dt = U(() => {
|
|
7982
7982
|
if (f.current) {
|
|
7983
|
-
f.current.stopSpeaking(), F.current && (clearInterval(F.current), F.current = null),
|
|
7983
|
+
f.current.stopSpeaking(), F.current && (clearInterval(F.current), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], v(!1), B.current = !1;
|
|
7984
7984
|
try {
|
|
7985
7985
|
x();
|
|
7986
7986
|
} catch (S) {
|
|
@@ -8062,9 +8062,9 @@ const Ut = Ke(({
|
|
|
8062
8062
|
},
|
|
8063
8063
|
onCustomAction: a = () => {
|
|
8064
8064
|
},
|
|
8065
|
-
autoStart:
|
|
8065
|
+
autoStart: u = !1
|
|
8066
8066
|
}, l) => {
|
|
8067
|
-
const
|
|
8067
|
+
const c = V(null), r = V({
|
|
8068
8068
|
currentModuleIndex: 0,
|
|
8069
8069
|
currentLessonIndex: 0,
|
|
8070
8070
|
currentQuestionIndex: 0,
|
|
@@ -8145,15 +8145,15 @@ const Ut = Ke(({
|
|
|
8145
8145
|
score: r.current.score,
|
|
8146
8146
|
totalQuestions: r.current.totalQuestions,
|
|
8147
8147
|
percentage: A
|
|
8148
|
-
}),
|
|
8149
|
-
if (
|
|
8148
|
+
}), c.current) {
|
|
8149
|
+
if (c.current.setMood("happy"), e.lessonComplete)
|
|
8150
8150
|
try {
|
|
8151
|
-
|
|
8151
|
+
c.current.playAnimation(e.lessonComplete, !0);
|
|
8152
8152
|
} catch {
|
|
8153
|
-
|
|
8153
|
+
c.current.playCelebration();
|
|
8154
8154
|
}
|
|
8155
|
-
const T = D.current || { modules: [] }, O = T.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1,
|
|
8156
|
-
|
|
8155
|
+
const T = D.current || { modules: [] }, O = T.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (T.modules?.length || 0) - 1, q = Y || K, te = E.current || { lipsyncLang: "en" };
|
|
8156
|
+
c.current.speakText(v, {
|
|
8157
8157
|
lipsyncLang: te.lipsyncLang,
|
|
8158
8158
|
onSpeechEnd: () => {
|
|
8159
8159
|
h.current.onCustomAction({
|
|
@@ -8174,15 +8174,15 @@ const Ut = Ke(({
|
|
|
8174
8174
|
if (h.current.onCurriculumComplete({
|
|
8175
8175
|
modules: A.modules.length,
|
|
8176
8176
|
totalLessons: A.modules.reduce((v, T) => v + T.lessons.length, 0)
|
|
8177
|
-
}),
|
|
8178
|
-
if (
|
|
8177
|
+
}), c.current) {
|
|
8178
|
+
if (c.current.setMood("celebrating"), e.curriculumComplete)
|
|
8179
8179
|
try {
|
|
8180
|
-
|
|
8180
|
+
c.current.playAnimation(e.curriculumComplete, !0);
|
|
8181
8181
|
} catch {
|
|
8182
|
-
|
|
8182
|
+
c.current.playCelebration();
|
|
8183
8183
|
}
|
|
8184
8184
|
const v = E.current || { lipsyncLang: "en" };
|
|
8185
|
-
|
|
8185
|
+
c.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
|
|
8186
8186
|
}
|
|
8187
8187
|
}, [e.curriculumComplete]), I = U(() => {
|
|
8188
8188
|
const A = y();
|
|
@@ -8198,24 +8198,24 @@ const Ut = Ke(({
|
|
|
8198
8198
|
score: r.current.score
|
|
8199
8199
|
});
|
|
8200
8200
|
const T = () => {
|
|
8201
|
-
if (!
|
|
8202
|
-
if (
|
|
8201
|
+
if (!c.current || !v) return;
|
|
8202
|
+
if (c.current.setMood("happy"), e.questionStart)
|
|
8203
8203
|
try {
|
|
8204
|
-
|
|
8204
|
+
c.current.playAnimation(e.questionStart, !0);
|
|
8205
8205
|
} catch (Y) {
|
|
8206
8206
|
console.warn("Failed to play questionStart animation:", Y);
|
|
8207
8207
|
}
|
|
8208
8208
|
const O = E.current || { lipsyncLang: "en" };
|
|
8209
|
-
v.type === "code_test" ?
|
|
8209
|
+
v.type === "code_test" ? c.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : v.type === "multiple_choice" ? c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : v.type === "true_false" ? c.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: O.lipsyncLang });
|
|
8210
8210
|
};
|
|
8211
|
-
if (
|
|
8211
|
+
if (c.current && c.current.isReady && v)
|
|
8212
8212
|
T();
|
|
8213
|
-
else if (
|
|
8213
|
+
else if (c.current && c.current.isReady) {
|
|
8214
8214
|
const O = E.current || { lipsyncLang: "en" };
|
|
8215
|
-
|
|
8215
|
+
c.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: O.lipsyncLang });
|
|
8216
8216
|
} else {
|
|
8217
8217
|
const O = setInterval(() => {
|
|
8218
|
-
|
|
8218
|
+
c.current && c.current.isReady && (clearInterval(O), v && T());
|
|
8219
8219
|
}, 100);
|
|
8220
8220
|
setTimeout(() => {
|
|
8221
8221
|
clearInterval(O);
|
|
@@ -8224,7 +8224,7 @@ const Ut = Ke(({
|
|
|
8224
8224
|
}, [e.questionStart, y, P]), F = U(() => {
|
|
8225
8225
|
const A = y();
|
|
8226
8226
|
if (r.current.currentQuestionIndex < (A?.questions?.length || 0) - 1) {
|
|
8227
|
-
|
|
8227
|
+
c.current && c.current.stopSpeaking && c.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
|
|
8228
8228
|
const v = P();
|
|
8229
8229
|
v && h.current.onCustomAction({
|
|
8230
8230
|
type: "nextQuestion",
|
|
@@ -8236,41 +8236,41 @@ const Ut = Ke(({
|
|
|
8236
8236
|
score: r.current.score
|
|
8237
8237
|
});
|
|
8238
8238
|
const T = () => {
|
|
8239
|
-
if (!
|
|
8240
|
-
if (
|
|
8239
|
+
if (!c.current || !v) return;
|
|
8240
|
+
if (c.current.setMood("happy"), c.current.setBodyMovement("idle"), e.nextQuestion)
|
|
8241
8241
|
try {
|
|
8242
|
-
|
|
8242
|
+
c.current.playAnimation(e.nextQuestion, !0);
|
|
8243
8243
|
} catch (te) {
|
|
8244
8244
|
console.warn("Failed to play nextQuestion animation:", te);
|
|
8245
8245
|
}
|
|
8246
|
-
const O = E.current || { lipsyncLang: "en" },
|
|
8246
|
+
const O = E.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, q = r.current.currentQuestionIndex >= K - 1;
|
|
8247
8247
|
if (v.type === "code_test") {
|
|
8248
8248
|
const te = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
|
|
8249
|
-
|
|
8249
|
+
c.current.speakText(te, {
|
|
8250
8250
|
lipsyncLang: O.lipsyncLang
|
|
8251
8251
|
});
|
|
8252
8252
|
} else if (v.type === "multiple_choice") {
|
|
8253
8253
|
const te = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
|
|
8254
|
-
|
|
8254
|
+
c.current.speakText(te, {
|
|
8255
8255
|
lipsyncLang: O.lipsyncLang
|
|
8256
8256
|
});
|
|
8257
8257
|
} else if (v.type === "true_false") {
|
|
8258
8258
|
const te = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
|
|
8259
|
-
|
|
8259
|
+
c.current.speakText(te, {
|
|
8260
8260
|
lipsyncLang: O.lipsyncLang
|
|
8261
8261
|
});
|
|
8262
8262
|
} else {
|
|
8263
8263
|
const te = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
|
|
8264
|
-
|
|
8264
|
+
c.current.speakText(te, {
|
|
8265
8265
|
lipsyncLang: O.lipsyncLang
|
|
8266
8266
|
});
|
|
8267
8267
|
}
|
|
8268
8268
|
};
|
|
8269
|
-
if (
|
|
8269
|
+
if (c.current && c.current.isReady && v)
|
|
8270
8270
|
T();
|
|
8271
8271
|
else if (v) {
|
|
8272
8272
|
const O = setInterval(() => {
|
|
8273
|
-
|
|
8273
|
+
c.current && c.current.isReady && (clearInterval(O), T());
|
|
8274
8274
|
}, 100);
|
|
8275
8275
|
setTimeout(() => {
|
|
8276
8276
|
clearInterval(O);
|
|
@@ -8288,7 +8288,7 @@ const Ut = Ke(({
|
|
|
8288
8288
|
const A = D.current || { modules: [] }, v = A.modules[r.current.currentModuleIndex];
|
|
8289
8289
|
if (r.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
|
|
8290
8290
|
r.current.currentLessonIndex += 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
|
|
8291
|
-
const O = A.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1,
|
|
8291
|
+
const O = A.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (A.modules?.length || 0) - 1, q = Y || K;
|
|
8292
8292
|
h.current.onCustomAction({
|
|
8293
8293
|
type: "lessonStart",
|
|
8294
8294
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8298,10 +8298,10 @@ const Ut = Ke(({
|
|
|
8298
8298
|
moduleIndex: r.current.currentModuleIndex,
|
|
8299
8299
|
lessonIndex: r.current.currentLessonIndex,
|
|
8300
8300
|
lesson: y()
|
|
8301
|
-
}),
|
|
8301
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8302
8302
|
} else if (r.current.currentModuleIndex < (A.modules?.length || 0) - 1) {
|
|
8303
8303
|
r.current.currentModuleIndex += 1, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
|
|
8304
|
-
const Y = A.modules[r.current.currentModuleIndex],
|
|
8304
|
+
const Y = A.modules[r.current.currentModuleIndex], K = r.current.currentLessonIndex < (Y?.lessons?.length || 0) - 1, q = r.current.currentModuleIndex < (A.modules?.length || 0) - 1, te = K || q;
|
|
8305
8305
|
h.current.onCustomAction({
|
|
8306
8306
|
type: "lessonStart",
|
|
8307
8307
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8311,7 +8311,7 @@ const Ut = Ke(({
|
|
|
8311
8311
|
moduleIndex: r.current.currentModuleIndex,
|
|
8312
8312
|
lessonIndex: r.current.currentLessonIndex,
|
|
8313
8313
|
lesson: y()
|
|
8314
|
-
}),
|
|
8314
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8315
8315
|
} else
|
|
8316
8316
|
k.current && k.current();
|
|
8317
8317
|
}, []), Q = U(() => {
|
|
@@ -8322,16 +8322,16 @@ const Ut = Ke(({
|
|
|
8322
8322
|
v = `${T}${Y}${O}`;
|
|
8323
8323
|
} else
|
|
8324
8324
|
v = A?.avatar_script || A?.body || null;
|
|
8325
|
-
if (
|
|
8326
|
-
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0,
|
|
8325
|
+
if (c.current && c.current.isReady && v) {
|
|
8326
|
+
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.setMood("happy");
|
|
8327
8327
|
let T = !1;
|
|
8328
8328
|
if (e.teaching)
|
|
8329
8329
|
try {
|
|
8330
|
-
|
|
8330
|
+
c.current.playAnimation(e.teaching, !0), T = !0;
|
|
8331
8331
|
} catch (Y) {
|
|
8332
8332
|
console.warn("Failed to play teaching animation:", Y);
|
|
8333
8333
|
}
|
|
8334
|
-
T ||
|
|
8334
|
+
T || c.current.setBodyMovement("gesturing");
|
|
8335
8335
|
const O = E.current || { lipsyncLang: "en" };
|
|
8336
8336
|
h.current.onLessonStart({
|
|
8337
8337
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8342,7 +8342,7 @@ const Ut = Ke(({
|
|
|
8342
8342
|
moduleIndex: r.current.currentModuleIndex,
|
|
8343
8343
|
lessonIndex: r.current.currentLessonIndex,
|
|
8344
8344
|
lesson: A
|
|
8345
|
-
}),
|
|
8345
|
+
}), c.current.speakText(v, {
|
|
8346
8346
|
lipsyncLang: O.lipsyncLang,
|
|
8347
8347
|
onSpeechEnd: () => {
|
|
8348
8348
|
r.current.isTeaching = !1, h.current.onCustomAction({
|
|
@@ -8370,21 +8370,21 @@ const Ut = Ke(({
|
|
|
8370
8370
|
answer: A,
|
|
8371
8371
|
isCorrect: T,
|
|
8372
8372
|
question: v
|
|
8373
|
-
}),
|
|
8373
|
+
}), c.current)
|
|
8374
8374
|
if (T) {
|
|
8375
|
-
if (
|
|
8375
|
+
if (c.current.setMood("happy"), e.correct)
|
|
8376
8376
|
try {
|
|
8377
|
-
|
|
8377
|
+
c.current.playReaction("happy");
|
|
8378
8378
|
} catch {
|
|
8379
|
-
|
|
8379
|
+
c.current.setBodyMovement("happy");
|
|
8380
8380
|
}
|
|
8381
|
-
|
|
8381
|
+
c.current.setBodyMovement("gesturing");
|
|
8382
8382
|
const Y = y()?.questions?.length || 0;
|
|
8383
8383
|
r.current.currentQuestionIndex >= Y - 1;
|
|
8384
|
-
const
|
|
8385
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:",
|
|
8384
|
+
const K = r.current.currentQuestionIndex < Y - 1;
|
|
8385
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", K);
|
|
8386
8386
|
const q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, te = E.current || { lipsyncLang: "en" };
|
|
8387
|
-
|
|
8387
|
+
c.current.speakText(q, {
|
|
8388
8388
|
lipsyncLang: te.lipsyncLang,
|
|
8389
8389
|
onSpeechEnd: () => {
|
|
8390
8390
|
h.current.onCustomAction({
|
|
@@ -8393,24 +8393,24 @@ const Ut = Ke(({
|
|
|
8393
8393
|
lessonIndex: r.current.currentLessonIndex,
|
|
8394
8394
|
questionIndex: r.current.currentQuestionIndex,
|
|
8395
8395
|
isCorrect: !0,
|
|
8396
|
-
hasNextQuestion:
|
|
8396
|
+
hasNextQuestion: K,
|
|
8397
8397
|
score: r.current.score,
|
|
8398
8398
|
totalQuestions: r.current.totalQuestions
|
|
8399
8399
|
});
|
|
8400
8400
|
}
|
|
8401
8401
|
});
|
|
8402
8402
|
} else {
|
|
8403
|
-
if (
|
|
8403
|
+
if (c.current.setMood("sad"), e.incorrect)
|
|
8404
8404
|
try {
|
|
8405
|
-
|
|
8405
|
+
c.current.playAnimation(e.incorrect, !0);
|
|
8406
8406
|
} catch {
|
|
8407
|
-
|
|
8407
|
+
c.current.setBodyMovement("idle");
|
|
8408
8408
|
}
|
|
8409
|
-
|
|
8410
|
-
const Y = y()?.questions?.length || 0,
|
|
8409
|
+
c.current.setBodyMovement("gesturing");
|
|
8410
|
+
const Y = y()?.questions?.length || 0, K = r.current.currentQuestionIndex >= Y - 1, q = r.current.currentQuestionIndex < Y - 1;
|
|
8411
8411
|
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", q);
|
|
8412
|
-
const te = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${
|
|
8413
|
-
|
|
8412
|
+
const te = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${K ? "" : " Let's move on to the next question."}`, fe = E.current || { lipsyncLang: "en" };
|
|
8413
|
+
c.current.speakText(te, {
|
|
8414
8414
|
lipsyncLang: fe.lipsyncLang,
|
|
8415
8415
|
onSpeechEnd: () => {
|
|
8416
8416
|
h.current.onCustomAction({
|
|
@@ -8482,20 +8482,20 @@ const Ut = Ke(({
|
|
|
8482
8482
|
score: r.current.score
|
|
8483
8483
|
});
|
|
8484
8484
|
const v = () => {
|
|
8485
|
-
if (!
|
|
8486
|
-
|
|
8485
|
+
if (!c.current || !A) return;
|
|
8486
|
+
c.current.setMood("happy"), c.current.setBodyMovement("idle");
|
|
8487
8487
|
const T = E.current || { lipsyncLang: "en" };
|
|
8488
|
-
A.type === "code_test" ?
|
|
8488
|
+
A.type === "code_test" ? c.current.speakText(`Let's go back to this coding challenge: ${A.question}`, {
|
|
8489
8489
|
lipsyncLang: T.lipsyncLang
|
|
8490
|
-
}) :
|
|
8490
|
+
}) : c.current.speakText(`Going back to: ${A.question}`, {
|
|
8491
8491
|
lipsyncLang: T.lipsyncLang
|
|
8492
8492
|
});
|
|
8493
8493
|
};
|
|
8494
|
-
if (
|
|
8494
|
+
if (c.current && c.current.isReady && A)
|
|
8495
8495
|
v();
|
|
8496
8496
|
else if (A) {
|
|
8497
8497
|
const T = setInterval(() => {
|
|
8498
|
-
|
|
8498
|
+
c.current && c.current.isReady && (clearInterval(T), v());
|
|
8499
8499
|
}, 100);
|
|
8500
8500
|
setTimeout(() => {
|
|
8501
8501
|
clearInterval(T);
|
|
@@ -8513,7 +8513,7 @@ const Ut = Ke(({
|
|
|
8513
8513
|
moduleIndex: r.current.currentModuleIndex,
|
|
8514
8514
|
lessonIndex: r.current.currentLessonIndex,
|
|
8515
8515
|
lesson: y()
|
|
8516
|
-
}),
|
|
8516
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8517
8517
|
else if (r.current.currentModuleIndex > 0) {
|
|
8518
8518
|
const O = A.modules[r.current.currentModuleIndex - 1];
|
|
8519
8519
|
r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (O?.lessons?.length || 1) - 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.onCustomAction({
|
|
@@ -8524,17 +8524,17 @@ const Ut = Ke(({
|
|
|
8524
8524
|
moduleIndex: r.current.currentModuleIndex,
|
|
8525
8525
|
lessonIndex: r.current.currentLessonIndex,
|
|
8526
8526
|
lesson: y()
|
|
8527
|
-
}),
|
|
8527
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8528
8528
|
}
|
|
8529
8529
|
}, [y]), ye = U(() => {
|
|
8530
8530
|
r.current.currentModuleIndex = 0, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.isTeaching = !1, r.current.isQuestionMode = !1, r.current.lessonCompleted = !1, r.current.curriculumCompleted = !1, r.current.score = 0, r.current.totalQuestions = 0;
|
|
8531
8531
|
}, []), Re = U((A) => {
|
|
8532
8532
|
console.log("Avatar is ready!", A);
|
|
8533
8533
|
const v = y(), T = v?.avatar_script || v?.body;
|
|
8534
|
-
|
|
8534
|
+
u && T && setTimeout(() => {
|
|
8535
8535
|
d.current && d.current();
|
|
8536
8536
|
}, 10);
|
|
8537
|
-
}, [
|
|
8537
|
+
}, [u, y]);
|
|
8538
8538
|
pt(() => {
|
|
8539
8539
|
d.current = Q, g.current = B, R.current = f, x.current = F, k.current = M, G.current = I, m.current = _;
|
|
8540
8540
|
}), Je(l, () => ({
|
|
@@ -8554,17 +8554,17 @@ const Ut = Ke(({
|
|
|
8554
8554
|
getCurrentQuestion: () => P(),
|
|
8555
8555
|
getCurrentLesson: () => y(),
|
|
8556
8556
|
// Direct access to avatar ref (always returns current value)
|
|
8557
|
-
getAvatarRef: () =>
|
|
8557
|
+
getAvatarRef: () => c.current,
|
|
8558
8558
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8559
8559
|
speakText: async (A, v = {}) => {
|
|
8560
|
-
await
|
|
8560
|
+
await c.current?.resumeAudioContext?.();
|
|
8561
8561
|
const T = E.current || { lipsyncLang: "en" };
|
|
8562
|
-
|
|
8562
|
+
c.current?.speakText(A, { ...v, lipsyncLang: v.lipsyncLang || T.lipsyncLang });
|
|
8563
8563
|
},
|
|
8564
8564
|
resumeAudioContext: async () => {
|
|
8565
|
-
if (
|
|
8566
|
-
return await
|
|
8567
|
-
const A =
|
|
8565
|
+
if (c.current?.resumeAudioContext)
|
|
8566
|
+
return await c.current.resumeAudioContext();
|
|
8567
|
+
const A = c.current?.talkingHead;
|
|
8568
8568
|
if (A?.audioCtx) {
|
|
8569
8569
|
const v = A.audioCtx;
|
|
8570
8570
|
if (v.state === "suspended" || v.state === "interrupted")
|
|
@@ -8576,21 +8576,21 @@ const Ut = Ke(({
|
|
|
8576
8576
|
} else
|
|
8577
8577
|
console.warn("Audio context not available yet");
|
|
8578
8578
|
},
|
|
8579
|
-
stopSpeaking: () =>
|
|
8580
|
-
pauseSpeaking: () =>
|
|
8581
|
-
resumeSpeaking: async () => await
|
|
8582
|
-
isPaused: () =>
|
|
8583
|
-
setMood: (A) =>
|
|
8584
|
-
playAnimation: (A, v) =>
|
|
8585
|
-
setBodyMovement: (A) =>
|
|
8586
|
-
setMovementIntensity: (A) =>
|
|
8587
|
-
playRandomDance: () =>
|
|
8588
|
-
playReaction: (A) =>
|
|
8589
|
-
playCelebration: () =>
|
|
8590
|
-
setShowFullAvatar: (A) =>
|
|
8591
|
-
setTimingAdjustment: (A) =>
|
|
8592
|
-
lockAvatarPosition: () =>
|
|
8593
|
-
unlockAvatarPosition: () =>
|
|
8579
|
+
stopSpeaking: () => c.current?.stopSpeaking(),
|
|
8580
|
+
pauseSpeaking: () => c.current?.pauseSpeaking(),
|
|
8581
|
+
resumeSpeaking: async () => await c.current?.resumeSpeaking(),
|
|
8582
|
+
isPaused: () => c.current && typeof c.current.isPaused < "u" ? c.current.isPaused : !1,
|
|
8583
|
+
setMood: (A) => c.current?.setMood(A),
|
|
8584
|
+
playAnimation: (A, v) => c.current?.playAnimation(A, v),
|
|
8585
|
+
setBodyMovement: (A) => c.current?.setBodyMovement(A),
|
|
8586
|
+
setMovementIntensity: (A) => c.current?.setMovementIntensity(A),
|
|
8587
|
+
playRandomDance: () => c.current?.playRandomDance(),
|
|
8588
|
+
playReaction: (A) => c.current?.playReaction(A),
|
|
8589
|
+
playCelebration: () => c.current?.playCelebration(),
|
|
8590
|
+
setShowFullAvatar: (A) => c.current?.setShowFullAvatar(A),
|
|
8591
|
+
setTimingAdjustment: (A) => c.current?.setTimingAdjustment(A),
|
|
8592
|
+
lockAvatarPosition: () => c.current?.lockAvatarPosition(),
|
|
8593
|
+
unlockAvatarPosition: () => c.current?.unlockAvatarPosition(),
|
|
8594
8594
|
// Custom action trigger
|
|
8595
8595
|
triggerCustomAction: (A, v) => {
|
|
8596
8596
|
h.current.onCustomAction({
|
|
@@ -8600,9 +8600,9 @@ const Ut = Ke(({
|
|
|
8600
8600
|
});
|
|
8601
8601
|
},
|
|
8602
8602
|
// Responsive resize handler
|
|
8603
|
-
handleResize: () =>
|
|
8603
|
+
handleResize: () => c.current?.handleResize(),
|
|
8604
8604
|
// Avatar readiness check (always returns current value)
|
|
8605
|
-
isAvatarReady: () =>
|
|
8605
|
+
isAvatarReady: () => c.current?.isReady || !1
|
|
8606
8606
|
}), [Q, I, _, ve, F, B, f, M, ye, P, y]);
|
|
8607
8607
|
const he = E.current || {
|
|
8608
8608
|
avatarUrl: "/avatars/brunette.glb",
|
|
@@ -8618,9 +8618,9 @@ const Ut = Ke(({
|
|
|
8618
8618
|
animations: e
|
|
8619
8619
|
};
|
|
8620
8620
|
return /* @__PURE__ */ ae("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ ae(
|
|
8621
|
-
|
|
8621
|
+
ct,
|
|
8622
8622
|
{
|
|
8623
|
-
ref:
|
|
8623
|
+
ref: c,
|
|
8624
8624
|
avatarUrl: he.avatarUrl,
|
|
8625
8625
|
avatarBody: he.avatarBody,
|
|
8626
8626
|
mood: he.mood,
|
|
@@ -8651,7 +8651,7 @@ function _t({
|
|
|
8651
8651
|
onDeleteAnimations: o = null,
|
|
8652
8652
|
style: s = {}
|
|
8653
8653
|
}) {
|
|
8654
|
-
const [i, a] = pe([]), [
|
|
8654
|
+
const [i, a] = pe([]), [u, l] = pe(/* @__PURE__ */ new Set()), [c, r] = pe(!0), [h, d] = pe(null), [g, R] = pe("all"), [x, k] = pe("");
|
|
8655
8655
|
Se(() => {
|
|
8656
8656
|
(async () => {
|
|
8657
8657
|
r(!0), d(null);
|
|
@@ -8698,20 +8698,20 @@ function _t({
|
|
|
8698
8698
|
const M = g === "all" || f.group === g, I = x === "" || f.name.toLowerCase().includes(x.toLowerCase()) || f.path.toLowerCase().includes(x.toLowerCase());
|
|
8699
8699
|
return M && I;
|
|
8700
8700
|
}), D = (f) => {
|
|
8701
|
-
const M = new Set(
|
|
8701
|
+
const M = new Set(u);
|
|
8702
8702
|
M.has(f) ? M.delete(f) : M.add(f), l(M), t && t(Array.from(M));
|
|
8703
8703
|
}, E = () => {
|
|
8704
|
-
const f = new Set(
|
|
8704
|
+
const f = new Set(u);
|
|
8705
8705
|
m.forEach((M) => {
|
|
8706
8706
|
f.add(M.path);
|
|
8707
8707
|
}), l(f), t && t(Array.from(f));
|
|
8708
8708
|
}, y = () => {
|
|
8709
|
-
const f = new Set(
|
|
8709
|
+
const f = new Set(u);
|
|
8710
8710
|
m.forEach((M) => {
|
|
8711
8711
|
f.delete(M.path);
|
|
8712
8712
|
}), l(f), t && t(Array.from(f));
|
|
8713
8713
|
}, P = () => {
|
|
8714
|
-
const M = i.filter((I) => !
|
|
8714
|
+
const M = i.filter((I) => !u.has(I.path)).map((I) => I.path);
|
|
8715
8715
|
if (M.length === 0) {
|
|
8716
8716
|
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8717
8717
|
return;
|
|
@@ -8721,11 +8721,11 @@ function _t({
|
|
|
8721
8721
|
This will delete:
|
|
8722
8722
|
${M.slice(0, 5).join(`
|
|
8723
8723
|
`)}${M.length > 5 ? `
|
|
8724
|
-
...` : ""}`) && (o && o(M), a(i.filter((I) =>
|
|
8724
|
+
...` : ""}`) && (o && o(M), a(i.filter((I) => u.has(I.path))), l(/* @__PURE__ */ new Set()));
|
|
8725
8725
|
}, L = (f) => {
|
|
8726
8726
|
e && e(f);
|
|
8727
8727
|
};
|
|
8728
|
-
return
|
|
8728
|
+
return c ? /* @__PURE__ */ ae("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ ae("p", { children: "Loading animations..." }) }) : h ? /* @__PURE__ */ ae("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ Pe("p", { children: [
|
|
8729
8729
|
"Error loading animations: ",
|
|
8730
8730
|
h
|
|
8731
8731
|
] }) }) : /* @__PURE__ */ Pe("div", { style: {
|
|
@@ -8827,7 +8827,7 @@ ${M.slice(0, 5).join(`
|
|
|
8827
8827
|
},
|
|
8828
8828
|
children: [
|
|
8829
8829
|
"Delete Unselected (",
|
|
8830
|
-
i.length -
|
|
8830
|
+
i.length - u.size,
|
|
8831
8831
|
")"
|
|
8832
8832
|
]
|
|
8833
8833
|
}
|
|
@@ -8841,7 +8841,7 @@ ${M.slice(0, 5).join(`
|
|
|
8841
8841
|
"Total: ",
|
|
8842
8842
|
i.length,
|
|
8843
8843
|
" | Selected: ",
|
|
8844
|
-
|
|
8844
|
+
u.size,
|
|
8845
8845
|
" | Showing: ",
|
|
8846
8846
|
m.length
|
|
8847
8847
|
] }),
|
|
@@ -8855,7 +8855,7 @@ ${M.slice(0, 5).join(`
|
|
|
8855
8855
|
backgroundColor: "#1a1a1a",
|
|
8856
8856
|
borderRadius: "6px"
|
|
8857
8857
|
}, children: m.map((f, M) => {
|
|
8858
|
-
const I =
|
|
8858
|
+
const I = u.has(f.path);
|
|
8859
8859
|
return /* @__PURE__ */ Pe(
|
|
8860
8860
|
"div",
|
|
8861
8861
|
{
|
|
@@ -8926,7 +8926,7 @@ ${M.slice(0, 5).join(`
|
|
|
8926
8926
|
}, children: "No animations found matching your filters." })
|
|
8927
8927
|
] });
|
|
8928
8928
|
}
|
|
8929
|
-
const
|
|
8929
|
+
const ut = {
|
|
8930
8930
|
// Code-based dance animations (no FBX required)
|
|
8931
8931
|
dance: {
|
|
8932
8932
|
name: "dance",
|
|
@@ -9029,14 +9029,14 @@ const ct = {
|
|
|
9029
9029
|
duration: 5e3,
|
|
9030
9030
|
description: "Excited, energetic movement"
|
|
9031
9031
|
}
|
|
9032
|
-
}, Kt = (Z) =>
|
|
9032
|
+
}, Kt = (Z) => ut[Z] || null, Jt = (Z) => ut.hasOwnProperty(Z);
|
|
9033
9033
|
export {
|
|
9034
9034
|
_t as AnimationSelector,
|
|
9035
9035
|
Ut as CurriculumLearning,
|
|
9036
9036
|
Nt as SimpleTalkingAvatar,
|
|
9037
|
-
|
|
9037
|
+
ct as TalkingHeadAvatar,
|
|
9038
9038
|
Ot as TalkingHeadComponent,
|
|
9039
|
-
|
|
9039
|
+
ut as animations,
|
|
9040
9040
|
$e as getActiveTTSConfig,
|
|
9041
9041
|
Kt as getAnimation,
|
|
9042
9042
|
qt as getVoiceOptions,
|