@sage-rsc/talking-head-react 1.5.11 → 1.6.1
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 +5 -5
- package/dist/index.js +1098 -1020
- package/package.json +3 -2
- package/scripts/generate-folder-listings.js +75 -0
- package/src/components/SimpleTalkingAvatar.jsx +76 -7
- package/src/utils/animationLoader.js +131 -0
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
1
|
+
import { jsxs as ve, jsx as J } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Be, useRef as X, useState as le, useEffect as ge, useCallback as G, useImperativeHandle as Oe, useLayoutEffect as Ke } from "react";
|
|
3
3
|
import * as x from "three";
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
6
|
-
import { DRACOLoader as
|
|
7
|
-
import { FBXLoader as
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let m,
|
|
11
|
-
const
|
|
4
|
+
import { OrbitControls as $e } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as Je } from "three/addons/loaders/GLTFLoader.js";
|
|
6
|
+
import { DRACOLoader as et } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
+
import { FBXLoader as Ve } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
+
import { RoomEnvironment as tt } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import nt from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, pe, fe;
|
|
11
|
+
const H = [0, 0, 0, 0], P = new x.Vector3(), Me = new x.Vector3(), he = new x.Vector3(), Fe = new x.Vector3();
|
|
12
12
|
new x.Plane();
|
|
13
13
|
new x.Ray();
|
|
14
14
|
new x.Euler();
|
|
15
|
-
const
|
|
15
|
+
const de = new x.Quaternion(), Ge = new x.Quaternion(), Re = new x.Matrix4(), Ae = new x.Matrix4();
|
|
16
16
|
new x.Vector3();
|
|
17
|
-
const
|
|
18
|
-
class
|
|
17
|
+
const Ee = new x.Vector3(0, 0, 1), it = new x.Vector3(1, 0, 0), ot = new x.Vector3(0, 1, 0), st = new x.Vector3(0, 0, 1);
|
|
18
|
+
class at {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -192,7 +192,7 @@ class nt {
|
|
|
192
192
|
const r = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!r) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const u = {
|
|
196
196
|
bone: r,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class nt {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((a) => Number.isNaN(a))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
|
|
206
|
-
|
|
206
|
+
u.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
i.excludes.push(
|
|
208
|
+
i.excludes.push(u);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class nt {
|
|
|
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((u) => {
|
|
286
|
+
n.has(u) || (this.objectsUpdate.push(u), n.add(u));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((o) => {
|
|
@@ -308,12 +308,12 @@ class nt {
|
|
|
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 r = "Config item #" + o + ": ";
|
|
310
310
|
i(s.bone, r + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
i(typeof
|
|
313
|
-
const a = this.armature.getObjectByName(
|
|
314
|
-
i(a, r + "Bone '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const u = s.bone;
|
|
312
|
+
i(typeof u == "string" && u.length > 0, r + "Bone name must be a non-empty string.");
|
|
313
|
+
const a = this.armature.getObjectByName(u);
|
|
314
|
+
i(a, r + "Bone '" + u + "' not found."), i(a.parent?.isBone, r + "Bone must have a parent bone."), i(this.data.every((l) => l.bone !== a), r + "Bone '" + u + "' already exists."), a.updateMatrixWorld(!0);
|
|
315
|
+
const c = {
|
|
316
|
+
name: u,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: a,
|
|
319
319
|
// Bone object
|
|
@@ -321,7 +321,7 @@ class nt {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: a.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: a.parent.getWorldPosition(
|
|
324
|
+
vWorld: a.parent.getWorldPosition(P).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: a.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,9 +338,9 @@ class nt {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
c.boneParent.matrixWorld.decompose(P, de, he), P.copy(Ee).applyQuaternion(de).setY(0).normalize(), de.premultiply(Ge.setFromUnitVectors(Ee, P).invert()).normalize(), c.qWorldInverseYaw = de.clone().normalize(), this.data.push(c), this.dict[u] = c;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
|
|
344
344
|
} catch (l) {
|
|
345
345
|
i(!1, r + l);
|
|
346
346
|
}
|
|
@@ -356,22 +356,22 @@ class nt {
|
|
|
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], P.copy(o.vWorld), Re.copy(o.boneParent.matrixWorld), Ae.copy(Re).invert(), o.vWorld.setFromMatrixPosition(Re), P.applyMatrix4(Ae), P.length() > 0.5 && (console.info("Info: Unrealistic jump of " + P.length().toFixed(2) + " meters."), P.setLength(0.5)), P.applyQuaternion(o.bone.quaternion), H[0] = P.x, H[1] = P.y, H[2] = -P.z, H[3] = P.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], H[0] -= m.v[0] * t / 3, H[1] -= m.v[1] * t / 3, H[2] += m.v[2] * t / 3, H[3] -= m.v[3] * t / 3;
|
|
362
|
+
if (m = this.opt.sensitivityFactor, H[0] *= o.ext * m, H[1] *= o.ext * m, H[2] *= o.ext * m, H[3] *= o.ext * m, o.isX && (m = H[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 + H[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 = H[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 + H[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 = H[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 + H[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 = H[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 + H[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), H[0] = o.p[0], H[1] = o.p[1], H[2] = o.p[2], H[3] = o.p[3], m = this.opt.movementFactor, H[0] *= m, H[1] *= m, H[2] *= m, H[3] *= m, o.dl && (m = o.dl, H[0] += m[0], H[1] += m[1], H[2] += m[2]), o.dw && (m = o.dw, P.set(
|
|
363
|
+
o.vBasis.x + H[0],
|
|
364
|
+
o.vBasis.y + H[1],
|
|
365
|
+
o.vBasis.z + H[2]
|
|
366
|
+
), P.applyMatrix4(Re), P.x += m[0], P.y += m[1], P.z += m[2], P.applyMatrix4(Ae), H[0] += P.x - o.vBasis.x, H[1] += P.y - o.vBasis.y, H[2] += P.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && H[0] < m[0][0] && (H[0] = m[0][0]), m[0][1] !== null && H[0] > m[0][1] && (H[0] = m[0][1])), m[1] && (m[1][0] !== null && H[1] < m[1][0] && (H[1] = m[1][0]), m[1][1] !== null && H[1] > m[1][1] && (H[1] = m[1][1])), m[2] && (m[2][0] !== null && H[2] < m[2][0] && (H[2] = m[2][0]), m[2][1] !== null && H[2] > m[2][1] && (H[2] = m[2][1])), m[3] && (m[3][0] !== null && H[3] < m[3][0] && (H[3] = m[3][0]), m[3][1] !== null && H[3] > m[3][1] && (H[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 + H[0],
|
|
369
|
+
o.vBasis.y + H[1],
|
|
370
|
+
o.vBasis.z - H[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(P, de, he), P.copy(Ee).applyQuaternion(de).setY(0).normalize(), de.premultiply(Ge.setFromUnitVectors(Ee, P).invert()).normalize(), o.boneParent.quaternion.multiply(de.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(H[0] / o.l), de.setFromAxisAngle(st, -m), o.boneParent.quaternion.multiply(de)), o.isY && (m = o.l / 3, m = m * Math.tanh(H[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(H[2] / o.l), de.setFromAxisAngle(it, -m), o.boneParent.quaternion.multiply(de)), o.isT && (m = 1.5 * Math.tanh(H[3] * 1.5), de.setFromAxisAngle(ot, -m), o.boneParent.quaternion.multiply(de)), 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], he.set(0, 0, 0), m.deltaLocal && (he.x += m.deltaLocal[0], he.y += m.deltaLocal[1], he.z += m.deltaLocal[2]), he.applyMatrix4(m.bone.matrixWorld), Ae.copy(o.boneParent.matrixWorld).invert(), he.applyMatrix4(Ae), P.copy(o.bone.position), !(P.distanceToSquared(he) >= m.radiusSq) && (fe = P.length(), pe = he.length(), !(pe > m.radius + fe) && (pe < Math.abs(m.radius - fe) || (pe = (pe * pe + fe * fe - m.radiusSq) / (2 * pe), he.normalize(), Fe.copy(he).multiplyScalar(pe), pe = Math.sqrt(fe * fe - pe * pe), P.subVectors(P, Fe).projectOnPlane(he).normalize().multiplyScalar(pe), Me.subVectors(o.vBasis, Fe).projectOnPlane(he).normalize(), fe = Me.dot(P), fe < 0 && (fe = Math.sqrt(pe * pe - fe * fe), Me.multiplyScalar(fe), P.add(Me)), P.add(Fe).normalize(), he.copy(o.bone.position).normalize(), de.setFromUnitVectors(he, P), o.boneParent.quaternion.premultiply(de), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -408,9 +408,9 @@ class nt {
|
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new x.BufferGeometry(), n = m.bones.map((
|
|
411
|
+
const e = new x.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
|
|
413
|
-
const i = new x.Color(this.opt.helperBoneColor1), s = new x.Color(this.opt.helperBoneColor2), o = m.pivots.map((
|
|
413
|
+
const i = new x.Color(this.opt.helperBoneColor1), s = new x.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
|
|
414
414
|
e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
|
|
415
415
|
const r = new x.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class nt {
|
|
|
423
423
|
m.object = new x.Points(e, r), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new x.BufferGeometry(), n = m.bones.map((
|
|
426
|
+
const e = new x.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
|
|
428
|
-
const i = new x.Color(this.opt.helperLinkColor1), s = new x.Color(this.opt.helperLinkColor2), o = m.bones.map((
|
|
428
|
+
const i = new x.Color(this.opt.helperLinkColor1), s = new x.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
|
|
430
430
|
const r = new x.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -442,17 +442,17 @@ class nt {
|
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
444
|
if (m = this.helpers.points, m.bones.length) {
|
|
445
|
-
|
|
445
|
+
Ae.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
|
+
Re.multiplyMatrices(Ae, m.bones[e].matrixWorld), P.setFromMatrixPosition(Re), t.setXYZ(e, P.x, P.y, P.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
|
-
|
|
452
|
+
Ae.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
|
+
Re.multiplyMatrices(Ae, m.bones[e].matrixWorld), P.setFromMatrixPosition(Re), t.setXYZ(n, P.x, P.y, P.z), Re.multiplyMatrices(Ae, m.bones[e].parent.matrixWorld), P.setFromMatrixPosition(Re), t.setXYZ(n + 1, P.x, P.y, P.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -489,7 +489,7 @@ class nt {
|
|
|
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 rt {
|
|
493
493
|
constructor(t) {
|
|
494
494
|
this.audioContext = t, this.analyzer = null, this.dataArray = null, this.bufferLength = 0;
|
|
495
495
|
}
|
|
@@ -519,13 +519,13 @@ class it {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
|
|
521
521
|
for (let r = 0; r < o; r++) {
|
|
522
|
-
const
|
|
522
|
+
const u = r * s, a = Math.min(u + i, t.length), c = t.slice(u, a), l = this.calculateEnergy(c);
|
|
523
523
|
n.energy.push(l);
|
|
524
|
-
const d = this.calculateSpectralCentroid(
|
|
524
|
+
const d = this.calculateSpectralCentroid(c);
|
|
525
525
|
n.spectralCentroid.push(d);
|
|
526
|
-
const h = this.calculateZeroCrossingRate(
|
|
526
|
+
const h = this.calculateZeroCrossingRate(c);
|
|
527
527
|
n.zeroCrossingRate.push(h);
|
|
528
|
-
const p = this.calculateMFCC(
|
|
528
|
+
const p = this.calculateMFCC(c);
|
|
529
529
|
n.mfcc.push(p);
|
|
530
530
|
}
|
|
531
531
|
return n.onsets = this.detectOnsets(n.energy), n.phonemeBoundaries = this.detectPhonemeBoundaries(n), n;
|
|
@@ -597,19 +597,19 @@ class it {
|
|
|
597
597
|
for (; s & o; )
|
|
598
598
|
s ^= o, o >>= 1;
|
|
599
599
|
if (s ^= o, i < s) {
|
|
600
|
-
const r = n[i * 2],
|
|
601
|
-
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = r, n[s * 2 + 1] =
|
|
600
|
+
const r = n[i * 2], u = n[i * 2 + 1];
|
|
601
|
+
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = r, n[s * 2 + 1] = u;
|
|
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), r = Math.sin(s);
|
|
606
|
-
for (let
|
|
607
|
-
let a = 1,
|
|
606
|
+
for (let u = 0; u < e; u += i) {
|
|
607
|
+
let a = 1, c = 0;
|
|
608
608
|
for (let l = 0; l < i / 2; l++) {
|
|
609
|
-
const d = n[(
|
|
610
|
-
n[(
|
|
611
|
-
const f = a * o -
|
|
612
|
-
a = f,
|
|
609
|
+
const d = n[(u + l) * 2], h = n[(u + l) * 2 + 1], p = n[(u + l + i / 2) * 2] * a - n[(u + l + i / 2) * 2 + 1] * c, b = n[(u + l + i / 2) * 2] * c + n[(u + l + i / 2) * 2 + 1] * a;
|
|
610
|
+
n[(u + l) * 2] = d + p, n[(u + l) * 2 + 1] = h + b, n[(u + l + i / 2) * 2] = d - p, n[(u + l + i / 2) * 2 + 1] = h - b;
|
|
611
|
+
const f = a * o - c * r, S = a * r + c * o;
|
|
612
|
+
a = f, c = S;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class it {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let o = 1; o < t.length; o++) {
|
|
627
|
-
const r = t[o] - t[o - 1],
|
|
628
|
-
r > 0.1 &&
|
|
627
|
+
const r = t[o] - t[o - 1], u = o * 0.023;
|
|
628
|
+
r > 0.1 && u - s > 0.1 && (e.push(u), s = u);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class it {
|
|
|
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 r = o * 0.023,
|
|
641
|
-
|
|
640
|
+
const r = o * 0.023, u = Math.abs(n[o] - n[o - 1]), a = Math.abs(i[o] - i[o - 1]), c = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
u + a * 0.1 + c * 0.5 > 0.2 && e.push(r);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ class it {
|
|
|
654
654
|
t.phonemeBoundaries, t.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let o = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const a = i[
|
|
657
|
+
for (let u = 0; u < i.length; u++) {
|
|
658
|
+
const a = i[u], c = this.estimateWordDuration(a, n / i.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: a,
|
|
661
661
|
startTime: o,
|
|
662
|
-
endTime: o +
|
|
663
|
-
duration:
|
|
664
|
-
}), o +=
|
|
662
|
+
endTime: o + c,
|
|
663
|
+
duration: c
|
|
664
|
+
}), o += c;
|
|
665
665
|
}
|
|
666
666
|
const r = this.generateVisemeTimings(t, e, n);
|
|
667
667
|
return {
|
|
@@ -701,27 +701,27 @@ class it {
|
|
|
701
701
|
const i = [], s = t.phonemeBoundaries;
|
|
702
702
|
t.onsets;
|
|
703
703
|
const o = this.textToVisemes(e);
|
|
704
|
-
let r = 0,
|
|
704
|
+
let r = 0, u = 0;
|
|
705
705
|
for (let a = 0; a < s.length && r < o.length; a++) {
|
|
706
|
-
const
|
|
706
|
+
const c = s[a], l = o[r], d = t.energy[Math.floor(c / 0.023)] || 0, h = this.calculateVisemeDuration(l, d);
|
|
707
707
|
i.push({
|
|
708
708
|
viseme: l,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
709
|
+
startTime: u,
|
|
710
|
+
endTime: u + h,
|
|
711
711
|
duration: h,
|
|
712
712
|
intensity: Math.min(1, d * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), u += h, r++;
|
|
715
715
|
}
|
|
716
716
|
for (; r < o.length; ) {
|
|
717
|
-
const a = o[r],
|
|
717
|
+
const a = o[r], c = this.calculateVisemeDuration(a, 0.5);
|
|
718
718
|
i.push({
|
|
719
719
|
viseme: a,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: u,
|
|
721
|
+
endTime: u + c,
|
|
722
|
+
duration: c,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), u += c, r++;
|
|
725
725
|
}
|
|
726
726
|
return i;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class it {
|
|
|
775
775
|
let o = 0;
|
|
776
776
|
for (; o < s.length; ) {
|
|
777
777
|
let r = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const a = s.substr(o,
|
|
778
|
+
for (let u = 3; u >= 2; u--) {
|
|
779
|
+
const a = s.substr(o, u);
|
|
780
780
|
if (e[a]) {
|
|
781
|
-
n.push(e[a]), o +=
|
|
781
|
+
n.push(e[a]), o += u, r = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!r) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const u = s[o];
|
|
787
|
+
e[u] && n.push(e[u]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -814,7 +814,7 @@ class it {
|
|
|
814
814
|
return i * s;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
class
|
|
817
|
+
class lt {
|
|
818
818
|
/**
|
|
819
819
|
* @constructor
|
|
820
820
|
*/
|
|
@@ -1206,11 +1206,11 @@ class ot {
|
|
|
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("="), r = n.substring(0, i),
|
|
1209
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), r = n.substring(0, i), u = n.substring(i + 1, s), a = n.substring(s + 1, o), c = n.substring(o + 1), l = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let d = "";
|
|
1211
1211
|
d += [...r].map((p) => t[p] || p).join("");
|
|
1212
|
-
const h = [...
|
|
1213
|
-
return h[0] = h[0].toLowerCase(), d += h.join(""), l.move = h.length, d += [...a].map((p) => t[p] || p).join(""), l.regex = new RegExp(d),
|
|
1212
|
+
const h = [...u];
|
|
1213
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), l.move = h.length, d += [...a].map((p) => t[p] || p).join(""), l.regex = new RegExp(d), c.length && c.split(" ").forEach((p) => {
|
|
1214
1214
|
l.visemes.push(p);
|
|
1215
1215
|
}), l;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class ot {
|
|
|
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, r = n || i ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let u = [];
|
|
1328
|
+
return s ? u.push(this.convertNumberToWords(s).trim(), "thousands") : (o && u.push(this.convertNumberToWords(o).trim()), r ? u.push(this.decades[r] || this.convertNumberToWords(r).trim() + "s") : o ? u.push("hundreds") : u.push(t)), u.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class ot {
|
|
|
1376
1376
|
const s = i[e.i], o = this.rules[s];
|
|
1377
1377
|
if (o)
|
|
1378
1378
|
for (let r = 0; r < o.length; r++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const u = o[r];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
|
|
1381
|
+
u.visemes.forEach((l) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
|
|
1383
1383
|
const d = 0.7 * (this.visemeDurations[l] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += d, n += d;
|
|
@@ -1386,7 +1386,7 @@ class ot {
|
|
|
1386
1386
|
const d = this.visemeDurations[l] || 1;
|
|
1387
1387
|
e.visemes.push(l), e.times.push(n), e.durations.push(d), n += d;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += u.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1396,11 +1396,11 @@ class ot {
|
|
|
1396
1396
|
return e;
|
|
1397
1397
|
}
|
|
1398
1398
|
}
|
|
1399
|
-
const
|
|
1399
|
+
const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1400
1400
|
__proto__: null,
|
|
1401
|
-
LipsyncEn:
|
|
1401
|
+
LipsyncEn: lt
|
|
1402
1402
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1403
|
-
class
|
|
1403
|
+
class ut {
|
|
1404
1404
|
/**
|
|
1405
1405
|
* @constructor
|
|
1406
1406
|
*/
|
|
@@ -1616,11 +1616,11 @@ class at {
|
|
|
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("="), r = n.substring(0, i),
|
|
1619
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), r = n.substring(0, i), u = n.substring(i + 1, s), a = n.substring(s + 1, o), c = n.substring(o + 1), l = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let d = "";
|
|
1621
1621
|
d += [...r].map((p) => t[p] || p).join("");
|
|
1622
|
-
const h = [...
|
|
1623
|
-
return h[0] = h[0].toLowerCase(), d += h.join(""), l.move = h.length, d += [...a].map((p) => t[p] || p).join(""), l.regex = new RegExp(d),
|
|
1622
|
+
const h = [...u];
|
|
1623
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), l.move = h.length, d += [...a].map((p) => t[p] || p).join(""), l.regex = new RegExp(d), c.length && c.split(" ").forEach((p) => {
|
|
1624
1624
|
l.visemes.push(p);
|
|
1625
1625
|
}), l;
|
|
1626
1626
|
});
|
|
@@ -1732,8 +1732,8 @@ class at {
|
|
|
1732
1732
|
const s = i[e.i], o = this.rules[s];
|
|
1733
1733
|
if (o) {
|
|
1734
1734
|
let r = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const a = o[
|
|
1735
|
+
for (let u = 0; u < o.length; u++) {
|
|
1736
|
+
const a = o[u];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
|
|
1738
1738
|
a.visemes.forEach((d) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
@@ -1754,11 +1754,11 @@ class at {
|
|
|
1754
1754
|
return e;
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
1757
|
-
const
|
|
1757
|
+
const ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1758
1758
|
__proto__: null,
|
|
1759
|
-
LipsyncDe:
|
|
1759
|
+
LipsyncDe: ut
|
|
1760
1760
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1761
|
-
class
|
|
1761
|
+
class dt {
|
|
1762
1762
|
/**
|
|
1763
1763
|
* @constructor
|
|
1764
1764
|
*/
|
|
@@ -2131,11 +2131,11 @@ class lt {
|
|
|
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("="), r = n.substring(0, i),
|
|
2134
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), r = n.substring(0, i), u = n.substring(i + 1, s), a = n.substring(s + 1, o), c = n.substring(o + 1), l = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let d = "";
|
|
2136
2136
|
d += [...r].map((p) => t[p] || p).join("");
|
|
2137
|
-
const h = [...
|
|
2138
|
-
return h[0] = h[0].toLowerCase(), d += h.join(""), l.move = h.length, d += [...a].map((p) => t[p] || p).join(""), l.regex = new RegExp(d, "i"),
|
|
2137
|
+
const h = [...u];
|
|
2138
|
+
return h[0] = h[0].toLowerCase(), d += h.join(""), l.move = h.length, d += [...a].map((p) => t[p] || p).join(""), l.regex = new RegExp(d, "i"), c.length && c.split(" ").forEach((p) => {
|
|
2139
2139
|
p && l.visemes.push(p);
|
|
2140
2140
|
}), l;
|
|
2141
2141
|
});
|
|
@@ -2267,8 +2267,8 @@ class lt {
|
|
|
2267
2267
|
const s = i[e.i], o = this.rules[s];
|
|
2268
2268
|
if (o) {
|
|
2269
2269
|
let r = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const a = o[
|
|
2270
|
+
for (let u = 0; u < o.length; u++) {
|
|
2271
|
+
const a = o[u];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
|
|
2273
2273
|
a.visemes.forEach((d) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
@@ -2289,11 +2289,11 @@ class lt {
|
|
|
2289
2289
|
return e;
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
|
-
const
|
|
2292
|
+
const mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2293
2293
|
__proto__: null,
|
|
2294
|
-
LipsyncFr:
|
|
2294
|
+
LipsyncFr: dt
|
|
2295
2295
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2296
|
-
class
|
|
2296
|
+
class pt {
|
|
2297
2297
|
/**
|
|
2298
2298
|
* @constructor
|
|
2299
2299
|
*/
|
|
@@ -2381,10 +2381,10 @@ class ct {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let n = parseFloat(t);
|
|
2383
2383
|
if (n === void 0) return t;
|
|
2384
|
-
let i = (s, o, r,
|
|
2384
|
+
let i = (s, o, r, u, a) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(r + (
|
|
2386
|
+
const c = Math.floor(s / o);
|
|
2387
|
+
return e.push(r + (c === 1 ? u : this.numberToFinnishWords(c.toString()) + a)), s - c * 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,11 +2436,11 @@ class ct {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const gt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
|
-
LipsyncFi:
|
|
2441
|
+
LipsyncFi: pt
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class yt {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2559,10 +2559,10 @@ class dt {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let n = parseFloat(t);
|
|
2561
2561
|
if (n === void 0) return t;
|
|
2562
|
-
let i = (s, o, r,
|
|
2562
|
+
let i = (s, o, r, u, a) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
2564
|
+
const c = Math.floor(s / o);
|
|
2565
|
+
return c === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(c.toString())), c % 10 === 1 ? e.push(r) : c % 10 === 0 || c % 100 > 10 && c % 100 < 20 ? e.push(a) : e.push(u), s - c * 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 dt {
|
|
|
2608
2608
|
const o = i[s].toLowerCase(), r = this.visemes[o];
|
|
2609
2609
|
if (r)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const u = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += u, n += u;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(r), e.times.push(n), e.durations.push(
|
|
2614
|
+
const u = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(r), e.times.push(n), e.durations.push(u), n += u;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
n += this.pauses[i[s]] || 0;
|
|
@@ -2620,24 +2620,24 @@ class dt {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const ft = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), pt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), We = {
|
|
2627
|
-
en:
|
|
2628
|
-
de:
|
|
2629
|
-
fr:
|
|
2630
|
-
fi:
|
|
2631
|
-
lt:
|
|
2632
|
-
},
|
|
2625
|
+
LipsyncLt: yt
|
|
2626
|
+
}, Symbol.toStringTag, { value: "Module" })), xt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ze = {
|
|
2627
|
+
en: ct,
|
|
2628
|
+
de: ht,
|
|
2629
|
+
fr: mt,
|
|
2630
|
+
fi: gt,
|
|
2631
|
+
lt: ft
|
|
2632
|
+
}, oe = new x.Quaternion(), _ = new x.Euler(), Le = new x.Vector3(), Se = new x.Vector3(), Xe = new x.Box3();
|
|
2633
2633
|
new x.Matrix4();
|
|
2634
2634
|
new x.Matrix4();
|
|
2635
2635
|
new x.Vector3();
|
|
2636
2636
|
new x.Vector3(0, 0, 1);
|
|
2637
|
-
const
|
|
2637
|
+
const bt = new x.Vector3(1, 0, 0);
|
|
2638
2638
|
new x.Vector3(0, 1, 0);
|
|
2639
2639
|
new x.Vector3(0, 0, 1);
|
|
2640
|
-
class
|
|
2640
|
+
class Ue {
|
|
2641
2641
|
/**
|
|
2642
2642
|
* Avatar.
|
|
2643
2643
|
* @typedef {Object} Avatar
|
|
@@ -2763,7 +2763,7 @@ class Oe {
|
|
|
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 nt(), 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 Oe {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((r) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[r +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[r +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
|
|
3573
|
+
this.poseDelta.props[r + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
|
|
3575
|
+
this.poseDelta.props[r + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[r + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[r + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const n = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((r) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(r.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(r.props)).forEach((u) => n.add(u));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((r) => {
|
|
3582
3582
|
n.add(r);
|
|
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 Oe {
|
|
|
4086
4086
|
this.opt.lightSpotDispersion
|
|
4087
4087
|
), this.setLighting(this.opt);
|
|
4088
4088
|
const r = new x.PMREMGenerator(this.renderer);
|
|
4089
|
-
r.compileEquirectangularShader(), this.scene.environment = r.fromScene(new
|
|
4089
|
+
r.compileEquirectangularShader(), this.scene.environment = r.fromScene(new tt()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new $e(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 x.SkinnedMesh();
|
|
4092
4092
|
const s = {
|
|
@@ -4101,17 +4101,17 @@ class Oe {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, o = [];
|
|
4104
|
-
Object.entries(s).forEach((r,
|
|
4104
|
+
Object.entries(s).forEach((r, u) => {
|
|
4105
4105
|
const a = new x.Bone();
|
|
4106
4106
|
a.name = r[0], r[1] ? this.ikMesh.getObjectByName(r[1]).add(a) : this.ikMesh.add(a), o.push(a);
|
|
4107
|
-
}), this.ikMesh.bind(new x.Skeleton(o)), this.dynamicbones = new
|
|
4107
|
+
}), this.ikMesh.bind(new x.Skeleton(o)), this.dynamicbones = new at(), 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 rt(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 Oe {
|
|
|
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, r,
|
|
4153
|
+
let s, o = 0, r, u, a, c;
|
|
4154
4154
|
for (s = 0; s < t.length; s += 4)
|
|
4155
|
-
r = this.b64Lookup[t.charCodeAt(s)],
|
|
4155
|
+
r = this.b64Lookup[t.charCodeAt(s)], u = this.b64Lookup[t.charCodeAt(s + 1)], a = this.b64Lookup[t.charCodeAt(s + 2)], c = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = r << 2 | u >> 4, i[o++] = (u & 15) << 4 | a >> 2, i[o++] = (a & 3) << 6 | c & 63;
|
|
4156
4156
|
return n;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class Oe {
|
|
|
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, r = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[n] = new x.Vector3(o, r,
|
|
4196
|
+
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, r = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, u = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[n] = new x.Vector3(o, r, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new x.Quaternion().setFromEuler(new x.Euler(o, r, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new x.Quaternion(o, r, u, i.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class Oe {
|
|
|
4222
4222
|
t.forEach((s) => {
|
|
4223
4223
|
if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const o = s.geometry;
|
|
4225
|
-
let r = null,
|
|
4226
|
-
for (const [a,
|
|
4225
|
+
let r = null, u = null;
|
|
4226
|
+
for (const [a, c] of Object.entries(n))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(a)) {
|
|
4228
4228
|
const l = s.morphTargetDictionary[a], d = o.morphAttributes.position[l], h = o.morphAttributes.normal?.[l];
|
|
4229
|
-
r || (r = new x.Float32BufferAttribute(d.count * 3, 3), h && (
|
|
4229
|
+
r || (r = new x.Float32BufferAttribute(d.count * 3, 3), h && (u = new x.Float32BufferAttribute(d.count * 3, 3)));
|
|
4230
4230
|
for (let p = 0; p < d.count; p++) {
|
|
4231
|
-
const b = r.getX(p) + d.getX(p) *
|
|
4231
|
+
const b = r.getX(p) + d.getX(p) * c, f = r.getY(p) + d.getY(p) * c, S = r.getZ(p) + d.getZ(p) * c;
|
|
4232
4232
|
r.setXYZ(p, b, f, S);
|
|
4233
4233
|
}
|
|
4234
4234
|
if (h)
|
|
4235
4235
|
for (let p = 0; p < d.count; p++) {
|
|
4236
|
-
const b =
|
|
4237
|
-
|
|
4236
|
+
const b = u.getX(p) + h.getX(p) * c, f = u.getY(p) + h.getY(p) * c, S = u.getZ(p) + h.getZ(p) * c;
|
|
4237
|
+
u.setXYZ(p, b, f, S);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (r) {
|
|
4241
|
-
o.morphAttributes.position.push(r),
|
|
4241
|
+
o.morphAttributes.position.push(r), u && o.morphAttributes.normal.push(u);
|
|
4242
4242
|
const a = o.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[a] = 0, s.morphTargetDictionary[e] = a;
|
|
4244
4244
|
}
|
|
@@ -4252,9 +4252,9 @@ class Oe {
|
|
|
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 Je();
|
|
4256
4256
|
if (this.dracoEnabled) {
|
|
4257
|
-
const a = new
|
|
4257
|
+
const a = new et();
|
|
4258
4258
|
a.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(a);
|
|
4259
4259
|
}
|
|
4260
4260
|
let i = await n.loadAsync(t.url, e);
|
|
@@ -4268,7 +4268,7 @@ class Oe {
|
|
|
4268
4268
|
throw new Error("Blend shapes not found");
|
|
4269
4269
|
const o = new Set(this.mtCustoms);
|
|
4270
4270
|
this.morphs.forEach((a) => {
|
|
4271
|
-
Object.keys(a.morphTargetDictionary).forEach((
|
|
4271
|
+
Object.keys(a.morphTargetDictionary).forEach((c) => o.add(c));
|
|
4272
4272
|
}), this.mtExtras.forEach((a) => {
|
|
4273
4273
|
o.has(a.key) || (this.addMixedMorphTarget(this.morphs, a.key, a.mix), o.add(a.key));
|
|
4274
4274
|
});
|
|
@@ -4295,16 +4295,16 @@ class Oe {
|
|
|
4295
4295
|
ms: [],
|
|
4296
4296
|
is: []
|
|
4297
4297
|
}, r[a].value = r[a].baseline, r[a].applied = r[a].baseline;
|
|
4298
|
-
const
|
|
4299
|
-
|
|
4300
|
-
r[a][l] =
|
|
4298
|
+
const c = this.mtAvatar[a];
|
|
4299
|
+
c && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((l) => {
|
|
4300
|
+
r[a][l] = c[l];
|
|
4301
4301
|
}), this.morphs.forEach((l) => {
|
|
4302
4302
|
const d = l.morphTargetDictionary[a];
|
|
4303
4303
|
d !== void 0 && (r[a].ms.push(l.morphTargetInfluences), r[a].is.push(d), l.morphTargetInfluences[d] = r[a].applied);
|
|
4304
4304
|
});
|
|
4305
4305
|
}), this.mtAvatar = r, this.poseAvatar = { props: {} }, this.posePropNames.forEach((a) => {
|
|
4306
|
-
const
|
|
4307
|
-
this.poseAvatar.props[a] = l[
|
|
4306
|
+
const c = a.split("."), l = this.armature.getObjectByName(c[0]);
|
|
4307
|
+
this.poseAvatar.props[a] = l[c[1]], this.poseBase.props.hasOwnProperty(a) ? this.poseAvatar.props[a].copy(this.poseBase.props[a]) : this.poseBase.props[a] = this.poseAvatar.props[a].clone(), this.poseDelta.props.hasOwnProperty(a) && !this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a] = this.poseAvatar.props[a].clone()), this.poseTarget.props[a].t = this.animClock, this.poseTarget.props[a].d = 2e3;
|
|
4308
4308
|
}), this.ikMesh.traverse((a) => {
|
|
4309
4309
|
a.isBone && a.position.copy(this.armature.getObjectByName(a.name).position);
|
|
4310
4310
|
}), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(i.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), t.hasOwnProperty("modelDynamicBones"))
|
|
@@ -4314,8 +4314,8 @@ class Oe {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + a);
|
|
4315
4315
|
}
|
|
4316
4316
|
this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
|
|
4317
|
-
const
|
|
4318
|
-
this.objectLeftEye.getWorldPosition(
|
|
4317
|
+
const u = new x.Vector3();
|
|
4318
|
+
this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), 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,22 +4343,22 @@ class Oe {
|
|
|
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, r = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let a = -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, r = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let a = -n * Math.tan(u / 2), c = (1 - i) * Math.tan(u / 2), l = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
|
-
l += 2,
|
|
4350
|
+
l += 2, c = c * l + 4 * this.avatarHeight / 5;
|
|
4351
4351
|
break;
|
|
4352
4352
|
case "upper":
|
|
4353
|
-
l += 4.5,
|
|
4353
|
+
l += 4.5, c = c * l + 2 * this.avatarHeight / 3;
|
|
4354
4354
|
break;
|
|
4355
4355
|
case "mid":
|
|
4356
|
-
l += 8,
|
|
4356
|
+
l += 8, c = c * l + this.avatarHeight / 3;
|
|
4357
4357
|
break;
|
|
4358
4358
|
default:
|
|
4359
|
-
l += 12,
|
|
4359
|
+
l += 12, c = c * l;
|
|
4360
4360
|
}
|
|
4361
|
-
a = a * l, this.controlsEnd = new x.Vector3(a,
|
|
4361
|
+
a = a * l, this.controlsEnd = new x.Vector3(a, c, 0), this.cameraEnd = new x.Vector3(a, c, l).applyEuler(new x.Euler(o, r, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
|
|
4362
4362
|
}
|
|
4363
4363
|
/**
|
|
4364
4364
|
* Change light colors and intensities.
|
|
@@ -4414,7 +4414,7 @@ class Oe {
|
|
|
4414
4414
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4415
4415
|
_.set(e.x, e.y, e.z);
|
|
4416
4416
|
const n = this.poseAvatar.props[t];
|
|
4417
|
-
n.isQuaternion ? (
|
|
4417
|
+
n.isQuaternion ? (oe.setFromEuler(_), n.multiply(oe)) : n.isVector3 && n.add(_);
|
|
4418
4418
|
}
|
|
4419
4419
|
}
|
|
4420
4420
|
/**
|
|
@@ -4469,17 +4469,17 @@ class Oe {
|
|
|
4469
4469
|
"HandMiddle",
|
|
4470
4470
|
"HandRing",
|
|
4471
4471
|
"HandPinky"
|
|
4472
|
-
].forEach((
|
|
4473
|
-
l === 0 ? (this.poseDelta.props[o +
|
|
4472
|
+
].forEach((c, l) => {
|
|
4473
|
+
l === 0 ? (this.poseDelta.props[o + c + "1.quaternion"].x = 0, this.poseDelta.props[o + c + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + c + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + c + "1.quaternion"].x = n.applied, this.poseDelta.props[o + c + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + c + "3.quaternion"].x = 1.5 * n.applied);
|
|
4474
4474
|
});
|
|
4475
4475
|
break;
|
|
4476
4476
|
case "chestInhale":
|
|
4477
|
-
const r = n.applied / 20,
|
|
4478
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4477
|
+
const r = n.applied / 20, u = { x: r, y: r / 2, z: 3 * r }, a = { x: 1 / (1 + r) - 1, y: 1 / (1 + r / 2) - 1, z: 1 / (1 + 3 * r) - 1 };
|
|
4478
|
+
this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = a, this.poseDelta.props["LeftArm.scale"] = a, this.poseDelta.props["RightArm.scale"] = a;
|
|
4479
4479
|
break;
|
|
4480
4480
|
default:
|
|
4481
|
-
for (let
|
|
4482
|
-
n.ms[
|
|
4481
|
+
for (let c = 0, l = n.ms.length; c < l; c++)
|
|
4482
|
+
n.ms[c][n.is[c]] = n.applied;
|
|
4483
4483
|
}
|
|
4484
4484
|
}
|
|
4485
4485
|
}
|
|
@@ -4494,8 +4494,8 @@ class Oe {
|
|
|
4494
4494
|
return Object.entries(t).forEach((i, s) => {
|
|
4495
4495
|
const o = i[0].split(".");
|
|
4496
4496
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4497
|
-
const r = o[1] === "quaternion" ? o[0] + ".rotation" : i[0],
|
|
4498
|
-
n += (s ? ", " : "") + "'" + r + "':{", n += "x:" + Math.round(
|
|
4497
|
+
const r = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new x.Euler().setFromQuaternion(i[1]) : i[1];
|
|
4498
|
+
n += (s ? ", " : "") + "'" + r + "':{", n += "x:" + Math.round(u.x * e) / e, n += ", y:" + Math.round(u.y * e) / e, n += ", z:" + Math.round(u.z * e) / e, n += "}";
|
|
4499
4499
|
}
|
|
4500
4500
|
}), n += "}", n;
|
|
4501
4501
|
}
|
|
@@ -4565,8 +4565,8 @@ class Oe {
|
|
|
4565
4565
|
if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4566
4566
|
this.setPoseFromTemplate(t, e);
|
|
4567
4567
|
}, 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)
|
|
4568
|
-
for (let [r,
|
|
4569
|
-
this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r].copy(
|
|
4568
|
+
for (let [r, u] of Object.entries(this.gesture))
|
|
4569
|
+
this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r].copy(u), this.poseTarget.props[r].t = u.t, this.poseTarget.props[r].d = u.d);
|
|
4570
4570
|
Object.keys(this.poseDelta.props).forEach((r) => {
|
|
4571
4571
|
this.poseTarget.props.hasOwnProperty(r) || (this.poseTarget.props[r] = this.poseBase.props[r].clone(), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = o);
|
|
4572
4572
|
});
|
|
@@ -4999,11 +4999,11 @@ class Oe {
|
|
|
4999
4999
|
else if (r.hasOwnProperty("alt")) {
|
|
5000
5000
|
let a = r.alt[0];
|
|
5001
5001
|
if (r.alt.length > 1) {
|
|
5002
|
-
const
|
|
5002
|
+
const c = Math.random();
|
|
5003
5003
|
let l = 0;
|
|
5004
5004
|
for (let d = 0; d < r.alt.length; d++) {
|
|
5005
5005
|
let h = this.valueFn(r.alt[d].p);
|
|
5006
|
-
if (l += h === void 0 ? (1 - l) / (r.alt.length - 1 - d) : h,
|
|
5006
|
+
if (l += h === void 0 ? (1 - l) / (r.alt.length - 1 - d) : h, c < l) {
|
|
5007
5007
|
a = r.alt[d];
|
|
5008
5008
|
break;
|
|
5009
5009
|
}
|
|
@@ -5013,19 +5013,19 @@ class Oe {
|
|
|
5013
5013
|
continue;
|
|
5014
5014
|
} else
|
|
5015
5015
|
break;
|
|
5016
|
-
let
|
|
5017
|
-
if (Array.isArray(
|
|
5018
|
-
r.dt.forEach((a,
|
|
5016
|
+
let u = this.valueFn(r.delay) || 0;
|
|
5017
|
+
if (Array.isArray(u) && (u = this.gaussianRandom(...u)), r.hasOwnProperty("dt"))
|
|
5018
|
+
r.dt.forEach((a, c) => {
|
|
5019
5019
|
let l = this.valueFn(a);
|
|
5020
|
-
Array.isArray(l) && (l = this.gaussianRandom(...l)), o.ts[
|
|
5020
|
+
Array.isArray(l) && (l = this.gaussianRandom(...l)), o.ts[c + 1] = o.ts[c] + l;
|
|
5021
5021
|
});
|
|
5022
5022
|
else {
|
|
5023
|
-
let a = Object.values(r.vs).reduce((
|
|
5023
|
+
let a = Object.values(r.vs).reduce((c, l) => l.length > c ? l.length : c, 0);
|
|
5024
5024
|
o.ts = Array(a + 1).fill(0);
|
|
5025
5025
|
}
|
|
5026
|
-
s ? o.ts = o.ts.map((a) =>
|
|
5027
|
-
for (let [a,
|
|
5028
|
-
const l = this.getBaselineValue(a), d =
|
|
5026
|
+
s ? o.ts = o.ts.map((a) => u + a * n) : o.ts = o.ts.map((a) => this.animClock + u + a * n), r.vs && r.vs.pose && console.log("Pose being selected from vs.pose:", r.vs.pose, "for avatar body:", this.avatar?.body);
|
|
5027
|
+
for (let [a, c] of Object.entries(r.vs)) {
|
|
5028
|
+
const l = this.getBaselineValue(a), d = c.map((h) => (h = this.valueFn(h), h === null ? null : typeof h == "function" ? h : typeof h == "string" || h instanceof String ? a === "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) ? a === "gesture" ? h.slice() : (l === void 0 ? 0 : l) + i * this.gaussianRandom(...h) : typeof h == "boolean" ? h : h instanceof Object && h.constructor === Object ? Object.assign({}, h) : (l === void 0 ? 0 : l) + i * h));
|
|
5029
5029
|
a === "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)]) : a === "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[a] = [null, ...d];
|
|
5030
5030
|
}
|
|
5031
5031
|
for (let a of Object.keys(o.vs))
|
|
@@ -5107,8 +5107,8 @@ class Oe {
|
|
|
5107
5107
|
if (this.isSpeaking)
|
|
5108
5108
|
for (r = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5109
5109
|
this.volumeFrequencyData[n] > r && (r = this.volumeFrequencyData[n]);
|
|
5110
|
-
let
|
|
5111
|
-
const
|
|
5110
|
+
let u = null, a = null;
|
|
5111
|
+
const c = [];
|
|
5112
5112
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5113
5113
|
const l = this.animQueue[n];
|
|
5114
5114
|
if (!(!l || !l.ts || !l.ts.length || this.animClock < l.ts[0])) {
|
|
@@ -5135,12 +5135,12 @@ class Oe {
|
|
|
5135
5135
|
p.newvalue *= 1 + r / 255 - 0.5;
|
|
5136
5136
|
}
|
|
5137
5137
|
p.needsUpdate = !0;
|
|
5138
|
-
} else d === "eyeContact" && h[i] !== null &&
|
|
5138
|
+
} else d === "eyeContact" && h[i] !== null && u !== !1 ? u = !!h[i] : d === "headMove" && h[i] !== null && a !== !1 ? h[i] === 0 ? a = !1 : (Math.random() < h[i] && (a = !0), h[i] = null) : h[i] !== null && (c.push({ mt: d, val: h[i] }), h[i] = null);
|
|
5139
5139
|
i === o ? (l.hasOwnProperty("mood") && this.setMood(l.mood), l.loop ? (o = this.isSpeaking && (l.template.name === "head" || l.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(l.template, l.loop > 0 ? l.loop - 1 : l.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : l.ndx = i - 1;
|
|
5140
5140
|
}
|
|
5141
5141
|
}
|
|
5142
|
-
for (let l = 0, d =
|
|
5143
|
-
switch (i =
|
|
5142
|
+
for (let l = 0, d = c.length; l < d; l++)
|
|
5143
|
+
switch (i = c[l].val, c[l].mt) {
|
|
5144
5144
|
case "speak":
|
|
5145
5145
|
this.speakText(i);
|
|
5146
5146
|
break;
|
|
@@ -5186,7 +5186,7 @@ class Oe {
|
|
|
5186
5186
|
}, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5187
5187
|
break;
|
|
5188
5188
|
}
|
|
5189
|
-
if ((
|
|
5189
|
+
if ((u || a) && (_.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), _.x = Math.max(-0.9, Math.min(0.9, 2 * _.x - 0.5)), _.y = Math.max(-0.9, Math.min(0.9, -2.5 * _.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: _.x < 0 ? -_.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: _.x < 0 ? 0 : _.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: _.y < 0 ? -_.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: _.y < 0 ? 0 : _.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: _.y < 0 ? 0 : _.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: _.y < 0 ? -_.y : 0, needsUpdate: !0 }), a && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5190
5190
|
name: "headmove",
|
|
5191
5191
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5192
5192
|
vs: {
|
|
@@ -5207,7 +5207,7 @@ class Oe {
|
|
|
5207
5207
|
eyeLookOutRight: [null, 0],
|
|
5208
5208
|
eyeContact: [0]
|
|
5209
5209
|
}
|
|
5210
|
-
})))), 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 + r / 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) &&
|
|
5210
|
+
})))), 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 + r / 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) && u ? r > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = r) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), 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 && (oe.setFromAxisAngle(bt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(oe)), Xe.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Le), Le.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Se), Se.sub(this.armature.position), this.objectHips.position.y -= Xe.min.y / 2, this.objectHips.position.x -= (Le.x + Se.x) / 4, this.objectHips.position.z -= (Le.z + Se.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5211
5211
|
this.stats && this.stats.end();
|
|
5212
5212
|
else {
|
|
5213
5213
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5238,8 +5238,8 @@ class Oe {
|
|
|
5238
5238
|
if (!this.lipsync.hasOwnProperty(t)) {
|
|
5239
5239
|
const n = t.toLowerCase(), i = "Lipsync" + t.charAt(0).toUpperCase() + t.slice(1);
|
|
5240
5240
|
try {
|
|
5241
|
-
const s =
|
|
5242
|
-
s && s[i] ? (this.lipsync[t] = new s[i](), console.log(`Loaded lip-sync module for ${t}`)) : console.warn(`Lip-sync module for ${t} not found. Available modules:`, Object.keys(
|
|
5241
|
+
const s = Ze[n];
|
|
5242
|
+
s && s[i] ? (this.lipsync[t] = new s[i](), console.log(`Loaded lip-sync module for ${t}`)) : console.warn(`Lip-sync module for ${t} not found. Available modules:`, Object.keys(Ze));
|
|
5243
5243
|
} catch (s) {
|
|
5244
5244
|
console.warn(`Failed to load lip-sync module for ${t}:`, s);
|
|
5245
5245
|
}
|
|
@@ -5274,34 +5274,34 @@ class Oe {
|
|
|
5274
5274
|
*/
|
|
5275
5275
|
speakText(t, e = null, n = null, i = null) {
|
|
5276
5276
|
e = e || {};
|
|
5277
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, r = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5278
|
-
let
|
|
5277
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, r = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, a = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5278
|
+
let c = "", l = "", d = 0, h = [], p = [];
|
|
5279
5279
|
const b = Array.from(this.segmenter.segment(t), (f) => f.segment);
|
|
5280
5280
|
for (let f = 0; f < b.length; f++) {
|
|
5281
|
-
const S = f === b.length - 1,
|
|
5281
|
+
const S = f === b.length - 1, B = b[f].match(r);
|
|
5282
5282
|
let g = b[f].match(s);
|
|
5283
|
-
const
|
|
5284
|
-
if (g && !S && !
|
|
5283
|
+
const D = b[f].match(u), T = b[f].match(o);
|
|
5284
|
+
if (g && !S && !D && b[f + 1].match(s) && (g = !1), n && (c += b[f]), B && (!i || i.every((I) => f < I[0] || f > I[1])) && (l += b[f]), (T || g || S) && (l.length && (l = this.lipsyncPreProcessText(l, a), l.length && h.push({
|
|
5285
5285
|
mark: d,
|
|
5286
5286
|
word: l
|
|
5287
|
-
})),
|
|
5287
|
+
})), c.length && (p.push({
|
|
5288
5288
|
mark: d,
|
|
5289
5289
|
template: { name: "subtitles" },
|
|
5290
5290
|
ts: [0],
|
|
5291
5291
|
vs: {
|
|
5292
|
-
subtitles: [
|
|
5292
|
+
subtitles: [c]
|
|
5293
5293
|
}
|
|
5294
|
-
}),
|
|
5295
|
-
const
|
|
5296
|
-
if (
|
|
5297
|
-
const
|
|
5298
|
-
for (let L = 0; L <
|
|
5294
|
+
}), c = ""), l.length)) {
|
|
5295
|
+
const I = this.lipsyncWordsToVisemes(l, a);
|
|
5296
|
+
if (I && I.visemes && I.visemes.length) {
|
|
5297
|
+
const N = I.times[I.visemes.length - 1] + I.durations[I.visemes.length - 1];
|
|
5298
|
+
for (let L = 0; L < I.visemes.length; L++)
|
|
5299
5299
|
p.push({
|
|
5300
5300
|
mark: d,
|
|
5301
5301
|
template: { name: "viseme" },
|
|
5302
|
-
ts: [(
|
|
5302
|
+
ts: [(I.times[L] - 0.6) / N, (I.times[L] + 0.5) / N, (I.times[L] + I.durations[L] + 0.5) / N],
|
|
5303
5303
|
vs: {
|
|
5304
|
-
["viseme_" +
|
|
5304
|
+
["viseme_" + I.visemes[L]]: [null, I.visemes[L] === "PP" || I.visemes[L] === "FF" ? 0.9 : 0.6, 0]
|
|
5305
5305
|
}
|
|
5306
5306
|
});
|
|
5307
5307
|
}
|
|
@@ -5309,14 +5309,14 @@ class Oe {
|
|
|
5309
5309
|
}
|
|
5310
5310
|
if (g || S) {
|
|
5311
5311
|
if (h.length || S && p.length) {
|
|
5312
|
-
const
|
|
5312
|
+
const I = {
|
|
5313
5313
|
anim: p
|
|
5314
5314
|
};
|
|
5315
|
-
n && (
|
|
5315
|
+
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 = [], l = "", d = 0, p = [];
|
|
5316
5316
|
}
|
|
5317
|
-
if (
|
|
5318
|
-
let
|
|
5319
|
-
|
|
5317
|
+
if (D) {
|
|
5318
|
+
let I = this.animEmojis[b[f]];
|
|
5319
|
+
I && I.link && (I = this.animEmojis[I.link]), I && this.speechQueue.push({ emoji: I });
|
|
5320
5320
|
}
|
|
5321
5321
|
this.speechQueue.push({ break: 100 });
|
|
5322
5322
|
}
|
|
@@ -5397,25 +5397,25 @@ class Oe {
|
|
|
5397
5397
|
if (t.words) {
|
|
5398
5398
|
let o = [];
|
|
5399
5399
|
for (let r = 0; r < t.words.length; r++) {
|
|
5400
|
-
const
|
|
5401
|
-
let
|
|
5402
|
-
if (
|
|
5400
|
+
const u = t.words[r], a = t.wtimes[r];
|
|
5401
|
+
let c = t.wdurations[r];
|
|
5402
|
+
if (u.length && (n && o.push({
|
|
5403
5403
|
template: { name: "subtitles" },
|
|
5404
5404
|
ts: [a],
|
|
5405
5405
|
vs: {
|
|
5406
|
-
subtitles: [" " +
|
|
5406
|
+
subtitles: [" " + u]
|
|
5407
5407
|
}
|
|
5408
5408
|
}), !t.visemes)) {
|
|
5409
|
-
const l = this.lipsyncPreProcessText(
|
|
5409
|
+
const l = this.lipsyncPreProcessText(u, i), d = this.lipsyncWordsToVisemes(l, i);
|
|
5410
5410
|
if (d && d.visemes && d.visemes.length) {
|
|
5411
|
-
const h = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], p = Math.min(
|
|
5412
|
-
let b = 0.6 + this.convertRange(p, [0,
|
|
5413
|
-
if (
|
|
5411
|
+
const h = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], p = Math.min(c, Math.max(0, c - d.visemes.length * 150));
|
|
5412
|
+
let b = 0.6 + this.convertRange(p, [0, c], [0, 0.4]);
|
|
5413
|
+
if (c = Math.min(c, d.visemes.length * 200), h > 0)
|
|
5414
5414
|
for (let f = 0; f < d.visemes.length; f++) {
|
|
5415
|
-
const S = a + d.times[f] / h *
|
|
5415
|
+
const S = a + d.times[f] / h * c, B = d.durations[f] / h * c;
|
|
5416
5416
|
o.push({
|
|
5417
5417
|
template: { name: "viseme" },
|
|
5418
|
-
ts: [S - Math.min(60, 2 *
|
|
5418
|
+
ts: [S - Math.min(60, 2 * B / 3), S + Math.min(25, B / 2), S + B + Math.min(60, B / 2)],
|
|
5419
5419
|
vs: {
|
|
5420
5420
|
["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : b, 0]
|
|
5421
5421
|
}
|
|
@@ -5426,22 +5426,22 @@ class Oe {
|
|
|
5426
5426
|
}
|
|
5427
5427
|
if (t.visemes)
|
|
5428
5428
|
for (let r = 0; r < t.visemes.length; r++) {
|
|
5429
|
-
const
|
|
5429
|
+
const u = t.visemes[r], a = t.vtimes[r], c = t.vdurations[r];
|
|
5430
5430
|
o.push({
|
|
5431
5431
|
template: { name: "viseme" },
|
|
5432
|
-
ts: [a - 2 *
|
|
5432
|
+
ts: [a - 2 * c / 3, a + c / 2, a + c + c / 2],
|
|
5433
5433
|
vs: {
|
|
5434
|
-
["viseme_" +
|
|
5434
|
+
["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
|
|
5435
5435
|
}
|
|
5436
5436
|
});
|
|
5437
5437
|
}
|
|
5438
5438
|
if (t.markers)
|
|
5439
5439
|
for (let r = 0; r < t.markers.length; r++) {
|
|
5440
|
-
const
|
|
5440
|
+
const u = t.markers[r], a = t.mtimes[r];
|
|
5441
5441
|
o.push({
|
|
5442
5442
|
template: { name: "markers" },
|
|
5443
5443
|
ts: [a],
|
|
5444
|
-
vs: { function: [
|
|
5444
|
+
vs: { function: [u] }
|
|
5445
5445
|
});
|
|
5446
5446
|
}
|
|
5447
5447
|
o.length && (s.anim = o);
|
|
@@ -5461,7 +5461,7 @@ class Oe {
|
|
|
5461
5461
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5462
5462
|
const e = this.audioPlaylist.shift();
|
|
5463
5463
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5464
|
-
const s = this.audioCtx.resume(), o = new Promise((r,
|
|
5464
|
+
const s = this.audioCtx.resume(), o = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
|
|
5465
5465
|
try {
|
|
5466
5466
|
await Promise.race([s, o]);
|
|
5467
5467
|
} catch {
|
|
@@ -5493,11 +5493,11 @@ class Oe {
|
|
|
5493
5493
|
*/
|
|
5494
5494
|
async synthesizeWithBrowserTTS(t) {
|
|
5495
5495
|
return new Promise((e, n) => {
|
|
5496
|
-
const i = t.text.map((g) => g.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", r = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5497
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, r)), s.pitch = Math.max(0, Math.min(2,
|
|
5498
|
-
const
|
|
5499
|
-
if (l &&
|
|
5500
|
-
const g =
|
|
5496
|
+
const i = t.text.map((g) => g.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", r = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, a = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5497
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, r)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, a));
|
|
5498
|
+
const c = speechSynthesis.getVoices(), l = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5499
|
+
if (l && c.length > 0) {
|
|
5500
|
+
const g = c.find((D) => D.name.includes(l) || D.lang === o);
|
|
5501
5501
|
g && (s.voice = g);
|
|
5502
5502
|
}
|
|
5503
5503
|
const d = i.length * 100 / s.rate, h = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), p = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", b = this.lipsyncPreProcessText(i, p), f = this.lipsyncWordsToVisemes(b, p);
|
|
@@ -5512,8 +5512,8 @@ class Oe {
|
|
|
5512
5512
|
const S = [];
|
|
5513
5513
|
if (f && f.visemes && f.visemes.length > 0) {
|
|
5514
5514
|
const g = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5515
|
-
for (let
|
|
5516
|
-
const T = f.visemes[
|
|
5515
|
+
for (let D = 0; D < f.visemes.length; D++) {
|
|
5516
|
+
const T = f.visemes[D], I = f.times[D] / g, N = f.durations[D] / g, L = I * d, R = N * d;
|
|
5517
5517
|
S.push({
|
|
5518
5518
|
template: { name: "viseme" },
|
|
5519
5519
|
ts: [L - Math.min(60, 2 * R / 3), L + Math.min(25, R / 2), L + R + Math.min(60, R / 2)],
|
|
@@ -5523,8 +5523,8 @@ class Oe {
|
|
|
5523
5523
|
});
|
|
5524
5524
|
}
|
|
5525
5525
|
}
|
|
5526
|
-
const
|
|
5527
|
-
this.audioPlaylist.push({ anim:
|
|
5526
|
+
const B = [...t.anim, ...S];
|
|
5527
|
+
this.audioPlaylist.push({ anim: B, audio: h }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5528
5528
|
e();
|
|
5529
5529
|
}, s.onerror = (g) => {
|
|
5530
5530
|
console.error("Speech synthesis error:", g.error), n(g.error);
|
|
@@ -5558,15 +5558,15 @@ class Oe {
|
|
|
5558
5558
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5559
5559
|
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5560
5560
|
console.log("Using text-based lip-sync for debugging...");
|
|
5561
|
-
const
|
|
5561
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5562
5562
|
let a;
|
|
5563
5563
|
try {
|
|
5564
5564
|
console.log("Lip-sync modules available:", {
|
|
5565
5565
|
hasLipsync: !!this.lipsync,
|
|
5566
5566
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5567
|
-
lipsyncLang:
|
|
5567
|
+
lipsyncLang: u
|
|
5568
5568
|
});
|
|
5569
|
-
const d = this.lipsyncPreProcessText(e,
|
|
5569
|
+
const d = this.lipsyncPreProcessText(e, u), h = this.lipsyncWordsToVisemes(d, u);
|
|
5570
5570
|
if (console.log("Lip-sync data:", {
|
|
5571
5571
|
processedText: d,
|
|
5572
5572
|
lipsyncData: h,
|
|
@@ -5619,12 +5619,12 @@ class Oe {
|
|
|
5619
5619
|
visemes: a.visemes ? a.visemes.slice(0, 3) : []
|
|
5620
5620
|
// Show first 3 visemes for debugging
|
|
5621
5621
|
});
|
|
5622
|
-
const
|
|
5622
|
+
const c = [];
|
|
5623
5623
|
if (a.visemes && a.visemes.length > 0) {
|
|
5624
5624
|
console.log("ElevenLabs: Generating lip-sync animation from", a.visemes.length, "visemes");
|
|
5625
5625
|
for (let d = 0; d < a.visemes.length; d++) {
|
|
5626
5626
|
const h = a.visemes[d], p = h.startTime * 1e3, b = h.duration * 1e3, f = h.intensity;
|
|
5627
|
-
|
|
5627
|
+
c.push({
|
|
5628
5628
|
template: { name: "viseme" },
|
|
5629
5629
|
ts: [p - Math.min(60, 2 * b / 3), p + Math.min(25, b / 2), p + b + Math.min(60, b / 2)],
|
|
5630
5630
|
vs: {
|
|
@@ -5632,11 +5632,11 @@ class Oe {
|
|
|
5632
5632
|
}
|
|
5633
5633
|
});
|
|
5634
5634
|
}
|
|
5635
|
-
console.log("ElevenLabs: Generated",
|
|
5635
|
+
console.log("ElevenLabs: Generated", c.length, "lip-sync animation frames");
|
|
5636
5636
|
} else
|
|
5637
5637
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5638
|
-
const l = [...t.anim, ...
|
|
5639
|
-
console.log("ElevenLabs: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5638
|
+
const l = [...t.anim, ...c];
|
|
5639
|
+
console.log("ElevenLabs: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:", c.length, ")"), this.audioPlaylist.push({ anim: l, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5640
5640
|
}
|
|
5641
5641
|
/**
|
|
5642
5642
|
* Synthesize speech using Deepgram Aura-2 TTS
|
|
@@ -5656,15 +5656,15 @@ class Oe {
|
|
|
5656
5656
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5657
5657
|
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5658
5658
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5659
|
-
const
|
|
5659
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5660
5660
|
let a;
|
|
5661
5661
|
try {
|
|
5662
5662
|
console.log("Lip-sync modules available:", {
|
|
5663
5663
|
hasLipsync: !!this.lipsync,
|
|
5664
5664
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5665
|
-
lipsyncLang:
|
|
5665
|
+
lipsyncLang: u
|
|
5666
5666
|
});
|
|
5667
|
-
const d = this.lipsyncPreProcessText(e,
|
|
5667
|
+
const d = this.lipsyncPreProcessText(e, u), h = this.lipsyncWordsToVisemes(d, u);
|
|
5668
5668
|
if (console.log("Lip-sync data:", {
|
|
5669
5669
|
processedText: d,
|
|
5670
5670
|
lipsyncData: h,
|
|
@@ -5717,12 +5717,12 @@ class Oe {
|
|
|
5717
5717
|
visemes: a.visemes ? a.visemes.slice(0, 3) : []
|
|
5718
5718
|
// Show first 3 visemes for debugging
|
|
5719
5719
|
});
|
|
5720
|
-
const
|
|
5720
|
+
const c = [];
|
|
5721
5721
|
if (a.visemes && a.visemes.length > 0) {
|
|
5722
5722
|
console.log("Deepgram: Generating lip-sync animation from", a.visemes.length, "visemes");
|
|
5723
5723
|
for (let d = 0; d < a.visemes.length; d++) {
|
|
5724
5724
|
const h = a.visemes[d], p = h.startTime * 1e3, b = h.duration * 1e3, f = h.intensity;
|
|
5725
|
-
|
|
5725
|
+
c.push({
|
|
5726
5726
|
template: { name: "viseme" },
|
|
5727
5727
|
ts: [p - Math.min(60, 2 * b / 3), p + Math.min(25, b / 2), p + b + Math.min(60, b / 2)],
|
|
5728
5728
|
vs: {
|
|
@@ -5730,11 +5730,11 @@ class Oe {
|
|
|
5730
5730
|
}
|
|
5731
5731
|
});
|
|
5732
5732
|
}
|
|
5733
|
-
console.log("Deepgram: Generated",
|
|
5733
|
+
console.log("Deepgram: Generated", c.length, "lip-sync animation frames");
|
|
5734
5734
|
} else
|
|
5735
5735
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5736
|
-
const l = [...t.anim, ...
|
|
5737
|
-
console.log("Deepgram: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5736
|
+
const l = [...t.anim, ...c];
|
|
5737
|
+
console.log("Deepgram: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:", c.length, ")"), this.audioPlaylist.push({ anim: l, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5738
5738
|
}
|
|
5739
5739
|
/**
|
|
5740
5740
|
* Synthesize speech using Azure TTS
|
|
@@ -5760,20 +5760,20 @@ class Oe {
|
|
|
5760
5760
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5761
5761
|
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5762
5762
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5763
|
-
const
|
|
5763
|
+
const u = await this.audioAnalyzer.analyzeAudio(r, e);
|
|
5764
5764
|
console.log("Azure TTS Audio Analysis:", {
|
|
5765
5765
|
text: e,
|
|
5766
5766
|
audioDuration: r.duration,
|
|
5767
|
-
visemeCount:
|
|
5768
|
-
wordCount:
|
|
5767
|
+
visemeCount: u.visemes.length,
|
|
5768
|
+
wordCount: u.words.length,
|
|
5769
5769
|
features: {
|
|
5770
|
-
onsets:
|
|
5771
|
-
boundaries:
|
|
5770
|
+
onsets: u.features.onsets.length,
|
|
5771
|
+
boundaries: u.features.phonemeBoundaries.length
|
|
5772
5772
|
}
|
|
5773
5773
|
});
|
|
5774
5774
|
const a = [];
|
|
5775
|
-
for (let l = 0; l <
|
|
5776
|
-
const d =
|
|
5775
|
+
for (let l = 0; l < u.visemes.length; l++) {
|
|
5776
|
+
const d = u.visemes[l], h = d.startTime * 1e3, p = d.duration * 1e3, b = d.intensity;
|
|
5777
5777
|
a.push({
|
|
5778
5778
|
template: { name: "viseme" },
|
|
5779
5779
|
ts: [h - Math.min(60, 2 * p / 3), h + Math.min(25, p / 2), h + p + Math.min(60, p / 2)],
|
|
@@ -5782,8 +5782,8 @@ class Oe {
|
|
|
5782
5782
|
}
|
|
5783
5783
|
});
|
|
5784
5784
|
}
|
|
5785
|
-
const
|
|
5786
|
-
this.audioPlaylist.push({ anim:
|
|
5785
|
+
const c = [...t.anim, ...a];
|
|
5786
|
+
this.audioPlaylist.push({ anim: c, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5787
5787
|
}
|
|
5788
5788
|
/**
|
|
5789
5789
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5822,24 +5822,24 @@ class Oe {
|
|
|
5822
5822
|
if (i.status === 200 && s && s.audioContent) {
|
|
5823
5823
|
const o = this.b64ToArrayBuffer(s.audioContent), r = await this.audioCtx.decodeAudioData(o);
|
|
5824
5824
|
this.speakWithHands();
|
|
5825
|
-
const
|
|
5825
|
+
const u = [0];
|
|
5826
5826
|
let a = 0;
|
|
5827
5827
|
t.text.forEach((d, h) => {
|
|
5828
5828
|
if (h > 0) {
|
|
5829
|
-
let p =
|
|
5830
|
-
s.timepoints[a] && (p = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + d.mark && a++),
|
|
5829
|
+
let p = u[u.length - 1];
|
|
5830
|
+
s.timepoints[a] && (p = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + d.mark && a++), u.push(p);
|
|
5831
5831
|
}
|
|
5832
5832
|
});
|
|
5833
|
-
const
|
|
5834
|
-
|
|
5833
|
+
const c = [{ mark: 0, time: 0 }];
|
|
5834
|
+
u.forEach((d, h) => {
|
|
5835
5835
|
if (h > 0) {
|
|
5836
|
-
let p = d -
|
|
5837
|
-
|
|
5836
|
+
let p = d - u[h - 1];
|
|
5837
|
+
c[h - 1].duration = p, c.push({ mark: h, time: d });
|
|
5838
5838
|
}
|
|
5839
5839
|
});
|
|
5840
5840
|
let l = 1e3 * r.duration;
|
|
5841
|
-
l > this.opt.ttsTrimEnd && (l = l - this.opt.ttsTrimEnd),
|
|
5842
|
-
const h =
|
|
5841
|
+
l > this.opt.ttsTrimEnd && (l = l - this.opt.ttsTrimEnd), c[c.length - 1].duration = l - c[c.length - 1].time, t.anim.forEach((d) => {
|
|
5842
|
+
const h = c[d.mark];
|
|
5843
5843
|
if (h)
|
|
5844
5844
|
for (let p = 0; p < d.ts.length; p++)
|
|
5845
5845
|
d.ts[p] = h.time + d.ts[p] * h.duration + this.opt.ttsTrimStart;
|
|
@@ -5922,10 +5922,10 @@ class Oe {
|
|
|
5922
5922
|
}
|
|
5923
5923
|
if (!this.workletLoaded)
|
|
5924
5924
|
try {
|
|
5925
|
-
const r = this.audioCtx.audioWorklet.addModule(
|
|
5926
|
-
(a,
|
|
5925
|
+
const r = this.audioCtx.audioWorklet.addModule(xt.href), u = new Promise(
|
|
5926
|
+
(a, c) => setTimeout(() => c(new Error("Worklet loading timed out")), 5e3)
|
|
5927
5927
|
);
|
|
5928
|
-
await Promise.race([r,
|
|
5928
|
+
await Promise.race([r, u]), this.workletLoaded = !0;
|
|
5929
5929
|
} catch (r) {
|
|
5930
5930
|
throw console.error("Failed to load audio worklet:", r), new Error("Failed to initialize streaming speech");
|
|
5931
5931
|
}
|
|
@@ -5938,8 +5938,8 @@ class Oe {
|
|
|
5938
5938
|
if (r.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5939
5939
|
try {
|
|
5940
5940
|
this.onAudioStart?.();
|
|
5941
|
-
} catch (
|
|
5942
|
-
console.error(
|
|
5941
|
+
} catch (u) {
|
|
5942
|
+
console.error(u);
|
|
5943
5943
|
}
|
|
5944
5944
|
if (r.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5945
5945
|
try {
|
|
@@ -5959,9 +5959,9 @@ class Oe {
|
|
|
5959
5959
|
} catch {
|
|
5960
5960
|
}
|
|
5961
5961
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5962
|
-
const r = this.audioCtx.resume(),
|
|
5962
|
+
const r = this.audioCtx.resume(), u = new Promise((a, c) => setTimeout(() => c("p2"), 1e3));
|
|
5963
5963
|
try {
|
|
5964
|
-
await Promise.race([r,
|
|
5964
|
+
await Promise.race([r, u]);
|
|
5965
5965
|
} catch {
|
|
5966
5966
|
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.");
|
|
5967
5967
|
return;
|
|
@@ -6058,13 +6058,13 @@ class Oe {
|
|
|
6058
6058
|
subtitles: [" " + i]
|
|
6059
6059
|
}
|
|
6060
6060
|
}), this.streamLipsyncType == "words")) {
|
|
6061
|
-
const r = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6061
|
+
const r = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(i, r), a = this.lipsyncWordsToVisemes(u, r);
|
|
6062
6062
|
if (a && a.visemes && a.visemes.length) {
|
|
6063
|
-
const
|
|
6063
|
+
const c = a.times[a.visemes.length - 1] + a.durations[a.visemes.length - 1], l = Math.min(o, Math.max(0, o - a.visemes.length * 150));
|
|
6064
6064
|
let d = 0.6 + this.convertRange(l, [0, o], [0, 0.4]);
|
|
6065
|
-
if (o = Math.min(o, a.visemes.length * 200),
|
|
6065
|
+
if (o = Math.min(o, a.visemes.length * 200), c > 0)
|
|
6066
6066
|
for (let h = 0; h < a.visemes.length; h++) {
|
|
6067
|
-
const p = e + s + a.times[h] /
|
|
6067
|
+
const p = e + s + a.times[h] / c * o, b = a.durations[h] / c * o;
|
|
6068
6068
|
this.animQueue.push({
|
|
6069
6069
|
template: { name: "viseme" },
|
|
6070
6070
|
ts: [p - Math.min(60, 2 * b / 3), p + Math.min(25, b / 2), p + b + Math.min(60, b / 2)],
|
|
@@ -6160,7 +6160,7 @@ class Oe {
|
|
|
6160
6160
|
*/
|
|
6161
6161
|
lookAtCamera(t) {
|
|
6162
6162
|
let e;
|
|
6163
|
-
if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0),
|
|
6163
|
+
if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Le.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Se.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Le, Se).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) {
|
|
6164
6164
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6165
6165
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6166
6166
|
this.lookAhead(t);
|
|
@@ -6173,12 +6173,12 @@ class Oe {
|
|
|
6173
6173
|
this.lookAt(null, null, t);
|
|
6174
6174
|
return;
|
|
6175
6175
|
}
|
|
6176
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0),
|
|
6177
|
-
const n = new x.Vector3().subVectors(e,
|
|
6176
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Le.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Se.setFromMatrixPosition(this.objectRightEye.matrixWorld), Le.add(Se).divideScalar(2), oe.copy(this.armature.quaternion), oe.multiply(this.poseTarget.props["Hips.quaternion"]), oe.multiply(this.poseTarget.props["Spine.quaternion"]), oe.multiply(this.poseTarget.props["Spine1.quaternion"]), oe.multiply(this.poseTarget.props["Spine2.quaternion"]), oe.multiply(this.poseTarget.props["Neck.quaternion"]), oe.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6177
|
+
const n = new x.Vector3().subVectors(e, Le).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6178
6178
|
_.set(s, i, 0, "YXZ");
|
|
6179
|
-
const r = new x.Quaternion().setFromEuler(_),
|
|
6180
|
-
_.setFromQuaternion(
|
|
6181
|
-
let a = _.x / (40 / 24) + 0.2,
|
|
6179
|
+
const r = new x.Quaternion().setFromEuler(_), u = new x.Quaternion().copy(r).multiply(oe.clone().invert());
|
|
6180
|
+
_.setFromQuaternion(u, "YXZ");
|
|
6181
|
+
let a = _.x / (40 / 24) + 0.2, c = _.y / (9 / 4), l = Math.min(0.6, Math.max(-0.3, a)), d = Math.min(0.8, Math.max(-0.8, c)), h = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6182
6182
|
if (t) {
|
|
6183
6183
|
let b = this.animQueue.findIndex((S) => S.template.name === "lookat");
|
|
6184
6184
|
b !== -1 && this.animQueue.splice(b, 1);
|
|
@@ -6212,21 +6212,21 @@ class Oe {
|
|
|
6212
6212
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6213
6213
|
const s = new x.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new x.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), r = new x.Vector3().addVectors(s, o).divideScalar(2);
|
|
6214
6214
|
r.project(this.camera);
|
|
6215
|
-
let
|
|
6216
|
-
t === null && (t =
|
|
6217
|
-
let
|
|
6215
|
+
let u = (r.x + 1) / 2 * i.width + i.left, a = -(r.y - 1) / 2 * i.height + i.top;
|
|
6216
|
+
t === null && (t = u), e === null && (e = a), oe.copy(this.armature.quaternion), oe.multiply(this.poseTarget.props["Hips.quaternion"]), oe.multiply(this.poseTarget.props["Spine.quaternion"]), oe.multiply(this.poseTarget.props["Spine1.quaternion"]), oe.multiply(this.poseTarget.props["Spine2.quaternion"]), oe.multiply(this.poseTarget.props["Neck.quaternion"]), oe.multiply(this.poseTarget.props["Head.quaternion"]), _.setFromQuaternion(oe);
|
|
6217
|
+
let c = _.x / (40 / 24), l = _.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)), p = Math.max(window.innerWidth - u, u), b = Math.max(window.innerHeight - a, a), f = this.convertRange(e, [a - b, a + b], [-0.3, 0.6]) - c + d, S = this.convertRange(t, [u - p, u + p], [-0.8, 0.8]) - l + h;
|
|
6218
6218
|
f = Math.min(0.6, Math.max(-0.3, f)), S = Math.min(0.8, Math.max(-0.8, S));
|
|
6219
|
-
let
|
|
6219
|
+
let B = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6220
6220
|
if (n) {
|
|
6221
|
-
let
|
|
6222
|
-
|
|
6221
|
+
let D = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6222
|
+
D !== -1 && this.animQueue.splice(D, 1);
|
|
6223
6223
|
const T = {
|
|
6224
6224
|
name: "lookat",
|
|
6225
6225
|
dt: [750, n],
|
|
6226
6226
|
vs: {
|
|
6227
|
-
bodyRotateX: [f +
|
|
6227
|
+
bodyRotateX: [f + B],
|
|
6228
6228
|
bodyRotateY: [S + g],
|
|
6229
|
-
eyesRotateX: [-3 *
|
|
6229
|
+
eyesRotateX: [-3 * B + 0.1],
|
|
6230
6230
|
eyesRotateY: [-5 * g],
|
|
6231
6231
|
browInnerUp: [[0, 0.7]],
|
|
6232
6232
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6253,10 +6253,10 @@ class Oe {
|
|
|
6253
6253
|
s.setFromCamera(i, this.camera);
|
|
6254
6254
|
const o = s.intersectObject(this.armature);
|
|
6255
6255
|
if (o.length > 0) {
|
|
6256
|
-
const r = o[0].point,
|
|
6257
|
-
this.objectLeftArm.getWorldPosition(
|
|
6258
|
-
const
|
|
6259
|
-
|
|
6256
|
+
const r = o[0].point, u = new x.Vector3(), a = new x.Vector3();
|
|
6257
|
+
this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(a);
|
|
6258
|
+
const c = u.distanceToSquared(r), l = a.distanceToSquared(r);
|
|
6259
|
+
c < l ? (this.ikSolve({
|
|
6260
6260
|
iterations: 20,
|
|
6261
6261
|
root: "LeftShoulder",
|
|
6262
6262
|
effector: "LeftHandMiddle1",
|
|
@@ -6277,8 +6277,8 @@ class Oe {
|
|
|
6277
6277
|
}, r, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6278
6278
|
} else
|
|
6279
6279
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((r) => {
|
|
6280
|
-
let
|
|
6281
|
-
this.poseTarget.props[
|
|
6280
|
+
let u = r + ".quaternion";
|
|
6281
|
+
this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
|
|
6282
6282
|
});
|
|
6283
6283
|
return o.length > 0;
|
|
6284
6284
|
}
|
|
@@ -6397,17 +6397,17 @@ class Oe {
|
|
|
6397
6397
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1, r = null) {
|
|
6398
6398
|
if (!this.armature) return;
|
|
6399
6399
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6400
|
-
let
|
|
6401
|
-
if (
|
|
6400
|
+
let u = this.animClips.find((a) => a.url === t + "-" + i);
|
|
6401
|
+
if (u) {
|
|
6402
6402
|
let a = this.animQueue.find((h) => h.template.name === "pose");
|
|
6403
|
-
a && (a.ts[0] = 1 / 0), Object.entries(
|
|
6403
|
+
a && (a.ts[0] = 1 / 0), Object.entries(u.pose.props).forEach((h) => {
|
|
6404
6404
|
this.poseBase.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]].t = 0, this.poseTarget.props[h[0]].d = 1e3;
|
|
6405
6405
|
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new x.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.animationFinishedCallback = r;
|
|
6406
|
-
const
|
|
6406
|
+
const c = () => {
|
|
6407
6407
|
this.animationFinishedCallback && (this.animationFinishedCallback(), this.animationFinishedCallback = null), this.stopAnimation();
|
|
6408
6408
|
};
|
|
6409
|
-
this.mixer.addEventListener("finished",
|
|
6410
|
-
const l = Math.ceil(n /
|
|
6409
|
+
this.mixer.addEventListener("finished", c, { once: !0 });
|
|
6410
|
+
const l = Math.ceil(n / u.clip.duration), d = this.mixer.clipAction(u.clip);
|
|
6411
6411
|
if (d.setLoop(x.LoopRepeat, l), d.clampWhenFinished = !0, this.currentFBXAction && this.currentFBXAction.isRunning()) {
|
|
6412
6412
|
this.currentFBXAction.fadeOut(0.3), setTimeout(() => {
|
|
6413
6413
|
this.currentFBXAction = d;
|
|
@@ -6435,17 +6435,17 @@ class Oe {
|
|
|
6435
6435
|
console.error(`Invalid file type for FBX animation: ${t}. Expected .fbx file.`);
|
|
6436
6436
|
return;
|
|
6437
6437
|
}
|
|
6438
|
-
let
|
|
6438
|
+
let c = !1;
|
|
6439
6439
|
try {
|
|
6440
6440
|
const h = await fetch(t, { method: "HEAD" });
|
|
6441
|
-
if (
|
|
6441
|
+
if (c = h.ok, !c) {
|
|
6442
6442
|
console.error(`FBX file not found at ${t}. Status: ${h.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
|
|
6443
6443
|
return;
|
|
6444
6444
|
}
|
|
6445
6445
|
} catch (h) {
|
|
6446
6446
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, h);
|
|
6447
6447
|
}
|
|
6448
|
-
const l = new
|
|
6448
|
+
const l = new Ve();
|
|
6449
6449
|
let d;
|
|
6450
6450
|
try {
|
|
6451
6451
|
d = await l.loadAsync(t, e);
|
|
@@ -6477,10 +6477,10 @@ class Oe {
|
|
|
6477
6477
|
const b = /* @__PURE__ */ new Map(), f = (R) => {
|
|
6478
6478
|
if (p.has(R))
|
|
6479
6479
|
return R;
|
|
6480
|
-
let
|
|
6481
|
-
if (p.has(
|
|
6482
|
-
return
|
|
6483
|
-
const y =
|
|
6480
|
+
let z = R.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
|
|
6481
|
+
if (p.has(z))
|
|
6482
|
+
return z;
|
|
6483
|
+
const y = z.toLowerCase();
|
|
6484
6484
|
if (y.includes("left") && y.includes("arm")) {
|
|
6485
6485
|
if (y.includes("fore") || y.includes("lower")) {
|
|
6486
6486
|
if (p.has("LeftForeArm")) return "LeftForeArm";
|
|
@@ -6543,67 +6543,67 @@ class Oe {
|
|
|
6543
6543
|
Root: "Hips",
|
|
6544
6544
|
root: "Hips"
|
|
6545
6545
|
};
|
|
6546
|
-
if (M[
|
|
6547
|
-
const
|
|
6548
|
-
if (p.has(
|
|
6549
|
-
return
|
|
6546
|
+
if (M[z]) {
|
|
6547
|
+
const O = M[z];
|
|
6548
|
+
if (p.has(O))
|
|
6549
|
+
return O;
|
|
6550
6550
|
}
|
|
6551
|
-
for (const
|
|
6552
|
-
if (
|
|
6553
|
-
return
|
|
6554
|
-
for (const
|
|
6555
|
-
const
|
|
6556
|
-
if ((y.includes("left") &&
|
|
6557
|
-
return
|
|
6551
|
+
for (const O of p)
|
|
6552
|
+
if (O.toLowerCase() === y)
|
|
6553
|
+
return O;
|
|
6554
|
+
for (const O of p) {
|
|
6555
|
+
const E = O.toLowerCase();
|
|
6556
|
+
if ((y.includes("left") && E.includes("left") || y.includes("right") && E.includes("right")) && (y.includes("arm") && E.includes("arm") && !E.includes("fore") || y.includes("forearm") && E.includes("forearm") || y.includes("hand") && E.includes("hand") && !E.includes("index") && !E.includes("thumb") || y.includes("shoulder") && E.includes("shoulder")))
|
|
6557
|
+
return O;
|
|
6558
6558
|
}
|
|
6559
6559
|
return null;
|
|
6560
6560
|
}, S = /* @__PURE__ */ new Set();
|
|
6561
6561
|
h.tracks.forEach((R) => {
|
|
6562
|
-
const
|
|
6563
|
-
S.add(
|
|
6562
|
+
const z = R.name.split(".");
|
|
6563
|
+
S.add(z[0]);
|
|
6564
6564
|
}), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(S).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(p).sort().join(", "));
|
|
6565
|
-
const
|
|
6565
|
+
const B = Array.from(S).filter(
|
|
6566
6566
|
(R) => R.toLowerCase().includes("arm") || R.toLowerCase().includes("hand") || R.toLowerCase().includes("shoulder")
|
|
6567
6567
|
), g = Array.from(p).filter(
|
|
6568
6568
|
(R) => R.includes("Arm") || R.includes("Hand") || R.includes("Shoulder")
|
|
6569
6569
|
);
|
|
6570
|
-
console.log("FBX arm/hand/shoulder bones:",
|
|
6571
|
-
const
|
|
6572
|
-
let
|
|
6570
|
+
console.log("FBX arm/hand/shoulder bones:", B.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", g.sort().join(", "));
|
|
6571
|
+
const D = [], T = /* @__PURE__ */ new Set();
|
|
6572
|
+
let I = 0;
|
|
6573
6573
|
if (h.tracks.forEach((R) => {
|
|
6574
|
-
const y = R.name.replaceAll("mixamorig", "").split("."), M = y[0],
|
|
6575
|
-
if (
|
|
6576
|
-
|
|
6574
|
+
const y = R.name.replaceAll("mixamorig", "").split("."), M = y[0], O = y[1], E = f(M);
|
|
6575
|
+
if (E && (E === "LeftShoulder" || E === "RightShoulder") && (O === "quaternion" || O === "rotation")) {
|
|
6576
|
+
I++;
|
|
6577
6577
|
return;
|
|
6578
6578
|
}
|
|
6579
|
-
if (
|
|
6580
|
-
const
|
|
6581
|
-
ae.name =
|
|
6579
|
+
if (E && O) {
|
|
6580
|
+
const j = `${E}.${O}`, ae = R.clone();
|
|
6581
|
+
ae.name = j, D.push(ae), M !== E && b.set(M, E);
|
|
6582
6582
|
} else
|
|
6583
6583
|
T.add(M), (M.toLowerCase().includes("arm") || M.toLowerCase().includes("hand") || M.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${M}" could not be mapped to avatar skeleton`);
|
|
6584
|
-
}),
|
|
6585
|
-
h = new x.AnimationClip(h.name, h.duration,
|
|
6584
|
+
}), I > 0 && console.log(`✓ Filtered out ${I} shoulder rotation track(s) to prevent high shoulders`), T.size > 0 && console.warn(`⚠️ ${T.size} bone(s) could not be mapped:`, Array.from(T).sort().join(", ")), D.length > 0) {
|
|
6585
|
+
h = new x.AnimationClip(h.name, h.duration, D), console.log(`✓ Created animation with ${D.length} mapped tracks (from ${h.tracks.length} original tracks)`), b.size > 0 && console.log(
|
|
6586
6586
|
`✓ Mapped ${b.size} bone(s):`,
|
|
6587
|
-
Array.from(b.entries()).map(([
|
|
6587
|
+
Array.from(b.entries()).map(([z, y]) => `${z}→${y}`).join(", ")
|
|
6588
6588
|
);
|
|
6589
6589
|
const R = Array.from(b.values()).filter(
|
|
6590
|
-
(
|
|
6590
|
+
(z) => z.includes("Arm") || z.includes("Hand") || z.includes("Shoulder")
|
|
6591
6591
|
);
|
|
6592
6592
|
R.length > 0 ? console.log(`✓ Arm bones mapped: ${R.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
|
|
6593
6593
|
} else
|
|
6594
6594
|
console.error("❌ No tracks could be mapped! Animation may not work correctly.");
|
|
6595
|
-
const
|
|
6595
|
+
const N = {};
|
|
6596
6596
|
h.tracks.forEach((R) => {
|
|
6597
6597
|
R.name = R.name.replaceAll("mixamorig", "");
|
|
6598
|
-
const
|
|
6599
|
-
if (
|
|
6598
|
+
const z = R.name.split(".");
|
|
6599
|
+
if (z[1] === "position") {
|
|
6600
6600
|
for (let y = 0; y < R.values.length; y++)
|
|
6601
6601
|
R.values[y] = R.values[y] * s;
|
|
6602
|
-
|
|
6603
|
-
} else
|
|
6602
|
+
N[R.name] = new x.Vector3(R.values[0], R.values[1], R.values[2]);
|
|
6603
|
+
} else z[1] === "quaternion" ? N[R.name] = new x.Quaternion(R.values[0], R.values[1], R.values[2], R.values[3]) : z[1] === "rotation" && (N[z[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(R.values[0], R.values[1], R.values[2], "XYZ")).normalize());
|
|
6604
6604
|
});
|
|
6605
|
-
const L = { props:
|
|
6606
|
-
|
|
6605
|
+
const L = { props: N };
|
|
6606
|
+
N["Hips.position"] && (N["Hips.position"].y < 0.5 ? L.lying = !0 : L.standing = !0), this.animClips.push({
|
|
6607
6607
|
url: t + "-" + i,
|
|
6608
6608
|
clip: h,
|
|
6609
6609
|
pose: L
|
|
@@ -6636,25 +6636,25 @@ class Oe {
|
|
|
6636
6636
|
if (!this.armature) return;
|
|
6637
6637
|
let o = this.poseTemplates[t];
|
|
6638
6638
|
if (!o) {
|
|
6639
|
-
const r = this.animPoses.find((
|
|
6639
|
+
const r = this.animPoses.find((u) => u.url === t + "-" + i);
|
|
6640
6640
|
r && (o = r.pose);
|
|
6641
6641
|
}
|
|
6642
6642
|
if (o) {
|
|
6643
6643
|
this.poseName = t, this.mixer = null;
|
|
6644
|
-
let r = this.animQueue.find((
|
|
6644
|
+
let r = this.animQueue.find((u) => u.template.name === "pose");
|
|
6645
6645
|
r && (r.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6646
6646
|
} else {
|
|
6647
|
-
let
|
|
6648
|
-
if (
|
|
6649
|
-
let a =
|
|
6650
|
-
const
|
|
6647
|
+
let u = await new Ve().loadAsync(t, e);
|
|
6648
|
+
if (u && u.animations && u.animations[i]) {
|
|
6649
|
+
let a = u.animations[i];
|
|
6650
|
+
const c = {};
|
|
6651
6651
|
a.tracks.forEach((d) => {
|
|
6652
6652
|
d.name = d.name.replaceAll("mixamorig", "");
|
|
6653
6653
|
const h = d.name.split(".");
|
|
6654
|
-
h[1] === "position" ?
|
|
6654
|
+
h[1] === "position" ? c[d.name] = new x.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : h[1] === "quaternion" ? c[d.name] = new x.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : h[1] === "rotation" && (c[h[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
|
|
6655
6655
|
});
|
|
6656
|
-
const l = { props:
|
|
6657
|
-
|
|
6656
|
+
const l = { props: c };
|
|
6657
|
+
c["Hips.position"] && (c["Hips.position"].y < 0.5 ? l.lying = !0 : l.standing = !0), this.animPoses.push({
|
|
6658
6658
|
url: t + "-" + i,
|
|
6659
6659
|
pose: l
|
|
6660
6660
|
}), this.playPose(t, e, n, i, s);
|
|
@@ -6683,10 +6683,10 @@ class Oe {
|
|
|
6683
6683
|
let s = this.gestureTemplates[t];
|
|
6684
6684
|
if (s) {
|
|
6685
6685
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6686
|
-
let r = this.animQueue.findIndex((
|
|
6687
|
-
r !== -1 && (this.animQueue[r].ts = this.animQueue[r].ts.map((
|
|
6688
|
-
for (let [
|
|
6689
|
-
a.t = this.animClock, a.d = i, this.poseTarget.props.hasOwnProperty(
|
|
6686
|
+
let r = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
|
|
6687
|
+
r !== -1 && (this.animQueue[r].ts = this.animQueue[r].ts.map((u) => 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 x.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new x.Quaternion(0, 1, 0, 0), -0.25));
|
|
6688
|
+
for (let [u, a] of Object.entries(this.gesture))
|
|
6689
|
+
a.t = this.animClock, a.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(a), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
|
|
6690
6690
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6691
6691
|
}
|
|
6692
6692
|
let o = this.animEmojis[t];
|
|
@@ -6694,15 +6694,15 @@ class Oe {
|
|
|
6694
6694
|
this.lookAtCamera(500);
|
|
6695
6695
|
const r = this.animFactory(o);
|
|
6696
6696
|
if (r.gesture = !0, e && Number.isFinite(e)) {
|
|
6697
|
-
const
|
|
6698
|
-
if (e * 1e3 -
|
|
6697
|
+
const u = r.ts[0], c = r.ts[r.ts.length - 1] - u;
|
|
6698
|
+
if (e * 1e3 - c > 0) {
|
|
6699
6699
|
const d = [];
|
|
6700
6700
|
for (let b = 1; b < r.ts.length; b++) d.push(r.ts[b] - r.ts[b - 1]);
|
|
6701
|
-
const h = o.template?.rescale || d.map((b) => b /
|
|
6702
|
-
r.ts = r.ts.map((b, f, S) => f === 0 ?
|
|
6701
|
+
const h = o.template?.rescale || d.map((b) => b / c), p = e * 1e3 - c;
|
|
6702
|
+
r.ts = r.ts.map((b, f, S) => f === 0 ? u : S[f - 1] + d[f - 1] + h[f - 1] * p);
|
|
6703
6703
|
} else {
|
|
6704
|
-
const d = e * 1e3 /
|
|
6705
|
-
r.ts = r.ts.map((h) =>
|
|
6704
|
+
const d = e * 1e3 / c;
|
|
6705
|
+
r.ts = r.ts.map((h) => u + d * (h - u));
|
|
6706
6706
|
}
|
|
6707
6707
|
}
|
|
6708
6708
|
this.animQueue.push(r);
|
|
@@ -6732,7 +6732,7 @@ class Oe {
|
|
|
6732
6732
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6733
6733
|
*/
|
|
6734
6734
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6735
|
-
const s = new x.Vector3(), o = new x.Vector3(), r = new x.Vector3(),
|
|
6735
|
+
const s = new x.Vector3(), o = new x.Vector3(), r = new x.Vector3(), u = new x.Vector3(), a = new x.Quaternion(), c = new x.Vector3(), l = new x.Vector3(), d = new x.Vector3(), h = this.ikMesh.getObjectByName(t.root);
|
|
6736
6736
|
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);
|
|
6737
6737
|
const p = this.ikMesh.getObjectByName(t.effector), b = t.links;
|
|
6738
6738
|
b.forEach((S) => {
|
|
@@ -6741,12 +6741,12 @@ class Oe {
|
|
|
6741
6741
|
const f = t.iterations || 10;
|
|
6742
6742
|
if (e)
|
|
6743
6743
|
for (let S = 0; S < f; S++) {
|
|
6744
|
-
let
|
|
6745
|
-
for (let g = 0,
|
|
6744
|
+
let B = !1;
|
|
6745
|
+
for (let g = 0, D = b.length; g < D; g++) {
|
|
6746
6746
|
const T = b[g].bone;
|
|
6747
|
-
T.matrixWorld.decompose(
|
|
6748
|
-
let
|
|
6749
|
-
|
|
6747
|
+
T.matrixWorld.decompose(u, a, c), a.invert(), o.setFromMatrixPosition(p.matrixWorld), r.subVectors(o, u), r.applyQuaternion(a), r.normalize(), s.subVectors(e, u), s.applyQuaternion(a), s.normalize();
|
|
6748
|
+
let I = s.dot(r);
|
|
6749
|
+
I > 1 ? I = 1 : I < -1 && (I = -1), I = Math.acos(I), !(I < 1e-5) && (b[g].minAngle !== void 0 && I < b[g].minAngle && (I = b[g].minAngle), b[g].maxAngle !== void 0 && I > b[g].maxAngle && (I = b[g].maxAngle), l.crossVectors(r, s), l.normalize(), oe.setFromAxisAngle(l, I), T.quaternion.multiply(oe), T.rotation.setFromVector3(d.setFromEuler(T.rotation).clamp(new x.Vector3(
|
|
6750
6750
|
b[g].minx !== void 0 ? b[g].minx : -1 / 0,
|
|
6751
6751
|
b[g].miny !== void 0 ? b[g].miny : -1 / 0,
|
|
6752
6752
|
b[g].minz !== void 0 ? b[g].minz : -1 / 0
|
|
@@ -6754,9 +6754,9 @@ class Oe {
|
|
|
6754
6754
|
b[g].maxx !== void 0 ? b[g].maxx : 1 / 0,
|
|
6755
6755
|
b[g].maxy !== void 0 ? b[g].maxy : 1 / 0,
|
|
6756
6756
|
b[g].maxz !== void 0 ? b[g].maxz : 1 / 0
|
|
6757
|
-
))), T.updateMatrixWorld(!0),
|
|
6757
|
+
))), T.updateMatrixWorld(!0), B = !0);
|
|
6758
6758
|
}
|
|
6759
|
-
if (!
|
|
6759
|
+
if (!B) break;
|
|
6760
6760
|
}
|
|
6761
6761
|
i && b.forEach((S) => {
|
|
6762
6762
|
this.poseTarget.props[S.link + ".quaternion"].copy(S.bone.quaternion), this.poseTarget.props[S.link + ".quaternion"].t = this.animClock, this.poseTarget.props[S.link + ".quaternion"].d = i;
|
|
@@ -6769,7 +6769,7 @@ class Oe {
|
|
|
6769
6769
|
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();
|
|
6770
6770
|
}
|
|
6771
6771
|
}
|
|
6772
|
-
const
|
|
6772
|
+
const ke = {
|
|
6773
6773
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6774
6774
|
// Replace with your actual API key (should start with sk_)
|
|
6775
6775
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6789,7 +6789,7 @@ const Se = {
|
|
|
6789
6789
|
josh: "VR6AewLTigWG4xSOukaG"
|
|
6790
6790
|
// Male, American
|
|
6791
6791
|
}
|
|
6792
|
-
},
|
|
6792
|
+
}, Pe = {
|
|
6793
6793
|
defaultVoice: "aura-2-thalia-en",
|
|
6794
6794
|
// Thalia (Female, English)
|
|
6795
6795
|
voices: {
|
|
@@ -6809,17 +6809,17 @@ const Se = {
|
|
|
6809
6809
|
// Male, English - Powerful
|
|
6810
6810
|
}
|
|
6811
6811
|
};
|
|
6812
|
-
function
|
|
6812
|
+
function De() {
|
|
6813
6813
|
return {
|
|
6814
6814
|
service: "elevenlabs",
|
|
6815
|
-
endpoint:
|
|
6816
|
-
apiKey:
|
|
6817
|
-
defaultVoice:
|
|
6818
|
-
voices:
|
|
6815
|
+
endpoint: ke.endpoint,
|
|
6816
|
+
apiKey: ke.apiKey,
|
|
6817
|
+
defaultVoice: ke.defaultVoice,
|
|
6818
|
+
voices: ke.voices
|
|
6819
6819
|
};
|
|
6820
6820
|
}
|
|
6821
|
-
function
|
|
6822
|
-
const Z =
|
|
6821
|
+
function Mt() {
|
|
6822
|
+
const Z = De(), t = [];
|
|
6823
6823
|
return Object.entries(Z.voices).forEach(([e, n]) => {
|
|
6824
6824
|
t.push({
|
|
6825
6825
|
value: n,
|
|
@@ -6827,7 +6827,7 @@ function wt() {
|
|
|
6827
6827
|
});
|
|
6828
6828
|
}), t;
|
|
6829
6829
|
}
|
|
6830
|
-
const
|
|
6830
|
+
const Ye = Be(({
|
|
6831
6831
|
avatarUrl: Z = "/avatars/brunette.glb",
|
|
6832
6832
|
avatarBody: t = "F",
|
|
6833
6833
|
mood: e = "neutral",
|
|
@@ -6836,9 +6836,9 @@ const Ge = Fe(({
|
|
|
6836
6836
|
ttsVoice: s = null,
|
|
6837
6837
|
ttsApiKey: o = null,
|
|
6838
6838
|
bodyMovement: r = "idle",
|
|
6839
|
-
movementIntensity:
|
|
6839
|
+
movementIntensity: u = 0.5,
|
|
6840
6840
|
showFullAvatar: a = !0,
|
|
6841
|
-
cameraView:
|
|
6841
|
+
cameraView: c = "upper",
|
|
6842
6842
|
onReady: l = () => {
|
|
6843
6843
|
},
|
|
6844
6844
|
onLoading: d = () => {
|
|
@@ -6849,13 +6849,13 @@ const Ge = Fe(({
|
|
|
6849
6849
|
style: b = {},
|
|
6850
6850
|
animations: f = {}
|
|
6851
6851
|
}, S) => {
|
|
6852
|
-
const
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
}, [
|
|
6856
|
-
|
|
6852
|
+
const B = X(null), g = X(null), D = X(a), T = X(null), I = X(null), N = X(!1), L = X({ remainingText: null, originalText: null, options: null }), R = X([]), z = X(0), [y, M] = le(!0), [O, E] = le(null), [j, ae] = le(!1), [ce, xe] = le(!1);
|
|
6853
|
+
ge(() => {
|
|
6854
|
+
N.current = ce;
|
|
6855
|
+
}, [ce]), ge(() => {
|
|
6856
|
+
D.current = a;
|
|
6857
6857
|
}, [a]);
|
|
6858
|
-
const
|
|
6858
|
+
const se = De(), Ie = i || se.service;
|
|
6859
6859
|
let ee;
|
|
6860
6860
|
Ie === "browser" ? ee = {
|
|
6861
6861
|
service: "browser",
|
|
@@ -6865,19 +6865,19 @@ const Ge = Fe(({
|
|
|
6865
6865
|
} : Ie === "elevenlabs" ? ee = {
|
|
6866
6866
|
service: "elevenlabs",
|
|
6867
6867
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6868
|
-
apiKey: o ||
|
|
6869
|
-
defaultVoice: s ||
|
|
6870
|
-
voices:
|
|
6868
|
+
apiKey: o || se.apiKey,
|
|
6869
|
+
defaultVoice: s || se.defaultVoice || ke.defaultVoice,
|
|
6870
|
+
voices: se.voices || ke.voices
|
|
6871
6871
|
} : Ie === "deepgram" ? ee = {
|
|
6872
6872
|
service: "deepgram",
|
|
6873
6873
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6874
|
-
apiKey: o ||
|
|
6875
|
-
defaultVoice: s ||
|
|
6876
|
-
voices:
|
|
6874
|
+
apiKey: o || se.apiKey,
|
|
6875
|
+
defaultVoice: s || se.defaultVoice || Pe.defaultVoice,
|
|
6876
|
+
voices: se.voices || Pe.voices
|
|
6877
6877
|
} : ee = {
|
|
6878
|
-
...
|
|
6878
|
+
...se,
|
|
6879
6879
|
// Override API key if provided via props
|
|
6880
|
-
apiKey: o !== null ? o :
|
|
6880
|
+
apiKey: o !== null ? o : se.apiKey
|
|
6881
6881
|
};
|
|
6882
6882
|
const v = {
|
|
6883
6883
|
url: Z,
|
|
@@ -6888,229 +6888,229 @@ const Ge = Fe(({
|
|
|
6888
6888
|
lipsyncLang: "en",
|
|
6889
6889
|
showFullAvatar: a,
|
|
6890
6890
|
bodyMovement: r,
|
|
6891
|
-
movementIntensity:
|
|
6892
|
-
},
|
|
6891
|
+
movementIntensity: u
|
|
6892
|
+
}, A = {
|
|
6893
6893
|
ttsEndpoint: ee.endpoint,
|
|
6894
6894
|
ttsApikey: ee.apiKey,
|
|
6895
6895
|
ttsService: Ie,
|
|
6896
6896
|
lipsyncModules: ["en"],
|
|
6897
|
-
cameraView:
|
|
6898
|
-
},
|
|
6899
|
-
if (!(!
|
|
6897
|
+
cameraView: c
|
|
6898
|
+
}, F = G(async () => {
|
|
6899
|
+
if (!(!B.current || g.current))
|
|
6900
6900
|
try {
|
|
6901
|
-
if (M(!0),
|
|
6902
|
-
if (
|
|
6903
|
-
const ne = Math.min(100, Math.round(
|
|
6901
|
+
if (M(!0), E(null), g.current = new Ue(B.current, A), g.current.controls && (g.current.controls.enableRotate = !1, g.current.controls.enableZoom = !1, g.current.controls.enablePan = !1, g.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (g.current.customAnimations = f), await g.current.showAvatar(v, (q) => {
|
|
6902
|
+
if (q.lengthComputable) {
|
|
6903
|
+
const ne = Math.min(100, Math.round(q.loaded / q.total * 100));
|
|
6904
6904
|
d(ne);
|
|
6905
6905
|
}
|
|
6906
|
-
}), await new Promise((
|
|
6906
|
+
}), await new Promise((q) => {
|
|
6907
6907
|
const ne = () => {
|
|
6908
|
-
g.current.lipsync && Object.keys(g.current.lipsync).length > 0 ?
|
|
6908
|
+
g.current.lipsync && Object.keys(g.current.lipsync).length > 0 ? q() : setTimeout(ne, 100);
|
|
6909
6909
|
};
|
|
6910
6910
|
ne();
|
|
6911
6911
|
}), g.current && g.current.setShowFullAvatar)
|
|
6912
6912
|
try {
|
|
6913
6913
|
g.current.setShowFullAvatar(a);
|
|
6914
|
-
} catch (
|
|
6915
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6914
|
+
} catch (q) {
|
|
6915
|
+
console.warn("Error setting full body mode on initialization:", q);
|
|
6916
6916
|
}
|
|
6917
6917
|
g.current && g.current.controls && (g.current.controls.enableRotate = !1, g.current.controls.enableZoom = !1, g.current.controls.enablePan = !1, g.current.controls.enableDamping = !1, g.current.controls.update()), M(!1), ae(!0), l(g.current);
|
|
6918
|
-
const
|
|
6918
|
+
const Q = () => {
|
|
6919
6919
|
document.visibilityState === "visible" ? g.current?.start() : g.current?.stop();
|
|
6920
6920
|
};
|
|
6921
|
-
return document.addEventListener("visibilitychange",
|
|
6922
|
-
document.removeEventListener("visibilitychange",
|
|
6921
|
+
return document.addEventListener("visibilitychange", Q), () => {
|
|
6922
|
+
document.removeEventListener("visibilitychange", Q);
|
|
6923
6923
|
};
|
|
6924
6924
|
} catch (w) {
|
|
6925
|
-
console.error("Error initializing TalkingHead:", w),
|
|
6925
|
+
console.error("Error initializing TalkingHead:", w), E(w.message || "Failed to initialize avatar"), M(!1), h(w);
|
|
6926
6926
|
}
|
|
6927
|
-
}, [Z, t, e, n, i, s, o, a, r,
|
|
6928
|
-
|
|
6927
|
+
}, [Z, t, e, n, i, s, o, a, r, u, c]);
|
|
6928
|
+
ge(() => (F(), () => {
|
|
6929
6929
|
g.current && (g.current.stop(), g.current.dispose(), g.current = null);
|
|
6930
|
-
}), [
|
|
6931
|
-
if (!
|
|
6932
|
-
const w = new ResizeObserver((
|
|
6933
|
-
for (const ne of
|
|
6930
|
+
}), [F]), ge(() => {
|
|
6931
|
+
if (!B.current || !g.current) return;
|
|
6932
|
+
const w = new ResizeObserver((q) => {
|
|
6933
|
+
for (const ne of q)
|
|
6934
6934
|
g.current && g.current.onResize && g.current.onResize();
|
|
6935
6935
|
});
|
|
6936
|
-
w.observe(
|
|
6937
|
-
const
|
|
6936
|
+
w.observe(B.current);
|
|
6937
|
+
const Q = () => {
|
|
6938
6938
|
g.current && g.current.onResize && g.current.onResize();
|
|
6939
6939
|
};
|
|
6940
|
-
return window.addEventListener("resize",
|
|
6941
|
-
w.disconnect(), window.removeEventListener("resize",
|
|
6940
|
+
return window.addEventListener("resize", Q), () => {
|
|
6941
|
+
w.disconnect(), window.removeEventListener("resize", Q);
|
|
6942
6942
|
};
|
|
6943
|
-
}, [
|
|
6944
|
-
const
|
|
6943
|
+
}, [j]);
|
|
6944
|
+
const U = G(async () => {
|
|
6945
6945
|
if (g.current && g.current.audioCtx)
|
|
6946
6946
|
try {
|
|
6947
6947
|
(g.current.audioCtx.state === "suspended" || g.current.audioCtx.state === "interrupted") && (await g.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6948
6948
|
} catch (w) {
|
|
6949
6949
|
console.warn("Failed to resume audio context:", w);
|
|
6950
6950
|
}
|
|
6951
|
-
}, []),
|
|
6952
|
-
if (g.current &&
|
|
6951
|
+
}, []), Y = G(async (w, Q = {}) => {
|
|
6952
|
+
if (g.current && j)
|
|
6953
6953
|
try {
|
|
6954
|
-
|
|
6955
|
-
const
|
|
6956
|
-
R.current = ne,
|
|
6957
|
-
const
|
|
6958
|
-
...
|
|
6959
|
-
lipsyncLang:
|
|
6954
|
+
I.current && (clearInterval(I.current), I.current = null), T.current = { text: w, options: Q }, L.current = { remainingText: null, originalText: null, options: null };
|
|
6955
|
+
const q = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = w.split(q).map(($) => $.trim()).filter(($) => $.length > 0);
|
|
6956
|
+
R.current = ne, z.current = 0, xe(!1), N.current = !1, await U();
|
|
6957
|
+
const be = {
|
|
6958
|
+
...Q,
|
|
6959
|
+
lipsyncLang: Q.lipsyncLang || v.lipsyncLang || "en"
|
|
6960
6960
|
};
|
|
6961
|
-
if (
|
|
6962
|
-
const
|
|
6963
|
-
let
|
|
6964
|
-
const
|
|
6965
|
-
let
|
|
6966
|
-
|
|
6967
|
-
if (k++,
|
|
6961
|
+
if (Q.onSpeechEnd && g.current) {
|
|
6962
|
+
const $ = g.current;
|
|
6963
|
+
let me = null, k = 0;
|
|
6964
|
+
const C = 1200;
|
|
6965
|
+
let W = !1;
|
|
6966
|
+
me = setInterval(() => {
|
|
6967
|
+
if (k++, N.current)
|
|
6968
6968
|
return;
|
|
6969
|
-
if (k >
|
|
6970
|
-
if (
|
|
6971
|
-
|
|
6969
|
+
if (k > C) {
|
|
6970
|
+
if (me && (clearInterval(me), me = null, I.current = null), !W && !N.current) {
|
|
6971
|
+
W = !0;
|
|
6972
6972
|
try {
|
|
6973
|
-
|
|
6974
|
-
} catch (
|
|
6975
|
-
console.error("Error in onSpeechEnd callback (timeout):",
|
|
6973
|
+
Q.onSpeechEnd();
|
|
6974
|
+
} catch (Ce) {
|
|
6975
|
+
console.error("Error in onSpeechEnd callback (timeout):", Ce);
|
|
6976
6976
|
}
|
|
6977
6977
|
}
|
|
6978
6978
|
return;
|
|
6979
6979
|
}
|
|
6980
|
-
const
|
|
6981
|
-
|
|
6982
|
-
if (
|
|
6983
|
-
|
|
6980
|
+
const V = !$.speechQueue || $.speechQueue.length === 0, ie = !$.audioPlaylist || $.audioPlaylist.length === 0;
|
|
6981
|
+
$ && $.isSpeaking === !1 && V && ie && $.isAudioPlaying === !1 && !W && !N.current && setTimeout(() => {
|
|
6982
|
+
if ($ && !N.current && $.isSpeaking === !1 && (!$.speechQueue || $.speechQueue.length === 0) && (!$.audioPlaylist || $.audioPlaylist.length === 0) && $.isAudioPlaying === !1 && !W && !N.current) {
|
|
6983
|
+
W = !0, me && (clearInterval(me), me = null, I.current = null);
|
|
6984
6984
|
try {
|
|
6985
|
-
|
|
6986
|
-
} catch (
|
|
6987
|
-
console.error("Error in onSpeechEnd callback:",
|
|
6985
|
+
Q.onSpeechEnd();
|
|
6986
|
+
} catch (He) {
|
|
6987
|
+
console.error("Error in onSpeechEnd callback:", He);
|
|
6988
6988
|
}
|
|
6989
6989
|
}
|
|
6990
6990
|
}, 100);
|
|
6991
|
-
}, 100),
|
|
6991
|
+
}, 100), I.current = me;
|
|
6992
6992
|
}
|
|
6993
|
-
g.current.lipsync && Object.keys(g.current.lipsync).length > 0 ? (g.current.setSlowdownRate && g.current.setSlowdownRate(1.05), g.current.speakText(w,
|
|
6994
|
-
await
|
|
6993
|
+
g.current.lipsync && Object.keys(g.current.lipsync).length > 0 ? (g.current.setSlowdownRate && g.current.setSlowdownRate(1.05), g.current.speakText(w, be)) : setTimeout(async () => {
|
|
6994
|
+
await U(), g.current && g.current.lipsync && (g.current.setSlowdownRate && g.current.setSlowdownRate(1.05), g.current.speakText(w, be));
|
|
6995
6995
|
}, 100);
|
|
6996
|
-
} catch (
|
|
6997
|
-
console.error("Error speaking text:",
|
|
6996
|
+
} catch (q) {
|
|
6997
|
+
console.error("Error speaking text:", q), E(q.message || "Failed to speak text");
|
|
6998
6998
|
}
|
|
6999
|
-
}, [
|
|
7000
|
-
g.current && (g.current.stopSpeaking(), g.current.setSlowdownRate && g.current.setSlowdownRate(1), T.current = null,
|
|
7001
|
-
}, []), K =
|
|
6999
|
+
}, [j, U, v.lipsyncLang]), re = G(() => {
|
|
7000
|
+
g.current && (g.current.stopSpeaking(), g.current.setSlowdownRate && g.current.setSlowdownRate(1), T.current = null, xe(!1));
|
|
7001
|
+
}, []), K = G(() => {
|
|
7002
7002
|
if (g.current && g.current.pauseSpeaking) {
|
|
7003
7003
|
const w = g.current;
|
|
7004
7004
|
if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
|
|
7005
|
-
|
|
7006
|
-
let
|
|
7005
|
+
I.current && (clearInterval(I.current), I.current = null);
|
|
7006
|
+
let q = "";
|
|
7007
7007
|
if (T.current && R.current.length > 0) {
|
|
7008
|
-
const ne = R.current.length,
|
|
7009
|
-
if (
|
|
7010
|
-
const
|
|
7011
|
-
|
|
7008
|
+
const ne = R.current.length, be = w.speechQueue ? w.speechQueue.filter((C) => C && C.text && Array.isArray(C.text) && C.text.length > 0).length : 0, $ = w.audioPlaylist && w.audioPlaylist.length > 0, me = be + ($ ? 1 : 0), k = ne - me;
|
|
7009
|
+
if (me > 0 && k < ne && (q = R.current.slice(k).join(". ").trim(), !q && be > 0 && w.speechQueue)) {
|
|
7010
|
+
const W = w.speechQueue.filter((V) => V && V.text && Array.isArray(V.text) && V.text.length > 0).map((V) => V.text.map((ie) => ie.word || "").filter((ie) => ie.length > 0).join(" ")).filter((V) => V.length > 0).join(" ");
|
|
7011
|
+
W && W.trim() && (q = W.trim());
|
|
7012
7012
|
}
|
|
7013
7013
|
}
|
|
7014
7014
|
T.current && (L.current = {
|
|
7015
|
-
remainingText:
|
|
7015
|
+
remainingText: q || null,
|
|
7016
7016
|
originalText: T.current.text,
|
|
7017
7017
|
options: T.current.options
|
|
7018
|
-
}), w.speechQueue && (w.speechQueue.length = 0), g.current.pauseSpeaking(),
|
|
7018
|
+
}), w.speechQueue && (w.speechQueue.length = 0), g.current.pauseSpeaking(), N.current = !0, xe(!0);
|
|
7019
7019
|
}
|
|
7020
7020
|
}
|
|
7021
|
-
}, []), te =
|
|
7022
|
-
if (!g.current || !
|
|
7021
|
+
}, []), te = G(async () => {
|
|
7022
|
+
if (!g.current || !ce)
|
|
7023
7023
|
return;
|
|
7024
|
-
let w = "",
|
|
7024
|
+
let w = "", Q = {};
|
|
7025
7025
|
if (L.current && L.current.remainingText)
|
|
7026
|
-
w = L.current.remainingText,
|
|
7026
|
+
w = L.current.remainingText, Q = L.current.options || {}, L.current = { remainingText: null, originalText: null, options: null };
|
|
7027
7027
|
else if (T.current && T.current.text)
|
|
7028
|
-
w = T.current.text,
|
|
7028
|
+
w = T.current.text, Q = T.current.options || {};
|
|
7029
7029
|
else {
|
|
7030
|
-
console.warn("Resume called but no paused speech found"),
|
|
7030
|
+
console.warn("Resume called but no paused speech found"), xe(!1), N.current = !1;
|
|
7031
7031
|
return;
|
|
7032
7032
|
}
|
|
7033
|
-
|
|
7034
|
-
const
|
|
7035
|
-
...
|
|
7036
|
-
lipsyncLang:
|
|
7033
|
+
xe(!1), N.current = !1, await U();
|
|
7034
|
+
const q = {
|
|
7035
|
+
...Q,
|
|
7036
|
+
lipsyncLang: Q.lipsyncLang || v.lipsyncLang || "en"
|
|
7037
7037
|
};
|
|
7038
7038
|
try {
|
|
7039
|
-
await
|
|
7039
|
+
await Y(w, q);
|
|
7040
7040
|
} catch (ne) {
|
|
7041
|
-
console.error("Error resuming speech:", ne),
|
|
7041
|
+
console.error("Error resuming speech:", ne), xe(!1), N.current = !1;
|
|
7042
7042
|
}
|
|
7043
|
-
}, [
|
|
7043
|
+
}, [U, ce, Y, v]), ye = G((w) => {
|
|
7044
7044
|
g.current && g.current.setMood(w);
|
|
7045
|
-
}, []),
|
|
7045
|
+
}, []), we = G((w) => {
|
|
7046
7046
|
g.current && g.current.setSlowdownRate && g.current.setSlowdownRate(w);
|
|
7047
|
-
}, []),
|
|
7047
|
+
}, []), Ne = G((w, Q = !1) => {
|
|
7048
7048
|
if (g.current && g.current.playAnimation) {
|
|
7049
7049
|
if (f && f[w] && (w = f[w]), g.current.setShowFullAvatar)
|
|
7050
7050
|
try {
|
|
7051
|
-
g.current.setShowFullAvatar(
|
|
7051
|
+
g.current.setShowFullAvatar(D.current);
|
|
7052
7052
|
} catch (ne) {
|
|
7053
7053
|
console.warn("Error setting full body mode:", ne);
|
|
7054
7054
|
}
|
|
7055
7055
|
if (w.includes("."))
|
|
7056
7056
|
try {
|
|
7057
|
-
g.current.playAnimation(w, null, 10, 0, 0.01,
|
|
7057
|
+
g.current.playAnimation(w, null, 10, 0, 0.01, Q);
|
|
7058
7058
|
} catch (ne) {
|
|
7059
7059
|
console.warn(`Failed to play ${w}:`, ne);
|
|
7060
7060
|
try {
|
|
7061
7061
|
g.current.setBodyMovement("idle");
|
|
7062
|
-
} catch (
|
|
7063
|
-
console.warn("Fallback animation also failed:",
|
|
7062
|
+
} catch (be) {
|
|
7063
|
+
console.warn("Fallback animation also failed:", be);
|
|
7064
7064
|
}
|
|
7065
7065
|
}
|
|
7066
7066
|
else {
|
|
7067
7067
|
const ne = [".fbx", ".glb", ".gltf"];
|
|
7068
|
-
let
|
|
7069
|
-
for (const
|
|
7068
|
+
let be = !1;
|
|
7069
|
+
for (const $ of ne)
|
|
7070
7070
|
try {
|
|
7071
|
-
g.current.playAnimation(w +
|
|
7071
|
+
g.current.playAnimation(w + $, null, 10, 0, 0.01, Q), be = !0;
|
|
7072
7072
|
break;
|
|
7073
7073
|
} catch {
|
|
7074
7074
|
}
|
|
7075
|
-
if (!
|
|
7075
|
+
if (!be) {
|
|
7076
7076
|
console.warn("Animation not found:", w);
|
|
7077
7077
|
try {
|
|
7078
7078
|
g.current.setBodyMovement("idle");
|
|
7079
|
-
} catch (
|
|
7080
|
-
console.warn("Fallback animation also failed:",
|
|
7079
|
+
} catch ($) {
|
|
7080
|
+
console.warn("Fallback animation also failed:", $);
|
|
7081
7081
|
}
|
|
7082
7082
|
}
|
|
7083
7083
|
}
|
|
7084
7084
|
}
|
|
7085
|
-
}, [f]),
|
|
7085
|
+
}, [f]), Te = G(() => {
|
|
7086
7086
|
g.current && g.current.onResize && g.current.onResize();
|
|
7087
7087
|
}, []);
|
|
7088
|
-
return
|
|
7089
|
-
speakText:
|
|
7088
|
+
return Oe(S, () => ({
|
|
7089
|
+
speakText: Y,
|
|
7090
7090
|
stopSpeaking: re,
|
|
7091
7091
|
pauseSpeaking: K,
|
|
7092
7092
|
resumeSpeaking: te,
|
|
7093
|
-
resumeAudioContext:
|
|
7094
|
-
setMood:
|
|
7095
|
-
setTimingAdjustment:
|
|
7096
|
-
playAnimation:
|
|
7097
|
-
isReady:
|
|
7098
|
-
isPaused:
|
|
7093
|
+
resumeAudioContext: U,
|
|
7094
|
+
setMood: ye,
|
|
7095
|
+
setTimingAdjustment: we,
|
|
7096
|
+
playAnimation: Ne,
|
|
7097
|
+
isReady: j,
|
|
7098
|
+
isPaused: ce,
|
|
7099
7099
|
talkingHead: g.current,
|
|
7100
|
-
handleResize:
|
|
7100
|
+
handleResize: Te,
|
|
7101
7101
|
setBodyMovement: (w) => {
|
|
7102
7102
|
if (g.current && g.current.setShowFullAvatar && g.current.setBodyMovement)
|
|
7103
7103
|
try {
|
|
7104
|
-
g.current.setShowFullAvatar(
|
|
7105
|
-
} catch (
|
|
7106
|
-
console.warn("Error setting body movement:",
|
|
7104
|
+
g.current.setShowFullAvatar(D.current), g.current.setBodyMovement(w);
|
|
7105
|
+
} catch (Q) {
|
|
7106
|
+
console.warn("Error setting body movement:", Q);
|
|
7107
7107
|
}
|
|
7108
7108
|
},
|
|
7109
7109
|
setMovementIntensity: (w) => g.current?.setMovementIntensity(w),
|
|
7110
7110
|
playRandomDance: () => {
|
|
7111
7111
|
if (g.current && g.current.setShowFullAvatar && g.current.playRandomDance)
|
|
7112
7112
|
try {
|
|
7113
|
-
g.current.setShowFullAvatar(
|
|
7113
|
+
g.current.setShowFullAvatar(D.current), g.current.playRandomDance();
|
|
7114
7114
|
} catch (w) {
|
|
7115
7115
|
console.warn("Error playing random dance:", w);
|
|
7116
7116
|
}
|
|
@@ -7118,15 +7118,15 @@ const Ge = Fe(({
|
|
|
7118
7118
|
playReaction: (w) => {
|
|
7119
7119
|
if (g.current && g.current.setShowFullAvatar && g.current.playReaction)
|
|
7120
7120
|
try {
|
|
7121
|
-
g.current.setShowFullAvatar(
|
|
7122
|
-
} catch (
|
|
7123
|
-
console.warn("Error playing reaction:",
|
|
7121
|
+
g.current.setShowFullAvatar(D.current), g.current.playReaction(w);
|
|
7122
|
+
} catch (Q) {
|
|
7123
|
+
console.warn("Error playing reaction:", Q);
|
|
7124
7124
|
}
|
|
7125
7125
|
},
|
|
7126
7126
|
playCelebration: () => {
|
|
7127
7127
|
if (g.current && g.current.setShowFullAvatar && g.current.playCelebration)
|
|
7128
7128
|
try {
|
|
7129
|
-
g.current.setShowFullAvatar(
|
|
7129
|
+
g.current.setShowFullAvatar(D.current), g.current.playCelebration();
|
|
7130
7130
|
} catch (w) {
|
|
7131
7131
|
console.warn("Error playing celebration:", w);
|
|
7132
7132
|
}
|
|
@@ -7134,9 +7134,9 @@ const Ge = Fe(({
|
|
|
7134
7134
|
setShowFullAvatar: (w) => {
|
|
7135
7135
|
if (g.current && g.current.setShowFullAvatar)
|
|
7136
7136
|
try {
|
|
7137
|
-
|
|
7138
|
-
} catch (
|
|
7139
|
-
console.warn("Error setting showFullAvatar:",
|
|
7137
|
+
D.current = w, g.current.setShowFullAvatar(w);
|
|
7138
|
+
} catch (Q) {
|
|
7139
|
+
console.warn("Error setting showFullAvatar:", Q);
|
|
7140
7140
|
}
|
|
7141
7141
|
},
|
|
7142
7142
|
lockAvatarPosition: () => {
|
|
@@ -7155,7 +7155,7 @@ const Ge = Fe(({
|
|
|
7155
7155
|
console.warn("Error unlocking avatar position:", w);
|
|
7156
7156
|
}
|
|
7157
7157
|
}
|
|
7158
|
-
})), /* @__PURE__ */
|
|
7158
|
+
})), /* @__PURE__ */ ve(
|
|
7159
7159
|
"div",
|
|
7160
7160
|
{
|
|
7161
7161
|
className: `talking-head-avatar ${p}`,
|
|
@@ -7166,10 +7166,10 @@ const Ge = Fe(({
|
|
|
7166
7166
|
...b
|
|
7167
7167
|
},
|
|
7168
7168
|
children: [
|
|
7169
|
-
/* @__PURE__ */
|
|
7169
|
+
/* @__PURE__ */ J(
|
|
7170
7170
|
"div",
|
|
7171
7171
|
{
|
|
7172
|
-
ref:
|
|
7172
|
+
ref: B,
|
|
7173
7173
|
className: "talking-head-viewer",
|
|
7174
7174
|
style: {
|
|
7175
7175
|
width: "100%",
|
|
@@ -7178,7 +7178,7 @@ const Ge = Fe(({
|
|
|
7178
7178
|
}
|
|
7179
7179
|
}
|
|
7180
7180
|
),
|
|
7181
|
-
y && /* @__PURE__ */
|
|
7181
|
+
y && /* @__PURE__ */ J("div", { className: "loading-overlay", style: {
|
|
7182
7182
|
position: "absolute",
|
|
7183
7183
|
top: "50%",
|
|
7184
7184
|
left: "50%",
|
|
@@ -7187,7 +7187,7 @@ const Ge = Fe(({
|
|
|
7187
7187
|
fontSize: "18px",
|
|
7188
7188
|
zIndex: 10
|
|
7189
7189
|
}, children: "Loading avatar..." }),
|
|
7190
|
-
|
|
7190
|
+
O && /* @__PURE__ */ J("div", { className: "error-overlay", style: {
|
|
7191
7191
|
position: "absolute",
|
|
7192
7192
|
top: "50%",
|
|
7193
7193
|
left: "50%",
|
|
@@ -7198,13 +7198,13 @@ const Ge = Fe(({
|
|
|
7198
7198
|
zIndex: 10,
|
|
7199
7199
|
padding: "20px",
|
|
7200
7200
|
borderRadius: "8px"
|
|
7201
|
-
}, children:
|
|
7201
|
+
}, children: O })
|
|
7202
7202
|
]
|
|
7203
7203
|
}
|
|
7204
7204
|
);
|
|
7205
7205
|
});
|
|
7206
|
-
|
|
7207
|
-
const
|
|
7206
|
+
Ye.displayName = "TalkingHeadAvatar";
|
|
7207
|
+
const vt = Be(({
|
|
7208
7208
|
text: Z = "Hello! I'm a talking avatar. How are you today?",
|
|
7209
7209
|
onLoading: t = () => {
|
|
7210
7210
|
},
|
|
@@ -7216,7 +7216,7 @@ const yt = Fe(({
|
|
|
7216
7216
|
style: s = {},
|
|
7217
7217
|
avatarConfig: o = {}
|
|
7218
7218
|
}, r) => {
|
|
7219
|
-
const
|
|
7219
|
+
const u = X(null), a = X(null), [c, l] = le(!0), [d, h] = le(null), [p, b] = le(!1), f = De(), S = o.ttsService || f.service, B = S === "browser" ? {
|
|
7220
7220
|
endpoint: "",
|
|
7221
7221
|
apiKey: null,
|
|
7222
7222
|
defaultVoice: "Google US English"
|
|
@@ -7232,7 +7232,7 @@ const yt = Fe(({
|
|
|
7232
7232
|
body: "F",
|
|
7233
7233
|
avatarMood: "neutral",
|
|
7234
7234
|
ttsLang: S === "browser" ? "en-US" : "en",
|
|
7235
|
-
ttsVoice: o.ttsVoice ||
|
|
7235
|
+
ttsVoice: o.ttsVoice || B.defaultVoice,
|
|
7236
7236
|
lipsyncLang: "en",
|
|
7237
7237
|
// English lip-sync
|
|
7238
7238
|
showFullAvatar: !0,
|
|
@@ -7240,36 +7240,36 @@ const yt = Fe(({
|
|
|
7240
7240
|
bodyMovement: "idle",
|
|
7241
7241
|
movementIntensity: 0.5,
|
|
7242
7242
|
...o
|
|
7243
|
-
},
|
|
7244
|
-
ttsEndpoint:
|
|
7245
|
-
ttsApikey:
|
|
7243
|
+
}, D = {
|
|
7244
|
+
ttsEndpoint: B.endpoint,
|
|
7245
|
+
ttsApikey: B.apiKey,
|
|
7246
7246
|
ttsService: S,
|
|
7247
7247
|
lipsyncModules: ["en"],
|
|
7248
7248
|
cameraView: "upper"
|
|
7249
|
-
}, T =
|
|
7250
|
-
if (!(!
|
|
7249
|
+
}, T = G(async () => {
|
|
7250
|
+
if (!(!u.current || a.current))
|
|
7251
7251
|
try {
|
|
7252
|
-
if (l(!0), h(null), a.current = new
|
|
7253
|
-
if (
|
|
7254
|
-
const
|
|
7255
|
-
t(
|
|
7252
|
+
if (l(!0), h(null), a.current = new Ue(u.current, D), await a.current.showAvatar(g, (O) => {
|
|
7253
|
+
if (O.lengthComputable) {
|
|
7254
|
+
const E = Math.min(100, Math.round(O.loaded / O.total * 100));
|
|
7255
|
+
t(E);
|
|
7256
7256
|
}
|
|
7257
7257
|
}), a.current.morphs && a.current.morphs.length > 0) {
|
|
7258
|
-
const
|
|
7259
|
-
console.log("Available morph targets:", Object.keys(
|
|
7260
|
-
const
|
|
7261
|
-
console.log("Viseme morph targets found:",
|
|
7258
|
+
const O = a.current.morphs[0].morphTargetDictionary;
|
|
7259
|
+
console.log("Available morph targets:", Object.keys(O));
|
|
7260
|
+
const E = Object.keys(O).filter((j) => j.startsWith("viseme_"));
|
|
7261
|
+
console.log("Viseme morph targets found:", E), E.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"));
|
|
7262
7262
|
}
|
|
7263
|
-
if (await new Promise((
|
|
7264
|
-
const
|
|
7265
|
-
a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)),
|
|
7263
|
+
if (await new Promise((O) => {
|
|
7264
|
+
const E = () => {
|
|
7265
|
+
a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), O()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(E, 100));
|
|
7266
7266
|
};
|
|
7267
|
-
|
|
7267
|
+
E();
|
|
7268
7268
|
}), a.current && a.current.setShowFullAvatar)
|
|
7269
7269
|
try {
|
|
7270
7270
|
a.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7271
|
-
} catch (
|
|
7272
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7271
|
+
} catch (O) {
|
|
7272
|
+
console.warn("Error setting full body mode on initialization:", O);
|
|
7273
7273
|
}
|
|
7274
7274
|
l(!1), b(!0), n(a.current);
|
|
7275
7275
|
const M = () => {
|
|
@@ -7282,10 +7282,10 @@ const yt = Fe(({
|
|
|
7282
7282
|
console.error("Error initializing TalkingHead:", y), h(y.message || "Failed to initialize avatar"), l(!1), e(y);
|
|
7283
7283
|
}
|
|
7284
7284
|
}, []);
|
|
7285
|
-
|
|
7285
|
+
ge(() => (T(), () => {
|
|
7286
7286
|
a.current && (a.current.stop(), a.current.dispose(), a.current = null);
|
|
7287
7287
|
}), [T]);
|
|
7288
|
-
const
|
|
7288
|
+
const I = G((y) => {
|
|
7289
7289
|
if (a.current && p)
|
|
7290
7290
|
try {
|
|
7291
7291
|
console.log("Speaking text:", y), console.log("Avatar config:", g), console.log("TalkingHead instance:", a.current), a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(y)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
@@ -7296,42 +7296,42 @@ const yt = Fe(({
|
|
|
7296
7296
|
}
|
|
7297
7297
|
else
|
|
7298
7298
|
console.warn("Avatar not ready for speaking. isReady:", p, "talkingHeadRef:", !!a.current);
|
|
7299
|
-
}, [p, g]),
|
|
7299
|
+
}, [p, g]), N = G(() => {
|
|
7300
7300
|
a.current && (a.current.stopSpeaking(), a.current.setSlowdownRate && (a.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7301
|
-
}, []), L =
|
|
7301
|
+
}, []), L = G((y) => {
|
|
7302
7302
|
a.current && a.current.setMood(y);
|
|
7303
|
-
}, []), R =
|
|
7303
|
+
}, []), R = G((y) => {
|
|
7304
7304
|
a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(y), console.log("Timing adjustment set to:", y));
|
|
7305
|
-
}, []),
|
|
7305
|
+
}, []), z = G((y, M = !1) => {
|
|
7306
7306
|
if (a.current && a.current.playAnimation) {
|
|
7307
7307
|
if (a.current.setShowFullAvatar)
|
|
7308
7308
|
try {
|
|
7309
7309
|
a.current.setShowFullAvatar(!0);
|
|
7310
|
-
} catch (
|
|
7311
|
-
console.warn("Error setting full body mode:",
|
|
7310
|
+
} catch (E) {
|
|
7311
|
+
console.warn("Error setting full body mode:", E);
|
|
7312
7312
|
}
|
|
7313
7313
|
if (y.includes("."))
|
|
7314
7314
|
try {
|
|
7315
7315
|
a.current.playAnimation(y, null, 10, 0, 0.01, M), console.log("Playing animation:", y);
|
|
7316
|
-
} catch (
|
|
7317
|
-
console.log(`Failed to play ${y}:`,
|
|
7316
|
+
} catch (E) {
|
|
7317
|
+
console.log(`Failed to play ${y}:`, E);
|
|
7318
7318
|
try {
|
|
7319
7319
|
a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7320
|
-
} catch (
|
|
7321
|
-
console.warn("Fallback animation also failed:",
|
|
7320
|
+
} catch (j) {
|
|
7321
|
+
console.warn("Fallback animation also failed:", j);
|
|
7322
7322
|
}
|
|
7323
7323
|
}
|
|
7324
7324
|
else {
|
|
7325
|
-
const
|
|
7326
|
-
let
|
|
7327
|
-
for (const ae of
|
|
7325
|
+
const E = [".fbx", ".glb", ".gltf"];
|
|
7326
|
+
let j = !1;
|
|
7327
|
+
for (const ae of E)
|
|
7328
7328
|
try {
|
|
7329
|
-
a.current.playAnimation(y + ae, null, 10, 0, 0.01, M), console.log("Playing animation:", y + ae),
|
|
7329
|
+
a.current.playAnimation(y + ae, null, 10, 0, 0.01, M), console.log("Playing animation:", y + ae), j = !0;
|
|
7330
7330
|
break;
|
|
7331
7331
|
} catch {
|
|
7332
7332
|
console.log(`Failed to play ${y}${ae}, trying next format...`);
|
|
7333
7333
|
}
|
|
7334
|
-
if (!
|
|
7334
|
+
if (!j) {
|
|
7335
7335
|
console.warn("Animation system not available or animation not found:", y);
|
|
7336
7336
|
try {
|
|
7337
7337
|
a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
@@ -7343,12 +7343,12 @@ const yt = Fe(({
|
|
|
7343
7343
|
} else
|
|
7344
7344
|
console.warn("Animation system not available or animation not found:", y);
|
|
7345
7345
|
}, []);
|
|
7346
|
-
return
|
|
7347
|
-
speakText:
|
|
7348
|
-
stopSpeaking:
|
|
7346
|
+
return Oe(r, () => ({
|
|
7347
|
+
speakText: I,
|
|
7348
|
+
stopSpeaking: N,
|
|
7349
7349
|
setMood: L,
|
|
7350
7350
|
setTimingAdjustment: R,
|
|
7351
|
-
playAnimation:
|
|
7351
|
+
playAnimation: z,
|
|
7352
7352
|
isReady: p,
|
|
7353
7353
|
talkingHead: a.current,
|
|
7354
7354
|
setBodyMovement: (y) => {
|
|
@@ -7408,11 +7408,11 @@ const yt = Fe(({
|
|
|
7408
7408
|
console.warn("Error unlocking avatar position:", y);
|
|
7409
7409
|
}
|
|
7410
7410
|
}
|
|
7411
|
-
})), /* @__PURE__ */
|
|
7412
|
-
/* @__PURE__ */
|
|
7411
|
+
})), /* @__PURE__ */ ve("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7412
|
+
/* @__PURE__ */ J(
|
|
7413
7413
|
"div",
|
|
7414
7414
|
{
|
|
7415
|
-
ref:
|
|
7415
|
+
ref: u,
|
|
7416
7416
|
className: "talking-head-viewer",
|
|
7417
7417
|
style: {
|
|
7418
7418
|
width: "100%",
|
|
@@ -7421,7 +7421,7 @@ const yt = Fe(({
|
|
|
7421
7421
|
}
|
|
7422
7422
|
}
|
|
7423
7423
|
),
|
|
7424
|
-
|
|
7424
|
+
c && /* @__PURE__ */ J("div", { className: "loading-overlay", style: {
|
|
7425
7425
|
position: "absolute",
|
|
7426
7426
|
top: "50%",
|
|
7427
7427
|
left: "50%",
|
|
@@ -7430,7 +7430,7 @@ const yt = Fe(({
|
|
|
7430
7430
|
fontSize: "18px",
|
|
7431
7431
|
zIndex: 10
|
|
7432
7432
|
}, children: "Loading avatar..." }),
|
|
7433
|
-
d && /* @__PURE__ */
|
|
7433
|
+
d && /* @__PURE__ */ J("div", { className: "error-overlay", style: {
|
|
7434
7434
|
position: "absolute",
|
|
7435
7435
|
top: "50%",
|
|
7436
7436
|
left: "50%",
|
|
@@ -7444,8 +7444,8 @@ const yt = Fe(({
|
|
|
7444
7444
|
}, children: d })
|
|
7445
7445
|
] });
|
|
7446
7446
|
});
|
|
7447
|
-
|
|
7448
|
-
async function
|
|
7447
|
+
vt.displayName = "TalkingHeadComponent";
|
|
7448
|
+
async function Qe(Z) {
|
|
7449
7449
|
try {
|
|
7450
7450
|
console.log(`📥 Loading animation manifest from: ${Z}`);
|
|
7451
7451
|
const t = await fetch(Z);
|
|
@@ -7463,7 +7463,57 @@ async function Ze(Z) {
|
|
|
7463
7463
|
return console.error("❌ Failed to load animation manifest:", t), {};
|
|
7464
7464
|
}
|
|
7465
7465
|
}
|
|
7466
|
-
|
|
7466
|
+
async function Rt(Z, t = "F") {
|
|
7467
|
+
const e = [], n = Z.replace(/\/$/, "");
|
|
7468
|
+
try {
|
|
7469
|
+
const s = [
|
|
7470
|
+
`${n}/.list.json`,
|
|
7471
|
+
// Custom listing file
|
|
7472
|
+
`/api/directory?path=${encodeURIComponent(n)}`,
|
|
7473
|
+
// API endpoint
|
|
7474
|
+
`${n}/index.json`
|
|
7475
|
+
// Index file
|
|
7476
|
+
];
|
|
7477
|
+
for (const o of s)
|
|
7478
|
+
try {
|
|
7479
|
+
const r = await fetch(o);
|
|
7480
|
+
if (r.ok) {
|
|
7481
|
+
const u = await r.json(), c = (Array.isArray(u) ? u : u.files || []).filter((l) => typeof l == "string" && l.toLowerCase().endsWith(".fbx")).map((l) => l.startsWith("/") ? l : `${n}/${l}`);
|
|
7482
|
+
if (c.length > 0)
|
|
7483
|
+
return console.log(`✅ Auto-discovered ${c.length} animations from ${o}`), c;
|
|
7484
|
+
}
|
|
7485
|
+
} catch {
|
|
7486
|
+
continue;
|
|
7487
|
+
}
|
|
7488
|
+
} catch (s) {
|
|
7489
|
+
console.warn(`⚠️ Could not use directory listing API for ${n}:`, s);
|
|
7490
|
+
}
|
|
7491
|
+
const i = [];
|
|
7492
|
+
t === "M" || t === "m" ? i.push(`${n}/male`, `${n}/m`) : i.push(`${n}/female`, `${n}/f`), i.push(`${n}/shared`);
|
|
7493
|
+
for (const s of i)
|
|
7494
|
+
try {
|
|
7495
|
+
const o = `${s}/.list.json`, r = await fetch(o);
|
|
7496
|
+
if (r.ok) {
|
|
7497
|
+
const u = await r.json(), a = (Array.isArray(u) ? u : u.files || []).filter((c) => typeof c == "string" && c.toLowerCase().endsWith(".fbx")).map((c) => c.startsWith("/") ? c : `${s}/${c}`);
|
|
7498
|
+
a.length > 0 && (console.log(`✅ Auto-discovered ${a.length} animations from ${s}`), e.push(...a));
|
|
7499
|
+
}
|
|
7500
|
+
} catch {
|
|
7501
|
+
continue;
|
|
7502
|
+
}
|
|
7503
|
+
return e.length > 0 || (console.warn(`⚠️ Could not auto-discover animations from ${n}. Consider using a manifest.json file or a server-side directory listing API.`), console.info(`💡 Tip: Create a ${n}/.list.json file with an array of FBX filenames, or use animations: { manifest: "/animations/manifest.json" }`)), e;
|
|
7504
|
+
}
|
|
7505
|
+
async function je(Z, t = "F") {
|
|
7506
|
+
const e = {};
|
|
7507
|
+
for (const [n, i] of Object.entries(Z))
|
|
7508
|
+
try {
|
|
7509
|
+
const s = await Rt(i, t);
|
|
7510
|
+
s.length > 0 ? (e[n] = s, console.log(`✅ Auto-loaded ${s.length} animations for group "${n}"`)) : console.warn(`⚠️ No animations found in ${i} for group "${n}"`);
|
|
7511
|
+
} catch (s) {
|
|
7512
|
+
console.error(`❌ Failed to auto-load animations from ${i}:`, s);
|
|
7513
|
+
}
|
|
7514
|
+
return e;
|
|
7515
|
+
}
|
|
7516
|
+
const At = Be(({
|
|
7467
7517
|
text: Z = null,
|
|
7468
7518
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7469
7519
|
avatarBody: e = "F",
|
|
@@ -7472,9 +7522,9 @@ const ft = Fe(({
|
|
|
7472
7522
|
ttsService: s = null,
|
|
7473
7523
|
ttsVoice: o = null,
|
|
7474
7524
|
ttsApiKey: r = null,
|
|
7475
|
-
bodyMovement:
|
|
7525
|
+
bodyMovement: u = "idle",
|
|
7476
7526
|
movementIntensity: a = 0.5,
|
|
7477
|
-
showFullAvatar:
|
|
7527
|
+
showFullAvatar: c = !1,
|
|
7478
7528
|
cameraView: l = "upper",
|
|
7479
7529
|
onReady: d = () => {
|
|
7480
7530
|
},
|
|
@@ -7486,86 +7536,114 @@ const ft = Fe(({
|
|
|
7486
7536
|
},
|
|
7487
7537
|
className: f = "",
|
|
7488
7538
|
style: S = {},
|
|
7489
|
-
animations:
|
|
7539
|
+
animations: B = {},
|
|
7490
7540
|
autoAnimationGroup: g = null,
|
|
7491
7541
|
// e.g., "talking" - will randomly select from this group when speaking
|
|
7492
|
-
autoIdleGroup:
|
|
7542
|
+
autoIdleGroup: D = null,
|
|
7493
7543
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7494
7544
|
autoSpeak: T = !1
|
|
7495
|
-
},
|
|
7496
|
-
const
|
|
7497
|
-
|
|
7545
|
+
}, I) => {
|
|
7546
|
+
const N = X(null), L = X(null), R = X(c), z = X(null), y = X(null), M = X(!1), O = X({ remainingText: null, originalText: null, options: null }), E = X([]), [j, ae] = le(!0), [ce, xe] = le(null), [se, Ie] = le(!1), [ee, v] = le(!1), [A, F] = le(B), U = X(null), Y = X(!1), re = X(null);
|
|
7547
|
+
ge(() => {
|
|
7498
7548
|
M.current = ee;
|
|
7499
|
-
}, [ee]),
|
|
7549
|
+
}, [ee]), ge(() => {
|
|
7500
7550
|
(async () => {
|
|
7501
|
-
if (
|
|
7551
|
+
if (B.manifest)
|
|
7502
7552
|
try {
|
|
7503
|
-
console.log("🔄 Loading animations from manifest:",
|
|
7504
|
-
const
|
|
7505
|
-
|
|
7506
|
-
male: Object.keys(
|
|
7507
|
-
female: Object.keys(
|
|
7508
|
-
shared: Object.keys(
|
|
7553
|
+
console.log("🔄 Loading animations from manifest:", B.manifest);
|
|
7554
|
+
const C = await Qe(B.manifest);
|
|
7555
|
+
F(C), console.log("✅ Animations loaded and set:", C), C._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
|
|
7556
|
+
male: Object.keys(C._genderSpecific.male || {}),
|
|
7557
|
+
female: Object.keys(C._genderSpecific.female || {}),
|
|
7558
|
+
shared: Object.keys(C._genderSpecific.shared || {})
|
|
7509
7559
|
}) : console.log("⚠️ No gender-specific animations found in manifest");
|
|
7510
|
-
} catch (
|
|
7511
|
-
console.error("❌ Failed to load animation manifest:",
|
|
7560
|
+
} catch (C) {
|
|
7561
|
+
console.error("❌ Failed to load animation manifest:", C), F(B);
|
|
7562
|
+
}
|
|
7563
|
+
else if (B.auto)
|
|
7564
|
+
try {
|
|
7565
|
+
if (console.log("🔄 Auto-discovering animations from folder:", B.auto), typeof B.auto == "string") {
|
|
7566
|
+
const C = B.auto, W = {
|
|
7567
|
+
talking: `${C}/talking`,
|
|
7568
|
+
idle: `${C}/idle`
|
|
7569
|
+
}, V = e === "M" ? "male" : "female";
|
|
7570
|
+
W[`${V}_talking`] = `${C}/${V}/talking`, W[`${V}_idle`] = `${C}/${V}/idle`, W.shared_talking = `${C}/shared/talking`, W.shared_idle = `${C}/shared/idle`;
|
|
7571
|
+
const ie = await je(W, e), ue = {
|
|
7572
|
+
_genderSpecific: {
|
|
7573
|
+
[V]: {},
|
|
7574
|
+
shared: {}
|
|
7575
|
+
}
|
|
7576
|
+
};
|
|
7577
|
+
Object.entries(ie).forEach(([Ce, He]) => {
|
|
7578
|
+
if (Ce.includes("_")) {
|
|
7579
|
+
const [We, ..._e] = Ce.split("_"), ze = _e.join("_");
|
|
7580
|
+
We === "shared" ? (ue._genderSpecific.shared[ze] || (ue._genderSpecific.shared[ze] = []), ue._genderSpecific.shared[ze].push(...He)) : We === V && (ue._genderSpecific[V][ze] || (ue._genderSpecific[V][ze] = []), ue._genderSpecific[V][ze].push(...He));
|
|
7581
|
+
} else
|
|
7582
|
+
ue[Ce] = He;
|
|
7583
|
+
}), F(ue), console.log("✅ Auto-discovered animations:", ue);
|
|
7584
|
+
} else if (typeof B.auto == "object") {
|
|
7585
|
+
const C = await je(B.auto, e);
|
|
7586
|
+
F(C), console.log("✅ Auto-discovered animations from folders:", C);
|
|
7587
|
+
}
|
|
7588
|
+
} catch (C) {
|
|
7589
|
+
console.error("❌ Failed to auto-discover animations:", C), F(B);
|
|
7512
7590
|
}
|
|
7513
7591
|
else
|
|
7514
|
-
console.log("📝 Using animations from props (no manifest):",
|
|
7592
|
+
console.log("📝 Using animations from props (no manifest or auto):", B), F(B);
|
|
7515
7593
|
})();
|
|
7516
|
-
}, [
|
|
7517
|
-
R.current =
|
|
7518
|
-
}, [
|
|
7519
|
-
const K =
|
|
7520
|
-
let
|
|
7521
|
-
te === "browser" ?
|
|
7594
|
+
}, [B, e]), ge(() => {
|
|
7595
|
+
R.current = c;
|
|
7596
|
+
}, [c]);
|
|
7597
|
+
const K = De(), te = s || K.service;
|
|
7598
|
+
let ye;
|
|
7599
|
+
te === "browser" ? ye = {
|
|
7522
7600
|
service: "browser",
|
|
7523
7601
|
endpoint: "",
|
|
7524
7602
|
apiKey: null,
|
|
7525
7603
|
defaultVoice: "Google US English"
|
|
7526
|
-
} : te === "elevenlabs" ?
|
|
7604
|
+
} : te === "elevenlabs" ? ye = {
|
|
7527
7605
|
service: "elevenlabs",
|
|
7528
7606
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7529
7607
|
apiKey: r || K.apiKey,
|
|
7530
|
-
defaultVoice: o || K.defaultVoice ||
|
|
7531
|
-
voices: K.voices ||
|
|
7532
|
-
} : te === "deepgram" ?
|
|
7608
|
+
defaultVoice: o || K.defaultVoice || ke.defaultVoice,
|
|
7609
|
+
voices: K.voices || ke.voices
|
|
7610
|
+
} : te === "deepgram" ? ye = {
|
|
7533
7611
|
service: "deepgram",
|
|
7534
7612
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7535
7613
|
apiKey: r || K.apiKey,
|
|
7536
|
-
defaultVoice: o || K.defaultVoice ||
|
|
7537
|
-
voices: K.voices ||
|
|
7538
|
-
} :
|
|
7614
|
+
defaultVoice: o || K.defaultVoice || Pe.defaultVoice,
|
|
7615
|
+
voices: K.voices || Pe.voices
|
|
7616
|
+
} : ye = {
|
|
7539
7617
|
...K,
|
|
7540
7618
|
apiKey: r !== null ? r : K.apiKey
|
|
7541
7619
|
};
|
|
7542
|
-
const
|
|
7620
|
+
const we = {
|
|
7543
7621
|
url: t,
|
|
7544
7622
|
body: e,
|
|
7545
7623
|
avatarMood: n,
|
|
7546
7624
|
ttsLang: te === "browser" ? "en-US" : i,
|
|
7547
|
-
ttsVoice: o ||
|
|
7625
|
+
ttsVoice: o || ye.defaultVoice,
|
|
7548
7626
|
lipsyncLang: "en",
|
|
7549
|
-
showFullAvatar:
|
|
7550
|
-
bodyMovement:
|
|
7627
|
+
showFullAvatar: c,
|
|
7628
|
+
bodyMovement: u,
|
|
7551
7629
|
movementIntensity: a
|
|
7552
|
-
},
|
|
7553
|
-
ttsEndpoint:
|
|
7554
|
-
ttsApikey:
|
|
7630
|
+
}, Ne = {
|
|
7631
|
+
ttsEndpoint: ye.endpoint,
|
|
7632
|
+
ttsApikey: ye.apiKey,
|
|
7555
7633
|
ttsService: te,
|
|
7556
7634
|
lipsyncModules: ["en"],
|
|
7557
7635
|
cameraView: l
|
|
7558
|
-
},
|
|
7559
|
-
if (!(!
|
|
7636
|
+
}, Te = G(async () => {
|
|
7637
|
+
if (!(!N.current || L.current))
|
|
7560
7638
|
try {
|
|
7561
|
-
ae(!0),
|
|
7562
|
-
url:
|
|
7563
|
-
body:
|
|
7564
|
-
avatarMood:
|
|
7565
|
-
}), await L.current.showAvatar(
|
|
7566
|
-
if (
|
|
7567
|
-
const
|
|
7568
|
-
h(
|
|
7639
|
+
ae(!0), xe(null), L.current = new Ue(N.current, Ne), console.log("Avatar config being passed:", {
|
|
7640
|
+
url: we.url,
|
|
7641
|
+
body: we.body,
|
|
7642
|
+
avatarMood: we.avatarMood
|
|
7643
|
+
}), await L.current.showAvatar(we, (C) => {
|
|
7644
|
+
if (C.lengthComputable) {
|
|
7645
|
+
const W = Math.min(100, Math.round(C.loaded / C.total * 100));
|
|
7646
|
+
h(W);
|
|
7569
7647
|
}
|
|
7570
7648
|
}), L.current?.avatar && console.log("Avatar body after initialization:", L.current.avatar.body), ae(!1), Ie(!0), d(L.current);
|
|
7571
7649
|
const k = () => {
|
|
@@ -7575,13 +7653,13 @@ const ft = Fe(({
|
|
|
7575
7653
|
document.removeEventListener("visibilitychange", k);
|
|
7576
7654
|
};
|
|
7577
7655
|
} catch (k) {
|
|
7578
|
-
console.error("Error initializing TalkingHead:", k),
|
|
7656
|
+
console.error("Error initializing TalkingHead:", k), xe(k.message || "Failed to initialize avatar"), ae(!1), p(k);
|
|
7579
7657
|
}
|
|
7580
7658
|
}, []);
|
|
7581
|
-
|
|
7659
|
+
ge(() => (Te(), () => {
|
|
7582
7660
|
L.current && (L.current.stop(), L.current.dispose(), L.current = null);
|
|
7583
|
-
}), [
|
|
7584
|
-
const w =
|
|
7661
|
+
}), [Te]);
|
|
7662
|
+
const w = G(async () => {
|
|
7585
7663
|
if (L.current)
|
|
7586
7664
|
try {
|
|
7587
7665
|
const k = L.current.audioCtx || L.current.audioContext;
|
|
@@ -7589,46 +7667,46 @@ const ft = Fe(({
|
|
|
7589
7667
|
} catch (k) {
|
|
7590
7668
|
console.warn("Failed to resume audio context:", k);
|
|
7591
7669
|
}
|
|
7592
|
-
}, []),
|
|
7593
|
-
if (!
|
|
7670
|
+
}, []), Q = G((k) => {
|
|
7671
|
+
if (!A)
|
|
7594
7672
|
return console.warn("No animations loaded"), null;
|
|
7595
|
-
let
|
|
7596
|
-
if (
|
|
7597
|
-
const
|
|
7598
|
-
|
|
7673
|
+
let C = null;
|
|
7674
|
+
if (A._genderSpecific) {
|
|
7675
|
+
const V = (e?.toUpperCase() || "F") === "M" ? "male" : "female", ie = A._genderSpecific[V];
|
|
7676
|
+
ie && ie[k] ? (C = ie[k], console.log(`Using ${V} animations for "${k}":`, C)) : A._genderSpecific.shared && A._genderSpecific.shared[k] && (C = A._genderSpecific.shared[k], console.log(`Using shared animations for "${k}":`, C));
|
|
7599
7677
|
}
|
|
7600
|
-
if (!
|
|
7601
|
-
if (console.warn(`Animation group "${k}" not found. Available groups:`, Object.keys(
|
|
7602
|
-
const
|
|
7603
|
-
console.warn(`Gender-specific groups (${
|
|
7678
|
+
if (!C && A[k] && (C = A[k], console.log(`Using root-level animations for "${k}":`, C)), !C) {
|
|
7679
|
+
if (console.warn(`Animation group "${k}" not found. Available groups:`, Object.keys(A).filter((W) => W !== "_genderSpecific")), A._genderSpecific) {
|
|
7680
|
+
const V = (e?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
7681
|
+
console.warn(`Gender-specific groups (${V}):`, Object.keys(A._genderSpecific[V] || {}));
|
|
7604
7682
|
}
|
|
7605
7683
|
return null;
|
|
7606
7684
|
}
|
|
7607
|
-
if (Array.isArray(
|
|
7608
|
-
const
|
|
7609
|
-
return
|
|
7685
|
+
if (Array.isArray(C) && C.length > 0) {
|
|
7686
|
+
const W = Math.floor(Math.random() * C.length);
|
|
7687
|
+
return C[W];
|
|
7610
7688
|
}
|
|
7611
|
-
return typeof
|
|
7612
|
-
}, [
|
|
7689
|
+
return typeof C == "string" ? C : (console.warn(`Animation group "${k}" is not a valid format (expected array or string):`, C), null);
|
|
7690
|
+
}, [A, e]), q = G((k, C = !1, W = null) => {
|
|
7613
7691
|
if (!L.current)
|
|
7614
7692
|
return console.warn("TalkingHead not initialized yet"), null;
|
|
7615
|
-
const
|
|
7616
|
-
if (
|
|
7693
|
+
const V = Q(k);
|
|
7694
|
+
if (V)
|
|
7617
7695
|
try {
|
|
7618
|
-
const
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
}, 100) :
|
|
7696
|
+
const ie = () => {
|
|
7697
|
+
Y.current && re.current === k ? setTimeout(() => {
|
|
7698
|
+
q(k, C, W);
|
|
7699
|
+
}, 100) : W && W();
|
|
7622
7700
|
};
|
|
7623
|
-
return L.current.playAnimation(
|
|
7624
|
-
} catch (
|
|
7625
|
-
return console.error(`❌ Failed to play random animation from "${k}" group:`,
|
|
7701
|
+
return L.current.playAnimation(V, null, 10, 0, 0.01, C, ie), console.log(`✅ Playing random animation from "${k}" group:`, V), V;
|
|
7702
|
+
} catch (ie) {
|
|
7703
|
+
return console.error(`❌ Failed to play random animation from "${k}" group:`, ie), null;
|
|
7626
7704
|
}
|
|
7627
7705
|
else
|
|
7628
7706
|
console.warn(`⚠️ No animation found for group "${k}"`);
|
|
7629
7707
|
return null;
|
|
7630
|
-
}, [
|
|
7631
|
-
if (!L.current || !
|
|
7708
|
+
}, [Q]), ne = G(async (k, C = {}) => {
|
|
7709
|
+
if (!L.current || !se) {
|
|
7632
7710
|
console.warn("Avatar not ready for speaking");
|
|
7633
7711
|
return;
|
|
7634
7712
|
}
|
|
@@ -7637,93 +7715,93 @@ const ft = Fe(({
|
|
|
7637
7715
|
return;
|
|
7638
7716
|
}
|
|
7639
7717
|
await w();
|
|
7640
|
-
const
|
|
7641
|
-
|
|
7642
|
-
const
|
|
7643
|
-
|
|
7644
|
-
const
|
|
7645
|
-
lipsyncLang:
|
|
7718
|
+
const W = C.animationGroup || g;
|
|
7719
|
+
W && !C.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${W}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, A), Y.current = !0, re.current = W, q(W)) : console.log(`⏭️ Skipping animation (group: ${W}, skipAnimation: ${C.skipAnimation})`), O.current = { remainingText: null, originalText: null, options: null }, E.current = [], z.current = { text: k, options: C }, y.current && (clearInterval(y.current), y.current = null), v(!1), M.current = !1;
|
|
7720
|
+
const V = k.split(/[.!?]+/).filter((ue) => ue.trim().length > 0);
|
|
7721
|
+
E.current = V;
|
|
7722
|
+
const ie = {
|
|
7723
|
+
lipsyncLang: C.lipsyncLang || "en",
|
|
7646
7724
|
onSpeechEnd: () => {
|
|
7647
|
-
y.current && (clearInterval(y.current), y.current = null),
|
|
7725
|
+
y.current && (clearInterval(y.current), y.current = null), Y.current = !1, re.current = null, C.onSpeechEnd && C.onSpeechEnd(), b();
|
|
7648
7726
|
}
|
|
7649
7727
|
};
|
|
7650
7728
|
try {
|
|
7651
|
-
L.current.speakText(k,
|
|
7652
|
-
} catch (
|
|
7653
|
-
console.error("Error speaking text:",
|
|
7729
|
+
L.current.speakText(k, ie);
|
|
7730
|
+
} catch (ue) {
|
|
7731
|
+
console.error("Error speaking text:", ue), xe(ue.message || "Failed to speak text");
|
|
7654
7732
|
}
|
|
7655
|
-
}, [
|
|
7656
|
-
|
|
7657
|
-
if (!
|
|
7733
|
+
}, [se, b, w, g, q]);
|
|
7734
|
+
ge(() => {
|
|
7735
|
+
if (!se || !D || !L.current)
|
|
7658
7736
|
return;
|
|
7659
|
-
|
|
7737
|
+
U.current && clearInterval(U.current);
|
|
7660
7738
|
const k = () => {
|
|
7661
|
-
L.current && !M.current &&
|
|
7739
|
+
L.current && !M.current && q(D);
|
|
7662
7740
|
};
|
|
7663
|
-
return k(),
|
|
7741
|
+
return k(), U.current = setInterval(() => {
|
|
7664
7742
|
k();
|
|
7665
7743
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7666
|
-
|
|
7744
|
+
U.current && (clearInterval(U.current), U.current = null);
|
|
7667
7745
|
};
|
|
7668
|
-
}, [
|
|
7669
|
-
|
|
7670
|
-
}, [
|
|
7671
|
-
const
|
|
7746
|
+
}, [se, D, q]), ge(() => {
|
|
7747
|
+
se && Z && T && L.current && ne(Z);
|
|
7748
|
+
}, [se, Z, T, ne]);
|
|
7749
|
+
const be = G(() => {
|
|
7672
7750
|
if (L.current)
|
|
7673
7751
|
try {
|
|
7674
|
-
const k = L.current.isSpeaking || !1,
|
|
7675
|
-
if (k ||
|
|
7752
|
+
const k = L.current.isSpeaking || !1, C = L.current.audioPlaylist || [], W = L.current.speechQueue || [];
|
|
7753
|
+
if (k || C.length > 0 || W.length > 0) {
|
|
7676
7754
|
y.current && (clearInterval(y.current), y.current = null);
|
|
7677
|
-
let
|
|
7678
|
-
|
|
7679
|
-
remainingText:
|
|
7680
|
-
originalText:
|
|
7681
|
-
options:
|
|
7755
|
+
let V = "";
|
|
7756
|
+
W.length > 0 && (V = W.map((ie) => ie.text && Array.isArray(ie.text) ? ie.text.map((ue) => ue.word).join(" ") : ie.text || "").join(" ")), O.current = {
|
|
7757
|
+
remainingText: V || null,
|
|
7758
|
+
originalText: z.current?.text || null,
|
|
7759
|
+
options: z.current?.options || null
|
|
7682
7760
|
}, L.current.speechQueue.length = 0, L.current.pauseSpeaking(), v(!0), M.current = !0;
|
|
7683
7761
|
}
|
|
7684
7762
|
} catch (k) {
|
|
7685
7763
|
console.warn("Error pausing speech:", k);
|
|
7686
7764
|
}
|
|
7687
|
-
}, []),
|
|
7765
|
+
}, []), $ = G(async () => {
|
|
7688
7766
|
if (!(!L.current || !ee))
|
|
7689
7767
|
try {
|
|
7690
7768
|
await w(), v(!1), M.current = !1;
|
|
7691
|
-
const k =
|
|
7692
|
-
|
|
7769
|
+
const k = O.current?.remainingText, C = O.current?.originalText || z.current?.text, W = O.current?.options || z.current?.options || {}, V = k || C;
|
|
7770
|
+
V && ne(V, W);
|
|
7693
7771
|
} catch (k) {
|
|
7694
7772
|
console.warn("Error resuming speech:", k), v(!1), M.current = !1;
|
|
7695
7773
|
}
|
|
7696
|
-
}, [ee, ne, w]),
|
|
7697
|
-
L.current && (L.current.stopSpeaking(), y.current && (clearInterval(y.current), y.current = null),
|
|
7774
|
+
}, [ee, ne, w]), me = G(() => {
|
|
7775
|
+
L.current && (L.current.stopSpeaking(), y.current && (clearInterval(y.current), y.current = null), Y.current = !1, re.current = null, v(!1), M.current = !1);
|
|
7698
7776
|
}, []);
|
|
7699
|
-
return
|
|
7777
|
+
return Oe(I, () => ({
|
|
7700
7778
|
speakText: ne,
|
|
7701
|
-
pauseSpeaking:
|
|
7702
|
-
resumeSpeaking:
|
|
7703
|
-
stopSpeaking:
|
|
7779
|
+
pauseSpeaking: be,
|
|
7780
|
+
resumeSpeaking: $,
|
|
7781
|
+
stopSpeaking: me,
|
|
7704
7782
|
resumeAudioContext: w,
|
|
7705
7783
|
isPaused: () => ee,
|
|
7706
7784
|
setMood: (k) => L.current?.setMood(k),
|
|
7707
7785
|
setBodyMovement: (k) => {
|
|
7708
7786
|
L.current && L.current.setBodyMovement(k);
|
|
7709
7787
|
},
|
|
7710
|
-
playAnimation: (k,
|
|
7711
|
-
L.current && L.current.playAnimation && L.current.playAnimation(k, null, 10, 0, 0.01,
|
|
7788
|
+
playAnimation: (k, C = !1) => {
|
|
7789
|
+
L.current && L.current.playAnimation && L.current.playAnimation(k, null, 10, 0, 0.01, C);
|
|
7712
7790
|
},
|
|
7713
|
-
playRandomAnimation: (k,
|
|
7714
|
-
getRandomAnimation: (k) =>
|
|
7791
|
+
playRandomAnimation: (k, C = !1) => q(k, C),
|
|
7792
|
+
getRandomAnimation: (k) => Q(k),
|
|
7715
7793
|
playReaction: (k) => L.current?.playReaction(k),
|
|
7716
7794
|
playCelebration: () => L.current?.playCelebration(),
|
|
7717
7795
|
setShowFullAvatar: (k) => {
|
|
7718
7796
|
L.current && (R.current = k, L.current.setShowFullAvatar(k));
|
|
7719
7797
|
},
|
|
7720
|
-
isReady:
|
|
7798
|
+
isReady: se,
|
|
7721
7799
|
talkingHead: L.current
|
|
7722
|
-
})), /* @__PURE__ */
|
|
7723
|
-
/* @__PURE__ */
|
|
7800
|
+
})), /* @__PURE__ */ ve("div", { className: `simple-talking-avatar-container ${f}`, style: S, children: [
|
|
7801
|
+
/* @__PURE__ */ J(
|
|
7724
7802
|
"div",
|
|
7725
7803
|
{
|
|
7726
|
-
ref:
|
|
7804
|
+
ref: N,
|
|
7727
7805
|
className: "talking-head-viewer",
|
|
7728
7806
|
style: {
|
|
7729
7807
|
width: "100%",
|
|
@@ -7732,7 +7810,7 @@ const ft = Fe(({
|
|
|
7732
7810
|
}
|
|
7733
7811
|
}
|
|
7734
7812
|
),
|
|
7735
|
-
|
|
7813
|
+
j && /* @__PURE__ */ J("div", { className: "loading-overlay", style: {
|
|
7736
7814
|
position: "absolute",
|
|
7737
7815
|
top: "50%",
|
|
7738
7816
|
left: "50%",
|
|
@@ -7741,7 +7819,7 @@ const ft = Fe(({
|
|
|
7741
7819
|
fontSize: "18px",
|
|
7742
7820
|
zIndex: 10
|
|
7743
7821
|
}, children: "Loading avatar..." }),
|
|
7744
|
-
|
|
7822
|
+
ce && /* @__PURE__ */ J("div", { className: "error-overlay", style: {
|
|
7745
7823
|
position: "absolute",
|
|
7746
7824
|
top: "50%",
|
|
7747
7825
|
left: "50%",
|
|
@@ -7752,11 +7830,11 @@ const ft = Fe(({
|
|
|
7752
7830
|
zIndex: 10,
|
|
7753
7831
|
padding: "20px",
|
|
7754
7832
|
borderRadius: "8px"
|
|
7755
|
-
}, children:
|
|
7833
|
+
}, children: ce })
|
|
7756
7834
|
] });
|
|
7757
7835
|
});
|
|
7758
|
-
|
|
7759
|
-
const
|
|
7836
|
+
At.displayName = "SimpleTalkingAvatar";
|
|
7837
|
+
const It = Be(({
|
|
7760
7838
|
curriculumData: Z = null,
|
|
7761
7839
|
avatarConfig: t = {},
|
|
7762
7840
|
animations: e = {},
|
|
@@ -7770,9 +7848,9 @@ const xt = Fe(({
|
|
|
7770
7848
|
},
|
|
7771
7849
|
onCustomAction: r = () => {
|
|
7772
7850
|
},
|
|
7773
|
-
autoStart:
|
|
7851
|
+
autoStart: u = !1
|
|
7774
7852
|
}, a) => {
|
|
7775
|
-
const
|
|
7853
|
+
const c = X(null), l = X({
|
|
7776
7854
|
currentModuleIndex: 0,
|
|
7777
7855
|
currentLessonIndex: 0,
|
|
7778
7856
|
currentQuestionIndex: 0,
|
|
@@ -7782,18 +7860,18 @@ const xt = Fe(({
|
|
|
7782
7860
|
curriculumCompleted: !1,
|
|
7783
7861
|
score: 0,
|
|
7784
7862
|
totalQuestions: 0
|
|
7785
|
-
}), d =
|
|
7863
|
+
}), d = X({
|
|
7786
7864
|
onLessonStart: n,
|
|
7787
7865
|
onLessonComplete: i,
|
|
7788
7866
|
onQuestionAnswer: s,
|
|
7789
7867
|
onCurriculumComplete: o,
|
|
7790
7868
|
onCustomAction: r
|
|
7791
|
-
}), h =
|
|
7869
|
+
}), h = X(null), p = X(null), b = X(null), f = X(null), S = X(null), B = X(null), g = X(null), D = X(Z?.curriculum || {
|
|
7792
7870
|
title: "Default Curriculum",
|
|
7793
7871
|
description: "No curriculum data provided",
|
|
7794
7872
|
language: "en",
|
|
7795
7873
|
modules: []
|
|
7796
|
-
}), T =
|
|
7874
|
+
}), T = X({
|
|
7797
7875
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7798
7876
|
avatarBody: t.avatarBody || "F",
|
|
7799
7877
|
mood: t.mood || "happy",
|
|
@@ -7807,7 +7885,7 @@ const xt = Fe(({
|
|
|
7807
7885
|
animations: e,
|
|
7808
7886
|
lipsyncLang: "en"
|
|
7809
7887
|
});
|
|
7810
|
-
|
|
7888
|
+
ge(() => {
|
|
7811
7889
|
d.current = {
|
|
7812
7890
|
onLessonStart: n,
|
|
7813
7891
|
onLessonComplete: i,
|
|
@@ -7815,8 +7893,8 @@ const xt = Fe(({
|
|
|
7815
7893
|
onCurriculumComplete: o,
|
|
7816
7894
|
onCustomAction: r
|
|
7817
7895
|
};
|
|
7818
|
-
}, [n, i, s, o, r]),
|
|
7819
|
-
|
|
7896
|
+
}, [n, i, s, o, r]), ge(() => {
|
|
7897
|
+
D.current = Z?.curriculum || {
|
|
7820
7898
|
title: "Default Curriculum",
|
|
7821
7899
|
description: "No curriculum data provided",
|
|
7822
7900
|
language: "en",
|
|
@@ -7836,11 +7914,11 @@ const xt = Fe(({
|
|
|
7836
7914
|
lipsyncLang: "en"
|
|
7837
7915
|
};
|
|
7838
7916
|
}, [Z, t, e]);
|
|
7839
|
-
const
|
|
7917
|
+
const I = G(() => (D.current || { modules: [] }).modules[l.current.currentModuleIndex]?.lessons[l.current.currentLessonIndex], []), N = G(() => I()?.questions[l.current.currentQuestionIndex], [I]), L = G((v, A) => A.type === "multiple_choice" || A.type === "true_false" ? v === A.answer : A.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), R = G(() => {
|
|
7840
7918
|
l.current.lessonCompleted = !0, l.current.isQuestionMode = !1;
|
|
7841
7919
|
const v = l.current.totalQuestions > 0 ? Math.round(l.current.score / l.current.totalQuestions * 100) : 100;
|
|
7842
|
-
let
|
|
7843
|
-
if (l.current.totalQuestions > 0 ?
|
|
7920
|
+
let A = "Congratulations! You've completed this lesson";
|
|
7921
|
+
if (l.current.totalQuestions > 0 ? A += ` You got ${l.current.score} correct out of ${l.current.totalQuestions} question${l.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : A += "! ", v >= 80 ? A += "Excellent work! You have a great understanding of this topic." : v >= 60 ? A += "Good job! You understand most of the concepts." : A += "Keep practicing! You're making progress.", d.current.onLessonComplete({
|
|
7844
7922
|
moduleIndex: l.current.currentModuleIndex,
|
|
7845
7923
|
lessonIndex: l.current.currentLessonIndex,
|
|
7846
7924
|
score: l.current.score,
|
|
@@ -7853,15 +7931,15 @@ const xt = Fe(({
|
|
|
7853
7931
|
score: l.current.score,
|
|
7854
7932
|
totalQuestions: l.current.totalQuestions,
|
|
7855
7933
|
percentage: v
|
|
7856
|
-
}),
|
|
7857
|
-
if (
|
|
7934
|
+
}), c.current) {
|
|
7935
|
+
if (c.current.setMood("happy"), e.lessonComplete)
|
|
7858
7936
|
try {
|
|
7859
|
-
|
|
7937
|
+
c.current.playAnimation(e.lessonComplete, !0);
|
|
7860
7938
|
} catch {
|
|
7861
|
-
|
|
7939
|
+
c.current.playCelebration();
|
|
7862
7940
|
}
|
|
7863
|
-
const
|
|
7864
|
-
|
|
7941
|
+
const F = D.current || { modules: [] }, U = F.modules[l.current.currentModuleIndex], Y = l.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, re = l.current.currentModuleIndex < (F.modules?.length || 0) - 1, K = Y || re, te = T.current || { lipsyncLang: "en" };
|
|
7942
|
+
c.current.speakText(A, {
|
|
7865
7943
|
lipsyncLang: te.lipsyncLang,
|
|
7866
7944
|
onSpeechEnd: () => {
|
|
7867
7945
|
d.current.onCustomAction({
|
|
@@ -7876,112 +7954,112 @@ const xt = Fe(({
|
|
|
7876
7954
|
}
|
|
7877
7955
|
});
|
|
7878
7956
|
}
|
|
7879
|
-
}, [e.lessonComplete]),
|
|
7957
|
+
}, [e.lessonComplete]), z = G(() => {
|
|
7880
7958
|
l.current.curriculumCompleted = !0;
|
|
7881
|
-
const v =
|
|
7959
|
+
const v = D.current || { modules: [] };
|
|
7882
7960
|
if (d.current.onCurriculumComplete({
|
|
7883
7961
|
modules: v.modules.length,
|
|
7884
|
-
totalLessons: v.modules.reduce((
|
|
7885
|
-
}),
|
|
7886
|
-
if (
|
|
7962
|
+
totalLessons: v.modules.reduce((A, F) => A + F.lessons.length, 0)
|
|
7963
|
+
}), c.current) {
|
|
7964
|
+
if (c.current.setMood("celebrating"), e.curriculumComplete)
|
|
7887
7965
|
try {
|
|
7888
|
-
|
|
7966
|
+
c.current.playAnimation(e.curriculumComplete, !0);
|
|
7889
7967
|
} catch {
|
|
7890
|
-
|
|
7968
|
+
c.current.playCelebration();
|
|
7891
7969
|
}
|
|
7892
|
-
const
|
|
7893
|
-
|
|
7970
|
+
const A = T.current || { lipsyncLang: "en" };
|
|
7971
|
+
c.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: A.lipsyncLang });
|
|
7894
7972
|
}
|
|
7895
|
-
}, [e.curriculumComplete]), y =
|
|
7896
|
-
const v =
|
|
7973
|
+
}, [e.curriculumComplete]), y = G(() => {
|
|
7974
|
+
const v = I();
|
|
7897
7975
|
l.current.isQuestionMode = !0, l.current.currentQuestionIndex = 0, l.current.totalQuestions = v?.questions?.length || 0, l.current.score = 0;
|
|
7898
|
-
const
|
|
7899
|
-
|
|
7976
|
+
const A = N();
|
|
7977
|
+
A && d.current.onCustomAction({
|
|
7900
7978
|
type: "questionStart",
|
|
7901
7979
|
moduleIndex: l.current.currentModuleIndex,
|
|
7902
7980
|
lessonIndex: l.current.currentLessonIndex,
|
|
7903
7981
|
questionIndex: l.current.currentQuestionIndex,
|
|
7904
7982
|
totalQuestions: l.current.totalQuestions,
|
|
7905
|
-
question:
|
|
7983
|
+
question: A,
|
|
7906
7984
|
score: l.current.score
|
|
7907
7985
|
});
|
|
7908
|
-
const
|
|
7909
|
-
if (!
|
|
7910
|
-
if (
|
|
7986
|
+
const F = () => {
|
|
7987
|
+
if (!c.current || !A) return;
|
|
7988
|
+
if (c.current.setMood("happy"), e.questionStart)
|
|
7911
7989
|
try {
|
|
7912
|
-
|
|
7913
|
-
} catch (
|
|
7914
|
-
console.warn("Failed to play questionStart animation:",
|
|
7990
|
+
c.current.playAnimation(e.questionStart, !0);
|
|
7991
|
+
} catch (Y) {
|
|
7992
|
+
console.warn("Failed to play questionStart animation:", Y);
|
|
7915
7993
|
}
|
|
7916
|
-
const
|
|
7917
|
-
|
|
7994
|
+
const U = T.current || { lipsyncLang: "en" };
|
|
7995
|
+
A.type === "code_test" ? c.current.speakText(`Let's test your coding skills! Here's your first challenge: ${A.question}`, { lipsyncLang: U.lipsyncLang }) : A.type === "multiple_choice" ? c.current.speakText(`Now let me ask you some questions. Here's the first one: ${A.question}`, { lipsyncLang: U.lipsyncLang }) : A.type === "true_false" ? c.current.speakText(`Let's start with some true or false questions. First question: ${A.question}`, { lipsyncLang: U.lipsyncLang }) : c.current.speakText(`Now let me ask you some questions. Here's the first one: ${A.question}`, { lipsyncLang: U.lipsyncLang });
|
|
7918
7996
|
};
|
|
7919
|
-
if (
|
|
7920
|
-
|
|
7921
|
-
else if (
|
|
7922
|
-
const
|
|
7923
|
-
|
|
7997
|
+
if (c.current && c.current.isReady && A)
|
|
7998
|
+
F();
|
|
7999
|
+
else if (c.current && c.current.isReady) {
|
|
8000
|
+
const U = T.current || { lipsyncLang: "en" };
|
|
8001
|
+
c.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: U.lipsyncLang });
|
|
7924
8002
|
} else {
|
|
7925
|
-
const
|
|
7926
|
-
|
|
8003
|
+
const U = setInterval(() => {
|
|
8004
|
+
c.current && c.current.isReady && (clearInterval(U), A && F());
|
|
7927
8005
|
}, 100);
|
|
7928
8006
|
setTimeout(() => {
|
|
7929
|
-
clearInterval(
|
|
8007
|
+
clearInterval(U);
|
|
7930
8008
|
}, 5e3);
|
|
7931
8009
|
}
|
|
7932
|
-
}, [e.questionStart,
|
|
7933
|
-
const v =
|
|
8010
|
+
}, [e.questionStart, I, N]), M = G(() => {
|
|
8011
|
+
const v = I();
|
|
7934
8012
|
if (l.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7935
|
-
|
|
7936
|
-
const
|
|
7937
|
-
|
|
8013
|
+
c.current && c.current.stopSpeaking && c.current.stopSpeaking(), l.current.currentQuestionIndex += 1;
|
|
8014
|
+
const A = N();
|
|
8015
|
+
A && d.current.onCustomAction({
|
|
7938
8016
|
type: "nextQuestion",
|
|
7939
8017
|
moduleIndex: l.current.currentModuleIndex,
|
|
7940
8018
|
lessonIndex: l.current.currentLessonIndex,
|
|
7941
8019
|
questionIndex: l.current.currentQuestionIndex,
|
|
7942
8020
|
totalQuestions: l.current.totalQuestions,
|
|
7943
|
-
question:
|
|
8021
|
+
question: A,
|
|
7944
8022
|
score: l.current.score
|
|
7945
8023
|
});
|
|
7946
|
-
const
|
|
7947
|
-
if (!
|
|
7948
|
-
if (
|
|
8024
|
+
const F = () => {
|
|
8025
|
+
if (!c.current || !A) return;
|
|
8026
|
+
if (c.current.setMood("happy"), c.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7949
8027
|
try {
|
|
7950
|
-
|
|
8028
|
+
c.current.playAnimation(e.nextQuestion, !0);
|
|
7951
8029
|
} catch (te) {
|
|
7952
8030
|
console.warn("Failed to play nextQuestion animation:", te);
|
|
7953
8031
|
}
|
|
7954
|
-
const
|
|
7955
|
-
if (
|
|
7956
|
-
const te = K ? `Great! Here's your final coding challenge: ${
|
|
7957
|
-
|
|
7958
|
-
lipsyncLang:
|
|
8032
|
+
const U = T.current || { lipsyncLang: "en" }, re = I()?.questions?.length || 0, K = l.current.currentQuestionIndex >= re - 1;
|
|
8033
|
+
if (A.type === "code_test") {
|
|
8034
|
+
const te = K ? `Great! Here's your final coding challenge: ${A.question}` : `Great! Now let's move on to your next coding challenge: ${A.question}`;
|
|
8035
|
+
c.current.speakText(te, {
|
|
8036
|
+
lipsyncLang: U.lipsyncLang
|
|
7959
8037
|
});
|
|
7960
|
-
} else if (
|
|
7961
|
-
const te = K ? `Alright! Here's your final question: ${
|
|
7962
|
-
|
|
7963
|
-
lipsyncLang:
|
|
8038
|
+
} else if (A.type === "multiple_choice") {
|
|
8039
|
+
const te = K ? `Alright! Here's your final question: ${A.question}` : `Alright! Here's your next question: ${A.question}`;
|
|
8040
|
+
c.current.speakText(te, {
|
|
8041
|
+
lipsyncLang: U.lipsyncLang
|
|
7964
8042
|
});
|
|
7965
|
-
} else if (
|
|
7966
|
-
const te = K ? `Now let's try this final one: ${
|
|
7967
|
-
|
|
7968
|
-
lipsyncLang:
|
|
8043
|
+
} else if (A.type === "true_false") {
|
|
8044
|
+
const te = K ? `Now let's try this final one: ${A.question}` : `Now let's try this one: ${A.question}`;
|
|
8045
|
+
c.current.speakText(te, {
|
|
8046
|
+
lipsyncLang: U.lipsyncLang
|
|
7969
8047
|
});
|
|
7970
8048
|
} else {
|
|
7971
|
-
const te = K ? `Here's your final question: ${
|
|
7972
|
-
|
|
7973
|
-
lipsyncLang:
|
|
8049
|
+
const te = K ? `Here's your final question: ${A.question}` : `Here's the next question: ${A.question}`;
|
|
8050
|
+
c.current.speakText(te, {
|
|
8051
|
+
lipsyncLang: U.lipsyncLang
|
|
7974
8052
|
});
|
|
7975
8053
|
}
|
|
7976
8054
|
};
|
|
7977
|
-
if (
|
|
7978
|
-
|
|
7979
|
-
else if (
|
|
7980
|
-
const
|
|
7981
|
-
|
|
8055
|
+
if (c.current && c.current.isReady && A)
|
|
8056
|
+
F();
|
|
8057
|
+
else if (A) {
|
|
8058
|
+
const U = setInterval(() => {
|
|
8059
|
+
c.current && c.current.isReady && (clearInterval(U), F());
|
|
7982
8060
|
}, 100);
|
|
7983
8061
|
setTimeout(() => {
|
|
7984
|
-
clearInterval(
|
|
8062
|
+
clearInterval(U);
|
|
7985
8063
|
}, 5e3);
|
|
7986
8064
|
}
|
|
7987
8065
|
} else
|
|
@@ -7992,11 +8070,11 @@ const xt = Fe(({
|
|
|
7992
8070
|
totalQuestions: l.current.totalQuestions,
|
|
7993
8071
|
score: l.current.score
|
|
7994
8072
|
});
|
|
7995
|
-
}, [e.nextQuestion,
|
|
7996
|
-
const v =
|
|
7997
|
-
if (l.current.currentLessonIndex < (
|
|
8073
|
+
}, [e.nextQuestion, I, N]), O = G(() => {
|
|
8074
|
+
const v = D.current || { modules: [] }, A = v.modules[l.current.currentModuleIndex];
|
|
8075
|
+
if (l.current.currentLessonIndex < (A?.lessons?.length || 0) - 1) {
|
|
7998
8076
|
l.current.currentLessonIndex += 1, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0;
|
|
7999
|
-
const
|
|
8077
|
+
const U = v.modules[l.current.currentModuleIndex], Y = l.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, re = l.current.currentModuleIndex < (v.modules?.length || 0) - 1, K = Y || re;
|
|
8000
8078
|
d.current.onCustomAction({
|
|
8001
8079
|
type: "lessonStart",
|
|
8002
8080
|
moduleIndex: l.current.currentModuleIndex,
|
|
@@ -8005,11 +8083,11 @@ const xt = Fe(({
|
|
|
8005
8083
|
}), d.current.onLessonStart({
|
|
8006
8084
|
moduleIndex: l.current.currentModuleIndex,
|
|
8007
8085
|
lessonIndex: l.current.currentLessonIndex,
|
|
8008
|
-
lesson:
|
|
8009
|
-
}),
|
|
8086
|
+
lesson: I()
|
|
8087
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8010
8088
|
} else if (l.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
8011
8089
|
l.current.currentModuleIndex += 1, l.current.currentLessonIndex = 0, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0;
|
|
8012
|
-
const
|
|
8090
|
+
const Y = v.modules[l.current.currentModuleIndex], re = l.current.currentLessonIndex < (Y?.lessons?.length || 0) - 1, K = l.current.currentModuleIndex < (v.modules?.length || 0) - 1, te = re || K;
|
|
8013
8091
|
d.current.onCustomAction({
|
|
8014
8092
|
type: "lessonStart",
|
|
8015
8093
|
moduleIndex: l.current.currentModuleIndex,
|
|
@@ -8018,29 +8096,29 @@ const xt = Fe(({
|
|
|
8018
8096
|
}), d.current.onLessonStart({
|
|
8019
8097
|
moduleIndex: l.current.currentModuleIndex,
|
|
8020
8098
|
lessonIndex: l.current.currentLessonIndex,
|
|
8021
|
-
lesson:
|
|
8022
|
-
}),
|
|
8099
|
+
lesson: I()
|
|
8100
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8023
8101
|
} else
|
|
8024
8102
|
S.current && S.current();
|
|
8025
|
-
}, []),
|
|
8026
|
-
const v =
|
|
8027
|
-
let
|
|
8103
|
+
}, []), E = G(() => {
|
|
8104
|
+
const v = I();
|
|
8105
|
+
let A = null;
|
|
8028
8106
|
if (v?.avatar_script && v?.body) {
|
|
8029
|
-
const
|
|
8030
|
-
|
|
8107
|
+
const F = v.avatar_script.trim(), U = v.body.trim(), Y = F.match(/[.!?]$/) ? " " : ". ";
|
|
8108
|
+
A = `${F}${Y}${U}`;
|
|
8031
8109
|
} else
|
|
8032
|
-
|
|
8033
|
-
if (
|
|
8034
|
-
l.current.isTeaching = !0, l.current.isQuestionMode = !1, l.current.score = 0, l.current.totalQuestions = 0,
|
|
8035
|
-
let
|
|
8110
|
+
A = v?.avatar_script || v?.body || null;
|
|
8111
|
+
if (c.current && c.current.isReady && A) {
|
|
8112
|
+
l.current.isTeaching = !0, l.current.isQuestionMode = !1, l.current.score = 0, l.current.totalQuestions = 0, c.current.setMood("happy");
|
|
8113
|
+
let F = !1;
|
|
8036
8114
|
if (e.teaching)
|
|
8037
8115
|
try {
|
|
8038
|
-
|
|
8039
|
-
} catch (
|
|
8040
|
-
console.warn("Failed to play teaching animation:",
|
|
8116
|
+
c.current.playAnimation(e.teaching, !0), F = !0;
|
|
8117
|
+
} catch (Y) {
|
|
8118
|
+
console.warn("Failed to play teaching animation:", Y);
|
|
8041
8119
|
}
|
|
8042
|
-
|
|
8043
|
-
const
|
|
8120
|
+
F || c.current.setBodyMovement("gesturing");
|
|
8121
|
+
const U = T.current || { lipsyncLang: "en" };
|
|
8044
8122
|
d.current.onLessonStart({
|
|
8045
8123
|
moduleIndex: l.current.currentModuleIndex,
|
|
8046
8124
|
lessonIndex: l.current.currentLessonIndex,
|
|
@@ -8050,8 +8128,8 @@ const xt = Fe(({
|
|
|
8050
8128
|
moduleIndex: l.current.currentModuleIndex,
|
|
8051
8129
|
lessonIndex: l.current.currentLessonIndex,
|
|
8052
8130
|
lesson: v
|
|
8053
|
-
}),
|
|
8054
|
-
lipsyncLang:
|
|
8131
|
+
}), c.current.speakText(A, {
|
|
8132
|
+
lipsyncLang: U.lipsyncLang,
|
|
8055
8133
|
onSpeechEnd: () => {
|
|
8056
8134
|
l.current.isTeaching = !1, d.current.onCustomAction({
|
|
8057
8135
|
type: "teachingComplete",
|
|
@@ -8069,30 +8147,30 @@ const xt = Fe(({
|
|
|
8069
8147
|
}
|
|
8070
8148
|
});
|
|
8071
8149
|
}
|
|
8072
|
-
}, [e.teaching,
|
|
8073
|
-
const
|
|
8074
|
-
if (
|
|
8150
|
+
}, [e.teaching, I]), j = G((v) => {
|
|
8151
|
+
const A = N(), F = L(v, A);
|
|
8152
|
+
if (F && (l.current.score += 1), d.current.onQuestionAnswer({
|
|
8075
8153
|
moduleIndex: l.current.currentModuleIndex,
|
|
8076
8154
|
lessonIndex: l.current.currentLessonIndex,
|
|
8077
8155
|
questionIndex: l.current.currentQuestionIndex,
|
|
8078
8156
|
answer: v,
|
|
8079
|
-
isCorrect:
|
|
8080
|
-
question:
|
|
8081
|
-
}),
|
|
8082
|
-
if (
|
|
8083
|
-
if (
|
|
8157
|
+
isCorrect: F,
|
|
8158
|
+
question: A
|
|
8159
|
+
}), c.current)
|
|
8160
|
+
if (F) {
|
|
8161
|
+
if (c.current.setMood("happy"), e.correct)
|
|
8084
8162
|
try {
|
|
8085
|
-
|
|
8163
|
+
c.current.playReaction("happy");
|
|
8086
8164
|
} catch {
|
|
8087
|
-
|
|
8165
|
+
c.current.setBodyMovement("happy");
|
|
8088
8166
|
}
|
|
8089
|
-
|
|
8090
|
-
const
|
|
8091
|
-
l.current.currentQuestionIndex >=
|
|
8092
|
-
const re = l.current.currentQuestionIndex <
|
|
8093
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", l.current.currentQuestionIndex, "totalQuestions:",
|
|
8094
|
-
const K =
|
|
8095
|
-
|
|
8167
|
+
c.current.setBodyMovement("gesturing");
|
|
8168
|
+
const Y = I()?.questions?.length || 0;
|
|
8169
|
+
l.current.currentQuestionIndex >= Y - 1;
|
|
8170
|
+
const re = l.current.currentQuestionIndex < Y - 1;
|
|
8171
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", l.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", re);
|
|
8172
|
+
const K = A.type === "code_test" ? `Great job! Your code passed all the tests! ${A.explanation || ""}` : `Excellent! That's correct! ${A.explanation || ""}`, te = T.current || { lipsyncLang: "en" };
|
|
8173
|
+
c.current.speakText(K, {
|
|
8096
8174
|
lipsyncLang: te.lipsyncLang,
|
|
8097
8175
|
onSpeechEnd: () => {
|
|
8098
8176
|
d.current.onCustomAction({
|
|
@@ -8108,18 +8186,18 @@ const xt = Fe(({
|
|
|
8108
8186
|
}
|
|
8109
8187
|
});
|
|
8110
8188
|
} else {
|
|
8111
|
-
if (
|
|
8189
|
+
if (c.current.setMood("sad"), e.incorrect)
|
|
8112
8190
|
try {
|
|
8113
|
-
|
|
8191
|
+
c.current.playAnimation(e.incorrect, !0);
|
|
8114
8192
|
} catch {
|
|
8115
|
-
|
|
8193
|
+
c.current.setBodyMovement("idle");
|
|
8116
8194
|
}
|
|
8117
|
-
|
|
8118
|
-
const
|
|
8119
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", l.current.currentQuestionIndex, "totalQuestions:",
|
|
8120
|
-
const te =
|
|
8121
|
-
|
|
8122
|
-
lipsyncLang:
|
|
8195
|
+
c.current.setBodyMovement("gesturing");
|
|
8196
|
+
const Y = I()?.questions?.length || 0, re = l.current.currentQuestionIndex >= Y - 1, K = l.current.currentQuestionIndex < Y - 1;
|
|
8197
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", l.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", K);
|
|
8198
|
+
const te = A.type === "code_test" ? `Your code didn't pass all the tests. ${A.explanation || "Try again!"}` : `Not quite right, but don't worry! ${A.explanation || ""}${re ? "" : " Let's move on to the next question."}`, ye = T.current || { lipsyncLang: "en" };
|
|
8199
|
+
c.current.speakText(te, {
|
|
8200
|
+
lipsyncLang: ye.lipsyncLang,
|
|
8123
8201
|
onSpeechEnd: () => {
|
|
8124
8202
|
d.current.onCustomAction({
|
|
8125
8203
|
type: "answerFeedbackComplete",
|
|
@@ -8135,30 +8213,30 @@ const xt = Fe(({
|
|
|
8135
8213
|
});
|
|
8136
8214
|
}
|
|
8137
8215
|
else {
|
|
8138
|
-
const
|
|
8216
|
+
const Y = I()?.questions?.length || 0;
|
|
8139
8217
|
d.current.onCustomAction({
|
|
8140
8218
|
type: "answerFeedbackComplete",
|
|
8141
8219
|
moduleIndex: l.current.currentModuleIndex,
|
|
8142
8220
|
lessonIndex: l.current.currentLessonIndex,
|
|
8143
8221
|
questionIndex: l.current.currentQuestionIndex,
|
|
8144
|
-
isCorrect:
|
|
8145
|
-
hasNextQuestion: l.current.currentQuestionIndex <
|
|
8222
|
+
isCorrect: F,
|
|
8223
|
+
hasNextQuestion: l.current.currentQuestionIndex < Y - 1,
|
|
8146
8224
|
score: l.current.score,
|
|
8147
8225
|
totalQuestions: l.current.totalQuestions,
|
|
8148
8226
|
avatarNotReady: !0
|
|
8149
8227
|
});
|
|
8150
8228
|
}
|
|
8151
|
-
}, [e.correct, e.incorrect,
|
|
8152
|
-
const
|
|
8229
|
+
}, [e.correct, e.incorrect, N, I, L]), ae = G((v) => {
|
|
8230
|
+
const A = N();
|
|
8153
8231
|
if (!v || typeof v != "object") {
|
|
8154
8232
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8155
8233
|
return;
|
|
8156
8234
|
}
|
|
8157
|
-
if (
|
|
8235
|
+
if (A?.type !== "code_test") {
|
|
8158
8236
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8159
8237
|
return;
|
|
8160
8238
|
}
|
|
8161
|
-
const
|
|
8239
|
+
const F = {
|
|
8162
8240
|
passed: v.passed === !0,
|
|
8163
8241
|
results: v.results || [],
|
|
8164
8242
|
output: v.output || "",
|
|
@@ -8173,13 +8251,13 @@ const xt = Fe(({
|
|
|
8173
8251
|
moduleIndex: l.current.currentModuleIndex,
|
|
8174
8252
|
lessonIndex: l.current.currentLessonIndex,
|
|
8175
8253
|
questionIndex: l.current.currentQuestionIndex,
|
|
8176
|
-
testResult:
|
|
8177
|
-
question:
|
|
8178
|
-
}), g.current && g.current(
|
|
8179
|
-
}, [
|
|
8254
|
+
testResult: F,
|
|
8255
|
+
question: A
|
|
8256
|
+
}), g.current && g.current(F);
|
|
8257
|
+
}, [N, L]), ce = G(() => {
|
|
8180
8258
|
if (l.current.currentQuestionIndex > 0) {
|
|
8181
8259
|
l.current.currentQuestionIndex -= 1;
|
|
8182
|
-
const v =
|
|
8260
|
+
const v = N();
|
|
8183
8261
|
v && d.current.onCustomAction({
|
|
8184
8262
|
type: "questionStart",
|
|
8185
8263
|
moduleIndex: l.current.currentModuleIndex,
|
|
@@ -8189,29 +8267,29 @@ const xt = Fe(({
|
|
|
8189
8267
|
question: v,
|
|
8190
8268
|
score: l.current.score
|
|
8191
8269
|
});
|
|
8192
|
-
const
|
|
8193
|
-
if (!
|
|
8194
|
-
|
|
8195
|
-
const
|
|
8196
|
-
v.type === "code_test" ?
|
|
8197
|
-
lipsyncLang:
|
|
8198
|
-
}) :
|
|
8199
|
-
lipsyncLang:
|
|
8270
|
+
const A = () => {
|
|
8271
|
+
if (!c.current || !v) return;
|
|
8272
|
+
c.current.setMood("happy"), c.current.setBodyMovement("idle");
|
|
8273
|
+
const F = T.current || { lipsyncLang: "en" };
|
|
8274
|
+
v.type === "code_test" ? c.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8275
|
+
lipsyncLang: F.lipsyncLang
|
|
8276
|
+
}) : c.current.speakText(`Going back to: ${v.question}`, {
|
|
8277
|
+
lipsyncLang: F.lipsyncLang
|
|
8200
8278
|
});
|
|
8201
8279
|
};
|
|
8202
|
-
if (
|
|
8203
|
-
|
|
8280
|
+
if (c.current && c.current.isReady && v)
|
|
8281
|
+
A();
|
|
8204
8282
|
else if (v) {
|
|
8205
|
-
const
|
|
8206
|
-
|
|
8283
|
+
const F = setInterval(() => {
|
|
8284
|
+
c.current && c.current.isReady && (clearInterval(F), A());
|
|
8207
8285
|
}, 100);
|
|
8208
8286
|
setTimeout(() => {
|
|
8209
|
-
clearInterval(
|
|
8287
|
+
clearInterval(F);
|
|
8210
8288
|
}, 5e3);
|
|
8211
8289
|
}
|
|
8212
8290
|
}
|
|
8213
|
-
}, [
|
|
8214
|
-
const v =
|
|
8291
|
+
}, [N]), xe = G(() => {
|
|
8292
|
+
const v = D.current || { modules: [] };
|
|
8215
8293
|
if (v.modules[l.current.currentModuleIndex], l.current.currentLessonIndex > 0)
|
|
8216
8294
|
l.current.currentLessonIndex -= 1, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8217
8295
|
type: "lessonStart",
|
|
@@ -8220,98 +8298,98 @@ const xt = Fe(({
|
|
|
8220
8298
|
}), d.current.onLessonStart({
|
|
8221
8299
|
moduleIndex: l.current.currentModuleIndex,
|
|
8222
8300
|
lessonIndex: l.current.currentLessonIndex,
|
|
8223
|
-
lesson:
|
|
8224
|
-
}),
|
|
8301
|
+
lesson: I()
|
|
8302
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8225
8303
|
else if (l.current.currentModuleIndex > 0) {
|
|
8226
|
-
const
|
|
8227
|
-
l.current.currentModuleIndex -= 1, l.current.currentLessonIndex = (
|
|
8304
|
+
const U = v.modules[l.current.currentModuleIndex - 1];
|
|
8305
|
+
l.current.currentModuleIndex -= 1, l.current.currentLessonIndex = (U?.lessons?.length || 1) - 1, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8228
8306
|
type: "lessonStart",
|
|
8229
8307
|
moduleIndex: l.current.currentModuleIndex,
|
|
8230
8308
|
lessonIndex: l.current.currentLessonIndex
|
|
8231
8309
|
}), d.current.onLessonStart({
|
|
8232
8310
|
moduleIndex: l.current.currentModuleIndex,
|
|
8233
8311
|
lessonIndex: l.current.currentLessonIndex,
|
|
8234
|
-
lesson:
|
|
8235
|
-
}),
|
|
8312
|
+
lesson: I()
|
|
8313
|
+
}), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
|
|
8236
8314
|
}
|
|
8237
|
-
}, [
|
|
8315
|
+
}, [I]), se = G(() => {
|
|
8238
8316
|
l.current.currentModuleIndex = 0, l.current.currentLessonIndex = 0, l.current.currentQuestionIndex = 0, l.current.isTeaching = !1, l.current.isQuestionMode = !1, l.current.lessonCompleted = !1, l.current.curriculumCompleted = !1, l.current.score = 0, l.current.totalQuestions = 0;
|
|
8239
|
-
}, []), Ie =
|
|
8317
|
+
}, []), Ie = G((v) => {
|
|
8240
8318
|
console.log("Avatar is ready!", v);
|
|
8241
|
-
const
|
|
8242
|
-
|
|
8319
|
+
const A = I(), F = A?.avatar_script || A?.body;
|
|
8320
|
+
u && F && setTimeout(() => {
|
|
8243
8321
|
h.current && h.current();
|
|
8244
8322
|
}, 10);
|
|
8245
|
-
}, [
|
|
8246
|
-
|
|
8247
|
-
h.current =
|
|
8248
|
-
}),
|
|
8323
|
+
}, [u, I]);
|
|
8324
|
+
Ke(() => {
|
|
8325
|
+
h.current = E, p.current = O, b.current = R, f.current = M, S.current = z, B.current = y, g.current = j;
|
|
8326
|
+
}), Oe(a, () => ({
|
|
8249
8327
|
// Curriculum control methods
|
|
8250
|
-
startTeaching:
|
|
8328
|
+
startTeaching: E,
|
|
8251
8329
|
startQuestions: y,
|
|
8252
|
-
handleAnswerSelect:
|
|
8330
|
+
handleAnswerSelect: j,
|
|
8253
8331
|
handleCodeTestResult: ae,
|
|
8254
8332
|
nextQuestion: M,
|
|
8255
|
-
previousQuestion:
|
|
8256
|
-
nextLesson:
|
|
8257
|
-
previousLesson:
|
|
8333
|
+
previousQuestion: ce,
|
|
8334
|
+
nextLesson: O,
|
|
8335
|
+
previousLesson: xe,
|
|
8258
8336
|
completeLesson: R,
|
|
8259
|
-
completeCurriculum:
|
|
8260
|
-
resetCurriculum:
|
|
8337
|
+
completeCurriculum: z,
|
|
8338
|
+
resetCurriculum: se,
|
|
8261
8339
|
getState: () => ({ ...l.current }),
|
|
8262
|
-
getCurrentQuestion: () =>
|
|
8263
|
-
getCurrentLesson: () =>
|
|
8340
|
+
getCurrentQuestion: () => N(),
|
|
8341
|
+
getCurrentLesson: () => I(),
|
|
8264
8342
|
// Direct access to avatar ref (always returns current value)
|
|
8265
|
-
getAvatarRef: () =>
|
|
8343
|
+
getAvatarRef: () => c.current,
|
|
8266
8344
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8267
|
-
speakText: async (v,
|
|
8268
|
-
await
|
|
8269
|
-
const
|
|
8270
|
-
|
|
8345
|
+
speakText: async (v, A = {}) => {
|
|
8346
|
+
await c.current?.resumeAudioContext?.();
|
|
8347
|
+
const F = T.current || { lipsyncLang: "en" };
|
|
8348
|
+
c.current?.speakText(v, { ...A, lipsyncLang: A.lipsyncLang || F.lipsyncLang });
|
|
8271
8349
|
},
|
|
8272
8350
|
resumeAudioContext: async () => {
|
|
8273
|
-
if (
|
|
8274
|
-
return await
|
|
8275
|
-
const v =
|
|
8351
|
+
if (c.current?.resumeAudioContext)
|
|
8352
|
+
return await c.current.resumeAudioContext();
|
|
8353
|
+
const v = c.current?.talkingHead;
|
|
8276
8354
|
if (v?.audioCtx) {
|
|
8277
|
-
const
|
|
8278
|
-
if (
|
|
8355
|
+
const A = v.audioCtx;
|
|
8356
|
+
if (A.state === "suspended" || A.state === "interrupted")
|
|
8279
8357
|
try {
|
|
8280
|
-
await
|
|
8281
|
-
} catch (
|
|
8282
|
-
console.warn("Failed to resume audio context:",
|
|
8358
|
+
await A.resume(), console.log("Audio context resumed via talkingHead");
|
|
8359
|
+
} catch (F) {
|
|
8360
|
+
console.warn("Failed to resume audio context:", F);
|
|
8283
8361
|
}
|
|
8284
8362
|
} else
|
|
8285
8363
|
console.warn("Audio context not available yet");
|
|
8286
8364
|
},
|
|
8287
|
-
stopSpeaking: () =>
|
|
8288
|
-
pauseSpeaking: () =>
|
|
8289
|
-
resumeSpeaking: async () => await
|
|
8290
|
-
isPaused: () =>
|
|
8291
|
-
setMood: (v) =>
|
|
8292
|
-
playAnimation: (v,
|
|
8293
|
-
setBodyMovement: (v) =>
|
|
8294
|
-
setMovementIntensity: (v) =>
|
|
8295
|
-
playRandomDance: () =>
|
|
8296
|
-
playReaction: (v) =>
|
|
8297
|
-
playCelebration: () =>
|
|
8298
|
-
setShowFullAvatar: (v) =>
|
|
8299
|
-
setTimingAdjustment: (v) =>
|
|
8300
|
-
lockAvatarPosition: () =>
|
|
8301
|
-
unlockAvatarPosition: () =>
|
|
8365
|
+
stopSpeaking: () => c.current?.stopSpeaking(),
|
|
8366
|
+
pauseSpeaking: () => c.current?.pauseSpeaking(),
|
|
8367
|
+
resumeSpeaking: async () => await c.current?.resumeSpeaking(),
|
|
8368
|
+
isPaused: () => c.current && typeof c.current.isPaused < "u" ? c.current.isPaused : !1,
|
|
8369
|
+
setMood: (v) => c.current?.setMood(v),
|
|
8370
|
+
playAnimation: (v, A) => c.current?.playAnimation(v, A),
|
|
8371
|
+
setBodyMovement: (v) => c.current?.setBodyMovement(v),
|
|
8372
|
+
setMovementIntensity: (v) => c.current?.setMovementIntensity(v),
|
|
8373
|
+
playRandomDance: () => c.current?.playRandomDance(),
|
|
8374
|
+
playReaction: (v) => c.current?.playReaction(v),
|
|
8375
|
+
playCelebration: () => c.current?.playCelebration(),
|
|
8376
|
+
setShowFullAvatar: (v) => c.current?.setShowFullAvatar(v),
|
|
8377
|
+
setTimingAdjustment: (v) => c.current?.setTimingAdjustment(v),
|
|
8378
|
+
lockAvatarPosition: () => c.current?.lockAvatarPosition(),
|
|
8379
|
+
unlockAvatarPosition: () => c.current?.unlockAvatarPosition(),
|
|
8302
8380
|
// Custom action trigger
|
|
8303
|
-
triggerCustomAction: (v,
|
|
8381
|
+
triggerCustomAction: (v, A) => {
|
|
8304
8382
|
d.current.onCustomAction({
|
|
8305
8383
|
type: v,
|
|
8306
|
-
...
|
|
8384
|
+
...A,
|
|
8307
8385
|
state: { ...l.current }
|
|
8308
8386
|
});
|
|
8309
8387
|
},
|
|
8310
8388
|
// Responsive resize handler
|
|
8311
|
-
handleResize: () =>
|
|
8389
|
+
handleResize: () => c.current?.handleResize(),
|
|
8312
8390
|
// Avatar readiness check (always returns current value)
|
|
8313
|
-
isAvatarReady: () =>
|
|
8314
|
-
}), [
|
|
8391
|
+
isAvatarReady: () => c.current?.isReady || !1
|
|
8392
|
+
}), [E, y, j, ae, M, O, R, z, se, N, I]);
|
|
8315
8393
|
const ee = T.current || {
|
|
8316
8394
|
avatarUrl: "/avatars/brunette.glb",
|
|
8317
8395
|
avatarBody: "F",
|
|
@@ -8325,10 +8403,10 @@ const xt = Fe(({
|
|
|
8325
8403
|
showFullAvatar: !1,
|
|
8326
8404
|
animations: e
|
|
8327
8405
|
};
|
|
8328
|
-
return /* @__PURE__ */
|
|
8329
|
-
|
|
8406
|
+
return /* @__PURE__ */ J("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ J(
|
|
8407
|
+
Ye,
|
|
8330
8408
|
{
|
|
8331
|
-
ref:
|
|
8409
|
+
ref: c,
|
|
8332
8410
|
avatarUrl: ee.avatarUrl,
|
|
8333
8411
|
avatarBody: ee.avatarBody,
|
|
8334
8412
|
mood: ee.mood,
|
|
@@ -8350,8 +8428,8 @@ const xt = Fe(({
|
|
|
8350
8428
|
}
|
|
8351
8429
|
) });
|
|
8352
8430
|
});
|
|
8353
|
-
|
|
8354
|
-
function
|
|
8431
|
+
It.displayName = "CurriculumLearning";
|
|
8432
|
+
function Ft({
|
|
8355
8433
|
manifestPath: Z = "/animations/manifest.json",
|
|
8356
8434
|
avatarBody: t = "F",
|
|
8357
8435
|
onAnimationPlay: e = null,
|
|
@@ -8359,100 +8437,100 @@ function Ct({
|
|
|
8359
8437
|
onDeleteAnimations: i = null,
|
|
8360
8438
|
style: s = {}
|
|
8361
8439
|
}) {
|
|
8362
|
-
const [o, r] = le([]), [
|
|
8363
|
-
|
|
8440
|
+
const [o, r] = le([]), [u, a] = le(/* @__PURE__ */ new Set()), [c, l] = le(!0), [d, h] = le(null), [p, b] = le("all"), [f, S] = le("");
|
|
8441
|
+
ge(() => {
|
|
8364
8442
|
(async () => {
|
|
8365
8443
|
l(!0), h(null);
|
|
8366
8444
|
try {
|
|
8367
|
-
const
|
|
8368
|
-
if (
|
|
8369
|
-
const
|
|
8370
|
-
|
|
8371
|
-
(Array.isArray(
|
|
8445
|
+
const z = await Qe(Z), y = [];
|
|
8446
|
+
if (z._genderSpecific) {
|
|
8447
|
+
const O = (t?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
8448
|
+
z._genderSpecific[O] && Object.entries(z._genderSpecific[O]).forEach(([E, j]) => {
|
|
8449
|
+
(Array.isArray(j) ? j : [j]).forEach((ce) => {
|
|
8372
8450
|
y.push({
|
|
8373
|
-
path:
|
|
8374
|
-
group:
|
|
8375
|
-
gender:
|
|
8376
|
-
name:
|
|
8451
|
+
path: ce,
|
|
8452
|
+
group: E,
|
|
8453
|
+
gender: O,
|
|
8454
|
+
name: ce.split("/").pop().replace(".fbx", "")
|
|
8377
8455
|
});
|
|
8378
8456
|
});
|
|
8379
|
-
}),
|
|
8380
|
-
(Array.isArray(
|
|
8457
|
+
}), z._genderSpecific.shared && Object.entries(z._genderSpecific.shared).forEach(([E, j]) => {
|
|
8458
|
+
(Array.isArray(j) ? j : [j]).forEach((ce) => {
|
|
8381
8459
|
y.push({
|
|
8382
|
-
path:
|
|
8383
|
-
group:
|
|
8460
|
+
path: ce,
|
|
8461
|
+
group: E,
|
|
8384
8462
|
gender: "shared",
|
|
8385
|
-
name:
|
|
8463
|
+
name: ce.split("/").pop().replace(".fbx", "")
|
|
8386
8464
|
});
|
|
8387
8465
|
});
|
|
8388
8466
|
});
|
|
8389
8467
|
}
|
|
8390
|
-
Object.entries(
|
|
8391
|
-
M !== "_genderSpecific" && (Array.isArray(
|
|
8392
|
-
typeof
|
|
8393
|
-
path:
|
|
8468
|
+
Object.entries(z).forEach(([M, O]) => {
|
|
8469
|
+
M !== "_genderSpecific" && (Array.isArray(O) ? O : [O]).forEach((j) => {
|
|
8470
|
+
typeof j == "string" && y.push({
|
|
8471
|
+
path: j,
|
|
8394
8472
|
group: M,
|
|
8395
8473
|
gender: "root",
|
|
8396
|
-
name:
|
|
8474
|
+
name: j.split("/").pop().replace(".fbx", "")
|
|
8397
8475
|
});
|
|
8398
8476
|
});
|
|
8399
8477
|
}), r(y), l(!1);
|
|
8400
|
-
} catch (
|
|
8401
|
-
console.error("Failed to load animations:",
|
|
8478
|
+
} catch (z) {
|
|
8479
|
+
console.error("Failed to load animations:", z), h(z.message), l(!1);
|
|
8402
8480
|
}
|
|
8403
8481
|
})();
|
|
8404
8482
|
}, [Z, t]);
|
|
8405
|
-
const
|
|
8406
|
-
const
|
|
8407
|
-
return
|
|
8408
|
-
}),
|
|
8409
|
-
const
|
|
8410
|
-
|
|
8483
|
+
const B = ["all", ...new Set(o.map((R) => R.group))], g = o.filter((R) => {
|
|
8484
|
+
const z = p === "all" || R.group === p, y = f === "" || R.name.toLowerCase().includes(f.toLowerCase()) || R.path.toLowerCase().includes(f.toLowerCase());
|
|
8485
|
+
return z && y;
|
|
8486
|
+
}), D = (R) => {
|
|
8487
|
+
const z = new Set(u);
|
|
8488
|
+
z.has(R) ? z.delete(R) : z.add(R), a(z), n && n(Array.from(z));
|
|
8411
8489
|
}, T = () => {
|
|
8412
|
-
const R = new Set(
|
|
8413
|
-
g.forEach((
|
|
8414
|
-
R.add(
|
|
8490
|
+
const R = new Set(u);
|
|
8491
|
+
g.forEach((z) => {
|
|
8492
|
+
R.add(z.path);
|
|
8415
8493
|
}), a(R), n && n(Array.from(R));
|
|
8416
|
-
},
|
|
8417
|
-
const R = new Set(
|
|
8418
|
-
g.forEach((
|
|
8419
|
-
R.delete(
|
|
8494
|
+
}, I = () => {
|
|
8495
|
+
const R = new Set(u);
|
|
8496
|
+
g.forEach((z) => {
|
|
8497
|
+
R.delete(z.path);
|
|
8420
8498
|
}), a(R), n && n(Array.from(R));
|
|
8421
|
-
},
|
|
8422
|
-
const
|
|
8423
|
-
if (
|
|
8499
|
+
}, N = () => {
|
|
8500
|
+
const z = o.filter((y) => !u.has(y.path)).map((y) => y.path);
|
|
8501
|
+
if (z.length === 0) {
|
|
8424
8502
|
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8425
8503
|
return;
|
|
8426
8504
|
}
|
|
8427
|
-
window.confirm(`Are you sure you want to delete ${
|
|
8505
|
+
window.confirm(`Are you sure you want to delete ${z.length} animation(s)?
|
|
8428
8506
|
|
|
8429
8507
|
This will delete:
|
|
8430
|
-
${
|
|
8431
|
-
`)}${
|
|
8432
|
-
...` : ""}`) && (i && i(
|
|
8508
|
+
${z.slice(0, 5).join(`
|
|
8509
|
+
`)}${z.length > 5 ? `
|
|
8510
|
+
...` : ""}`) && (i && i(z), r(o.filter((y) => u.has(y.path))), a(/* @__PURE__ */ new Set()));
|
|
8433
8511
|
}, L = (R) => {
|
|
8434
8512
|
e && e(R);
|
|
8435
8513
|
};
|
|
8436
|
-
return
|
|
8514
|
+
return c ? /* @__PURE__ */ J("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ J("p", { children: "Loading animations..." }) }) : d ? /* @__PURE__ */ J("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ ve("p", { children: [
|
|
8437
8515
|
"Error loading animations: ",
|
|
8438
8516
|
d
|
|
8439
|
-
] }) }) : /* @__PURE__ */
|
|
8517
|
+
] }) }) : /* @__PURE__ */ ve("div", { style: {
|
|
8440
8518
|
padding: "20px",
|
|
8441
8519
|
backgroundColor: "#2a2a2a",
|
|
8442
8520
|
borderRadius: "8px",
|
|
8443
8521
|
color: "#fff",
|
|
8444
8522
|
...s
|
|
8445
8523
|
}, children: [
|
|
8446
|
-
/* @__PURE__ */
|
|
8447
|
-
/* @__PURE__ */
|
|
8448
|
-
/* @__PURE__ */
|
|
8524
|
+
/* @__PURE__ */ J("h2", { style: { marginTop: 0 }, children: "Animation Selector" }),
|
|
8525
|
+
/* @__PURE__ */ J("p", { style: { color: "#aaa", fontSize: "14px" }, children: "Click buttons to play animations. Select animations to keep, then delete will remove the rest." }),
|
|
8526
|
+
/* @__PURE__ */ ve("div", { style: {
|
|
8449
8527
|
display: "flex",
|
|
8450
8528
|
gap: "10px",
|
|
8451
8529
|
marginBottom: "20px",
|
|
8452
8530
|
flexWrap: "wrap",
|
|
8453
8531
|
alignItems: "center"
|
|
8454
8532
|
}, children: [
|
|
8455
|
-
/* @__PURE__ */
|
|
8533
|
+
/* @__PURE__ */ J(
|
|
8456
8534
|
"input",
|
|
8457
8535
|
{
|
|
8458
8536
|
type: "text",
|
|
@@ -8471,7 +8549,7 @@ ${C.slice(0, 5).join(`
|
|
|
8471
8549
|
}
|
|
8472
8550
|
}
|
|
8473
8551
|
),
|
|
8474
|
-
/* @__PURE__ */
|
|
8552
|
+
/* @__PURE__ */ J(
|
|
8475
8553
|
"select",
|
|
8476
8554
|
{
|
|
8477
8555
|
value: p,
|
|
@@ -8484,10 +8562,10 @@ ${C.slice(0, 5).join(`
|
|
|
8484
8562
|
color: "#fff",
|
|
8485
8563
|
fontSize: "14px"
|
|
8486
8564
|
},
|
|
8487
|
-
children:
|
|
8565
|
+
children: B.map((R) => /* @__PURE__ */ J("option", { value: R, children: R === "all" ? "All Groups" : R }, R))
|
|
8488
8566
|
}
|
|
8489
8567
|
),
|
|
8490
|
-
/* @__PURE__ */
|
|
8568
|
+
/* @__PURE__ */ J(
|
|
8491
8569
|
"button",
|
|
8492
8570
|
{
|
|
8493
8571
|
onClick: T,
|
|
@@ -8503,10 +8581,10 @@ ${C.slice(0, 5).join(`
|
|
|
8503
8581
|
children: "Select All Visible"
|
|
8504
8582
|
}
|
|
8505
8583
|
),
|
|
8506
|
-
/* @__PURE__ */
|
|
8584
|
+
/* @__PURE__ */ J(
|
|
8507
8585
|
"button",
|
|
8508
8586
|
{
|
|
8509
|
-
onClick:
|
|
8587
|
+
onClick: I,
|
|
8510
8588
|
style: {
|
|
8511
8589
|
padding: "8px 16px",
|
|
8512
8590
|
backgroundColor: "#666",
|
|
@@ -8519,10 +8597,10 @@ ${C.slice(0, 5).join(`
|
|
|
8519
8597
|
children: "Deselect All Visible"
|
|
8520
8598
|
}
|
|
8521
8599
|
),
|
|
8522
|
-
/* @__PURE__ */
|
|
8600
|
+
/* @__PURE__ */ ve(
|
|
8523
8601
|
"button",
|
|
8524
8602
|
{
|
|
8525
|
-
onClick:
|
|
8603
|
+
onClick: N,
|
|
8526
8604
|
style: {
|
|
8527
8605
|
padding: "8px 16px",
|
|
8528
8606
|
backgroundColor: "#f44336",
|
|
@@ -8535,13 +8613,13 @@ ${C.slice(0, 5).join(`
|
|
|
8535
8613
|
},
|
|
8536
8614
|
children: [
|
|
8537
8615
|
"Delete Unselected (",
|
|
8538
|
-
o.length -
|
|
8616
|
+
o.length - u.size,
|
|
8539
8617
|
")"
|
|
8540
8618
|
]
|
|
8541
8619
|
}
|
|
8542
8620
|
)
|
|
8543
8621
|
] }),
|
|
8544
|
-
/* @__PURE__ */
|
|
8622
|
+
/* @__PURE__ */ ve("div", { style: {
|
|
8545
8623
|
marginBottom: "15px",
|
|
8546
8624
|
fontSize: "14px",
|
|
8547
8625
|
color: "#aaa"
|
|
@@ -8549,11 +8627,11 @@ ${C.slice(0, 5).join(`
|
|
|
8549
8627
|
"Total: ",
|
|
8550
8628
|
o.length,
|
|
8551
8629
|
" | Selected: ",
|
|
8552
|
-
|
|
8630
|
+
u.size,
|
|
8553
8631
|
" | Showing: ",
|
|
8554
8632
|
g.length
|
|
8555
8633
|
] }),
|
|
8556
|
-
/* @__PURE__ */
|
|
8634
|
+
/* @__PURE__ */ J("div", { style: {
|
|
8557
8635
|
display: "grid",
|
|
8558
8636
|
gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
|
|
8559
8637
|
gap: "10px",
|
|
@@ -8562,9 +8640,9 @@ ${C.slice(0, 5).join(`
|
|
|
8562
8640
|
padding: "10px",
|
|
8563
8641
|
backgroundColor: "#1a1a1a",
|
|
8564
8642
|
borderRadius: "6px"
|
|
8565
|
-
}, children: g.map((R,
|
|
8566
|
-
const y =
|
|
8567
|
-
return /* @__PURE__ */
|
|
8643
|
+
}, children: g.map((R, z) => {
|
|
8644
|
+
const y = u.has(R.path);
|
|
8645
|
+
return /* @__PURE__ */ ve(
|
|
8568
8646
|
"div",
|
|
8569
8647
|
{
|
|
8570
8648
|
style: {
|
|
@@ -8575,15 +8653,15 @@ ${C.slice(0, 5).join(`
|
|
|
8575
8653
|
cursor: "pointer",
|
|
8576
8654
|
transition: "all 0.2s"
|
|
8577
8655
|
},
|
|
8578
|
-
onClick: () =>
|
|
8656
|
+
onClick: () => D(R.path),
|
|
8579
8657
|
children: [
|
|
8580
|
-
/* @__PURE__ */
|
|
8581
|
-
/* @__PURE__ */
|
|
8658
|
+
/* @__PURE__ */ ve("div", { style: { marginBottom: "8px" }, children: [
|
|
8659
|
+
/* @__PURE__ */ J(
|
|
8582
8660
|
"input",
|
|
8583
8661
|
{
|
|
8584
8662
|
type: "checkbox",
|
|
8585
8663
|
checked: y,
|
|
8586
|
-
onChange: () =>
|
|
8664
|
+
onChange: () => D(R.path),
|
|
8587
8665
|
onClick: (M) => M.stopPropagation(),
|
|
8588
8666
|
style: {
|
|
8589
8667
|
marginRight: "8px",
|
|
@@ -8591,19 +8669,19 @@ ${C.slice(0, 5).join(`
|
|
|
8591
8669
|
}
|
|
8592
8670
|
}
|
|
8593
8671
|
),
|
|
8594
|
-
/* @__PURE__ */
|
|
8672
|
+
/* @__PURE__ */ ve("span", { style: { fontSize: "12px", color: "#aaa" }, children: [
|
|
8595
8673
|
R.group,
|
|
8596
8674
|
" ",
|
|
8597
8675
|
R.gender !== "root" && `(${R.gender})`
|
|
8598
8676
|
] })
|
|
8599
8677
|
] }),
|
|
8600
|
-
/* @__PURE__ */
|
|
8678
|
+
/* @__PURE__ */ J("div", { style: {
|
|
8601
8679
|
fontSize: "13px",
|
|
8602
8680
|
fontWeight: "bold",
|
|
8603
8681
|
marginBottom: "8px",
|
|
8604
8682
|
wordBreak: "break-word"
|
|
8605
8683
|
}, children: R.name }),
|
|
8606
|
-
/* @__PURE__ */
|
|
8684
|
+
/* @__PURE__ */ J(
|
|
8607
8685
|
"button",
|
|
8608
8686
|
{
|
|
8609
8687
|
onClick: (M) => {
|
|
@@ -8624,17 +8702,17 @@ ${C.slice(0, 5).join(`
|
|
|
8624
8702
|
)
|
|
8625
8703
|
]
|
|
8626
8704
|
},
|
|
8627
|
-
`${R.path}-${
|
|
8705
|
+
`${R.path}-${z}`
|
|
8628
8706
|
);
|
|
8629
8707
|
}) }),
|
|
8630
|
-
g.length === 0 && /* @__PURE__ */
|
|
8708
|
+
g.length === 0 && /* @__PURE__ */ J("div", { style: {
|
|
8631
8709
|
padding: "40px",
|
|
8632
8710
|
textAlign: "center",
|
|
8633
8711
|
color: "#aaa"
|
|
8634
8712
|
}, children: "No animations found matching your filters." })
|
|
8635
8713
|
] });
|
|
8636
8714
|
}
|
|
8637
|
-
const
|
|
8715
|
+
const qe = {
|
|
8638
8716
|
// Code-based dance animations (no FBX required)
|
|
8639
8717
|
dance: {
|
|
8640
8718
|
name: "dance",
|
|
@@ -8737,16 +8815,16 @@ const Xe = {
|
|
|
8737
8815
|
duration: 5e3,
|
|
8738
8816
|
description: "Excited, energetic movement"
|
|
8739
8817
|
}
|
|
8740
|
-
},
|
|
8818
|
+
}, Et = (Z) => qe[Z] || null, Pt = (Z) => qe.hasOwnProperty(Z);
|
|
8741
8819
|
export {
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8820
|
+
Ft as AnimationSelector,
|
|
8821
|
+
It as CurriculumLearning,
|
|
8822
|
+
At as SimpleTalkingAvatar,
|
|
8823
|
+
Ye as TalkingHeadAvatar,
|
|
8824
|
+
vt as TalkingHeadComponent,
|
|
8825
|
+
qe as animations,
|
|
8826
|
+
De as getActiveTTSConfig,
|
|
8827
|
+
Et as getAnimation,
|
|
8828
|
+
Mt as getVoiceOptions,
|
|
8829
|
+
Pt as hasAnimation
|
|
8752
8830
|
};
|