@sage-rsc/talking-head-react 1.1.5 → 1.1.7
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/README.md +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.js +1039 -1253
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +0 -408
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as Me, useRef as
|
|
3
|
-
import * as
|
|
2
|
+
import { forwardRef as Me, useRef as D, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
|
|
3
|
+
import * as x from "three";
|
|
4
4
|
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
-
import { FBXLoader as
|
|
7
|
+
import { FBXLoader as Oe } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
-
import
|
|
10
|
-
let m, re,
|
|
11
|
-
const A = [0, 0, 0, 0],
|
|
12
|
-
new
|
|
13
|
-
new
|
|
14
|
-
new
|
|
15
|
-
const
|
|
16
|
-
new
|
|
17
|
-
const He = new
|
|
9
|
+
import Ke from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, re, ue;
|
|
11
|
+
const A = [0, 0, 0, 0], w = new x.Vector3(), ze = new x.Vector3(), ne = new x.Vector3(), Ce = new x.Vector3();
|
|
12
|
+
new x.Plane();
|
|
13
|
+
new x.Ray();
|
|
14
|
+
new x.Euler();
|
|
15
|
+
const ie = new x.Quaternion(), Ne = new x.Quaternion(), fe = new x.Matrix4(), xe = new x.Matrix4();
|
|
16
|
+
new x.Vector3();
|
|
17
|
+
const He = new x.Vector3(0, 0, 1), _e = new x.Vector3(1, 0, 0), Je = new x.Vector3(0, 1, 0), $e = new x.Vector3(0, 0, 1);
|
|
18
18
|
class et {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
@@ -192,7 +192,7 @@ class et {
|
|
|
192
192
|
const l = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!l) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const h = {
|
|
196
196
|
bone: l,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class et {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((r) => Number.isNaN(r))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
|
|
206
|
-
|
|
206
|
+
h.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
i.excludes.push(
|
|
208
|
+
i.excludes.push(h);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class et {
|
|
|
282
282
|
m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const n = /* @__PURE__ */ new WeakSet(), i = (o) => o.parent?.isBone ? [o, ...i(o.parent)] : [o], s = (o) => {
|
|
285
|
-
i(o).forEach((
|
|
286
|
-
n.has(
|
|
285
|
+
i(o).forEach((h) => {
|
|
286
|
+
n.has(h) || (this.objectsUpdate.push(h), n.add(h));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((o) => {
|
|
@@ -308,12 +308,12 @@ class et {
|
|
|
308
308
|
i(t?.isScene, "First parameter must be Scene."), this.scene = t, i(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, i(Array.isArray(n), "Third parameter must be an array of bone configs."), this.config = n, this.config.forEach((s, o) => {
|
|
309
309
|
const l = "Config item #" + o + ": ";
|
|
310
310
|
i(s.bone, l + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
i(typeof
|
|
313
|
-
const r = this.armature.getObjectByName(
|
|
314
|
-
i(r, l + "Bone '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const h = s.bone;
|
|
312
|
+
i(typeof h == "string" && h.length > 0, l + "Bone name must be a non-empty string.");
|
|
313
|
+
const r = this.armature.getObjectByName(h);
|
|
314
|
+
i(r, l + "Bone '" + h + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + h + "' already exists."), r.updateMatrixWorld(!0);
|
|
315
|
+
const u = {
|
|
316
|
+
name: h,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: r,
|
|
319
319
|
// Bone object
|
|
@@ -321,7 +321,7 @@ class et {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: r.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: r.parent.getWorldPosition(
|
|
324
|
+
vWorld: r.parent.getWorldPosition(w).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: r.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,9 +338,9 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
|
|
344
344
|
} catch (a) {
|
|
345
345
|
i(!1, l + a);
|
|
346
346
|
}
|
|
@@ -356,22 +356,22 @@ class et {
|
|
|
356
356
|
for (this.timerMs += t, t > 1e3 && (this.timerMs = 0), t /= 1e3, e = 0, i = this.objectsUpdate.length; e < i; e++)
|
|
357
357
|
o = this.objectsUpdate[e], o.updateMatrix(), o.parent === null ? o.matrixWorld.copy(o.matrix) : o.matrixWorld.multiplyMatrices(o.parent.matrixWorld, o.matrix), o.matrixWorldNeedsUpdate = !1;
|
|
358
358
|
for (e = 0, i = this.data.length; e < i; e++) {
|
|
359
|
-
if (o = this.data[e],
|
|
359
|
+
if (o = this.data[e], w.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), w.applyMatrix4(xe), w.length() > 0.5 && (console.info("Info: Unrealistic jump of " + w.length().toFixed(2) + " meters."), w.setLength(0.5)), w.applyQuaternion(o.bone.quaternion), A[0] = w.x, A[1] = w.y, A[2] = -w.z, A[3] = w.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
361
|
m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
|
|
362
|
-
if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[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 + A[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 = A[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 + A[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 = A[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 + A[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 = A[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 + A[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), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw,
|
|
362
|
+
if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[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 + A[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 = A[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 + A[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 = A[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 + A[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 = A[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 + A[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), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, w.set(
|
|
363
363
|
o.vBasis.x + A[0],
|
|
364
364
|
o.vBasis.y + A[1],
|
|
365
365
|
o.vBasis.z + A[2]
|
|
366
|
-
),
|
|
366
|
+
), w.applyMatrix4(fe), w.x += m[0], w.y += m[1], w.z += m[2], w.applyMatrix4(xe), A[0] += w.x - o.vBasis.x, A[1] += w.y - o.vBasis.y, A[2] += w.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + A[0],
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), 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], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (ue = w.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(w), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -393,7 +393,7 @@ class et {
|
|
|
393
393
|
i || (m.excludes.bones.push(n.bone), m.excludes.radii.push(n.radius), m.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), m.excludes.objects.push(null));
|
|
394
394
|
}));
|
|
395
395
|
}), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, n) => {
|
|
396
|
-
const i = new
|
|
396
|
+
const i = new x.SphereGeometry(m.radii[n], 6, 6), s = new x.MeshBasicMaterial({
|
|
397
397
|
depthTest: !1,
|
|
398
398
|
depthWrite: !1,
|
|
399
399
|
toneMapped: !1,
|
|
@@ -401,18 +401,18 @@ class et {
|
|
|
401
401
|
wireframe: !0,
|
|
402
402
|
color: this.opt.helperExcludesColor
|
|
403
403
|
});
|
|
404
|
-
m.objects[n] = new
|
|
404
|
+
m.objects[n] = new x.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
|
|
405
405
|
m.deltaLocals[n][0],
|
|
406
406
|
m.deltaLocals[n][1],
|
|
407
407
|
m.deltaLocals[n][2]
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new
|
|
412
|
-
e.setAttribute("position", new
|
|
413
|
-
const i = new
|
|
414
|
-
e.setAttribute("color", new
|
|
415
|
-
const l = new
|
|
411
|
+
const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
|
|
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((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
|
|
414
|
+
e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
|
|
415
|
+
const l = new x.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
417
417
|
depthWrite: !1,
|
|
418
418
|
toneMapped: !1,
|
|
@@ -420,21 +420,21 @@ class et {
|
|
|
420
420
|
size: 0.2,
|
|
421
421
|
vertexColors: !0
|
|
422
422
|
});
|
|
423
|
-
m.object = new
|
|
423
|
+
m.object = new x.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new
|
|
427
|
-
e.setAttribute("position", new
|
|
428
|
-
const i = new
|
|
429
|
-
e.setAttribute("color", new
|
|
430
|
-
const l = new
|
|
426
|
+
const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
|
|
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((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
|
|
429
|
+
e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
|
|
430
|
+
const l = new x.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
432
432
|
depthTest: !1,
|
|
433
433
|
depthWrite: !1,
|
|
434
434
|
toneMapped: !1,
|
|
435
435
|
transparent: !0
|
|
436
436
|
});
|
|
437
|
-
m.object = new
|
|
437
|
+
m.object = new x.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
/**
|
|
@@ -445,14 +445,14 @@ class et {
|
|
|
445
445
|
xe.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
|
-
fe.multiplyMatrices(xe, m.bones[e].matrixWorld),
|
|
448
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(e, w.x, w.y, w.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
452
|
xe.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
|
-
fe.multiplyMatrices(xe, m.bones[e].matrixWorld),
|
|
455
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n, w.x, w.y, w.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n + 1, w.x, w.y, w.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -519,13 +519,13 @@ class tt {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
|
|
521
521
|
for (let l = 0; l < o; l++) {
|
|
522
|
-
const
|
|
522
|
+
const h = l * s, r = Math.min(h + i, t.length), u = t.slice(h, r), a = this.calculateEnergy(u);
|
|
523
523
|
n.energy.push(a);
|
|
524
|
-
const
|
|
525
|
-
n.spectralCentroid.push(
|
|
526
|
-
const
|
|
527
|
-
n.zeroCrossingRate.push(
|
|
528
|
-
const g = this.calculateMFCC(
|
|
524
|
+
const d = this.calculateSpectralCentroid(u);
|
|
525
|
+
n.spectralCentroid.push(d);
|
|
526
|
+
const c = this.calculateZeroCrossingRate(u);
|
|
527
|
+
n.zeroCrossingRate.push(c);
|
|
528
|
+
const g = this.calculateMFCC(u);
|
|
529
529
|
n.mfcc.push(g);
|
|
530
530
|
}
|
|
531
531
|
return n.onsets = this.detectOnsets(n.energy), n.phonemeBoundaries = this.detectPhonemeBoundaries(n), n;
|
|
@@ -597,19 +597,19 @@ class tt {
|
|
|
597
597
|
for (; s & o; )
|
|
598
598
|
s ^= o, o >>= 1;
|
|
599
599
|
if (s ^= o, i < s) {
|
|
600
|
-
const l = n[i * 2],
|
|
601
|
-
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] =
|
|
600
|
+
const l = n[i * 2], h = n[i * 2 + 1];
|
|
601
|
+
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] = h;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let i = 2; i <= e; i <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / i, o = Math.cos(s), l = Math.sin(s);
|
|
606
|
-
for (let
|
|
607
|
-
let r = 1,
|
|
606
|
+
for (let h = 0; h < e; h += i) {
|
|
607
|
+
let r = 1, u = 0;
|
|
608
608
|
for (let a = 0; a < i / 2; a++) {
|
|
609
|
-
const
|
|
610
|
-
n[(
|
|
611
|
-
const
|
|
612
|
-
r =
|
|
609
|
+
const d = n[(h + a) * 2], c = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, y = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
|
|
610
|
+
n[(h + a) * 2] = d + g, n[(h + a) * 2 + 1] = c + y, n[(h + a + i / 2) * 2] = d - g, n[(h + a + i / 2) * 2 + 1] = c - y;
|
|
611
|
+
const b = r * o - u * l, R = r * l + u * o;
|
|
612
|
+
r = b, u = R;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class tt {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let o = 1; o < t.length; o++) {
|
|
627
|
-
const l = t[o] - t[o - 1],
|
|
628
|
-
l > 0.1 &&
|
|
627
|
+
const l = t[o] - t[o - 1], h = o * 0.023;
|
|
628
|
+
l > 0.1 && h - s > 0.1 && (e.push(h), s = h);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class tt {
|
|
|
637
637
|
detectPhonemeBoundaries(t) {
|
|
638
638
|
const e = [], { energy: n, spectralCentroid: i, zeroCrossingRate: s } = t;
|
|
639
639
|
for (let o = 1; o < n.length; o++) {
|
|
640
|
-
const l = o * 0.023,
|
|
641
|
-
|
|
640
|
+
const l = o * 0.023, h = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), u = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
h + r * 0.1 + u * 0.5 > 0.2 && e.push(l);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ class tt {
|
|
|
654
654
|
t.phonemeBoundaries, t.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let o = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const r = i[
|
|
657
|
+
for (let h = 0; h < i.length; h++) {
|
|
658
|
+
const r = i[h], u = this.estimateWordDuration(r, n / i.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: r,
|
|
661
661
|
startTime: o,
|
|
662
|
-
endTime: o +
|
|
663
|
-
duration:
|
|
664
|
-
}), o +=
|
|
662
|
+
endTime: o + u,
|
|
663
|
+
duration: u
|
|
664
|
+
}), o += u;
|
|
665
665
|
}
|
|
666
666
|
const l = this.generateVisemeTimings(t, e, n);
|
|
667
667
|
return {
|
|
@@ -701,27 +701,27 @@ class tt {
|
|
|
701
701
|
const i = [], s = t.phonemeBoundaries;
|
|
702
702
|
t.onsets;
|
|
703
703
|
const o = this.textToVisemes(e);
|
|
704
|
-
let l = 0,
|
|
704
|
+
let l = 0, h = 0;
|
|
705
705
|
for (let r = 0; r < s.length && l < o.length; r++) {
|
|
706
|
-
const
|
|
706
|
+
const u = s[r], a = o[l], d = t.energy[Math.floor(u / 0.023)] || 0, c = this.calculateVisemeDuration(a, d);
|
|
707
707
|
i.push({
|
|
708
708
|
viseme: a,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
711
|
-
duration:
|
|
712
|
-
intensity: Math.min(1,
|
|
709
|
+
startTime: h,
|
|
710
|
+
endTime: h + c,
|
|
711
|
+
duration: c,
|
|
712
|
+
intensity: Math.min(1, d * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), h += c, l++;
|
|
715
715
|
}
|
|
716
716
|
for (; l < o.length; ) {
|
|
717
|
-
const r = o[l],
|
|
717
|
+
const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
|
|
718
718
|
i.push({
|
|
719
719
|
viseme: r,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: h,
|
|
721
|
+
endTime: h + u,
|
|
722
|
+
duration: u,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), h += u, l++;
|
|
725
725
|
}
|
|
726
726
|
return i;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class tt {
|
|
|
775
775
|
let o = 0;
|
|
776
776
|
for (; o < s.length; ) {
|
|
777
777
|
let l = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const r = s.substr(o,
|
|
778
|
+
for (let h = 3; h >= 2; h--) {
|
|
779
|
+
const r = s.substr(o, h);
|
|
780
780
|
if (e[r]) {
|
|
781
|
-
n.push(e[r]), o +=
|
|
781
|
+
n.push(e[r]), o += h, l = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!l) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const h = s[o];
|
|
787
|
+
e[h] && n.push(e[h]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -1206,11 +1206,11 @@ class nt {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1209
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1210
|
-
let
|
|
1211
|
-
|
|
1212
|
-
const
|
|
1213
|
-
return
|
|
1209
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1210
|
+
let d = "";
|
|
1211
|
+
d += [...l].map((g) => t[g] || g).join("");
|
|
1212
|
+
const c = [...h];
|
|
1213
|
+
return c[0] = c[0].toLowerCase(), d += c.join(""), a.move = c.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
|
|
1214
1214
|
a.visemes.push(g);
|
|
1215
1215
|
}), a;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class nt {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(t) {
|
|
1326
1326
|
const e = parseInt(t), n = !isNaN(e) && t.length === 2, i = !isNaN(e) && t.length > 2 && e > 0 && e <= 3e3, s = i && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, o = i && !s ? Math.floor(e / 100) : null, l = n || i ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let h = [];
|
|
1328
|
+
return s ? h.push(this.convertNumberToWords(s).trim(), "thousands") : (o && h.push(this.convertNumberToWords(o).trim()), l ? h.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? h.push("hundreds") : h.push(t)), h.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,17 +1376,17 @@ class nt {
|
|
|
1376
1376
|
const s = i[e.i], o = this.rules[s];
|
|
1377
1377
|
if (o)
|
|
1378
1378
|
for (let l = 0; l < o.length; l++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const h = o[l];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(h.regex)) {
|
|
1381
|
+
h.visemes.forEach((a) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
1383
|
-
const
|
|
1384
|
-
e.durations[e.durations.length - 1] +=
|
|
1383
|
+
const d = 0.7 * (this.visemeDurations[a] || 1);
|
|
1384
|
+
e.durations[e.durations.length - 1] += d, n += d;
|
|
1385
1385
|
} else {
|
|
1386
|
-
const
|
|
1387
|
-
e.visemes.push(a), e.times.push(n), e.durations.push(
|
|
1386
|
+
const d = this.visemeDurations[a] || 1;
|
|
1387
|
+
e.visemes.push(a), e.times.push(n), e.durations.push(d), n += d;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += h.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1616,11 +1616,11 @@ class ot {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1619
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1620
|
-
let
|
|
1621
|
-
|
|
1622
|
-
const
|
|
1623
|
-
return
|
|
1619
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1620
|
+
let d = "";
|
|
1621
|
+
d += [...l].map((g) => t[g] || g).join("");
|
|
1622
|
+
const c = [...h];
|
|
1623
|
+
return c[0] = c[0].toLowerCase(), d += c.join(""), a.move = c.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
|
|
1624
1624
|
a.visemes.push(g);
|
|
1625
1625
|
}), a;
|
|
1626
1626
|
});
|
|
@@ -1732,16 +1732,16 @@ class ot {
|
|
|
1732
1732
|
const s = i[e.i], o = this.rules[s];
|
|
1733
1733
|
if (o) {
|
|
1734
1734
|
let l = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const r = o[
|
|
1735
|
+
for (let h = 0; h < o.length; h++) {
|
|
1736
|
+
const r = o[h];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
1738
|
-
r.visemes.forEach((
|
|
1739
|
-
if (e.visemes.length && e.visemes[e.visemes.length - 1] ===
|
|
1740
|
-
const
|
|
1741
|
-
e.durations[e.durations.length - 1] +=
|
|
1738
|
+
r.visemes.forEach((d) => {
|
|
1739
|
+
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
1740
|
+
const c = 0.7 * (this.visemeDurations[d] || 1);
|
|
1741
|
+
e.durations[e.durations.length - 1] += c, n += c;
|
|
1742
1742
|
} else {
|
|
1743
|
-
const
|
|
1744
|
-
e.visemes.push(
|
|
1743
|
+
const c = this.visemeDurations[d] || 1;
|
|
1744
|
+
e.visemes.push(d), e.times.push(n), e.durations.push(c), n += c;
|
|
1745
1745
|
}
|
|
1746
1746
|
}), e.i += r.move, l = !0;
|
|
1747
1747
|
break;
|
|
@@ -2131,11 +2131,11 @@ class at {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((n) => {
|
|
2134
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
2135
|
-
let
|
|
2136
|
-
|
|
2137
|
-
const
|
|
2138
|
-
return
|
|
2134
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
2135
|
+
let d = "";
|
|
2136
|
+
d += [...l].map((g) => t[g] || g).join("");
|
|
2137
|
+
const c = [...h];
|
|
2138
|
+
return c[0] = c[0].toLowerCase(), d += c.join(""), a.move = c.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d, "i"), u.length && u.split(" ").forEach((g) => {
|
|
2139
2139
|
g && a.visemes.push(g);
|
|
2140
2140
|
}), a;
|
|
2141
2141
|
});
|
|
@@ -2267,16 +2267,16 @@ class at {
|
|
|
2267
2267
|
const s = i[e.i], o = this.rules[s];
|
|
2268
2268
|
if (o) {
|
|
2269
2269
|
let l = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const r = o[
|
|
2270
|
+
for (let h = 0; h < o.length; h++) {
|
|
2271
|
+
const r = o[h];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
2273
|
-
r.visemes.forEach((
|
|
2274
|
-
if (e.visemes.length && e.visemes[e.visemes.length - 1] ===
|
|
2275
|
-
const
|
|
2276
|
-
e.durations[e.durations.length - 1] +=
|
|
2273
|
+
r.visemes.forEach((d) => {
|
|
2274
|
+
if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
|
|
2275
|
+
const c = 0.7 * (this.visemeDurations[d] || 1);
|
|
2276
|
+
e.durations[e.durations.length - 1] += c, n += c;
|
|
2277
2277
|
} else {
|
|
2278
|
-
const
|
|
2279
|
-
e.visemes.push(
|
|
2278
|
+
const c = this.visemeDurations[d] || 1;
|
|
2279
|
+
e.visemes.push(d), e.times.push(n), e.durations.push(c), n += c;
|
|
2280
2280
|
}
|
|
2281
2281
|
}), e.i += r.move, l = !0;
|
|
2282
2282
|
break;
|
|
@@ -2381,10 +2381,10 @@ class lt {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let n = parseFloat(t);
|
|
2383
2383
|
if (n === void 0) return t;
|
|
2384
|
-
let i = (s, o, l,
|
|
2384
|
+
let i = (s, o, l, h, r) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(l + (
|
|
2386
|
+
const u = Math.floor(s / o);
|
|
2387
|
+
return e.push(l + (u === 1 ? h : this.numberToFinnishWords(u.toString()) + r)), s - u * o;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (n < 0 && (e.push("miinus "), n = Math.abs(n)), n = i(n, 1e9, " ", "miljardi", " miljardia"), n = i(n, 1e6, " ", "miljoona", " miljoonaa"), n = i(n, 1e3, "", "tuhat", "tuhatta"), n = i(n, 100, " ", "sata", "sataa"), n > 20 && (n = i(n, 10, "", "", "kymmentä")), n >= 1) {
|
|
2390
2390
|
let s = Math.floor(n);
|
|
@@ -2436,11 +2436,11 @@ class lt {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
2441
|
LipsyncFi: lt
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class ht {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2559,10 +2559,10 @@ class ut {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let n = parseFloat(t);
|
|
2561
2561
|
if (n === void 0) return t;
|
|
2562
|
-
let i = (s, o, l,
|
|
2562
|
+
let i = (s, o, l, h, r) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
2564
|
+
const u = Math.floor(s / o);
|
|
2565
|
+
return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(l) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(r) : e.push(h), s - u * o;
|
|
2566
2566
|
};
|
|
2567
2567
|
n < 0 && (e.push("minus"), n = Math.abs(n)), n = i(n, 1e9, "milijardas", "milijardai", "milijardų"), n = i(n, 1e6, "milijonas", "milijonai", "milijonų"), n = i(n, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), n = i(n, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class ut {
|
|
|
2608
2608
|
const o = i[s].toLowerCase(), l = this.visemes[o];
|
|
2609
2609
|
if (l)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const h = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += h, n += h;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(l), e.times.push(n), e.durations.push(
|
|
2614
|
+
const h = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(l), e.times.push(n), e.durations.push(h), n += h;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
n += this.pauses[i[s]] || 0;
|
|
@@ -2622,21 +2622,21 @@ class ut {
|
|
|
2622
2622
|
}
|
|
2623
2623
|
const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2625
|
+
LipsyncLt: ht
|
|
2626
2626
|
}, Symbol.toStringTag, { value: "Module" })), dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
|
|
2627
2627
|
en: it,
|
|
2628
2628
|
de: st,
|
|
2629
2629
|
fr: rt,
|
|
2630
|
-
fi:
|
|
2630
|
+
fi: ut,
|
|
2631
2631
|
lt: ct
|
|
2632
|
-
}, Q = new
|
|
2633
|
-
new
|
|
2634
|
-
new
|
|
2635
|
-
new
|
|
2636
|
-
new
|
|
2637
|
-
const mt = new
|
|
2638
|
-
new
|
|
2639
|
-
new
|
|
2632
|
+
}, Q = new x.Quaternion(), W = new x.Euler(), ve = new x.Vector3(), Ie = new x.Vector3(), We = new x.Box3();
|
|
2633
|
+
new x.Matrix4();
|
|
2634
|
+
new x.Matrix4();
|
|
2635
|
+
new x.Vector3();
|
|
2636
|
+
new x.Vector3(0, 0, 1);
|
|
2637
|
+
const mt = new x.Vector3(1, 0, 0);
|
|
2638
|
+
new x.Vector3(0, 1, 0);
|
|
2639
|
+
new x.Vector3(0, 0, 1);
|
|
2640
2640
|
class Be {
|
|
2641
2641
|
/**
|
|
2642
2642
|
* Avatar.
|
|
@@ -2763,7 +2763,7 @@ class Be {
|
|
|
2763
2763
|
avatarOnlyCamera: null,
|
|
2764
2764
|
statsNode: null,
|
|
2765
2765
|
statsStyle: null
|
|
2766
|
-
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new
|
|
2766
|
+
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new Ke(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
|
|
2767
2767
|
side: {
|
|
2768
2768
|
standing: !0,
|
|
2769
2769
|
props: {
|
|
@@ -3569,15 +3569,15 @@ class Be {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((l) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[l +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[l +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((h) => {
|
|
3573
|
+
this.poseDelta.props[l + h + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((h) => {
|
|
3575
|
+
this.poseDelta.props[l + h + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + h + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + h + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const n = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((l) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(l.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(l.props)).forEach((h) => n.add(h));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((l) => {
|
|
3582
3582
|
n.add(l);
|
|
3583
3583
|
}), this.posePropNames = [...n], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
|
|
@@ -4073,22 +4073,22 @@ class Be {
|
|
|
4073
4073
|
if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
|
|
4074
4074
|
this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
|
|
4075
4075
|
else {
|
|
4076
|
-
this.renderer = new
|
|
4077
|
-
new
|
|
4076
|
+
this.renderer = new x.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = x.SRGBColorSpace, this.renderer.toneMapping = x.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new x.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new x.Scene(), this.lightAmbient = new x.AmbientLight(
|
|
4077
|
+
new x.Color(this.opt.lightAmbientColor),
|
|
4078
4078
|
this.opt.lightAmbientIntensity
|
|
4079
|
-
), this.lightDirect = new
|
|
4080
|
-
new
|
|
4079
|
+
), this.lightDirect = new x.DirectionalLight(
|
|
4080
|
+
new x.Color(this.opt.lightDirectColor),
|
|
4081
4081
|
this.opt.lightDirectIntensity
|
|
4082
|
-
), this.lightSpot = new
|
|
4083
|
-
new
|
|
4082
|
+
), this.lightSpot = new x.SpotLight(
|
|
4083
|
+
new x.Color(this.opt.lightSpotColor),
|
|
4084
4084
|
this.opt.lightSpotIntensity,
|
|
4085
4085
|
0,
|
|
4086
4086
|
this.opt.lightSpotDispersion
|
|
4087
4087
|
), this.setLighting(this.opt);
|
|
4088
|
-
const l = new
|
|
4088
|
+
const l = new x.PMREMGenerator(this.renderer);
|
|
4089
4089
|
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new qe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4090
4090
|
}
|
|
4091
|
-
this.ikMesh = new
|
|
4091
|
+
this.ikMesh = new x.SkinnedMesh();
|
|
4092
4092
|
const s = {
|
|
4093
4093
|
LeftShoulder: null,
|
|
4094
4094
|
LeftArm: "LeftShoulder",
|
|
@@ -4101,10 +4101,10 @@ class Be {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, o = [];
|
|
4104
|
-
Object.entries(s).forEach((l,
|
|
4105
|
-
const r = new
|
|
4104
|
+
Object.entries(s).forEach((l, h) => {
|
|
4105
|
+
const r = new x.Bone();
|
|
4106
4106
|
r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
|
|
4107
|
-
}), this.ikMesh.bind(new
|
|
4107
|
+
}), this.ikMesh.bind(new x.Skeleton(o)), this.dynamicbones = new et(), 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.
|
|
@@ -4150,9 +4150,9 @@ class Be {
|
|
|
4150
4150
|
let e = 3 * t.length / 4;
|
|
4151
4151
|
t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
|
|
4152
4152
|
const n = new ArrayBuffer(e), i = new Uint8Array(n);
|
|
4153
|
-
let s, o = 0, l,
|
|
4153
|
+
let s, o = 0, l, h, r, u;
|
|
4154
4154
|
for (s = 0; s < t.length; s += 4)
|
|
4155
|
-
l = this.b64Lookup[t.charCodeAt(s)],
|
|
4155
|
+
l = this.b64Lookup[t.charCodeAt(s)], h = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], u = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | h >> 4, i[o++] = (h & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | u & 63;
|
|
4156
4156
|
return n;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class Be {
|
|
|
4193
4193
|
const e = {};
|
|
4194
4194
|
for (let [n, i] of Object.entries(t)) {
|
|
4195
4195
|
const s = n.split(".");
|
|
4196
|
-
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[n] = new
|
|
4196
|
+
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, h = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[n] = new x.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new x.Quaternion().setFromEuler(new x.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new x.Quaternion(o, l, h, i.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class Be {
|
|
|
4222
4222
|
t.forEach((s) => {
|
|
4223
4223
|
if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const o = s.geometry;
|
|
4225
|
-
let l = null,
|
|
4226
|
-
for (const [r,
|
|
4225
|
+
let l = null, h = null;
|
|
4226
|
+
for (const [r, u] of Object.entries(n))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(r)) {
|
|
4228
|
-
const a = s.morphTargetDictionary[r],
|
|
4229
|
-
l || (l = new
|
|
4230
|
-
for (let g = 0; g <
|
|
4231
|
-
const
|
|
4232
|
-
l.setXYZ(g,
|
|
4228
|
+
const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], c = o.morphAttributes.normal?.[a];
|
|
4229
|
+
l || (l = new x.Float32BufferAttribute(d.count * 3, 3), c && (h = new x.Float32BufferAttribute(d.count * 3, 3)));
|
|
4230
|
+
for (let g = 0; g < d.count; g++) {
|
|
4231
|
+
const y = l.getX(g) + d.getX(g) * u, b = l.getY(g) + d.getY(g) * u, R = l.getZ(g) + d.getZ(g) * u;
|
|
4232
|
+
l.setXYZ(g, y, b, R);
|
|
4233
4233
|
}
|
|
4234
|
-
if (
|
|
4235
|
-
for (let g = 0; g <
|
|
4236
|
-
const
|
|
4237
|
-
|
|
4234
|
+
if (c)
|
|
4235
|
+
for (let g = 0; g < d.count; g++) {
|
|
4236
|
+
const y = h.getX(g) + c.getX(g) * u, b = h.getY(g) + c.getY(g) * u, R = h.getZ(g) + c.getZ(g) * u;
|
|
4237
|
+
h.setXYZ(g, y, b, R);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (l) {
|
|
4241
|
-
o.morphAttributes.position.push(l),
|
|
4241
|
+
o.morphAttributes.position.push(l), h && o.morphAttributes.normal.push(h);
|
|
4242
4242
|
const r = o.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
|
|
4244
4244
|
}
|
|
@@ -4268,7 +4268,7 @@ class Be {
|
|
|
4268
4268
|
throw new Error("Blend shapes not found");
|
|
4269
4269
|
const o = new Set(this.mtCustoms);
|
|
4270
4270
|
this.morphs.forEach((r) => {
|
|
4271
|
-
Object.keys(r.morphTargetDictionary).forEach((
|
|
4271
|
+
Object.keys(r.morphTargetDictionary).forEach((u) => o.add(u));
|
|
4272
4272
|
}), this.mtExtras.forEach((r) => {
|
|
4273
4273
|
o.has(r.key) || (this.addMixedMorphTarget(this.morphs, r.key, r.mix), o.add(r.key));
|
|
4274
4274
|
});
|
|
@@ -4295,16 +4295,16 @@ class Be {
|
|
|
4295
4295
|
ms: [],
|
|
4296
4296
|
is: []
|
|
4297
4297
|
}, l[r].value = l[r].baseline, l[r].applied = l[r].baseline;
|
|
4298
|
-
const
|
|
4299
|
-
|
|
4300
|
-
l[r][a] =
|
|
4298
|
+
const u = this.mtAvatar[r];
|
|
4299
|
+
u && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
|
|
4300
|
+
l[r][a] = u[a];
|
|
4301
4301
|
}), this.morphs.forEach((a) => {
|
|
4302
|
-
const
|
|
4303
|
-
|
|
4302
|
+
const d = a.morphTargetDictionary[r];
|
|
4303
|
+
d !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(d), a.morphTargetInfluences[d] = l[r].applied);
|
|
4304
4304
|
});
|
|
4305
4305
|
}), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((r) => {
|
|
4306
|
-
const
|
|
4307
|
-
this.poseAvatar.props[r] = a[
|
|
4306
|
+
const u = r.split("."), a = this.armature.getObjectByName(u[0]);
|
|
4307
|
+
this.poseAvatar.props[r] = a[u[1]], this.poseBase.props.hasOwnProperty(r) ? this.poseAvatar.props[r].copy(this.poseBase.props[r]) : this.poseBase.props[r] = this.poseAvatar.props[r].clone(), this.poseDelta.props.hasOwnProperty(r) && !this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r] = this.poseAvatar.props[r].clone()), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = 2e3;
|
|
4308
4308
|
}), this.ikMesh.traverse((r) => {
|
|
4309
4309
|
r.isBone && r.position.copy(this.armature.getObjectByName(r.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 Be {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + r);
|
|
4315
4315
|
}
|
|
4316
4316
|
this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
|
|
4317
|
-
const
|
|
4318
|
-
this.objectLeftEye.getWorldPosition(
|
|
4317
|
+
const h = new x.Vector3();
|
|
4318
|
+
this.objectLeftEye.getWorldPosition(h), this.avatarHeight = h.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,29 +4343,29 @@ class Be {
|
|
|
4343
4343
|
return;
|
|
4344
4344
|
}
|
|
4345
4345
|
if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4346
|
-
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let r = -n * Math.tan(
|
|
4346
|
+
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, h = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let r = -n * Math.tan(h / 2), u = (1 - i) * Math.tan(h / 2), a = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
|
-
a += 2,
|
|
4350
|
+
a += 2, u = u * a + 4 * this.avatarHeight / 5;
|
|
4351
4351
|
break;
|
|
4352
4352
|
case "upper":
|
|
4353
|
-
a += 4.5,
|
|
4353
|
+
a += 4.5, u = u * a + 2 * this.avatarHeight / 3;
|
|
4354
4354
|
break;
|
|
4355
4355
|
case "mid":
|
|
4356
|
-
a += 8,
|
|
4356
|
+
a += 8, u = u * a + this.avatarHeight / 3;
|
|
4357
4357
|
break;
|
|
4358
4358
|
default:
|
|
4359
|
-
a += 12,
|
|
4359
|
+
a += 12, u = u * a;
|
|
4360
4360
|
}
|
|
4361
|
-
r = r * a, this.controlsEnd = new
|
|
4361
|
+
r = r * a, this.controlsEnd = new x.Vector3(r, u, 0), this.cameraEnd = new x.Vector3(r, u, a).applyEuler(new x.Euler(o, l, 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.
|
|
4365
4365
|
* @param {Object} opt Options
|
|
4366
4366
|
*/
|
|
4367
4367
|
setLighting(t) {
|
|
4368
|
-
this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new
|
|
4368
|
+
this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new x.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new x.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new x.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new x.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
|
|
4369
4369
|
}
|
|
4370
4370
|
/**
|
|
4371
4371
|
* Render scene.
|
|
@@ -4398,9 +4398,9 @@ class Be {
|
|
|
4398
4398
|
updatePoseDelta() {
|
|
4399
4399
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
4400
4400
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4401
|
-
|
|
4401
|
+
W.set(e.x, e.y, e.z);
|
|
4402
4402
|
const n = this.poseAvatar.props[t];
|
|
4403
|
-
n.isQuaternion ? (Q.setFromEuler(
|
|
4403
|
+
n.isQuaternion ? (Q.setFromEuler(W), n.multiply(Q)) : n.isVector3 && n.add(W);
|
|
4404
4404
|
}
|
|
4405
4405
|
}
|
|
4406
4406
|
/**
|
|
@@ -4455,17 +4455,17 @@ class Be {
|
|
|
4455
4455
|
"HandMiddle",
|
|
4456
4456
|
"HandRing",
|
|
4457
4457
|
"HandPinky"
|
|
4458
|
-
].forEach((
|
|
4459
|
-
a === 0 ? (this.poseDelta.props[o +
|
|
4458
|
+
].forEach((u, a) => {
|
|
4459
|
+
a === 0 ? (this.poseDelta.props[o + u + "1.quaternion"].x = 0, this.poseDelta.props[o + u + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + u + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + u + "1.quaternion"].x = n.applied, this.poseDelta.props[o + u + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + u + "3.quaternion"].x = 1.5 * n.applied);
|
|
4460
4460
|
});
|
|
4461
4461
|
break;
|
|
4462
4462
|
case "chestInhale":
|
|
4463
|
-
const l = n.applied / 20,
|
|
4464
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4463
|
+
const l = n.applied / 20, h = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
|
|
4464
|
+
this.poseDelta.props["Spine1.scale"] = h, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
|
|
4465
4465
|
break;
|
|
4466
4466
|
default:
|
|
4467
|
-
for (let
|
|
4468
|
-
n.ms[
|
|
4467
|
+
for (let u = 0, a = n.ms.length; u < a; u++)
|
|
4468
|
+
n.ms[u][n.is[u]] = n.applied;
|
|
4469
4469
|
}
|
|
4470
4470
|
}
|
|
4471
4471
|
}
|
|
@@ -4480,8 +4480,8 @@ class Be {
|
|
|
4480
4480
|
return Object.entries(t).forEach((i, s) => {
|
|
4481
4481
|
const o = i[0].split(".");
|
|
4482
4482
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4483
|
-
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0],
|
|
4484
|
-
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(
|
|
4483
|
+
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new x.Euler().setFromQuaternion(i[1]) : i[1];
|
|
4484
|
+
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(h.x * e) / e, n += ", y:" + Math.round(h.y * e) / e, n += ", z:" + Math.round(h.z * e) / e, n += "}";
|
|
4485
4485
|
}
|
|
4486
4486
|
}), n += "}", n;
|
|
4487
4487
|
}
|
|
@@ -4551,8 +4551,8 @@ class Be {
|
|
|
4551
4551
|
if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4552
4552
|
this.setPoseFromTemplate(t, e);
|
|
4553
4553
|
}, 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)
|
|
4554
|
-
for (let [l,
|
|
4555
|
-
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(
|
|
4554
|
+
for (let [l, h] of Object.entries(this.gesture))
|
|
4555
|
+
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(h), this.poseTarget.props[l].t = h.t, this.poseTarget.props[l].d = h.d);
|
|
4556
4556
|
Object.keys(this.poseDelta.props).forEach((l) => {
|
|
4557
4557
|
this.poseTarget.props.hasOwnProperty(l) || (this.poseTarget.props[l] = this.poseBase.props[l].clone(), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = o);
|
|
4558
4558
|
});
|
|
@@ -4985,12 +4985,12 @@ class Be {
|
|
|
4985
4985
|
else if (l.hasOwnProperty("alt")) {
|
|
4986
4986
|
let r = l.alt[0];
|
|
4987
4987
|
if (l.alt.length > 1) {
|
|
4988
|
-
const
|
|
4988
|
+
const u = Math.random();
|
|
4989
4989
|
let a = 0;
|
|
4990
|
-
for (let
|
|
4991
|
-
let
|
|
4992
|
-
if (a +=
|
|
4993
|
-
r = l.alt[
|
|
4990
|
+
for (let d = 0; d < l.alt.length; d++) {
|
|
4991
|
+
let c = this.valueFn(l.alt[d].p);
|
|
4992
|
+
if (a += c === void 0 ? (1 - a) / (l.alt.length - 1 - d) : c, u < a) {
|
|
4993
|
+
r = l.alt[d];
|
|
4994
4994
|
break;
|
|
4995
4995
|
}
|
|
4996
4996
|
}
|
|
@@ -4999,20 +4999,20 @@ class Be {
|
|
|
4999
4999
|
continue;
|
|
5000
5000
|
} else
|
|
5001
5001
|
break;
|
|
5002
|
-
let
|
|
5003
|
-
if (Array.isArray(
|
|
5004
|
-
l.dt.forEach((r,
|
|
5002
|
+
let h = this.valueFn(l.delay) || 0;
|
|
5003
|
+
if (Array.isArray(h) && (h = this.gaussianRandom(...h)), l.hasOwnProperty("dt"))
|
|
5004
|
+
l.dt.forEach((r, u) => {
|
|
5005
5005
|
let a = this.valueFn(r);
|
|
5006
|
-
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[
|
|
5006
|
+
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[u + 1] = o.ts[u] + a;
|
|
5007
5007
|
});
|
|
5008
5008
|
else {
|
|
5009
|
-
let r = Object.values(l.vs).reduce((
|
|
5009
|
+
let r = Object.values(l.vs).reduce((u, a) => a.length > u ? a.length : u, 0);
|
|
5010
5010
|
o.ts = Array(r + 1).fill(0);
|
|
5011
5011
|
}
|
|
5012
|
-
s ? o.ts = o.ts.map((r) =>
|
|
5013
|
-
for (let [r,
|
|
5014
|
-
const a = this.getBaselineValue(r),
|
|
5015
|
-
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...
|
|
5012
|
+
s ? o.ts = o.ts.map((r) => h + r * n) : o.ts = o.ts.map((r) => this.animClock + h + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
|
|
5013
|
+
for (let [r, u] of Object.entries(l.vs)) {
|
|
5014
|
+
const a = this.getBaselineValue(r), d = u.map((c) => (c = this.valueFn(c), c === null ? null : typeof c == "function" ? c : typeof c == "string" || c instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (c === "hip" || c === "side") ? (console.log("Intercepting pose", c, "in animation factory, overriding to wide for male avatar"), "wide") : c.slice() : Array.isArray(c) ? r === "gesture" ? c.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...c) : typeof c == "boolean" ? c : c instanceof Object && c.constructor === Object ? Object.assign({}, c) : (a === void 0 ? 0 : a) + i * c));
|
|
5015
|
+
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((c) => c > 0 ? c : 0)], o.vs.eyeLookInLeft = [null, ...d.map((c) => c > 0 ? 0 : -c)], o.vs.eyeLookOutRight = [null, ...d.map((c) => c > 0 ? 0 : -c)], o.vs.eyeLookInRight = [null, ...d.map((c) => c > 0 ? c : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...d.map((c) => c > 0 ? c : 0)], o.vs.eyesLookUp = [null, ...d.map((c) => c > 0 ? 0 : -c)]) : o.vs[r] = [null, ...d];
|
|
5016
5016
|
}
|
|
5017
5017
|
for (let r of Object.keys(o.vs))
|
|
5018
5018
|
for (; o.vs[r].length <= o.ts.length; ) o.vs[r].push(o.vs[r][o.vs[r].length - 1]);
|
|
@@ -5093,26 +5093,26 @@ class Be {
|
|
|
5093
5093
|
if (this.isSpeaking)
|
|
5094
5094
|
for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5095
5095
|
this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
|
|
5096
|
-
let
|
|
5097
|
-
const
|
|
5096
|
+
let h = null, r = null;
|
|
5097
|
+
const u = [];
|
|
5098
5098
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5099
5099
|
const a = this.animQueue[n];
|
|
5100
5100
|
if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
|
|
5101
5101
|
for (i = a.ndx || 0, o = a.ts.length; i < o && !(this.animClock < a.ts[i]); i++)
|
|
5102
|
-
for (let [
|
|
5103
|
-
if (this.mtAvatar.hasOwnProperty(
|
|
5104
|
-
if (
|
|
5105
|
-
const g = this.mtAvatar[
|
|
5106
|
-
if (
|
|
5107
|
-
g.newvalue =
|
|
5102
|
+
for (let [d, c] of Object.entries(a.vs))
|
|
5103
|
+
if (this.mtAvatar.hasOwnProperty(d)) {
|
|
5104
|
+
if (c[i + 1] === null) continue;
|
|
5105
|
+
const g = this.mtAvatar[d];
|
|
5106
|
+
if (c[i] === null && (c[i] = g.value), i === o - 1)
|
|
5107
|
+
g.newvalue = c[i];
|
|
5108
5108
|
else {
|
|
5109
|
-
g.newvalue =
|
|
5110
|
-
const
|
|
5111
|
-
let
|
|
5112
|
-
|
|
5109
|
+
g.newvalue = c[i + 1];
|
|
5110
|
+
const y = a.ts[i + 1] - a.ts[i];
|
|
5111
|
+
let b = 1;
|
|
5112
|
+
y > 1e-4 && (b = (this.animClock - a.ts[i]) / y), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * c[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
|
|
5113
5113
|
}
|
|
5114
5114
|
if (l)
|
|
5115
|
-
switch (
|
|
5115
|
+
switch (d) {
|
|
5116
5116
|
case "viseme_aa":
|
|
5117
5117
|
case "viseme_E":
|
|
5118
5118
|
case "viseme_I":
|
|
@@ -5121,12 +5121,12 @@ class Be {
|
|
|
5121
5121
|
g.newvalue *= 1 + l / 255 - 0.5;
|
|
5122
5122
|
}
|
|
5123
5123
|
g.needsUpdate = !0;
|
|
5124
|
-
} else
|
|
5124
|
+
} else d === "eyeContact" && c[i] !== null && h !== !1 ? h = !!c[i] : d === "headMove" && c[i] !== null && r !== !1 ? c[i] === 0 ? r = !1 : (Math.random() < c[i] && (r = !0), c[i] = null) : c[i] !== null && (u.push({ mt: d, val: c[i] }), c[i] = null);
|
|
5125
5125
|
i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
|
|
5126
5126
|
}
|
|
5127
5127
|
}
|
|
5128
|
-
for (let a = 0,
|
|
5129
|
-
switch (i =
|
|
5128
|
+
for (let a = 0, d = u.length; a < d; a++)
|
|
5129
|
+
switch (i = u[a].val, u[a].mt) {
|
|
5130
5130
|
case "speak":
|
|
5131
5131
|
this.speakText(i);
|
|
5132
5132
|
break;
|
|
@@ -5143,8 +5143,8 @@ class Be {
|
|
|
5143
5143
|
i && typeof i == "function" && i();
|
|
5144
5144
|
break;
|
|
5145
5145
|
case "moveto":
|
|
5146
|
-
Object.entries(i.props).forEach((
|
|
5147
|
-
|
|
5146
|
+
Object.entries(i.props).forEach((c) => {
|
|
5147
|
+
c[1] ? this.poseTarget.props[c[0]].copy(c[1]) : this.poseTarget.props[c[0]].copy(this.getPoseTemplateProp(c[0])), this.poseTarget.props[c[0]].t = this.animClock, this.poseTarget.props[c[0]].d = c[1] && c[1].d ? c[1].d : c.duration || 2e3;
|
|
5148
5148
|
});
|
|
5149
5149
|
break;
|
|
5150
5150
|
case "handLeft":
|
|
@@ -5157,7 +5157,7 @@ class Be {
|
|
|
5157
5157
|
{ link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
|
|
5158
5158
|
{ link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
|
|
5159
5159
|
]
|
|
5160
|
-
}, i.x ? new
|
|
5160
|
+
}, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5161
5161
|
break;
|
|
5162
5162
|
case "handRight":
|
|
5163
5163
|
this.ikSolve({
|
|
@@ -5169,10 +5169,10 @@ class Be {
|
|
|
5169
5169
|
{ link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
|
|
5170
5170
|
{ link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
|
|
5171
5171
|
]
|
|
5172
|
-
}, i.x ? new
|
|
5172
|
+
}, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5173
5173
|
break;
|
|
5174
5174
|
}
|
|
5175
|
-
if ((
|
|
5175
|
+
if ((h || r) && (W.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), W.x = Math.max(-0.9, Math.min(0.9, 2 * W.x - 0.5)), W.y = Math.max(-0.9, Math.min(0.9, -2.5 * W.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: W.x < 0 ? -W.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: W.x < 0 ? 0 : W.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5176
5176
|
name: "headmove",
|
|
5177
5177
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5178
5178
|
vs: {
|
|
@@ -5193,13 +5193,13 @@ class Be {
|
|
|
5193
5193
|
eyeLookOutRight: [null, 0],
|
|
5194
5194
|
eyeContact: [0]
|
|
5195
5195
|
}
|
|
5196
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) &&
|
|
5196
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Ie), Ie.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Ie.x) / 4, this.objectHips.position.z -= (ve.z + Ie.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5197
5197
|
this.stats && this.stats.end();
|
|
5198
5198
|
else {
|
|
5199
5199
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
5200
5200
|
this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
|
|
5201
|
-
let a = new
|
|
5202
|
-
a.phi += this.easing(this.cameraClock / 1e3) * (
|
|
5201
|
+
let a = new x.Spherical().setFromVector3(this.cameraStart), d = new x.Spherical().setFromVector3(this.cameraEnd);
|
|
5202
|
+
a.phi += this.easing(this.cameraClock / 1e3) * (d.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (d.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (d.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), d.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (d.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (d.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (d.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
|
|
5203
5203
|
}
|
|
5204
5204
|
this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
|
|
5205
5205
|
}
|
|
@@ -5260,49 +5260,49 @@ class Be {
|
|
|
5260
5260
|
*/
|
|
5261
5261
|
speakText(t, e = null, n = null, i = null) {
|
|
5262
5262
|
e = e || {};
|
|
5263
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5264
|
-
let
|
|
5265
|
-
const
|
|
5266
|
-
for (let
|
|
5267
|
-
const R =
|
|
5268
|
-
let p =
|
|
5269
|
-
const
|
|
5270
|
-
if (p && !R && !
|
|
5271
|
-
mark:
|
|
5263
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, h = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5264
|
+
let u = "", a = "", d = 0, c = [], g = [];
|
|
5265
|
+
const y = Array.from(this.segmenter.segment(t), (b) => b.segment);
|
|
5266
|
+
for (let b = 0; b < y.length; b++) {
|
|
5267
|
+
const R = b === y.length - 1, V = y[b].match(l);
|
|
5268
|
+
let p = y[b].match(s);
|
|
5269
|
+
const M = y[b].match(h), z = y[b].match(o);
|
|
5270
|
+
if (p && !R && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (z || p || R) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
|
|
5271
|
+
mark: d,
|
|
5272
5272
|
word: a
|
|
5273
|
-
})),
|
|
5274
|
-
mark:
|
|
5273
|
+
})), u.length && (g.push({
|
|
5274
|
+
mark: d,
|
|
5275
5275
|
template: { name: "subtitles" },
|
|
5276
5276
|
ts: [0],
|
|
5277
5277
|
vs: {
|
|
5278
|
-
subtitles: [
|
|
5278
|
+
subtitles: [u]
|
|
5279
5279
|
}
|
|
5280
|
-
}),
|
|
5281
|
-
const
|
|
5282
|
-
if (
|
|
5283
|
-
const
|
|
5284
|
-
for (let
|
|
5280
|
+
}), u = ""), a.length)) {
|
|
5281
|
+
const f = this.lipsyncWordsToVisemes(a, r);
|
|
5282
|
+
if (f && f.visemes && f.visemes.length) {
|
|
5283
|
+
const E = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
|
|
5284
|
+
for (let P = 0; P < f.visemes.length; P++)
|
|
5285
5285
|
g.push({
|
|
5286
|
-
mark:
|
|
5286
|
+
mark: d,
|
|
5287
5287
|
template: { name: "viseme" },
|
|
5288
|
-
ts: [(
|
|
5288
|
+
ts: [(f.times[P] - 0.6) / E, (f.times[P] + 0.5) / E, (f.times[P] + f.durations[P] + 0.5) / E],
|
|
5289
5289
|
vs: {
|
|
5290
|
-
["viseme_" +
|
|
5290
|
+
["viseme_" + f.visemes[P]]: [null, f.visemes[P] === "PP" || f.visemes[P] === "FF" ? 0.9 : 0.6, 0]
|
|
5291
5291
|
}
|
|
5292
5292
|
});
|
|
5293
5293
|
}
|
|
5294
|
-
a = "",
|
|
5294
|
+
a = "", d++;
|
|
5295
5295
|
}
|
|
5296
5296
|
if (p || R) {
|
|
5297
|
-
if (
|
|
5298
|
-
const
|
|
5297
|
+
if (c.length || R && g.length) {
|
|
5298
|
+
const f = {
|
|
5299
5299
|
anim: g
|
|
5300
5300
|
};
|
|
5301
|
-
n && (
|
|
5301
|
+
n && (f.onSubtitles = n), c.length && !e.avatarMute && (f.text = c, e.avatarMood && (f.mood = e.avatarMood), e.ttsLang && (f.lang = e.ttsLang), e.ttsVoice && (f.voice = e.ttsVoice), e.ttsRate && (f.rate = e.ttsRate), e.ttsVoice && (f.pitch = e.ttsPitch), e.ttsVolume && (f.volume = e.ttsVolume)), this.speechQueue.push(f), c = [], a = "", d = 0, g = [];
|
|
5302
5302
|
}
|
|
5303
|
-
if (
|
|
5304
|
-
let
|
|
5305
|
-
|
|
5303
|
+
if (M) {
|
|
5304
|
+
let f = this.animEmojis[y[b]];
|
|
5305
|
+
f && f.link && (f = this.animEmojis[f.link]), f && this.speechQueue.push({ emoji: f });
|
|
5306
5306
|
}
|
|
5307
5307
|
this.speechQueue.push({ break: 100 });
|
|
5308
5308
|
}
|
|
@@ -5383,27 +5383,27 @@ class Be {
|
|
|
5383
5383
|
if (t.words) {
|
|
5384
5384
|
let o = [];
|
|
5385
5385
|
for (let l = 0; l < t.words.length; l++) {
|
|
5386
|
-
const
|
|
5387
|
-
let
|
|
5388
|
-
if (
|
|
5386
|
+
const h = t.words[l], r = t.wtimes[l];
|
|
5387
|
+
let u = t.wdurations[l];
|
|
5388
|
+
if (h.length && (n && o.push({
|
|
5389
5389
|
template: { name: "subtitles" },
|
|
5390
5390
|
ts: [r],
|
|
5391
5391
|
vs: {
|
|
5392
|
-
subtitles: [" " +
|
|
5392
|
+
subtitles: [" " + h]
|
|
5393
5393
|
}
|
|
5394
5394
|
}), !t.visemes)) {
|
|
5395
|
-
const a = this.lipsyncPreProcessText(
|
|
5396
|
-
if (
|
|
5397
|
-
const
|
|
5398
|
-
let
|
|
5399
|
-
if (
|
|
5400
|
-
for (let
|
|
5401
|
-
const R = r +
|
|
5395
|
+
const a = this.lipsyncPreProcessText(h, i), d = this.lipsyncWordsToVisemes(a, i);
|
|
5396
|
+
if (d && d.visemes && d.visemes.length) {
|
|
5397
|
+
const c = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], g = Math.min(u, Math.max(0, u - d.visemes.length * 150));
|
|
5398
|
+
let y = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5399
|
+
if (u = Math.min(u, d.visemes.length * 200), c > 0)
|
|
5400
|
+
for (let b = 0; b < d.visemes.length; b++) {
|
|
5401
|
+
const R = r + d.times[b] / c * u, V = d.durations[b] / c * u;
|
|
5402
5402
|
o.push({
|
|
5403
5403
|
template: { name: "viseme" },
|
|
5404
|
-
ts: [R - Math.min(60, 2 *
|
|
5404
|
+
ts: [R - Math.min(60, 2 * V / 3), R + Math.min(25, V / 2), R + V + Math.min(60, V / 2)],
|
|
5405
5405
|
vs: {
|
|
5406
|
-
["viseme_" +
|
|
5406
|
+
["viseme_" + d.visemes[b]]: [null, d.visemes[b] === "PP" || d.visemes[b] === "FF" ? 0.9 : y, 0]
|
|
5407
5407
|
}
|
|
5408
5408
|
});
|
|
5409
5409
|
}
|
|
@@ -5412,22 +5412,22 @@ class Be {
|
|
|
5412
5412
|
}
|
|
5413
5413
|
if (t.visemes)
|
|
5414
5414
|
for (let l = 0; l < t.visemes.length; l++) {
|
|
5415
|
-
const
|
|
5415
|
+
const h = t.visemes[l], r = t.vtimes[l], u = t.vdurations[l];
|
|
5416
5416
|
o.push({
|
|
5417
5417
|
template: { name: "viseme" },
|
|
5418
|
-
ts: [r - 2 *
|
|
5418
|
+
ts: [r - 2 * u / 3, r + u / 2, r + u + u / 2],
|
|
5419
5419
|
vs: {
|
|
5420
|
-
["viseme_" +
|
|
5420
|
+
["viseme_" + h]: [null, h === "PP" || h === "FF" ? 0.9 : 0.6, 0]
|
|
5421
5421
|
}
|
|
5422
5422
|
});
|
|
5423
5423
|
}
|
|
5424
5424
|
if (t.markers)
|
|
5425
5425
|
for (let l = 0; l < t.markers.length; l++) {
|
|
5426
|
-
const
|
|
5426
|
+
const h = t.markers[l], r = t.mtimes[l];
|
|
5427
5427
|
o.push({
|
|
5428
5428
|
template: { name: "markers" },
|
|
5429
5429
|
ts: [r],
|
|
5430
|
-
vs: { function: [
|
|
5430
|
+
vs: { function: [h] }
|
|
5431
5431
|
});
|
|
5432
5432
|
}
|
|
5433
5433
|
o.length && (s.anim = o);
|
|
@@ -5447,7 +5447,7 @@ class Be {
|
|
|
5447
5447
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5448
5448
|
const e = this.audioPlaylist.shift();
|
|
5449
5449
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5450
|
-
const s = this.audioCtx.resume(), o = new Promise((l,
|
|
5450
|
+
const s = this.audioCtx.resume(), o = new Promise((l, h) => setTimeout(() => h("p2"), 1e3));
|
|
5451
5451
|
try {
|
|
5452
5452
|
await Promise.race([s, o]);
|
|
5453
5453
|
} catch {
|
|
@@ -5479,38 +5479,38 @@ class Be {
|
|
|
5479
5479
|
*/
|
|
5480
5480
|
async synthesizeWithBrowserTTS(t) {
|
|
5481
5481
|
return new Promise((e, n) => {
|
|
5482
|
-
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5483
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2,
|
|
5484
|
-
const
|
|
5485
|
-
if (a &&
|
|
5486
|
-
const p =
|
|
5482
|
+
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, h = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5483
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, h)), s.volume = Math.max(0, Math.min(1, r));
|
|
5484
|
+
const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5485
|
+
if (a && u.length > 0) {
|
|
5486
|
+
const p = u.find((M) => M.name.includes(a) || M.lang === o);
|
|
5487
5487
|
p && (s.voice = p);
|
|
5488
5488
|
}
|
|
5489
|
-
const
|
|
5489
|
+
const d = i.length * 100 / s.rate, c = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(y, g);
|
|
5490
5490
|
console.log("Browser TTS Lip-sync Debug:", {
|
|
5491
5491
|
text: i,
|
|
5492
5492
|
lipsyncLang: g,
|
|
5493
|
-
processedText:
|
|
5494
|
-
lipsyncData:
|
|
5495
|
-
hasVisemes:
|
|
5496
|
-
estimatedDuration:
|
|
5493
|
+
processedText: y,
|
|
5494
|
+
lipsyncData: b,
|
|
5495
|
+
hasVisemes: b && b.visemes && b.visemes.length > 0,
|
|
5496
|
+
estimatedDuration: d
|
|
5497
5497
|
});
|
|
5498
5498
|
const R = [];
|
|
5499
|
-
if (
|
|
5500
|
-
const p =
|
|
5501
|
-
for (let
|
|
5502
|
-
const
|
|
5499
|
+
if (b && b.visemes && b.visemes.length > 0) {
|
|
5500
|
+
const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
|
|
5501
|
+
for (let M = 0; M < b.visemes.length; M++) {
|
|
5502
|
+
const z = b.visemes[M], f = b.times[M] / p, E = b.durations[M] / p, P = f * d, U = E * d;
|
|
5503
5503
|
R.push({
|
|
5504
5504
|
template: { name: "viseme" },
|
|
5505
|
-
ts: [
|
|
5505
|
+
ts: [P - Math.min(60, 2 * U / 3), P + Math.min(25, U / 2), P + U + Math.min(60, U / 2)],
|
|
5506
5506
|
vs: {
|
|
5507
|
-
["viseme_" +
|
|
5507
|
+
["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
|
|
5508
5508
|
}
|
|
5509
5509
|
});
|
|
5510
5510
|
}
|
|
5511
5511
|
}
|
|
5512
|
-
const
|
|
5513
|
-
this.audioPlaylist.push({ anim:
|
|
5512
|
+
const V = [...t.anim, ...R];
|
|
5513
|
+
this.audioPlaylist.push({ anim: V, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5514
5514
|
e();
|
|
5515
5515
|
}, s.onerror = (p) => {
|
|
5516
5516
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -5522,7 +5522,7 @@ class Be {
|
|
|
5522
5522
|
* @param {Object} line Speech line object
|
|
5523
5523
|
*/
|
|
5524
5524
|
async synthesizeWithElevenLabsTTS(t) {
|
|
5525
|
-
const e = t.text.map((
|
|
5525
|
+
const e = t.text.map((d) => d.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "21m00Tcm4TlvDq8ikWAM", i = {
|
|
5526
5526
|
text: e,
|
|
5527
5527
|
model_id: "eleven_monolingual_v1",
|
|
5528
5528
|
voice_settings: {
|
|
@@ -5544,26 +5544,26 @@ class Be {
|
|
|
5544
5544
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5545
5545
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5546
5546
|
console.log("Using text-based lip-sync for debugging...");
|
|
5547
|
-
const
|
|
5547
|
+
const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5548
5548
|
let r;
|
|
5549
5549
|
try {
|
|
5550
5550
|
console.log("Lip-sync modules available:", {
|
|
5551
5551
|
hasLipsync: !!this.lipsync,
|
|
5552
5552
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5553
|
-
lipsyncLang:
|
|
5553
|
+
lipsyncLang: h
|
|
5554
5554
|
});
|
|
5555
|
-
const
|
|
5555
|
+
const d = this.lipsyncPreProcessText(e, h), c = this.lipsyncWordsToVisemes(d, h);
|
|
5556
5556
|
if (console.log("Lip-sync data:", {
|
|
5557
|
-
processedText:
|
|
5558
|
-
lipsyncData:
|
|
5559
|
-
hasVisemes:
|
|
5560
|
-
}),
|
|
5557
|
+
processedText: d,
|
|
5558
|
+
lipsyncData: c,
|
|
5559
|
+
hasVisemes: c && c.visemes && c.visemes.length > 0
|
|
5560
|
+
}), c && c.visemes && c.visemes.length > 0)
|
|
5561
5561
|
r = {
|
|
5562
|
-
visemes:
|
|
5562
|
+
visemes: c.visemes.map((g, y) => ({
|
|
5563
5563
|
viseme: g,
|
|
5564
|
-
startTime:
|
|
5565
|
-
endTime: (
|
|
5566
|
-
duration: l.duration /
|
|
5564
|
+
startTime: y * l.duration / c.visemes.length,
|
|
5565
|
+
endTime: (y + 1) * l.duration / c.visemes.length,
|
|
5566
|
+
duration: l.duration / c.visemes.length,
|
|
5567
5567
|
intensity: 0.7
|
|
5568
5568
|
})),
|
|
5569
5569
|
words: [],
|
|
@@ -5572,19 +5572,19 @@ class Be {
|
|
|
5572
5572
|
};
|
|
5573
5573
|
else
|
|
5574
5574
|
throw new Error("No visemes generated from text");
|
|
5575
|
-
} catch (
|
|
5576
|
-
console.error("Text-based lip-sync failed, using fallback:",
|
|
5577
|
-
const
|
|
5578
|
-
for (const
|
|
5579
|
-
for (const
|
|
5575
|
+
} catch (d) {
|
|
5576
|
+
console.error("Text-based lip-sync failed, using fallback:", d);
|
|
5577
|
+
const c = e.toLowerCase().split(/\s+/), g = [];
|
|
5578
|
+
for (const y of c)
|
|
5579
|
+
for (const b of y) {
|
|
5580
5580
|
let R = "aa";
|
|
5581
|
-
"aeiou".includes(
|
|
5581
|
+
"aeiou".includes(b) ? R = "aa" : "bp".includes(b) ? R = "PP" : "fv".includes(b) ? R = "FF" : "st".includes(b) ? R = "SS" : "dln".includes(b) ? R = "DD" : "kg".includes(b) ? R = "kk" : "rw".includes(b) && (R = "RR"), g.push(R);
|
|
5582
5582
|
}
|
|
5583
5583
|
r = {
|
|
5584
|
-
visemes: g.map((
|
|
5585
|
-
viseme:
|
|
5586
|
-
startTime:
|
|
5587
|
-
endTime: (
|
|
5584
|
+
visemes: g.map((y, b) => ({
|
|
5585
|
+
viseme: y,
|
|
5586
|
+
startTime: b * l.duration / g.length,
|
|
5587
|
+
endTime: (b + 1) * l.duration / g.length,
|
|
5588
5588
|
duration: l.duration / g.length,
|
|
5589
5589
|
intensity: 0.6
|
|
5590
5590
|
})),
|
|
@@ -5605,31 +5605,31 @@ class Be {
|
|
|
5605
5605
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5606
5606
|
// Show first 3 visemes for debugging
|
|
5607
5607
|
});
|
|
5608
|
-
const
|
|
5608
|
+
const u = [];
|
|
5609
5609
|
if (r.visemes && r.visemes.length > 0) {
|
|
5610
5610
|
console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5611
|
-
for (let
|
|
5612
|
-
const
|
|
5613
|
-
|
|
5611
|
+
for (let d = 0; d < r.visemes.length; d++) {
|
|
5612
|
+
const c = r.visemes[d], g = c.startTime * 1e3, y = c.duration * 1e3, b = c.intensity;
|
|
5613
|
+
u.push({
|
|
5614
5614
|
template: { name: "viseme" },
|
|
5615
|
-
ts: [g - Math.min(60, 2 *
|
|
5615
|
+
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5616
5616
|
vs: {
|
|
5617
|
-
["viseme_" +
|
|
5617
|
+
["viseme_" + c.viseme]: [null, b, 0]
|
|
5618
5618
|
}
|
|
5619
5619
|
});
|
|
5620
5620
|
}
|
|
5621
|
-
console.log("ElevenLabs: Generated",
|
|
5621
|
+
console.log("ElevenLabs: Generated", u.length, "lip-sync animation frames");
|
|
5622
5622
|
} else
|
|
5623
5623
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5624
|
-
const a = [...t.anim, ...
|
|
5625
|
-
console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5624
|
+
const a = [...t.anim, ...u];
|
|
5625
|
+
console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5626
5626
|
}
|
|
5627
5627
|
/**
|
|
5628
5628
|
* Synthesize speech using Deepgram Aura-2 TTS
|
|
5629
5629
|
* @param {Object} line Speech line object
|
|
5630
5630
|
*/
|
|
5631
5631
|
async synthesizeWithDeepgramTTS(t) {
|
|
5632
|
-
const e = t.text.map((
|
|
5632
|
+
const e = t.text.map((d) => d.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "aura-2-thalia-en", i = `${this.opt.ttsEndpoint}?model=${n}`, s = await fetch(i, {
|
|
5633
5633
|
method: "POST",
|
|
5634
5634
|
headers: {
|
|
5635
5635
|
Authorization: `Token ${this.opt.ttsApikey}`,
|
|
@@ -5642,26 +5642,26 @@ class Be {
|
|
|
5642
5642
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5643
5643
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5644
5644
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5645
|
-
const
|
|
5645
|
+
const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5646
5646
|
let r;
|
|
5647
5647
|
try {
|
|
5648
5648
|
console.log("Lip-sync modules available:", {
|
|
5649
5649
|
hasLipsync: !!this.lipsync,
|
|
5650
5650
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5651
|
-
lipsyncLang:
|
|
5651
|
+
lipsyncLang: h
|
|
5652
5652
|
});
|
|
5653
|
-
const
|
|
5653
|
+
const d = this.lipsyncPreProcessText(e, h), c = this.lipsyncWordsToVisemes(d, h);
|
|
5654
5654
|
if (console.log("Lip-sync data:", {
|
|
5655
|
-
processedText:
|
|
5656
|
-
lipsyncData:
|
|
5657
|
-
hasVisemes:
|
|
5658
|
-
}),
|
|
5655
|
+
processedText: d,
|
|
5656
|
+
lipsyncData: c,
|
|
5657
|
+
hasVisemes: c && c.visemes && c.visemes.length > 0
|
|
5658
|
+
}), c && c.visemes && c.visemes.length > 0)
|
|
5659
5659
|
r = {
|
|
5660
|
-
visemes:
|
|
5660
|
+
visemes: c.visemes.map((g, y) => ({
|
|
5661
5661
|
viseme: g,
|
|
5662
|
-
startTime:
|
|
5663
|
-
endTime: (
|
|
5664
|
-
duration: l.duration /
|
|
5662
|
+
startTime: y * l.duration / c.visemes.length,
|
|
5663
|
+
endTime: (y + 1) * l.duration / c.visemes.length,
|
|
5664
|
+
duration: l.duration / c.visemes.length,
|
|
5665
5665
|
intensity: 0.7
|
|
5666
5666
|
})),
|
|
5667
5667
|
words: [],
|
|
@@ -5670,19 +5670,19 @@ class Be {
|
|
|
5670
5670
|
};
|
|
5671
5671
|
else
|
|
5672
5672
|
throw new Error("No visemes generated from text");
|
|
5673
|
-
} catch (
|
|
5674
|
-
console.error("Text-based lip-sync failed, using fallback:",
|
|
5675
|
-
const
|
|
5676
|
-
for (const
|
|
5677
|
-
for (const
|
|
5673
|
+
} catch (d) {
|
|
5674
|
+
console.error("Text-based lip-sync failed, using fallback:", d);
|
|
5675
|
+
const c = e.toLowerCase().split(/\s+/), g = [];
|
|
5676
|
+
for (const y of c)
|
|
5677
|
+
for (const b of y) {
|
|
5678
5678
|
let R = "aa";
|
|
5679
|
-
"aeiou".includes(
|
|
5679
|
+
"aeiou".includes(b) ? R = "aa" : "bp".includes(b) ? R = "PP" : "fv".includes(b) ? R = "FF" : "st".includes(b) ? R = "SS" : "dln".includes(b) ? R = "DD" : "kg".includes(b) ? R = "kk" : "rw".includes(b) && (R = "RR"), g.push(R);
|
|
5680
5680
|
}
|
|
5681
5681
|
r = {
|
|
5682
|
-
visemes: g.map((
|
|
5683
|
-
viseme:
|
|
5684
|
-
startTime:
|
|
5685
|
-
endTime: (
|
|
5682
|
+
visemes: g.map((y, b) => ({
|
|
5683
|
+
viseme: y,
|
|
5684
|
+
startTime: b * l.duration / g.length,
|
|
5685
|
+
endTime: (b + 1) * l.duration / g.length,
|
|
5686
5686
|
duration: l.duration / g.length,
|
|
5687
5687
|
intensity: 0.6
|
|
5688
5688
|
})),
|
|
@@ -5703,24 +5703,24 @@ class Be {
|
|
|
5703
5703
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5704
5704
|
// Show first 3 visemes for debugging
|
|
5705
5705
|
});
|
|
5706
|
-
const
|
|
5706
|
+
const u = [];
|
|
5707
5707
|
if (r.visemes && r.visemes.length > 0) {
|
|
5708
5708
|
console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5709
|
-
for (let
|
|
5710
|
-
const
|
|
5711
|
-
|
|
5709
|
+
for (let d = 0; d < r.visemes.length; d++) {
|
|
5710
|
+
const c = r.visemes[d], g = c.startTime * 1e3, y = c.duration * 1e3, b = c.intensity;
|
|
5711
|
+
u.push({
|
|
5712
5712
|
template: { name: "viseme" },
|
|
5713
|
-
ts: [g - Math.min(60, 2 *
|
|
5713
|
+
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5714
5714
|
vs: {
|
|
5715
|
-
["viseme_" +
|
|
5715
|
+
["viseme_" + c.viseme]: [null, b, 0]
|
|
5716
5716
|
}
|
|
5717
5717
|
});
|
|
5718
5718
|
}
|
|
5719
|
-
console.log("Deepgram: Generated",
|
|
5719
|
+
console.log("Deepgram: Generated", u.length, "lip-sync animation frames");
|
|
5720
5720
|
} else
|
|
5721
5721
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5722
|
-
const a = [...t.anim, ...
|
|
5723
|
-
console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5722
|
+
const a = [...t.anim, ...u];
|
|
5723
|
+
console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5724
5724
|
}
|
|
5725
5725
|
/**
|
|
5726
5726
|
* Synthesize speech using Azure TTS
|
|
@@ -5746,30 +5746,30 @@ class Be {
|
|
|
5746
5746
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5747
5747
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5748
5748
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5749
|
-
const
|
|
5749
|
+
const h = await this.audioAnalyzer.analyzeAudio(l, e);
|
|
5750
5750
|
console.log("Azure TTS Audio Analysis:", {
|
|
5751
5751
|
text: e,
|
|
5752
5752
|
audioDuration: l.duration,
|
|
5753
|
-
visemeCount:
|
|
5754
|
-
wordCount:
|
|
5753
|
+
visemeCount: h.visemes.length,
|
|
5754
|
+
wordCount: h.words.length,
|
|
5755
5755
|
features: {
|
|
5756
|
-
onsets:
|
|
5757
|
-
boundaries:
|
|
5756
|
+
onsets: h.features.onsets.length,
|
|
5757
|
+
boundaries: h.features.phonemeBoundaries.length
|
|
5758
5758
|
}
|
|
5759
5759
|
});
|
|
5760
5760
|
const r = [];
|
|
5761
|
-
for (let a = 0; a <
|
|
5762
|
-
const
|
|
5761
|
+
for (let a = 0; a < h.visemes.length; a++) {
|
|
5762
|
+
const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, y = d.intensity;
|
|
5763
5763
|
r.push({
|
|
5764
5764
|
template: { name: "viseme" },
|
|
5765
|
-
ts: [
|
|
5765
|
+
ts: [c - Math.min(60, 2 * g / 3), c + Math.min(25, g / 2), c + g + Math.min(60, g / 2)],
|
|
5766
5766
|
vs: {
|
|
5767
|
-
["viseme_" +
|
|
5767
|
+
["viseme_" + d.viseme]: [null, y, 0]
|
|
5768
5768
|
}
|
|
5769
5769
|
});
|
|
5770
5770
|
}
|
|
5771
|
-
const
|
|
5772
|
-
this.audioPlaylist.push({ anim:
|
|
5771
|
+
const u = [...t.anim, ...r];
|
|
5772
|
+
this.audioPlaylist.push({ anim: u, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5773
5773
|
}
|
|
5774
5774
|
/**
|
|
5775
5775
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5808,27 +5808,27 @@ class Be {
|
|
|
5808
5808
|
if (i.status === 200 && s && s.audioContent) {
|
|
5809
5809
|
const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
|
|
5810
5810
|
this.speakWithHands();
|
|
5811
|
-
const
|
|
5811
|
+
const h = [0];
|
|
5812
5812
|
let r = 0;
|
|
5813
|
-
t.text.forEach((
|
|
5814
|
-
if (
|
|
5815
|
-
let g =
|
|
5816
|
-
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" +
|
|
5813
|
+
t.text.forEach((d, c) => {
|
|
5814
|
+
if (c > 0) {
|
|
5815
|
+
let g = h[h.length - 1];
|
|
5816
|
+
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + d.mark && r++), h.push(g);
|
|
5817
5817
|
}
|
|
5818
5818
|
});
|
|
5819
|
-
const
|
|
5820
|
-
|
|
5821
|
-
if (
|
|
5822
|
-
let g =
|
|
5823
|
-
|
|
5819
|
+
const u = [{ mark: 0, time: 0 }];
|
|
5820
|
+
h.forEach((d, c) => {
|
|
5821
|
+
if (c > 0) {
|
|
5822
|
+
let g = d - h[c - 1];
|
|
5823
|
+
u[c - 1].duration = g, u.push({ mark: c, time: d });
|
|
5824
5824
|
}
|
|
5825
5825
|
});
|
|
5826
5826
|
let a = 1e3 * l.duration;
|
|
5827
|
-
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd),
|
|
5828
|
-
const
|
|
5829
|
-
if (
|
|
5830
|
-
for (let g = 0; g <
|
|
5831
|
-
|
|
5827
|
+
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((d) => {
|
|
5828
|
+
const c = u[d.mark];
|
|
5829
|
+
if (c)
|
|
5830
|
+
for (let g = 0; g < d.ts.length; g++)
|
|
5831
|
+
d.ts[g] = c.time + d.ts[g] * c.duration + this.opt.ttsTrimStart;
|
|
5832
5832
|
}), this.audioPlaylist.push({ anim: t.anim, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5833
5833
|
} else
|
|
5834
5834
|
this.startSpeaking(!0);
|
|
@@ -5908,10 +5908,10 @@ class Be {
|
|
|
5908
5908
|
}
|
|
5909
5909
|
if (!this.workletLoaded)
|
|
5910
5910
|
try {
|
|
5911
|
-
const l = this.audioCtx.audioWorklet.addModule(dt.href),
|
|
5912
|
-
(r,
|
|
5911
|
+
const l = this.audioCtx.audioWorklet.addModule(dt.href), h = new Promise(
|
|
5912
|
+
(r, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
|
|
5913
5913
|
);
|
|
5914
|
-
await Promise.race([l,
|
|
5914
|
+
await Promise.race([l, h]), this.workletLoaded = !0;
|
|
5915
5915
|
} catch (l) {
|
|
5916
5916
|
throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
|
|
5917
5917
|
}
|
|
@@ -5924,8 +5924,8 @@ class Be {
|
|
|
5924
5924
|
if (l.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5925
5925
|
try {
|
|
5926
5926
|
this.onAudioStart?.();
|
|
5927
|
-
} catch (
|
|
5928
|
-
console.error(
|
|
5927
|
+
} catch (h) {
|
|
5928
|
+
console.error(h);
|
|
5929
5929
|
}
|
|
5930
5930
|
if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5931
5931
|
try {
|
|
@@ -5945,9 +5945,9 @@ class Be {
|
|
|
5945
5945
|
} catch {
|
|
5946
5946
|
}
|
|
5947
5947
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5948
|
-
const l = this.audioCtx.resume(),
|
|
5948
|
+
const l = this.audioCtx.resume(), h = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
|
|
5949
5949
|
try {
|
|
5950
|
-
await Promise.race([l,
|
|
5950
|
+
await Promise.race([l, h]);
|
|
5951
5951
|
} catch {
|
|
5952
5952
|
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.");
|
|
5953
5953
|
return;
|
|
@@ -6044,18 +6044,18 @@ class Be {
|
|
|
6044
6044
|
subtitles: [" " + i]
|
|
6045
6045
|
}
|
|
6046
6046
|
}), this.streamLipsyncType == "words")) {
|
|
6047
|
-
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6047
|
+
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, h = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(h, l);
|
|
6048
6048
|
if (r && r.visemes && r.visemes.length) {
|
|
6049
|
-
const
|
|
6050
|
-
let
|
|
6051
|
-
if (o = Math.min(o, r.visemes.length * 200),
|
|
6052
|
-
for (let
|
|
6053
|
-
const g = e + s + r.times[
|
|
6049
|
+
const u = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
|
|
6050
|
+
let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
|
|
6051
|
+
if (o = Math.min(o, r.visemes.length * 200), u > 0)
|
|
6052
|
+
for (let c = 0; c < r.visemes.length; c++) {
|
|
6053
|
+
const g = e + s + r.times[c] / u * o, y = r.durations[c] / u * o;
|
|
6054
6054
|
this.animQueue.push({
|
|
6055
6055
|
template: { name: "viseme" },
|
|
6056
|
-
ts: [g - Math.min(60, 2 *
|
|
6056
|
+
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
6057
6057
|
vs: {
|
|
6058
|
-
["viseme_" + r.visemes[
|
|
6058
|
+
["viseme_" + r.visemes[c]]: [null, r.visemes[c] === "PP" || r.visemes[c] === "FF" ? 0.9 : d, 0]
|
|
6059
6059
|
}
|
|
6060
6060
|
});
|
|
6061
6061
|
}
|
|
@@ -6146,7 +6146,7 @@ class Be {
|
|
|
6146
6146
|
*/
|
|
6147
6147
|
lookAtCamera(t) {
|
|
6148
6148
|
let e;
|
|
6149
|
-
if (this.speakTo && (e = new
|
|
6149
|
+
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), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Ie).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
|
|
6150
6150
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6151
6151
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6152
6152
|
this.lookAhead(t);
|
|
@@ -6159,22 +6159,22 @@ class Be {
|
|
|
6159
6159
|
this.lookAt(null, null, t);
|
|
6160
6160
|
return;
|
|
6161
6161
|
}
|
|
6162
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld),
|
|
6163
|
-
const n = new
|
|
6164
|
-
|
|
6165
|
-
const l = new
|
|
6166
|
-
|
|
6167
|
-
let r =
|
|
6162
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Ie).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6163
|
+
const n = new x.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6164
|
+
W.set(s, i, 0, "YXZ");
|
|
6165
|
+
const l = new x.Quaternion().setFromEuler(W), h = new x.Quaternion().copy(l).multiply(Q.clone().invert());
|
|
6166
|
+
W.setFromQuaternion(h, "YXZ");
|
|
6167
|
+
let r = W.x / (40 / 24) + 0.2, u = W.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6168
6168
|
if (t) {
|
|
6169
|
-
let
|
|
6170
|
-
|
|
6171
|
-
const
|
|
6169
|
+
let y = this.animQueue.findIndex((R) => R.template.name === "lookat");
|
|
6170
|
+
y !== -1 && this.animQueue.splice(y, 1);
|
|
6171
|
+
const b = {
|
|
6172
6172
|
name: "lookat",
|
|
6173
6173
|
dt: [750, t],
|
|
6174
6174
|
vs: {
|
|
6175
|
-
bodyRotateX: [a +
|
|
6176
|
-
bodyRotateY: [
|
|
6177
|
-
eyesRotateX: [-3 *
|
|
6175
|
+
bodyRotateX: [a + c],
|
|
6176
|
+
bodyRotateY: [d + g],
|
|
6177
|
+
eyesRotateX: [-3 * c + 0.1],
|
|
6178
6178
|
eyesRotateY: [-5 * g],
|
|
6179
6179
|
browInnerUp: [[0, 0.7]],
|
|
6180
6180
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6183,7 +6183,7 @@ class Be {
|
|
|
6183
6183
|
headMove: [0]
|
|
6184
6184
|
}
|
|
6185
6185
|
};
|
|
6186
|
-
this.animQueue.push(this.animFactory(
|
|
6186
|
+
this.animQueue.push(this.animFactory(b));
|
|
6187
6187
|
}
|
|
6188
6188
|
}
|
|
6189
6189
|
/**
|
|
@@ -6196,23 +6196,23 @@ class Be {
|
|
|
6196
6196
|
if (!this.camera) return;
|
|
6197
6197
|
const i = this.nodeAvatar.getBoundingClientRect();
|
|
6198
6198
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6199
|
-
const s = new
|
|
6199
|
+
const s = new x.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new x.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new x.Vector3().addVectors(s, o).divideScalar(2);
|
|
6200
6200
|
l.project(this.camera);
|
|
6201
|
-
let
|
|
6202
|
-
t === null && (t =
|
|
6203
|
-
let
|
|
6204
|
-
|
|
6205
|
-
let
|
|
6201
|
+
let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6202
|
+
t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), W.setFromQuaternion(Q);
|
|
6203
|
+
let u = W.x / (40 / 24), a = W.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), y = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - y, r + y], [-0.3, 0.6]) - u + d, R = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
|
|
6204
|
+
b = Math.min(0.6, Math.max(-0.3, b)), R = Math.min(0.8, Math.max(-0.8, R));
|
|
6205
|
+
let V = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (n) {
|
|
6207
|
-
let
|
|
6208
|
-
|
|
6209
|
-
const
|
|
6207
|
+
let M = this.animQueue.findIndex((f) => f.template.name === "lookat");
|
|
6208
|
+
M !== -1 && this.animQueue.splice(M, 1);
|
|
6209
|
+
const z = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, n],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [
|
|
6213
|
+
bodyRotateX: [b + V],
|
|
6214
6214
|
bodyRotateY: [R + p],
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6215
|
+
eyesRotateX: [-3 * V + 0.1],
|
|
6216
6216
|
eyesRotateY: [-5 * p],
|
|
6217
6217
|
browInnerUp: [[0, 0.7]],
|
|
6218
6218
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6221,7 +6221,7 @@ class Be {
|
|
|
6221
6221
|
headMove: [0]
|
|
6222
6222
|
}
|
|
6223
6223
|
};
|
|
6224
|
-
this.animQueue.push(this.animFactory(
|
|
6224
|
+
this.animQueue.push(this.animFactory(z));
|
|
6225
6225
|
}
|
|
6226
6226
|
}
|
|
6227
6227
|
/**
|
|
@@ -6232,17 +6232,17 @@ class Be {
|
|
|
6232
6232
|
*/
|
|
6233
6233
|
touchAt(t, e) {
|
|
6234
6234
|
if (!this.camera) return;
|
|
6235
|
-
const n = this.nodeAvatar.getBoundingClientRect(), i = new
|
|
6235
|
+
const n = this.nodeAvatar.getBoundingClientRect(), i = new x.Vector2(
|
|
6236
6236
|
(t - n.left) / n.width * 2 - 1,
|
|
6237
6237
|
-((e - n.top) / n.height) * 2 + 1
|
|
6238
|
-
), s = new
|
|
6238
|
+
), s = new x.Raycaster();
|
|
6239
6239
|
s.setFromCamera(i, this.camera);
|
|
6240
6240
|
const o = s.intersectObject(this.armature);
|
|
6241
6241
|
if (o.length > 0) {
|
|
6242
|
-
const l = o[0].point,
|
|
6243
|
-
this.objectLeftArm.getWorldPosition(
|
|
6244
|
-
const
|
|
6245
|
-
|
|
6242
|
+
const l = o[0].point, h = new x.Vector3(), r = new x.Vector3();
|
|
6243
|
+
this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(r);
|
|
6244
|
+
const u = h.distanceToSquared(l), a = r.distanceToSquared(l);
|
|
6245
|
+
u < a ? (this.ikSolve({
|
|
6246
6246
|
iterations: 20,
|
|
6247
6247
|
root: "LeftShoulder",
|
|
6248
6248
|
effector: "LeftHandMiddle1",
|
|
@@ -6263,8 +6263,8 @@ class Be {
|
|
|
6263
6263
|
}, l, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6264
6264
|
} else
|
|
6265
6265
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
|
|
6266
|
-
let
|
|
6267
|
-
this.poseTarget.props[
|
|
6266
|
+
let h = l + ".quaternion";
|
|
6267
|
+
this.poseTarget.props[h].copy(this.getPoseTemplateProp(h)), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = 1e3;
|
|
6268
6268
|
});
|
|
6269
6269
|
return o.length > 0;
|
|
6270
6270
|
}
|
|
@@ -6283,7 +6283,7 @@ class Be {
|
|
|
6283
6283
|
{ link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
|
|
6284
6284
|
{ link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
|
|
6285
6285
|
]
|
|
6286
|
-
}, new
|
|
6286
|
+
}, new x.Vector3(
|
|
6287
6287
|
this.gaussianRandom(0, 0.5),
|
|
6288
6288
|
this.gaussianRandom(-0.8, -0.2),
|
|
6289
6289
|
this.gaussianRandom(0, 0.5)
|
|
@@ -6295,15 +6295,15 @@ class Be {
|
|
|
6295
6295
|
{ link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
|
|
6296
6296
|
{ link: "RightArm" }
|
|
6297
6297
|
]
|
|
6298
|
-
}, new
|
|
6298
|
+
}, new x.Vector3(
|
|
6299
6299
|
this.gaussianRandom(-0.5, 0),
|
|
6300
6300
|
this.gaussianRandom(-0.8, -0.2),
|
|
6301
6301
|
this.gaussianRandom(0, 0.5)
|
|
6302
6302
|
), !0);
|
|
6303
6303
|
const n = [], i = [];
|
|
6304
6304
|
n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
|
|
6305
|
-
"LeftHand.quaternion": new
|
|
6306
|
-
"RightHand.quaternion": new
|
|
6305
|
+
"LeftHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, -1 - Math.random(), 0)),
|
|
6306
|
+
"RightHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, 1 + Math.random(), 0))
|
|
6307
6307
|
} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
|
|
6308
6308
|
i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
|
|
6309
6309
|
}), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
|
|
@@ -6380,232 +6380,24 @@ class Be {
|
|
|
6380
6380
|
* @param {number} [ndx=0] Index of the clip
|
|
6381
6381
|
* @param {number} [scale=0.01] Position scale factor
|
|
6382
6382
|
*/
|
|
6383
|
-
/**
|
|
6384
|
-
* Get all bone names from the avatar's armature
|
|
6385
|
-
* @returns {Set<string>} Set of bone names
|
|
6386
|
-
*/
|
|
6387
|
-
getAvailableBoneNames() {
|
|
6388
|
-
const t = /* @__PURE__ */ new Set();
|
|
6389
|
-
return this.armature && this.armature.traverse((e) => {
|
|
6390
|
-
(e.isBone || e.type === "Bone") && t.add(e.name);
|
|
6391
|
-
}), t;
|
|
6392
|
-
}
|
|
6393
|
-
/**
|
|
6394
|
-
* Map bone names from different naming conventions to avatar bone names
|
|
6395
|
-
* @param {string} fbxBoneName - Bone name from FBX animation
|
|
6396
|
-
* @param {Set<string>} availableBones - Set of available bone names in avatar
|
|
6397
|
-
* @returns {string|null} Mapped bone name or null if no match found
|
|
6398
|
-
*/
|
|
6399
|
-
mapBoneName(t, e) {
|
|
6400
|
-
if (e.has(t))
|
|
6401
|
-
return t;
|
|
6402
|
-
let n = t;
|
|
6403
|
-
if (n.startsWith("CC_Base_") && (n = n.replace("CC_Base_", "")), n = n.replace(/^mixamorig/i, ""), e.has(n))
|
|
6404
|
-
return n;
|
|
6405
|
-
if (this._mappingDebugLog || (this._mappingDebugLog = /* @__PURE__ */ new Set()), this._mappingDebugLog.size < 5 && !this._mappingDebugLog.has(t) && (this._mappingDebugLog.add(t), console.debug(`Mapping attempt: "${t}" -> "${n}" (not found in available bones)`)), n.match(/^Spine\d+$/)) {
|
|
6406
|
-
const a = n.match(/\d+/)?.[0];
|
|
6407
|
-
if (a) {
|
|
6408
|
-
const c = `Spine${parseInt(a)}`;
|
|
6409
|
-
if (e.has(c))
|
|
6410
|
-
return c;
|
|
6411
|
-
if (a === "01" && e.has("Spine1"))
|
|
6412
|
-
return "Spine1";
|
|
6413
|
-
if (parseInt(a) >= 2 && e.has("Spine2"))
|
|
6414
|
-
return "Spine2";
|
|
6415
|
-
}
|
|
6416
|
-
}
|
|
6417
|
-
if (n.includes("Twist"))
|
|
6418
|
-
return null;
|
|
6419
|
-
const i = {
|
|
6420
|
-
// Spine mapping
|
|
6421
|
-
Spine01: "Spine1",
|
|
6422
|
-
Spine02: "Spine2",
|
|
6423
|
-
Spine03: "Spine2",
|
|
6424
|
-
// Left arm mapping
|
|
6425
|
-
L_Upperarm: "LeftArm",
|
|
6426
|
-
L_Forearm: "LeftForeArm",
|
|
6427
|
-
L_Hand: "LeftHand",
|
|
6428
|
-
L_Shoulder: "LeftShoulder",
|
|
6429
|
-
L_Index1: "LeftHandIndex1",
|
|
6430
|
-
L_Index2: "LeftHandIndex2",
|
|
6431
|
-
L_Index3: "LeftHandIndex3",
|
|
6432
|
-
L_Middle1: "LeftHandMiddle1",
|
|
6433
|
-
L_Middle2: "LeftHandMiddle2",
|
|
6434
|
-
L_Middle3: "LeftHandMiddle3",
|
|
6435
|
-
L_Mid1: "LeftHandMiddle1",
|
|
6436
|
-
L_Mid2: "LeftHandMiddle2",
|
|
6437
|
-
L_Mid3: "LeftHandMiddle3",
|
|
6438
|
-
L_Ring1: "LeftHandRing1",
|
|
6439
|
-
L_Ring2: "LeftHandRing2",
|
|
6440
|
-
L_Ring3: "LeftHandRing3",
|
|
6441
|
-
L_Pinky1: "LeftHandPinky1",
|
|
6442
|
-
L_Pinky2: "LeftHandPinky2",
|
|
6443
|
-
L_Pinky3: "LeftHandPinky3",
|
|
6444
|
-
L_Thumb1: "LeftHandThumb1",
|
|
6445
|
-
L_Thumb2: "LeftHandThumb2",
|
|
6446
|
-
L_Thumb3: "LeftHandThumb3",
|
|
6447
|
-
// Right arm mapping
|
|
6448
|
-
R_Upperarm: "RightArm",
|
|
6449
|
-
R_Forearm: "RightForeArm",
|
|
6450
|
-
R_Hand: "RightHand",
|
|
6451
|
-
R_Shoulder: "RightShoulder",
|
|
6452
|
-
R_Index1: "RightHandIndex1",
|
|
6453
|
-
R_Index2: "RightHandIndex2",
|
|
6454
|
-
R_Index3: "RightHandIndex3",
|
|
6455
|
-
R_Middle1: "RightHandMiddle1",
|
|
6456
|
-
R_Middle2: "RightHandMiddle2",
|
|
6457
|
-
R_Middle3: "RightHandMiddle3",
|
|
6458
|
-
R_Mid1: "RightHandMiddle1",
|
|
6459
|
-
R_Mid2: "RightHandMiddle2",
|
|
6460
|
-
R_Mid3: "RightHandMiddle3",
|
|
6461
|
-
R_Ring1: "RightHandRing1",
|
|
6462
|
-
R_Ring2: "RightHandRing2",
|
|
6463
|
-
R_Ring3: "RightHandRing3",
|
|
6464
|
-
R_Pinky1: "RightHandPinky1",
|
|
6465
|
-
R_Pinky2: "RightHandPinky2",
|
|
6466
|
-
R_Pinky3: "RightHandPinky3",
|
|
6467
|
-
R_Thumb1: "RightHandThumb1",
|
|
6468
|
-
R_Thumb2: "RightHandThumb2",
|
|
6469
|
-
R_Thumb3: "RightHandThumb3",
|
|
6470
|
-
// Leg mapping
|
|
6471
|
-
L_Thigh: "LeftUpLeg",
|
|
6472
|
-
L_Calf: "LeftLeg",
|
|
6473
|
-
L_Foot: "LeftFoot",
|
|
6474
|
-
R_Thigh: "RightUpLeg",
|
|
6475
|
-
R_Calf: "RightLeg",
|
|
6476
|
-
R_Foot: "RightFoot"
|
|
6477
|
-
};
|
|
6478
|
-
if (i[n]) {
|
|
6479
|
-
const a = i[n];
|
|
6480
|
-
if (e.has(a))
|
|
6481
|
-
return a;
|
|
6482
|
-
}
|
|
6483
|
-
const s = n.toLowerCase();
|
|
6484
|
-
n.charAt(0).toUpperCase() + n.slice(1).toLowerCase();
|
|
6485
|
-
const o = s.match(/^[rl]_index(\d+)$/);
|
|
6486
|
-
if (o) {
|
|
6487
|
-
const a = o[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandIndex${a}`;
|
|
6488
|
-
if (e.has(d))
|
|
6489
|
-
return d;
|
|
6490
|
-
}
|
|
6491
|
-
const l = s.match(/^[rl]_pinky(\d+)$/);
|
|
6492
|
-
if (l) {
|
|
6493
|
-
const a = l[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandPinky${a}`;
|
|
6494
|
-
if (e.has(d))
|
|
6495
|
-
return d;
|
|
6496
|
-
}
|
|
6497
|
-
const u = s.match(/^[rl]_ring(\d+)$/);
|
|
6498
|
-
if (u) {
|
|
6499
|
-
const a = u[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandRing${a}`;
|
|
6500
|
-
if (e.has(d))
|
|
6501
|
-
return d;
|
|
6502
|
-
}
|
|
6503
|
-
const r = s.match(/^[rl]_(?:middle|mid)(\d+)$/);
|
|
6504
|
-
if (r) {
|
|
6505
|
-
const a = r[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandMiddle${a}`;
|
|
6506
|
-
if (e.has(d))
|
|
6507
|
-
return d;
|
|
6508
|
-
}
|
|
6509
|
-
const h = s.match(/^[rl]_thumb(\d+)$/);
|
|
6510
|
-
if (h) {
|
|
6511
|
-
const a = h[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandThumb${a}`;
|
|
6512
|
-
if (e.has(d))
|
|
6513
|
-
return d;
|
|
6514
|
-
}
|
|
6515
|
-
if (s.match(/^[rl]_upperarm/)) {
|
|
6516
|
-
const c = `${s.startsWith("r") ? "Right" : "Left"}Arm`;
|
|
6517
|
-
if (e.has(c))
|
|
6518
|
-
return c;
|
|
6519
|
-
}
|
|
6520
|
-
if (s.includes("upperarmtwist") || s.includes("forearmtwist") || s.includes("ribstwist") || s.includes("breast") || s.includes("twist"))
|
|
6521
|
-
return null;
|
|
6522
|
-
if (s.match(/^[rl]_forearm/)) {
|
|
6523
|
-
const c = `${s.startsWith("r") ? "Right" : "Left"}ForeArm`;
|
|
6524
|
-
if (e.has(c))
|
|
6525
|
-
return c;
|
|
6526
|
-
}
|
|
6527
|
-
if (s.match(/^[rl]_hand$/)) {
|
|
6528
|
-
const c = `${s.startsWith("r") ? "Right" : "Left"}Hand`;
|
|
6529
|
-
if (e.has(c))
|
|
6530
|
-
return c;
|
|
6531
|
-
}
|
|
6532
|
-
for (const a of e)
|
|
6533
|
-
if (a.toLowerCase() === s)
|
|
6534
|
-
return a;
|
|
6535
|
-
return null;
|
|
6536
|
-
}
|
|
6537
|
-
/**
|
|
6538
|
-
* Filter animation tracks to only include bones that exist in the avatar
|
|
6539
|
-
* Maps bone names from different naming conventions to avatar bone names
|
|
6540
|
-
* @param {THREE.AnimationClip} clip - Animation clip to filter
|
|
6541
|
-
* @param {Set<string>} availableBones - Set of available bone names
|
|
6542
|
-
* @returns {THREE.AnimationClip} Filtered animation clip with mapped bone names
|
|
6543
|
-
*/
|
|
6544
|
-
filterAnimationTracks(t, e) {
|
|
6545
|
-
const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
|
|
6546
|
-
return this._loggedAvailableBones || (console.log(
|
|
6547
|
-
"Available avatar bones:",
|
|
6548
|
-
Array.from(e).sort().slice(0, 50).join(", "),
|
|
6549
|
-
e.size > 50 ? `... (${e.size} total)` : ""
|
|
6550
|
-
), this._loggedAvailableBones = !0), t.tracks.forEach((o) => {
|
|
6551
|
-
const l = o.name.split("."), u = l[0], r = l[1], h = this.mapBoneName(u, e);
|
|
6552
|
-
if (h) {
|
|
6553
|
-
const a = `${h}.${r}`, c = o.clone();
|
|
6554
|
-
c.name = a;
|
|
6555
|
-
const d = h.includes("Arm") || h.includes("Hand") || h.includes("Shoulder"), g = h.includes("ForeArm");
|
|
6556
|
-
if (d && (r === "quaternion" || r === "rotation")) {
|
|
6557
|
-
if (r === "quaternion" && c.values && c.values.length >= 4) {
|
|
6558
|
-
const x = c.times.length;
|
|
6559
|
-
for (let f = 0; f < x; f++) {
|
|
6560
|
-
const R = f * 4;
|
|
6561
|
-
if (R + 3 < c.values.length) {
|
|
6562
|
-
let F = c.values[R], p = c.values[R + 1], H = c.values[R + 2], k = c.values[R + 3];
|
|
6563
|
-
if (g || h.includes("Hand")) {
|
|
6564
|
-
const y = Math.PI, T = Math.cos(y / 2), E = Math.sin(y / 2), O = T * k - E * F, te = T * F + E * k, S = T * p - E * H, G = T * H + E * p;
|
|
6565
|
-
F = te, p = S, H = G, k = O;
|
|
6566
|
-
}
|
|
6567
|
-
c.values[R] = F, c.values[R + 1] = p, c.values[R + 2] = H, c.values[R + 3] = k;
|
|
6568
|
-
}
|
|
6569
|
-
}
|
|
6570
|
-
} else if (r === "rotation" && c.values && c.values.length >= 3) {
|
|
6571
|
-
const x = c.times.length;
|
|
6572
|
-
for (let f = 0; f < x; f++) {
|
|
6573
|
-
const R = f * 3;
|
|
6574
|
-
R + 2 < c.values.length && (g || h.includes("Hand")) && (c.values[R + 1] += Math.PI);
|
|
6575
|
-
}
|
|
6576
|
-
}
|
|
6577
|
-
}
|
|
6578
|
-
n.push(c), u !== h && s.set(u, h);
|
|
6579
|
-
} else
|
|
6580
|
-
i.add(u);
|
|
6581
|
-
}), s.size > 0 && console.info(
|
|
6582
|
-
`FBX animation "${t.name}": Mapped ${s.size} bone(s) to avatar skeleton:`,
|
|
6583
|
-
Array.from(s.entries()).slice(0, 5).map(([o, l]) => `${o} → ${l}`).join(", "),
|
|
6584
|
-
s.size > 5 ? "..." : ""
|
|
6585
|
-
), i.size > 0 && console.warn(
|
|
6586
|
-
`FBX animation "${t.name}" contains tracks for ${i.size} bone(s) that couldn't be mapped:`,
|
|
6587
|
-
Array.from(i).slice(0, 10).join(", "),
|
|
6588
|
-
i.size > 10 ? "..." : ""
|
|
6589
|
-
), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new b.AnimationClip(t.name, t.duration, n);
|
|
6590
|
-
}
|
|
6591
6383
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6592
6384
|
if (!this.armature) return;
|
|
6593
6385
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6594
|
-
let l = this.animClips.find((
|
|
6386
|
+
let l = this.animClips.find((h) => h.url === t + "-" + i);
|
|
6595
6387
|
if (l) {
|
|
6596
|
-
let
|
|
6597
|
-
|
|
6388
|
+
let h = this.animQueue.find((a) => a.template.name === "pose");
|
|
6389
|
+
h && (h.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
|
|
6598
6390
|
this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
|
|
6599
|
-
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new
|
|
6600
|
-
const r = Math.ceil(n / l.clip.duration),
|
|
6601
|
-
|
|
6391
|
+
}), 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.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6392
|
+
const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
|
|
6393
|
+
u.setLoop(x.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
|
|
6602
6394
|
try {
|
|
6603
|
-
|
|
6395
|
+
u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
|
|
6604
6396
|
} catch (a) {
|
|
6605
6397
|
console.warn("FBX animation failed to start:", a), this.stopAnimation();
|
|
6606
6398
|
return;
|
|
6607
6399
|
}
|
|
6608
|
-
if (
|
|
6400
|
+
if (u.getClip().tracks.length === 0) {
|
|
6609
6401
|
console.warn("FBX animation has no valid tracks, stopping"), this.stopAnimation();
|
|
6610
6402
|
return;
|
|
6611
6403
|
}
|
|
@@ -6616,64 +6408,58 @@ class Be {
|
|
|
6616
6408
|
}
|
|
6617
6409
|
let r = !1;
|
|
6618
6410
|
try {
|
|
6619
|
-
const
|
|
6620
|
-
if (r =
|
|
6621
|
-
console.error(`FBX file not found at ${t}. Status: ${
|
|
6411
|
+
const d = await fetch(t, { method: "HEAD" });
|
|
6412
|
+
if (r = d.ok, !r) {
|
|
6413
|
+
console.error(`FBX file not found at ${t}. Status: ${d.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
|
|
6622
6414
|
return;
|
|
6623
6415
|
}
|
|
6624
|
-
} catch (
|
|
6625
|
-
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`,
|
|
6416
|
+
} catch (d) {
|
|
6417
|
+
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, d);
|
|
6626
6418
|
}
|
|
6627
|
-
const
|
|
6419
|
+
const u = new Oe();
|
|
6628
6420
|
let a;
|
|
6629
6421
|
try {
|
|
6630
|
-
a = await
|
|
6631
|
-
} catch (
|
|
6632
|
-
console.error(`Failed to load FBX animation from ${t}:`,
|
|
6633
|
-
message:
|
|
6422
|
+
a = await u.loadAsync(t, e);
|
|
6423
|
+
} catch (d) {
|
|
6424
|
+
console.error(`Failed to load FBX animation from ${t}:`, d), console.error("Error details:", {
|
|
6425
|
+
message: d.message,
|
|
6634
6426
|
url: t,
|
|
6635
6427
|
suggestion: "Make sure the file is a valid FBX file and the path is correct"
|
|
6636
|
-
}),
|
|
6428
|
+
}), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
|
|
6637
6429
|
try {
|
|
6638
|
-
const
|
|
6430
|
+
const c = await fetch(t), g = c.headers.get("content-type"), y = await c.text();
|
|
6639
6431
|
console.error("Response details:", {
|
|
6640
|
-
status:
|
|
6432
|
+
status: c.status,
|
|
6641
6433
|
contentType: g,
|
|
6642
|
-
firstBytes:
|
|
6643
|
-
isHTML:
|
|
6644
|
-
}), (
|
|
6645
|
-
} catch (
|
|
6646
|
-
console.error("Could not fetch file for debugging:",
|
|
6434
|
+
firstBytes: y.substring(0, 100),
|
|
6435
|
+
isHTML: y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")
|
|
6436
|
+
}), (y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
|
|
6437
|
+
} catch (c) {
|
|
6438
|
+
console.error("Could not fetch file for debugging:", c);
|
|
6647
6439
|
}
|
|
6648
6440
|
return;
|
|
6649
6441
|
}
|
|
6650
6442
|
if (a && a.animations && a.animations[i]) {
|
|
6651
|
-
let
|
|
6652
|
-
const
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
const F = R.name.split(".");
|
|
6662
|
-
if (F[1] === "position") {
|
|
6663
|
-
for (let p = 0; p < R.values.length; p++)
|
|
6664
|
-
R.values[p] = R.values[p] * s;
|
|
6665
|
-
x[R.name] = new b.Vector3(R.values[0], R.values[1], R.values[2]);
|
|
6666
|
-
} else F[1] === "quaternion" ? x[R.name] = new b.Quaternion(R.values[0], R.values[1], R.values[2], R.values[3]) : F[1] === "rotation" && (x[F[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(R.values[0], R.values[1], R.values[2], "XYZ")).normalize());
|
|
6443
|
+
let d = a.animations[i];
|
|
6444
|
+
const c = {};
|
|
6445
|
+
d.tracks.forEach((y) => {
|
|
6446
|
+
y.name = y.name.replaceAll("mixamorig", "");
|
|
6447
|
+
const b = y.name.split(".");
|
|
6448
|
+
if (b[1] === "position") {
|
|
6449
|
+
for (let R = 0; R < y.values.length; R++)
|
|
6450
|
+
y.values[R] = y.values[R] * s;
|
|
6451
|
+
c[y.name] = new x.Vector3(y.values[0], y.values[1], y.values[2]);
|
|
6452
|
+
} else b[1] === "quaternion" ? c[y.name] = new x.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : b[1] === "rotation" && (c[b[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
|
|
6667
6453
|
});
|
|
6668
|
-
const
|
|
6669
|
-
|
|
6454
|
+
const g = { props: c };
|
|
6455
|
+
c["Hips.position"] && (c["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
|
|
6670
6456
|
url: t + "-" + i,
|
|
6671
|
-
clip:
|
|
6672
|
-
pose:
|
|
6457
|
+
clip: d,
|
|
6458
|
+
pose: g
|
|
6673
6459
|
}), this.playAnimation(t, e, n, i, s);
|
|
6674
6460
|
} else {
|
|
6675
|
-
const
|
|
6676
|
-
console.error(
|
|
6461
|
+
const d = "Animation " + t + " (ndx=" + i + ") not found";
|
|
6462
|
+
console.error(d), a && a.animations ? console.error(`FBX file loaded but has ${a.animations.length} animation(s), requested index ${i}`) : console.error(a ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
|
|
6677
6463
|
}
|
|
6678
6464
|
}
|
|
6679
6465
|
}
|
|
@@ -6699,25 +6485,25 @@ class Be {
|
|
|
6699
6485
|
if (!this.armature) return;
|
|
6700
6486
|
let o = this.poseTemplates[t];
|
|
6701
6487
|
if (!o) {
|
|
6702
|
-
const l = this.animPoses.find((
|
|
6488
|
+
const l = this.animPoses.find((h) => h.url === t + "-" + i);
|
|
6703
6489
|
l && (o = l.pose);
|
|
6704
6490
|
}
|
|
6705
6491
|
if (o) {
|
|
6706
6492
|
this.poseName = t, this.mixer = null;
|
|
6707
|
-
let l = this.animQueue.find((
|
|
6493
|
+
let l = this.animQueue.find((h) => h.template.name === "pose");
|
|
6708
6494
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6709
6495
|
} else {
|
|
6710
|
-
let
|
|
6711
|
-
if (
|
|
6712
|
-
let r =
|
|
6713
|
-
const
|
|
6714
|
-
r.tracks.forEach((
|
|
6715
|
-
|
|
6716
|
-
const
|
|
6717
|
-
|
|
6496
|
+
let h = await new Oe().loadAsync(t, e);
|
|
6497
|
+
if (h && h.animations && h.animations[i]) {
|
|
6498
|
+
let r = h.animations[i];
|
|
6499
|
+
const u = {};
|
|
6500
|
+
r.tracks.forEach((d) => {
|
|
6501
|
+
d.name = d.name.replaceAll("mixamorig", "");
|
|
6502
|
+
const c = d.name.split(".");
|
|
6503
|
+
c[1] === "position" ? u[d.name] = new x.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : c[1] === "quaternion" ? u[d.name] = new x.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : c[1] === "rotation" && (u[c[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
|
|
6718
6504
|
});
|
|
6719
|
-
const a = { props:
|
|
6720
|
-
|
|
6505
|
+
const a = { props: u };
|
|
6506
|
+
u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
|
|
6721
6507
|
url: t + "-" + i,
|
|
6722
6508
|
pose: a
|
|
6723
6509
|
}), this.playPose(t, e, n, i, s);
|
|
@@ -6746,10 +6532,10 @@ class Be {
|
|
|
6746
6532
|
let s = this.gestureTemplates[t];
|
|
6747
6533
|
if (s) {
|
|
6748
6534
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6749
|
-
let l = this.animQueue.findIndex((
|
|
6750
|
-
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((
|
|
6751
|
-
for (let [
|
|
6752
|
-
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(
|
|
6535
|
+
let l = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
|
|
6536
|
+
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 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));
|
|
6537
|
+
for (let [h, r] of Object.entries(this.gesture))
|
|
6538
|
+
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(r), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = i);
|
|
6753
6539
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6754
6540
|
}
|
|
6755
6541
|
let o = this.animEmojis[t];
|
|
@@ -6757,15 +6543,15 @@ class Be {
|
|
|
6757
6543
|
this.lookAtCamera(500);
|
|
6758
6544
|
const l = this.animFactory(o);
|
|
6759
6545
|
if (l.gesture = !0, e && Number.isFinite(e)) {
|
|
6760
|
-
const
|
|
6761
|
-
if (e * 1e3 -
|
|
6762
|
-
const
|
|
6763
|
-
for (let
|
|
6764
|
-
const
|
|
6765
|
-
l.ts = l.ts.map((
|
|
6546
|
+
const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
|
|
6547
|
+
if (e * 1e3 - u > 0) {
|
|
6548
|
+
const d = [];
|
|
6549
|
+
for (let y = 1; y < l.ts.length; y++) d.push(l.ts[y] - l.ts[y - 1]);
|
|
6550
|
+
const c = o.template?.rescale || d.map((y) => y / u), g = e * 1e3 - u;
|
|
6551
|
+
l.ts = l.ts.map((y, b, R) => b === 0 ? h : R[b - 1] + d[b - 1] + c[b - 1] * g);
|
|
6766
6552
|
} else {
|
|
6767
|
-
const
|
|
6768
|
-
l.ts = l.ts.map((
|
|
6553
|
+
const d = e * 1e3 / u;
|
|
6554
|
+
l.ts = l.ts.map((c) => h + d * (c - h));
|
|
6769
6555
|
}
|
|
6770
6556
|
}
|
|
6771
6557
|
this.animQueue.push(l);
|
|
@@ -6795,33 +6581,33 @@ class Be {
|
|
|
6795
6581
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6796
6582
|
*/
|
|
6797
6583
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6798
|
-
const s = new
|
|
6799
|
-
|
|
6800
|
-
const g = this.ikMesh.getObjectByName(t.effector),
|
|
6801
|
-
|
|
6584
|
+
const s = new x.Vector3(), o = new x.Vector3(), l = new x.Vector3(), h = new x.Vector3(), r = new x.Quaternion(), u = new x.Vector3(), a = new x.Vector3(), d = new x.Vector3(), c = this.ikMesh.getObjectByName(t.root);
|
|
6585
|
+
c.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), c.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(c.position);
|
|
6586
|
+
const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
|
|
6587
|
+
y.forEach((R) => {
|
|
6802
6588
|
R.bone = this.ikMesh.getObjectByName(R.link), R.bone.quaternion.copy(this.getPoseTemplateProp(R.link + ".quaternion"));
|
|
6803
|
-
}),
|
|
6804
|
-
const
|
|
6589
|
+
}), c.updateMatrixWorld(!0);
|
|
6590
|
+
const b = t.iterations || 10;
|
|
6805
6591
|
if (e)
|
|
6806
|
-
for (let R = 0; R <
|
|
6807
|
-
let
|
|
6808
|
-
for (let p = 0,
|
|
6809
|
-
const
|
|
6810
|
-
|
|
6811
|
-
let
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
), new
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
))),
|
|
6592
|
+
for (let R = 0; R < b; R++) {
|
|
6593
|
+
let V = !1;
|
|
6594
|
+
for (let p = 0, M = y.length; p < M; p++) {
|
|
6595
|
+
const z = y[p].bone;
|
|
6596
|
+
z.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
|
|
6597
|
+
let f = s.dot(l);
|
|
6598
|
+
f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f), z.quaternion.multiply(Q), z.rotation.setFromVector3(d.setFromEuler(z.rotation).clamp(new x.Vector3(
|
|
6599
|
+
y[p].minx !== void 0 ? y[p].minx : -1 / 0,
|
|
6600
|
+
y[p].miny !== void 0 ? y[p].miny : -1 / 0,
|
|
6601
|
+
y[p].minz !== void 0 ? y[p].minz : -1 / 0
|
|
6602
|
+
), new x.Vector3(
|
|
6603
|
+
y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
|
|
6604
|
+
y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
|
|
6605
|
+
y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
|
|
6606
|
+
))), z.updateMatrixWorld(!0), V = !0);
|
|
6821
6607
|
}
|
|
6822
|
-
if (!
|
|
6608
|
+
if (!V) break;
|
|
6823
6609
|
}
|
|
6824
|
-
i &&
|
|
6610
|
+
i && y.forEach((R) => {
|
|
6825
6611
|
this.poseTarget.props[R.link + ".quaternion"].copy(R.bone.quaternion), this.poseTarget.props[R.link + ".quaternion"].t = this.animClock, this.poseTarget.props[R.link + ".quaternion"].d = i;
|
|
6826
6612
|
});
|
|
6827
6613
|
}
|
|
@@ -6832,7 +6618,7 @@ class Be {
|
|
|
6832
6618
|
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();
|
|
6833
6619
|
}
|
|
6834
6620
|
}
|
|
6835
|
-
const
|
|
6621
|
+
const Re = {
|
|
6836
6622
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6837
6623
|
// Replace with your actual API key (should start with sk_)
|
|
6838
6624
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6875,23 +6661,23 @@ const Ie = {
|
|
|
6875
6661
|
function Fe() {
|
|
6876
6662
|
return {
|
|
6877
6663
|
service: "elevenlabs",
|
|
6878
|
-
endpoint:
|
|
6879
|
-
apiKey:
|
|
6880
|
-
defaultVoice:
|
|
6881
|
-
voices:
|
|
6664
|
+
endpoint: Re.endpoint,
|
|
6665
|
+
apiKey: Re.apiKey,
|
|
6666
|
+
defaultVoice: Re.defaultVoice,
|
|
6667
|
+
voices: Re.voices
|
|
6882
6668
|
};
|
|
6883
6669
|
}
|
|
6884
6670
|
function kt() {
|
|
6885
|
-
const
|
|
6886
|
-
return Object.entries(
|
|
6671
|
+
const G = Fe(), t = [];
|
|
6672
|
+
return Object.entries(G.voices).forEach(([e, n]) => {
|
|
6887
6673
|
t.push({
|
|
6888
6674
|
value: n,
|
|
6889
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6675
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
|
|
6890
6676
|
});
|
|
6891
6677
|
}), t;
|
|
6892
6678
|
}
|
|
6893
6679
|
const Ve = Me(({
|
|
6894
|
-
avatarUrl:
|
|
6680
|
+
avatarUrl: G = "/avatars/brunette.glb",
|
|
6895
6681
|
avatarBody: t = "F",
|
|
6896
6682
|
mood: e = "neutral",
|
|
6897
6683
|
ttsLang: n = "en",
|
|
@@ -6899,141 +6685,141 @@ const Ve = Me(({
|
|
|
6899
6685
|
ttsVoice: s = null,
|
|
6900
6686
|
ttsApiKey: o = null,
|
|
6901
6687
|
bodyMovement: l = "idle",
|
|
6902
|
-
movementIntensity:
|
|
6688
|
+
movementIntensity: h = 0.5,
|
|
6903
6689
|
showFullAvatar: r = !0,
|
|
6904
|
-
cameraView:
|
|
6690
|
+
cameraView: u = "upper",
|
|
6905
6691
|
onReady: a = () => {
|
|
6906
6692
|
},
|
|
6907
|
-
onLoading:
|
|
6693
|
+
onLoading: d = () => {
|
|
6908
6694
|
},
|
|
6909
|
-
onError:
|
|
6695
|
+
onError: c = () => {
|
|
6910
6696
|
},
|
|
6911
6697
|
className: g = "",
|
|
6912
|
-
style:
|
|
6913
|
-
animations:
|
|
6698
|
+
style: y = {},
|
|
6699
|
+
animations: b = {}
|
|
6914
6700
|
}, R) => {
|
|
6915
|
-
const
|
|
6701
|
+
const V = D(null), p = D(null), M = D(r), z = D(null), f = D(null), E = D(!1), P = D({ remainingText: null, originalText: null, options: null }), U = D([]), oe = D(0), [S, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6916
6702
|
de(() => {
|
|
6917
|
-
|
|
6703
|
+
E.current = ae;
|
|
6918
6704
|
}, [ae]), de(() => {
|
|
6919
|
-
|
|
6705
|
+
M.current = r;
|
|
6920
6706
|
}, [r]);
|
|
6921
6707
|
const ee = Fe(), le = i || ee.service;
|
|
6922
|
-
let
|
|
6923
|
-
le === "browser" ?
|
|
6708
|
+
let O;
|
|
6709
|
+
le === "browser" ? O = {
|
|
6924
6710
|
service: "browser",
|
|
6925
6711
|
endpoint: "",
|
|
6926
6712
|
apiKey: null,
|
|
6927
6713
|
defaultVoice: "Google US English"
|
|
6928
|
-
} : le === "elevenlabs" ?
|
|
6714
|
+
} : le === "elevenlabs" ? O = {
|
|
6929
6715
|
service: "elevenlabs",
|
|
6930
6716
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6931
6717
|
apiKey: o || ee.apiKey,
|
|
6932
|
-
defaultVoice: s || ee.defaultVoice ||
|
|
6933
|
-
voices: ee.voices ||
|
|
6934
|
-
} : le === "deepgram" ?
|
|
6718
|
+
defaultVoice: s || ee.defaultVoice || Re.defaultVoice,
|
|
6719
|
+
voices: ee.voices || Re.voices
|
|
6720
|
+
} : le === "deepgram" ? O = {
|
|
6935
6721
|
service: "deepgram",
|
|
6936
6722
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6937
6723
|
apiKey: o || ee.apiKey,
|
|
6938
6724
|
defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
|
|
6939
6725
|
voices: ee.voices || Te.voices
|
|
6940
|
-
} :
|
|
6726
|
+
} : O = {
|
|
6941
6727
|
...ee,
|
|
6942
6728
|
// Override API key if provided via props
|
|
6943
6729
|
apiKey: o !== null ? o : ee.apiKey
|
|
6944
6730
|
};
|
|
6945
6731
|
const v = {
|
|
6946
|
-
url:
|
|
6732
|
+
url: G,
|
|
6947
6733
|
body: t,
|
|
6948
6734
|
avatarMood: e,
|
|
6949
6735
|
ttsLang: le === "browser" ? "en-US" : n,
|
|
6950
|
-
ttsVoice: s ||
|
|
6736
|
+
ttsVoice: s || O.defaultVoice,
|
|
6951
6737
|
lipsyncLang: "en",
|
|
6952
6738
|
showFullAvatar: r,
|
|
6953
6739
|
bodyMovement: l,
|
|
6954
|
-
movementIntensity:
|
|
6740
|
+
movementIntensity: h
|
|
6955
6741
|
}, I = {
|
|
6956
|
-
ttsEndpoint:
|
|
6957
|
-
ttsApikey:
|
|
6742
|
+
ttsEndpoint: O.endpoint,
|
|
6743
|
+
ttsApikey: O.apiKey,
|
|
6958
6744
|
ttsService: le,
|
|
6959
6745
|
lipsyncModules: ["en"],
|
|
6960
|
-
cameraView:
|
|
6961
|
-
},
|
|
6962
|
-
if (!(!
|
|
6746
|
+
cameraView: u
|
|
6747
|
+
}, k = T(async () => {
|
|
6748
|
+
if (!(!V.current || p.current))
|
|
6963
6749
|
try {
|
|
6964
|
-
if (
|
|
6965
|
-
if (
|
|
6966
|
-
const J = Math.min(100, Math.round(
|
|
6967
|
-
|
|
6750
|
+
if (Z(!0), X(null), p.current = new Be(V.current, I), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (B) => {
|
|
6751
|
+
if (B.lengthComputable) {
|
|
6752
|
+
const J = Math.min(100, Math.round(B.loaded / B.total * 100));
|
|
6753
|
+
d(J);
|
|
6968
6754
|
}
|
|
6969
|
-
}), await new Promise((
|
|
6755
|
+
}), await new Promise((B) => {
|
|
6970
6756
|
const J = () => {
|
|
6971
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6757
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
|
|
6972
6758
|
};
|
|
6973
6759
|
J();
|
|
6974
6760
|
}), p.current && p.current.setShowFullAvatar)
|
|
6975
6761
|
try {
|
|
6976
6762
|
p.current.setShowFullAvatar(r);
|
|
6977
|
-
} catch (
|
|
6978
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6763
|
+
} catch (B) {
|
|
6764
|
+
console.warn("Error setting full body mode on initialization:", B);
|
|
6979
6765
|
}
|
|
6980
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()),
|
|
6981
|
-
const
|
|
6766
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), Z(!1), se(!0), a(p.current);
|
|
6767
|
+
const F = () => {
|
|
6982
6768
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6983
6769
|
};
|
|
6984
|
-
return document.addEventListener("visibilitychange",
|
|
6985
|
-
document.removeEventListener("visibilitychange",
|
|
6770
|
+
return document.addEventListener("visibilitychange", F), () => {
|
|
6771
|
+
document.removeEventListener("visibilitychange", F);
|
|
6986
6772
|
};
|
|
6987
6773
|
} catch (L) {
|
|
6988
|
-
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"),
|
|
6774
|
+
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), c(L);
|
|
6989
6775
|
}
|
|
6990
|
-
}, [
|
|
6991
|
-
de(() => (
|
|
6776
|
+
}, [G, t, e, n, i, s, o, r, l, h, u]);
|
|
6777
|
+
de(() => (k(), () => {
|
|
6992
6778
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6993
|
-
}), [
|
|
6994
|
-
if (!
|
|
6995
|
-
const L = new ResizeObserver((
|
|
6996
|
-
for (const J of
|
|
6779
|
+
}), [k]), de(() => {
|
|
6780
|
+
if (!V.current || !p.current) return;
|
|
6781
|
+
const L = new ResizeObserver((B) => {
|
|
6782
|
+
for (const J of B)
|
|
6997
6783
|
p.current && p.current.onResize && p.current.onResize();
|
|
6998
6784
|
});
|
|
6999
|
-
L.observe(
|
|
7000
|
-
const
|
|
6785
|
+
L.observe(V.current);
|
|
6786
|
+
const F = () => {
|
|
7001
6787
|
p.current && p.current.onResize && p.current.onResize();
|
|
7002
6788
|
};
|
|
7003
|
-
return window.addEventListener("resize",
|
|
7004
|
-
L.disconnect(), window.removeEventListener("resize",
|
|
6789
|
+
return window.addEventListener("resize", F), () => {
|
|
6790
|
+
L.disconnect(), window.removeEventListener("resize", F);
|
|
7005
6791
|
};
|
|
7006
6792
|
}, [$]);
|
|
7007
|
-
const
|
|
6793
|
+
const H = T(async () => {
|
|
7008
6794
|
if (p.current && p.current.audioCtx)
|
|
7009
6795
|
try {
|
|
7010
6796
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
7011
6797
|
} catch (L) {
|
|
7012
6798
|
console.warn("Failed to resume audio context:", L);
|
|
7013
6799
|
}
|
|
7014
|
-
}, []),
|
|
6800
|
+
}, []), N = T(async (L, F = {}) => {
|
|
7015
6801
|
if (p.current && $)
|
|
7016
6802
|
try {
|
|
7017
|
-
|
|
7018
|
-
const
|
|
7019
|
-
|
|
6803
|
+
f.current && (clearInterval(f.current), f.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
|
|
6804
|
+
const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
|
|
6805
|
+
U.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
|
|
7020
6806
|
const ge = {
|
|
7021
|
-
...
|
|
7022
|
-
lipsyncLang:
|
|
6807
|
+
...F,
|
|
6808
|
+
lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
|
|
7023
6809
|
};
|
|
7024
|
-
if (
|
|
6810
|
+
if (F.onSpeechEnd && p.current) {
|
|
7025
6811
|
const Y = p.current;
|
|
7026
|
-
let
|
|
6812
|
+
let he = null, Se = 0;
|
|
7027
6813
|
const Ae = 1200;
|
|
7028
6814
|
let be = !1;
|
|
7029
|
-
|
|
7030
|
-
if (Se++,
|
|
6815
|
+
he = setInterval(() => {
|
|
6816
|
+
if (Se++, E.current)
|
|
7031
6817
|
return;
|
|
7032
6818
|
if (Se > Ae) {
|
|
7033
|
-
if (
|
|
6819
|
+
if (he && (clearInterval(he), he = null, f.current = null), !be && !E.current) {
|
|
7034
6820
|
be = !0;
|
|
7035
6821
|
try {
|
|
7036
|
-
|
|
6822
|
+
F.onSpeechEnd();
|
|
7037
6823
|
} catch (De) {
|
|
7038
6824
|
console.error("Error in onSpeechEnd callback (timeout):", De);
|
|
7039
6825
|
}
|
|
@@ -7041,83 +6827,83 @@ const Ve = Me(({
|
|
|
7041
6827
|
return;
|
|
7042
6828
|
}
|
|
7043
6829
|
const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
|
|
7044
|
-
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !
|
|
7045
|
-
if (Y && !
|
|
7046
|
-
be = !0,
|
|
6830
|
+
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
|
|
6831
|
+
if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
|
|
6832
|
+
be = !0, he && (clearInterval(he), he = null, f.current = null);
|
|
7047
6833
|
try {
|
|
7048
|
-
|
|
6834
|
+
F.onSpeechEnd();
|
|
7049
6835
|
} catch (Ze) {
|
|
7050
6836
|
console.error("Error in onSpeechEnd callback:", Ze);
|
|
7051
6837
|
}
|
|
7052
6838
|
}
|
|
7053
6839
|
}, 100);
|
|
7054
|
-
}, 100),
|
|
6840
|
+
}, 100), f.current = he;
|
|
7055
6841
|
}
|
|
7056
6842
|
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
|
|
7057
|
-
await
|
|
6843
|
+
await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
|
|
7058
6844
|
}, 100);
|
|
7059
|
-
} catch (
|
|
7060
|
-
console.error("Error speaking text:",
|
|
6845
|
+
} catch (B) {
|
|
6846
|
+
console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
|
|
7061
6847
|
}
|
|
7062
|
-
}, [$,
|
|
7063
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
7064
|
-
}, []), j =
|
|
6848
|
+
}, [$, H, v.lipsyncLang]), _ = T(() => {
|
|
6849
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
|
|
6850
|
+
}, []), j = T(() => {
|
|
7065
6851
|
if (p.current && p.current.pauseSpeaking) {
|
|
7066
6852
|
const L = p.current;
|
|
7067
6853
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
7068
|
-
|
|
7069
|
-
let
|
|
7070
|
-
if (
|
|
7071
|
-
const J =
|
|
7072
|
-
if (
|
|
6854
|
+
f.current && (clearInterval(f.current), f.current = null);
|
|
6855
|
+
let B = "";
|
|
6856
|
+
if (z.current && U.current.length > 0) {
|
|
6857
|
+
const J = U.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), Se = J - he;
|
|
6858
|
+
if (he > 0 && Se < J && (B = U.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
|
|
7073
6859
|
const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
|
|
7074
|
-
be && be.trim() && (
|
|
6860
|
+
be && be.trim() && (B = be.trim());
|
|
7075
6861
|
}
|
|
7076
6862
|
}
|
|
7077
|
-
|
|
7078
|
-
remainingText:
|
|
7079
|
-
originalText:
|
|
7080
|
-
options:
|
|
7081
|
-
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(),
|
|
6863
|
+
z.current && (P.current = {
|
|
6864
|
+
remainingText: B || null,
|
|
6865
|
+
originalText: z.current.text,
|
|
6866
|
+
options: z.current.options
|
|
6867
|
+
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
|
|
7082
6868
|
}
|
|
7083
6869
|
}
|
|
7084
|
-
}, []), q =
|
|
6870
|
+
}, []), q = T(async () => {
|
|
7085
6871
|
if (!p.current || !ae)
|
|
7086
6872
|
return;
|
|
7087
|
-
let L = "",
|
|
7088
|
-
if (
|
|
7089
|
-
L =
|
|
7090
|
-
else if (
|
|
7091
|
-
L =
|
|
6873
|
+
let L = "", F = {};
|
|
6874
|
+
if (P.current && P.current.remainingText)
|
|
6875
|
+
L = P.current.remainingText, F = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
|
|
6876
|
+
else if (z.current && z.current.text)
|
|
6877
|
+
L = z.current.text, F = z.current.options || {};
|
|
7092
6878
|
else {
|
|
7093
|
-
console.warn("Resume called but no paused speech found"), pe(!1),
|
|
6879
|
+
console.warn("Resume called but no paused speech found"), pe(!1), E.current = !1;
|
|
7094
6880
|
return;
|
|
7095
6881
|
}
|
|
7096
|
-
pe(!1),
|
|
7097
|
-
const
|
|
7098
|
-
...
|
|
7099
|
-
lipsyncLang:
|
|
6882
|
+
pe(!1), E.current = !1, await H();
|
|
6883
|
+
const B = {
|
|
6884
|
+
...F,
|
|
6885
|
+
lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
|
|
7100
6886
|
};
|
|
7101
6887
|
try {
|
|
7102
|
-
await
|
|
6888
|
+
await N(L, B);
|
|
7103
6889
|
} catch (J) {
|
|
7104
|
-
console.error("Error resuming speech:", J), pe(!1),
|
|
6890
|
+
console.error("Error resuming speech:", J), pe(!1), E.current = !1;
|
|
7105
6891
|
}
|
|
7106
|
-
}, [
|
|
6892
|
+
}, [H, ae, N, v]), Le = T((L) => {
|
|
7107
6893
|
p.current && p.current.setMood(L);
|
|
7108
|
-
}, []), we =
|
|
6894
|
+
}, []), we = T((L) => {
|
|
7109
6895
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
7110
|
-
}, []), C =
|
|
6896
|
+
}, []), C = T((L, F = !1) => {
|
|
7111
6897
|
if (p.current && p.current.playAnimation) {
|
|
7112
|
-
if (
|
|
6898
|
+
if (b && b[L] && (L = b[L]), p.current.setShowFullAvatar)
|
|
7113
6899
|
try {
|
|
7114
|
-
p.current.setShowFullAvatar(
|
|
6900
|
+
p.current.setShowFullAvatar(M.current);
|
|
7115
6901
|
} catch (J) {
|
|
7116
6902
|
console.warn("Error setting full body mode:", J);
|
|
7117
6903
|
}
|
|
7118
6904
|
if (L.includes("."))
|
|
7119
6905
|
try {
|
|
7120
|
-
p.current.playAnimation(L, null, 10, 0, 0.01,
|
|
6906
|
+
p.current.playAnimation(L, null, 10, 0, 0.01, F);
|
|
7121
6907
|
} catch (J) {
|
|
7122
6908
|
console.warn(`Failed to play ${L}:`, J);
|
|
7123
6909
|
try {
|
|
@@ -7131,7 +6917,7 @@ const Ve = Me(({
|
|
|
7131
6917
|
let ge = !1;
|
|
7132
6918
|
for (const Y of J)
|
|
7133
6919
|
try {
|
|
7134
|
-
p.current.playAnimation(L + Y, null, 10, 0, 0.01,
|
|
6920
|
+
p.current.playAnimation(L + Y, null, 10, 0, 0.01, F), ge = !0;
|
|
7135
6921
|
break;
|
|
7136
6922
|
} catch {
|
|
7137
6923
|
}
|
|
@@ -7145,35 +6931,35 @@ const Ve = Me(({
|
|
|
7145
6931
|
}
|
|
7146
6932
|
}
|
|
7147
6933
|
}
|
|
7148
|
-
}, [
|
|
6934
|
+
}, [b]), te = T(() => {
|
|
7149
6935
|
p.current && p.current.onResize && p.current.onResize();
|
|
7150
6936
|
}, []);
|
|
7151
6937
|
return Ee(R, () => ({
|
|
7152
|
-
speakText:
|
|
7153
|
-
stopSpeaking:
|
|
6938
|
+
speakText: N,
|
|
6939
|
+
stopSpeaking: _,
|
|
7154
6940
|
pauseSpeaking: j,
|
|
7155
6941
|
resumeSpeaking: q,
|
|
7156
|
-
resumeAudioContext:
|
|
6942
|
+
resumeAudioContext: H,
|
|
7157
6943
|
setMood: Le,
|
|
7158
6944
|
setTimingAdjustment: we,
|
|
7159
6945
|
playAnimation: C,
|
|
7160
6946
|
isReady: $,
|
|
7161
6947
|
isPaused: ae,
|
|
7162
6948
|
talkingHead: p.current,
|
|
7163
|
-
handleResize:
|
|
6949
|
+
handleResize: te,
|
|
7164
6950
|
setBodyMovement: (L) => {
|
|
7165
6951
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
7166
6952
|
try {
|
|
7167
|
-
p.current.setShowFullAvatar(
|
|
7168
|
-
} catch (
|
|
7169
|
-
console.warn("Error setting body movement:",
|
|
6953
|
+
p.current.setShowFullAvatar(M.current), p.current.setBodyMovement(L);
|
|
6954
|
+
} catch (F) {
|
|
6955
|
+
console.warn("Error setting body movement:", F);
|
|
7170
6956
|
}
|
|
7171
6957
|
},
|
|
7172
6958
|
setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
|
|
7173
6959
|
playRandomDance: () => {
|
|
7174
6960
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
7175
6961
|
try {
|
|
7176
|
-
p.current.setShowFullAvatar(
|
|
6962
|
+
p.current.setShowFullAvatar(M.current), p.current.playRandomDance();
|
|
7177
6963
|
} catch (L) {
|
|
7178
6964
|
console.warn("Error playing random dance:", L);
|
|
7179
6965
|
}
|
|
@@ -7181,15 +6967,15 @@ const Ve = Me(({
|
|
|
7181
6967
|
playReaction: (L) => {
|
|
7182
6968
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
7183
6969
|
try {
|
|
7184
|
-
p.current.setShowFullAvatar(
|
|
7185
|
-
} catch (
|
|
7186
|
-
console.warn("Error playing reaction:",
|
|
6970
|
+
p.current.setShowFullAvatar(M.current), p.current.playReaction(L);
|
|
6971
|
+
} catch (F) {
|
|
6972
|
+
console.warn("Error playing reaction:", F);
|
|
7187
6973
|
}
|
|
7188
6974
|
},
|
|
7189
6975
|
playCelebration: () => {
|
|
7190
6976
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
7191
6977
|
try {
|
|
7192
|
-
p.current.setShowFullAvatar(
|
|
6978
|
+
p.current.setShowFullAvatar(M.current), p.current.playCelebration();
|
|
7193
6979
|
} catch (L) {
|
|
7194
6980
|
console.warn("Error playing celebration:", L);
|
|
7195
6981
|
}
|
|
@@ -7197,9 +6983,9 @@ const Ve = Me(({
|
|
|
7197
6983
|
setShowFullAvatar: (L) => {
|
|
7198
6984
|
if (p.current && p.current.setShowFullAvatar)
|
|
7199
6985
|
try {
|
|
7200
|
-
|
|
7201
|
-
} catch (
|
|
7202
|
-
console.warn("Error setting showFullAvatar:",
|
|
6986
|
+
M.current = L, p.current.setShowFullAvatar(L);
|
|
6987
|
+
} catch (F) {
|
|
6988
|
+
console.warn("Error setting showFullAvatar:", F);
|
|
7203
6989
|
}
|
|
7204
6990
|
},
|
|
7205
6991
|
lockAvatarPosition: () => {
|
|
@@ -7226,13 +7012,13 @@ const Ve = Me(({
|
|
|
7226
7012
|
width: "100%",
|
|
7227
7013
|
height: "100%",
|
|
7228
7014
|
position: "relative",
|
|
7229
|
-
...
|
|
7015
|
+
...y
|
|
7230
7016
|
},
|
|
7231
7017
|
children: [
|
|
7232
7018
|
/* @__PURE__ */ me(
|
|
7233
7019
|
"div",
|
|
7234
7020
|
{
|
|
7235
|
-
ref:
|
|
7021
|
+
ref: V,
|
|
7236
7022
|
className: "talking-head-viewer",
|
|
7237
7023
|
style: {
|
|
7238
7024
|
width: "100%",
|
|
@@ -7250,7 +7036,7 @@ const Ve = Me(({
|
|
|
7250
7036
|
fontSize: "18px",
|
|
7251
7037
|
zIndex: 10
|
|
7252
7038
|
}, children: "Loading avatar..." }),
|
|
7253
|
-
|
|
7039
|
+
K && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7254
7040
|
position: "absolute",
|
|
7255
7041
|
top: "50%",
|
|
7256
7042
|
left: "50%",
|
|
@@ -7261,14 +7047,14 @@ const Ve = Me(({
|
|
|
7261
7047
|
zIndex: 10,
|
|
7262
7048
|
padding: "20px",
|
|
7263
7049
|
borderRadius: "8px"
|
|
7264
|
-
}, children:
|
|
7050
|
+
}, children: K })
|
|
7265
7051
|
]
|
|
7266
7052
|
}
|
|
7267
7053
|
);
|
|
7268
7054
|
});
|
|
7269
7055
|
Ve.displayName = "TalkingHeadAvatar";
|
|
7270
7056
|
const pt = Me(({
|
|
7271
|
-
text:
|
|
7057
|
+
text: G = "Hello! I'm a talking avatar. How are you today?",
|
|
7272
7058
|
onLoading: t = () => {
|
|
7273
7059
|
},
|
|
7274
7060
|
onError: e = () => {
|
|
@@ -7279,23 +7065,23 @@ const pt = Me(({
|
|
|
7279
7065
|
style: s = {},
|
|
7280
7066
|
avatarConfig: o = {}
|
|
7281
7067
|
}, l) => {
|
|
7282
|
-
const
|
|
7068
|
+
const h = D(null), r = D(null), [u, a] = ce(!0), [d, c] = ce(null), [g, y] = ce(!1), b = Fe(), R = o.ttsService || b.service, V = R === "browser" ? {
|
|
7283
7069
|
endpoint: "",
|
|
7284
7070
|
apiKey: null,
|
|
7285
7071
|
defaultVoice: "Google US English"
|
|
7286
7072
|
} : {
|
|
7287
|
-
...
|
|
7073
|
+
...b,
|
|
7288
7074
|
// Override API key if provided via avatarConfig
|
|
7289
|
-
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey :
|
|
7075
|
+
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
|
|
7290
7076
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7291
|
-
endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" :
|
|
7077
|
+
endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
|
|
7292
7078
|
}, p = {
|
|
7293
7079
|
url: "/avatars/brunette.glb",
|
|
7294
7080
|
// Use brunette avatar (working glTF file)
|
|
7295
7081
|
body: "F",
|
|
7296
7082
|
avatarMood: "neutral",
|
|
7297
7083
|
ttsLang: R === "browser" ? "en-US" : "en",
|
|
7298
|
-
ttsVoice: o.ttsVoice ||
|
|
7084
|
+
ttsVoice: o.ttsVoice || V.defaultVoice,
|
|
7299
7085
|
lipsyncLang: "en",
|
|
7300
7086
|
// English lip-sync
|
|
7301
7087
|
showFullAvatar: !0,
|
|
@@ -7303,69 +7089,69 @@ const pt = Me(({
|
|
|
7303
7089
|
bodyMovement: "idle",
|
|
7304
7090
|
movementIntensity: 0.5,
|
|
7305
7091
|
...o
|
|
7306
|
-
},
|
|
7307
|
-
ttsEndpoint:
|
|
7308
|
-
ttsApikey:
|
|
7092
|
+
}, M = {
|
|
7093
|
+
ttsEndpoint: V.endpoint,
|
|
7094
|
+
ttsApikey: V.apiKey,
|
|
7309
7095
|
ttsService: R,
|
|
7310
7096
|
lipsyncModules: ["en"],
|
|
7311
7097
|
cameraView: "upper"
|
|
7312
|
-
},
|
|
7313
|
-
if (!(!
|
|
7098
|
+
}, z = T(async () => {
|
|
7099
|
+
if (!(!h.current || r.current))
|
|
7314
7100
|
try {
|
|
7315
|
-
if (a(!0),
|
|
7316
|
-
if (
|
|
7317
|
-
const X = Math.min(100, Math.round(
|
|
7101
|
+
if (a(!0), c(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
|
|
7102
|
+
if (K.lengthComputable) {
|
|
7103
|
+
const X = Math.min(100, Math.round(K.loaded / K.total * 100));
|
|
7318
7104
|
t(X);
|
|
7319
7105
|
}
|
|
7320
7106
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7321
|
-
const
|
|
7322
|
-
console.log("Available morph targets:", Object.keys(
|
|
7323
|
-
const X = Object.keys(
|
|
7107
|
+
const K = r.current.morphs[0].morphTargetDictionary;
|
|
7108
|
+
console.log("Available morph targets:", Object.keys(K));
|
|
7109
|
+
const X = Object.keys(K).filter(($) => $.startsWith("viseme_"));
|
|
7324
7110
|
console.log("Viseme morph targets found:", X), X.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"));
|
|
7325
7111
|
}
|
|
7326
|
-
if (await new Promise((
|
|
7112
|
+
if (await new Promise((K) => {
|
|
7327
7113
|
const X = () => {
|
|
7328
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7114
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), K()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
|
|
7329
7115
|
};
|
|
7330
7116
|
X();
|
|
7331
7117
|
}), r.current && r.current.setShowFullAvatar)
|
|
7332
7118
|
try {
|
|
7333
7119
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7334
|
-
} catch (
|
|
7335
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7120
|
+
} catch (K) {
|
|
7121
|
+
console.warn("Error setting full body mode on initialization:", K);
|
|
7336
7122
|
}
|
|
7337
|
-
a(!1),
|
|
7338
|
-
const
|
|
7123
|
+
a(!1), y(!0), n(r.current);
|
|
7124
|
+
const Z = () => {
|
|
7339
7125
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7340
7126
|
};
|
|
7341
|
-
return document.addEventListener("visibilitychange",
|
|
7342
|
-
document.removeEventListener("visibilitychange",
|
|
7127
|
+
return document.addEventListener("visibilitychange", Z), () => {
|
|
7128
|
+
document.removeEventListener("visibilitychange", Z);
|
|
7343
7129
|
};
|
|
7344
7130
|
} catch (S) {
|
|
7345
|
-
console.error("Error initializing TalkingHead:", S),
|
|
7131
|
+
console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7346
7132
|
}
|
|
7347
7133
|
}, []);
|
|
7348
|
-
de(() => (
|
|
7134
|
+
de(() => (z(), () => {
|
|
7349
7135
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7350
|
-
}), [
|
|
7351
|
-
const
|
|
7136
|
+
}), [z]);
|
|
7137
|
+
const f = T((S) => {
|
|
7352
7138
|
if (r.current && g)
|
|
7353
7139
|
try {
|
|
7354
7140
|
console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7355
7141
|
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
|
|
7356
7142
|
}, 500));
|
|
7357
|
-
} catch (
|
|
7358
|
-
console.error("Error speaking text:",
|
|
7143
|
+
} catch (Z) {
|
|
7144
|
+
console.error("Error speaking text:", Z), c(Z.message || "Failed to speak text");
|
|
7359
7145
|
}
|
|
7360
7146
|
else
|
|
7361
7147
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7362
|
-
}, [g, p]),
|
|
7148
|
+
}, [g, p]), E = T(() => {
|
|
7363
7149
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7364
|
-
}, []),
|
|
7150
|
+
}, []), P = T((S) => {
|
|
7365
7151
|
r.current && r.current.setMood(S);
|
|
7366
|
-
}, []),
|
|
7152
|
+
}, []), U = T((S) => {
|
|
7367
7153
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
7368
|
-
}, []),
|
|
7154
|
+
}, []), oe = T((S, Z = !1) => {
|
|
7369
7155
|
if (r.current && r.current.playAnimation) {
|
|
7370
7156
|
if (r.current.setShowFullAvatar)
|
|
7371
7157
|
try {
|
|
@@ -7375,7 +7161,7 @@ const pt = Me(({
|
|
|
7375
7161
|
}
|
|
7376
7162
|
if (S.includes("."))
|
|
7377
7163
|
try {
|
|
7378
|
-
r.current.playAnimation(S, null, 10, 0, 0.01,
|
|
7164
|
+
r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
|
|
7379
7165
|
} catch (X) {
|
|
7380
7166
|
console.log(`Failed to play ${S}:`, X);
|
|
7381
7167
|
try {
|
|
@@ -7389,7 +7175,7 @@ const pt = Me(({
|
|
|
7389
7175
|
let $ = !1;
|
|
7390
7176
|
for (const se of X)
|
|
7391
7177
|
try {
|
|
7392
|
-
r.current.playAnimation(S + se, null, 10, 0, 0.01,
|
|
7178
|
+
r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
|
|
7393
7179
|
break;
|
|
7394
7180
|
} catch {
|
|
7395
7181
|
console.log(`Failed to play ${S}${se}, trying next format...`);
|
|
@@ -7407,19 +7193,19 @@ const pt = Me(({
|
|
|
7407
7193
|
console.warn("Animation system not available or animation not found:", S);
|
|
7408
7194
|
}, []);
|
|
7409
7195
|
return Ee(l, () => ({
|
|
7410
|
-
speakText:
|
|
7411
|
-
stopSpeaking:
|
|
7412
|
-
setMood:
|
|
7413
|
-
setTimingAdjustment:
|
|
7414
|
-
playAnimation:
|
|
7196
|
+
speakText: f,
|
|
7197
|
+
stopSpeaking: E,
|
|
7198
|
+
setMood: P,
|
|
7199
|
+
setTimingAdjustment: U,
|
|
7200
|
+
playAnimation: oe,
|
|
7415
7201
|
isReady: g,
|
|
7416
7202
|
talkingHead: r.current,
|
|
7417
7203
|
setBodyMovement: (S) => {
|
|
7418
7204
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7419
7205
|
try {
|
|
7420
7206
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
|
|
7421
|
-
} catch (
|
|
7422
|
-
console.warn("Error setting body movement:",
|
|
7207
|
+
} catch (Z) {
|
|
7208
|
+
console.warn("Error setting body movement:", Z);
|
|
7423
7209
|
}
|
|
7424
7210
|
},
|
|
7425
7211
|
setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
|
|
@@ -7435,8 +7221,8 @@ const pt = Me(({
|
|
|
7435
7221
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7436
7222
|
try {
|
|
7437
7223
|
r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
|
|
7438
|
-
} catch (
|
|
7439
|
-
console.warn("Error playing reaction:",
|
|
7224
|
+
} catch (Z) {
|
|
7225
|
+
console.warn("Error playing reaction:", Z);
|
|
7440
7226
|
}
|
|
7441
7227
|
},
|
|
7442
7228
|
playCelebration: () => {
|
|
@@ -7451,8 +7237,8 @@ const pt = Me(({
|
|
|
7451
7237
|
if (r.current && r.current.setShowFullAvatar)
|
|
7452
7238
|
try {
|
|
7453
7239
|
r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
|
|
7454
|
-
} catch (
|
|
7455
|
-
console.warn("Error setting showFullAvatar:",
|
|
7240
|
+
} catch (Z) {
|
|
7241
|
+
console.warn("Error setting showFullAvatar:", Z);
|
|
7456
7242
|
}
|
|
7457
7243
|
},
|
|
7458
7244
|
lockAvatarPosition: () => {
|
|
@@ -7475,7 +7261,7 @@ const pt = Me(({
|
|
|
7475
7261
|
/* @__PURE__ */ me(
|
|
7476
7262
|
"div",
|
|
7477
7263
|
{
|
|
7478
|
-
ref:
|
|
7264
|
+
ref: h,
|
|
7479
7265
|
className: "talking-head-viewer",
|
|
7480
7266
|
style: {
|
|
7481
7267
|
width: "100%",
|
|
@@ -7484,7 +7270,7 @@ const pt = Me(({
|
|
|
7484
7270
|
}
|
|
7485
7271
|
}
|
|
7486
7272
|
),
|
|
7487
|
-
|
|
7273
|
+
u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7488
7274
|
position: "absolute",
|
|
7489
7275
|
top: "50%",
|
|
7490
7276
|
left: "50%",
|
|
@@ -7493,7 +7279,7 @@ const pt = Me(({
|
|
|
7493
7279
|
fontSize: "18px",
|
|
7494
7280
|
zIndex: 10
|
|
7495
7281
|
}, children: "Loading avatar..." }),
|
|
7496
|
-
|
|
7282
|
+
d && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7497
7283
|
position: "absolute",
|
|
7498
7284
|
top: "50%",
|
|
7499
7285
|
left: "50%",
|
|
@@ -7504,12 +7290,12 @@ const pt = Me(({
|
|
|
7504
7290
|
zIndex: 10,
|
|
7505
7291
|
padding: "20px",
|
|
7506
7292
|
borderRadius: "8px"
|
|
7507
|
-
}, children:
|
|
7293
|
+
}, children: d })
|
|
7508
7294
|
] });
|
|
7509
7295
|
});
|
|
7510
7296
|
pt.displayName = "TalkingHeadComponent";
|
|
7511
7297
|
const gt = Me(({
|
|
7512
|
-
text:
|
|
7298
|
+
text: G = null,
|
|
7513
7299
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7514
7300
|
avatarBody: e = "F",
|
|
7515
7301
|
mood: n = "neutral",
|
|
@@ -7517,30 +7303,30 @@ const gt = Me(({
|
|
|
7517
7303
|
ttsService: s = null,
|
|
7518
7304
|
ttsVoice: o = null,
|
|
7519
7305
|
ttsApiKey: l = null,
|
|
7520
|
-
bodyMovement:
|
|
7306
|
+
bodyMovement: h = "idle",
|
|
7521
7307
|
movementIntensity: r = 0.5,
|
|
7522
|
-
showFullAvatar:
|
|
7308
|
+
showFullAvatar: u = !1,
|
|
7523
7309
|
cameraView: a = "upper",
|
|
7524
|
-
onReady:
|
|
7310
|
+
onReady: d = () => {
|
|
7525
7311
|
},
|
|
7526
|
-
onLoading:
|
|
7312
|
+
onLoading: c = () => {
|
|
7527
7313
|
},
|
|
7528
7314
|
onError: g = () => {
|
|
7529
7315
|
},
|
|
7530
|
-
onSpeechEnd:
|
|
7316
|
+
onSpeechEnd: y = () => {
|
|
7531
7317
|
},
|
|
7532
|
-
className:
|
|
7318
|
+
className: b = "",
|
|
7533
7319
|
style: R = {},
|
|
7534
|
-
animations:
|
|
7320
|
+
animations: V = {},
|
|
7535
7321
|
autoSpeak: p = !1
|
|
7536
|
-
},
|
|
7537
|
-
const
|
|
7322
|
+
}, M) => {
|
|
7323
|
+
const z = D(null), f = D(null), E = D(u), P = D(null), U = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
|
|
7538
7324
|
de(() => {
|
|
7539
|
-
|
|
7325
|
+
oe.current = ee;
|
|
7540
7326
|
}, [ee]), de(() => {
|
|
7541
|
-
|
|
7542
|
-
}, [
|
|
7543
|
-
const
|
|
7327
|
+
E.current = u;
|
|
7328
|
+
}, [u]);
|
|
7329
|
+
const O = Fe(), v = s || O.service;
|
|
7544
7330
|
let I;
|
|
7545
7331
|
v === "browser" ? I = {
|
|
7546
7332
|
service: "browser",
|
|
@@ -7550,50 +7336,50 @@ const gt = Me(({
|
|
|
7550
7336
|
} : v === "elevenlabs" ? I = {
|
|
7551
7337
|
service: "elevenlabs",
|
|
7552
7338
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7553
|
-
apiKey: l ||
|
|
7554
|
-
defaultVoice: o ||
|
|
7555
|
-
voices:
|
|
7339
|
+
apiKey: l || O.apiKey,
|
|
7340
|
+
defaultVoice: o || O.defaultVoice || Re.defaultVoice,
|
|
7341
|
+
voices: O.voices || Re.voices
|
|
7556
7342
|
} : v === "deepgram" ? I = {
|
|
7557
7343
|
service: "deepgram",
|
|
7558
7344
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7559
|
-
apiKey: l ||
|
|
7560
|
-
defaultVoice: o ||
|
|
7561
|
-
voices:
|
|
7345
|
+
apiKey: l || O.apiKey,
|
|
7346
|
+
defaultVoice: o || O.defaultVoice || Te.defaultVoice,
|
|
7347
|
+
voices: O.voices || Te.voices
|
|
7562
7348
|
} : I = {
|
|
7563
|
-
...
|
|
7564
|
-
apiKey: l !== null ? l :
|
|
7349
|
+
...O,
|
|
7350
|
+
apiKey: l !== null ? l : O.apiKey
|
|
7565
7351
|
};
|
|
7566
|
-
const
|
|
7352
|
+
const k = {
|
|
7567
7353
|
url: t,
|
|
7568
7354
|
body: e,
|
|
7569
7355
|
avatarMood: n,
|
|
7570
7356
|
ttsLang: v === "browser" ? "en-US" : i,
|
|
7571
7357
|
ttsVoice: o || I.defaultVoice,
|
|
7572
7358
|
lipsyncLang: "en",
|
|
7573
|
-
showFullAvatar:
|
|
7574
|
-
bodyMovement:
|
|
7359
|
+
showFullAvatar: u,
|
|
7360
|
+
bodyMovement: h,
|
|
7575
7361
|
movementIntensity: r
|
|
7576
|
-
},
|
|
7362
|
+
}, H = {
|
|
7577
7363
|
ttsEndpoint: I.endpoint,
|
|
7578
7364
|
ttsApikey: I.apiKey,
|
|
7579
7365
|
ttsService: v,
|
|
7580
7366
|
lipsyncModules: ["en"],
|
|
7581
7367
|
cameraView: a
|
|
7582
|
-
},
|
|
7583
|
-
if (!(!
|
|
7368
|
+
}, N = T(async () => {
|
|
7369
|
+
if (!(!z.current || f.current))
|
|
7584
7370
|
try {
|
|
7585
|
-
X(!0), se(null),
|
|
7586
|
-
url:
|
|
7587
|
-
body:
|
|
7588
|
-
avatarMood:
|
|
7589
|
-
}), await
|
|
7590
|
-
if (
|
|
7591
|
-
const L = Math.min(100, Math.round(
|
|
7592
|
-
|
|
7371
|
+
X(!0), se(null), f.current = new Be(z.current, H), console.log("Avatar config being passed:", {
|
|
7372
|
+
url: k.url,
|
|
7373
|
+
body: k.body,
|
|
7374
|
+
avatarMood: k.avatarMood
|
|
7375
|
+
}), await f.current.showAvatar(k, (te) => {
|
|
7376
|
+
if (te.lengthComputable) {
|
|
7377
|
+
const L = Math.min(100, Math.round(te.loaded / te.total * 100));
|
|
7378
|
+
c(L);
|
|
7593
7379
|
}
|
|
7594
|
-
}),
|
|
7380
|
+
}), f.current?.avatar && console.log("Avatar body after initialization:", f.current.avatar.body), X(!1), pe(!0), d(f.current);
|
|
7595
7381
|
const C = () => {
|
|
7596
|
-
document.visibilityState === "visible" ?
|
|
7382
|
+
document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
|
|
7597
7383
|
};
|
|
7598
7384
|
return document.addEventListener("visibilitychange", C), () => {
|
|
7599
7385
|
document.removeEventListener("visibilitychange", C);
|
|
@@ -7602,19 +7388,19 @@ const gt = Me(({
|
|
|
7602
7388
|
console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
|
|
7603
7389
|
}
|
|
7604
7390
|
}, []);
|
|
7605
|
-
de(() => (
|
|
7606
|
-
|
|
7607
|
-
}), [
|
|
7608
|
-
const
|
|
7609
|
-
if (
|
|
7391
|
+
de(() => (N(), () => {
|
|
7392
|
+
f.current && (f.current.stop(), f.current.dispose(), f.current = null);
|
|
7393
|
+
}), [N]);
|
|
7394
|
+
const _ = T(async () => {
|
|
7395
|
+
if (f.current)
|
|
7610
7396
|
try {
|
|
7611
|
-
const C =
|
|
7397
|
+
const C = f.current.audioCtx || f.current.audioContext;
|
|
7612
7398
|
C && (C.state === "suspended" || C.state === "interrupted") && (await C.resume(), console.log("Audio context resumed"));
|
|
7613
7399
|
} catch (C) {
|
|
7614
7400
|
console.warn("Failed to resume audio context:", C);
|
|
7615
7401
|
}
|
|
7616
|
-
}, []), j =
|
|
7617
|
-
if (!
|
|
7402
|
+
}, []), j = T(async (C, te = {}) => {
|
|
7403
|
+
if (!f.current || !ae) {
|
|
7618
7404
|
console.warn("Avatar not ready for speaking");
|
|
7619
7405
|
return;
|
|
7620
7406
|
}
|
|
@@ -7622,78 +7408,78 @@ const gt = Me(({
|
|
|
7622
7408
|
console.warn("No text provided to speak");
|
|
7623
7409
|
return;
|
|
7624
7410
|
}
|
|
7625
|
-
await
|
|
7626
|
-
const L = C.split(/[.!?]+/).filter((
|
|
7627
|
-
|
|
7628
|
-
const
|
|
7629
|
-
lipsyncLang:
|
|
7411
|
+
await _(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1;
|
|
7412
|
+
const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
|
|
7413
|
+
Z.current = L;
|
|
7414
|
+
const F = {
|
|
7415
|
+
lipsyncLang: te.lipsyncLang || "en",
|
|
7630
7416
|
onSpeechEnd: () => {
|
|
7631
|
-
|
|
7417
|
+
U.current && (clearInterval(U.current), U.current = null), te.onSpeechEnd && te.onSpeechEnd(), y();
|
|
7632
7418
|
}
|
|
7633
7419
|
};
|
|
7634
7420
|
try {
|
|
7635
|
-
|
|
7636
|
-
} catch (
|
|
7637
|
-
console.error("Error speaking text:",
|
|
7421
|
+
f.current.speakText(C, F);
|
|
7422
|
+
} catch (B) {
|
|
7423
|
+
console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
|
|
7638
7424
|
}
|
|
7639
|
-
}, [ae,
|
|
7425
|
+
}, [ae, y, _]);
|
|
7640
7426
|
de(() => {
|
|
7641
|
-
ae &&
|
|
7642
|
-
}, [ae,
|
|
7643
|
-
const q =
|
|
7644
|
-
if (
|
|
7427
|
+
ae && G && p && f.current && j(G);
|
|
7428
|
+
}, [ae, G, p, j]);
|
|
7429
|
+
const q = T(() => {
|
|
7430
|
+
if (f.current)
|
|
7645
7431
|
try {
|
|
7646
|
-
const C =
|
|
7647
|
-
if (C ||
|
|
7648
|
-
|
|
7649
|
-
let
|
|
7650
|
-
L.length > 0 && (
|
|
7651
|
-
remainingText:
|
|
7652
|
-
originalText:
|
|
7653
|
-
options:
|
|
7654
|
-
},
|
|
7432
|
+
const C = f.current.isSpeaking || !1, te = f.current.audioPlaylist || [], L = f.current.speechQueue || [];
|
|
7433
|
+
if (C || te.length > 0 || L.length > 0) {
|
|
7434
|
+
U.current && (clearInterval(U.current), U.current = null);
|
|
7435
|
+
let F = "";
|
|
7436
|
+
L.length > 0 && (F = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map((J) => J.word).join(" ") : B.text || "").join(" ")), S.current = {
|
|
7437
|
+
remainingText: F || null,
|
|
7438
|
+
originalText: P.current?.text || null,
|
|
7439
|
+
options: P.current?.options || null
|
|
7440
|
+
}, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), le(!0), oe.current = !0;
|
|
7655
7441
|
}
|
|
7656
7442
|
} catch (C) {
|
|
7657
7443
|
console.warn("Error pausing speech:", C);
|
|
7658
7444
|
}
|
|
7659
|
-
}, []), Le =
|
|
7660
|
-
if (!(!
|
|
7445
|
+
}, []), Le = T(async () => {
|
|
7446
|
+
if (!(!f.current || !ee))
|
|
7661
7447
|
try {
|
|
7662
|
-
await
|
|
7663
|
-
const C = S.current?.remainingText,
|
|
7664
|
-
|
|
7448
|
+
await _(), le(!1), oe.current = !1;
|
|
7449
|
+
const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
|
|
7450
|
+
F && j(F, L);
|
|
7665
7451
|
} catch (C) {
|
|
7666
|
-
console.warn("Error resuming speech:", C), le(!1),
|
|
7452
|
+
console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
|
|
7667
7453
|
}
|
|
7668
|
-
}, [ee, j,
|
|
7669
|
-
|
|
7454
|
+
}, [ee, j, _]), we = T(() => {
|
|
7455
|
+
f.current && (f.current.stopSpeaking(), U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1);
|
|
7670
7456
|
}, []);
|
|
7671
|
-
return Ee(
|
|
7457
|
+
return Ee(M, () => ({
|
|
7672
7458
|
speakText: j,
|
|
7673
7459
|
pauseSpeaking: q,
|
|
7674
7460
|
resumeSpeaking: Le,
|
|
7675
7461
|
stopSpeaking: we,
|
|
7676
|
-
resumeAudioContext:
|
|
7462
|
+
resumeAudioContext: _,
|
|
7677
7463
|
isPaused: () => ee,
|
|
7678
|
-
setMood: (C) =>
|
|
7464
|
+
setMood: (C) => f.current?.setMood(C),
|
|
7679
7465
|
setBodyMovement: (C) => {
|
|
7680
|
-
|
|
7466
|
+
f.current && f.current.setBodyMovement(C);
|
|
7681
7467
|
},
|
|
7682
|
-
playAnimation: (C,
|
|
7683
|
-
|
|
7468
|
+
playAnimation: (C, te = !1) => {
|
|
7469
|
+
f.current && f.current.playAnimation && f.current.playAnimation(C, null, 10, 0, 0.01, te);
|
|
7684
7470
|
},
|
|
7685
|
-
playReaction: (C) =>
|
|
7686
|
-
playCelebration: () =>
|
|
7471
|
+
playReaction: (C) => f.current?.playReaction(C),
|
|
7472
|
+
playCelebration: () => f.current?.playCelebration(),
|
|
7687
7473
|
setShowFullAvatar: (C) => {
|
|
7688
|
-
|
|
7474
|
+
f.current && (E.current = C, f.current.setShowFullAvatar(C));
|
|
7689
7475
|
},
|
|
7690
7476
|
isReady: ae,
|
|
7691
|
-
talkingHead:
|
|
7692
|
-
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${
|
|
7477
|
+
talkingHead: f.current
|
|
7478
|
+
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: R, children: [
|
|
7693
7479
|
/* @__PURE__ */ me(
|
|
7694
7480
|
"div",
|
|
7695
7481
|
{
|
|
7696
|
-
ref:
|
|
7482
|
+
ref: z,
|
|
7697
7483
|
className: "talking-head-viewer",
|
|
7698
7484
|
style: {
|
|
7699
7485
|
width: "100%",
|
|
@@ -7702,7 +7488,7 @@ const gt = Me(({
|
|
|
7702
7488
|
}
|
|
7703
7489
|
}
|
|
7704
7490
|
),
|
|
7705
|
-
|
|
7491
|
+
K && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7706
7492
|
position: "absolute",
|
|
7707
7493
|
top: "50%",
|
|
7708
7494
|
left: "50%",
|
|
@@ -7727,7 +7513,7 @@ const gt = Me(({
|
|
|
7727
7513
|
});
|
|
7728
7514
|
gt.displayName = "SimpleTalkingAvatar";
|
|
7729
7515
|
const yt = Me(({
|
|
7730
|
-
curriculumData:
|
|
7516
|
+
curriculumData: G = null,
|
|
7731
7517
|
avatarConfig: t = {},
|
|
7732
7518
|
animations: e = {},
|
|
7733
7519
|
onLessonStart: n = () => {
|
|
@@ -7740,9 +7526,9 @@ const yt = Me(({
|
|
|
7740
7526
|
},
|
|
7741
7527
|
onCustomAction: l = () => {
|
|
7742
7528
|
},
|
|
7743
|
-
autoStart:
|
|
7529
|
+
autoStart: h = !1
|
|
7744
7530
|
}, r) => {
|
|
7745
|
-
const
|
|
7531
|
+
const u = D(null), a = D({
|
|
7746
7532
|
currentModuleIndex: 0,
|
|
7747
7533
|
currentLessonIndex: 0,
|
|
7748
7534
|
currentQuestionIndex: 0,
|
|
@@ -7752,18 +7538,18 @@ const yt = Me(({
|
|
|
7752
7538
|
curriculumCompleted: !1,
|
|
7753
7539
|
score: 0,
|
|
7754
7540
|
totalQuestions: 0
|
|
7755
|
-
}),
|
|
7541
|
+
}), d = D({
|
|
7756
7542
|
onLessonStart: n,
|
|
7757
7543
|
onLessonComplete: i,
|
|
7758
7544
|
onQuestionAnswer: s,
|
|
7759
7545
|
onCurriculumComplete: o,
|
|
7760
7546
|
onCustomAction: l
|
|
7761
|
-
}),
|
|
7547
|
+
}), c = D(null), g = D(null), y = D(null), b = D(null), R = D(null), V = D(null), p = D(null), M = D(G?.curriculum || {
|
|
7762
7548
|
title: "Default Curriculum",
|
|
7763
7549
|
description: "No curriculum data provided",
|
|
7764
7550
|
language: "en",
|
|
7765
7551
|
modules: []
|
|
7766
|
-
}),
|
|
7552
|
+
}), z = D({
|
|
7767
7553
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7768
7554
|
avatarBody: t.avatarBody || "F",
|
|
7769
7555
|
mood: t.mood || "happy",
|
|
@@ -7778,7 +7564,7 @@ const yt = Me(({
|
|
|
7778
7564
|
lipsyncLang: "en"
|
|
7779
7565
|
});
|
|
7780
7566
|
de(() => {
|
|
7781
|
-
|
|
7567
|
+
d.current = {
|
|
7782
7568
|
onLessonStart: n,
|
|
7783
7569
|
onLessonComplete: i,
|
|
7784
7570
|
onQuestionAnswer: s,
|
|
@@ -7786,12 +7572,12 @@ const yt = Me(({
|
|
|
7786
7572
|
onCustomAction: l
|
|
7787
7573
|
};
|
|
7788
7574
|
}, [n, i, s, o, l]), de(() => {
|
|
7789
|
-
|
|
7575
|
+
M.current = G?.curriculum || {
|
|
7790
7576
|
title: "Default Curriculum",
|
|
7791
7577
|
description: "No curriculum data provided",
|
|
7792
7578
|
language: "en",
|
|
7793
7579
|
modules: []
|
|
7794
|
-
},
|
|
7580
|
+
}, z.current = {
|
|
7795
7581
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7796
7582
|
avatarBody: t.avatarBody || "F",
|
|
7797
7583
|
mood: t.mood || "happy",
|
|
@@ -7805,36 +7591,36 @@ const yt = Me(({
|
|
|
7805
7591
|
animations: e,
|
|
7806
7592
|
lipsyncLang: "en"
|
|
7807
7593
|
};
|
|
7808
|
-
}, [
|
|
7809
|
-
const
|
|
7594
|
+
}, [G, t, e]);
|
|
7595
|
+
const f = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => f()?.questions[a.current.currentQuestionIndex], [f]), P = T((v, I) => I.type === "multiple_choice" || I.type === "true_false" ? v === I.answer : I.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), U = T(() => {
|
|
7810
7596
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7811
7597
|
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7812
7598
|
let I = "Congratulations! You've completed this lesson";
|
|
7813
|
-
if (a.current.totalQuestions > 0 ? I += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : I += "! ", v >= 80 ? I += "Excellent work! You have a great understanding of this topic." : v >= 60 ? I += "Good job! You understand most of the concepts." : I += "Keep practicing! You're making progress.",
|
|
7599
|
+
if (a.current.totalQuestions > 0 ? I += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : I += "! ", v >= 80 ? I += "Excellent work! You have a great understanding of this topic." : v >= 60 ? I += "Good job! You understand most of the concepts." : I += "Keep practicing! You're making progress.", d.current.onLessonComplete({
|
|
7814
7600
|
moduleIndex: a.current.currentModuleIndex,
|
|
7815
7601
|
lessonIndex: a.current.currentLessonIndex,
|
|
7816
7602
|
score: a.current.score,
|
|
7817
7603
|
totalQuestions: a.current.totalQuestions,
|
|
7818
7604
|
percentage: v
|
|
7819
|
-
}),
|
|
7605
|
+
}), d.current.onCustomAction({
|
|
7820
7606
|
type: "lessonComplete",
|
|
7821
7607
|
moduleIndex: a.current.currentModuleIndex,
|
|
7822
7608
|
lessonIndex: a.current.currentLessonIndex,
|
|
7823
7609
|
score: a.current.score,
|
|
7824
7610
|
totalQuestions: a.current.totalQuestions,
|
|
7825
7611
|
percentage: v
|
|
7826
|
-
}),
|
|
7827
|
-
if (
|
|
7612
|
+
}), u.current) {
|
|
7613
|
+
if (u.current.setMood("happy"), e.lessonComplete)
|
|
7828
7614
|
try {
|
|
7829
|
-
|
|
7615
|
+
u.current.playAnimation(e.lessonComplete, !0);
|
|
7830
7616
|
} catch {
|
|
7831
|
-
|
|
7617
|
+
u.current.playCelebration();
|
|
7832
7618
|
}
|
|
7833
|
-
const
|
|
7834
|
-
|
|
7619
|
+
const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = N || _, q = z.current || { lipsyncLang: "en" };
|
|
7620
|
+
u.current.speakText(I, {
|
|
7835
7621
|
lipsyncLang: q.lipsyncLang,
|
|
7836
7622
|
onSpeechEnd: () => {
|
|
7837
|
-
|
|
7623
|
+
d.current.onCustomAction({
|
|
7838
7624
|
type: "lessonCompleteFeedbackDone",
|
|
7839
7625
|
moduleIndex: a.current.currentModuleIndex,
|
|
7840
7626
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7846,27 +7632,27 @@ const yt = Me(({
|
|
|
7846
7632
|
}
|
|
7847
7633
|
});
|
|
7848
7634
|
}
|
|
7849
|
-
}, [e.lessonComplete]),
|
|
7635
|
+
}, [e.lessonComplete]), oe = T(() => {
|
|
7850
7636
|
a.current.curriculumCompleted = !0;
|
|
7851
|
-
const v =
|
|
7852
|
-
if (
|
|
7637
|
+
const v = M.current || { modules: [] };
|
|
7638
|
+
if (d.current.onCurriculumComplete({
|
|
7853
7639
|
modules: v.modules.length,
|
|
7854
|
-
totalLessons: v.modules.reduce((I,
|
|
7855
|
-
}),
|
|
7856
|
-
if (
|
|
7640
|
+
totalLessons: v.modules.reduce((I, k) => I + k.lessons.length, 0)
|
|
7641
|
+
}), u.current) {
|
|
7642
|
+
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7857
7643
|
try {
|
|
7858
|
-
|
|
7644
|
+
u.current.playAnimation(e.curriculumComplete, !0);
|
|
7859
7645
|
} catch {
|
|
7860
|
-
|
|
7646
|
+
u.current.playCelebration();
|
|
7861
7647
|
}
|
|
7862
|
-
const I =
|
|
7863
|
-
|
|
7648
|
+
const I = z.current || { lipsyncLang: "en" };
|
|
7649
|
+
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: I.lipsyncLang });
|
|
7864
7650
|
}
|
|
7865
|
-
}, [e.curriculumComplete]), S =
|
|
7866
|
-
const v =
|
|
7651
|
+
}, [e.curriculumComplete]), S = T(() => {
|
|
7652
|
+
const v = f();
|
|
7867
7653
|
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7868
|
-
const I =
|
|
7869
|
-
I &&
|
|
7654
|
+
const I = E();
|
|
7655
|
+
I && d.current.onCustomAction({
|
|
7870
7656
|
type: "questionStart",
|
|
7871
7657
|
moduleIndex: a.current.currentModuleIndex,
|
|
7872
7658
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7875,36 +7661,36 @@ const yt = Me(({
|
|
|
7875
7661
|
question: I,
|
|
7876
7662
|
score: a.current.score
|
|
7877
7663
|
});
|
|
7878
|
-
const
|
|
7879
|
-
if (!
|
|
7880
|
-
if (
|
|
7664
|
+
const k = () => {
|
|
7665
|
+
if (!u.current || !I) return;
|
|
7666
|
+
if (u.current.setMood("happy"), e.questionStart)
|
|
7881
7667
|
try {
|
|
7882
|
-
|
|
7883
|
-
} catch (
|
|
7884
|
-
console.warn("Failed to play questionStart animation:",
|
|
7668
|
+
u.current.playAnimation(e.questionStart, !0);
|
|
7669
|
+
} catch (N) {
|
|
7670
|
+
console.warn("Failed to play questionStart animation:", N);
|
|
7885
7671
|
}
|
|
7886
|
-
const
|
|
7887
|
-
I.type === "code_test" ?
|
|
7672
|
+
const H = z.current || { lipsyncLang: "en" };
|
|
7673
|
+
I.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: H.lipsyncLang }) : I.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: H.lipsyncLang }) : I.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: H.lipsyncLang });
|
|
7888
7674
|
};
|
|
7889
|
-
if (
|
|
7890
|
-
|
|
7891
|
-
else if (
|
|
7892
|
-
const
|
|
7893
|
-
|
|
7675
|
+
if (u.current && u.current.isReady && I)
|
|
7676
|
+
k();
|
|
7677
|
+
else if (u.current && u.current.isReady) {
|
|
7678
|
+
const H = z.current || { lipsyncLang: "en" };
|
|
7679
|
+
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7894
7680
|
} else {
|
|
7895
|
-
const
|
|
7896
|
-
|
|
7681
|
+
const H = setInterval(() => {
|
|
7682
|
+
u.current && u.current.isReady && (clearInterval(H), I && k());
|
|
7897
7683
|
}, 100);
|
|
7898
7684
|
setTimeout(() => {
|
|
7899
|
-
clearInterval(
|
|
7685
|
+
clearInterval(H);
|
|
7900
7686
|
}, 5e3);
|
|
7901
7687
|
}
|
|
7902
|
-
}, [e.questionStart,
|
|
7903
|
-
const v =
|
|
7688
|
+
}, [e.questionStart, f, E]), Z = T(() => {
|
|
7689
|
+
const v = f();
|
|
7904
7690
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7905
|
-
|
|
7906
|
-
const I =
|
|
7907
|
-
I &&
|
|
7691
|
+
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7692
|
+
const I = E();
|
|
7693
|
+
I && d.current.onCustomAction({
|
|
7908
7694
|
type: "nextQuestion",
|
|
7909
7695
|
moduleIndex: a.current.currentModuleIndex,
|
|
7910
7696
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7913,123 +7699,123 @@ const yt = Me(({
|
|
|
7913
7699
|
question: I,
|
|
7914
7700
|
score: a.current.score
|
|
7915
7701
|
});
|
|
7916
|
-
const
|
|
7917
|
-
if (!
|
|
7918
|
-
if (
|
|
7702
|
+
const k = () => {
|
|
7703
|
+
if (!u.current || !I) return;
|
|
7704
|
+
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7919
7705
|
try {
|
|
7920
|
-
|
|
7706
|
+
u.current.playAnimation(e.nextQuestion, !0);
|
|
7921
7707
|
} catch (q) {
|
|
7922
7708
|
console.warn("Failed to play nextQuestion animation:", q);
|
|
7923
7709
|
}
|
|
7924
|
-
const
|
|
7710
|
+
const H = z.current || { lipsyncLang: "en" }, _ = f()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
|
|
7925
7711
|
if (I.type === "code_test") {
|
|
7926
7712
|
const q = j ? `Great! Here's your final coding challenge: ${I.question}` : `Great! Now let's move on to your next coding challenge: ${I.question}`;
|
|
7927
|
-
|
|
7928
|
-
lipsyncLang:
|
|
7713
|
+
u.current.speakText(q, {
|
|
7714
|
+
lipsyncLang: H.lipsyncLang
|
|
7929
7715
|
});
|
|
7930
7716
|
} else if (I.type === "multiple_choice") {
|
|
7931
7717
|
const q = j ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
|
|
7932
|
-
|
|
7933
|
-
lipsyncLang:
|
|
7718
|
+
u.current.speakText(q, {
|
|
7719
|
+
lipsyncLang: H.lipsyncLang
|
|
7934
7720
|
});
|
|
7935
7721
|
} else if (I.type === "true_false") {
|
|
7936
7722
|
const q = j ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
|
|
7937
|
-
|
|
7938
|
-
lipsyncLang:
|
|
7723
|
+
u.current.speakText(q, {
|
|
7724
|
+
lipsyncLang: H.lipsyncLang
|
|
7939
7725
|
});
|
|
7940
7726
|
} else {
|
|
7941
7727
|
const q = j ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
|
|
7942
|
-
|
|
7943
|
-
lipsyncLang:
|
|
7728
|
+
u.current.speakText(q, {
|
|
7729
|
+
lipsyncLang: H.lipsyncLang
|
|
7944
7730
|
});
|
|
7945
7731
|
}
|
|
7946
7732
|
};
|
|
7947
|
-
if (
|
|
7948
|
-
|
|
7733
|
+
if (u.current && u.current.isReady && I)
|
|
7734
|
+
k();
|
|
7949
7735
|
else if (I) {
|
|
7950
|
-
const
|
|
7951
|
-
|
|
7736
|
+
const H = setInterval(() => {
|
|
7737
|
+
u.current && u.current.isReady && (clearInterval(H), k());
|
|
7952
7738
|
}, 100);
|
|
7953
7739
|
setTimeout(() => {
|
|
7954
|
-
clearInterval(
|
|
7740
|
+
clearInterval(H);
|
|
7955
7741
|
}, 5e3);
|
|
7956
7742
|
}
|
|
7957
7743
|
} else
|
|
7958
|
-
|
|
7744
|
+
d.current.onCustomAction({
|
|
7959
7745
|
type: "allQuestionsComplete",
|
|
7960
7746
|
moduleIndex: a.current.currentModuleIndex,
|
|
7961
7747
|
lessonIndex: a.current.currentLessonIndex,
|
|
7962
7748
|
totalQuestions: a.current.totalQuestions,
|
|
7963
7749
|
score: a.current.score
|
|
7964
7750
|
});
|
|
7965
|
-
}, [e.nextQuestion,
|
|
7966
|
-
const v =
|
|
7751
|
+
}, [e.nextQuestion, f, E]), K = T(() => {
|
|
7752
|
+
const v = M.current || { modules: [] }, I = v.modules[a.current.currentModuleIndex];
|
|
7967
7753
|
if (a.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
|
|
7968
7754
|
a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7969
|
-
const
|
|
7970
|
-
|
|
7755
|
+
const H = v.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = N || _;
|
|
7756
|
+
d.current.onCustomAction({
|
|
7971
7757
|
type: "lessonStart",
|
|
7972
7758
|
moduleIndex: a.current.currentModuleIndex,
|
|
7973
7759
|
lessonIndex: a.current.currentLessonIndex,
|
|
7974
7760
|
hasNextLesson: j
|
|
7975
|
-
}),
|
|
7761
|
+
}), d.current.onLessonStart({
|
|
7976
7762
|
moduleIndex: a.current.currentModuleIndex,
|
|
7977
7763
|
lessonIndex: a.current.currentLessonIndex,
|
|
7978
|
-
lesson:
|
|
7979
|
-
}),
|
|
7764
|
+
lesson: f()
|
|
7765
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7980
7766
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7981
7767
|
a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7982
|
-
const
|
|
7983
|
-
|
|
7768
|
+
const N = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
|
|
7769
|
+
d.current.onCustomAction({
|
|
7984
7770
|
type: "lessonStart",
|
|
7985
7771
|
moduleIndex: a.current.currentModuleIndex,
|
|
7986
7772
|
lessonIndex: a.current.currentLessonIndex,
|
|
7987
7773
|
hasNextLesson: q
|
|
7988
|
-
}),
|
|
7774
|
+
}), d.current.onLessonStart({
|
|
7989
7775
|
moduleIndex: a.current.currentModuleIndex,
|
|
7990
7776
|
lessonIndex: a.current.currentLessonIndex,
|
|
7991
|
-
lesson:
|
|
7992
|
-
}),
|
|
7777
|
+
lesson: f()
|
|
7778
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7993
7779
|
} else
|
|
7994
7780
|
R.current && R.current();
|
|
7995
|
-
}, []), X =
|
|
7996
|
-
const v =
|
|
7781
|
+
}, []), X = T(() => {
|
|
7782
|
+
const v = f();
|
|
7997
7783
|
let I = null;
|
|
7998
7784
|
if (v?.avatar_script && v?.body) {
|
|
7999
|
-
const
|
|
8000
|
-
I = `${
|
|
7785
|
+
const k = v.avatar_script.trim(), H = v.body.trim(), N = k.match(/[.!?]$/) ? " " : ". ";
|
|
7786
|
+
I = `${k}${N}${H}`;
|
|
8001
7787
|
} else
|
|
8002
7788
|
I = v?.avatar_script || v?.body || null;
|
|
8003
|
-
if (
|
|
8004
|
-
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0,
|
|
8005
|
-
let
|
|
7789
|
+
if (u.current && u.current.isReady && I) {
|
|
7790
|
+
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
7791
|
+
let k = !1;
|
|
8006
7792
|
if (e.teaching)
|
|
8007
7793
|
try {
|
|
8008
|
-
|
|
8009
|
-
} catch (
|
|
8010
|
-
console.warn("Failed to play teaching animation:",
|
|
7794
|
+
u.current.playAnimation(e.teaching, !0), k = !0;
|
|
7795
|
+
} catch (N) {
|
|
7796
|
+
console.warn("Failed to play teaching animation:", N);
|
|
8011
7797
|
}
|
|
8012
|
-
|
|
8013
|
-
const
|
|
8014
|
-
|
|
7798
|
+
k || u.current.setBodyMovement("gesturing");
|
|
7799
|
+
const H = z.current || { lipsyncLang: "en" };
|
|
7800
|
+
d.current.onLessonStart({
|
|
8015
7801
|
moduleIndex: a.current.currentModuleIndex,
|
|
8016
7802
|
lessonIndex: a.current.currentLessonIndex,
|
|
8017
7803
|
lesson: v
|
|
8018
|
-
}),
|
|
7804
|
+
}), d.current.onCustomAction({
|
|
8019
7805
|
type: "teachingStart",
|
|
8020
7806
|
moduleIndex: a.current.currentModuleIndex,
|
|
8021
7807
|
lessonIndex: a.current.currentLessonIndex,
|
|
8022
7808
|
lesson: v
|
|
8023
|
-
}),
|
|
8024
|
-
lipsyncLang:
|
|
7809
|
+
}), u.current.speakText(I, {
|
|
7810
|
+
lipsyncLang: H.lipsyncLang,
|
|
8025
7811
|
onSpeechEnd: () => {
|
|
8026
|
-
a.current.isTeaching = !1,
|
|
7812
|
+
a.current.isTeaching = !1, d.current.onCustomAction({
|
|
8027
7813
|
type: "teachingComplete",
|
|
8028
7814
|
moduleIndex: a.current.currentModuleIndex,
|
|
8029
7815
|
lessonIndex: a.current.currentLessonIndex,
|
|
8030
7816
|
lesson: v,
|
|
8031
7817
|
hasQuestions: v.questions && v.questions.length > 0
|
|
8032
|
-
}), v?.code_example &&
|
|
7818
|
+
}), v?.code_example && d.current.onCustomAction({
|
|
8033
7819
|
type: "codeExampleReady",
|
|
8034
7820
|
moduleIndex: a.current.currentModuleIndex,
|
|
8035
7821
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -8039,59 +7825,59 @@ const yt = Me(({
|
|
|
8039
7825
|
}
|
|
8040
7826
|
});
|
|
8041
7827
|
}
|
|
8042
|
-
}, [e.teaching,
|
|
8043
|
-
const I =
|
|
8044
|
-
if (
|
|
7828
|
+
}, [e.teaching, f]), $ = T((v) => {
|
|
7829
|
+
const I = E(), k = P(v, I);
|
|
7830
|
+
if (k && (a.current.score += 1), d.current.onQuestionAnswer({
|
|
8045
7831
|
moduleIndex: a.current.currentModuleIndex,
|
|
8046
7832
|
lessonIndex: a.current.currentLessonIndex,
|
|
8047
7833
|
questionIndex: a.current.currentQuestionIndex,
|
|
8048
7834
|
answer: v,
|
|
8049
|
-
isCorrect:
|
|
7835
|
+
isCorrect: k,
|
|
8050
7836
|
question: I
|
|
8051
|
-
}),
|
|
8052
|
-
if (
|
|
8053
|
-
if (
|
|
7837
|
+
}), u.current)
|
|
7838
|
+
if (k) {
|
|
7839
|
+
if (u.current.setMood("happy"), e.correct)
|
|
8054
7840
|
try {
|
|
8055
|
-
|
|
7841
|
+
u.current.playReaction("happy");
|
|
8056
7842
|
} catch {
|
|
8057
|
-
|
|
7843
|
+
u.current.setBodyMovement("happy");
|
|
8058
7844
|
}
|
|
8059
|
-
|
|
8060
|
-
const
|
|
8061
|
-
a.current.currentQuestionIndex >=
|
|
8062
|
-
const
|
|
8063
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8064
|
-
const j = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, q =
|
|
8065
|
-
|
|
7845
|
+
u.current.setBodyMovement("gesturing");
|
|
7846
|
+
const N = f()?.questions?.length || 0;
|
|
7847
|
+
a.current.currentQuestionIndex >= N - 1;
|
|
7848
|
+
const _ = a.current.currentQuestionIndex < N - 1;
|
|
7849
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", _);
|
|
7850
|
+
const j = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
|
|
7851
|
+
u.current.speakText(j, {
|
|
8066
7852
|
lipsyncLang: q.lipsyncLang,
|
|
8067
7853
|
onSpeechEnd: () => {
|
|
8068
|
-
|
|
7854
|
+
d.current.onCustomAction({
|
|
8069
7855
|
type: "answerFeedbackComplete",
|
|
8070
7856
|
moduleIndex: a.current.currentModuleIndex,
|
|
8071
7857
|
lessonIndex: a.current.currentLessonIndex,
|
|
8072
7858
|
questionIndex: a.current.currentQuestionIndex,
|
|
8073
7859
|
isCorrect: !0,
|
|
8074
|
-
hasNextQuestion:
|
|
7860
|
+
hasNextQuestion: _,
|
|
8075
7861
|
score: a.current.score,
|
|
8076
7862
|
totalQuestions: a.current.totalQuestions
|
|
8077
7863
|
});
|
|
8078
7864
|
}
|
|
8079
7865
|
});
|
|
8080
7866
|
} else {
|
|
8081
|
-
if (
|
|
7867
|
+
if (u.current.setMood("sad"), e.incorrect)
|
|
8082
7868
|
try {
|
|
8083
|
-
|
|
7869
|
+
u.current.playAnimation(e.incorrect, !0);
|
|
8084
7870
|
} catch {
|
|
8085
|
-
|
|
7871
|
+
u.current.setBodyMovement("idle");
|
|
8086
7872
|
}
|
|
8087
|
-
|
|
8088
|
-
const
|
|
8089
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8090
|
-
const q = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${
|
|
8091
|
-
|
|
7873
|
+
u.current.setBodyMovement("gesturing");
|
|
7874
|
+
const N = f()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= N - 1, j = a.current.currentQuestionIndex < N - 1;
|
|
7875
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", j);
|
|
7876
|
+
const q = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
|
|
7877
|
+
u.current.speakText(q, {
|
|
8092
7878
|
lipsyncLang: Le.lipsyncLang,
|
|
8093
7879
|
onSpeechEnd: () => {
|
|
8094
|
-
|
|
7880
|
+
d.current.onCustomAction({
|
|
8095
7881
|
type: "answerFeedbackComplete",
|
|
8096
7882
|
moduleIndex: a.current.currentModuleIndex,
|
|
8097
7883
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -8105,21 +7891,21 @@ const yt = Me(({
|
|
|
8105
7891
|
});
|
|
8106
7892
|
}
|
|
8107
7893
|
else {
|
|
8108
|
-
const
|
|
8109
|
-
|
|
7894
|
+
const N = f()?.questions?.length || 0;
|
|
7895
|
+
d.current.onCustomAction({
|
|
8110
7896
|
type: "answerFeedbackComplete",
|
|
8111
7897
|
moduleIndex: a.current.currentModuleIndex,
|
|
8112
7898
|
lessonIndex: a.current.currentLessonIndex,
|
|
8113
7899
|
questionIndex: a.current.currentQuestionIndex,
|
|
8114
|
-
isCorrect:
|
|
8115
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
7900
|
+
isCorrect: k,
|
|
7901
|
+
hasNextQuestion: a.current.currentQuestionIndex < N - 1,
|
|
8116
7902
|
score: a.current.score,
|
|
8117
7903
|
totalQuestions: a.current.totalQuestions,
|
|
8118
7904
|
avatarNotReady: !0
|
|
8119
7905
|
});
|
|
8120
7906
|
}
|
|
8121
|
-
}, [e.correct, e.incorrect,
|
|
8122
|
-
const I =
|
|
7907
|
+
}, [e.correct, e.incorrect, E, f, P]), se = T((v) => {
|
|
7908
|
+
const I = E();
|
|
8123
7909
|
if (!v || typeof v != "object") {
|
|
8124
7910
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8125
7911
|
return;
|
|
@@ -8128,7 +7914,7 @@ const yt = Me(({
|
|
|
8128
7914
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8129
7915
|
return;
|
|
8130
7916
|
}
|
|
8131
|
-
const
|
|
7917
|
+
const k = {
|
|
8132
7918
|
passed: v.passed === !0,
|
|
8133
7919
|
results: v.results || [],
|
|
8134
7920
|
output: v.output || "",
|
|
@@ -8138,19 +7924,19 @@ const yt = Me(({
|
|
|
8138
7924
|
passedCount: v.passedCount || 0,
|
|
8139
7925
|
failedCount: v.failedCount || 0
|
|
8140
7926
|
};
|
|
8141
|
-
|
|
7927
|
+
d.current.onCustomAction({
|
|
8142
7928
|
type: "codeTestSubmitted",
|
|
8143
7929
|
moduleIndex: a.current.currentModuleIndex,
|
|
8144
7930
|
lessonIndex: a.current.currentLessonIndex,
|
|
8145
7931
|
questionIndex: a.current.currentQuestionIndex,
|
|
8146
|
-
testResult:
|
|
7932
|
+
testResult: k,
|
|
8147
7933
|
question: I
|
|
8148
|
-
}), p.current && p.current(
|
|
8149
|
-
}, [
|
|
7934
|
+
}), p.current && p.current(k);
|
|
7935
|
+
}, [E, P]), ae = T(() => {
|
|
8150
7936
|
if (a.current.currentQuestionIndex > 0) {
|
|
8151
7937
|
a.current.currentQuestionIndex -= 1;
|
|
8152
|
-
const v =
|
|
8153
|
-
v &&
|
|
7938
|
+
const v = E();
|
|
7939
|
+
v && d.current.onCustomAction({
|
|
8154
7940
|
type: "questionStart",
|
|
8155
7941
|
moduleIndex: a.current.currentModuleIndex,
|
|
8156
7942
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -8160,129 +7946,129 @@ const yt = Me(({
|
|
|
8160
7946
|
score: a.current.score
|
|
8161
7947
|
});
|
|
8162
7948
|
const I = () => {
|
|
8163
|
-
if (!
|
|
8164
|
-
|
|
8165
|
-
const
|
|
8166
|
-
v.type === "code_test" ?
|
|
8167
|
-
lipsyncLang:
|
|
8168
|
-
}) :
|
|
8169
|
-
lipsyncLang:
|
|
7949
|
+
if (!u.current || !v) return;
|
|
7950
|
+
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
7951
|
+
const k = z.current || { lipsyncLang: "en" };
|
|
7952
|
+
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
7953
|
+
lipsyncLang: k.lipsyncLang
|
|
7954
|
+
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
7955
|
+
lipsyncLang: k.lipsyncLang
|
|
8170
7956
|
});
|
|
8171
7957
|
};
|
|
8172
|
-
if (
|
|
7958
|
+
if (u.current && u.current.isReady && v)
|
|
8173
7959
|
I();
|
|
8174
7960
|
else if (v) {
|
|
8175
|
-
const
|
|
8176
|
-
|
|
7961
|
+
const k = setInterval(() => {
|
|
7962
|
+
u.current && u.current.isReady && (clearInterval(k), I());
|
|
8177
7963
|
}, 100);
|
|
8178
7964
|
setTimeout(() => {
|
|
8179
|
-
clearInterval(
|
|
7965
|
+
clearInterval(k);
|
|
8180
7966
|
}, 5e3);
|
|
8181
7967
|
}
|
|
8182
7968
|
}
|
|
8183
|
-
}, [
|
|
8184
|
-
const v =
|
|
7969
|
+
}, [E]), pe = T(() => {
|
|
7970
|
+
const v = M.current || { modules: [] };
|
|
8185
7971
|
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
8186
|
-
a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0,
|
|
7972
|
+
a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8187
7973
|
type: "lessonStart",
|
|
8188
7974
|
moduleIndex: a.current.currentModuleIndex,
|
|
8189
7975
|
lessonIndex: a.current.currentLessonIndex
|
|
8190
|
-
}),
|
|
7976
|
+
}), d.current.onLessonStart({
|
|
8191
7977
|
moduleIndex: a.current.currentModuleIndex,
|
|
8192
7978
|
lessonIndex: a.current.currentLessonIndex,
|
|
8193
|
-
lesson:
|
|
8194
|
-
}),
|
|
7979
|
+
lesson: f()
|
|
7980
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8195
7981
|
else if (a.current.currentModuleIndex > 0) {
|
|
8196
|
-
const
|
|
8197
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
7982
|
+
const H = v.modules[a.current.currentModuleIndex - 1];
|
|
7983
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8198
7984
|
type: "lessonStart",
|
|
8199
7985
|
moduleIndex: a.current.currentModuleIndex,
|
|
8200
7986
|
lessonIndex: a.current.currentLessonIndex
|
|
8201
|
-
}),
|
|
7987
|
+
}), d.current.onLessonStart({
|
|
8202
7988
|
moduleIndex: a.current.currentModuleIndex,
|
|
8203
7989
|
lessonIndex: a.current.currentLessonIndex,
|
|
8204
|
-
lesson:
|
|
8205
|
-
}),
|
|
7990
|
+
lesson: f()
|
|
7991
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8206
7992
|
}
|
|
8207
|
-
}, [
|
|
7993
|
+
}, [f]), ee = T(() => {
|
|
8208
7994
|
a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
8209
|
-
}, []), le =
|
|
7995
|
+
}, []), le = T((v) => {
|
|
8210
7996
|
console.log("Avatar is ready!", v);
|
|
8211
|
-
const I =
|
|
8212
|
-
|
|
8213
|
-
|
|
7997
|
+
const I = f(), k = I?.avatar_script || I?.body;
|
|
7998
|
+
h && k && setTimeout(() => {
|
|
7999
|
+
c.current && c.current();
|
|
8214
8000
|
}, 10);
|
|
8215
|
-
}, [
|
|
8001
|
+
}, [h, f]);
|
|
8216
8002
|
Xe(() => {
|
|
8217
|
-
|
|
8003
|
+
c.current = X, g.current = K, y.current = U, b.current = Z, R.current = oe, V.current = S, p.current = $;
|
|
8218
8004
|
}), Ee(r, () => ({
|
|
8219
8005
|
// Curriculum control methods
|
|
8220
8006
|
startTeaching: X,
|
|
8221
8007
|
startQuestions: S,
|
|
8222
8008
|
handleAnswerSelect: $,
|
|
8223
8009
|
handleCodeTestResult: se,
|
|
8224
|
-
nextQuestion:
|
|
8010
|
+
nextQuestion: Z,
|
|
8225
8011
|
previousQuestion: ae,
|
|
8226
|
-
nextLesson:
|
|
8012
|
+
nextLesson: K,
|
|
8227
8013
|
previousLesson: pe,
|
|
8228
|
-
completeLesson:
|
|
8229
|
-
completeCurriculum:
|
|
8014
|
+
completeLesson: U,
|
|
8015
|
+
completeCurriculum: oe,
|
|
8230
8016
|
resetCurriculum: ee,
|
|
8231
8017
|
getState: () => ({ ...a.current }),
|
|
8232
|
-
getCurrentQuestion: () =>
|
|
8233
|
-
getCurrentLesson: () =>
|
|
8018
|
+
getCurrentQuestion: () => E(),
|
|
8019
|
+
getCurrentLesson: () => f(),
|
|
8234
8020
|
// Direct access to avatar ref (always returns current value)
|
|
8235
|
-
getAvatarRef: () =>
|
|
8021
|
+
getAvatarRef: () => u.current,
|
|
8236
8022
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8237
8023
|
speakText: async (v, I = {}) => {
|
|
8238
|
-
await
|
|
8239
|
-
const
|
|
8240
|
-
|
|
8024
|
+
await u.current?.resumeAudioContext?.();
|
|
8025
|
+
const k = z.current || { lipsyncLang: "en" };
|
|
8026
|
+
u.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || k.lipsyncLang });
|
|
8241
8027
|
},
|
|
8242
8028
|
resumeAudioContext: async () => {
|
|
8243
|
-
if (
|
|
8244
|
-
return await
|
|
8245
|
-
const v =
|
|
8029
|
+
if (u.current?.resumeAudioContext)
|
|
8030
|
+
return await u.current.resumeAudioContext();
|
|
8031
|
+
const v = u.current?.talkingHead;
|
|
8246
8032
|
if (v?.audioCtx) {
|
|
8247
8033
|
const I = v.audioCtx;
|
|
8248
8034
|
if (I.state === "suspended" || I.state === "interrupted")
|
|
8249
8035
|
try {
|
|
8250
8036
|
await I.resume(), console.log("Audio context resumed via talkingHead");
|
|
8251
|
-
} catch (
|
|
8252
|
-
console.warn("Failed to resume audio context:",
|
|
8037
|
+
} catch (k) {
|
|
8038
|
+
console.warn("Failed to resume audio context:", k);
|
|
8253
8039
|
}
|
|
8254
8040
|
} else
|
|
8255
8041
|
console.warn("Audio context not available yet");
|
|
8256
8042
|
},
|
|
8257
|
-
stopSpeaking: () =>
|
|
8258
|
-
pauseSpeaking: () =>
|
|
8259
|
-
resumeSpeaking: async () => await
|
|
8260
|
-
isPaused: () =>
|
|
8261
|
-
setMood: (v) =>
|
|
8262
|
-
playAnimation: (v, I) =>
|
|
8263
|
-
setBodyMovement: (v) =>
|
|
8264
|
-
setMovementIntensity: (v) =>
|
|
8265
|
-
playRandomDance: () =>
|
|
8266
|
-
playReaction: (v) =>
|
|
8267
|
-
playCelebration: () =>
|
|
8268
|
-
setShowFullAvatar: (v) =>
|
|
8269
|
-
setTimingAdjustment: (v) =>
|
|
8270
|
-
lockAvatarPosition: () =>
|
|
8271
|
-
unlockAvatarPosition: () =>
|
|
8043
|
+
stopSpeaking: () => u.current?.stopSpeaking(),
|
|
8044
|
+
pauseSpeaking: () => u.current?.pauseSpeaking(),
|
|
8045
|
+
resumeSpeaking: async () => await u.current?.resumeSpeaking(),
|
|
8046
|
+
isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
|
|
8047
|
+
setMood: (v) => u.current?.setMood(v),
|
|
8048
|
+
playAnimation: (v, I) => u.current?.playAnimation(v, I),
|
|
8049
|
+
setBodyMovement: (v) => u.current?.setBodyMovement(v),
|
|
8050
|
+
setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
|
|
8051
|
+
playRandomDance: () => u.current?.playRandomDance(),
|
|
8052
|
+
playReaction: (v) => u.current?.playReaction(v),
|
|
8053
|
+
playCelebration: () => u.current?.playCelebration(),
|
|
8054
|
+
setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
|
|
8055
|
+
setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
|
|
8056
|
+
lockAvatarPosition: () => u.current?.lockAvatarPosition(),
|
|
8057
|
+
unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
|
|
8272
8058
|
// Custom action trigger
|
|
8273
8059
|
triggerCustomAction: (v, I) => {
|
|
8274
|
-
|
|
8060
|
+
d.current.onCustomAction({
|
|
8275
8061
|
type: v,
|
|
8276
8062
|
...I,
|
|
8277
8063
|
state: { ...a.current }
|
|
8278
8064
|
});
|
|
8279
8065
|
},
|
|
8280
8066
|
// Responsive resize handler
|
|
8281
|
-
handleResize: () =>
|
|
8067
|
+
handleResize: () => u.current?.handleResize(),
|
|
8282
8068
|
// Avatar readiness check (always returns current value)
|
|
8283
|
-
isAvatarReady: () =>
|
|
8284
|
-
}), [X, S, $, se,
|
|
8285
|
-
const
|
|
8069
|
+
isAvatarReady: () => u.current?.isReady || !1
|
|
8070
|
+
}), [X, S, $, se, Z, K, U, oe, ee, E, f]);
|
|
8071
|
+
const O = z.current || {
|
|
8286
8072
|
avatarUrl: "/avatars/brunette.glb",
|
|
8287
8073
|
avatarBody: "F",
|
|
8288
8074
|
mood: "happy",
|
|
@@ -8298,19 +8084,19 @@ const yt = Me(({
|
|
|
8298
8084
|
return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
|
|
8299
8085
|
Ve,
|
|
8300
8086
|
{
|
|
8301
|
-
ref:
|
|
8302
|
-
avatarUrl:
|
|
8303
|
-
avatarBody:
|
|
8304
|
-
mood:
|
|
8305
|
-
ttsLang:
|
|
8306
|
-
ttsService:
|
|
8307
|
-
ttsVoice:
|
|
8308
|
-
ttsApiKey:
|
|
8309
|
-
bodyMovement:
|
|
8310
|
-
movementIntensity:
|
|
8311
|
-
showFullAvatar:
|
|
8087
|
+
ref: u,
|
|
8088
|
+
avatarUrl: O.avatarUrl,
|
|
8089
|
+
avatarBody: O.avatarBody,
|
|
8090
|
+
mood: O.mood,
|
|
8091
|
+
ttsLang: O.ttsLang,
|
|
8092
|
+
ttsService: O.ttsService,
|
|
8093
|
+
ttsVoice: O.ttsVoice,
|
|
8094
|
+
ttsApiKey: O.ttsApiKey,
|
|
8095
|
+
bodyMovement: O.bodyMovement,
|
|
8096
|
+
movementIntensity: O.movementIntensity,
|
|
8097
|
+
showFullAvatar: O.showFullAvatar,
|
|
8312
8098
|
cameraView: "upper",
|
|
8313
|
-
animations:
|
|
8099
|
+
animations: O.animations,
|
|
8314
8100
|
onReady: le,
|
|
8315
8101
|
onLoading: () => {
|
|
8316
8102
|
},
|
|
@@ -8424,7 +8210,7 @@ const Ge = {
|
|
|
8424
8210
|
duration: 5e3,
|
|
8425
8211
|
description: "Excited, energetic movement"
|
|
8426
8212
|
}
|
|
8427
|
-
}, wt = (
|
|
8213
|
+
}, wt = (G) => Ge[G] || null, zt = (G) => Ge.hasOwnProperty(G);
|
|
8428
8214
|
export {
|
|
8429
8215
|
yt as CurriculumLearning,
|
|
8430
8216
|
gt as SimpleTalkingAvatar,
|