@sage-rsc/talking-head-react 1.5.0 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +7 -2
- package/dist/index.js +1446 -1157
- package/package.json +1 -1
- package/src/components/AnimationSelector.jsx +419 -0
- package/src/index.js +1 -0
- package/src/lib/talkinghead.mjs +34 -28
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
1
|
+
import { jsxs as fe, jsx as q } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Fe, useRef as X, useState as ae, useEffect as me, useCallback as U, useImperativeHandle as Ee, useLayoutEffect as je } from "react";
|
|
3
3
|
import * as y from "three";
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
6
|
-
import { DRACOLoader as
|
|
4
|
+
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as Qe } from "three/addons/loaders/GLTFLoader.js";
|
|
6
|
+
import { DRACOLoader as qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
7
|
import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let m,
|
|
11
|
-
const
|
|
8
|
+
import { RoomEnvironment as _e } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import Ke from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, de, pe;
|
|
11
|
+
const z = [0, 0, 0, 0], E = new y.Vector3(), ze = new y.Vector3(), ce = new y.Vector3(), He = new y.Vector3();
|
|
12
12
|
new y.Plane();
|
|
13
13
|
new y.Ray();
|
|
14
14
|
new y.Euler();
|
|
15
|
-
const
|
|
15
|
+
const he = new y.Quaternion(), Ne = new y.Quaternion(), xe = new y.Matrix4(), be = new y.Matrix4();
|
|
16
16
|
new y.Vector3();
|
|
17
|
-
const
|
|
18
|
-
class
|
|
17
|
+
const Te = new y.Vector3(0, 0, 1), Je = new y.Vector3(1, 0, 0), $e = new y.Vector3(0, 1, 0), et = new y.Vector3(0, 0, 1);
|
|
18
|
+
class tt {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -192,7 +192,7 @@ class et {
|
|
|
192
192
|
const l = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!l) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const c = {
|
|
196
196
|
bone: l,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class et {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((r) => Number.isNaN(r))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
|
|
206
|
-
|
|
206
|
+
c.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
i.excludes.push(
|
|
208
|
+
i.excludes.push(c);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class et {
|
|
|
282
282
|
m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const n = /* @__PURE__ */ new WeakSet(), i = (o) => o.parent?.isBone ? [o, ...i(o.parent)] : [o], s = (o) => {
|
|
285
|
-
i(o).forEach((
|
|
286
|
-
n.has(
|
|
285
|
+
i(o).forEach((c) => {
|
|
286
|
+
n.has(c) || (this.objectsUpdate.push(c), n.add(c));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((o) => {
|
|
@@ -308,12 +308,12 @@ class et {
|
|
|
308
308
|
i(t?.isScene, "First parameter must be Scene."), this.scene = t, i(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, i(Array.isArray(n), "Third parameter must be an array of bone configs."), this.config = n, this.config.forEach((s, o) => {
|
|
309
309
|
const l = "Config item #" + o + ": ";
|
|
310
310
|
i(s.bone, l + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
i(typeof
|
|
313
|
-
const r = this.armature.getObjectByName(
|
|
314
|
-
i(r, l + "Bone '" +
|
|
311
|
+
const c = s.bone;
|
|
312
|
+
i(typeof c == "string" && c.length > 0, l + "Bone name must be a non-empty string.");
|
|
313
|
+
const r = this.armature.getObjectByName(c);
|
|
314
|
+
i(r, l + "Bone '" + c + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + c + "' already exists."), r.updateMatrixWorld(!0);
|
|
315
315
|
const u = {
|
|
316
|
-
name:
|
|
316
|
+
name: c,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: r,
|
|
319
319
|
// Bone object
|
|
@@ -321,7 +321,7 @@ class et {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: r.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: r.parent.getWorldPosition(
|
|
324
|
+
vWorld: r.parent.getWorldPosition(E).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: r.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,9 +338,9 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
u.boneParent.matrixWorld.decompose(
|
|
341
|
+
u.boneParent.matrixWorld.decompose(E, he, ce), E.copy(Te).applyQuaternion(he).setY(0).normalize(), he.premultiply(Ne.setFromUnitVectors(Te, E).invert()).normalize(), u.qWorldInverseYaw = he.clone().normalize(), this.data.push(u), this.dict[c] = u;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(c, "type", s.type), this.setValue(c, "stiffness", s.stiffness), this.setValue(c, "damping", s.damping), this.setValue(c, "external", s.external), this.setValue(c, "limits", s.limits), this.setValue(c, "excludes", s.excludes), this.setValue(c, "deltaLocal", s.deltaLocal), this.setValue(c, "deltaWorld", s.deltaWorld), this.setValue(c, "pivot", s.pivot), this.setValue(c, "helper", s.helper);
|
|
344
344
|
} catch (a) {
|
|
345
345
|
i(!1, l + a);
|
|
346
346
|
}
|
|
@@ -356,22 +356,22 @@ class et {
|
|
|
356
356
|
for (this.timerMs += t, t > 1e3 && (this.timerMs = 0), t /= 1e3, e = 0, i = this.objectsUpdate.length; e < i; e++)
|
|
357
357
|
o = this.objectsUpdate[e], o.updateMatrix(), o.parent === null ? o.matrixWorld.copy(o.matrix) : o.matrixWorld.multiplyMatrices(o.parent.matrixWorld, o.matrix), o.matrixWorldNeedsUpdate = !1;
|
|
358
358
|
for (e = 0, i = this.data.length; e < i; e++) {
|
|
359
|
-
if (o = this.data[e],
|
|
359
|
+
if (o = this.data[e], E.copy(o.vWorld), xe.copy(o.boneParent.matrixWorld), be.copy(xe).invert(), o.vWorld.setFromMatrixPosition(xe), E.applyMatrix4(be), E.length() > 0.5 && (console.info("Info: Unrealistic jump of " + E.length().toFixed(2) + " meters."), E.setLength(0.5)), E.applyQuaternion(o.bone.quaternion), z[0] = E.x, z[1] = E.y, z[2] = -E.z, z[3] = E.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
|
-
m = o.children[n],
|
|
362
|
-
if (m = this.opt.sensitivityFactor,
|
|
363
|
-
o.vBasis.x +
|
|
364
|
-
o.vBasis.y +
|
|
365
|
-
o.vBasis.z +
|
|
366
|
-
),
|
|
361
|
+
m = o.children[n], z[0] -= m.v[0] * t / 3, z[1] -= m.v[1] * t / 3, z[2] += m.v[2] * t / 3, z[3] -= m.v[3] * t / 3;
|
|
362
|
+
if (m = this.opt.sensitivityFactor, z[0] *= o.ext * m, z[1] *= o.ext * m, z[2] *= o.ext * m, z[3] *= o.ext * m, o.isX && (m = z[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + z[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = z[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + z[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = z[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + z[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = z[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + z[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), z[0] = o.p[0], z[1] = o.p[1], z[2] = o.p[2], z[3] = o.p[3], m = this.opt.movementFactor, z[0] *= m, z[1] *= m, z[2] *= m, z[3] *= m, o.dl && (m = o.dl, z[0] += m[0], z[1] += m[1], z[2] += m[2]), o.dw && (m = o.dw, E.set(
|
|
363
|
+
o.vBasis.x + z[0],
|
|
364
|
+
o.vBasis.y + z[1],
|
|
365
|
+
o.vBasis.z + z[2]
|
|
366
|
+
), E.applyMatrix4(xe), E.x += m[0], E.y += m[1], E.z += m[2], E.applyMatrix4(be), z[0] += E.x - o.vBasis.x, z[1] += E.y - o.vBasis.y, z[2] += E.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && z[0] < m[0][0] && (z[0] = m[0][0]), m[0][1] !== null && z[0] > m[0][1] && (z[0] = m[0][1])), m[1] && (m[1][0] !== null && z[1] < m[1][0] && (z[1] = m[1][0]), m[1][1] !== null && z[1] > m[1][1] && (z[1] = m[1][1])), m[2] && (m[2][0] !== null && z[2] < m[2][0] && (z[2] = m[2][0]), m[2][1] !== null && z[2] > m[2][1] && (z[2] = m[2][1])), m[3] && (m[3][0] !== null && z[3] < m[3][0] && (z[3] = m[3][0]), m[3][1] !== null && z[3] > m[3][1] && (z[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
|
-
o.vBasis.x +
|
|
369
|
-
o.vBasis.y +
|
|
370
|
-
o.vBasis.z -
|
|
368
|
+
o.vBasis.x + z[0],
|
|
369
|
+
o.vBasis.y + z[1],
|
|
370
|
+
o.vBasis.z - z[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(E, he, ce), E.copy(Te).applyQuaternion(he).setY(0).normalize(), he.premultiply(Ne.setFromUnitVectors(Te, E).invert()).normalize(), o.boneParent.quaternion.multiply(he.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(z[0] / o.l), he.setFromAxisAngle(et, -m), o.boneParent.quaternion.multiply(he)), o.isY && (m = o.l / 3, m = m * Math.tanh(z[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(z[2] / o.l), he.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(he)), o.isT && (m = 1.5 * Math.tanh(z[3] * 1.5), he.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(he)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
m = o.excludes[n],
|
|
374
|
+
m = o.excludes[n], ce.set(0, 0, 0), m.deltaLocal && (ce.x += m.deltaLocal[0], ce.y += m.deltaLocal[1], ce.z += m.deltaLocal[2]), ce.applyMatrix4(m.bone.matrixWorld), be.copy(o.boneParent.matrixWorld).invert(), ce.applyMatrix4(be), E.copy(o.bone.position), !(E.distanceToSquared(ce) >= m.radiusSq) && (pe = E.length(), de = ce.length(), !(de > m.radius + pe) && (de < Math.abs(m.radius - pe) || (de = (de * de + pe * pe - m.radiusSq) / (2 * de), ce.normalize(), He.copy(ce).multiplyScalar(de), de = Math.sqrt(pe * pe - de * de), E.subVectors(E, He).projectOnPlane(ce).normalize().multiplyScalar(de), ze.subVectors(o.vBasis, He).projectOnPlane(ce).normalize(), pe = ze.dot(E), pe < 0 && (pe = Math.sqrt(de * de - pe * pe), ze.multiplyScalar(pe), E.add(ze)), E.add(He).normalize(), ce.copy(o.bone.position).normalize(), he.setFromUnitVectors(ce, E), o.boneParent.quaternion.premultiply(he), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -408,9 +408,9 @@ class et {
|
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new y.BufferGeometry(), n = m.bones.map((
|
|
411
|
+
const e = new y.BufferGeometry(), n = m.bones.map((c) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new y.Float32BufferAttribute(n, 3));
|
|
413
|
-
const i = new y.Color(this.opt.helperBoneColor1), s = new y.Color(this.opt.helperBoneColor2), o = m.pivots.map((
|
|
413
|
+
const i = new y.Color(this.opt.helperBoneColor1), s = new y.Color(this.opt.helperBoneColor2), o = m.pivots.map((c) => c && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
|
|
414
414
|
e.setAttribute("color", new y.Float32BufferAttribute(o, 3));
|
|
415
415
|
const l = new y.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class et {
|
|
|
423
423
|
m.object = new y.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new y.BufferGeometry(), n = m.bones.map((
|
|
426
|
+
const e = new y.BufferGeometry(), n = m.bones.map((c) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new y.Float32BufferAttribute(n, 3));
|
|
428
|
-
const i = new y.Color(this.opt.helperLinkColor1), s = new y.Color(this.opt.helperLinkColor2), o = m.bones.map((
|
|
428
|
+
const i = new y.Color(this.opt.helperLinkColor1), s = new y.Color(this.opt.helperLinkColor2), o = m.bones.map((c) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new y.Float32BufferAttribute(o, 3));
|
|
430
430
|
const l = new y.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -442,17 +442,17 @@ class et {
|
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
444
|
if (m = this.helpers.points, m.bones.length) {
|
|
445
|
-
|
|
445
|
+
be.copy(this.armature.matrixWorld).invert();
|
|
446
446
|
const t = m.object.geometry.getAttribute("position");
|
|
447
447
|
for (let e = 0, n = m.bones.length; e < n; e++)
|
|
448
|
-
|
|
448
|
+
xe.multiplyMatrices(be, m.bones[e].matrixWorld), E.setFromMatrixPosition(xe), t.setXYZ(e, E.x, E.y, E.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
|
-
|
|
452
|
+
be.copy(this.armature.matrixWorld).invert();
|
|
453
453
|
const t = m.object.geometry.getAttribute("position");
|
|
454
454
|
for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
|
|
455
|
-
|
|
455
|
+
xe.multiplyMatrices(be, m.bones[e].matrixWorld), E.setFromMatrixPosition(xe), t.setXYZ(n, E.x, E.y, E.z), xe.multiplyMatrices(be, m.bones[e].parent.matrixWorld), E.setFromMatrixPosition(xe), t.setXYZ(n + 1, E.x, E.y, E.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -489,7 +489,7 @@ class et {
|
|
|
489
489
|
this.stop(), this.scene = null, this.armature = null, this.config = [], this.data = [], this.dict = {}, this.objectsUpdate = [], this.timerMs = 0;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
class
|
|
492
|
+
class nt {
|
|
493
493
|
constructor(t) {
|
|
494
494
|
this.audioContext = t, this.analyzer = null, this.dataArray = null, this.bufferLength = 0;
|
|
495
495
|
}
|
|
@@ -519,12 +519,12 @@ class tt {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
|
|
521
521
|
for (let l = 0; l < o; l++) {
|
|
522
|
-
const
|
|
522
|
+
const c = l * s, r = Math.min(c + i, t.length), u = t.slice(c, r), a = this.calculateEnergy(u);
|
|
523
523
|
n.energy.push(a);
|
|
524
524
|
const d = this.calculateSpectralCentroid(u);
|
|
525
525
|
n.spectralCentroid.push(d);
|
|
526
|
-
const
|
|
527
|
-
n.zeroCrossingRate.push(
|
|
526
|
+
const h = this.calculateZeroCrossingRate(u);
|
|
527
|
+
n.zeroCrossingRate.push(h);
|
|
528
528
|
const g = this.calculateMFCC(u);
|
|
529
529
|
n.mfcc.push(g);
|
|
530
530
|
}
|
|
@@ -597,19 +597,19 @@ class tt {
|
|
|
597
597
|
for (; s & o; )
|
|
598
598
|
s ^= o, o >>= 1;
|
|
599
599
|
if (s ^= o, i < s) {
|
|
600
|
-
const l = n[i * 2],
|
|
601
|
-
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] =
|
|
600
|
+
const l = n[i * 2], c = n[i * 2 + 1];
|
|
601
|
+
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] = c;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let i = 2; i <= e; i <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / i, o = Math.cos(s), l = Math.sin(s);
|
|
606
|
-
for (let
|
|
606
|
+
for (let c = 0; c < e; c += i) {
|
|
607
607
|
let r = 1, u = 0;
|
|
608
608
|
for (let a = 0; a < i / 2; a++) {
|
|
609
|
-
const d = n[(
|
|
610
|
-
n[(
|
|
611
|
-
const f = r * o - u * l,
|
|
612
|
-
r = f, u =
|
|
609
|
+
const d = n[(c + a) * 2], h = n[(c + a) * 2 + 1], g = n[(c + a + i / 2) * 2] * r - n[(c + a + i / 2) * 2 + 1] * u, b = n[(c + a + i / 2) * 2] * u + n[(c + a + i / 2) * 2 + 1] * r;
|
|
610
|
+
n[(c + a) * 2] = d + g, n[(c + a) * 2 + 1] = h + b, n[(c + a + i / 2) * 2] = d - g, n[(c + a + i / 2) * 2 + 1] = h - b;
|
|
611
|
+
const f = r * o - u * l, w = r * l + u * o;
|
|
612
|
+
r = f, u = w;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class tt {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let o = 1; o < t.length; o++) {
|
|
627
|
-
const l = t[o] - t[o - 1],
|
|
628
|
-
l > 0.1 &&
|
|
627
|
+
const l = t[o] - t[o - 1], c = o * 0.023;
|
|
628
|
+
l > 0.1 && c - s > 0.1 && (e.push(c), s = c);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class tt {
|
|
|
637
637
|
detectPhonemeBoundaries(t) {
|
|
638
638
|
const e = [], { energy: n, spectralCentroid: i, zeroCrossingRate: s } = t;
|
|
639
639
|
for (let o = 1; o < n.length; o++) {
|
|
640
|
-
const l = o * 0.023,
|
|
641
|
-
|
|
640
|
+
const l = o * 0.023, c = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), u = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
c + r * 0.1 + u * 0.5 > 0.2 && e.push(l);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,8 +654,8 @@ class tt {
|
|
|
654
654
|
t.phonemeBoundaries, t.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let o = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const r = i[
|
|
657
|
+
for (let c = 0; c < i.length; c++) {
|
|
658
|
+
const r = i[c], u = this.estimateWordDuration(r, n / i.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: r,
|
|
661
661
|
startTime: o,
|
|
@@ -701,27 +701,27 @@ class tt {
|
|
|
701
701
|
const i = [], s = t.phonemeBoundaries;
|
|
702
702
|
t.onsets;
|
|
703
703
|
const o = this.textToVisemes(e);
|
|
704
|
-
let l = 0,
|
|
704
|
+
let l = 0, c = 0;
|
|
705
705
|
for (let r = 0; r < s.length && l < o.length; r++) {
|
|
706
|
-
const u = s[r], a = o[l], d = t.energy[Math.floor(u / 0.023)] || 0,
|
|
706
|
+
const u = s[r], a = o[l], d = t.energy[Math.floor(u / 0.023)] || 0, h = this.calculateVisemeDuration(a, d);
|
|
707
707
|
i.push({
|
|
708
708
|
viseme: a,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
711
|
-
duration:
|
|
709
|
+
startTime: c,
|
|
710
|
+
endTime: c + h,
|
|
711
|
+
duration: h,
|
|
712
712
|
intensity: Math.min(1, d * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), c += h, l++;
|
|
715
715
|
}
|
|
716
716
|
for (; l < o.length; ) {
|
|
717
717
|
const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
|
|
718
718
|
i.push({
|
|
719
719
|
viseme: r,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
720
|
+
startTime: c,
|
|
721
|
+
endTime: c + u,
|
|
722
722
|
duration: u,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), c += u, l++;
|
|
725
725
|
}
|
|
726
726
|
return i;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class tt {
|
|
|
775
775
|
let o = 0;
|
|
776
776
|
for (; o < s.length; ) {
|
|
777
777
|
let l = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const r = s.substr(o,
|
|
778
|
+
for (let c = 3; c >= 2; c--) {
|
|
779
|
+
const r = s.substr(o, c);
|
|
780
780
|
if (e[r]) {
|
|
781
|
-
n.push(e[r]), o +=
|
|
781
|
+
n.push(e[r]), o += c, l = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!l) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const c = s[o];
|
|
787
|
+
e[c] && n.push(e[c]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -814,7 +814,7 @@ class tt {
|
|
|
814
814
|
return i * s;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
class
|
|
817
|
+
class it {
|
|
818
818
|
/**
|
|
819
819
|
* @constructor
|
|
820
820
|
*/
|
|
@@ -1206,11 +1206,11 @@ class nt {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1209
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1209
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), c = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let d = "";
|
|
1211
1211
|
d += [...l].map((g) => t[g] || g).join("");
|
|
1212
|
-
const
|
|
1213
|
-
return
|
|
1212
|
+
const h = [...c];
|
|
1213
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), a.move = h.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
|
|
1214
1214
|
a.visemes.push(g);
|
|
1215
1215
|
}), a;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class nt {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(t) {
|
|
1326
1326
|
const e = parseInt(t), n = !isNaN(e) && t.length === 2, i = !isNaN(e) && t.length > 2 && e > 0 && e <= 3e3, s = i && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, o = i && !s ? Math.floor(e / 100) : null, l = n || i ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let c = [];
|
|
1328
|
+
return s ? c.push(this.convertNumberToWords(s).trim(), "thousands") : (o && c.push(this.convertNumberToWords(o).trim()), l ? c.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? c.push("hundreds") : c.push(t)), c.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class nt {
|
|
|
1376
1376
|
const s = i[e.i], o = this.rules[s];
|
|
1377
1377
|
if (o)
|
|
1378
1378
|
for (let l = 0; l < o.length; l++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const c = o[l];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(c.regex)) {
|
|
1381
|
+
c.visemes.forEach((a) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
1383
1383
|
const d = 0.7 * (this.visemeDurations[a] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += d, n += d;
|
|
@@ -1386,7 +1386,7 @@ class nt {
|
|
|
1386
1386
|
const d = this.visemeDurations[a] || 1;
|
|
1387
1387
|
e.visemes.push(a), e.times.push(n), e.durations.push(d), n += d;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += c.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1396,11 +1396,11 @@ class nt {
|
|
|
1396
1396
|
return e;
|
|
1397
1397
|
}
|
|
1398
1398
|
}
|
|
1399
|
-
const
|
|
1399
|
+
const ot = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1400
1400
|
__proto__: null,
|
|
1401
|
-
LipsyncEn:
|
|
1401
|
+
LipsyncEn: it
|
|
1402
1402
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1403
|
-
class
|
|
1403
|
+
class st {
|
|
1404
1404
|
/**
|
|
1405
1405
|
* @constructor
|
|
1406
1406
|
*/
|
|
@@ -1616,11 +1616,11 @@ class ot {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1619
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1619
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), c = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let d = "";
|
|
1621
1621
|
d += [...l].map((g) => t[g] || g).join("");
|
|
1622
|
-
const
|
|
1623
|
-
return
|
|
1622
|
+
const h = [...c];
|
|
1623
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), a.move = h.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
|
|
1624
1624
|
a.visemes.push(g);
|
|
1625
1625
|
}), a;
|
|
1626
1626
|
});
|
|
@@ -1732,16 +1732,16 @@ class ot {
|
|
|
1732
1732
|
const s = i[e.i], o = this.rules[s];
|
|
1733
1733
|
if (o) {
|
|
1734
1734
|
let l = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const r = o[
|
|
1735
|
+
for (let c = 0; c < o.length; c++) {
|
|
1736
|
+
const r = o[c];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
1738
1738
|
r.visemes.forEach((d) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
1740
|
-
const
|
|
1741
|
-
e.durations[e.durations.length - 1] +=
|
|
1740
|
+
const h = 0.7 * (this.visemeDurations[d] || 1);
|
|
1741
|
+
e.durations[e.durations.length - 1] += h, n += h;
|
|
1742
1742
|
} else {
|
|
1743
|
-
const
|
|
1744
|
-
e.visemes.push(d), e.times.push(n), e.durations.push(
|
|
1743
|
+
const h = this.visemeDurations[d] || 1;
|
|
1744
|
+
e.visemes.push(d), e.times.push(n), e.durations.push(h), n += h;
|
|
1745
1745
|
}
|
|
1746
1746
|
}), e.i += r.move, l = !0;
|
|
1747
1747
|
break;
|
|
@@ -1754,11 +1754,11 @@ class ot {
|
|
|
1754
1754
|
return e;
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
1757
|
-
const
|
|
1757
|
+
const at = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1758
1758
|
__proto__: null,
|
|
1759
|
-
LipsyncDe:
|
|
1759
|
+
LipsyncDe: st
|
|
1760
1760
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1761
|
-
class
|
|
1761
|
+
class rt {
|
|
1762
1762
|
/**
|
|
1763
1763
|
* @constructor
|
|
1764
1764
|
*/
|
|
@@ -2131,11 +2131,11 @@ class at {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((n) => {
|
|
2134
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
2134
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), c = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let d = "";
|
|
2136
2136
|
d += [...l].map((g) => t[g] || g).join("");
|
|
2137
|
-
const
|
|
2138
|
-
return
|
|
2137
|
+
const h = [...c];
|
|
2138
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), a.move = h.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d, "i"), u.length && u.split(" ").forEach((g) => {
|
|
2139
2139
|
g && a.visemes.push(g);
|
|
2140
2140
|
}), a;
|
|
2141
2141
|
});
|
|
@@ -2267,16 +2267,16 @@ class at {
|
|
|
2267
2267
|
const s = i[e.i], o = this.rules[s];
|
|
2268
2268
|
if (o) {
|
|
2269
2269
|
let l = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const r = o[
|
|
2270
|
+
for (let c = 0; c < o.length; c++) {
|
|
2271
|
+
const r = o[c];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
2273
2273
|
r.visemes.forEach((d) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
2275
|
-
const
|
|
2276
|
-
e.durations[e.durations.length - 1] +=
|
|
2275
|
+
const h = 0.7 * (this.visemeDurations[d] || 1);
|
|
2276
|
+
e.durations[e.durations.length - 1] += h, n += h;
|
|
2277
2277
|
} else {
|
|
2278
|
-
const
|
|
2279
|
-
e.visemes.push(d), e.times.push(n), e.durations.push(
|
|
2278
|
+
const h = this.visemeDurations[d] || 1;
|
|
2279
|
+
e.visemes.push(d), e.times.push(n), e.durations.push(h), n += h;
|
|
2280
2280
|
}
|
|
2281
2281
|
}), e.i += r.move, l = !0;
|
|
2282
2282
|
break;
|
|
@@ -2289,11 +2289,11 @@ class at {
|
|
|
2289
2289
|
return e;
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
|
-
const
|
|
2292
|
+
const lt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2293
2293
|
__proto__: null,
|
|
2294
|
-
LipsyncFr:
|
|
2294
|
+
LipsyncFr: rt
|
|
2295
2295
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2296
|
-
class
|
|
2296
|
+
class ut {
|
|
2297
2297
|
/**
|
|
2298
2298
|
* @constructor
|
|
2299
2299
|
*/
|
|
@@ -2381,10 +2381,10 @@ class lt {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let n = parseFloat(t);
|
|
2383
2383
|
if (n === void 0) return t;
|
|
2384
|
-
let i = (s, o, l,
|
|
2384
|
+
let i = (s, o, l, c, r) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
2386
|
const u = Math.floor(s / o);
|
|
2387
|
-
return e.push(l + (u === 1 ?
|
|
2387
|
+
return e.push(l + (u === 1 ? c : this.numberToFinnishWords(u.toString()) + r)), s - u * o;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (n < 0 && (e.push("miinus "), n = Math.abs(n)), n = i(n, 1e9, " ", "miljardi", " miljardia"), n = i(n, 1e6, " ", "miljoona", " miljoonaa"), n = i(n, 1e3, "", "tuhat", "tuhatta"), n = i(n, 100, " ", "sata", "sataa"), n > 20 && (n = i(n, 10, "", "", "kymmentä")), n >= 1) {
|
|
2390
2390
|
let s = Math.floor(n);
|
|
@@ -2436,9 +2436,9 @@ class lt {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
|
-
LipsyncFi:
|
|
2441
|
+
LipsyncFi: ut
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
2443
|
class ht {
|
|
2444
2444
|
/**
|
|
@@ -2559,10 +2559,10 @@ class ht {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let n = parseFloat(t);
|
|
2561
2561
|
if (n === void 0) return t;
|
|
2562
|
-
let i = (s, o, l,
|
|
2562
|
+
let i = (s, o, l, c, r) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
2564
|
const u = Math.floor(s / o);
|
|
2565
|
-
return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(l) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(r) : e.push(
|
|
2565
|
+
return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(l) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(r) : e.push(c), s - u * o;
|
|
2566
2566
|
};
|
|
2567
2567
|
n < 0 && (e.push("minus"), n = Math.abs(n)), n = i(n, 1e9, "milijardas", "milijardai", "milijardų"), n = i(n, 1e6, "milijonas", "milijonai", "milijonų"), n = i(n, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), n = i(n, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class ht {
|
|
|
2608
2608
|
const o = i[s].toLowerCase(), l = this.visemes[o];
|
|
2609
2609
|
if (l)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const c = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += c, n += c;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(l), e.times.push(n), e.durations.push(
|
|
2614
|
+
const c = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(l), e.times.push(n), e.durations.push(c), n += c;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
n += this.pauses[i[s]] || 0;
|
|
@@ -2620,21 +2620,21 @@ class ht {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const dt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
2625
|
LipsyncLt: ht
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
|
|
2627
|
-
en:
|
|
2628
|
-
de:
|
|
2629
|
-
fr:
|
|
2630
|
-
fi:
|
|
2631
|
-
lt:
|
|
2632
|
-
},
|
|
2626
|
+
}, Symbol.toStringTag, { value: "Module" })), mt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
|
|
2627
|
+
en: ot,
|
|
2628
|
+
de: at,
|
|
2629
|
+
fr: lt,
|
|
2630
|
+
fi: ct,
|
|
2631
|
+
lt: dt
|
|
2632
|
+
}, te = new y.Quaternion(), Q = new y.Euler(), Re = new y.Vector3(), Ie = new y.Vector3(), We = new y.Box3();
|
|
2633
2633
|
new y.Matrix4();
|
|
2634
2634
|
new y.Matrix4();
|
|
2635
2635
|
new y.Vector3();
|
|
2636
2636
|
new y.Vector3(0, 0, 1);
|
|
2637
|
-
const
|
|
2637
|
+
const pt = new y.Vector3(1, 0, 0);
|
|
2638
2638
|
new y.Vector3(0, 1, 0);
|
|
2639
2639
|
new y.Vector3(0, 0, 1);
|
|
2640
2640
|
class Be {
|
|
@@ -2763,7 +2763,7 @@ class Be {
|
|
|
2763
2763
|
avatarOnlyCamera: null,
|
|
2764
2764
|
statsNode: null,
|
|
2765
2765
|
statsStyle: null
|
|
2766
|
-
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new
|
|
2766
|
+
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new Ke(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
|
|
2767
2767
|
side: {
|
|
2768
2768
|
standing: !0,
|
|
2769
2769
|
props: {
|
|
@@ -3569,15 +3569,15 @@ class Be {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((l) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[l +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[l +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((c) => {
|
|
3573
|
+
this.poseDelta.props[l + c + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((c) => {
|
|
3575
|
+
this.poseDelta.props[l + c + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + c + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + c + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const n = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((l) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(l.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(l.props)).forEach((c) => n.add(c));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((l) => {
|
|
3582
3582
|
n.add(l);
|
|
3583
3583
|
}), this.posePropNames = [...n], 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 = {
|
|
@@ -4086,7 +4086,7 @@ class Be {
|
|
|
4086
4086
|
this.opt.lightSpotDispersion
|
|
4087
4087
|
), this.setLighting(this.opt);
|
|
4088
4088
|
const l = new y.PMREMGenerator(this.renderer);
|
|
4089
|
-
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new
|
|
4089
|
+
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new _e()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4090
4090
|
}
|
|
4091
4091
|
this.ikMesh = new y.SkinnedMesh();
|
|
4092
4092
|
const s = {
|
|
@@ -4101,17 +4101,17 @@ class Be {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, o = [];
|
|
4104
|
-
Object.entries(s).forEach((l,
|
|
4104
|
+
Object.entries(s).forEach((l, c) => {
|
|
4105
4105
|
const r = new y.Bone();
|
|
4106
4106
|
r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
|
|
4107
|
-
}), this.ikMesh.bind(new y.Skeleton(o)), this.dynamicbones = new
|
|
4107
|
+
}), this.ikMesh.bind(new y.Skeleton(o)), this.dynamicbones = new tt(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
4108
4108
|
}
|
|
4109
4109
|
/**
|
|
4110
4110
|
* Helper that re/creates the audio context and the other nodes.
|
|
4111
4111
|
* @param {number} sampleRate
|
|
4112
4112
|
*/
|
|
4113
4113
|
initAudioGraph(t = null) {
|
|
4114
|
-
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new
|
|
4114
|
+
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new nt(this.audioCtx), this.audioReverbNode = this.audioCtx.createConvolver(), this.audioBackgroundGainNode.connect(this.audioReverbNode), this.audioAnalyzerNode.connect(this.audioSpeechGainNode), this.audioSpeechGainNode.connect(this.audioReverbNode), this.audioStreamGainNode.connect(this.audioReverbNode), this.audioReverbNode.connect(this.audioCtx.destination), this.setReverb(this.currentReverb || null), this.setMixerGain(
|
|
4115
4115
|
this.opt.mixerGainSpeech,
|
|
4116
4116
|
this.opt.mixerGainBackground
|
|
4117
4117
|
), this.workletLoaded = !1, this.streamWorkletNode) {
|
|
@@ -4150,9 +4150,9 @@ class Be {
|
|
|
4150
4150
|
let e = 3 * t.length / 4;
|
|
4151
4151
|
t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
|
|
4152
4152
|
const n = new ArrayBuffer(e), i = new Uint8Array(n);
|
|
4153
|
-
let s, o = 0, l,
|
|
4153
|
+
let s, o = 0, l, c, r, u;
|
|
4154
4154
|
for (s = 0; s < t.length; s += 4)
|
|
4155
|
-
l = this.b64Lookup[t.charCodeAt(s)],
|
|
4155
|
+
l = this.b64Lookup[t.charCodeAt(s)], c = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], u = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | c >> 4, i[o++] = (c & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | u & 63;
|
|
4156
4156
|
return n;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class Be {
|
|
|
4193
4193
|
const e = {};
|
|
4194
4194
|
for (let [n, i] of Object.entries(t)) {
|
|
4195
4195
|
const s = n.split(".");
|
|
4196
|
-
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[n] = new y.Vector3(o, l,
|
|
4196
|
+
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, c = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[n] = new y.Vector3(o, l, c) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new y.Quaternion().setFromEuler(new y.Euler(o, l, c, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new y.Quaternion(o, l, c, i.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class Be {
|
|
|
4222
4222
|
t.forEach((s) => {
|
|
4223
4223
|
if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const o = s.geometry;
|
|
4225
|
-
let l = null,
|
|
4225
|
+
let l = null, c = null;
|
|
4226
4226
|
for (const [r, u] of Object.entries(n))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(r)) {
|
|
4228
|
-
const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a],
|
|
4229
|
-
l || (l = new y.Float32BufferAttribute(d.count * 3, 3),
|
|
4228
|
+
const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], h = o.morphAttributes.normal?.[a];
|
|
4229
|
+
l || (l = new y.Float32BufferAttribute(d.count * 3, 3), h && (c = new y.Float32BufferAttribute(d.count * 3, 3)));
|
|
4230
4230
|
for (let g = 0; g < d.count; g++) {
|
|
4231
|
-
const
|
|
4232
|
-
l.setXYZ(g,
|
|
4231
|
+
const b = l.getX(g) + d.getX(g) * u, f = l.getY(g) + d.getY(g) * u, w = l.getZ(g) + d.getZ(g) * u;
|
|
4232
|
+
l.setXYZ(g, b, f, w);
|
|
4233
4233
|
}
|
|
4234
|
-
if (
|
|
4234
|
+
if (h)
|
|
4235
4235
|
for (let g = 0; g < d.count; g++) {
|
|
4236
|
-
const
|
|
4237
|
-
|
|
4236
|
+
const b = c.getX(g) + h.getX(g) * u, f = c.getY(g) + h.getY(g) * u, w = c.getZ(g) + h.getZ(g) * u;
|
|
4237
|
+
c.setXYZ(g, b, f, w);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (l) {
|
|
4241
|
-
o.morphAttributes.position.push(l),
|
|
4241
|
+
o.morphAttributes.position.push(l), c && o.morphAttributes.normal.push(c);
|
|
4242
4242
|
const r = o.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
|
|
4244
4244
|
}
|
|
@@ -4252,9 +4252,9 @@ class Be {
|
|
|
4252
4252
|
async showAvatar(t, e = null) {
|
|
4253
4253
|
if (!t || !t.hasOwnProperty("url"))
|
|
4254
4254
|
throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
|
|
4255
|
-
const n = new
|
|
4255
|
+
const n = new Qe();
|
|
4256
4256
|
if (this.dracoEnabled) {
|
|
4257
|
-
const r = new
|
|
4257
|
+
const r = new qe();
|
|
4258
4258
|
r.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(r);
|
|
4259
4259
|
}
|
|
4260
4260
|
let i = await n.loadAsync(t.url, e);
|
|
@@ -4314,8 +4314,8 @@ class Be {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + r);
|
|
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 c = new y.Vector3();
|
|
4318
|
+
this.objectLeftEye.getWorldPosition(c), this.avatarHeight = c.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), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4319
4319
|
}
|
|
4320
4320
|
/**
|
|
4321
4321
|
* Get view names.
|
|
@@ -4343,8 +4343,8 @@ class Be {
|
|
|
4343
4343
|
return;
|
|
4344
4344
|
}
|
|
4345
4345
|
if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4346
|
-
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let r = -n * Math.tan(
|
|
4346
|
+
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, c = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let r = -n * Math.tan(c / 2), u = (1 - i) * Math.tan(c / 2), a = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
4350
|
a += 2, u = u * a + 4 * this.avatarHeight / 5;
|
|
@@ -4418,16 +4418,16 @@ class Be {
|
|
|
4418
4418
|
if (!this.armature) return;
|
|
4419
4419
|
const t = this.armature.getObjectByName("LeftShoulder"), e = this.armature.getObjectByName("RightShoulder");
|
|
4420
4420
|
if (!t || !e) return;
|
|
4421
|
-
const n = new y.Euler(), i = new y.Quaternion(),
|
|
4421
|
+
const n = new y.Euler(), i = new y.Quaternion(), s = 0.6, o = 0.7;
|
|
4422
4422
|
if (t.quaternion) {
|
|
4423
4423
|
n.setFromQuaternion(t.quaternion, "XYZ");
|
|
4424
|
-
const
|
|
4425
|
-
n.x >
|
|
4424
|
+
const l = n.x;
|
|
4425
|
+
n.x > o ? n.x = s : n.x > s && (n.x = s + (n.x - s) * 0.2), Math.abs(n.x - l) > 0.01 && (i.setFromEuler(n, "XYZ"), t.quaternion.copy(i), t.updateMatrixWorld(!0));
|
|
4426
4426
|
}
|
|
4427
4427
|
if (e.quaternion) {
|
|
4428
4428
|
n.setFromQuaternion(e.quaternion, "XYZ");
|
|
4429
|
-
const
|
|
4430
|
-
n.x >
|
|
4429
|
+
const l = n.x;
|
|
4430
|
+
n.x > o ? n.x = s : n.x > s && (n.x = s + (n.x - s) * 0.2), Math.abs(n.x - l) > 0.01 && (i.setFromEuler(n, "XYZ"), e.quaternion.copy(i), e.updateMatrixWorld(!0));
|
|
4431
4431
|
}
|
|
4432
4432
|
}
|
|
4433
4433
|
/**
|
|
@@ -4436,9 +4436,9 @@ class Be {
|
|
|
4436
4436
|
updatePoseDelta() {
|
|
4437
4437
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
4438
4438
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4439
|
-
|
|
4439
|
+
Q.set(e.x, e.y, e.z);
|
|
4440
4440
|
const n = this.poseAvatar.props[t];
|
|
4441
|
-
n.isQuaternion ? (
|
|
4441
|
+
n.isQuaternion ? (te.setFromEuler(Q), n.multiply(te)) : n.isVector3 && n.add(Q);
|
|
4442
4442
|
}
|
|
4443
4443
|
}
|
|
4444
4444
|
/**
|
|
@@ -4498,8 +4498,8 @@ class Be {
|
|
|
4498
4498
|
});
|
|
4499
4499
|
break;
|
|
4500
4500
|
case "chestInhale":
|
|
4501
|
-
const l = n.applied / 20,
|
|
4502
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4501
|
+
const l = n.applied / 20, c = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
|
|
4502
|
+
this.poseDelta.props["Spine1.scale"] = c, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
|
|
4503
4503
|
break;
|
|
4504
4504
|
default:
|
|
4505
4505
|
for (let u = 0, a = n.ms.length; u < a; u++)
|
|
@@ -4518,8 +4518,8 @@ class Be {
|
|
|
4518
4518
|
return Object.entries(t).forEach((i, s) => {
|
|
4519
4519
|
const o = i[0].split(".");
|
|
4520
4520
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4521
|
-
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0],
|
|
4522
|
-
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(
|
|
4521
|
+
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], c = i[1].isQuaternion ? new y.Euler().setFromQuaternion(i[1]) : i[1];
|
|
4522
|
+
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(c.x * e) / e, n += ", y:" + Math.round(c.y * e) / e, n += ", z:" + Math.round(c.z * e) / e, n += "}";
|
|
4523
4523
|
}
|
|
4524
4524
|
}), n += "}", n;
|
|
4525
4525
|
}
|
|
@@ -4589,8 +4589,8 @@ class Be {
|
|
|
4589
4589
|
if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4590
4590
|
this.setPoseFromTemplate(t, e);
|
|
4591
4591
|
}, o)) : this.poseCurrentTemplate = t || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, o), this.poseWeightOnLeft = !0, (!i && !s || i && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
|
|
4592
|
-
for (let [l,
|
|
4593
|
-
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(
|
|
4592
|
+
for (let [l, c] of Object.entries(this.gesture))
|
|
4593
|
+
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(c), this.poseTarget.props[l].t = c.t, this.poseTarget.props[l].d = c.d);
|
|
4594
4594
|
Object.keys(this.poseDelta.props).forEach((l) => {
|
|
4595
4595
|
this.poseTarget.props.hasOwnProperty(l) || (this.poseTarget.props[l] = this.poseBase.props[l].clone(), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = o);
|
|
4596
4596
|
});
|
|
@@ -5026,8 +5026,8 @@ class Be {
|
|
|
5026
5026
|
const u = Math.random();
|
|
5027
5027
|
let a = 0;
|
|
5028
5028
|
for (let d = 0; d < l.alt.length; d++) {
|
|
5029
|
-
let
|
|
5030
|
-
if (a +=
|
|
5029
|
+
let h = this.valueFn(l.alt[d].p);
|
|
5030
|
+
if (a += h === void 0 ? (1 - a) / (l.alt.length - 1 - d) : h, u < a) {
|
|
5031
5031
|
r = l.alt[d];
|
|
5032
5032
|
break;
|
|
5033
5033
|
}
|
|
@@ -5037,8 +5037,8 @@ class Be {
|
|
|
5037
5037
|
continue;
|
|
5038
5038
|
} else
|
|
5039
5039
|
break;
|
|
5040
|
-
let
|
|
5041
|
-
if (Array.isArray(
|
|
5040
|
+
let c = this.valueFn(l.delay) || 0;
|
|
5041
|
+
if (Array.isArray(c) && (c = this.gaussianRandom(...c)), l.hasOwnProperty("dt"))
|
|
5042
5042
|
l.dt.forEach((r, u) => {
|
|
5043
5043
|
let a = this.valueFn(r);
|
|
5044
5044
|
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[u + 1] = o.ts[u] + a;
|
|
@@ -5047,10 +5047,10 @@ class Be {
|
|
|
5047
5047
|
let r = Object.values(l.vs).reduce((u, a) => a.length > u ? a.length : u, 0);
|
|
5048
5048
|
o.ts = Array(r + 1).fill(0);
|
|
5049
5049
|
}
|
|
5050
|
-
s ? o.ts = o.ts.map((r) =>
|
|
5050
|
+
s ? o.ts = o.ts.map((r) => c + r * n) : o.ts = o.ts.map((r) => this.animClock + c + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
|
|
5051
5051
|
for (let [r, u] of Object.entries(l.vs)) {
|
|
5052
|
-
const a = this.getBaselineValue(r), d = u.map((
|
|
5053
|
-
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((
|
|
5052
|
+
const a = this.getBaselineValue(r), d = u.map((h) => (h = this.valueFn(h), h === null ? null : typeof h == "function" ? h : typeof h == "string" || h instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (h === "hip" || h === "side") ? (console.log("Intercepting pose", h, "in animation factory, overriding to wide for male avatar"), "wide") : h.slice() : Array.isArray(h) ? r === "gesture" ? h.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...h) : typeof h == "boolean" ? h : h instanceof Object && h.constructor === Object ? Object.assign({}, h) : (a === void 0 ? 0 : a) + i * h));
|
|
5053
|
+
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((h) => h > 0 ? h : 0)], o.vs.eyeLookInLeft = [null, ...d.map((h) => h > 0 ? 0 : -h)], o.vs.eyeLookOutRight = [null, ...d.map((h) => h > 0 ? 0 : -h)], o.vs.eyeLookInRight = [null, ...d.map((h) => h > 0 ? h : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...d.map((h) => h > 0 ? h : 0)], o.vs.eyesLookUp = [null, ...d.map((h) => h > 0 ? 0 : -h)]) : o.vs[r] = [null, ...d];
|
|
5054
5054
|
}
|
|
5055
5055
|
for (let r of Object.keys(o.vs))
|
|
5056
5056
|
for (; o.vs[r].length <= o.ts.length; ) o.vs[r].push(o.vs[r][o.vs[r].length - 1]);
|
|
@@ -5131,23 +5131,23 @@ class Be {
|
|
|
5131
5131
|
if (this.isSpeaking)
|
|
5132
5132
|
for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5133
5133
|
this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
|
|
5134
|
-
let
|
|
5134
|
+
let c = null, r = null;
|
|
5135
5135
|
const u = [];
|
|
5136
5136
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5137
5137
|
const a = this.animQueue[n];
|
|
5138
5138
|
if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
|
|
5139
5139
|
for (i = a.ndx || 0, o = a.ts.length; i < o && !(this.animClock < a.ts[i]); i++)
|
|
5140
|
-
for (let [d,
|
|
5140
|
+
for (let [d, h] of Object.entries(a.vs))
|
|
5141
5141
|
if (this.mtAvatar.hasOwnProperty(d)) {
|
|
5142
|
-
if (
|
|
5142
|
+
if (h[i + 1] === null) continue;
|
|
5143
5143
|
const g = this.mtAvatar[d];
|
|
5144
|
-
if (
|
|
5145
|
-
g.newvalue =
|
|
5144
|
+
if (h[i] === null && (h[i] = g.value), i === o - 1)
|
|
5145
|
+
g.newvalue = h[i];
|
|
5146
5146
|
else {
|
|
5147
|
-
g.newvalue =
|
|
5148
|
-
const
|
|
5147
|
+
g.newvalue = h[i + 1];
|
|
5148
|
+
const b = a.ts[i + 1] - a.ts[i];
|
|
5149
5149
|
let f = 1;
|
|
5150
|
-
|
|
5150
|
+
b > 1e-4 && (f = (this.animClock - a.ts[i]) / b), f < 1 && (g.easing && (f = g.easing(f)), g.newvalue = (1 - f) * h[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
|
|
5151
5151
|
}
|
|
5152
5152
|
if (l)
|
|
5153
5153
|
switch (d) {
|
|
@@ -5159,7 +5159,7 @@ class Be {
|
|
|
5159
5159
|
g.newvalue *= 1 + l / 255 - 0.5;
|
|
5160
5160
|
}
|
|
5161
5161
|
g.needsUpdate = !0;
|
|
5162
|
-
} else d === "eyeContact" &&
|
|
5162
|
+
} else d === "eyeContact" && h[i] !== null && c !== !1 ? c = !!h[i] : d === "headMove" && h[i] !== null && r !== !1 ? h[i] === 0 ? r = !1 : (Math.random() < h[i] && (r = !0), h[i] = null) : h[i] !== null && (u.push({ mt: d, val: h[i] }), h[i] = null);
|
|
5163
5163
|
i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
|
|
5164
5164
|
}
|
|
5165
5165
|
}
|
|
@@ -5181,8 +5181,8 @@ class Be {
|
|
|
5181
5181
|
i && typeof i == "function" && i();
|
|
5182
5182
|
break;
|
|
5183
5183
|
case "moveto":
|
|
5184
|
-
Object.entries(i.props).forEach((
|
|
5185
|
-
|
|
5184
|
+
Object.entries(i.props).forEach((h) => {
|
|
5185
|
+
h[1] ? this.poseTarget.props[h[0]].copy(h[1]) : this.poseTarget.props[h[0]].copy(this.getPoseTemplateProp(h[0])), this.poseTarget.props[h[0]].t = this.animClock, this.poseTarget.props[h[0]].d = h[1] && h[1].d ? h[1].d : h.duration || 2e3;
|
|
5186
5186
|
});
|
|
5187
5187
|
break;
|
|
5188
5188
|
case "handLeft":
|
|
@@ -5210,7 +5210,7 @@ class Be {
|
|
|
5210
5210
|
}, i.x ? new y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5211
5211
|
break;
|
|
5212
5212
|
}
|
|
5213
|
-
if ((
|
|
5213
|
+
if ((c || r) && (Q.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Q.x = Math.max(-0.9, Math.min(0.9, 2 * Q.x - 0.5)), Q.y = Math.max(-0.9, Math.min(0.9, -2.5 * Q.y)), c ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Q.x < 0 ? -Q.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Q.x < 0 ? 0 : Q.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Q.y < 0 ? -Q.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Q.y < 0 ? 0 : Q.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Q.y < 0 ? 0 : Q.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Q.y < 0 ? -Q.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5214
5214
|
name: "headmove",
|
|
5215
5215
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5216
5216
|
vs: {
|
|
@@ -5231,7 +5231,7 @@ class Be {
|
|
|
5231
5231
|
eyeLookOutRight: [null, 0],
|
|
5232
5232
|
eyeContact: [0]
|
|
5233
5233
|
}
|
|
5234
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), this.applyShoulderAdjustmentToBones(), (this.isSpeaking || this.isListening) &&
|
|
5234
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), this.applyShoulderAdjustmentToBones(), (this.isSpeaking || this.isListening) && c ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (te.setFromAxisAngle(pt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(te)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Ie), Ie.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (Re.x + Ie.x) / 4, this.objectHips.position.z -= (Re.z + Ie.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5235
5235
|
this.stats && this.stats.end();
|
|
5236
5236
|
else {
|
|
5237
5237
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5298,14 +5298,14 @@ class Be {
|
|
|
5298
5298
|
*/
|
|
5299
5299
|
speakText(t, e = null, n = null, i = null) {
|
|
5300
5300
|
e = e || {};
|
|
5301
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5302
|
-
let u = "", a = "", d = 0,
|
|
5303
|
-
const
|
|
5304
|
-
for (let f = 0; f <
|
|
5305
|
-
const
|
|
5306
|
-
let p =
|
|
5307
|
-
const B =
|
|
5308
|
-
if (p && !
|
|
5301
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, c = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5302
|
+
let u = "", a = "", d = 0, h = [], g = [];
|
|
5303
|
+
const b = Array.from(this.segmenter.segment(t), (f) => f.segment);
|
|
5304
|
+
for (let f = 0; f < b.length; f++) {
|
|
5305
|
+
const w = f === b.length - 1, N = b[f].match(l);
|
|
5306
|
+
let p = b[f].match(s);
|
|
5307
|
+
const B = b[f].match(c), F = b[f].match(o);
|
|
5308
|
+
if (p && !w && !B && b[f + 1].match(s) && (p = !1), n && (u += b[f]), N && (!i || i.every((I) => f < I[0] || f > I[1])) && (a += b[f]), (F || p || w) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && h.push({
|
|
5309
5309
|
mark: d,
|
|
5310
5310
|
word: a
|
|
5311
5311
|
})), u.length && (g.push({
|
|
@@ -5316,31 +5316,31 @@ class Be {
|
|
|
5316
5316
|
subtitles: [u]
|
|
5317
5317
|
}
|
|
5318
5318
|
}), u = ""), a.length)) {
|
|
5319
|
-
const
|
|
5320
|
-
if (
|
|
5321
|
-
const
|
|
5322
|
-
for (let
|
|
5319
|
+
const I = this.lipsyncWordsToVisemes(a, r);
|
|
5320
|
+
if (I && I.visemes && I.visemes.length) {
|
|
5321
|
+
const D = I.times[I.visemes.length - 1] + I.durations[I.visemes.length - 1];
|
|
5322
|
+
for (let x = 0; x < I.visemes.length; x++)
|
|
5323
5323
|
g.push({
|
|
5324
5324
|
mark: d,
|
|
5325
5325
|
template: { name: "viseme" },
|
|
5326
|
-
ts: [(
|
|
5326
|
+
ts: [(I.times[x] - 0.6) / D, (I.times[x] + 0.5) / D, (I.times[x] + I.durations[x] + 0.5) / D],
|
|
5327
5327
|
vs: {
|
|
5328
|
-
["viseme_" +
|
|
5328
|
+
["viseme_" + I.visemes[x]]: [null, I.visemes[x] === "PP" || I.visemes[x] === "FF" ? 0.9 : 0.6, 0]
|
|
5329
5329
|
}
|
|
5330
5330
|
});
|
|
5331
5331
|
}
|
|
5332
5332
|
a = "", d++;
|
|
5333
5333
|
}
|
|
5334
|
-
if (p ||
|
|
5335
|
-
if (
|
|
5336
|
-
const
|
|
5334
|
+
if (p || w) {
|
|
5335
|
+
if (h.length || w && g.length) {
|
|
5336
|
+
const I = {
|
|
5337
5337
|
anim: g
|
|
5338
5338
|
};
|
|
5339
|
-
n && (
|
|
5339
|
+
n && (I.onSubtitles = n), h.length && !e.avatarMute && (I.text = h, e.avatarMood && (I.mood = e.avatarMood), e.ttsLang && (I.lang = e.ttsLang), e.ttsVoice && (I.voice = e.ttsVoice), e.ttsRate && (I.rate = e.ttsRate), e.ttsVoice && (I.pitch = e.ttsPitch), e.ttsVolume && (I.volume = e.ttsVolume)), this.speechQueue.push(I), h = [], a = "", d = 0, g = [];
|
|
5340
5340
|
}
|
|
5341
5341
|
if (B) {
|
|
5342
|
-
let
|
|
5343
|
-
|
|
5342
|
+
let I = this.animEmojis[b[f]];
|
|
5343
|
+
I && I.link && (I = this.animEmojis[I.link]), I && this.speechQueue.push({ emoji: I });
|
|
5344
5344
|
}
|
|
5345
5345
|
this.speechQueue.push({ break: 100 });
|
|
5346
5346
|
}
|
|
@@ -5421,27 +5421,27 @@ class Be {
|
|
|
5421
5421
|
if (t.words) {
|
|
5422
5422
|
let o = [];
|
|
5423
5423
|
for (let l = 0; l < t.words.length; l++) {
|
|
5424
|
-
const
|
|
5424
|
+
const c = t.words[l], r = t.wtimes[l];
|
|
5425
5425
|
let u = t.wdurations[l];
|
|
5426
|
-
if (
|
|
5426
|
+
if (c.length && (n && o.push({
|
|
5427
5427
|
template: { name: "subtitles" },
|
|
5428
5428
|
ts: [r],
|
|
5429
5429
|
vs: {
|
|
5430
|
-
subtitles: [" " +
|
|
5430
|
+
subtitles: [" " + c]
|
|
5431
5431
|
}
|
|
5432
5432
|
}), !t.visemes)) {
|
|
5433
|
-
const a = this.lipsyncPreProcessText(
|
|
5433
|
+
const a = this.lipsyncPreProcessText(c, i), d = this.lipsyncWordsToVisemes(a, i);
|
|
5434
5434
|
if (d && d.visemes && d.visemes.length) {
|
|
5435
|
-
const
|
|
5436
|
-
let
|
|
5437
|
-
if (u = Math.min(u, d.visemes.length * 200),
|
|
5435
|
+
const h = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], g = Math.min(u, Math.max(0, u - d.visemes.length * 150));
|
|
5436
|
+
let b = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5437
|
+
if (u = Math.min(u, d.visemes.length * 200), h > 0)
|
|
5438
5438
|
for (let f = 0; f < d.visemes.length; f++) {
|
|
5439
|
-
const
|
|
5439
|
+
const w = r + d.times[f] / h * u, N = d.durations[f] / h * u;
|
|
5440
5440
|
o.push({
|
|
5441
5441
|
template: { name: "viseme" },
|
|
5442
|
-
ts: [
|
|
5442
|
+
ts: [w - Math.min(60, 2 * N / 3), w + Math.min(25, N / 2), w + N + Math.min(60, N / 2)],
|
|
5443
5443
|
vs: {
|
|
5444
|
-
["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 :
|
|
5444
|
+
["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : b, 0]
|
|
5445
5445
|
}
|
|
5446
5446
|
});
|
|
5447
5447
|
}
|
|
@@ -5450,22 +5450,22 @@ class Be {
|
|
|
5450
5450
|
}
|
|
5451
5451
|
if (t.visemes)
|
|
5452
5452
|
for (let l = 0; l < t.visemes.length; l++) {
|
|
5453
|
-
const
|
|
5453
|
+
const c = t.visemes[l], r = t.vtimes[l], u = t.vdurations[l];
|
|
5454
5454
|
o.push({
|
|
5455
5455
|
template: { name: "viseme" },
|
|
5456
5456
|
ts: [r - 2 * u / 3, r + u / 2, r + u + u / 2],
|
|
5457
5457
|
vs: {
|
|
5458
|
-
["viseme_" +
|
|
5458
|
+
["viseme_" + c]: [null, c === "PP" || c === "FF" ? 0.9 : 0.6, 0]
|
|
5459
5459
|
}
|
|
5460
5460
|
});
|
|
5461
5461
|
}
|
|
5462
5462
|
if (t.markers)
|
|
5463
5463
|
for (let l = 0; l < t.markers.length; l++) {
|
|
5464
|
-
const
|
|
5464
|
+
const c = t.markers[l], r = t.mtimes[l];
|
|
5465
5465
|
o.push({
|
|
5466
5466
|
template: { name: "markers" },
|
|
5467
5467
|
ts: [r],
|
|
5468
|
-
vs: { function: [
|
|
5468
|
+
vs: { function: [c] }
|
|
5469
5469
|
});
|
|
5470
5470
|
}
|
|
5471
5471
|
o.length && (s.anim = o);
|
|
@@ -5485,7 +5485,7 @@ class Be {
|
|
|
5485
5485
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5486
5486
|
const e = this.audioPlaylist.shift();
|
|
5487
5487
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5488
|
-
const s = this.audioCtx.resume(), o = new Promise((l,
|
|
5488
|
+
const s = this.audioCtx.resume(), o = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
|
|
5489
5489
|
try {
|
|
5490
5490
|
await Promise.race([s, o]);
|
|
5491
5491
|
} catch {
|
|
@@ -5517,38 +5517,38 @@ class Be {
|
|
|
5517
5517
|
*/
|
|
5518
5518
|
async synthesizeWithBrowserTTS(t) {
|
|
5519
5519
|
return new Promise((e, n) => {
|
|
5520
|
-
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5521
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2,
|
|
5520
|
+
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, c = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5521
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, c)), s.volume = Math.max(0, Math.min(1, r));
|
|
5522
5522
|
const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5523
5523
|
if (a && u.length > 0) {
|
|
5524
5524
|
const p = u.find((B) => B.name.includes(a) || B.lang === o);
|
|
5525
5525
|
p && (s.voice = p);
|
|
5526
5526
|
}
|
|
5527
|
-
const d = i.length * 100 / s.rate,
|
|
5527
|
+
const d = i.length * 100 / s.rate, h = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", b = this.lipsyncPreProcessText(i, g), f = this.lipsyncWordsToVisemes(b, g);
|
|
5528
5528
|
console.log("Browser TTS Lip-sync Debug:", {
|
|
5529
5529
|
text: i,
|
|
5530
5530
|
lipsyncLang: g,
|
|
5531
|
-
processedText:
|
|
5531
|
+
processedText: b,
|
|
5532
5532
|
lipsyncData: f,
|
|
5533
5533
|
hasVisemes: f && f.visemes && f.visemes.length > 0,
|
|
5534
5534
|
estimatedDuration: d
|
|
5535
5535
|
});
|
|
5536
|
-
const
|
|
5536
|
+
const w = [];
|
|
5537
5537
|
if (f && f.visemes && f.visemes.length > 0) {
|
|
5538
5538
|
const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5539
5539
|
for (let B = 0; B < f.visemes.length; B++) {
|
|
5540
|
-
const
|
|
5541
|
-
|
|
5540
|
+
const F = f.visemes[B], I = f.times[B] / p, D = f.durations[B] / p, x = I * d, k = D * d;
|
|
5541
|
+
w.push({
|
|
5542
5542
|
template: { name: "viseme" },
|
|
5543
|
-
ts: [
|
|
5543
|
+
ts: [x - Math.min(60, 2 * k / 3), x + Math.min(25, k / 2), x + k + Math.min(60, k / 2)],
|
|
5544
5544
|
vs: {
|
|
5545
|
-
["viseme_" +
|
|
5545
|
+
["viseme_" + F]: [null, F === "PP" || F === "FF" ? 0.9 : 0.6, 0]
|
|
5546
5546
|
}
|
|
5547
5547
|
});
|
|
5548
5548
|
}
|
|
5549
5549
|
}
|
|
5550
|
-
const
|
|
5551
|
-
this.audioPlaylist.push({ anim:
|
|
5550
|
+
const N = [...t.anim, ...w];
|
|
5551
|
+
this.audioPlaylist.push({ anim: N, audio: h }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5552
5552
|
e();
|
|
5553
5553
|
}, s.onerror = (p) => {
|
|
5554
5554
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -5582,26 +5582,26 @@ class Be {
|
|
|
5582
5582
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5583
5583
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5584
5584
|
console.log("Using text-based lip-sync for debugging...");
|
|
5585
|
-
const
|
|
5585
|
+
const c = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5586
5586
|
let r;
|
|
5587
5587
|
try {
|
|
5588
5588
|
console.log("Lip-sync modules available:", {
|
|
5589
5589
|
hasLipsync: !!this.lipsync,
|
|
5590
5590
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5591
|
-
lipsyncLang:
|
|
5591
|
+
lipsyncLang: c
|
|
5592
5592
|
});
|
|
5593
|
-
const d = this.lipsyncPreProcessText(e,
|
|
5593
|
+
const d = this.lipsyncPreProcessText(e, c), h = this.lipsyncWordsToVisemes(d, c);
|
|
5594
5594
|
if (console.log("Lip-sync data:", {
|
|
5595
5595
|
processedText: d,
|
|
5596
|
-
lipsyncData:
|
|
5597
|
-
hasVisemes:
|
|
5598
|
-
}),
|
|
5596
|
+
lipsyncData: h,
|
|
5597
|
+
hasVisemes: h && h.visemes && h.visemes.length > 0
|
|
5598
|
+
}), h && h.visemes && h.visemes.length > 0)
|
|
5599
5599
|
r = {
|
|
5600
|
-
visemes:
|
|
5600
|
+
visemes: h.visemes.map((g, b) => ({
|
|
5601
5601
|
viseme: g,
|
|
5602
|
-
startTime:
|
|
5603
|
-
endTime: (
|
|
5604
|
-
duration: l.duration /
|
|
5602
|
+
startTime: b * l.duration / h.visemes.length,
|
|
5603
|
+
endTime: (b + 1) * l.duration / h.visemes.length,
|
|
5604
|
+
duration: l.duration / h.visemes.length,
|
|
5605
5605
|
intensity: 0.7
|
|
5606
5606
|
})),
|
|
5607
5607
|
words: [],
|
|
@@ -5612,15 +5612,15 @@ class Be {
|
|
|
5612
5612
|
throw new Error("No visemes generated from text");
|
|
5613
5613
|
} catch (d) {
|
|
5614
5614
|
console.error("Text-based lip-sync failed, using fallback:", d);
|
|
5615
|
-
const
|
|
5616
|
-
for (const
|
|
5617
|
-
for (const f of
|
|
5618
|
-
let
|
|
5619
|
-
"aeiou".includes(f) ?
|
|
5615
|
+
const h = e.toLowerCase().split(/\s+/), g = [];
|
|
5616
|
+
for (const b of h)
|
|
5617
|
+
for (const f of b) {
|
|
5618
|
+
let w = "aa";
|
|
5619
|
+
"aeiou".includes(f) ? w = "aa" : "bp".includes(f) ? w = "PP" : "fv".includes(f) ? w = "FF" : "st".includes(f) ? w = "SS" : "dln".includes(f) ? w = "DD" : "kg".includes(f) ? w = "kk" : "rw".includes(f) && (w = "RR"), g.push(w);
|
|
5620
5620
|
}
|
|
5621
5621
|
r = {
|
|
5622
|
-
visemes: g.map((
|
|
5623
|
-
viseme:
|
|
5622
|
+
visemes: g.map((b, f) => ({
|
|
5623
|
+
viseme: b,
|
|
5624
5624
|
startTime: f * l.duration / g.length,
|
|
5625
5625
|
endTime: (f + 1) * l.duration / g.length,
|
|
5626
5626
|
duration: l.duration / g.length,
|
|
@@ -5647,12 +5647,12 @@ class Be {
|
|
|
5647
5647
|
if (r.visemes && r.visemes.length > 0) {
|
|
5648
5648
|
console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5649
5649
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
5650
|
-
const
|
|
5650
|
+
const h = r.visemes[d], g = h.startTime * 1e3, b = h.duration * 1e3, f = h.intensity;
|
|
5651
5651
|
u.push({
|
|
5652
5652
|
template: { name: "viseme" },
|
|
5653
|
-
ts: [g - Math.min(60, 2 *
|
|
5653
|
+
ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
|
|
5654
5654
|
vs: {
|
|
5655
|
-
["viseme_" +
|
|
5655
|
+
["viseme_" + h.viseme]: [null, f, 0]
|
|
5656
5656
|
}
|
|
5657
5657
|
});
|
|
5658
5658
|
}
|
|
@@ -5680,26 +5680,26 @@ class Be {
|
|
|
5680
5680
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5681
5681
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5682
5682
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5683
|
-
const
|
|
5683
|
+
const c = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5684
5684
|
let r;
|
|
5685
5685
|
try {
|
|
5686
5686
|
console.log("Lip-sync modules available:", {
|
|
5687
5687
|
hasLipsync: !!this.lipsync,
|
|
5688
5688
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5689
|
-
lipsyncLang:
|
|
5689
|
+
lipsyncLang: c
|
|
5690
5690
|
});
|
|
5691
|
-
const d = this.lipsyncPreProcessText(e,
|
|
5691
|
+
const d = this.lipsyncPreProcessText(e, c), h = this.lipsyncWordsToVisemes(d, c);
|
|
5692
5692
|
if (console.log("Lip-sync data:", {
|
|
5693
5693
|
processedText: d,
|
|
5694
|
-
lipsyncData:
|
|
5695
|
-
hasVisemes:
|
|
5696
|
-
}),
|
|
5694
|
+
lipsyncData: h,
|
|
5695
|
+
hasVisemes: h && h.visemes && h.visemes.length > 0
|
|
5696
|
+
}), h && h.visemes && h.visemes.length > 0)
|
|
5697
5697
|
r = {
|
|
5698
|
-
visemes:
|
|
5698
|
+
visemes: h.visemes.map((g, b) => ({
|
|
5699
5699
|
viseme: g,
|
|
5700
|
-
startTime:
|
|
5701
|
-
endTime: (
|
|
5702
|
-
duration: l.duration /
|
|
5700
|
+
startTime: b * l.duration / h.visemes.length,
|
|
5701
|
+
endTime: (b + 1) * l.duration / h.visemes.length,
|
|
5702
|
+
duration: l.duration / h.visemes.length,
|
|
5703
5703
|
intensity: 0.7
|
|
5704
5704
|
})),
|
|
5705
5705
|
words: [],
|
|
@@ -5710,15 +5710,15 @@ class Be {
|
|
|
5710
5710
|
throw new Error("No visemes generated from text");
|
|
5711
5711
|
} catch (d) {
|
|
5712
5712
|
console.error("Text-based lip-sync failed, using fallback:", d);
|
|
5713
|
-
const
|
|
5714
|
-
for (const
|
|
5715
|
-
for (const f of
|
|
5716
|
-
let
|
|
5717
|
-
"aeiou".includes(f) ?
|
|
5713
|
+
const h = e.toLowerCase().split(/\s+/), g = [];
|
|
5714
|
+
for (const b of h)
|
|
5715
|
+
for (const f of b) {
|
|
5716
|
+
let w = "aa";
|
|
5717
|
+
"aeiou".includes(f) ? w = "aa" : "bp".includes(f) ? w = "PP" : "fv".includes(f) ? w = "FF" : "st".includes(f) ? w = "SS" : "dln".includes(f) ? w = "DD" : "kg".includes(f) ? w = "kk" : "rw".includes(f) && (w = "RR"), g.push(w);
|
|
5718
5718
|
}
|
|
5719
5719
|
r = {
|
|
5720
|
-
visemes: g.map((
|
|
5721
|
-
viseme:
|
|
5720
|
+
visemes: g.map((b, f) => ({
|
|
5721
|
+
viseme: b,
|
|
5722
5722
|
startTime: f * l.duration / g.length,
|
|
5723
5723
|
endTime: (f + 1) * l.duration / g.length,
|
|
5724
5724
|
duration: l.duration / g.length,
|
|
@@ -5745,12 +5745,12 @@ class Be {
|
|
|
5745
5745
|
if (r.visemes && r.visemes.length > 0) {
|
|
5746
5746
|
console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5747
5747
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
5748
|
-
const
|
|
5748
|
+
const h = r.visemes[d], g = h.startTime * 1e3, b = h.duration * 1e3, f = h.intensity;
|
|
5749
5749
|
u.push({
|
|
5750
5750
|
template: { name: "viseme" },
|
|
5751
|
-
ts: [g - Math.min(60, 2 *
|
|
5751
|
+
ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
|
|
5752
5752
|
vs: {
|
|
5753
|
-
["viseme_" +
|
|
5753
|
+
["viseme_" + h.viseme]: [null, f, 0]
|
|
5754
5754
|
}
|
|
5755
5755
|
});
|
|
5756
5756
|
}
|
|
@@ -5784,25 +5784,25 @@ class Be {
|
|
|
5784
5784
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5785
5785
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5786
5786
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5787
|
-
const
|
|
5787
|
+
const c = await this.audioAnalyzer.analyzeAudio(l, e);
|
|
5788
5788
|
console.log("Azure TTS Audio Analysis:", {
|
|
5789
5789
|
text: e,
|
|
5790
5790
|
audioDuration: l.duration,
|
|
5791
|
-
visemeCount:
|
|
5792
|
-
wordCount:
|
|
5791
|
+
visemeCount: c.visemes.length,
|
|
5792
|
+
wordCount: c.words.length,
|
|
5793
5793
|
features: {
|
|
5794
|
-
onsets:
|
|
5795
|
-
boundaries:
|
|
5794
|
+
onsets: c.features.onsets.length,
|
|
5795
|
+
boundaries: c.features.phonemeBoundaries.length
|
|
5796
5796
|
}
|
|
5797
5797
|
});
|
|
5798
5798
|
const r = [];
|
|
5799
|
-
for (let a = 0; a <
|
|
5800
|
-
const d =
|
|
5799
|
+
for (let a = 0; a < c.visemes.length; a++) {
|
|
5800
|
+
const d = c.visemes[a], h = d.startTime * 1e3, g = d.duration * 1e3, b = d.intensity;
|
|
5801
5801
|
r.push({
|
|
5802
5802
|
template: { name: "viseme" },
|
|
5803
|
-
ts: [
|
|
5803
|
+
ts: [h - Math.min(60, 2 * g / 3), h + Math.min(25, g / 2), h + g + Math.min(60, g / 2)],
|
|
5804
5804
|
vs: {
|
|
5805
|
-
["viseme_" + d.viseme]: [null,
|
|
5805
|
+
["viseme_" + d.viseme]: [null, b, 0]
|
|
5806
5806
|
}
|
|
5807
5807
|
});
|
|
5808
5808
|
}
|
|
@@ -5846,27 +5846,27 @@ class Be {
|
|
|
5846
5846
|
if (i.status === 200 && s && s.audioContent) {
|
|
5847
5847
|
const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
|
|
5848
5848
|
this.speakWithHands();
|
|
5849
|
-
const
|
|
5849
|
+
const c = [0];
|
|
5850
5850
|
let r = 0;
|
|
5851
|
-
t.text.forEach((d,
|
|
5852
|
-
if (
|
|
5853
|
-
let g =
|
|
5854
|
-
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + d.mark && r++),
|
|
5851
|
+
t.text.forEach((d, h) => {
|
|
5852
|
+
if (h > 0) {
|
|
5853
|
+
let g = c[c.length - 1];
|
|
5854
|
+
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + d.mark && r++), c.push(g);
|
|
5855
5855
|
}
|
|
5856
5856
|
});
|
|
5857
5857
|
const u = [{ mark: 0, time: 0 }];
|
|
5858
|
-
|
|
5859
|
-
if (
|
|
5860
|
-
let g = d - h
|
|
5861
|
-
u[
|
|
5858
|
+
c.forEach((d, h) => {
|
|
5859
|
+
if (h > 0) {
|
|
5860
|
+
let g = d - c[h - 1];
|
|
5861
|
+
u[h - 1].duration = g, u.push({ mark: h, time: d });
|
|
5862
5862
|
}
|
|
5863
5863
|
});
|
|
5864
5864
|
let a = 1e3 * l.duration;
|
|
5865
5865
|
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((d) => {
|
|
5866
|
-
const
|
|
5867
|
-
if (
|
|
5866
|
+
const h = u[d.mark];
|
|
5867
|
+
if (h)
|
|
5868
5868
|
for (let g = 0; g < d.ts.length; g++)
|
|
5869
|
-
d.ts[g] =
|
|
5869
|
+
d.ts[g] = h.time + d.ts[g] * h.duration + this.opt.ttsTrimStart;
|
|
5870
5870
|
}), this.audioPlaylist.push({ anim: t.anim, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5871
5871
|
} else
|
|
5872
5872
|
this.startSpeaking(!0);
|
|
@@ -5946,10 +5946,10 @@ class Be {
|
|
|
5946
5946
|
}
|
|
5947
5947
|
if (!this.workletLoaded)
|
|
5948
5948
|
try {
|
|
5949
|
-
const l = this.audioCtx.audioWorklet.addModule(
|
|
5949
|
+
const l = this.audioCtx.audioWorklet.addModule(mt.href), c = new Promise(
|
|
5950
5950
|
(r, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
|
|
5951
5951
|
);
|
|
5952
|
-
await Promise.race([l,
|
|
5952
|
+
await Promise.race([l, c]), this.workletLoaded = !0;
|
|
5953
5953
|
} catch (l) {
|
|
5954
5954
|
throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
|
|
5955
5955
|
}
|
|
@@ -5962,8 +5962,8 @@ class Be {
|
|
|
5962
5962
|
if (l.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5963
5963
|
try {
|
|
5964
5964
|
this.onAudioStart?.();
|
|
5965
|
-
} catch (
|
|
5966
|
-
console.error(
|
|
5965
|
+
} catch (c) {
|
|
5966
|
+
console.error(c);
|
|
5967
5967
|
}
|
|
5968
5968
|
if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5969
5969
|
try {
|
|
@@ -5983,9 +5983,9 @@ class Be {
|
|
|
5983
5983
|
} catch {
|
|
5984
5984
|
}
|
|
5985
5985
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5986
|
-
const l = this.audioCtx.resume(),
|
|
5986
|
+
const l = this.audioCtx.resume(), c = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
|
|
5987
5987
|
try {
|
|
5988
|
-
await Promise.race([l,
|
|
5988
|
+
await Promise.race([l, c]);
|
|
5989
5989
|
} catch {
|
|
5990
5990
|
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.");
|
|
5991
5991
|
return;
|
|
@@ -6082,18 +6082,18 @@ class Be {
|
|
|
6082
6082
|
subtitles: [" " + i]
|
|
6083
6083
|
}
|
|
6084
6084
|
}), this.streamLipsyncType == "words")) {
|
|
6085
|
-
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6085
|
+
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, c = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(c, l);
|
|
6086
6086
|
if (r && r.visemes && r.visemes.length) {
|
|
6087
6087
|
const u = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
|
|
6088
6088
|
let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
|
|
6089
6089
|
if (o = Math.min(o, r.visemes.length * 200), u > 0)
|
|
6090
|
-
for (let
|
|
6091
|
-
const g = e + s + r.times[
|
|
6090
|
+
for (let h = 0; h < r.visemes.length; h++) {
|
|
6091
|
+
const g = e + s + r.times[h] / u * o, b = r.durations[h] / u * o;
|
|
6092
6092
|
this.animQueue.push({
|
|
6093
6093
|
template: { name: "viseme" },
|
|
6094
|
-
ts: [g - Math.min(60, 2 *
|
|
6094
|
+
ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
|
|
6095
6095
|
vs: {
|
|
6096
|
-
["viseme_" + r.visemes[
|
|
6096
|
+
["viseme_" + r.visemes[h]]: [null, r.visemes[h] === "PP" || r.visemes[h] === "FF" ? 0.9 : d, 0]
|
|
6097
6097
|
}
|
|
6098
6098
|
});
|
|
6099
6099
|
}
|
|
@@ -6184,7 +6184,7 @@ class Be {
|
|
|
6184
6184
|
*/
|
|
6185
6185
|
lookAtCamera(t) {
|
|
6186
6186
|
let e;
|
|
6187
|
-
if (this.speakTo && (e = new y.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0),
|
|
6187
|
+
if (this.speakTo && (e = new y.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Re, Ie).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
|
|
6188
6188
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6189
6189
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6190
6190
|
this.lookAhead(t);
|
|
@@ -6197,22 +6197,22 @@ class Be {
|
|
|
6197
6197
|
this.lookAt(null, null, t);
|
|
6198
6198
|
return;
|
|
6199
6199
|
}
|
|
6200
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0),
|
|
6201
|
-
const n = new y.Vector3().subVectors(e,
|
|
6202
|
-
|
|
6203
|
-
const l = new y.Quaternion().setFromEuler(
|
|
6204
|
-
|
|
6205
|
-
let r =
|
|
6200
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.objectRightEye.matrixWorld), Re.add(Ie).divideScalar(2), te.copy(this.armature.quaternion), te.multiply(this.poseTarget.props["Hips.quaternion"]), te.multiply(this.poseTarget.props["Spine.quaternion"]), te.multiply(this.poseTarget.props["Spine1.quaternion"]), te.multiply(this.poseTarget.props["Spine2.quaternion"]), te.multiply(this.poseTarget.props["Neck.quaternion"]), te.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6201
|
+
const n = new y.Vector3().subVectors(e, Re).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6202
|
+
Q.set(s, i, 0, "YXZ");
|
|
6203
|
+
const l = new y.Quaternion().setFromEuler(Q), c = new y.Quaternion().copy(l).multiply(te.clone().invert());
|
|
6204
|
+
Q.setFromQuaternion(c, "YXZ");
|
|
6205
|
+
let r = Q.x / (40 / 24) + 0.2, u = Q.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), h = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (t) {
|
|
6207
|
-
let
|
|
6208
|
-
|
|
6207
|
+
let b = this.animQueue.findIndex((w) => w.template.name === "lookat");
|
|
6208
|
+
b !== -1 && this.animQueue.splice(b, 1);
|
|
6209
6209
|
const f = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, t],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [a +
|
|
6213
|
+
bodyRotateX: [a + h],
|
|
6214
6214
|
bodyRotateY: [d + g],
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6215
|
+
eyesRotateX: [-3 * h + 0.1],
|
|
6216
6216
|
eyesRotateY: [-5 * g],
|
|
6217
6217
|
browInnerUp: [[0, 0.7]],
|
|
6218
6218
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6236,21 +6236,21 @@ class Be {
|
|
|
6236
6236
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6237
6237
|
const s = new y.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new y.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new y.Vector3().addVectors(s, o).divideScalar(2);
|
|
6238
6238
|
l.project(this.camera);
|
|
6239
|
-
let
|
|
6240
|
-
t === null && (t =
|
|
6241
|
-
let u =
|
|
6242
|
-
f = Math.min(0.6, Math.max(-0.3, f)),
|
|
6243
|
-
let
|
|
6239
|
+
let c = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6240
|
+
t === null && (t = c), e === null && (e = r), te.copy(this.armature.quaternion), te.multiply(this.poseTarget.props["Hips.quaternion"]), te.multiply(this.poseTarget.props["Spine.quaternion"]), te.multiply(this.poseTarget.props["Spine1.quaternion"]), te.multiply(this.poseTarget.props["Spine2.quaternion"]), te.multiply(this.poseTarget.props["Neck.quaternion"]), te.multiply(this.poseTarget.props["Head.quaternion"]), Q.setFromQuaternion(te);
|
|
6241
|
+
let u = Q.x / (40 / 24), a = Q.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), h = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - c, c), b = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - b, r + b], [-0.3, 0.6]) - u + d, w = this.convertRange(t, [c - g, c + g], [-0.8, 0.8]) - a + h;
|
|
6242
|
+
f = Math.min(0.6, Math.max(-0.3, f)), w = Math.min(0.8, Math.max(-0.8, w));
|
|
6243
|
+
let N = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6244
6244
|
if (n) {
|
|
6245
|
-
let B = this.animQueue.findIndex((
|
|
6245
|
+
let B = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6246
6246
|
B !== -1 && this.animQueue.splice(B, 1);
|
|
6247
|
-
const
|
|
6247
|
+
const F = {
|
|
6248
6248
|
name: "lookat",
|
|
6249
6249
|
dt: [750, n],
|
|
6250
6250
|
vs: {
|
|
6251
|
-
bodyRotateX: [f +
|
|
6252
|
-
bodyRotateY: [
|
|
6253
|
-
eyesRotateX: [-3 *
|
|
6251
|
+
bodyRotateX: [f + N],
|
|
6252
|
+
bodyRotateY: [w + p],
|
|
6253
|
+
eyesRotateX: [-3 * N + 0.1],
|
|
6254
6254
|
eyesRotateY: [-5 * p],
|
|
6255
6255
|
browInnerUp: [[0, 0.7]],
|
|
6256
6256
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6259,7 +6259,7 @@ class Be {
|
|
|
6259
6259
|
headMove: [0]
|
|
6260
6260
|
}
|
|
6261
6261
|
};
|
|
6262
|
-
this.animQueue.push(this.animFactory(
|
|
6262
|
+
this.animQueue.push(this.animFactory(F));
|
|
6263
6263
|
}
|
|
6264
6264
|
}
|
|
6265
6265
|
/**
|
|
@@ -6277,9 +6277,9 @@ class Be {
|
|
|
6277
6277
|
s.setFromCamera(i, this.camera);
|
|
6278
6278
|
const o = s.intersectObject(this.armature);
|
|
6279
6279
|
if (o.length > 0) {
|
|
6280
|
-
const l = o[0].point,
|
|
6281
|
-
this.objectLeftArm.getWorldPosition(
|
|
6282
|
-
const u =
|
|
6280
|
+
const l = o[0].point, c = new y.Vector3(), r = new y.Vector3();
|
|
6281
|
+
this.objectLeftArm.getWorldPosition(c), this.objectRightArm.getWorldPosition(r);
|
|
6282
|
+
const u = c.distanceToSquared(l), a = r.distanceToSquared(l);
|
|
6283
6283
|
u < a ? (this.ikSolve({
|
|
6284
6284
|
iterations: 20,
|
|
6285
6285
|
root: "LeftShoulder",
|
|
@@ -6301,8 +6301,8 @@ class Be {
|
|
|
6301
6301
|
}, l, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6302
6302
|
} else
|
|
6303
6303
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
|
|
6304
|
-
let
|
|
6305
|
-
this.poseTarget.props[
|
|
6304
|
+
let c = l + ".quaternion";
|
|
6305
|
+
this.poseTarget.props[c].copy(this.getPoseTemplateProp(c)), this.poseTarget.props[c].t = this.animClock, this.poseTarget.props[c].d = 1e3;
|
|
6306
6306
|
});
|
|
6307
6307
|
return o.length > 0;
|
|
6308
6308
|
}
|
|
@@ -6421,10 +6421,10 @@ class Be {
|
|
|
6421
6421
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6422
6422
|
if (!this.armature) return;
|
|
6423
6423
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6424
|
-
let l = this.animClips.find((
|
|
6424
|
+
let l = this.animClips.find((c) => c.url === t + "-" + i);
|
|
6425
6425
|
if (l) {
|
|
6426
|
-
let
|
|
6427
|
-
|
|
6426
|
+
let c = this.animQueue.find((a) => a.template.name === "pose");
|
|
6427
|
+
c && (c.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
|
|
6428
6428
|
this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
|
|
6429
6429
|
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new y.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6430
6430
|
const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
|
|
@@ -6465,54 +6465,54 @@ class Be {
|
|
|
6465
6465
|
suggestion: "Make sure the file is a valid FBX file and the path is correct"
|
|
6466
6466
|
}), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
|
|
6467
6467
|
try {
|
|
6468
|
-
const
|
|
6468
|
+
const h = await fetch(t), g = h.headers.get("content-type"), b = await h.text();
|
|
6469
6469
|
console.error("Response details:", {
|
|
6470
|
-
status:
|
|
6470
|
+
status: h.status,
|
|
6471
6471
|
contentType: g,
|
|
6472
|
-
firstBytes:
|
|
6473
|
-
isHTML:
|
|
6474
|
-
}), (
|
|
6475
|
-
} catch (
|
|
6476
|
-
console.error("Could not fetch file for debugging:",
|
|
6472
|
+
firstBytes: b.substring(0, 100),
|
|
6473
|
+
isHTML: b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")
|
|
6474
|
+
}), (b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
|
|
6475
|
+
} catch (h) {
|
|
6476
|
+
console.error("Could not fetch file for debugging:", h);
|
|
6477
6477
|
}
|
|
6478
6478
|
return;
|
|
6479
6479
|
}
|
|
6480
6480
|
if (a && a.animations && a.animations[i]) {
|
|
6481
6481
|
let d = a.animations[i];
|
|
6482
|
-
const
|
|
6483
|
-
this.armature && this.armature.traverse((
|
|
6484
|
-
(
|
|
6482
|
+
const h = /* @__PURE__ */ new Set();
|
|
6483
|
+
this.armature && this.armature.traverse((x) => {
|
|
6484
|
+
(x.isBone || x.type === "Bone") && h.add(x.name);
|
|
6485
6485
|
});
|
|
6486
|
-
const g = /* @__PURE__ */ new Map(),
|
|
6487
|
-
if (
|
|
6488
|
-
return
|
|
6489
|
-
let
|
|
6490
|
-
if (
|
|
6491
|
-
return
|
|
6492
|
-
const
|
|
6493
|
-
if (
|
|
6494
|
-
if (
|
|
6495
|
-
if (
|
|
6496
|
-
if (
|
|
6497
|
-
} else if (!
|
|
6486
|
+
const g = /* @__PURE__ */ new Map(), b = (x) => {
|
|
6487
|
+
if (h.has(x))
|
|
6488
|
+
return x;
|
|
6489
|
+
let k = x.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
|
|
6490
|
+
if (h.has(k))
|
|
6491
|
+
return k;
|
|
6492
|
+
const A = k.toLowerCase();
|
|
6493
|
+
if (A.includes("left") && A.includes("arm")) {
|
|
6494
|
+
if (A.includes("fore") || A.includes("lower")) {
|
|
6495
|
+
if (h.has("LeftForeArm")) return "LeftForeArm";
|
|
6496
|
+
if (h.has("LeftForearm")) return "LeftForearm";
|
|
6497
|
+
} else if (!A.includes("fore") && !A.includes("hand") && h.has("LeftArm"))
|
|
6498
6498
|
return "LeftArm";
|
|
6499
6499
|
}
|
|
6500
|
-
if (
|
|
6501
|
-
if (
|
|
6502
|
-
if (
|
|
6503
|
-
if (
|
|
6504
|
-
} else if (!
|
|
6500
|
+
if (A.includes("right") && A.includes("arm")) {
|
|
6501
|
+
if (A.includes("fore") || A.includes("lower")) {
|
|
6502
|
+
if (h.has("RightForeArm")) return "RightForeArm";
|
|
6503
|
+
if (h.has("RightForearm")) return "RightForearm";
|
|
6504
|
+
} else if (!A.includes("fore") && !A.includes("hand") && h.has("RightArm"))
|
|
6505
6505
|
return "RightArm";
|
|
6506
6506
|
}
|
|
6507
|
-
if (
|
|
6507
|
+
if (A.includes("left") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && h.has("LeftHand"))
|
|
6508
6508
|
return "LeftHand";
|
|
6509
|
-
if (
|
|
6509
|
+
if (A.includes("right") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && h.has("RightHand"))
|
|
6510
6510
|
return "RightHand";
|
|
6511
|
-
if (
|
|
6511
|
+
if (A.includes("left") && (A.includes("shoulder") || A.includes("clavicle")) && h.has("LeftShoulder"))
|
|
6512
6512
|
return "LeftShoulder";
|
|
6513
|
-
if (
|
|
6513
|
+
if (A.includes("right") && (A.includes("shoulder") || A.includes("clavicle")) && h.has("RightShoulder"))
|
|
6514
6514
|
return "RightShoulder";
|
|
6515
|
-
const
|
|
6515
|
+
const L = {
|
|
6516
6516
|
// Arm bones - exact matches
|
|
6517
6517
|
LeftArm: "LeftArm",
|
|
6518
6518
|
leftArm: "LeftArm",
|
|
@@ -6552,65 +6552,70 @@ class Be {
|
|
|
6552
6552
|
Root: "Hips",
|
|
6553
6553
|
root: "Hips"
|
|
6554
6554
|
};
|
|
6555
|
-
if (
|
|
6556
|
-
const
|
|
6557
|
-
if (
|
|
6558
|
-
return
|
|
6555
|
+
if (L[k]) {
|
|
6556
|
+
const T = L[k];
|
|
6557
|
+
if (h.has(T))
|
|
6558
|
+
return T;
|
|
6559
6559
|
}
|
|
6560
|
-
for (const
|
|
6561
|
-
if (
|
|
6562
|
-
return
|
|
6563
|
-
for (const
|
|
6564
|
-
const
|
|
6565
|
-
if ((
|
|
6566
|
-
return
|
|
6560
|
+
for (const T of h)
|
|
6561
|
+
if (T.toLowerCase() === A)
|
|
6562
|
+
return T;
|
|
6563
|
+
for (const T of h) {
|
|
6564
|
+
const M = T.toLowerCase();
|
|
6565
|
+
if ((A.includes("left") && M.includes("left") || A.includes("right") && M.includes("right")) && (A.includes("arm") && M.includes("arm") && !M.includes("fore") || A.includes("forearm") && M.includes("forearm") || A.includes("hand") && M.includes("hand") && !M.includes("index") && !M.includes("thumb") || A.includes("shoulder") && M.includes("shoulder")))
|
|
6566
|
+
return T;
|
|
6567
6567
|
}
|
|
6568
6568
|
return null;
|
|
6569
6569
|
}, f = /* @__PURE__ */ new Set();
|
|
6570
|
-
d.tracks.forEach((
|
|
6571
|
-
const
|
|
6572
|
-
f.add(
|
|
6573
|
-
}), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(f).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(
|
|
6574
|
-
const
|
|
6575
|
-
(
|
|
6576
|
-
),
|
|
6577
|
-
(
|
|
6570
|
+
d.tracks.forEach((x) => {
|
|
6571
|
+
const k = x.name.split(".");
|
|
6572
|
+
f.add(k[0]);
|
|
6573
|
+
}), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(f).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(h).sort().join(", "));
|
|
6574
|
+
const w = Array.from(f).filter(
|
|
6575
|
+
(x) => x.toLowerCase().includes("arm") || x.toLowerCase().includes("hand") || x.toLowerCase().includes("shoulder")
|
|
6576
|
+
), N = Array.from(h).filter(
|
|
6577
|
+
(x) => x.includes("Arm") || x.includes("Hand") || x.includes("Shoulder")
|
|
6578
6578
|
);
|
|
6579
|
-
console.log("FBX arm/hand/shoulder bones:",
|
|
6579
|
+
console.log("FBX arm/hand/shoulder bones:", w.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", N.sort().join(", "));
|
|
6580
6580
|
const p = [], B = /* @__PURE__ */ new Set();
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6581
|
+
let F = 0;
|
|
6582
|
+
if (d.tracks.forEach((x) => {
|
|
6583
|
+
const A = x.name.replaceAll("mixamorig", "").split("."), L = A[0], T = A[1], M = b(L);
|
|
6584
|
+
if (M && (M === "LeftShoulder" || M === "RightShoulder") && (T === "quaternion" || T === "rotation")) {
|
|
6585
|
+
F++;
|
|
6586
|
+
return;
|
|
6587
|
+
}
|
|
6588
|
+
if (M && T) {
|
|
6589
|
+
const j = `${M}.${T}`, Z = x.clone();
|
|
6590
|
+
Z.name = j, p.push(Z), L !== M && g.set(L, M);
|
|
6586
6591
|
} else
|
|
6587
|
-
B.add(
|
|
6588
|
-
}), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
|
|
6592
|
+
B.add(L), (L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${L}" could not be mapped to avatar skeleton`);
|
|
6593
|
+
}), F > 0 && console.log(`✓ Filtered out ${F} shoulder rotation track(s) to prevent high shoulders`), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
|
|
6589
6594
|
d = new y.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
|
|
6590
6595
|
`✓ Mapped ${g.size} bone(s):`,
|
|
6591
|
-
Array.from(g.entries()).map(([
|
|
6596
|
+
Array.from(g.entries()).map(([k, A]) => `${k}→${A}`).join(", ")
|
|
6592
6597
|
);
|
|
6593
|
-
const
|
|
6594
|
-
(
|
|
6598
|
+
const x = Array.from(g.values()).filter(
|
|
6599
|
+
(k) => k.includes("Arm") || k.includes("Hand") || k.includes("Shoulder")
|
|
6595
6600
|
);
|
|
6596
|
-
|
|
6601
|
+
x.length > 0 ? console.log(`✓ Arm bones mapped: ${x.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
|
|
6597
6602
|
} else
|
|
6598
6603
|
console.error("❌ No tracks could be mapped! Animation may not work correctly.");
|
|
6599
|
-
const
|
|
6600
|
-
d.tracks.forEach((
|
|
6601
|
-
|
|
6602
|
-
const
|
|
6603
|
-
if (
|
|
6604
|
-
for (let
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
} else
|
|
6604
|
+
const I = {};
|
|
6605
|
+
d.tracks.forEach((x) => {
|
|
6606
|
+
x.name = x.name.replaceAll("mixamorig", "");
|
|
6607
|
+
const k = x.name.split(".");
|
|
6608
|
+
if (k[1] === "position") {
|
|
6609
|
+
for (let A = 0; A < x.values.length; A++)
|
|
6610
|
+
x.values[A] = x.values[A] * s;
|
|
6611
|
+
I[x.name] = new y.Vector3(x.values[0], x.values[1], x.values[2]);
|
|
6612
|
+
} else k[1] === "quaternion" ? I[x.name] = new y.Quaternion(x.values[0], x.values[1], x.values[2], x.values[3]) : k[1] === "rotation" && (I[k[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(x.values[0], x.values[1], x.values[2], "XYZ")).normalize());
|
|
6608
6613
|
});
|
|
6609
|
-
const
|
|
6610
|
-
|
|
6614
|
+
const D = { props: I };
|
|
6615
|
+
I["Hips.position"] && (I["Hips.position"].y < 0.5 ? D.lying = !0 : D.standing = !0), this.animClips.push({
|
|
6611
6616
|
url: t + "-" + i,
|
|
6612
6617
|
clip: d,
|
|
6613
|
-
pose:
|
|
6618
|
+
pose: D
|
|
6614
6619
|
}), this.playAnimation(t, e, n, i, s);
|
|
6615
6620
|
} else {
|
|
6616
6621
|
const d = "Animation " + t + " (ndx=" + i + ") not found";
|
|
@@ -6640,22 +6645,22 @@ class Be {
|
|
|
6640
6645
|
if (!this.armature) return;
|
|
6641
6646
|
let o = this.poseTemplates[t];
|
|
6642
6647
|
if (!o) {
|
|
6643
|
-
const l = this.animPoses.find((
|
|
6648
|
+
const l = this.animPoses.find((c) => c.url === t + "-" + i);
|
|
6644
6649
|
l && (o = l.pose);
|
|
6645
6650
|
}
|
|
6646
6651
|
if (o) {
|
|
6647
6652
|
this.poseName = t, this.mixer = null;
|
|
6648
|
-
let l = this.animQueue.find((
|
|
6653
|
+
let l = this.animQueue.find((c) => c.template.name === "pose");
|
|
6649
6654
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6650
6655
|
} else {
|
|
6651
|
-
let
|
|
6652
|
-
if (
|
|
6653
|
-
let r =
|
|
6656
|
+
let c = await new De().loadAsync(t, e);
|
|
6657
|
+
if (c && c.animations && c.animations[i]) {
|
|
6658
|
+
let r = c.animations[i];
|
|
6654
6659
|
const u = {};
|
|
6655
6660
|
r.tracks.forEach((d) => {
|
|
6656
6661
|
d.name = d.name.replaceAll("mixamorig", "");
|
|
6657
|
-
const
|
|
6658
|
-
|
|
6662
|
+
const h = d.name.split(".");
|
|
6663
|
+
h[1] === "position" ? u[d.name] = new y.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : h[1] === "quaternion" ? u[d.name] = new y.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : h[1] === "rotation" && (u[h[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
|
|
6659
6664
|
});
|
|
6660
6665
|
const a = { props: u };
|
|
6661
6666
|
u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
|
|
@@ -6687,10 +6692,10 @@ class Be {
|
|
|
6687
6692
|
let s = this.gestureTemplates[t];
|
|
6688
6693
|
if (s) {
|
|
6689
6694
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6690
|
-
let l = this.animQueue.findIndex((
|
|
6691
|
-
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((
|
|
6692
|
-
for (let [
|
|
6693
|
-
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(
|
|
6695
|
+
let l = this.animQueue.findIndex((c) => c.template.name === "talkinghands");
|
|
6696
|
+
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((c) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new y.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new y.Quaternion(0, 1, 0, 0), -0.25));
|
|
6697
|
+
for (let [c, r] of Object.entries(this.gesture))
|
|
6698
|
+
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(c) && (this.poseTarget.props[c].copy(r), this.poseTarget.props[c].t = this.animClock, this.poseTarget.props[c].d = i);
|
|
6694
6699
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6695
6700
|
}
|
|
6696
6701
|
let o = this.animEmojis[t];
|
|
@@ -6698,15 +6703,15 @@ class Be {
|
|
|
6698
6703
|
this.lookAtCamera(500);
|
|
6699
6704
|
const l = this.animFactory(o);
|
|
6700
6705
|
if (l.gesture = !0, e && Number.isFinite(e)) {
|
|
6701
|
-
const
|
|
6706
|
+
const c = l.ts[0], u = l.ts[l.ts.length - 1] - c;
|
|
6702
6707
|
if (e * 1e3 - u > 0) {
|
|
6703
6708
|
const d = [];
|
|
6704
|
-
for (let
|
|
6705
|
-
const
|
|
6706
|
-
l.ts = l.ts.map((
|
|
6709
|
+
for (let b = 1; b < l.ts.length; b++) d.push(l.ts[b] - l.ts[b - 1]);
|
|
6710
|
+
const h = o.template?.rescale || d.map((b) => b / u), g = e * 1e3 - u;
|
|
6711
|
+
l.ts = l.ts.map((b, f, w) => f === 0 ? c : w[f - 1] + d[f - 1] + h[f - 1] * g);
|
|
6707
6712
|
} else {
|
|
6708
6713
|
const d = e * 1e3 / u;
|
|
6709
|
-
l.ts = l.ts.map((
|
|
6714
|
+
l.ts = l.ts.map((h) => c + d * (h - c));
|
|
6710
6715
|
}
|
|
6711
6716
|
}
|
|
6712
6717
|
this.animQueue.push(l);
|
|
@@ -6736,34 +6741,34 @@ class Be {
|
|
|
6736
6741
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6737
6742
|
*/
|
|
6738
6743
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6739
|
-
const s = new y.Vector3(), o = new y.Vector3(), l = new y.Vector3(),
|
|
6740
|
-
|
|
6741
|
-
const g = this.ikMesh.getObjectByName(t.effector),
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
}),
|
|
6744
|
+
const s = new y.Vector3(), o = new y.Vector3(), l = new y.Vector3(), c = new y.Vector3(), r = new y.Quaternion(), u = new y.Vector3(), a = new y.Vector3(), d = new y.Vector3(), h = this.ikMesh.getObjectByName(t.root);
|
|
6745
|
+
h.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), h.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(h.position);
|
|
6746
|
+
const g = this.ikMesh.getObjectByName(t.effector), b = t.links;
|
|
6747
|
+
b.forEach((w) => {
|
|
6748
|
+
w.bone = this.ikMesh.getObjectByName(w.link), w.bone.quaternion.copy(this.getPoseTemplateProp(w.link + ".quaternion"));
|
|
6749
|
+
}), h.updateMatrixWorld(!0);
|
|
6745
6750
|
const f = t.iterations || 10;
|
|
6746
6751
|
if (e)
|
|
6747
|
-
for (let
|
|
6748
|
-
let
|
|
6749
|
-
for (let p = 0, B =
|
|
6750
|
-
const
|
|
6751
|
-
|
|
6752
|
-
let
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6752
|
+
for (let w = 0; w < f; w++) {
|
|
6753
|
+
let N = !1;
|
|
6754
|
+
for (let p = 0, B = b.length; p < B; p++) {
|
|
6755
|
+
const F = b[p].bone;
|
|
6756
|
+
F.matrixWorld.decompose(c, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, c), l.applyQuaternion(r), l.normalize(), s.subVectors(e, c), s.applyQuaternion(r), s.normalize();
|
|
6757
|
+
let I = s.dot(l);
|
|
6758
|
+
I > 1 ? I = 1 : I < -1 && (I = -1), I = Math.acos(I), !(I < 1e-5) && (b[p].minAngle !== void 0 && I < b[p].minAngle && (I = b[p].minAngle), b[p].maxAngle !== void 0 && I > b[p].maxAngle && (I = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), te.setFromAxisAngle(a, I), F.quaternion.multiply(te), F.rotation.setFromVector3(d.setFromEuler(F.rotation).clamp(new y.Vector3(
|
|
6759
|
+
b[p].minx !== void 0 ? b[p].minx : -1 / 0,
|
|
6760
|
+
b[p].miny !== void 0 ? b[p].miny : -1 / 0,
|
|
6761
|
+
b[p].minz !== void 0 ? b[p].minz : -1 / 0
|
|
6757
6762
|
), new y.Vector3(
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
))),
|
|
6763
|
+
b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
|
|
6764
|
+
b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
|
|
6765
|
+
b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
|
|
6766
|
+
))), F.updateMatrixWorld(!0), N = !0);
|
|
6762
6767
|
}
|
|
6763
|
-
if (!
|
|
6768
|
+
if (!N) break;
|
|
6764
6769
|
}
|
|
6765
|
-
i &&
|
|
6766
|
-
this.poseTarget.props[
|
|
6770
|
+
i && b.forEach((w) => {
|
|
6771
|
+
this.poseTarget.props[w.link + ".quaternion"].copy(w.bone.quaternion), this.poseTarget.props[w.link + ".quaternion"].t = this.animClock, this.poseTarget.props[w.link + ".quaternion"].d = i;
|
|
6767
6772
|
});
|
|
6768
6773
|
}
|
|
6769
6774
|
/**
|
|
@@ -6773,7 +6778,7 @@ class Be {
|
|
|
6773
6778
|
this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
|
|
6774
6779
|
}
|
|
6775
6780
|
}
|
|
6776
|
-
const
|
|
6781
|
+
const Ae = {
|
|
6777
6782
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6778
6783
|
// Replace with your actual API key (should start with sk_)
|
|
6779
6784
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6793,7 +6798,7 @@ const Ie = {
|
|
|
6793
6798
|
josh: "VR6AewLTigWG4xSOukaG"
|
|
6794
6799
|
// Male, American
|
|
6795
6800
|
}
|
|
6796
|
-
},
|
|
6801
|
+
}, Me = {
|
|
6797
6802
|
defaultVoice: "aura-2-thalia-en",
|
|
6798
6803
|
// Thalia (Female, English)
|
|
6799
6804
|
voices: {
|
|
@@ -6813,26 +6818,26 @@ const Ie = {
|
|
|
6813
6818
|
// Male, English - Powerful
|
|
6814
6819
|
}
|
|
6815
6820
|
};
|
|
6816
|
-
function
|
|
6821
|
+
function Pe() {
|
|
6817
6822
|
return {
|
|
6818
6823
|
service: "elevenlabs",
|
|
6819
|
-
endpoint:
|
|
6820
|
-
apiKey:
|
|
6821
|
-
defaultVoice:
|
|
6822
|
-
voices:
|
|
6824
|
+
endpoint: Ae.endpoint,
|
|
6825
|
+
apiKey: Ae.apiKey,
|
|
6826
|
+
defaultVoice: Ae.defaultVoice,
|
|
6827
|
+
voices: Ae.voices
|
|
6823
6828
|
};
|
|
6824
6829
|
}
|
|
6825
6830
|
function wt() {
|
|
6826
|
-
const
|
|
6827
|
-
return Object.entries(
|
|
6831
|
+
const G = Pe(), t = [];
|
|
6832
|
+
return Object.entries(G.voices).forEach(([e, n]) => {
|
|
6828
6833
|
t.push({
|
|
6829
6834
|
value: n,
|
|
6830
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6835
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
|
|
6831
6836
|
});
|
|
6832
6837
|
}), t;
|
|
6833
6838
|
}
|
|
6834
|
-
const Ve =
|
|
6835
|
-
avatarUrl:
|
|
6839
|
+
const Ve = Fe(({
|
|
6840
|
+
avatarUrl: G = "/avatars/brunette.glb",
|
|
6836
6841
|
avatarBody: t = "F",
|
|
6837
6842
|
mood: e = "neutral",
|
|
6838
6843
|
ttsLang: n = "en",
|
|
@@ -6840,326 +6845,326 @@ const Ve = Me(({
|
|
|
6840
6845
|
ttsVoice: s = null,
|
|
6841
6846
|
ttsApiKey: o = null,
|
|
6842
6847
|
bodyMovement: l = "idle",
|
|
6843
|
-
movementIntensity:
|
|
6848
|
+
movementIntensity: c = 0.5,
|
|
6844
6849
|
showFullAvatar: r = !0,
|
|
6845
6850
|
cameraView: u = "upper",
|
|
6846
6851
|
onReady: a = () => {
|
|
6847
6852
|
},
|
|
6848
6853
|
onLoading: d = () => {
|
|
6849
6854
|
},
|
|
6850
|
-
onError:
|
|
6855
|
+
onError: h = () => {
|
|
6851
6856
|
},
|
|
6852
6857
|
className: g = "",
|
|
6853
|
-
style:
|
|
6858
|
+
style: b = {},
|
|
6854
6859
|
animations: f = {}
|
|
6855
|
-
},
|
|
6856
|
-
const
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
}, [
|
|
6860
|
+
}, w) => {
|
|
6861
|
+
const N = X(null), p = X(null), B = X(r), F = X(null), I = X(null), D = X(!1), x = X({ remainingText: null, originalText: null, options: null }), k = X([]), A = X(0), [L, T] = ae(!0), [M, j] = ae(null), [Z, ue] = ae(!1), [re, ge] = ae(!1);
|
|
6862
|
+
me(() => {
|
|
6863
|
+
D.current = re;
|
|
6864
|
+
}, [re]), me(() => {
|
|
6860
6865
|
B.current = r;
|
|
6861
6866
|
}, [r]);
|
|
6862
|
-
const
|
|
6863
|
-
let
|
|
6864
|
-
|
|
6867
|
+
const ne = Pe(), ve = i || ne.service;
|
|
6868
|
+
let _;
|
|
6869
|
+
ve === "browser" ? _ = {
|
|
6865
6870
|
service: "browser",
|
|
6866
6871
|
endpoint: "",
|
|
6867
6872
|
apiKey: null,
|
|
6868
6873
|
defaultVoice: "Google US English"
|
|
6869
|
-
} :
|
|
6874
|
+
} : ve === "elevenlabs" ? _ = {
|
|
6870
6875
|
service: "elevenlabs",
|
|
6871
6876
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6872
|
-
apiKey: o ||
|
|
6873
|
-
defaultVoice: s ||
|
|
6874
|
-
voices:
|
|
6875
|
-
} :
|
|
6877
|
+
apiKey: o || ne.apiKey,
|
|
6878
|
+
defaultVoice: s || ne.defaultVoice || Ae.defaultVoice,
|
|
6879
|
+
voices: ne.voices || Ae.voices
|
|
6880
|
+
} : ve === "deepgram" ? _ = {
|
|
6876
6881
|
service: "deepgram",
|
|
6877
6882
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6878
|
-
apiKey: o ||
|
|
6879
|
-
defaultVoice: s ||
|
|
6880
|
-
voices:
|
|
6881
|
-
} :
|
|
6882
|
-
...
|
|
6883
|
+
apiKey: o || ne.apiKey,
|
|
6884
|
+
defaultVoice: s || ne.defaultVoice || Me.defaultVoice,
|
|
6885
|
+
voices: ne.voices || Me.voices
|
|
6886
|
+
} : _ = {
|
|
6887
|
+
...ne,
|
|
6883
6888
|
// Override API key if provided via props
|
|
6884
|
-
apiKey: o !== null ? o :
|
|
6889
|
+
apiKey: o !== null ? o : ne.apiKey
|
|
6885
6890
|
};
|
|
6886
|
-
const
|
|
6887
|
-
url:
|
|
6891
|
+
const v = {
|
|
6892
|
+
url: G,
|
|
6888
6893
|
body: t,
|
|
6889
6894
|
avatarMood: e,
|
|
6890
|
-
ttsLang:
|
|
6891
|
-
ttsVoice: s ||
|
|
6895
|
+
ttsLang: ve === "browser" ? "en-US" : n,
|
|
6896
|
+
ttsVoice: s || _.defaultVoice,
|
|
6892
6897
|
lipsyncLang: "en",
|
|
6893
6898
|
showFullAvatar: r,
|
|
6894
6899
|
bodyMovement: l,
|
|
6895
|
-
movementIntensity:
|
|
6896
|
-
},
|
|
6897
|
-
ttsEndpoint:
|
|
6898
|
-
ttsApikey:
|
|
6899
|
-
ttsService:
|
|
6900
|
+
movementIntensity: c
|
|
6901
|
+
}, R = {
|
|
6902
|
+
ttsEndpoint: _.endpoint,
|
|
6903
|
+
ttsApikey: _.apiKey,
|
|
6904
|
+
ttsService: ve,
|
|
6900
6905
|
lipsyncModules: ["en"],
|
|
6901
6906
|
cameraView: u
|
|
6902
|
-
},
|
|
6903
|
-
if (!(!
|
|
6907
|
+
}, P = U(async () => {
|
|
6908
|
+
if (!(!N.current || p.current))
|
|
6904
6909
|
try {
|
|
6905
|
-
if (
|
|
6906
|
-
if (
|
|
6907
|
-
const
|
|
6908
|
-
d(
|
|
6910
|
+
if (T(!0), j(null), p.current = new Be(N.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(v, ($) => {
|
|
6911
|
+
if ($.lengthComputable) {
|
|
6912
|
+
const oe = Math.min(100, Math.round($.loaded / $.total * 100));
|
|
6913
|
+
d(oe);
|
|
6909
6914
|
}
|
|
6910
|
-
}), await new Promise((
|
|
6911
|
-
const
|
|
6912
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6915
|
+
}), await new Promise(($) => {
|
|
6916
|
+
const oe = () => {
|
|
6917
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? $() : setTimeout(oe, 100);
|
|
6913
6918
|
};
|
|
6914
|
-
|
|
6919
|
+
oe();
|
|
6915
6920
|
}), p.current && p.current.setShowFullAvatar)
|
|
6916
6921
|
try {
|
|
6917
6922
|
p.current.setShowFullAvatar(r);
|
|
6918
|
-
} catch (
|
|
6919
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6923
|
+
} catch ($) {
|
|
6924
|
+
console.warn("Error setting full body mode on initialization:", $);
|
|
6920
6925
|
}
|
|
6921
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()),
|
|
6922
|
-
const
|
|
6926
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), T(!1), ue(!0), a(p.current);
|
|
6927
|
+
const V = () => {
|
|
6923
6928
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6924
6929
|
};
|
|
6925
|
-
return document.addEventListener("visibilitychange",
|
|
6926
|
-
document.removeEventListener("visibilitychange",
|
|
6930
|
+
return document.addEventListener("visibilitychange", V), () => {
|
|
6931
|
+
document.removeEventListener("visibilitychange", V);
|
|
6927
6932
|
};
|
|
6928
|
-
} catch (
|
|
6929
|
-
console.error("Error initializing TalkingHead:",
|
|
6933
|
+
} catch (C) {
|
|
6934
|
+
console.error("Error initializing TalkingHead:", C), j(C.message || "Failed to initialize avatar"), T(!1), h(C);
|
|
6930
6935
|
}
|
|
6931
|
-
}, [
|
|
6932
|
-
|
|
6936
|
+
}, [G, t, e, n, i, s, o, r, l, c, u]);
|
|
6937
|
+
me(() => (P(), () => {
|
|
6933
6938
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6934
|
-
}), [
|
|
6935
|
-
if (!
|
|
6936
|
-
const
|
|
6937
|
-
for (const
|
|
6939
|
+
}), [P]), me(() => {
|
|
6940
|
+
if (!N.current || !p.current) return;
|
|
6941
|
+
const C = new ResizeObserver(($) => {
|
|
6942
|
+
for (const oe of $)
|
|
6938
6943
|
p.current && p.current.onResize && p.current.onResize();
|
|
6939
6944
|
});
|
|
6940
|
-
|
|
6941
|
-
const
|
|
6945
|
+
C.observe(N.current);
|
|
6946
|
+
const V = () => {
|
|
6942
6947
|
p.current && p.current.onResize && p.current.onResize();
|
|
6943
6948
|
};
|
|
6944
|
-
return window.addEventListener("resize",
|
|
6945
|
-
|
|
6949
|
+
return window.addEventListener("resize", V), () => {
|
|
6950
|
+
C.disconnect(), window.removeEventListener("resize", V);
|
|
6946
6951
|
};
|
|
6947
|
-
}, [
|
|
6948
|
-
const
|
|
6952
|
+
}, [Z]);
|
|
6953
|
+
const O = U(async () => {
|
|
6949
6954
|
if (p.current && p.current.audioCtx)
|
|
6950
6955
|
try {
|
|
6951
6956
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6952
|
-
} catch (
|
|
6953
|
-
console.warn("Failed to resume audio context:",
|
|
6957
|
+
} catch (C) {
|
|
6958
|
+
console.warn("Failed to resume audio context:", C);
|
|
6954
6959
|
}
|
|
6955
|
-
}, []),
|
|
6956
|
-
if (p.current &&
|
|
6960
|
+
}, []), W = U(async (C, V = {}) => {
|
|
6961
|
+
if (p.current && Z)
|
|
6957
6962
|
try {
|
|
6958
|
-
|
|
6959
|
-
const
|
|
6960
|
-
|
|
6961
|
-
const
|
|
6962
|
-
...
|
|
6963
|
-
lipsyncLang:
|
|
6963
|
+
I.current && (clearInterval(I.current), I.current = null), F.current = { text: C, options: V }, x.current = { remainingText: null, originalText: null, options: null };
|
|
6964
|
+
const $ = /[!\.\?\n\p{Extended_Pictographic}]/ug, oe = C.split($).map((S) => S.trim()).filter((S) => S.length > 0);
|
|
6965
|
+
k.current = oe, A.current = 0, ge(!1), D.current = !1, await O();
|
|
6966
|
+
const ye = {
|
|
6967
|
+
...V,
|
|
6968
|
+
lipsyncLang: V.lipsyncLang || v.lipsyncLang || "en"
|
|
6964
6969
|
};
|
|
6965
|
-
if (
|
|
6966
|
-
const
|
|
6967
|
-
let H = null,
|
|
6968
|
-
const
|
|
6969
|
-
let
|
|
6970
|
+
if (V.onSpeechEnd && p.current) {
|
|
6971
|
+
const S = p.current;
|
|
6972
|
+
let H = null, Y = 0;
|
|
6973
|
+
const ee = 1200;
|
|
6974
|
+
let se = !1;
|
|
6970
6975
|
H = setInterval(() => {
|
|
6971
|
-
if (
|
|
6976
|
+
if (Y++, D.current)
|
|
6972
6977
|
return;
|
|
6973
|
-
if (
|
|
6974
|
-
if (H && (clearInterval(H), H = null,
|
|
6975
|
-
|
|
6978
|
+
if (Y > ee) {
|
|
6979
|
+
if (H && (clearInterval(H), H = null, I.current = null), !se && !D.current) {
|
|
6980
|
+
se = !0;
|
|
6976
6981
|
try {
|
|
6977
|
-
|
|
6982
|
+
V.onSpeechEnd();
|
|
6978
6983
|
} catch (Oe) {
|
|
6979
6984
|
console.error("Error in onSpeechEnd callback (timeout):", Oe);
|
|
6980
6985
|
}
|
|
6981
6986
|
}
|
|
6982
6987
|
return;
|
|
6983
6988
|
}
|
|
6984
|
-
const
|
|
6985
|
-
|
|
6986
|
-
if (
|
|
6987
|
-
|
|
6989
|
+
const le = !S.speechQueue || S.speechQueue.length === 0, Ce = !S.audioPlaylist || S.audioPlaylist.length === 0;
|
|
6990
|
+
S && S.isSpeaking === !1 && le && Ce && S.isAudioPlaying === !1 && !se && !D.current && setTimeout(() => {
|
|
6991
|
+
if (S && !D.current && S.isSpeaking === !1 && (!S.speechQueue || S.speechQueue.length === 0) && (!S.audioPlaylist || S.audioPlaylist.length === 0) && S.isAudioPlaying === !1 && !se && !D.current) {
|
|
6992
|
+
se = !0, H && (clearInterval(H), H = null, I.current = null);
|
|
6988
6993
|
try {
|
|
6989
|
-
|
|
6994
|
+
V.onSpeechEnd();
|
|
6990
6995
|
} catch (Xe) {
|
|
6991
6996
|
console.error("Error in onSpeechEnd callback:", Xe);
|
|
6992
6997
|
}
|
|
6993
6998
|
}
|
|
6994
6999
|
}, 100);
|
|
6995
|
-
}, 100),
|
|
7000
|
+
}, 100), I.current = H;
|
|
6996
7001
|
}
|
|
6997
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(
|
|
6998
|
-
await
|
|
7002
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(C, ye)) : setTimeout(async () => {
|
|
7003
|
+
await O(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(C, ye));
|
|
6999
7004
|
}, 100);
|
|
7000
|
-
} catch (
|
|
7001
|
-
console.error("Error speaking text:",
|
|
7005
|
+
} catch ($) {
|
|
7006
|
+
console.error("Error speaking text:", $), j($.message || "Failed to speak text");
|
|
7002
7007
|
}
|
|
7003
|
-
}, [
|
|
7004
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
7005
|
-
}, []),
|
|
7008
|
+
}, [Z, O, v.lipsyncLang]), ie = U(() => {
|
|
7009
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), F.current = null, ge(!1));
|
|
7010
|
+
}, []), K = U(() => {
|
|
7006
7011
|
if (p.current && p.current.pauseSpeaking) {
|
|
7007
|
-
const
|
|
7008
|
-
if (
|
|
7009
|
-
|
|
7010
|
-
let
|
|
7011
|
-
if (
|
|
7012
|
-
const
|
|
7013
|
-
if (H > 0 &&
|
|
7014
|
-
const
|
|
7015
|
-
|
|
7012
|
+
const C = p.current;
|
|
7013
|
+
if (C.isSpeaking || C.audioPlaylist && C.audioPlaylist.length > 0 || C.speechQueue && C.speechQueue.length > 0) {
|
|
7014
|
+
I.current && (clearInterval(I.current), I.current = null);
|
|
7015
|
+
let $ = "";
|
|
7016
|
+
if (F.current && k.current.length > 0) {
|
|
7017
|
+
const oe = k.current.length, ye = C.speechQueue ? C.speechQueue.filter((ee) => ee && ee.text && Array.isArray(ee.text) && ee.text.length > 0).length : 0, S = C.audioPlaylist && C.audioPlaylist.length > 0, H = ye + (S ? 1 : 0), Y = oe - H;
|
|
7018
|
+
if (H > 0 && Y < oe && ($ = k.current.slice(Y).join(". ").trim(), !$ && ye > 0 && C.speechQueue)) {
|
|
7019
|
+
const se = C.speechQueue.filter((le) => le && le.text && Array.isArray(le.text) && le.text.length > 0).map((le) => le.text.map((Ce) => Ce.word || "").filter((Ce) => Ce.length > 0).join(" ")).filter((le) => le.length > 0).join(" ");
|
|
7020
|
+
se && se.trim() && ($ = se.trim());
|
|
7016
7021
|
}
|
|
7017
7022
|
}
|
|
7018
|
-
|
|
7019
|
-
remainingText:
|
|
7020
|
-
originalText:
|
|
7021
|
-
options:
|
|
7022
|
-
}),
|
|
7023
|
+
F.current && (x.current = {
|
|
7024
|
+
remainingText: $ || null,
|
|
7025
|
+
originalText: F.current.text,
|
|
7026
|
+
options: F.current.options
|
|
7027
|
+
}), C.speechQueue && (C.speechQueue.length = 0), p.current.pauseSpeaking(), D.current = !0, ge(!0);
|
|
7023
7028
|
}
|
|
7024
7029
|
}
|
|
7025
|
-
}, []),
|
|
7026
|
-
if (!p.current || !
|
|
7030
|
+
}, []), J = U(async () => {
|
|
7031
|
+
if (!p.current || !re)
|
|
7027
7032
|
return;
|
|
7028
|
-
let
|
|
7029
|
-
if (
|
|
7030
|
-
|
|
7031
|
-
else if (
|
|
7032
|
-
|
|
7033
|
+
let C = "", V = {};
|
|
7034
|
+
if (x.current && x.current.remainingText)
|
|
7035
|
+
C = x.current.remainingText, V = x.current.options || {}, x.current = { remainingText: null, originalText: null, options: null };
|
|
7036
|
+
else if (F.current && F.current.text)
|
|
7037
|
+
C = F.current.text, V = F.current.options || {};
|
|
7033
7038
|
else {
|
|
7034
|
-
console.warn("Resume called but no paused speech found"),
|
|
7039
|
+
console.warn("Resume called but no paused speech found"), ge(!1), D.current = !1;
|
|
7035
7040
|
return;
|
|
7036
7041
|
}
|
|
7037
|
-
|
|
7038
|
-
const
|
|
7039
|
-
...
|
|
7040
|
-
lipsyncLang:
|
|
7042
|
+
ge(!1), D.current = !1, await O();
|
|
7043
|
+
const $ = {
|
|
7044
|
+
...V,
|
|
7045
|
+
lipsyncLang: V.lipsyncLang || v.lipsyncLang || "en"
|
|
7041
7046
|
};
|
|
7042
7047
|
try {
|
|
7043
|
-
await
|
|
7044
|
-
} catch (
|
|
7045
|
-
console.error("Error resuming speech:",
|
|
7048
|
+
await W(C, $);
|
|
7049
|
+
} catch (oe) {
|
|
7050
|
+
console.error("Error resuming speech:", oe), ge(!1), D.current = !1;
|
|
7046
7051
|
}
|
|
7047
|
-
}, [
|
|
7048
|
-
p.current && p.current.setMood(
|
|
7049
|
-
}, []),
|
|
7050
|
-
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(
|
|
7051
|
-
}, []),
|
|
7052
|
+
}, [O, re, W, v]), Le = U((C) => {
|
|
7053
|
+
p.current && p.current.setMood(C);
|
|
7054
|
+
}, []), ke = U((C) => {
|
|
7055
|
+
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(C);
|
|
7056
|
+
}, []), Se = U((C, V = !1) => {
|
|
7052
7057
|
if (p.current && p.current.playAnimation) {
|
|
7053
|
-
if (f && f[
|
|
7058
|
+
if (f && f[C] && (C = f[C]), p.current.setShowFullAvatar)
|
|
7054
7059
|
try {
|
|
7055
7060
|
p.current.setShowFullAvatar(B.current);
|
|
7056
|
-
} catch (
|
|
7057
|
-
console.warn("Error setting full body mode:",
|
|
7061
|
+
} catch (oe) {
|
|
7062
|
+
console.warn("Error setting full body mode:", oe);
|
|
7058
7063
|
}
|
|
7059
|
-
if (
|
|
7064
|
+
if (C.includes("."))
|
|
7060
7065
|
try {
|
|
7061
|
-
p.current.playAnimation(
|
|
7062
|
-
} catch (
|
|
7063
|
-
console.warn(`Failed to play ${
|
|
7066
|
+
p.current.playAnimation(C, null, 10, 0, 0.01, V);
|
|
7067
|
+
} catch (oe) {
|
|
7068
|
+
console.warn(`Failed to play ${C}:`, oe);
|
|
7064
7069
|
try {
|
|
7065
7070
|
p.current.setBodyMovement("idle");
|
|
7066
|
-
} catch (
|
|
7067
|
-
console.warn("Fallback animation also failed:",
|
|
7071
|
+
} catch (ye) {
|
|
7072
|
+
console.warn("Fallback animation also failed:", ye);
|
|
7068
7073
|
}
|
|
7069
7074
|
}
|
|
7070
7075
|
else {
|
|
7071
|
-
const
|
|
7072
|
-
let
|
|
7073
|
-
for (const
|
|
7076
|
+
const oe = [".fbx", ".glb", ".gltf"];
|
|
7077
|
+
let ye = !1;
|
|
7078
|
+
for (const S of oe)
|
|
7074
7079
|
try {
|
|
7075
|
-
p.current.playAnimation(
|
|
7080
|
+
p.current.playAnimation(C + S, null, 10, 0, 0.01, V), ye = !0;
|
|
7076
7081
|
break;
|
|
7077
7082
|
} catch {
|
|
7078
7083
|
}
|
|
7079
|
-
if (!
|
|
7080
|
-
console.warn("Animation not found:",
|
|
7084
|
+
if (!ye) {
|
|
7085
|
+
console.warn("Animation not found:", C);
|
|
7081
7086
|
try {
|
|
7082
7087
|
p.current.setBodyMovement("idle");
|
|
7083
|
-
} catch (
|
|
7084
|
-
console.warn("Fallback animation also failed:",
|
|
7088
|
+
} catch (S) {
|
|
7089
|
+
console.warn("Fallback animation also failed:", S);
|
|
7085
7090
|
}
|
|
7086
7091
|
}
|
|
7087
7092
|
}
|
|
7088
7093
|
}
|
|
7089
|
-
}, [f]),
|
|
7094
|
+
}, [f]), we = U(() => {
|
|
7090
7095
|
p.current && p.current.onResize && p.current.onResize();
|
|
7091
7096
|
}, []);
|
|
7092
|
-
return
|
|
7093
|
-
speakText:
|
|
7094
|
-
stopSpeaking:
|
|
7095
|
-
pauseSpeaking:
|
|
7096
|
-
resumeSpeaking:
|
|
7097
|
-
resumeAudioContext:
|
|
7098
|
-
setMood:
|
|
7099
|
-
setTimingAdjustment:
|
|
7100
|
-
playAnimation:
|
|
7101
|
-
isReady:
|
|
7102
|
-
isPaused:
|
|
7097
|
+
return Ee(w, () => ({
|
|
7098
|
+
speakText: W,
|
|
7099
|
+
stopSpeaking: ie,
|
|
7100
|
+
pauseSpeaking: K,
|
|
7101
|
+
resumeSpeaking: J,
|
|
7102
|
+
resumeAudioContext: O,
|
|
7103
|
+
setMood: Le,
|
|
7104
|
+
setTimingAdjustment: ke,
|
|
7105
|
+
playAnimation: Se,
|
|
7106
|
+
isReady: Z,
|
|
7107
|
+
isPaused: re,
|
|
7103
7108
|
talkingHead: p.current,
|
|
7104
|
-
handleResize:
|
|
7105
|
-
setBodyMovement: (
|
|
7109
|
+
handleResize: we,
|
|
7110
|
+
setBodyMovement: (C) => {
|
|
7106
7111
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
7107
7112
|
try {
|
|
7108
|
-
p.current.setShowFullAvatar(B.current), p.current.setBodyMovement(
|
|
7109
|
-
} catch (
|
|
7110
|
-
console.warn("Error setting body movement:",
|
|
7113
|
+
p.current.setShowFullAvatar(B.current), p.current.setBodyMovement(C);
|
|
7114
|
+
} catch (V) {
|
|
7115
|
+
console.warn("Error setting body movement:", V);
|
|
7111
7116
|
}
|
|
7112
7117
|
},
|
|
7113
|
-
setMovementIntensity: (
|
|
7118
|
+
setMovementIntensity: (C) => p.current?.setMovementIntensity(C),
|
|
7114
7119
|
playRandomDance: () => {
|
|
7115
7120
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
7116
7121
|
try {
|
|
7117
7122
|
p.current.setShowFullAvatar(B.current), p.current.playRandomDance();
|
|
7118
|
-
} catch (
|
|
7119
|
-
console.warn("Error playing random dance:",
|
|
7123
|
+
} catch (C) {
|
|
7124
|
+
console.warn("Error playing random dance:", C);
|
|
7120
7125
|
}
|
|
7121
7126
|
},
|
|
7122
|
-
playReaction: (
|
|
7127
|
+
playReaction: (C) => {
|
|
7123
7128
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
7124
7129
|
try {
|
|
7125
|
-
p.current.setShowFullAvatar(B.current), p.current.playReaction(
|
|
7126
|
-
} catch (
|
|
7127
|
-
console.warn("Error playing reaction:",
|
|
7130
|
+
p.current.setShowFullAvatar(B.current), p.current.playReaction(C);
|
|
7131
|
+
} catch (V) {
|
|
7132
|
+
console.warn("Error playing reaction:", V);
|
|
7128
7133
|
}
|
|
7129
7134
|
},
|
|
7130
7135
|
playCelebration: () => {
|
|
7131
7136
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
7132
7137
|
try {
|
|
7133
7138
|
p.current.setShowFullAvatar(B.current), p.current.playCelebration();
|
|
7134
|
-
} catch (
|
|
7135
|
-
console.warn("Error playing celebration:",
|
|
7139
|
+
} catch (C) {
|
|
7140
|
+
console.warn("Error playing celebration:", C);
|
|
7136
7141
|
}
|
|
7137
7142
|
},
|
|
7138
|
-
setShowFullAvatar: (
|
|
7143
|
+
setShowFullAvatar: (C) => {
|
|
7139
7144
|
if (p.current && p.current.setShowFullAvatar)
|
|
7140
7145
|
try {
|
|
7141
|
-
B.current =
|
|
7142
|
-
} catch (
|
|
7143
|
-
console.warn("Error setting showFullAvatar:",
|
|
7146
|
+
B.current = C, p.current.setShowFullAvatar(C);
|
|
7147
|
+
} catch (V) {
|
|
7148
|
+
console.warn("Error setting showFullAvatar:", V);
|
|
7144
7149
|
}
|
|
7145
7150
|
},
|
|
7146
7151
|
lockAvatarPosition: () => {
|
|
7147
7152
|
if (p.current && p.current.lockAvatarPosition)
|
|
7148
7153
|
try {
|
|
7149
7154
|
p.current.lockAvatarPosition();
|
|
7150
|
-
} catch (
|
|
7151
|
-
console.warn("Error locking avatar position:",
|
|
7155
|
+
} catch (C) {
|
|
7156
|
+
console.warn("Error locking avatar position:", C);
|
|
7152
7157
|
}
|
|
7153
7158
|
},
|
|
7154
7159
|
unlockAvatarPosition: () => {
|
|
7155
7160
|
if (p.current && p.current.unlockAvatarPosition)
|
|
7156
7161
|
try {
|
|
7157
7162
|
p.current.unlockAvatarPosition();
|
|
7158
|
-
} catch (
|
|
7159
|
-
console.warn("Error unlocking avatar position:",
|
|
7163
|
+
} catch (C) {
|
|
7164
|
+
console.warn("Error unlocking avatar position:", C);
|
|
7160
7165
|
}
|
|
7161
7166
|
}
|
|
7162
|
-
})), /* @__PURE__ */
|
|
7167
|
+
})), /* @__PURE__ */ fe(
|
|
7163
7168
|
"div",
|
|
7164
7169
|
{
|
|
7165
7170
|
className: `talking-head-avatar ${g}`,
|
|
@@ -7167,13 +7172,13 @@ const Ve = Me(({
|
|
|
7167
7172
|
width: "100%",
|
|
7168
7173
|
height: "100%",
|
|
7169
7174
|
position: "relative",
|
|
7170
|
-
...
|
|
7175
|
+
...b
|
|
7171
7176
|
},
|
|
7172
7177
|
children: [
|
|
7173
|
-
/* @__PURE__ */
|
|
7178
|
+
/* @__PURE__ */ q(
|
|
7174
7179
|
"div",
|
|
7175
7180
|
{
|
|
7176
|
-
ref:
|
|
7181
|
+
ref: N,
|
|
7177
7182
|
className: "talking-head-viewer",
|
|
7178
7183
|
style: {
|
|
7179
7184
|
width: "100%",
|
|
@@ -7182,7 +7187,7 @@ const Ve = Me(({
|
|
|
7182
7187
|
}
|
|
7183
7188
|
}
|
|
7184
7189
|
),
|
|
7185
|
-
|
|
7190
|
+
L && /* @__PURE__ */ q("div", { className: "loading-overlay", style: {
|
|
7186
7191
|
position: "absolute",
|
|
7187
7192
|
top: "50%",
|
|
7188
7193
|
left: "50%",
|
|
@@ -7191,7 +7196,7 @@ const Ve = Me(({
|
|
|
7191
7196
|
fontSize: "18px",
|
|
7192
7197
|
zIndex: 10
|
|
7193
7198
|
}, children: "Loading avatar..." }),
|
|
7194
|
-
|
|
7199
|
+
M && /* @__PURE__ */ q("div", { className: "error-overlay", style: {
|
|
7195
7200
|
position: "absolute",
|
|
7196
7201
|
top: "50%",
|
|
7197
7202
|
left: "50%",
|
|
@@ -7202,14 +7207,14 @@ const Ve = Me(({
|
|
|
7202
7207
|
zIndex: 10,
|
|
7203
7208
|
padding: "20px",
|
|
7204
7209
|
borderRadius: "8px"
|
|
7205
|
-
}, children:
|
|
7210
|
+
}, children: M })
|
|
7206
7211
|
]
|
|
7207
7212
|
}
|
|
7208
7213
|
);
|
|
7209
7214
|
});
|
|
7210
7215
|
Ve.displayName = "TalkingHeadAvatar";
|
|
7211
|
-
const
|
|
7212
|
-
text:
|
|
7216
|
+
const gt = Fe(({
|
|
7217
|
+
text: G = "Hello! I'm a talking avatar. How are you today?",
|
|
7213
7218
|
onLoading: t = () => {
|
|
7214
7219
|
},
|
|
7215
7220
|
onError: e = () => {
|
|
@@ -7220,7 +7225,7 @@ const pt = Me(({
|
|
|
7220
7225
|
style: s = {},
|
|
7221
7226
|
avatarConfig: o = {}
|
|
7222
7227
|
}, l) => {
|
|
7223
|
-
const
|
|
7228
|
+
const c = X(null), r = X(null), [u, a] = ae(!0), [d, h] = ae(null), [g, b] = ae(!1), f = Pe(), w = o.ttsService || f.service, N = w === "browser" ? {
|
|
7224
7229
|
endpoint: "",
|
|
7225
7230
|
apiKey: null,
|
|
7226
7231
|
defaultVoice: "Google US English"
|
|
@@ -7229,14 +7234,14 @@ const pt = Me(({
|
|
|
7229
7234
|
// Override API key if provided via avatarConfig
|
|
7230
7235
|
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
|
|
7231
7236
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7232
|
-
endpoint:
|
|
7237
|
+
endpoint: w === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
|
|
7233
7238
|
}, p = {
|
|
7234
7239
|
url: "/avatars/brunette.glb",
|
|
7235
7240
|
// Use brunette avatar (working glTF file)
|
|
7236
7241
|
body: "F",
|
|
7237
7242
|
avatarMood: "neutral",
|
|
7238
|
-
ttsLang:
|
|
7239
|
-
ttsVoice: o.ttsVoice ||
|
|
7243
|
+
ttsLang: w === "browser" ? "en-US" : "en",
|
|
7244
|
+
ttsVoice: o.ttsVoice || N.defaultVoice,
|
|
7240
7245
|
lipsyncLang: "en",
|
|
7241
7246
|
// English lip-sync
|
|
7242
7247
|
showFullAvatar: !0,
|
|
@@ -7245,178 +7250,178 @@ const pt = Me(({
|
|
|
7245
7250
|
movementIntensity: 0.5,
|
|
7246
7251
|
...o
|
|
7247
7252
|
}, B = {
|
|
7248
|
-
ttsEndpoint:
|
|
7249
|
-
ttsApikey:
|
|
7250
|
-
ttsService:
|
|
7253
|
+
ttsEndpoint: N.endpoint,
|
|
7254
|
+
ttsApikey: N.apiKey,
|
|
7255
|
+
ttsService: w,
|
|
7251
7256
|
lipsyncModules: ["en"],
|
|
7252
7257
|
cameraView: "upper"
|
|
7253
|
-
},
|
|
7254
|
-
if (!(!
|
|
7258
|
+
}, F = U(async () => {
|
|
7259
|
+
if (!(!c.current || r.current))
|
|
7255
7260
|
try {
|
|
7256
|
-
if (a(!0),
|
|
7257
|
-
if (
|
|
7258
|
-
const
|
|
7259
|
-
t(
|
|
7261
|
+
if (a(!0), h(null), r.current = new Be(c.current, B), await r.current.showAvatar(p, (M) => {
|
|
7262
|
+
if (M.lengthComputable) {
|
|
7263
|
+
const j = Math.min(100, Math.round(M.loaded / M.total * 100));
|
|
7264
|
+
t(j);
|
|
7260
7265
|
}
|
|
7261
7266
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7262
|
-
const
|
|
7263
|
-
console.log("Available morph targets:", Object.keys(
|
|
7264
|
-
const
|
|
7265
|
-
console.log("Viseme morph targets found:",
|
|
7267
|
+
const M = r.current.morphs[0].morphTargetDictionary;
|
|
7268
|
+
console.log("Available morph targets:", Object.keys(M));
|
|
7269
|
+
const j = Object.keys(M).filter((Z) => Z.startsWith("viseme_"));
|
|
7270
|
+
console.log("Viseme morph targets found:", j), j.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
|
|
7266
7271
|
}
|
|
7267
|
-
if (await new Promise((
|
|
7268
|
-
const
|
|
7269
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7272
|
+
if (await new Promise((M) => {
|
|
7273
|
+
const j = () => {
|
|
7274
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), M()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(j, 100));
|
|
7270
7275
|
};
|
|
7271
|
-
|
|
7276
|
+
j();
|
|
7272
7277
|
}), r.current && r.current.setShowFullAvatar)
|
|
7273
7278
|
try {
|
|
7274
7279
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7275
|
-
} catch (
|
|
7276
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7280
|
+
} catch (M) {
|
|
7281
|
+
console.warn("Error setting full body mode on initialization:", M);
|
|
7277
7282
|
}
|
|
7278
|
-
a(!1),
|
|
7279
|
-
const
|
|
7283
|
+
a(!1), b(!0), n(r.current);
|
|
7284
|
+
const T = () => {
|
|
7280
7285
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7281
7286
|
};
|
|
7282
|
-
return document.addEventListener("visibilitychange",
|
|
7283
|
-
document.removeEventListener("visibilitychange",
|
|
7287
|
+
return document.addEventListener("visibilitychange", T), () => {
|
|
7288
|
+
document.removeEventListener("visibilitychange", T);
|
|
7284
7289
|
};
|
|
7285
|
-
} catch (
|
|
7286
|
-
console.error("Error initializing TalkingHead:",
|
|
7290
|
+
} catch (L) {
|
|
7291
|
+
console.error("Error initializing TalkingHead:", L), h(L.message || "Failed to initialize avatar"), a(!1), e(L);
|
|
7287
7292
|
}
|
|
7288
7293
|
}, []);
|
|
7289
|
-
|
|
7294
|
+
me(() => (F(), () => {
|
|
7290
7295
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7291
|
-
}), [
|
|
7292
|
-
const
|
|
7296
|
+
}), [F]);
|
|
7297
|
+
const I = U((L) => {
|
|
7293
7298
|
if (r.current && g)
|
|
7294
7299
|
try {
|
|
7295
|
-
console.log("Speaking text:",
|
|
7296
|
-
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(
|
|
7300
|
+
console.log("Speaking text:", L), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(L)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7301
|
+
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(L)) : console.error("Lip-sync still not ready after waiting");
|
|
7297
7302
|
}, 500));
|
|
7298
|
-
} catch (
|
|
7299
|
-
console.error("Error speaking text:",
|
|
7303
|
+
} catch (T) {
|
|
7304
|
+
console.error("Error speaking text:", T), h(T.message || "Failed to speak text");
|
|
7300
7305
|
}
|
|
7301
7306
|
else
|
|
7302
7307
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7303
|
-
}, [g, p]),
|
|
7308
|
+
}, [g, p]), D = U(() => {
|
|
7304
7309
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7305
|
-
}, []),
|
|
7306
|
-
r.current && r.current.setMood(
|
|
7307
|
-
}, []),
|
|
7308
|
-
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(
|
|
7309
|
-
}, []),
|
|
7310
|
+
}, []), x = U((L) => {
|
|
7311
|
+
r.current && r.current.setMood(L);
|
|
7312
|
+
}, []), k = U((L) => {
|
|
7313
|
+
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(L), console.log("Timing adjustment set to:", L));
|
|
7314
|
+
}, []), A = U((L, T = !1) => {
|
|
7310
7315
|
if (r.current && r.current.playAnimation) {
|
|
7311
7316
|
if (r.current.setShowFullAvatar)
|
|
7312
7317
|
try {
|
|
7313
7318
|
r.current.setShowFullAvatar(!0);
|
|
7314
|
-
} catch (
|
|
7315
|
-
console.warn("Error setting full body mode:",
|
|
7319
|
+
} catch (j) {
|
|
7320
|
+
console.warn("Error setting full body mode:", j);
|
|
7316
7321
|
}
|
|
7317
|
-
if (
|
|
7322
|
+
if (L.includes("."))
|
|
7318
7323
|
try {
|
|
7319
|
-
r.current.playAnimation(
|
|
7320
|
-
} catch (
|
|
7321
|
-
console.log(`Failed to play ${
|
|
7324
|
+
r.current.playAnimation(L, null, 10, 0, 0.01, T), console.log("Playing animation:", L);
|
|
7325
|
+
} catch (j) {
|
|
7326
|
+
console.log(`Failed to play ${L}:`, j);
|
|
7322
7327
|
try {
|
|
7323
7328
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7324
|
-
} catch (
|
|
7325
|
-
console.warn("Fallback animation also failed:",
|
|
7329
|
+
} catch (Z) {
|
|
7330
|
+
console.warn("Fallback animation also failed:", Z);
|
|
7326
7331
|
}
|
|
7327
7332
|
}
|
|
7328
7333
|
else {
|
|
7329
|
-
const
|
|
7330
|
-
let
|
|
7331
|
-
for (const
|
|
7334
|
+
const j = [".fbx", ".glb", ".gltf"];
|
|
7335
|
+
let Z = !1;
|
|
7336
|
+
for (const ue of j)
|
|
7332
7337
|
try {
|
|
7333
|
-
r.current.playAnimation(
|
|
7338
|
+
r.current.playAnimation(L + ue, null, 10, 0, 0.01, T), console.log("Playing animation:", L + ue), Z = !0;
|
|
7334
7339
|
break;
|
|
7335
7340
|
} catch {
|
|
7336
|
-
console.log(`Failed to play ${
|
|
7341
|
+
console.log(`Failed to play ${L}${ue}, trying next format...`);
|
|
7337
7342
|
}
|
|
7338
|
-
if (!
|
|
7339
|
-
console.warn("Animation system not available or animation not found:",
|
|
7343
|
+
if (!Z) {
|
|
7344
|
+
console.warn("Animation system not available or animation not found:", L);
|
|
7340
7345
|
try {
|
|
7341
7346
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7342
|
-
} catch (
|
|
7343
|
-
console.warn("Fallback animation also failed:",
|
|
7347
|
+
} catch (ue) {
|
|
7348
|
+
console.warn("Fallback animation also failed:", ue);
|
|
7344
7349
|
}
|
|
7345
7350
|
}
|
|
7346
7351
|
}
|
|
7347
7352
|
} else
|
|
7348
|
-
console.warn("Animation system not available or animation not found:",
|
|
7353
|
+
console.warn("Animation system not available or animation not found:", L);
|
|
7349
7354
|
}, []);
|
|
7350
|
-
return
|
|
7351
|
-
speakText:
|
|
7352
|
-
stopSpeaking:
|
|
7353
|
-
setMood:
|
|
7354
|
-
setTimingAdjustment:
|
|
7355
|
-
playAnimation:
|
|
7355
|
+
return Ee(l, () => ({
|
|
7356
|
+
speakText: I,
|
|
7357
|
+
stopSpeaking: D,
|
|
7358
|
+
setMood: x,
|
|
7359
|
+
setTimingAdjustment: k,
|
|
7360
|
+
playAnimation: A,
|
|
7356
7361
|
isReady: g,
|
|
7357
7362
|
talkingHead: r.current,
|
|
7358
|
-
setBodyMovement: (
|
|
7363
|
+
setBodyMovement: (L) => {
|
|
7359
7364
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7360
7365
|
try {
|
|
7361
|
-
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(
|
|
7362
|
-
} catch (
|
|
7363
|
-
console.warn("Error setting body movement:",
|
|
7366
|
+
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(L), console.log("Body movement set with full body mode:", L);
|
|
7367
|
+
} catch (T) {
|
|
7368
|
+
console.warn("Error setting body movement:", T);
|
|
7364
7369
|
}
|
|
7365
7370
|
},
|
|
7366
|
-
setMovementIntensity: (
|
|
7371
|
+
setMovementIntensity: (L) => r.current?.setMovementIntensity(L),
|
|
7367
7372
|
playRandomDance: () => {
|
|
7368
7373
|
if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
|
|
7369
7374
|
try {
|
|
7370
7375
|
r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
|
|
7371
|
-
} catch (
|
|
7372
|
-
console.warn("Error playing random dance:",
|
|
7376
|
+
} catch (L) {
|
|
7377
|
+
console.warn("Error playing random dance:", L);
|
|
7373
7378
|
}
|
|
7374
7379
|
},
|
|
7375
|
-
playReaction: (
|
|
7380
|
+
playReaction: (L) => {
|
|
7376
7381
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7377
7382
|
try {
|
|
7378
|
-
r.current.setShowFullAvatar(!0), r.current.playReaction(
|
|
7379
|
-
} catch (
|
|
7380
|
-
console.warn("Error playing reaction:",
|
|
7383
|
+
r.current.setShowFullAvatar(!0), r.current.playReaction(L), console.log("Reaction played with full body mode:", L);
|
|
7384
|
+
} catch (T) {
|
|
7385
|
+
console.warn("Error playing reaction:", T);
|
|
7381
7386
|
}
|
|
7382
7387
|
},
|
|
7383
7388
|
playCelebration: () => {
|
|
7384
7389
|
if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
|
|
7385
7390
|
try {
|
|
7386
7391
|
r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
|
|
7387
|
-
} catch (
|
|
7388
|
-
console.warn("Error playing celebration:",
|
|
7392
|
+
} catch (L) {
|
|
7393
|
+
console.warn("Error playing celebration:", L);
|
|
7389
7394
|
}
|
|
7390
7395
|
},
|
|
7391
|
-
setShowFullAvatar: (
|
|
7396
|
+
setShowFullAvatar: (L) => {
|
|
7392
7397
|
if (r.current && r.current.setShowFullAvatar)
|
|
7393
7398
|
try {
|
|
7394
|
-
r.current.setShowFullAvatar(
|
|
7395
|
-
} catch (
|
|
7396
|
-
console.warn("Error setting showFullAvatar:",
|
|
7399
|
+
r.current.setShowFullAvatar(L), console.log("Show full avatar set to:", L);
|
|
7400
|
+
} catch (T) {
|
|
7401
|
+
console.warn("Error setting showFullAvatar:", T);
|
|
7397
7402
|
}
|
|
7398
7403
|
},
|
|
7399
7404
|
lockAvatarPosition: () => {
|
|
7400
7405
|
if (r.current && r.current.lockAvatarPosition)
|
|
7401
7406
|
try {
|
|
7402
7407
|
r.current.lockAvatarPosition();
|
|
7403
|
-
} catch (
|
|
7404
|
-
console.warn("Error locking avatar position:",
|
|
7408
|
+
} catch (L) {
|
|
7409
|
+
console.warn("Error locking avatar position:", L);
|
|
7405
7410
|
}
|
|
7406
7411
|
},
|
|
7407
7412
|
unlockAvatarPosition: () => {
|
|
7408
7413
|
if (r.current && r.current.unlockAvatarPosition)
|
|
7409
7414
|
try {
|
|
7410
7415
|
r.current.unlockAvatarPosition();
|
|
7411
|
-
} catch (
|
|
7412
|
-
console.warn("Error unlocking avatar position:",
|
|
7416
|
+
} catch (L) {
|
|
7417
|
+
console.warn("Error unlocking avatar position:", L);
|
|
7413
7418
|
}
|
|
7414
7419
|
}
|
|
7415
|
-
})), /* @__PURE__ */
|
|
7416
|
-
/* @__PURE__ */
|
|
7420
|
+
})), /* @__PURE__ */ fe("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7421
|
+
/* @__PURE__ */ q(
|
|
7417
7422
|
"div",
|
|
7418
7423
|
{
|
|
7419
|
-
ref:
|
|
7424
|
+
ref: c,
|
|
7420
7425
|
className: "talking-head-viewer",
|
|
7421
7426
|
style: {
|
|
7422
7427
|
width: "100%",
|
|
@@ -7425,7 +7430,7 @@ const pt = Me(({
|
|
|
7425
7430
|
}
|
|
7426
7431
|
}
|
|
7427
7432
|
),
|
|
7428
|
-
u && /* @__PURE__ */
|
|
7433
|
+
u && /* @__PURE__ */ q("div", { className: "loading-overlay", style: {
|
|
7429
7434
|
position: "absolute",
|
|
7430
7435
|
top: "50%",
|
|
7431
7436
|
left: "50%",
|
|
@@ -7434,7 +7439,7 @@ const pt = Me(({
|
|
|
7434
7439
|
fontSize: "18px",
|
|
7435
7440
|
zIndex: 10
|
|
7436
7441
|
}, children: "Loading avatar..." }),
|
|
7437
|
-
d && /* @__PURE__ */
|
|
7442
|
+
d && /* @__PURE__ */ q("div", { className: "error-overlay", style: {
|
|
7438
7443
|
position: "absolute",
|
|
7439
7444
|
top: "50%",
|
|
7440
7445
|
left: "50%",
|
|
@@ -7448,11 +7453,11 @@ const pt = Me(({
|
|
|
7448
7453
|
}, children: d })
|
|
7449
7454
|
] });
|
|
7450
7455
|
});
|
|
7451
|
-
|
|
7452
|
-
async function
|
|
7456
|
+
gt.displayName = "TalkingHeadComponent";
|
|
7457
|
+
async function Ge(G) {
|
|
7453
7458
|
try {
|
|
7454
|
-
console.log(`📥 Loading animation manifest from: ${
|
|
7455
|
-
const t = await fetch(
|
|
7459
|
+
console.log(`📥 Loading animation manifest from: ${G}`);
|
|
7460
|
+
const t = await fetch(G);
|
|
7456
7461
|
if (!t.ok)
|
|
7457
7462
|
throw new Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);
|
|
7458
7463
|
const e = await t.json();
|
|
@@ -7467,8 +7472,8 @@ async function gt(V) {
|
|
|
7467
7472
|
return console.error("❌ Failed to load animation manifest:", t), {};
|
|
7468
7473
|
}
|
|
7469
7474
|
}
|
|
7470
|
-
const yt =
|
|
7471
|
-
text:
|
|
7475
|
+
const yt = Fe(({
|
|
7476
|
+
text: G = null,
|
|
7472
7477
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7473
7478
|
avatarBody: e = "F",
|
|
7474
7479
|
mood: n = "neutral",
|
|
@@ -7476,253 +7481,253 @@ const yt = Me(({
|
|
|
7476
7481
|
ttsService: s = null,
|
|
7477
7482
|
ttsVoice: o = null,
|
|
7478
7483
|
ttsApiKey: l = null,
|
|
7479
|
-
bodyMovement:
|
|
7484
|
+
bodyMovement: c = "idle",
|
|
7480
7485
|
movementIntensity: r = 0.5,
|
|
7481
7486
|
showFullAvatar: u = !1,
|
|
7482
7487
|
cameraView: a = "upper",
|
|
7483
7488
|
onReady: d = () => {
|
|
7484
7489
|
},
|
|
7485
|
-
onLoading:
|
|
7490
|
+
onLoading: h = () => {
|
|
7486
7491
|
},
|
|
7487
7492
|
onError: g = () => {
|
|
7488
7493
|
},
|
|
7489
|
-
onSpeechEnd:
|
|
7494
|
+
onSpeechEnd: b = () => {
|
|
7490
7495
|
},
|
|
7491
7496
|
className: f = "",
|
|
7492
|
-
style:
|
|
7493
|
-
animations:
|
|
7497
|
+
style: w = {},
|
|
7498
|
+
animations: N = {},
|
|
7494
7499
|
autoAnimationGroup: p = null,
|
|
7495
7500
|
// e.g., "talking" - will randomly select from this group when speaking
|
|
7496
7501
|
autoIdleGroup: B = null,
|
|
7497
7502
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7498
|
-
autoSpeak:
|
|
7499
|
-
},
|
|
7500
|
-
const
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
}, [
|
|
7503
|
+
autoSpeak: F = !1
|
|
7504
|
+
}, I) => {
|
|
7505
|
+
const D = X(null), x = X(null), k = X(u), A = X(null), L = X(null), T = X(!1), M = X({ remainingText: null, originalText: null, options: null }), j = X([]), [Z, ue] = ae(!0), [re, ge] = ae(null), [ne, ve] = ae(!1), [_, v] = ae(!1), [R, P] = ae(N), O = X(null);
|
|
7506
|
+
me(() => {
|
|
7507
|
+
T.current = _;
|
|
7508
|
+
}, [_]), me(() => {
|
|
7504
7509
|
(async () => {
|
|
7505
|
-
if (
|
|
7510
|
+
if (N.manifest)
|
|
7506
7511
|
try {
|
|
7507
|
-
console.log("🔄 Loading animations from manifest:",
|
|
7508
|
-
const H = await
|
|
7509
|
-
|
|
7512
|
+
console.log("🔄 Loading animations from manifest:", N.manifest);
|
|
7513
|
+
const H = await Ge(N.manifest);
|
|
7514
|
+
P(H), console.log("✅ Animations loaded and set:", H), H._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
|
|
7510
7515
|
male: Object.keys(H._genderSpecific.male || {}),
|
|
7511
7516
|
female: Object.keys(H._genderSpecific.female || {}),
|
|
7512
7517
|
shared: Object.keys(H._genderSpecific.shared || {})
|
|
7513
7518
|
}) : console.log("⚠️ No gender-specific animations found in manifest");
|
|
7514
7519
|
} catch (H) {
|
|
7515
|
-
console.error("❌ Failed to load animation manifest:", H),
|
|
7520
|
+
console.error("❌ Failed to load animation manifest:", H), P(N);
|
|
7516
7521
|
}
|
|
7517
7522
|
else
|
|
7518
|
-
console.log("📝 Using animations from props (no manifest):",
|
|
7523
|
+
console.log("📝 Using animations from props (no manifest):", N), P(N);
|
|
7519
7524
|
})();
|
|
7520
|
-
}, [
|
|
7521
|
-
|
|
7525
|
+
}, [N]), me(() => {
|
|
7526
|
+
k.current = u;
|
|
7522
7527
|
}, [u]);
|
|
7523
|
-
const
|
|
7524
|
-
let
|
|
7525
|
-
|
|
7528
|
+
const W = Pe(), ie = s || W.service;
|
|
7529
|
+
let K;
|
|
7530
|
+
ie === "browser" ? K = {
|
|
7526
7531
|
service: "browser",
|
|
7527
7532
|
endpoint: "",
|
|
7528
7533
|
apiKey: null,
|
|
7529
7534
|
defaultVoice: "Google US English"
|
|
7530
|
-
} :
|
|
7535
|
+
} : ie === "elevenlabs" ? K = {
|
|
7531
7536
|
service: "elevenlabs",
|
|
7532
7537
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7533
|
-
apiKey: l ||
|
|
7534
|
-
defaultVoice: o ||
|
|
7535
|
-
voices:
|
|
7536
|
-
} :
|
|
7538
|
+
apiKey: l || W.apiKey,
|
|
7539
|
+
defaultVoice: o || W.defaultVoice || Ae.defaultVoice,
|
|
7540
|
+
voices: W.voices || Ae.voices
|
|
7541
|
+
} : ie === "deepgram" ? K = {
|
|
7537
7542
|
service: "deepgram",
|
|
7538
7543
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7539
|
-
apiKey: l ||
|
|
7540
|
-
defaultVoice: o ||
|
|
7541
|
-
voices:
|
|
7542
|
-
} :
|
|
7543
|
-
...
|
|
7544
|
-
apiKey: l !== null ? l :
|
|
7544
|
+
apiKey: l || W.apiKey,
|
|
7545
|
+
defaultVoice: o || W.defaultVoice || Me.defaultVoice,
|
|
7546
|
+
voices: W.voices || Me.voices
|
|
7547
|
+
} : K = {
|
|
7548
|
+
...W,
|
|
7549
|
+
apiKey: l !== null ? l : W.apiKey
|
|
7545
7550
|
};
|
|
7546
|
-
const
|
|
7551
|
+
const J = {
|
|
7547
7552
|
url: t,
|
|
7548
7553
|
body: e,
|
|
7549
7554
|
avatarMood: n,
|
|
7550
|
-
ttsLang:
|
|
7551
|
-
ttsVoice: o ||
|
|
7555
|
+
ttsLang: ie === "browser" ? "en-US" : i,
|
|
7556
|
+
ttsVoice: o || K.defaultVoice,
|
|
7552
7557
|
lipsyncLang: "en",
|
|
7553
7558
|
showFullAvatar: u,
|
|
7554
|
-
bodyMovement:
|
|
7559
|
+
bodyMovement: c,
|
|
7555
7560
|
movementIntensity: r
|
|
7556
|
-
},
|
|
7557
|
-
ttsEndpoint:
|
|
7558
|
-
ttsApikey:
|
|
7559
|
-
ttsService:
|
|
7561
|
+
}, Le = {
|
|
7562
|
+
ttsEndpoint: K.endpoint,
|
|
7563
|
+
ttsApikey: K.apiKey,
|
|
7564
|
+
ttsService: ie,
|
|
7560
7565
|
lipsyncModules: ["en"],
|
|
7561
7566
|
cameraView: a
|
|
7562
|
-
},
|
|
7563
|
-
if (!(!
|
|
7567
|
+
}, ke = U(async () => {
|
|
7568
|
+
if (!(!D.current || x.current))
|
|
7564
7569
|
try {
|
|
7565
|
-
|
|
7566
|
-
url:
|
|
7567
|
-
body:
|
|
7568
|
-
avatarMood:
|
|
7569
|
-
}), await
|
|
7570
|
+
ue(!0), ge(null), x.current = new Be(D.current, Le), console.log("Avatar config being passed:", {
|
|
7571
|
+
url: J.url,
|
|
7572
|
+
body: J.body,
|
|
7573
|
+
avatarMood: J.avatarMood
|
|
7574
|
+
}), await x.current.showAvatar(J, (H) => {
|
|
7570
7575
|
if (H.lengthComputable) {
|
|
7571
|
-
const
|
|
7572
|
-
|
|
7576
|
+
const Y = Math.min(100, Math.round(H.loaded / H.total * 100));
|
|
7577
|
+
h(Y);
|
|
7573
7578
|
}
|
|
7574
|
-
}),
|
|
7575
|
-
const
|
|
7576
|
-
document.visibilityState === "visible" ?
|
|
7579
|
+
}), x.current?.avatar && console.log("Avatar body after initialization:", x.current.avatar.body), ue(!1), ve(!0), d(x.current);
|
|
7580
|
+
const S = () => {
|
|
7581
|
+
document.visibilityState === "visible" ? x.current?.start() : x.current?.stop();
|
|
7577
7582
|
};
|
|
7578
|
-
return document.addEventListener("visibilitychange",
|
|
7579
|
-
document.removeEventListener("visibilitychange",
|
|
7583
|
+
return document.addEventListener("visibilitychange", S), () => {
|
|
7584
|
+
document.removeEventListener("visibilitychange", S);
|
|
7580
7585
|
};
|
|
7581
|
-
} catch (
|
|
7582
|
-
console.error("Error initializing TalkingHead:",
|
|
7586
|
+
} catch (S) {
|
|
7587
|
+
console.error("Error initializing TalkingHead:", S), ge(S.message || "Failed to initialize avatar"), ue(!1), g(S);
|
|
7583
7588
|
}
|
|
7584
7589
|
}, []);
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
}), [
|
|
7588
|
-
const
|
|
7589
|
-
if (
|
|
7590
|
+
me(() => (ke(), () => {
|
|
7591
|
+
x.current && (x.current.stop(), x.current.dispose(), x.current = null);
|
|
7592
|
+
}), [ke]);
|
|
7593
|
+
const Se = U(async () => {
|
|
7594
|
+
if (x.current)
|
|
7590
7595
|
try {
|
|
7591
|
-
const
|
|
7592
|
-
|
|
7593
|
-
} catch (
|
|
7594
|
-
console.warn("Failed to resume audio context:",
|
|
7596
|
+
const S = x.current.audioCtx || x.current.audioContext;
|
|
7597
|
+
S && (S.state === "suspended" || S.state === "interrupted") && (await S.resume(), console.log("Audio context resumed"));
|
|
7598
|
+
} catch (S) {
|
|
7599
|
+
console.warn("Failed to resume audio context:", S);
|
|
7595
7600
|
}
|
|
7596
|
-
}, []),
|
|
7597
|
-
if (!
|
|
7601
|
+
}, []), we = U((S) => {
|
|
7602
|
+
if (!R)
|
|
7598
7603
|
return console.warn("No animations loaded"), null;
|
|
7599
7604
|
let H = null;
|
|
7600
|
-
if (
|
|
7601
|
-
const
|
|
7602
|
-
|
|
7605
|
+
if (R._genderSpecific) {
|
|
7606
|
+
const ee = (e?.toUpperCase() || "F") === "M" ? "male" : "female", se = R._genderSpecific[ee];
|
|
7607
|
+
se && se[S] ? (H = se[S], console.log(`Using ${ee} animations for "${S}":`, H)) : R._genderSpecific.shared && R._genderSpecific.shared[S] && (H = R._genderSpecific.shared[S], console.log(`Using shared animations for "${S}":`, H));
|
|
7603
7608
|
}
|
|
7604
|
-
if (!H &&
|
|
7605
|
-
if (console.warn(`Animation group "${
|
|
7606
|
-
const
|
|
7607
|
-
console.warn(`Gender-specific groups (${
|
|
7609
|
+
if (!H && R[S] && (H = R[S], console.log(`Using root-level animations for "${S}":`, H)), !H) {
|
|
7610
|
+
if (console.warn(`Animation group "${S}" not found. Available groups:`, Object.keys(R).filter((Y) => Y !== "_genderSpecific")), R._genderSpecific) {
|
|
7611
|
+
const ee = (e?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
7612
|
+
console.warn(`Gender-specific groups (${ee}):`, Object.keys(R._genderSpecific[ee] || {}));
|
|
7608
7613
|
}
|
|
7609
7614
|
return null;
|
|
7610
7615
|
}
|
|
7611
7616
|
if (Array.isArray(H) && H.length > 0) {
|
|
7612
|
-
const
|
|
7613
|
-
return H[
|
|
7617
|
+
const Y = Math.floor(Math.random() * H.length);
|
|
7618
|
+
return H[Y];
|
|
7614
7619
|
}
|
|
7615
|
-
return typeof H == "string" ? H : (console.warn(`Animation group "${
|
|
7616
|
-
}, [
|
|
7617
|
-
if (!
|
|
7620
|
+
return typeof H == "string" ? H : (console.warn(`Animation group "${S}" is not a valid format (expected array or string):`, H), null);
|
|
7621
|
+
}, [R, e]), C = U((S, H = !1) => {
|
|
7622
|
+
if (!x.current)
|
|
7618
7623
|
return console.warn("TalkingHead not initialized yet"), null;
|
|
7619
|
-
const
|
|
7620
|
-
if (
|
|
7624
|
+
const Y = we(S);
|
|
7625
|
+
if (Y)
|
|
7621
7626
|
try {
|
|
7622
|
-
return
|
|
7623
|
-
} catch (
|
|
7624
|
-
return console.error(`❌ Failed to play random animation from "${
|
|
7627
|
+
return x.current.playAnimation(Y, null, 10, 0, 0.01, H), console.log(`✅ Playing random animation from "${S}" group:`, Y), Y;
|
|
7628
|
+
} catch (ee) {
|
|
7629
|
+
return console.error(`❌ Failed to play random animation from "${S}" group:`, ee), null;
|
|
7625
7630
|
}
|
|
7626
7631
|
else
|
|
7627
|
-
console.warn(`⚠️ No animation found for group "${
|
|
7632
|
+
console.warn(`⚠️ No animation found for group "${S}"`);
|
|
7628
7633
|
return null;
|
|
7629
|
-
}, [
|
|
7630
|
-
if (!
|
|
7634
|
+
}, [we]), V = U(async (S, H = {}) => {
|
|
7635
|
+
if (!x.current || !ne) {
|
|
7631
7636
|
console.warn("Avatar not ready for speaking");
|
|
7632
7637
|
return;
|
|
7633
7638
|
}
|
|
7634
|
-
if (!
|
|
7639
|
+
if (!S || S.trim() === "") {
|
|
7635
7640
|
console.warn("No text provided to speak");
|
|
7636
7641
|
return;
|
|
7637
7642
|
}
|
|
7638
|
-
await
|
|
7639
|
-
const
|
|
7640
|
-
|
|
7641
|
-
const
|
|
7642
|
-
|
|
7643
|
-
const
|
|
7643
|
+
await Se();
|
|
7644
|
+
const Y = H.animationGroup || p;
|
|
7645
|
+
Y && !H.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${Y}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, R), C(Y)) : console.log(`⏭️ Skipping animation (group: ${Y}, skipAnimation: ${H.skipAnimation})`), M.current = { remainingText: null, originalText: null, options: null }, j.current = [], A.current = { text: S, options: H }, L.current && (clearInterval(L.current), L.current = null), v(!1), T.current = !1;
|
|
7646
|
+
const ee = S.split(/[.!?]+/).filter((le) => le.trim().length > 0);
|
|
7647
|
+
j.current = ee;
|
|
7648
|
+
const se = {
|
|
7644
7649
|
lipsyncLang: H.lipsyncLang || "en",
|
|
7645
7650
|
onSpeechEnd: () => {
|
|
7646
|
-
|
|
7651
|
+
L.current && (clearInterval(L.current), L.current = null), H.onSpeechEnd && H.onSpeechEnd(), b();
|
|
7647
7652
|
}
|
|
7648
7653
|
};
|
|
7649
7654
|
try {
|
|
7650
|
-
|
|
7651
|
-
} catch (
|
|
7652
|
-
console.error("Error speaking text:",
|
|
7655
|
+
x.current.speakText(S, se);
|
|
7656
|
+
} catch (le) {
|
|
7657
|
+
console.error("Error speaking text:", le), ge(le.message || "Failed to speak text");
|
|
7653
7658
|
}
|
|
7654
|
-
}, [
|
|
7655
|
-
|
|
7656
|
-
if (!
|
|
7659
|
+
}, [ne, b, Se, p, C]);
|
|
7660
|
+
me(() => {
|
|
7661
|
+
if (!ne || !B || !x.current)
|
|
7657
7662
|
return;
|
|
7658
|
-
|
|
7659
|
-
const
|
|
7660
|
-
|
|
7663
|
+
O.current && clearInterval(O.current);
|
|
7664
|
+
const S = () => {
|
|
7665
|
+
x.current && !T.current && C(B);
|
|
7661
7666
|
};
|
|
7662
|
-
return
|
|
7663
|
-
|
|
7667
|
+
return S(), O.current = setInterval(() => {
|
|
7668
|
+
S();
|
|
7664
7669
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7665
|
-
|
|
7670
|
+
O.current && (clearInterval(O.current), O.current = null);
|
|
7666
7671
|
};
|
|
7667
|
-
}, [
|
|
7668
|
-
|
|
7669
|
-
}, [
|
|
7670
|
-
const
|
|
7671
|
-
if (
|
|
7672
|
+
}, [ne, B, C]), me(() => {
|
|
7673
|
+
ne && G && F && x.current && V(G);
|
|
7674
|
+
}, [ne, G, F, V]);
|
|
7675
|
+
const $ = U(() => {
|
|
7676
|
+
if (x.current)
|
|
7672
7677
|
try {
|
|
7673
|
-
const
|
|
7674
|
-
if (
|
|
7675
|
-
|
|
7676
|
-
let
|
|
7677
|
-
|
|
7678
|
-
remainingText:
|
|
7679
|
-
originalText:
|
|
7680
|
-
options:
|
|
7681
|
-
},
|
|
7678
|
+
const S = x.current.isSpeaking || !1, H = x.current.audioPlaylist || [], Y = x.current.speechQueue || [];
|
|
7679
|
+
if (S || H.length > 0 || Y.length > 0) {
|
|
7680
|
+
L.current && (clearInterval(L.current), L.current = null);
|
|
7681
|
+
let ee = "";
|
|
7682
|
+
Y.length > 0 && (ee = Y.map((se) => se.text && Array.isArray(se.text) ? se.text.map((le) => le.word).join(" ") : se.text || "").join(" ")), M.current = {
|
|
7683
|
+
remainingText: ee || null,
|
|
7684
|
+
originalText: A.current?.text || null,
|
|
7685
|
+
options: A.current?.options || null
|
|
7686
|
+
}, x.current.speechQueue.length = 0, x.current.pauseSpeaking(), v(!0), T.current = !0;
|
|
7682
7687
|
}
|
|
7683
|
-
} catch (
|
|
7684
|
-
console.warn("Error pausing speech:",
|
|
7688
|
+
} catch (S) {
|
|
7689
|
+
console.warn("Error pausing speech:", S);
|
|
7685
7690
|
}
|
|
7686
|
-
}, []),
|
|
7687
|
-
if (!(!
|
|
7691
|
+
}, []), oe = U(async () => {
|
|
7692
|
+
if (!(!x.current || !_))
|
|
7688
7693
|
try {
|
|
7689
|
-
await
|
|
7690
|
-
const
|
|
7691
|
-
|
|
7692
|
-
} catch (
|
|
7693
|
-
console.warn("Error resuming speech:",
|
|
7694
|
+
await Se(), v(!1), T.current = !1;
|
|
7695
|
+
const S = M.current?.remainingText, H = M.current?.originalText || A.current?.text, Y = M.current?.options || A.current?.options || {}, ee = S || H;
|
|
7696
|
+
ee && V(ee, Y);
|
|
7697
|
+
} catch (S) {
|
|
7698
|
+
console.warn("Error resuming speech:", S), v(!1), T.current = !1;
|
|
7694
7699
|
}
|
|
7695
|
-
}, [
|
|
7696
|
-
|
|
7700
|
+
}, [_, V, Se]), ye = U(() => {
|
|
7701
|
+
x.current && (x.current.stopSpeaking(), L.current && (clearInterval(L.current), L.current = null), v(!1), T.current = !1);
|
|
7697
7702
|
}, []);
|
|
7698
|
-
return
|
|
7699
|
-
speakText:
|
|
7700
|
-
pauseSpeaking:
|
|
7701
|
-
resumeSpeaking:
|
|
7702
|
-
stopSpeaking:
|
|
7703
|
-
resumeAudioContext:
|
|
7704
|
-
isPaused: () =>
|
|
7705
|
-
setMood: (
|
|
7706
|
-
setBodyMovement: (
|
|
7707
|
-
|
|
7703
|
+
return Ee(I, () => ({
|
|
7704
|
+
speakText: V,
|
|
7705
|
+
pauseSpeaking: $,
|
|
7706
|
+
resumeSpeaking: oe,
|
|
7707
|
+
stopSpeaking: ye,
|
|
7708
|
+
resumeAudioContext: Se,
|
|
7709
|
+
isPaused: () => _,
|
|
7710
|
+
setMood: (S) => x.current?.setMood(S),
|
|
7711
|
+
setBodyMovement: (S) => {
|
|
7712
|
+
x.current && x.current.setBodyMovement(S);
|
|
7708
7713
|
},
|
|
7709
|
-
playAnimation: (
|
|
7710
|
-
|
|
7714
|
+
playAnimation: (S, H = !1) => {
|
|
7715
|
+
x.current && x.current.playAnimation && x.current.playAnimation(S, null, 10, 0, 0.01, H);
|
|
7711
7716
|
},
|
|
7712
|
-
playRandomAnimation: (
|
|
7713
|
-
getRandomAnimation: (
|
|
7714
|
-
playReaction: (
|
|
7715
|
-
playCelebration: () =>
|
|
7716
|
-
setShowFullAvatar: (
|
|
7717
|
-
|
|
7717
|
+
playRandomAnimation: (S, H = !1) => C(S, H),
|
|
7718
|
+
getRandomAnimation: (S) => we(S),
|
|
7719
|
+
playReaction: (S) => x.current?.playReaction(S),
|
|
7720
|
+
playCelebration: () => x.current?.playCelebration(),
|
|
7721
|
+
setShowFullAvatar: (S) => {
|
|
7722
|
+
x.current && (k.current = S, x.current.setShowFullAvatar(S));
|
|
7718
7723
|
},
|
|
7719
|
-
isReady:
|
|
7720
|
-
talkingHead:
|
|
7721
|
-
})), /* @__PURE__ */
|
|
7722
|
-
/* @__PURE__ */
|
|
7724
|
+
isReady: ne,
|
|
7725
|
+
talkingHead: x.current
|
|
7726
|
+
})), /* @__PURE__ */ fe("div", { className: `simple-talking-avatar-container ${f}`, style: w, children: [
|
|
7727
|
+
/* @__PURE__ */ q(
|
|
7723
7728
|
"div",
|
|
7724
7729
|
{
|
|
7725
|
-
ref:
|
|
7730
|
+
ref: D,
|
|
7726
7731
|
className: "talking-head-viewer",
|
|
7727
7732
|
style: {
|
|
7728
7733
|
width: "100%",
|
|
@@ -7731,7 +7736,7 @@ const yt = Me(({
|
|
|
7731
7736
|
}
|
|
7732
7737
|
}
|
|
7733
7738
|
),
|
|
7734
|
-
|
|
7739
|
+
Z && /* @__PURE__ */ q("div", { className: "loading-overlay", style: {
|
|
7735
7740
|
position: "absolute",
|
|
7736
7741
|
top: "50%",
|
|
7737
7742
|
left: "50%",
|
|
@@ -7740,7 +7745,7 @@ const yt = Me(({
|
|
|
7740
7745
|
fontSize: "18px",
|
|
7741
7746
|
zIndex: 10
|
|
7742
7747
|
}, children: "Loading avatar..." }),
|
|
7743
|
-
|
|
7748
|
+
re && /* @__PURE__ */ q("div", { className: "error-overlay", style: {
|
|
7744
7749
|
position: "absolute",
|
|
7745
7750
|
top: "50%",
|
|
7746
7751
|
left: "50%",
|
|
@@ -7751,12 +7756,12 @@ const yt = Me(({
|
|
|
7751
7756
|
zIndex: 10,
|
|
7752
7757
|
padding: "20px",
|
|
7753
7758
|
borderRadius: "8px"
|
|
7754
|
-
}, children:
|
|
7759
|
+
}, children: re })
|
|
7755
7760
|
] });
|
|
7756
7761
|
});
|
|
7757
7762
|
yt.displayName = "SimpleTalkingAvatar";
|
|
7758
|
-
const ft =
|
|
7759
|
-
curriculumData:
|
|
7763
|
+
const ft = Fe(({
|
|
7764
|
+
curriculumData: G = null,
|
|
7760
7765
|
avatarConfig: t = {},
|
|
7761
7766
|
animations: e = {},
|
|
7762
7767
|
onLessonStart: n = () => {
|
|
@@ -7769,9 +7774,9 @@ const ft = Me(({
|
|
|
7769
7774
|
},
|
|
7770
7775
|
onCustomAction: l = () => {
|
|
7771
7776
|
},
|
|
7772
|
-
autoStart:
|
|
7777
|
+
autoStart: c = !1
|
|
7773
7778
|
}, r) => {
|
|
7774
|
-
const u =
|
|
7779
|
+
const u = X(null), a = X({
|
|
7775
7780
|
currentModuleIndex: 0,
|
|
7776
7781
|
currentLessonIndex: 0,
|
|
7777
7782
|
currentQuestionIndex: 0,
|
|
@@ -7781,18 +7786,18 @@ const ft = Me(({
|
|
|
7781
7786
|
curriculumCompleted: !1,
|
|
7782
7787
|
score: 0,
|
|
7783
7788
|
totalQuestions: 0
|
|
7784
|
-
}), d =
|
|
7789
|
+
}), d = X({
|
|
7785
7790
|
onLessonStart: n,
|
|
7786
7791
|
onLessonComplete: i,
|
|
7787
7792
|
onQuestionAnswer: s,
|
|
7788
7793
|
onCurriculumComplete: o,
|
|
7789
7794
|
onCustomAction: l
|
|
7790
|
-
}),
|
|
7795
|
+
}), h = X(null), g = X(null), b = X(null), f = X(null), w = X(null), N = X(null), p = X(null), B = X(G?.curriculum || {
|
|
7791
7796
|
title: "Default Curriculum",
|
|
7792
7797
|
description: "No curriculum data provided",
|
|
7793
7798
|
language: "en",
|
|
7794
7799
|
modules: []
|
|
7795
|
-
}),
|
|
7800
|
+
}), F = X({
|
|
7796
7801
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7797
7802
|
avatarBody: t.avatarBody || "F",
|
|
7798
7803
|
mood: t.mood || "happy",
|
|
@@ -7806,7 +7811,7 @@ const ft = Me(({
|
|
|
7806
7811
|
animations: e,
|
|
7807
7812
|
lipsyncLang: "en"
|
|
7808
7813
|
});
|
|
7809
|
-
|
|
7814
|
+
me(() => {
|
|
7810
7815
|
d.current = {
|
|
7811
7816
|
onLessonStart: n,
|
|
7812
7817
|
onLessonComplete: i,
|
|
@@ -7814,13 +7819,13 @@ const ft = Me(({
|
|
|
7814
7819
|
onCurriculumComplete: o,
|
|
7815
7820
|
onCustomAction: l
|
|
7816
7821
|
};
|
|
7817
|
-
}, [n, i, s, o, l]),
|
|
7818
|
-
B.current =
|
|
7822
|
+
}, [n, i, s, o, l]), me(() => {
|
|
7823
|
+
B.current = G?.curriculum || {
|
|
7819
7824
|
title: "Default Curriculum",
|
|
7820
7825
|
description: "No curriculum data provided",
|
|
7821
7826
|
language: "en",
|
|
7822
7827
|
modules: []
|
|
7823
|
-
},
|
|
7828
|
+
}, F.current = {
|
|
7824
7829
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7825
7830
|
avatarBody: t.avatarBody || "F",
|
|
7826
7831
|
mood: t.mood || "happy",
|
|
@@ -7834,24 +7839,24 @@ const ft = Me(({
|
|
|
7834
7839
|
animations: e,
|
|
7835
7840
|
lipsyncLang: "en"
|
|
7836
7841
|
};
|
|
7837
|
-
}, [
|
|
7838
|
-
const
|
|
7842
|
+
}, [G, t, e]);
|
|
7843
|
+
const I = U(() => (B.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), D = U(() => I()?.questions[a.current.currentQuestionIndex], [I]), x = U((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), k = U(() => {
|
|
7839
7844
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7840
|
-
const
|
|
7841
|
-
let
|
|
7842
|
-
if (a.current.totalQuestions > 0 ?
|
|
7845
|
+
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7846
|
+
let R = "Congratulations! You've completed this lesson";
|
|
7847
|
+
if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
|
|
7843
7848
|
moduleIndex: a.current.currentModuleIndex,
|
|
7844
7849
|
lessonIndex: a.current.currentLessonIndex,
|
|
7845
7850
|
score: a.current.score,
|
|
7846
7851
|
totalQuestions: a.current.totalQuestions,
|
|
7847
|
-
percentage:
|
|
7852
|
+
percentage: v
|
|
7848
7853
|
}), d.current.onCustomAction({
|
|
7849
7854
|
type: "lessonComplete",
|
|
7850
7855
|
moduleIndex: a.current.currentModuleIndex,
|
|
7851
7856
|
lessonIndex: a.current.currentLessonIndex,
|
|
7852
7857
|
score: a.current.score,
|
|
7853
7858
|
totalQuestions: a.current.totalQuestions,
|
|
7854
|
-
percentage:
|
|
7859
|
+
percentage: v
|
|
7855
7860
|
}), u.current) {
|
|
7856
7861
|
if (u.current.setMood("happy"), e.lessonComplete)
|
|
7857
7862
|
try {
|
|
@@ -7859,9 +7864,9 @@ const ft = Me(({
|
|
|
7859
7864
|
} catch {
|
|
7860
7865
|
u.current.playCelebration();
|
|
7861
7866
|
}
|
|
7862
|
-
const
|
|
7863
|
-
u.current.speakText(
|
|
7864
|
-
lipsyncLang:
|
|
7867
|
+
const P = B.current || { modules: [] }, O = P.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, ie = a.current.currentModuleIndex < (P.modules?.length || 0) - 1, K = W || ie, J = F.current || { lipsyncLang: "en" };
|
|
7868
|
+
u.current.speakText(R, {
|
|
7869
|
+
lipsyncLang: J.lipsyncLang,
|
|
7865
7870
|
onSpeechEnd: () => {
|
|
7866
7871
|
d.current.onCustomAction({
|
|
7867
7872
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7869,18 +7874,18 @@ const ft = Me(({
|
|
|
7869
7874
|
lessonIndex: a.current.currentLessonIndex,
|
|
7870
7875
|
score: a.current.score,
|
|
7871
7876
|
totalQuestions: a.current.totalQuestions,
|
|
7872
|
-
percentage:
|
|
7873
|
-
hasNextLesson:
|
|
7877
|
+
percentage: v,
|
|
7878
|
+
hasNextLesson: K
|
|
7874
7879
|
});
|
|
7875
7880
|
}
|
|
7876
7881
|
});
|
|
7877
7882
|
}
|
|
7878
|
-
}, [e.lessonComplete]),
|
|
7883
|
+
}, [e.lessonComplete]), A = U(() => {
|
|
7879
7884
|
a.current.curriculumCompleted = !0;
|
|
7880
|
-
const
|
|
7885
|
+
const v = B.current || { modules: [] };
|
|
7881
7886
|
if (d.current.onCurriculumComplete({
|
|
7882
|
-
modules:
|
|
7883
|
-
totalLessons:
|
|
7887
|
+
modules: v.modules.length,
|
|
7888
|
+
totalLessons: v.modules.reduce((R, P) => R + P.lessons.length, 0)
|
|
7884
7889
|
}), u.current) {
|
|
7885
7890
|
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7886
7891
|
try {
|
|
@@ -7888,99 +7893,99 @@ const ft = Me(({
|
|
|
7888
7893
|
} catch {
|
|
7889
7894
|
u.current.playCelebration();
|
|
7890
7895
|
}
|
|
7891
|
-
const
|
|
7892
|
-
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang:
|
|
7896
|
+
const R = F.current || { lipsyncLang: "en" };
|
|
7897
|
+
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
|
|
7893
7898
|
}
|
|
7894
|
-
}, [e.curriculumComplete]),
|
|
7895
|
-
const
|
|
7896
|
-
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions =
|
|
7897
|
-
const
|
|
7898
|
-
|
|
7899
|
+
}, [e.curriculumComplete]), L = U(() => {
|
|
7900
|
+
const v = I();
|
|
7901
|
+
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7902
|
+
const R = D();
|
|
7903
|
+
R && d.current.onCustomAction({
|
|
7899
7904
|
type: "questionStart",
|
|
7900
7905
|
moduleIndex: a.current.currentModuleIndex,
|
|
7901
7906
|
lessonIndex: a.current.currentLessonIndex,
|
|
7902
7907
|
questionIndex: a.current.currentQuestionIndex,
|
|
7903
7908
|
totalQuestions: a.current.totalQuestions,
|
|
7904
|
-
question:
|
|
7909
|
+
question: R,
|
|
7905
7910
|
score: a.current.score
|
|
7906
7911
|
});
|
|
7907
|
-
const
|
|
7908
|
-
if (!u.current || !
|
|
7912
|
+
const P = () => {
|
|
7913
|
+
if (!u.current || !R) return;
|
|
7909
7914
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7910
7915
|
try {
|
|
7911
7916
|
u.current.playAnimation(e.questionStart, !0);
|
|
7912
|
-
} catch (
|
|
7913
|
-
console.warn("Failed to play questionStart animation:",
|
|
7917
|
+
} catch (W) {
|
|
7918
|
+
console.warn("Failed to play questionStart animation:", W);
|
|
7914
7919
|
}
|
|
7915
|
-
const
|
|
7916
|
-
|
|
7920
|
+
const O = F.current || { lipsyncLang: "en" };
|
|
7921
|
+
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: O.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: O.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: O.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: O.lipsyncLang });
|
|
7917
7922
|
};
|
|
7918
|
-
if (u.current && u.current.isReady &&
|
|
7919
|
-
|
|
7923
|
+
if (u.current && u.current.isReady && R)
|
|
7924
|
+
P();
|
|
7920
7925
|
else if (u.current && u.current.isReady) {
|
|
7921
|
-
const
|
|
7922
|
-
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang:
|
|
7926
|
+
const O = F.current || { lipsyncLang: "en" };
|
|
7927
|
+
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: O.lipsyncLang });
|
|
7923
7928
|
} else {
|
|
7924
|
-
const
|
|
7925
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7929
|
+
const O = setInterval(() => {
|
|
7930
|
+
u.current && u.current.isReady && (clearInterval(O), R && P());
|
|
7926
7931
|
}, 100);
|
|
7927
7932
|
setTimeout(() => {
|
|
7928
|
-
clearInterval(
|
|
7933
|
+
clearInterval(O);
|
|
7929
7934
|
}, 5e3);
|
|
7930
7935
|
}
|
|
7931
|
-
}, [e.questionStart,
|
|
7932
|
-
const
|
|
7933
|
-
if (a.current.currentQuestionIndex < (
|
|
7936
|
+
}, [e.questionStart, I, D]), T = U(() => {
|
|
7937
|
+
const v = I();
|
|
7938
|
+
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7934
7939
|
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7935
|
-
const
|
|
7936
|
-
|
|
7940
|
+
const R = D();
|
|
7941
|
+
R && d.current.onCustomAction({
|
|
7937
7942
|
type: "nextQuestion",
|
|
7938
7943
|
moduleIndex: a.current.currentModuleIndex,
|
|
7939
7944
|
lessonIndex: a.current.currentLessonIndex,
|
|
7940
7945
|
questionIndex: a.current.currentQuestionIndex,
|
|
7941
7946
|
totalQuestions: a.current.totalQuestions,
|
|
7942
|
-
question:
|
|
7947
|
+
question: R,
|
|
7943
7948
|
score: a.current.score
|
|
7944
7949
|
});
|
|
7945
|
-
const
|
|
7946
|
-
if (!u.current || !
|
|
7950
|
+
const P = () => {
|
|
7951
|
+
if (!u.current || !R) return;
|
|
7947
7952
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7948
7953
|
try {
|
|
7949
7954
|
u.current.playAnimation(e.nextQuestion, !0);
|
|
7950
|
-
} catch (
|
|
7951
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7955
|
+
} catch (J) {
|
|
7956
|
+
console.warn("Failed to play nextQuestion animation:", J);
|
|
7952
7957
|
}
|
|
7953
|
-
const
|
|
7954
|
-
if (
|
|
7955
|
-
const
|
|
7956
|
-
u.current.speakText(
|
|
7957
|
-
lipsyncLang:
|
|
7958
|
+
const O = F.current || { lipsyncLang: "en" }, ie = I()?.questions?.length || 0, K = a.current.currentQuestionIndex >= ie - 1;
|
|
7959
|
+
if (R.type === "code_test") {
|
|
7960
|
+
const J = K ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7961
|
+
u.current.speakText(J, {
|
|
7962
|
+
lipsyncLang: O.lipsyncLang
|
|
7958
7963
|
});
|
|
7959
|
-
} else if (
|
|
7960
|
-
const
|
|
7961
|
-
u.current.speakText(
|
|
7962
|
-
lipsyncLang:
|
|
7964
|
+
} else if (R.type === "multiple_choice") {
|
|
7965
|
+
const J = K ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7966
|
+
u.current.speakText(J, {
|
|
7967
|
+
lipsyncLang: O.lipsyncLang
|
|
7963
7968
|
});
|
|
7964
|
-
} else if (
|
|
7965
|
-
const
|
|
7966
|
-
u.current.speakText(
|
|
7967
|
-
lipsyncLang:
|
|
7969
|
+
} else if (R.type === "true_false") {
|
|
7970
|
+
const J = K ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7971
|
+
u.current.speakText(J, {
|
|
7972
|
+
lipsyncLang: O.lipsyncLang
|
|
7968
7973
|
});
|
|
7969
7974
|
} else {
|
|
7970
|
-
const
|
|
7971
|
-
u.current.speakText(
|
|
7972
|
-
lipsyncLang:
|
|
7975
|
+
const J = K ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7976
|
+
u.current.speakText(J, {
|
|
7977
|
+
lipsyncLang: O.lipsyncLang
|
|
7973
7978
|
});
|
|
7974
7979
|
}
|
|
7975
7980
|
};
|
|
7976
|
-
if (u.current && u.current.isReady &&
|
|
7977
|
-
|
|
7978
|
-
else if (
|
|
7979
|
-
const
|
|
7980
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7981
|
+
if (u.current && u.current.isReady && R)
|
|
7982
|
+
P();
|
|
7983
|
+
else if (R) {
|
|
7984
|
+
const O = setInterval(() => {
|
|
7985
|
+
u.current && u.current.isReady && (clearInterval(O), P());
|
|
7981
7986
|
}, 100);
|
|
7982
7987
|
setTimeout(() => {
|
|
7983
|
-
clearInterval(
|
|
7988
|
+
clearInterval(O);
|
|
7984
7989
|
}, 5e3);
|
|
7985
7990
|
}
|
|
7986
7991
|
} else
|
|
@@ -7991,94 +7996,94 @@ const ft = Me(({
|
|
|
7991
7996
|
totalQuestions: a.current.totalQuestions,
|
|
7992
7997
|
score: a.current.score
|
|
7993
7998
|
});
|
|
7994
|
-
}, [e.nextQuestion,
|
|
7995
|
-
const
|
|
7996
|
-
if (a.current.currentLessonIndex < (
|
|
7999
|
+
}, [e.nextQuestion, I, D]), M = U(() => {
|
|
8000
|
+
const v = B.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
8001
|
+
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7997
8002
|
a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7998
|
-
const
|
|
8003
|
+
const O = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, ie = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, K = W || ie;
|
|
7999
8004
|
d.current.onCustomAction({
|
|
8000
8005
|
type: "lessonStart",
|
|
8001
8006
|
moduleIndex: a.current.currentModuleIndex,
|
|
8002
8007
|
lessonIndex: a.current.currentLessonIndex,
|
|
8003
|
-
hasNextLesson:
|
|
8008
|
+
hasNextLesson: K
|
|
8004
8009
|
}), d.current.onLessonStart({
|
|
8005
8010
|
moduleIndex: a.current.currentModuleIndex,
|
|
8006
8011
|
lessonIndex: a.current.currentLessonIndex,
|
|
8007
|
-
lesson:
|
|
8012
|
+
lesson: I()
|
|
8008
8013
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8009
|
-
} else if (a.current.currentModuleIndex < (
|
|
8014
|
+
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
8010
8015
|
a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
8011
|
-
const
|
|
8016
|
+
const W = v.modules[a.current.currentModuleIndex], ie = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, J = ie || K;
|
|
8012
8017
|
d.current.onCustomAction({
|
|
8013
8018
|
type: "lessonStart",
|
|
8014
8019
|
moduleIndex: a.current.currentModuleIndex,
|
|
8015
8020
|
lessonIndex: a.current.currentLessonIndex,
|
|
8016
|
-
hasNextLesson:
|
|
8021
|
+
hasNextLesson: J
|
|
8017
8022
|
}), d.current.onLessonStart({
|
|
8018
8023
|
moduleIndex: a.current.currentModuleIndex,
|
|
8019
8024
|
lessonIndex: a.current.currentLessonIndex,
|
|
8020
|
-
lesson:
|
|
8025
|
+
lesson: I()
|
|
8021
8026
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8022
8027
|
} else
|
|
8023
|
-
|
|
8024
|
-
}, []),
|
|
8025
|
-
const
|
|
8026
|
-
let
|
|
8027
|
-
if (
|
|
8028
|
-
const
|
|
8029
|
-
|
|
8028
|
+
w.current && w.current();
|
|
8029
|
+
}, []), j = U(() => {
|
|
8030
|
+
const v = I();
|
|
8031
|
+
let R = null;
|
|
8032
|
+
if (v?.avatar_script && v?.body) {
|
|
8033
|
+
const P = v.avatar_script.trim(), O = v.body.trim(), W = P.match(/[.!?]$/) ? " " : ". ";
|
|
8034
|
+
R = `${P}${W}${O}`;
|
|
8030
8035
|
} else
|
|
8031
|
-
|
|
8032
|
-
if (u.current && u.current.isReady &&
|
|
8036
|
+
R = v?.avatar_script || v?.body || null;
|
|
8037
|
+
if (u.current && u.current.isReady && R) {
|
|
8033
8038
|
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
8034
|
-
let
|
|
8039
|
+
let P = !1;
|
|
8035
8040
|
if (e.teaching)
|
|
8036
8041
|
try {
|
|
8037
|
-
u.current.playAnimation(e.teaching, !0),
|
|
8038
|
-
} catch (
|
|
8039
|
-
console.warn("Failed to play teaching animation:",
|
|
8042
|
+
u.current.playAnimation(e.teaching, !0), P = !0;
|
|
8043
|
+
} catch (W) {
|
|
8044
|
+
console.warn("Failed to play teaching animation:", W);
|
|
8040
8045
|
}
|
|
8041
|
-
|
|
8042
|
-
const
|
|
8046
|
+
P || u.current.setBodyMovement("gesturing");
|
|
8047
|
+
const O = F.current || { lipsyncLang: "en" };
|
|
8043
8048
|
d.current.onLessonStart({
|
|
8044
8049
|
moduleIndex: a.current.currentModuleIndex,
|
|
8045
8050
|
lessonIndex: a.current.currentLessonIndex,
|
|
8046
|
-
lesson:
|
|
8051
|
+
lesson: v
|
|
8047
8052
|
}), d.current.onCustomAction({
|
|
8048
8053
|
type: "teachingStart",
|
|
8049
8054
|
moduleIndex: a.current.currentModuleIndex,
|
|
8050
8055
|
lessonIndex: a.current.currentLessonIndex,
|
|
8051
|
-
lesson:
|
|
8052
|
-
}), u.current.speakText(
|
|
8053
|
-
lipsyncLang:
|
|
8056
|
+
lesson: v
|
|
8057
|
+
}), u.current.speakText(R, {
|
|
8058
|
+
lipsyncLang: O.lipsyncLang,
|
|
8054
8059
|
onSpeechEnd: () => {
|
|
8055
8060
|
a.current.isTeaching = !1, d.current.onCustomAction({
|
|
8056
8061
|
type: "teachingComplete",
|
|
8057
8062
|
moduleIndex: a.current.currentModuleIndex,
|
|
8058
8063
|
lessonIndex: a.current.currentLessonIndex,
|
|
8059
|
-
lesson:
|
|
8060
|
-
hasQuestions:
|
|
8061
|
-
}),
|
|
8064
|
+
lesson: v,
|
|
8065
|
+
hasQuestions: v.questions && v.questions.length > 0
|
|
8066
|
+
}), v?.code_example && d.current.onCustomAction({
|
|
8062
8067
|
type: "codeExampleReady",
|
|
8063
8068
|
moduleIndex: a.current.currentModuleIndex,
|
|
8064
8069
|
lessonIndex: a.current.currentLessonIndex,
|
|
8065
|
-
lesson:
|
|
8066
|
-
codeExample:
|
|
8070
|
+
lesson: v,
|
|
8071
|
+
codeExample: v.code_example
|
|
8067
8072
|
});
|
|
8068
8073
|
}
|
|
8069
8074
|
});
|
|
8070
8075
|
}
|
|
8071
|
-
}, [e.teaching,
|
|
8072
|
-
const
|
|
8073
|
-
if (
|
|
8076
|
+
}, [e.teaching, I]), Z = U((v) => {
|
|
8077
|
+
const R = D(), P = x(v, R);
|
|
8078
|
+
if (P && (a.current.score += 1), d.current.onQuestionAnswer({
|
|
8074
8079
|
moduleIndex: a.current.currentModuleIndex,
|
|
8075
8080
|
lessonIndex: a.current.currentLessonIndex,
|
|
8076
8081
|
questionIndex: a.current.currentQuestionIndex,
|
|
8077
|
-
answer:
|
|
8078
|
-
isCorrect:
|
|
8079
|
-
question:
|
|
8082
|
+
answer: v,
|
|
8083
|
+
isCorrect: P,
|
|
8084
|
+
question: R
|
|
8080
8085
|
}), u.current)
|
|
8081
|
-
if (
|
|
8086
|
+
if (P) {
|
|
8082
8087
|
if (u.current.setMood("happy"), e.correct)
|
|
8083
8088
|
try {
|
|
8084
8089
|
u.current.playReaction("happy");
|
|
@@ -8086,13 +8091,13 @@ const ft = Me(({
|
|
|
8086
8091
|
u.current.setBodyMovement("happy");
|
|
8087
8092
|
}
|
|
8088
8093
|
u.current.setBodyMovement("gesturing");
|
|
8089
|
-
const
|
|
8090
|
-
a.current.currentQuestionIndex >=
|
|
8091
|
-
const
|
|
8092
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8093
|
-
const
|
|
8094
|
-
u.current.speakText(
|
|
8095
|
-
lipsyncLang:
|
|
8094
|
+
const W = I()?.questions?.length || 0;
|
|
8095
|
+
a.current.currentQuestionIndex >= W - 1;
|
|
8096
|
+
const ie = a.current.currentQuestionIndex < W - 1;
|
|
8097
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", ie);
|
|
8098
|
+
const K = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, J = F.current || { lipsyncLang: "en" };
|
|
8099
|
+
u.current.speakText(K, {
|
|
8100
|
+
lipsyncLang: J.lipsyncLang,
|
|
8096
8101
|
onSpeechEnd: () => {
|
|
8097
8102
|
d.current.onCustomAction({
|
|
8098
8103
|
type: "answerFeedbackComplete",
|
|
@@ -8100,7 +8105,7 @@ const ft = Me(({
|
|
|
8100
8105
|
lessonIndex: a.current.currentLessonIndex,
|
|
8101
8106
|
questionIndex: a.current.currentQuestionIndex,
|
|
8102
8107
|
isCorrect: !0,
|
|
8103
|
-
hasNextQuestion:
|
|
8108
|
+
hasNextQuestion: ie,
|
|
8104
8109
|
score: a.current.score,
|
|
8105
8110
|
totalQuestions: a.current.totalQuestions
|
|
8106
8111
|
});
|
|
@@ -8114,11 +8119,11 @@ const ft = Me(({
|
|
|
8114
8119
|
u.current.setBodyMovement("idle");
|
|
8115
8120
|
}
|
|
8116
8121
|
u.current.setBodyMovement("gesturing");
|
|
8117
|
-
const
|
|
8118
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8119
|
-
const
|
|
8120
|
-
u.current.speakText(
|
|
8121
|
-
lipsyncLang:
|
|
8122
|
+
const W = I()?.questions?.length || 0, ie = a.current.currentQuestionIndex >= W - 1, K = a.current.currentQuestionIndex < W - 1;
|
|
8123
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", K);
|
|
8124
|
+
const J = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${ie ? "" : " Let's move on to the next question."}`, Le = F.current || { lipsyncLang: "en" };
|
|
8125
|
+
u.current.speakText(J, {
|
|
8126
|
+
lipsyncLang: Le.lipsyncLang,
|
|
8122
8127
|
onSpeechEnd: () => {
|
|
8123
8128
|
d.current.onCustomAction({
|
|
8124
8129
|
type: "answerFeedbackComplete",
|
|
@@ -8126,7 +8131,7 @@ const ft = Me(({
|
|
|
8126
8131
|
lessonIndex: a.current.currentLessonIndex,
|
|
8127
8132
|
questionIndex: a.current.currentQuestionIndex,
|
|
8128
8133
|
isCorrect: !1,
|
|
8129
|
-
hasNextQuestion:
|
|
8134
|
+
hasNextQuestion: K,
|
|
8130
8135
|
score: a.current.score,
|
|
8131
8136
|
totalQuestions: a.current.totalQuestions
|
|
8132
8137
|
});
|
|
@@ -8134,84 +8139,84 @@ const ft = Me(({
|
|
|
8134
8139
|
});
|
|
8135
8140
|
}
|
|
8136
8141
|
else {
|
|
8137
|
-
const
|
|
8142
|
+
const W = I()?.questions?.length || 0;
|
|
8138
8143
|
d.current.onCustomAction({
|
|
8139
8144
|
type: "answerFeedbackComplete",
|
|
8140
8145
|
moduleIndex: a.current.currentModuleIndex,
|
|
8141
8146
|
lessonIndex: a.current.currentLessonIndex,
|
|
8142
8147
|
questionIndex: a.current.currentQuestionIndex,
|
|
8143
|
-
isCorrect:
|
|
8144
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
8148
|
+
isCorrect: P,
|
|
8149
|
+
hasNextQuestion: a.current.currentQuestionIndex < W - 1,
|
|
8145
8150
|
score: a.current.score,
|
|
8146
8151
|
totalQuestions: a.current.totalQuestions,
|
|
8147
8152
|
avatarNotReady: !0
|
|
8148
8153
|
});
|
|
8149
8154
|
}
|
|
8150
|
-
}, [e.correct, e.incorrect,
|
|
8151
|
-
const
|
|
8152
|
-
if (!
|
|
8155
|
+
}, [e.correct, e.incorrect, D, I, x]), ue = U((v) => {
|
|
8156
|
+
const R = D();
|
|
8157
|
+
if (!v || typeof v != "object") {
|
|
8153
8158
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8154
8159
|
return;
|
|
8155
8160
|
}
|
|
8156
|
-
if (
|
|
8161
|
+
if (R?.type !== "code_test") {
|
|
8157
8162
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8158
8163
|
return;
|
|
8159
8164
|
}
|
|
8160
|
-
const
|
|
8161
|
-
passed:
|
|
8162
|
-
results:
|
|
8163
|
-
output:
|
|
8164
|
-
error:
|
|
8165
|
-
executionTime:
|
|
8166
|
-
testCount:
|
|
8167
|
-
passedCount:
|
|
8168
|
-
failedCount:
|
|
8165
|
+
const P = {
|
|
8166
|
+
passed: v.passed === !0,
|
|
8167
|
+
results: v.results || [],
|
|
8168
|
+
output: v.output || "",
|
|
8169
|
+
error: v.error || null,
|
|
8170
|
+
executionTime: v.executionTime || null,
|
|
8171
|
+
testCount: v.testCount || 0,
|
|
8172
|
+
passedCount: v.passedCount || 0,
|
|
8173
|
+
failedCount: v.failedCount || 0
|
|
8169
8174
|
};
|
|
8170
8175
|
d.current.onCustomAction({
|
|
8171
8176
|
type: "codeTestSubmitted",
|
|
8172
8177
|
moduleIndex: a.current.currentModuleIndex,
|
|
8173
8178
|
lessonIndex: a.current.currentLessonIndex,
|
|
8174
8179
|
questionIndex: a.current.currentQuestionIndex,
|
|
8175
|
-
testResult:
|
|
8176
|
-
question:
|
|
8177
|
-
}), p.current && p.current(
|
|
8178
|
-
}, [
|
|
8180
|
+
testResult: P,
|
|
8181
|
+
question: R
|
|
8182
|
+
}), p.current && p.current(P);
|
|
8183
|
+
}, [D, x]), re = U(() => {
|
|
8179
8184
|
if (a.current.currentQuestionIndex > 0) {
|
|
8180
8185
|
a.current.currentQuestionIndex -= 1;
|
|
8181
|
-
const
|
|
8182
|
-
|
|
8186
|
+
const v = D();
|
|
8187
|
+
v && d.current.onCustomAction({
|
|
8183
8188
|
type: "questionStart",
|
|
8184
8189
|
moduleIndex: a.current.currentModuleIndex,
|
|
8185
8190
|
lessonIndex: a.current.currentLessonIndex,
|
|
8186
8191
|
questionIndex: a.current.currentQuestionIndex,
|
|
8187
8192
|
totalQuestions: a.current.totalQuestions,
|
|
8188
|
-
question:
|
|
8193
|
+
question: v,
|
|
8189
8194
|
score: a.current.score
|
|
8190
8195
|
});
|
|
8191
|
-
const
|
|
8192
|
-
if (!u.current || !
|
|
8196
|
+
const R = () => {
|
|
8197
|
+
if (!u.current || !v) return;
|
|
8193
8198
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
8194
|
-
const
|
|
8195
|
-
|
|
8196
|
-
lipsyncLang:
|
|
8197
|
-
}) : u.current.speakText(`Going back to: ${
|
|
8198
|
-
lipsyncLang:
|
|
8199
|
+
const P = F.current || { lipsyncLang: "en" };
|
|
8200
|
+
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8201
|
+
lipsyncLang: P.lipsyncLang
|
|
8202
|
+
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
8203
|
+
lipsyncLang: P.lipsyncLang
|
|
8199
8204
|
});
|
|
8200
8205
|
};
|
|
8201
|
-
if (u.current && u.current.isReady &&
|
|
8202
|
-
|
|
8203
|
-
else if (
|
|
8204
|
-
const
|
|
8205
|
-
u.current && u.current.isReady && (clearInterval(
|
|
8206
|
+
if (u.current && u.current.isReady && v)
|
|
8207
|
+
R();
|
|
8208
|
+
else if (v) {
|
|
8209
|
+
const P = setInterval(() => {
|
|
8210
|
+
u.current && u.current.isReady && (clearInterval(P), R());
|
|
8206
8211
|
}, 100);
|
|
8207
8212
|
setTimeout(() => {
|
|
8208
|
-
clearInterval(
|
|
8213
|
+
clearInterval(P);
|
|
8209
8214
|
}, 5e3);
|
|
8210
8215
|
}
|
|
8211
8216
|
}
|
|
8212
|
-
}, [
|
|
8213
|
-
const
|
|
8214
|
-
if (
|
|
8217
|
+
}, [D]), ge = U(() => {
|
|
8218
|
+
const v = B.current || { modules: [] };
|
|
8219
|
+
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
8215
8220
|
a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8216
8221
|
type: "lessonStart",
|
|
8217
8222
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -8219,66 +8224,66 @@ const ft = Me(({
|
|
|
8219
8224
|
}), d.current.onLessonStart({
|
|
8220
8225
|
moduleIndex: a.current.currentModuleIndex,
|
|
8221
8226
|
lessonIndex: a.current.currentLessonIndex,
|
|
8222
|
-
lesson:
|
|
8227
|
+
lesson: I()
|
|
8223
8228
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8224
8229
|
else if (a.current.currentModuleIndex > 0) {
|
|
8225
|
-
const
|
|
8226
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
8230
|
+
const O = v.modules[a.current.currentModuleIndex - 1];
|
|
8231
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (O?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8227
8232
|
type: "lessonStart",
|
|
8228
8233
|
moduleIndex: a.current.currentModuleIndex,
|
|
8229
8234
|
lessonIndex: a.current.currentLessonIndex
|
|
8230
8235
|
}), d.current.onLessonStart({
|
|
8231
8236
|
moduleIndex: a.current.currentModuleIndex,
|
|
8232
8237
|
lessonIndex: a.current.currentLessonIndex,
|
|
8233
|
-
lesson:
|
|
8238
|
+
lesson: I()
|
|
8234
8239
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8235
8240
|
}
|
|
8236
|
-
}, [
|
|
8241
|
+
}, [I]), ne = U(() => {
|
|
8237
8242
|
a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
8238
|
-
}, []),
|
|
8239
|
-
console.log("Avatar is ready!",
|
|
8240
|
-
const
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
+
}, []), ve = U((v) => {
|
|
8244
|
+
console.log("Avatar is ready!", v);
|
|
8245
|
+
const R = I(), P = R?.avatar_script || R?.body;
|
|
8246
|
+
c && P && setTimeout(() => {
|
|
8247
|
+
h.current && h.current();
|
|
8243
8248
|
}, 10);
|
|
8244
|
-
}, [
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
}),
|
|
8249
|
+
}, [c, I]);
|
|
8250
|
+
je(() => {
|
|
8251
|
+
h.current = j, g.current = M, b.current = k, f.current = T, w.current = A, N.current = L, p.current = Z;
|
|
8252
|
+
}), Ee(r, () => ({
|
|
8248
8253
|
// Curriculum control methods
|
|
8249
|
-
startTeaching:
|
|
8250
|
-
startQuestions:
|
|
8251
|
-
handleAnswerSelect:
|
|
8252
|
-
handleCodeTestResult:
|
|
8253
|
-
nextQuestion:
|
|
8254
|
-
previousQuestion:
|
|
8255
|
-
nextLesson:
|
|
8256
|
-
previousLesson:
|
|
8257
|
-
completeLesson:
|
|
8258
|
-
completeCurriculum:
|
|
8259
|
-
resetCurriculum:
|
|
8254
|
+
startTeaching: j,
|
|
8255
|
+
startQuestions: L,
|
|
8256
|
+
handleAnswerSelect: Z,
|
|
8257
|
+
handleCodeTestResult: ue,
|
|
8258
|
+
nextQuestion: T,
|
|
8259
|
+
previousQuestion: re,
|
|
8260
|
+
nextLesson: M,
|
|
8261
|
+
previousLesson: ge,
|
|
8262
|
+
completeLesson: k,
|
|
8263
|
+
completeCurriculum: A,
|
|
8264
|
+
resetCurriculum: ne,
|
|
8260
8265
|
getState: () => ({ ...a.current }),
|
|
8261
|
-
getCurrentQuestion: () =>
|
|
8262
|
-
getCurrentLesson: () =>
|
|
8266
|
+
getCurrentQuestion: () => D(),
|
|
8267
|
+
getCurrentLesson: () => I(),
|
|
8263
8268
|
// Direct access to avatar ref (always returns current value)
|
|
8264
8269
|
getAvatarRef: () => u.current,
|
|
8265
8270
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8266
|
-
speakText: async (
|
|
8271
|
+
speakText: async (v, R = {}) => {
|
|
8267
8272
|
await u.current?.resumeAudioContext?.();
|
|
8268
|
-
const
|
|
8269
|
-
u.current?.speakText(
|
|
8273
|
+
const P = F.current || { lipsyncLang: "en" };
|
|
8274
|
+
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || P.lipsyncLang });
|
|
8270
8275
|
},
|
|
8271
8276
|
resumeAudioContext: async () => {
|
|
8272
8277
|
if (u.current?.resumeAudioContext)
|
|
8273
8278
|
return await u.current.resumeAudioContext();
|
|
8274
|
-
const
|
|
8275
|
-
if (
|
|
8276
|
-
const
|
|
8277
|
-
if (
|
|
8279
|
+
const v = u.current?.talkingHead;
|
|
8280
|
+
if (v?.audioCtx) {
|
|
8281
|
+
const R = v.audioCtx;
|
|
8282
|
+
if (R.state === "suspended" || R.state === "interrupted")
|
|
8278
8283
|
try {
|
|
8279
|
-
await
|
|
8280
|
-
} catch (
|
|
8281
|
-
console.warn("Failed to resume audio context:",
|
|
8284
|
+
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8285
|
+
} catch (P) {
|
|
8286
|
+
console.warn("Failed to resume audio context:", P);
|
|
8282
8287
|
}
|
|
8283
8288
|
} else
|
|
8284
8289
|
console.warn("Audio context not available yet");
|
|
@@ -8287,22 +8292,22 @@ const ft = Me(({
|
|
|
8287
8292
|
pauseSpeaking: () => u.current?.pauseSpeaking(),
|
|
8288
8293
|
resumeSpeaking: async () => await u.current?.resumeSpeaking(),
|
|
8289
8294
|
isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
|
|
8290
|
-
setMood: (
|
|
8291
|
-
playAnimation: (
|
|
8292
|
-
setBodyMovement: (
|
|
8293
|
-
setMovementIntensity: (
|
|
8295
|
+
setMood: (v) => u.current?.setMood(v),
|
|
8296
|
+
playAnimation: (v, R) => u.current?.playAnimation(v, R),
|
|
8297
|
+
setBodyMovement: (v) => u.current?.setBodyMovement(v),
|
|
8298
|
+
setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
|
|
8294
8299
|
playRandomDance: () => u.current?.playRandomDance(),
|
|
8295
|
-
playReaction: (
|
|
8300
|
+
playReaction: (v) => u.current?.playReaction(v),
|
|
8296
8301
|
playCelebration: () => u.current?.playCelebration(),
|
|
8297
|
-
setShowFullAvatar: (
|
|
8298
|
-
setTimingAdjustment: (
|
|
8302
|
+
setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
|
|
8303
|
+
setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
|
|
8299
8304
|
lockAvatarPosition: () => u.current?.lockAvatarPosition(),
|
|
8300
8305
|
unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
|
|
8301
8306
|
// Custom action trigger
|
|
8302
|
-
triggerCustomAction: (
|
|
8307
|
+
triggerCustomAction: (v, R) => {
|
|
8303
8308
|
d.current.onCustomAction({
|
|
8304
|
-
type:
|
|
8305
|
-
...
|
|
8309
|
+
type: v,
|
|
8310
|
+
...R,
|
|
8306
8311
|
state: { ...a.current }
|
|
8307
8312
|
});
|
|
8308
8313
|
},
|
|
@@ -8310,8 +8315,8 @@ const ft = Me(({
|
|
|
8310
8315
|
handleResize: () => u.current?.handleResize(),
|
|
8311
8316
|
// Avatar readiness check (always returns current value)
|
|
8312
8317
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8313
|
-
}), [
|
|
8314
|
-
const
|
|
8318
|
+
}), [j, L, Z, ue, T, M, k, A, ne, D, I]);
|
|
8319
|
+
const _ = F.current || {
|
|
8315
8320
|
avatarUrl: "/avatars/brunette.glb",
|
|
8316
8321
|
avatarBody: "F",
|
|
8317
8322
|
mood: "happy",
|
|
@@ -8324,33 +8329,316 @@ const ft = Me(({
|
|
|
8324
8329
|
showFullAvatar: !1,
|
|
8325
8330
|
animations: e
|
|
8326
8331
|
};
|
|
8327
|
-
return /* @__PURE__ */
|
|
8332
|
+
return /* @__PURE__ */ q("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ q(
|
|
8328
8333
|
Ve,
|
|
8329
8334
|
{
|
|
8330
8335
|
ref: u,
|
|
8331
|
-
avatarUrl:
|
|
8332
|
-
avatarBody:
|
|
8333
|
-
mood:
|
|
8334
|
-
ttsLang:
|
|
8335
|
-
ttsService:
|
|
8336
|
-
ttsVoice:
|
|
8337
|
-
ttsApiKey:
|
|
8338
|
-
bodyMovement:
|
|
8339
|
-
movementIntensity:
|
|
8340
|
-
showFullAvatar:
|
|
8336
|
+
avatarUrl: _.avatarUrl,
|
|
8337
|
+
avatarBody: _.avatarBody,
|
|
8338
|
+
mood: _.mood,
|
|
8339
|
+
ttsLang: _.ttsLang,
|
|
8340
|
+
ttsService: _.ttsService,
|
|
8341
|
+
ttsVoice: _.ttsVoice,
|
|
8342
|
+
ttsApiKey: _.ttsApiKey,
|
|
8343
|
+
bodyMovement: _.bodyMovement,
|
|
8344
|
+
movementIntensity: _.movementIntensity,
|
|
8345
|
+
showFullAvatar: _.showFullAvatar,
|
|
8341
8346
|
cameraView: "upper",
|
|
8342
|
-
animations:
|
|
8343
|
-
onReady:
|
|
8347
|
+
animations: _.animations,
|
|
8348
|
+
onReady: ve,
|
|
8344
8349
|
onLoading: () => {
|
|
8345
8350
|
},
|
|
8346
|
-
onError: (
|
|
8347
|
-
console.error("Avatar error:",
|
|
8351
|
+
onError: (v) => {
|
|
8352
|
+
console.error("Avatar error:", v);
|
|
8348
8353
|
}
|
|
8349
8354
|
}
|
|
8350
8355
|
) });
|
|
8351
8356
|
});
|
|
8352
8357
|
ft.displayName = "CurriculumLearning";
|
|
8353
|
-
|
|
8358
|
+
function Ct({
|
|
8359
|
+
manifestPath: G = "/animations/manifest.json",
|
|
8360
|
+
avatarBody: t = "F",
|
|
8361
|
+
onAnimationPlay: e = null,
|
|
8362
|
+
onAnimationsSelected: n = null,
|
|
8363
|
+
onDeleteAnimations: i = null,
|
|
8364
|
+
style: s = {}
|
|
8365
|
+
}) {
|
|
8366
|
+
const [o, l] = ae([]), [c, r] = ae(/* @__PURE__ */ new Set()), [u, a] = ae(!0), [d, h] = ae(null), [g, b] = ae("all"), [f, w] = ae("");
|
|
8367
|
+
me(() => {
|
|
8368
|
+
(async () => {
|
|
8369
|
+
a(!0), h(null);
|
|
8370
|
+
try {
|
|
8371
|
+
const A = await Ge(G), L = [];
|
|
8372
|
+
if (A._genderSpecific) {
|
|
8373
|
+
const M = (t?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
8374
|
+
A._genderSpecific[M] && Object.entries(A._genderSpecific[M]).forEach(([j, Z]) => {
|
|
8375
|
+
(Array.isArray(Z) ? Z : [Z]).forEach((re) => {
|
|
8376
|
+
L.push({
|
|
8377
|
+
path: re,
|
|
8378
|
+
group: j,
|
|
8379
|
+
gender: M,
|
|
8380
|
+
name: re.split("/").pop().replace(".fbx", "")
|
|
8381
|
+
});
|
|
8382
|
+
});
|
|
8383
|
+
}), A._genderSpecific.shared && Object.entries(A._genderSpecific.shared).forEach(([j, Z]) => {
|
|
8384
|
+
(Array.isArray(Z) ? Z : [Z]).forEach((re) => {
|
|
8385
|
+
L.push({
|
|
8386
|
+
path: re,
|
|
8387
|
+
group: j,
|
|
8388
|
+
gender: "shared",
|
|
8389
|
+
name: re.split("/").pop().replace(".fbx", "")
|
|
8390
|
+
});
|
|
8391
|
+
});
|
|
8392
|
+
});
|
|
8393
|
+
}
|
|
8394
|
+
Object.entries(A).forEach(([T, M]) => {
|
|
8395
|
+
T !== "_genderSpecific" && (Array.isArray(M) ? M : [M]).forEach((Z) => {
|
|
8396
|
+
typeof Z == "string" && L.push({
|
|
8397
|
+
path: Z,
|
|
8398
|
+
group: T,
|
|
8399
|
+
gender: "root",
|
|
8400
|
+
name: Z.split("/").pop().replace(".fbx", "")
|
|
8401
|
+
});
|
|
8402
|
+
});
|
|
8403
|
+
}), l(L), a(!1);
|
|
8404
|
+
} catch (A) {
|
|
8405
|
+
console.error("Failed to load animations:", A), h(A.message), a(!1);
|
|
8406
|
+
}
|
|
8407
|
+
})();
|
|
8408
|
+
}, [G, t]);
|
|
8409
|
+
const N = ["all", ...new Set(o.map((k) => k.group))], p = o.filter((k) => {
|
|
8410
|
+
const A = g === "all" || k.group === g, L = f === "" || k.name.toLowerCase().includes(f.toLowerCase()) || k.path.toLowerCase().includes(f.toLowerCase());
|
|
8411
|
+
return A && L;
|
|
8412
|
+
}), B = (k) => {
|
|
8413
|
+
const A = new Set(c);
|
|
8414
|
+
A.has(k) ? A.delete(k) : A.add(k), r(A), n && n(Array.from(A));
|
|
8415
|
+
}, F = () => {
|
|
8416
|
+
const k = new Set(c);
|
|
8417
|
+
p.forEach((A) => {
|
|
8418
|
+
k.add(A.path);
|
|
8419
|
+
}), r(k), n && n(Array.from(k));
|
|
8420
|
+
}, I = () => {
|
|
8421
|
+
const k = new Set(c);
|
|
8422
|
+
p.forEach((A) => {
|
|
8423
|
+
k.delete(A.path);
|
|
8424
|
+
}), r(k), n && n(Array.from(k));
|
|
8425
|
+
}, D = () => {
|
|
8426
|
+
const A = o.filter((L) => !c.has(L.path)).map((L) => L.path);
|
|
8427
|
+
if (A.length === 0) {
|
|
8428
|
+
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8429
|
+
return;
|
|
8430
|
+
}
|
|
8431
|
+
window.confirm(`Are you sure you want to delete ${A.length} animation(s)?
|
|
8432
|
+
|
|
8433
|
+
This will delete:
|
|
8434
|
+
${A.slice(0, 5).join(`
|
|
8435
|
+
`)}${A.length > 5 ? `
|
|
8436
|
+
...` : ""}`) && (i && i(A), l(o.filter((L) => c.has(L.path))), r(/* @__PURE__ */ new Set()));
|
|
8437
|
+
}, x = (k) => {
|
|
8438
|
+
e && e(k);
|
|
8439
|
+
};
|
|
8440
|
+
return u ? /* @__PURE__ */ q("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ q("p", { children: "Loading animations..." }) }) : d ? /* @__PURE__ */ q("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ fe("p", { children: [
|
|
8441
|
+
"Error loading animations: ",
|
|
8442
|
+
d
|
|
8443
|
+
] }) }) : /* @__PURE__ */ fe("div", { style: {
|
|
8444
|
+
padding: "20px",
|
|
8445
|
+
backgroundColor: "#2a2a2a",
|
|
8446
|
+
borderRadius: "8px",
|
|
8447
|
+
color: "#fff",
|
|
8448
|
+
...s
|
|
8449
|
+
}, children: [
|
|
8450
|
+
/* @__PURE__ */ q("h2", { style: { marginTop: 0 }, children: "Animation Selector" }),
|
|
8451
|
+
/* @__PURE__ */ q("p", { style: { color: "#aaa", fontSize: "14px" }, children: "Click buttons to play animations. Select animations to keep, then delete will remove the rest." }),
|
|
8452
|
+
/* @__PURE__ */ fe("div", { style: {
|
|
8453
|
+
display: "flex",
|
|
8454
|
+
gap: "10px",
|
|
8455
|
+
marginBottom: "20px",
|
|
8456
|
+
flexWrap: "wrap",
|
|
8457
|
+
alignItems: "center"
|
|
8458
|
+
}, children: [
|
|
8459
|
+
/* @__PURE__ */ q(
|
|
8460
|
+
"input",
|
|
8461
|
+
{
|
|
8462
|
+
type: "text",
|
|
8463
|
+
placeholder: "Search animations...",
|
|
8464
|
+
value: f,
|
|
8465
|
+
onChange: (k) => w(k.target.value),
|
|
8466
|
+
style: {
|
|
8467
|
+
padding: "8px 12px",
|
|
8468
|
+
borderRadius: "6px",
|
|
8469
|
+
border: "1px solid #555",
|
|
8470
|
+
backgroundColor: "#333",
|
|
8471
|
+
color: "#fff",
|
|
8472
|
+
fontSize: "14px",
|
|
8473
|
+
flex: "1",
|
|
8474
|
+
minWidth: "200px"
|
|
8475
|
+
}
|
|
8476
|
+
}
|
|
8477
|
+
),
|
|
8478
|
+
/* @__PURE__ */ q(
|
|
8479
|
+
"select",
|
|
8480
|
+
{
|
|
8481
|
+
value: g,
|
|
8482
|
+
onChange: (k) => b(k.target.value),
|
|
8483
|
+
style: {
|
|
8484
|
+
padding: "8px 12px",
|
|
8485
|
+
borderRadius: "6px",
|
|
8486
|
+
border: "1px solid #555",
|
|
8487
|
+
backgroundColor: "#333",
|
|
8488
|
+
color: "#fff",
|
|
8489
|
+
fontSize: "14px"
|
|
8490
|
+
},
|
|
8491
|
+
children: N.map((k) => /* @__PURE__ */ q("option", { value: k, children: k === "all" ? "All Groups" : k }, k))
|
|
8492
|
+
}
|
|
8493
|
+
),
|
|
8494
|
+
/* @__PURE__ */ q(
|
|
8495
|
+
"button",
|
|
8496
|
+
{
|
|
8497
|
+
onClick: F,
|
|
8498
|
+
style: {
|
|
8499
|
+
padding: "8px 16px",
|
|
8500
|
+
backgroundColor: "#4CAF50",
|
|
8501
|
+
color: "white",
|
|
8502
|
+
border: "none",
|
|
8503
|
+
borderRadius: "6px",
|
|
8504
|
+
cursor: "pointer",
|
|
8505
|
+
fontSize: "14px"
|
|
8506
|
+
},
|
|
8507
|
+
children: "Select All Visible"
|
|
8508
|
+
}
|
|
8509
|
+
),
|
|
8510
|
+
/* @__PURE__ */ q(
|
|
8511
|
+
"button",
|
|
8512
|
+
{
|
|
8513
|
+
onClick: I,
|
|
8514
|
+
style: {
|
|
8515
|
+
padding: "8px 16px",
|
|
8516
|
+
backgroundColor: "#666",
|
|
8517
|
+
color: "white",
|
|
8518
|
+
border: "none",
|
|
8519
|
+
borderRadius: "6px",
|
|
8520
|
+
cursor: "pointer",
|
|
8521
|
+
fontSize: "14px"
|
|
8522
|
+
},
|
|
8523
|
+
children: "Deselect All Visible"
|
|
8524
|
+
}
|
|
8525
|
+
),
|
|
8526
|
+
/* @__PURE__ */ fe(
|
|
8527
|
+
"button",
|
|
8528
|
+
{
|
|
8529
|
+
onClick: D,
|
|
8530
|
+
style: {
|
|
8531
|
+
padding: "8px 16px",
|
|
8532
|
+
backgroundColor: "#f44336",
|
|
8533
|
+
color: "white",
|
|
8534
|
+
border: "none",
|
|
8535
|
+
borderRadius: "6px",
|
|
8536
|
+
cursor: "pointer",
|
|
8537
|
+
fontSize: "14px",
|
|
8538
|
+
fontWeight: "bold"
|
|
8539
|
+
},
|
|
8540
|
+
children: [
|
|
8541
|
+
"Delete Unselected (",
|
|
8542
|
+
o.length - c.size,
|
|
8543
|
+
")"
|
|
8544
|
+
]
|
|
8545
|
+
}
|
|
8546
|
+
)
|
|
8547
|
+
] }),
|
|
8548
|
+
/* @__PURE__ */ fe("div", { style: {
|
|
8549
|
+
marginBottom: "15px",
|
|
8550
|
+
fontSize: "14px",
|
|
8551
|
+
color: "#aaa"
|
|
8552
|
+
}, children: [
|
|
8553
|
+
"Total: ",
|
|
8554
|
+
o.length,
|
|
8555
|
+
" | Selected: ",
|
|
8556
|
+
c.size,
|
|
8557
|
+
" | Showing: ",
|
|
8558
|
+
p.length
|
|
8559
|
+
] }),
|
|
8560
|
+
/* @__PURE__ */ q("div", { style: {
|
|
8561
|
+
display: "grid",
|
|
8562
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
|
|
8563
|
+
gap: "10px",
|
|
8564
|
+
maxHeight: "500px",
|
|
8565
|
+
overflowY: "auto",
|
|
8566
|
+
padding: "10px",
|
|
8567
|
+
backgroundColor: "#1a1a1a",
|
|
8568
|
+
borderRadius: "6px"
|
|
8569
|
+
}, children: p.map((k, A) => {
|
|
8570
|
+
const L = c.has(k.path);
|
|
8571
|
+
return /* @__PURE__ */ fe(
|
|
8572
|
+
"div",
|
|
8573
|
+
{
|
|
8574
|
+
style: {
|
|
8575
|
+
border: `2px solid ${L ? "#4CAF50" : "#555"}`,
|
|
8576
|
+
borderRadius: "6px",
|
|
8577
|
+
padding: "10px",
|
|
8578
|
+
backgroundColor: L ? "#2a4a2a" : "#222",
|
|
8579
|
+
cursor: "pointer",
|
|
8580
|
+
transition: "all 0.2s"
|
|
8581
|
+
},
|
|
8582
|
+
onClick: () => B(k.path),
|
|
8583
|
+
children: [
|
|
8584
|
+
/* @__PURE__ */ fe("div", { style: { marginBottom: "8px" }, children: [
|
|
8585
|
+
/* @__PURE__ */ q(
|
|
8586
|
+
"input",
|
|
8587
|
+
{
|
|
8588
|
+
type: "checkbox",
|
|
8589
|
+
checked: L,
|
|
8590
|
+
onChange: () => B(k.path),
|
|
8591
|
+
onClick: (T) => T.stopPropagation(),
|
|
8592
|
+
style: {
|
|
8593
|
+
marginRight: "8px",
|
|
8594
|
+
cursor: "pointer"
|
|
8595
|
+
}
|
|
8596
|
+
}
|
|
8597
|
+
),
|
|
8598
|
+
/* @__PURE__ */ fe("span", { style: { fontSize: "12px", color: "#aaa" }, children: [
|
|
8599
|
+
k.group,
|
|
8600
|
+
" ",
|
|
8601
|
+
k.gender !== "root" && `(${k.gender})`
|
|
8602
|
+
] })
|
|
8603
|
+
] }),
|
|
8604
|
+
/* @__PURE__ */ q("div", { style: {
|
|
8605
|
+
fontSize: "13px",
|
|
8606
|
+
fontWeight: "bold",
|
|
8607
|
+
marginBottom: "8px",
|
|
8608
|
+
wordBreak: "break-word"
|
|
8609
|
+
}, children: k.name }),
|
|
8610
|
+
/* @__PURE__ */ q(
|
|
8611
|
+
"button",
|
|
8612
|
+
{
|
|
8613
|
+
onClick: (T) => {
|
|
8614
|
+
T.stopPropagation(), x(k.path);
|
|
8615
|
+
},
|
|
8616
|
+
style: {
|
|
8617
|
+
width: "100%",
|
|
8618
|
+
padding: "6px",
|
|
8619
|
+
backgroundColor: "#2196F3",
|
|
8620
|
+
color: "white",
|
|
8621
|
+
border: "none",
|
|
8622
|
+
borderRadius: "4px",
|
|
8623
|
+
cursor: "pointer",
|
|
8624
|
+
fontSize: "12px"
|
|
8625
|
+
},
|
|
8626
|
+
children: "▶ Play"
|
|
8627
|
+
}
|
|
8628
|
+
)
|
|
8629
|
+
]
|
|
8630
|
+
},
|
|
8631
|
+
`${k.path}-${A}`
|
|
8632
|
+
);
|
|
8633
|
+
}) }),
|
|
8634
|
+
p.length === 0 && /* @__PURE__ */ q("div", { style: {
|
|
8635
|
+
padding: "40px",
|
|
8636
|
+
textAlign: "center",
|
|
8637
|
+
color: "#aaa"
|
|
8638
|
+
}, children: "No animations found matching your filters." })
|
|
8639
|
+
] });
|
|
8640
|
+
}
|
|
8641
|
+
const Ze = {
|
|
8354
8642
|
// Code-based dance animations (no FBX required)
|
|
8355
8643
|
dance: {
|
|
8356
8644
|
name: "dance",
|
|
@@ -8453,15 +8741,16 @@ const Ge = {
|
|
|
8453
8741
|
duration: 5e3,
|
|
8454
8742
|
description: "Excited, energetic movement"
|
|
8455
8743
|
}
|
|
8456
|
-
}, zt = (
|
|
8744
|
+
}, zt = (G) => Ze[G] || null, Ht = (G) => Ze.hasOwnProperty(G);
|
|
8457
8745
|
export {
|
|
8746
|
+
Ct as AnimationSelector,
|
|
8458
8747
|
ft as CurriculumLearning,
|
|
8459
8748
|
yt as SimpleTalkingAvatar,
|
|
8460
8749
|
Ve as TalkingHeadAvatar,
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8750
|
+
gt as TalkingHeadComponent,
|
|
8751
|
+
Ze as animations,
|
|
8752
|
+
Pe as getActiveTTSConfig,
|
|
8464
8753
|
zt as getAnimation,
|
|
8465
8754
|
wt as getVoiceOptions,
|
|
8466
|
-
|
|
8755
|
+
Ht as hasAnimation
|
|
8467
8756
|
};
|