@sage-rsc/talking-head-react 1.1.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
- import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as F, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
1
+ import { jsxs as Pe, jsx as pe } from "react/jsx-runtime";
2
+ import { forwardRef as Me, useRef as V, useState as de, useEffect as me, useCallback as N, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
3
3
  import * as f 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
7
  import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
- import Ke from "three/addons/libs/stats.module.js";
10
- let m, re, ue;
11
- const S = [0, 0, 0, 0], C = new f.Vector3(), ze = new f.Vector3(), ie = new f.Vector3(), Ce = new f.Vector3();
9
+ import _e from "three/addons/libs/stats.module.js";
10
+ let m, le, ue;
11
+ const w = [0, 0, 0, 0], F = new f.Vector3(), ze = new f.Vector3(), ae = new f.Vector3(), Ce = new f.Vector3();
12
12
  new f.Plane();
13
13
  new f.Ray();
14
14
  new f.Euler();
15
- const oe = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
15
+ const re = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
16
  new f.Vector3();
17
- const He = new f.Vector3(0, 0, 1), _e = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
17
+ const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -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(C).clone(),
324
+ vWorld: r.parent.getWorldPosition(F).clone(),
325
325
  // World position, parent
326
326
  qBasis: r.parent.quaternion.clone(),
327
327
  // Original quaternion, parent
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(C, oe, ie), C.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, C).invert()).normalize(), u.qWorldInverseYaw = oe.clone().normalize(), this.data.push(u), this.dict[h] = u;
341
+ u.boneParent.matrixWorld.decompose(F, re, ae), F.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, F).invert()).normalize(), u.qWorldInverseYaw = re.clone().normalize(), this.data.push(u), this.dict[h] = u;
342
342
  try {
343
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) {
@@ -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], C.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), C.applyMatrix4(xe), C.length() > 0.5 && (console.info("Info: Unrealistic jump of " + C.length().toFixed(2) + " meters."), C.setLength(0.5)), C.applyQuaternion(o.bone.quaternion), S[0] = C.x, S[1] = C.y, S[2] = -C.z, S[3] = C.length() / 3, o.children)
359
+ if (o = this.data[e], F.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), F.applyMatrix4(xe), F.length() > 0.5 && (console.info("Info: Unrealistic jump of " + F.length().toFixed(2) + " meters."), F.setLength(0.5)), F.applyQuaternion(o.bone.quaternion), w[0] = F.x, w[1] = F.y, w[2] = -F.z, w[3] = F.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
- m = o.children[n], S[0] -= m.v[0] * t / 3, S[1] -= m.v[1] * t / 3, S[2] += m.v[2] * t / 3, S[3] -= m.v[3] * t / 3;
362
- if (m = this.opt.sensitivityFactor, S[0] *= o.ext * m, S[1] *= o.ext * m, S[2] *= o.ext * m, S[3] *= o.ext * m, o.isX && (m = S[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 + S[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 = S[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 + S[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 = S[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 + S[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 = S[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 + S[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), S[0] = o.p[0], S[1] = o.p[1], S[2] = o.p[2], S[3] = o.p[3], m = this.opt.movementFactor, S[0] *= m, S[1] *= m, S[2] *= m, S[3] *= m, o.dl && (m = o.dl, S[0] += m[0], S[1] += m[1], S[2] += m[2]), o.dw && (m = o.dw, C.set(
363
- o.vBasis.x + S[0],
364
- o.vBasis.y + S[1],
365
- o.vBasis.z + S[2]
366
- ), C.applyMatrix4(fe), C.x += m[0], C.y += m[1], C.z += m[2], C.applyMatrix4(xe), S[0] += C.x - o.vBasis.x, S[1] += C.y - o.vBasis.y, S[2] += C.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && S[0] < m[0][0] && (S[0] = m[0][0]), m[0][1] !== null && S[0] > m[0][1] && (S[0] = m[0][1])), m[1] && (m[1][0] !== null && S[1] < m[1][0] && (S[1] = m[1][0]), m[1][1] !== null && S[1] > m[1][1] && (S[1] = m[1][1])), m[2] && (m[2][0] !== null && S[2] < m[2][0] && (S[2] = m[2][0]), m[2][1] !== null && S[2] > m[2][1] && (S[2] = m[2][1])), m[3] && (m[3][0] !== null && S[3] < m[3][0] && (S[3] = m[3][0]), m[3][1] !== null && S[3] > m[3][1] && (S[3] = m[3][1]))), o.isPoint)
361
+ m = o.children[n], w[0] -= m.v[0] * t / 3, w[1] -= m.v[1] * t / 3, w[2] += m.v[2] * t / 3, w[3] -= m.v[3] * t / 3;
362
+ if (m = this.opt.sensitivityFactor, w[0] *= o.ext * m, w[1] *= o.ext * m, w[2] *= o.ext * m, w[3] *= o.ext * m, o.isX && (m = w[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 + w[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 = w[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 + w[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 = w[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 + w[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 = w[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 + w[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), w[0] = o.p[0], w[1] = o.p[1], w[2] = o.p[2], w[3] = o.p[3], m = this.opt.movementFactor, w[0] *= m, w[1] *= m, w[2] *= m, w[3] *= m, o.dl && (m = o.dl, w[0] += m[0], w[1] += m[1], w[2] += m[2]), o.dw && (m = o.dw, F.set(
363
+ o.vBasis.x + w[0],
364
+ o.vBasis.y + w[1],
365
+ o.vBasis.z + w[2]
366
+ ), F.applyMatrix4(fe), F.x += m[0], F.y += m[1], F.z += m[2], F.applyMatrix4(xe), w[0] += F.x - o.vBasis.x, w[1] += F.y - o.vBasis.y, w[2] += F.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && w[0] < m[0][0] && (w[0] = m[0][0]), m[0][1] !== null && w[0] > m[0][1] && (w[0] = m[0][1])), m[1] && (m[1][0] !== null && w[1] < m[1][0] && (w[1] = m[1][0]), m[1][1] !== null && w[1] > m[1][1] && (w[1] = m[1][1])), m[2] && (m[2][0] !== null && w[2] < m[2][0] && (w[2] = m[2][0]), m[2][1] !== null && w[2] > m[2][1] && (w[2] = m[2][1])), m[3] && (m[3][0] !== null && w[3] < m[3][0] && (w[3] = m[3][0]), m[3][1] !== null && w[3] > m[3][1] && (w[3] = m[3][1]))), o.isPoint)
367
367
  o.bone.position.set(
368
- o.vBasis.x + S[0],
369
- o.vBasis.y + S[1],
370
- o.vBasis.z - S[2]
368
+ o.vBasis.x + w[0],
369
+ o.vBasis.y + w[1],
370
+ o.vBasis.z - w[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(C, oe, ie), C.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, C).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(S[0] / o.l), oe.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(oe)), o.isY && (m = o.l / 3, m = m * Math.tanh(S[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(S[2] / o.l), oe.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(oe)), o.isT && (m = 1.5 * Math.tanh(S[3] * 1.5), oe.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(oe)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
372
+ else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(F, re, ae), F.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, F).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(w[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), o.isY && (m = o.l / 3, m = m * Math.tanh(w[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(w[2] / o.l), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(w[3] * 1.5), re.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(re)), 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], ie.set(0, 0, 0), m.deltaLocal && (ie.x += m.deltaLocal[0], ie.y += m.deltaLocal[1], ie.z += m.deltaLocal[2]), ie.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), C.copy(o.bone.position), !(C.distanceToSquared(ie) >= m.radiusSq) && (ue = C.length(), re = ie.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), C.subVectors(C, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), ue = ze.dot(C), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), C.add(ze)), C.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, C), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
374
+ m = o.excludes[n], ae.set(0, 0, 0), m.deltaLocal && (ae.x += m.deltaLocal[0], ae.y += m.deltaLocal[1], ae.z += m.deltaLocal[2]), ae.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ae.applyMatrix4(xe), F.copy(o.bone.position), !(F.distanceToSquared(ae) >= m.radiusSq) && (ue = F.length(), le = ae.length(), !(le > m.radius + ue) && (le < Math.abs(m.radius - ue) || (le = (le * le + ue * ue - m.radiusSq) / (2 * le), ae.normalize(), Ce.copy(ae).multiplyScalar(le), le = Math.sqrt(ue * ue - le * le), F.subVectors(F, Ce).projectOnPlane(ae).normalize().multiplyScalar(le), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), ue = ze.dot(F), ue < 0 && (ue = Math.sqrt(le * le - ue * ue), ze.multiplyScalar(ue), F.add(ze)), F.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, F), o.boneParent.quaternion.premultiply(re), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
376
376
  this.helpers.isActive && this.updateHelpers();
377
377
  }
@@ -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), C.setFromMatrixPosition(fe), t.setXYZ(e, C.x, C.y, C.z);
448
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(e, F.x, F.y, F.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), C.setFromMatrixPosition(fe), t.setXYZ(n, C.x, C.y, C.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), C.setFromMatrixPosition(fe), t.setXYZ(n + 1, C.x, C.y, C.z);
455
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(n, F.x, F.y, F.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(n + 1, F.x, F.y, F.z);
456
456
  t.needsUpdate = !0, m.object.updateMatrixWorld();
457
457
  }
458
458
  }
@@ -521,10 +521,10 @@ class tt {
521
521
  for (let l = 0; l < o; l++) {
522
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 c = this.calculateSpectralCentroid(u);
525
- n.spectralCentroid.push(c);
526
- const d = this.calculateZeroCrossingRate(u);
527
- n.zeroCrossingRate.push(d);
524
+ const d = this.calculateSpectralCentroid(u);
525
+ n.spectralCentroid.push(d);
526
+ const c = this.calculateZeroCrossingRate(u);
527
+ n.zeroCrossingRate.push(c);
528
528
  const g = this.calculateMFCC(u);
529
529
  n.mfcc.push(g);
530
530
  }
@@ -606,10 +606,10 @@ class tt {
606
606
  for (let h = 0; h < e; h += i) {
607
607
  let r = 1, u = 0;
608
608
  for (let a = 0; a < i / 2; a++) {
609
- const c = n[(h + a) * 2], d = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, b = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
- n[(h + a) * 2] = c + g, n[(h + a) * 2 + 1] = d + b, n[(h + a + i / 2) * 2] = c - g, n[(h + a + i / 2) * 2 + 1] = d - b;
611
- const x = r * o - u * l, A = r * l + u * o;
612
- r = x, u = A;
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, b = 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 + b, n[(h + a + i / 2) * 2] = d - g, n[(h + a + i / 2) * 2 + 1] = c - b;
611
+ const x = r * o - u * l, S = r * l + u * o;
612
+ r = x, u = S;
613
613
  }
614
614
  }
615
615
  }
@@ -703,15 +703,15 @@ class tt {
703
703
  const o = this.textToVisemes(e);
704
704
  let l = 0, h = 0;
705
705
  for (let r = 0; r < s.length && l < o.length; r++) {
706
- const u = s[r], a = o[l], c = t.energy[Math.floor(u / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
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
709
  startTime: h,
710
- endTime: h + d,
711
- duration: d,
712
- intensity: Math.min(1, c * 2)
710
+ endTime: h + c,
711
+ duration: c,
712
+ intensity: Math.min(1, d * 2)
713
713
  // Map energy to viseme intensity
714
- }), h += d, l++;
714
+ }), h += c, l++;
715
715
  }
716
716
  for (; l < o.length; ) {
717
717
  const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
@@ -1207,10 +1207,10 @@ class nt {
1207
1207
  Object.keys(this.rules).forEach((e) => {
1208
1208
  this.rules[e] = this.rules[e].map((n) => {
1209
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 c = "";
1211
- c += [...l].map((g) => t[g] || g).join("");
1212
- const d = [...h];
1213
- return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
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
  });
@@ -1380,11 +1380,11 @@ class nt {
1380
1380
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(h.regex)) {
1381
1381
  h.visemes.forEach((a) => {
1382
1382
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
1383
- const c = 0.7 * (this.visemeDurations[a] || 1);
1384
- e.durations[e.durations.length - 1] += c, n += c;
1383
+ const d = 0.7 * (this.visemeDurations[a] || 1);
1384
+ e.durations[e.durations.length - 1] += d, n += d;
1385
1385
  } else {
1386
- const c = this.visemeDurations[a] || 1;
1387
- e.visemes.push(a), e.times.push(n), e.durations.push(c), n += c;
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
1389
  }), e.i += h.move;
1390
1390
  break;
@@ -1617,10 +1617,10 @@ class ot {
1617
1617
  Object.keys(this.rules).forEach((e) => {
1618
1618
  this.rules[e] = this.rules[e].map((n) => {
1619
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 c = "";
1621
- c += [...l].map((g) => t[g] || g).join("");
1622
- const d = [...h];
1623
- return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
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
  });
@@ -1735,13 +1735,13 @@ class ot {
1735
1735
  for (let h = 0; h < o.length; h++) {
1736
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((c) => {
1739
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
1740
- const d = 0.7 * (this.visemeDurations[c] || 1);
1741
- e.durations[e.durations.length - 1] += d, n += d;
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 d = this.visemeDurations[c] || 1;
1744
- e.visemes.push(c), e.times.push(n), e.durations.push(d), n += d;
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;
@@ -2132,10 +2132,10 @@ class at {
2132
2132
  Object.keys(this.rules).forEach((e) => {
2133
2133
  this.rules[e] = this.rules[e].map((n) => {
2134
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 c = "";
2136
- c += [...l].map((g) => t[g] || g).join("");
2137
- const d = [...h];
2138
- return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), u.length && u.split(" ").forEach((g) => {
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
  });
@@ -2270,13 +2270,13 @@ class at {
2270
2270
  for (let h = 0; h < o.length; h++) {
2271
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((c) => {
2274
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
2275
- const d = 0.7 * (this.visemeDurations[c] || 1);
2276
- e.durations[e.durations.length - 1] += d, n += d;
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 d = this.visemeDurations[c] || 1;
2279
- e.visemes.push(c), e.times.push(n), e.durations.push(d), n += d;
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;
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, Q = new f.Quaternion(), G = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2632
+ }, J = new f.Quaternion(), Z = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2633
2633
  new f.Matrix4();
2634
2634
  new f.Matrix4();
2635
2635
  new f.Vector3();
@@ -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 Ke(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
2766
+ }, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new _e(), 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: {
@@ -4225,16 +4225,16 @@ class Be {
4225
4225
  let l = null, h = null;
4226
4226
  for (const [r, u] of Object.entries(n))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4228
- const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4229
- l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (h = new f.Float32BufferAttribute(c.count * 3, 3)));
4230
- for (let g = 0; g < c.count; g++) {
4231
- const b = l.getX(g) + c.getX(g) * u, x = l.getY(g) + c.getY(g) * u, A = l.getZ(g) + c.getZ(g) * u;
4232
- l.setXYZ(g, b, x, A);
4228
+ const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], c = o.morphAttributes.normal?.[a];
4229
+ l || (l = new f.Float32BufferAttribute(d.count * 3, 3), c && (h = new f.Float32BufferAttribute(d.count * 3, 3)));
4230
+ for (let g = 0; g < d.count; g++) {
4231
+ const b = l.getX(g) + d.getX(g) * u, x = l.getY(g) + d.getY(g) * u, S = l.getZ(g) + d.getZ(g) * u;
4232
+ l.setXYZ(g, b, x, S);
4233
4233
  }
4234
- if (d)
4235
- for (let g = 0; g < c.count; g++) {
4236
- const b = h.getX(g) + d.getX(g) * u, x = h.getY(g) + d.getY(g) * u, A = h.getZ(g) + d.getZ(g) * u;
4237
- h.setXYZ(g, b, x, A);
4234
+ if (c)
4235
+ for (let g = 0; g < d.count; g++) {
4236
+ const b = h.getX(g) + c.getX(g) * u, x = h.getY(g) + c.getY(g) * u, S = h.getZ(g) + c.getZ(g) * u;
4237
+ h.setXYZ(g, b, x, S);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4299,8 +4299,8 @@ class Be {
4299
4299
  u && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
4300
4300
  l[r][a] = u[a];
4301
4301
  }), this.morphs.forEach((a) => {
4302
- const c = a.morphTargetDictionary[r];
4303
- c !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(c), a.morphTargetInfluences[c] = l[r].applied);
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
4306
  const u = r.split("."), a = this.armature.getObjectByName(u[0]);
@@ -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
- G.set(e.x, e.y, e.z);
4401
+ Z.set(e.x, e.y, e.z);
4402
4402
  const n = this.poseAvatar.props[t];
4403
- n.isQuaternion ? (Q.setFromEuler(G), n.multiply(Q)) : n.isVector3 && n.add(G);
4403
+ n.isQuaternion ? (J.setFromEuler(Z), n.multiply(J)) : n.isVector3 && n.add(Z);
4404
4404
  }
4405
4405
  }
4406
4406
  /**
@@ -4987,10 +4987,10 @@ class Be {
4987
4987
  if (l.alt.length > 1) {
4988
4988
  const u = Math.random();
4989
4989
  let a = 0;
4990
- for (let c = 0; c < l.alt.length; c++) {
4991
- let d = this.valueFn(l.alt[c].p);
4992
- if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, u < a) {
4993
- r = l.alt[c];
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
  }
@@ -5011,8 +5011,8 @@ class Be {
5011
5011
  }
5012
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
5013
  for (let [r, u] of Object.entries(l.vs)) {
5014
- const a = this.getBaselineValue(r), c = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? (console.log("Intercepting pose", d, "in animation factory, overriding to wide for male avatar"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5015
- r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
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]);
@@ -5099,20 +5099,20 @@ class Be {
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 [c, d] of Object.entries(a.vs))
5103
- if (this.mtAvatar.hasOwnProperty(c)) {
5104
- if (d[i + 1] === null) continue;
5105
- const g = this.mtAvatar[c];
5106
- if (d[i] === null && (d[i] = g.value), i === o - 1)
5107
- g.newvalue = d[i];
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 = d[i + 1];
5109
+ g.newvalue = c[i + 1];
5110
5110
  const b = a.ts[i + 1] - a.ts[i];
5111
5111
  let x = 1;
5112
- b > 1e-4 && (x = (this.animClock - a.ts[i]) / b), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * d[i] + x * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5112
+ b > 1e-4 && (x = (this.animClock - a.ts[i]) / b), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * c[i] + x * 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 (c) {
5115
+ switch (d) {
5116
5116
  case "viseme_aa":
5117
5117
  case "viseme_E":
5118
5118
  case "viseme_I":
@@ -5121,11 +5121,11 @@ class Be {
5121
5121
  g.newvalue *= 1 + l / 255 - 0.5;
5122
5122
  }
5123
5123
  g.needsUpdate = !0;
5124
- } else c === "eyeContact" && d[i] !== null && h !== !1 ? h = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (u.push({ mt: c, val: d[i] }), d[i] = null);
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, c = u.length; a < c; a++)
5128
+ for (let a = 0, d = u.length; a < d; a++)
5129
5129
  switch (i = u[a].val, u[a].mt) {
5130
5130
  case "speak":
5131
5131
  this.speakText(i);
@@ -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((d) => {
5147
- d[1] ? this.poseTarget.props[d[0]].copy(d[1]) : this.poseTarget.props[d[0]].copy(this.getPoseTemplateProp(d[0])), this.poseTarget.props[d[0]].t = this.animClock, this.poseTarget.props[d[0]].d = d[1] && d[1].d ? d[1].d : d.duration || 2e3;
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":
@@ -5172,7 +5172,7 @@ class Be {
5172
5172
  }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  }
5175
- if ((h || r) && (G.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), G.x = Math.max(-0.9, Math.min(0.9, 2 * G.x - 0.5)), G.y = Math.max(-0.9, Math.min(0.9, -2.5 * G.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: G.x < 0 ? -G.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: G.x < 0 ? 0 : G.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: G.y < 0 ? -G.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: G.y < 0 ? 0 : G.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: G.y < 0 ? 0 : G.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: G.y < 0 ? -G.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5175
+ if ((h || r) && (Z.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Z.x = Math.max(-0.9, Math.min(0.9, 2 * Z.x - 0.5)), Z.y = Math.max(-0.9, Math.min(0.9, -2.5 * Z.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Z.x < 0 ? -Z.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Z.x < 0 ? 0 : Z.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Z.y < 0 ? -Z.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) && 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(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
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 && (J.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(J)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.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 f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5202
- a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.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), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5201
+ let a = new f.Spherical().setFromVector3(this.cameraStart), d = new f.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
  }
@@ -5261,17 +5261,17 @@ class Be {
5261
5261
  speakText(t, e = null, n = null, i = null) {
5262
5262
  e = e || {};
5263
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 = "", c = 0, d = [], g = [];
5264
+ let u = "", a = "", d = 0, c = [], g = [];
5265
5265
  const b = Array.from(this.segmenter.segment(t), (x) => x.segment);
5266
5266
  for (let x = 0; x < b.length; x++) {
5267
- const A = x === b.length - 1, B = b[x].match(l);
5267
+ const S = x === b.length - 1, G = b[x].match(l);
5268
5268
  let p = b[x].match(s);
5269
- const E = b[x].match(h), I = b[x].match(o);
5270
- if (p && !A && !E && b[x + 1].match(s) && (p = !1), n && (u += b[x]), B && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (I || p || A) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5271
- mark: c,
5269
+ const P = b[x].match(h), H = b[x].match(o);
5270
+ if (p && !S && !P && b[x + 1].match(s) && (p = !1), n && (u += b[x]), G && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (H || p || S) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5271
+ mark: d,
5272
5272
  word: a
5273
5273
  })), u.length && (g.push({
5274
- mark: c,
5274
+ mark: d,
5275
5275
  template: { name: "subtitles" },
5276
5276
  ts: [0],
5277
5277
  vs: {
@@ -5280,27 +5280,27 @@ class Be {
5280
5280
  }), u = ""), a.length)) {
5281
5281
  const y = this.lipsyncWordsToVisemes(a, r);
5282
5282
  if (y && y.visemes && y.visemes.length) {
5283
- const H = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
- for (let w = 0; w < y.visemes.length; w++)
5283
+ const I = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
+ for (let z = 0; z < y.visemes.length; z++)
5285
5285
  g.push({
5286
- mark: c,
5286
+ mark: d,
5287
5287
  template: { name: "viseme" },
5288
- ts: [(y.times[w] - 0.6) / H, (y.times[w] + 0.5) / H, (y.times[w] + y.durations[w] + 0.5) / H],
5288
+ ts: [(y.times[z] - 0.6) / I, (y.times[z] + 0.5) / I, (y.times[z] + y.durations[z] + 0.5) / I],
5289
5289
  vs: {
5290
- ["viseme_" + y.visemes[w]]: [null, y.visemes[w] === "PP" || y.visemes[w] === "FF" ? 0.9 : 0.6, 0]
5290
+ ["viseme_" + y.visemes[z]]: [null, y.visemes[z] === "PP" || y.visemes[z] === "FF" ? 0.9 : 0.6, 0]
5291
5291
  }
5292
5292
  });
5293
5293
  }
5294
- a = "", c++;
5294
+ a = "", d++;
5295
5295
  }
5296
- if (p || A) {
5297
- if (d.length || A && g.length) {
5296
+ if (p || S) {
5297
+ if (c.length || S && g.length) {
5298
5298
  const y = {
5299
5299
  anim: g
5300
5300
  };
5301
- n && (y.onSubtitles = n), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], a = "", c = 0, g = [];
5301
+ n && (y.onSubtitles = n), c.length && !e.avatarMute && (y.text = c, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), c = [], a = "", d = 0, g = [];
5302
5302
  }
5303
- if (E) {
5303
+ if (P) {
5304
5304
  let y = this.animEmojis[b[x]];
5305
5305
  y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5306
5306
  }
@@ -5392,18 +5392,18 @@ class Be {
5392
5392
  subtitles: [" " + h]
5393
5393
  }
5394
5394
  }), !t.visemes)) {
5395
- const a = this.lipsyncPreProcessText(h, i), c = this.lipsyncWordsToVisemes(a, i);
5396
- if (c && c.visemes && c.visemes.length) {
5397
- const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(u, Math.max(0, u - c.visemes.length * 150));
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
5398
  let b = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5399
- if (u = Math.min(u, c.visemes.length * 200), d > 0)
5400
- for (let x = 0; x < c.visemes.length; x++) {
5401
- const A = r + c.times[x] / d * u, B = c.durations[x] / d * u;
5399
+ if (u = Math.min(u, d.visemes.length * 200), c > 0)
5400
+ for (let x = 0; x < d.visemes.length; x++) {
5401
+ const S = r + d.times[x] / c * u, G = d.durations[x] / c * u;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [A - Math.min(60, 2 * B / 3), A + Math.min(25, B / 2), A + B + Math.min(60, B / 2)],
5404
+ ts: [S - Math.min(60, 2 * G / 3), S + Math.min(25, G / 2), S + G + Math.min(60, G / 2)],
5405
5405
  vs: {
5406
- ["viseme_" + c.visemes[x]]: [null, c.visemes[x] === "PP" || c.visemes[x] === "FF" ? 0.9 : b, 0]
5406
+ ["viseme_" + d.visemes[x]]: [null, d.visemes[x] === "PP" || d.visemes[x] === "FF" ? 0.9 : b, 0]
5407
5407
  }
5408
5408
  });
5409
5409
  }
@@ -5483,34 +5483,34 @@ class Be {
5483
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
5484
  const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
5485
  if (a && u.length > 0) {
5486
- const p = u.find((E) => E.name.includes(a) || E.lang === o);
5486
+ const p = u.find((P) => P.name.includes(a) || P.lang === o);
5487
5487
  p && (s.voice = p);
5488
5488
  }
5489
- const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", b = this.lipsyncPreProcessText(i, g), x = this.lipsyncWordsToVisemes(b, g);
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", b = this.lipsyncPreProcessText(i, g), x = this.lipsyncWordsToVisemes(b, g);
5490
5490
  console.log("Browser TTS Lip-sync Debug:", {
5491
5491
  text: i,
5492
5492
  lipsyncLang: g,
5493
5493
  processedText: b,
5494
5494
  lipsyncData: x,
5495
5495
  hasVisemes: x && x.visemes && x.visemes.length > 0,
5496
- estimatedDuration: c
5496
+ estimatedDuration: d
5497
5497
  });
5498
- const A = [];
5498
+ const S = [];
5499
5499
  if (x && x.visemes && x.visemes.length > 0) {
5500
5500
  const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5501
- for (let E = 0; E < x.visemes.length; E++) {
5502
- const I = x.visemes[E], y = x.times[E] / p, H = x.durations[E] / p, w = y * c, D = H * c;
5503
- A.push({
5501
+ for (let P = 0; P < x.visemes.length; P++) {
5502
+ const H = x.visemes[P], y = x.times[P] / p, I = x.durations[P] / p, z = y * d, A = I * d;
5503
+ S.push({
5504
5504
  template: { name: "viseme" },
5505
- ts: [w - Math.min(60, 2 * D / 3), w + Math.min(25, D / 2), w + D + Math.min(60, D / 2)],
5505
+ ts: [z - Math.min(60, 2 * A / 3), z + Math.min(25, A / 2), z + A + Math.min(60, A / 2)],
5506
5506
  vs: {
5507
- ["viseme_" + I]: [null, I === "PP" || I === "FF" ? 0.9 : 0.6, 0]
5507
+ ["viseme_" + H]: [null, H === "PP" || H === "FF" ? 0.9 : 0.6, 0]
5508
5508
  }
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const B = [...t.anim, ...A];
5513
- this.audioPlaylist.push({ anim: B, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5512
+ const G = [...t.anim, ...S];
5513
+ this.audioPlaylist.push({ anim: G, 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((c) => c.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "21m00Tcm4TlvDq8ikWAM", i = {
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: {
@@ -5552,18 +5552,18 @@ class Be {
5552
5552
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5553
5553
  lipsyncLang: h
5554
5554
  });
5555
- const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
5555
+ const d = this.lipsyncPreProcessText(e, h), c = this.lipsyncWordsToVisemes(d, h);
5556
5556
  if (console.log("Lip-sync data:", {
5557
- processedText: c,
5558
- lipsyncData: d,
5559
- hasVisemes: d && d.visemes && d.visemes.length > 0
5560
- }), d && d.visemes && d.visemes.length > 0)
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: d.visemes.map((g, b) => ({
5562
+ visemes: c.visemes.map((g, b) => ({
5563
5563
  viseme: g,
5564
- startTime: b * l.duration / d.visemes.length,
5565
- endTime: (b + 1) * l.duration / d.visemes.length,
5566
- duration: l.duration / d.visemes.length,
5564
+ startTime: b * l.duration / c.visemes.length,
5565
+ endTime: (b + 1) * l.duration / c.visemes.length,
5566
+ duration: l.duration / c.visemes.length,
5567
5567
  intensity: 0.7
5568
5568
  })),
5569
5569
  words: [],
@@ -5572,13 +5572,13 @@ class Be {
5572
5572
  };
5573
5573
  else
5574
5574
  throw new Error("No visemes generated from text");
5575
- } catch (c) {
5576
- console.error("Text-based lip-sync failed, using fallback:", c);
5577
- const d = e.toLowerCase().split(/\s+/), g = [];
5578
- for (const b of d)
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 b of c)
5579
5579
  for (const x of b) {
5580
- let A = "aa";
5581
- "aeiou".includes(x) ? A = "aa" : "bp".includes(x) ? A = "PP" : "fv".includes(x) ? A = "FF" : "st".includes(x) ? A = "SS" : "dln".includes(x) ? A = "DD" : "kg".includes(x) ? A = "kk" : "rw".includes(x) && (A = "RR"), g.push(A);
5580
+ let S = "aa";
5581
+ "aeiou".includes(x) ? S = "aa" : "bp".includes(x) ? S = "PP" : "fv".includes(x) ? S = "FF" : "st".includes(x) ? S = "SS" : "dln".includes(x) ? S = "DD" : "kg".includes(x) ? S = "kk" : "rw".includes(x) && (S = "RR"), g.push(S);
5582
5582
  }
5583
5583
  r = {
5584
5584
  visemes: g.map((b, x) => ({
@@ -5608,13 +5608,13 @@ class Be {
5608
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 c = 0; c < r.visemes.length; c++) {
5612
- const d = r.visemes[c], g = d.startTime * 1e3, b = d.duration * 1e3, x = d.intensity;
5611
+ for (let d = 0; d < r.visemes.length; d++) {
5612
+ const c = r.visemes[d], g = c.startTime * 1e3, b = c.duration * 1e3, x = c.intensity;
5613
5613
  u.push({
5614
5614
  template: { name: "viseme" },
5615
5615
  ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
5616
5616
  vs: {
5617
- ["viseme_" + d.viseme]: [null, x, 0]
5617
+ ["viseme_" + c.viseme]: [null, x, 0]
5618
5618
  }
5619
5619
  });
5620
5620
  }
@@ -5629,7 +5629,7 @@ class Be {
5629
5629
  * @param {Object} line Speech line object
5630
5630
  */
5631
5631
  async synthesizeWithDeepgramTTS(t) {
5632
- const e = t.text.map((c) => c.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, {
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}`,
@@ -5650,18 +5650,18 @@ class Be {
5650
5650
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5651
5651
  lipsyncLang: h
5652
5652
  });
5653
- const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
5653
+ const d = this.lipsyncPreProcessText(e, h), c = this.lipsyncWordsToVisemes(d, h);
5654
5654
  if (console.log("Lip-sync data:", {
5655
- processedText: c,
5656
- lipsyncData: d,
5657
- hasVisemes: d && d.visemes && d.visemes.length > 0
5658
- }), d && d.visemes && d.visemes.length > 0)
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: d.visemes.map((g, b) => ({
5660
+ visemes: c.visemes.map((g, b) => ({
5661
5661
  viseme: g,
5662
- startTime: b * l.duration / d.visemes.length,
5663
- endTime: (b + 1) * l.duration / d.visemes.length,
5664
- duration: l.duration / d.visemes.length,
5662
+ startTime: b * l.duration / c.visemes.length,
5663
+ endTime: (b + 1) * l.duration / c.visemes.length,
5664
+ duration: l.duration / c.visemes.length,
5665
5665
  intensity: 0.7
5666
5666
  })),
5667
5667
  words: [],
@@ -5670,13 +5670,13 @@ class Be {
5670
5670
  };
5671
5671
  else
5672
5672
  throw new Error("No visemes generated from text");
5673
- } catch (c) {
5674
- console.error("Text-based lip-sync failed, using fallback:", c);
5675
- const d = e.toLowerCase().split(/\s+/), g = [];
5676
- for (const b of d)
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 b of c)
5677
5677
  for (const x of b) {
5678
- let A = "aa";
5679
- "aeiou".includes(x) ? A = "aa" : "bp".includes(x) ? A = "PP" : "fv".includes(x) ? A = "FF" : "st".includes(x) ? A = "SS" : "dln".includes(x) ? A = "DD" : "kg".includes(x) ? A = "kk" : "rw".includes(x) && (A = "RR"), g.push(A);
5678
+ let S = "aa";
5679
+ "aeiou".includes(x) ? S = "aa" : "bp".includes(x) ? S = "PP" : "fv".includes(x) ? S = "FF" : "st".includes(x) ? S = "SS" : "dln".includes(x) ? S = "DD" : "kg".includes(x) ? S = "kk" : "rw".includes(x) && (S = "RR"), g.push(S);
5680
5680
  }
5681
5681
  r = {
5682
5682
  visemes: g.map((b, x) => ({
@@ -5706,13 +5706,13 @@ class Be {
5706
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 c = 0; c < r.visemes.length; c++) {
5710
- const d = r.visemes[c], g = d.startTime * 1e3, b = d.duration * 1e3, x = d.intensity;
5709
+ for (let d = 0; d < r.visemes.length; d++) {
5710
+ const c = r.visemes[d], g = c.startTime * 1e3, b = c.duration * 1e3, x = c.intensity;
5711
5711
  u.push({
5712
5712
  template: { name: "viseme" },
5713
5713
  ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
5714
5714
  vs: {
5715
- ["viseme_" + d.viseme]: [null, x, 0]
5715
+ ["viseme_" + c.viseme]: [null, x, 0]
5716
5716
  }
5717
5717
  });
5718
5718
  }
@@ -5759,12 +5759,12 @@ class Be {
5759
5759
  });
5760
5760
  const r = [];
5761
5761
  for (let a = 0; a < h.visemes.length; a++) {
5762
- const c = h.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, b = c.intensity;
5762
+ const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, b = d.intensity;
5763
5763
  r.push({
5764
5764
  template: { name: "viseme" },
5765
- ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
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_" + c.viseme]: [null, b, 0]
5767
+ ["viseme_" + d.viseme]: [null, b, 0]
5768
5768
  }
5769
5769
  });
5770
5770
  }
@@ -5810,25 +5810,25 @@ class Be {
5810
5810
  this.speakWithHands();
5811
5811
  const h = [0];
5812
5812
  let r = 0;
5813
- t.text.forEach((c, d) => {
5814
- if (d > 0) {
5813
+ t.text.forEach((d, c) => {
5814
+ if (c > 0) {
5815
5815
  let g = h[h.length - 1];
5816
- s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), h.push(g);
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
5819
  const u = [{ mark: 0, time: 0 }];
5820
- h.forEach((c, d) => {
5821
- if (d > 0) {
5822
- let g = c - h[d - 1];
5823
- u[d - 1].duration = g, u.push({ mark: d, time: c });
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), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((c) => {
5828
- const d = u[c.mark];
5829
- if (d)
5830
- for (let g = 0; g < c.ts.length; g++)
5831
- c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
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);
@@ -6047,15 +6047,15 @@ class Be {
6047
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
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 c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6050
+ let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6051
6051
  if (o = Math.min(o, r.visemes.length * 200), u > 0)
6052
- for (let d = 0; d < r.visemes.length; d++) {
6053
- const g = e + s + r.times[d] / u * o, b = r.durations[d] / u * o;
6052
+ for (let c = 0; c < r.visemes.length; c++) {
6053
+ const g = e + s + r.times[c] / u * o, b = r.durations[c] / u * o;
6054
6054
  this.animQueue.push({
6055
6055
  template: { name: "viseme" },
6056
6056
  ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
6057
6057
  vs: {
6058
- ["viseme_" + r.visemes[d]]: [null, r.visemes[d] === "PP" || r.visemes[d] === "FF" ? 0.9 : c, 0]
6058
+ ["viseme_" + r.visemes[c]]: [null, r.visemes[c] === "PP" || r.visemes[c] === "FF" ? 0.9 : d, 0]
6059
6059
  }
6060
6060
  });
6061
6061
  }
@@ -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), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).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"]);
6162
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]);
6163
6163
  const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
- G.set(s, i, 0, "YXZ");
6165
- const l = new f.Quaternion().setFromEuler(G), h = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6166
- G.setFromQuaternion(h, "YXZ");
6167
- let r = G.x / (40 / 24) + 0.2, u = G.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6164
+ Z.set(s, i, 0, "YXZ");
6165
+ const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(J.clone().invert());
6166
+ Z.setFromQuaternion(h, "YXZ");
6167
+ let r = Z.x / (40 / 24) + 0.2, u = Z.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 b = this.animQueue.findIndex((A) => A.template.name === "lookat");
6169
+ let b = this.animQueue.findIndex((S) => S.template.name === "lookat");
6170
6170
  b !== -1 && this.animQueue.splice(b, 1);
6171
6171
  const x = {
6172
6172
  name: "lookat",
6173
6173
  dt: [750, t],
6174
6174
  vs: {
6175
- bodyRotateX: [a + d],
6176
- bodyRotateY: [c + g],
6177
- eyesRotateX: [-3 * d + 0.1],
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]],
@@ -6199,20 +6199,20 @@ class Be {
6199
6199
  const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
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"]), G.setFromQuaternion(Q);
6203
- let u = G.x / (40 / 24), a = G.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), b = Math.max(window.innerHeight - r, r), x = this.convertRange(e, [r - b, r + b], [-0.3, 0.6]) - u + c, A = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
6204
- x = Math.min(0.6, Math.max(-0.3, x)), A = Math.min(0.8, Math.max(-0.8, A));
6205
- let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6202
+ t === null && (t = h), e === null && (e = r), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion(J);
6203
+ let u = Z.x / (40 / 24), a = Z.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), b = Math.max(window.innerHeight - r, r), x = this.convertRange(e, [r - b, r + b], [-0.3, 0.6]) - u + d, S = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6204
+ x = Math.min(0.6, Math.max(-0.3, x)), S = Math.min(0.8, Math.max(-0.8, S));
6205
+ let G = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
- let E = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
- E !== -1 && this.animQueue.splice(E, 1);
6209
- const I = {
6207
+ let P = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
+ P !== -1 && this.animQueue.splice(P, 1);
6209
+ const H = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [x + B],
6214
- bodyRotateY: [A + p],
6215
- eyesRotateX: [-3 * B + 0.1],
6213
+ bodyRotateX: [x + G],
6214
+ bodyRotateY: [S + p],
6215
+ eyesRotateX: [-3 * G + 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(I));
6224
+ this.animQueue.push(this.animFactory(H));
6225
6225
  }
6226
6226
  }
6227
6227
  /**
@@ -6408,51 +6408,74 @@ class Be {
6408
6408
  }
6409
6409
  let r = !1;
6410
6410
  try {
6411
- const c = await fetch(t, { method: "HEAD" });
6412
- if (r = c.ok, !r) {
6413
- console.error(`FBX file not found at ${t}. Status: ${c.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)");
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)");
6414
6414
  return;
6415
6415
  }
6416
- } catch (c) {
6417
- console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6416
+ } catch (d) {
6417
+ console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, d);
6418
6418
  }
6419
6419
  const u = new De();
6420
6420
  let a;
6421
6421
  try {
6422
6422
  a = await u.loadAsync(t, e);
6423
- } catch (c) {
6424
- console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
6425
- message: c.message,
6423
+ } catch (d) {
6424
+ console.error(`Failed to load FBX animation from ${t}:`, d), console.error("Error details:", {
6425
+ message: d.message,
6426
6426
  url: t,
6427
6427
  suggestion: "Make sure the file is a valid FBX file and the path is correct"
6428
- }), c.message && c.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"));
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"));
6429
6429
  try {
6430
- const d = await fetch(t), g = d.headers.get("content-type"), b = await d.text();
6430
+ const c = await fetch(t), g = c.headers.get("content-type"), b = await c.text();
6431
6431
  console.error("Response details:", {
6432
- status: d.status,
6432
+ status: c.status,
6433
6433
  contentType: g,
6434
6434
  firstBytes: b.substring(0, 100),
6435
6435
  isHTML: b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")
6436
6436
  }), (b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6437
- } catch (d) {
6438
- console.error("Could not fetch file for debugging:", d);
6437
+ } catch (c) {
6438
+ console.error("Could not fetch file for debugging:", c);
6439
6439
  }
6440
6440
  return;
6441
6441
  }
6442
6442
  if (a && a.animations && a.animations[i]) {
6443
- let c = a.animations[i];
6444
- const d = /* @__PURE__ */ new Set();
6443
+ let d = a.animations[i];
6444
+ const c = /* @__PURE__ */ new Set();
6445
6445
  this.armature && this.armature.traverse((I) => {
6446
- (I.isBone || I.type === "Bone") && d.add(I.name);
6446
+ (I.isBone || I.type === "Bone") && c.add(I.name);
6447
6447
  });
6448
6448
  const g = /* @__PURE__ */ new Map(), b = (I) => {
6449
- if (d.has(I))
6449
+ if (c.has(I))
6450
6450
  return I;
6451
- let y = I.replace(/^mixamorig/i, "");
6452
- if (d.has(y))
6453
- return y;
6454
- const H = {
6455
- // Arm bones - handle common variations
6451
+ let z = I.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
6452
+ if (c.has(z))
6453
+ return z;
6454
+ const A = z.toLowerCase();
6455
+ if (A.includes("left") && A.includes("arm")) {
6456
+ if (A.includes("fore") || A.includes("lower")) {
6457
+ if (c.has("LeftForeArm")) return "LeftForeArm";
6458
+ if (c.has("LeftForearm")) return "LeftForearm";
6459
+ } else if (!A.includes("fore") && !A.includes("hand") && c.has("LeftArm"))
6460
+ return "LeftArm";
6461
+ }
6462
+ if (A.includes("right") && A.includes("arm")) {
6463
+ if (A.includes("fore") || A.includes("lower")) {
6464
+ if (c.has("RightForeArm")) return "RightForeArm";
6465
+ if (c.has("RightForearm")) return "RightForearm";
6466
+ } else if (!A.includes("fore") && !A.includes("hand") && c.has("RightArm"))
6467
+ return "RightArm";
6468
+ }
6469
+ if (A.includes("left") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && c.has("LeftHand"))
6470
+ return "LeftHand";
6471
+ if (A.includes("right") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && c.has("RightHand"))
6472
+ return "RightHand";
6473
+ if (A.includes("left") && (A.includes("shoulder") || A.includes("clavicle")) && c.has("LeftShoulder"))
6474
+ return "LeftShoulder";
6475
+ if (A.includes("right") && (A.includes("shoulder") || A.includes("clavicle")) && c.has("RightShoulder"))
6476
+ return "RightShoulder";
6477
+ const Y = {
6478
+ // Arm bones - exact matches
6456
6479
  LeftArm: "LeftArm",
6457
6480
  leftArm: "LeftArm",
6458
6481
  LEFTARM: "LeftArm",
@@ -6491,51 +6514,91 @@ class Be {
6491
6514
  Root: "Hips",
6492
6515
  root: "Hips"
6493
6516
  };
6494
- if (H[y]) {
6495
- const w = H[y];
6496
- if (d.has(w))
6497
- return w;
6517
+ if (Y[z]) {
6518
+ const k = Y[z];
6519
+ if (c.has(k))
6520
+ return k;
6521
+ }
6522
+ for (const k of c)
6523
+ if (k.toLowerCase() === A)
6524
+ return k;
6525
+ for (const k of c) {
6526
+ const C = k.toLowerCase();
6527
+ if ((A.includes("left") && C.includes("left") || A.includes("right") && C.includes("right")) && (A.includes("arm") && C.includes("arm") && !C.includes("fore") || A.includes("forearm") && C.includes("forearm") || A.includes("hand") && C.includes("hand") && !C.includes("index") && !C.includes("thumb") || A.includes("shoulder") && C.includes("shoulder")))
6528
+ return k;
6498
6529
  }
6499
- for (const w of d)
6500
- if (w.toLowerCase() === y.toLowerCase())
6501
- return w;
6502
6530
  return null;
6503
6531
  }, x = /* @__PURE__ */ new Set();
6504
- c.tracks.forEach((I) => {
6505
- const y = I.name.split(".");
6506
- x.add(y[0]);
6507
- }), console.log("Ready Player Me FBX bone names:", Array.from(x).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(d).sort().join(", "));
6508
- const A = [], B = /* @__PURE__ */ new Set();
6509
- c.tracks.forEach((I) => {
6510
- const H = I.name.replaceAll("mixamorig", "").split("."), w = H[0], D = H[1], $ = b(w);
6511
- if ($ && D) {
6512
- const k = `${$}.${D}`, V = I.clone();
6513
- V.name = k, A.push(V), w !== $ && g.set(w, $);
6532
+ d.tracks.forEach((I) => {
6533
+ const z = I.name.split(".");
6534
+ x.add(z[0]);
6535
+ }), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(x).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
6536
+ const S = Array.from(x).filter(
6537
+ (I) => I.toLowerCase().includes("arm") || I.toLowerCase().includes("hand") || I.toLowerCase().includes("shoulder")
6538
+ ), G = Array.from(c).filter(
6539
+ (I) => I.includes("Arm") || I.includes("Hand") || I.includes("Shoulder")
6540
+ );
6541
+ console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", G.sort().join(", "));
6542
+ const p = [], P = /* @__PURE__ */ new Set();
6543
+ if (d.tracks.forEach((I) => {
6544
+ const A = I.name.replaceAll("mixamorig", "").split("."), Y = A[0], k = A[1], C = b(Y);
6545
+ if (C && k) {
6546
+ const _ = `${C}.${k}`, B = I.clone();
6547
+ B.name = _;
6548
+ const ee = C.includes("Arm") || C.includes("Hand") || C.includes("Shoulder");
6549
+ C.includes("Left"), C.includes("Right");
6550
+ const ie = C.includes("ForeArm") || C.includes("Forearm"), oe = C.includes("Hand") && !C.includes("Index") && !C.includes("Thumb") && !C.includes("Middle") && !C.includes("Ring") && !C.includes("Pinky");
6551
+ if (ee && (k === "quaternion" || k === "rotation") && k === "quaternion" && B.values && B.values.length >= 4) {
6552
+ const he = B.times.length;
6553
+ for (let K = 0; K < he; K++) {
6554
+ const Q = K * 4;
6555
+ if (Q + 3 < B.values.length) {
6556
+ let W = B.values[Q], v = B.values[Q + 1], R = B.values[Q + 2], T = B.values[Q + 3];
6557
+ const M = new f.Quaternion(W, v, R, T);
6558
+ if (oe) {
6559
+ const O = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI);
6560
+ M.multiply(O);
6561
+ } else if (ie) {
6562
+ const O = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 0, 1), Math.PI / 2);
6563
+ M.multiply(O);
6564
+ }
6565
+ B.values[Q] = M.x, B.values[Q + 1] = M.y, B.values[Q + 2] = M.z, B.values[Q + 3] = M.w;
6566
+ }
6567
+ }
6568
+ }
6569
+ p.push(B), Y !== C && g.set(Y, C);
6514
6570
  } else
6515
- B.add(w), (w.toLowerCase().includes("arm") || w.toLowerCase().includes("hand") || w.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${w}" could not be mapped to avatar skeleton`);
6516
- }), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), A.length > 0 && (c = new f.AnimationClip(c.name, c.duration, A), g.size > 0 && console.log(
6517
- `Mapped ${g.size} bone(s) for Ready Player Me animation:`,
6518
- Array.from(g.entries()).slice(0, 5).map(([I, y]) => `${I}→${y}`).join(", ")
6519
- ));
6520
- const p = {};
6521
- c.tracks.forEach((I) => {
6571
+ P.add(Y), (Y.toLowerCase().includes("arm") || Y.toLowerCase().includes("hand") || Y.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${Y}" could not be mapped to avatar skeleton`);
6572
+ }), P.size > 0 && console.warn(`⚠️ ${P.size} bone(s) could not be mapped:`, Array.from(P).sort().join(", ")), p.length > 0) {
6573
+ d = new f.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
6574
+ `✓ Mapped ${g.size} bone(s):`,
6575
+ Array.from(g.entries()).map(([z, A]) => `${z}→${A}`).join(", ")
6576
+ );
6577
+ const I = Array.from(g.values()).filter(
6578
+ (z) => z.includes("Arm") || z.includes("Hand") || z.includes("Shoulder")
6579
+ );
6580
+ I.length > 0 ? console.log(`✓ Arm bones mapped: ${I.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
6581
+ } else
6582
+ console.error("❌ No tracks could be mapped! Animation may not work correctly.");
6583
+ const H = {};
6584
+ d.tracks.forEach((I) => {
6522
6585
  I.name = I.name.replaceAll("mixamorig", "");
6523
- const y = I.name.split(".");
6524
- if (y[1] === "position") {
6525
- for (let H = 0; H < I.values.length; H++)
6526
- I.values[H] = I.values[H] * s;
6527
- p[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6528
- } else y[1] === "quaternion" ? p[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : y[1] === "rotation" && (p[y[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6586
+ const z = I.name.split(".");
6587
+ if (z[1] === "position") {
6588
+ for (let A = 0; A < I.values.length; A++)
6589
+ I.values[A] = I.values[A] * s;
6590
+ H[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6591
+ } else z[1] === "quaternion" ? H[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : z[1] === "rotation" && (H[z[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6529
6592
  });
6530
- const E = { props: p };
6531
- p["Hips.position"] && (p["Hips.position"].y < 0.5 ? E.lying = !0 : E.standing = !0), this.animClips.push({
6593
+ const y = { props: H };
6594
+ H["Hips.position"] && (H["Hips.position"].y < 0.5 ? y.lying = !0 : y.standing = !0), this.animClips.push({
6532
6595
  url: t + "-" + i,
6533
- clip: c,
6534
- pose: E
6596
+ clip: d,
6597
+ pose: y
6535
6598
  }), this.playAnimation(t, e, n, i, s);
6536
6599
  } else {
6537
- const c = "Animation " + t + " (ndx=" + i + ") not found";
6538
- console.error(c), 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");
6600
+ const d = "Animation " + t + " (ndx=" + i + ") not found";
6601
+ 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");
6539
6602
  }
6540
6603
  }
6541
6604
  }
@@ -6573,10 +6636,10 @@ class Be {
6573
6636
  if (h && h.animations && h.animations[i]) {
6574
6637
  let r = h.animations[i];
6575
6638
  const u = {};
6576
- r.tracks.forEach((c) => {
6577
- c.name = c.name.replaceAll("mixamorig", "");
6578
- const d = c.name.split(".");
6579
- d[1] === "position" ? u[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6639
+ r.tracks.forEach((d) => {
6640
+ d.name = d.name.replaceAll("mixamorig", "");
6641
+ const c = d.name.split(".");
6642
+ c[1] === "position" ? u[d.name] = new f.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : c[1] === "quaternion" ? u[d.name] = new f.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : c[1] === "rotation" && (u[c[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
6580
6643
  });
6581
6644
  const a = { props: u };
6582
6645
  u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6621,13 +6684,13 @@ class Be {
6621
6684
  if (l.gesture = !0, e && Number.isFinite(e)) {
6622
6685
  const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
6623
6686
  if (e * 1e3 - u > 0) {
6624
- const c = [];
6625
- for (let b = 1; b < l.ts.length; b++) c.push(l.ts[b] - l.ts[b - 1]);
6626
- const d = o.template?.rescale || c.map((b) => b / u), g = e * 1e3 - u;
6627
- l.ts = l.ts.map((b, x, A) => x === 0 ? h : A[x - 1] + c[x - 1] + d[x - 1] * g);
6687
+ const d = [];
6688
+ for (let b = 1; b < l.ts.length; b++) d.push(l.ts[b] - l.ts[b - 1]);
6689
+ const c = o.template?.rescale || d.map((b) => b / u), g = e * 1e3 - u;
6690
+ l.ts = l.ts.map((b, x, S) => x === 0 ? h : S[x - 1] + d[x - 1] + c[x - 1] * g);
6628
6691
  } else {
6629
- const c = e * 1e3 / u;
6630
- l.ts = l.ts.map((d) => h + c * (d - h));
6692
+ const d = e * 1e3 / u;
6693
+ l.ts = l.ts.map((c) => h + d * (c - h));
6631
6694
  }
6632
6695
  }
6633
6696
  this.animQueue.push(l);
@@ -6657,21 +6720,21 @@ class Be {
6657
6720
  * @param {numeric} [d=null] If set, apply in d milliseconds
6658
6721
  */
6659
6722
  ikSolve(t, e = null, n = !1, i = null) {
6660
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), h = new f.Vector3(), r = new f.Quaternion(), u = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6661
- d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
6723
+ const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), h = new f.Vector3(), r = new f.Quaternion(), u = new f.Vector3(), a = new f.Vector3(), d = new f.Vector3(), c = this.ikMesh.getObjectByName(t.root);
6724
+ 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);
6662
6725
  const g = this.ikMesh.getObjectByName(t.effector), b = t.links;
6663
- b.forEach((A) => {
6664
- A.bone = this.ikMesh.getObjectByName(A.link), A.bone.quaternion.copy(this.getPoseTemplateProp(A.link + ".quaternion"));
6665
- }), d.updateMatrixWorld(!0);
6726
+ b.forEach((S) => {
6727
+ S.bone = this.ikMesh.getObjectByName(S.link), S.bone.quaternion.copy(this.getPoseTemplateProp(S.link + ".quaternion"));
6728
+ }), c.updateMatrixWorld(!0);
6666
6729
  const x = t.iterations || 10;
6667
6730
  if (e)
6668
- for (let A = 0; A < x; A++) {
6669
- let B = !1;
6670
- for (let p = 0, E = b.length; p < E; p++) {
6671
- const I = b[p].bone;
6672
- I.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();
6731
+ for (let S = 0; S < x; S++) {
6732
+ let G = !1;
6733
+ for (let p = 0, P = b.length; p < P; p++) {
6734
+ const H = b[p].bone;
6735
+ H.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();
6673
6736
  let y = s.dot(l);
6674
- y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (b[p].minAngle !== void 0 && y < b[p].minAngle && (y = b[p].minAngle), b[p].maxAngle !== void 0 && y > b[p].maxAngle && (y = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), I.quaternion.multiply(Q), I.rotation.setFromVector3(c.setFromEuler(I.rotation).clamp(new f.Vector3(
6737
+ y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (b[p].minAngle !== void 0 && y < b[p].minAngle && (y = b[p].minAngle), b[p].maxAngle !== void 0 && y > b[p].maxAngle && (y = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), J.setFromAxisAngle(a, y), H.quaternion.multiply(J), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new f.Vector3(
6675
6738
  b[p].minx !== void 0 ? b[p].minx : -1 / 0,
6676
6739
  b[p].miny !== void 0 ? b[p].miny : -1 / 0,
6677
6740
  b[p].minz !== void 0 ? b[p].minz : -1 / 0
@@ -6679,12 +6742,12 @@ class Be {
6679
6742
  b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
6680
6743
  b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
6681
6744
  b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
6682
- ))), I.updateMatrixWorld(!0), B = !0);
6745
+ ))), H.updateMatrixWorld(!0), G = !0);
6683
6746
  }
6684
- if (!B) break;
6747
+ if (!G) break;
6685
6748
  }
6686
- i && b.forEach((A) => {
6687
- this.poseTarget.props[A.link + ".quaternion"].copy(A.bone.quaternion), this.poseTarget.props[A.link + ".quaternion"].t = this.animClock, this.poseTarget.props[A.link + ".quaternion"].d = i;
6749
+ i && b.forEach((S) => {
6750
+ this.poseTarget.props[S.link + ".quaternion"].copy(S.bone.quaternion), this.poseTarget.props[S.link + ".quaternion"].t = this.animClock, this.poseTarget.props[S.link + ".quaternion"].d = i;
6688
6751
  });
6689
6752
  }
6690
6753
  /**
@@ -6734,7 +6797,7 @@ const Ie = {
6734
6797
  // Male, English - Powerful
6735
6798
  }
6736
6799
  };
6737
- function Fe() {
6800
+ function Ee() {
6738
6801
  return {
6739
6802
  service: "elevenlabs",
6740
6803
  endpoint: Ie.endpoint,
@@ -6744,16 +6807,16 @@ function Fe() {
6744
6807
  };
6745
6808
  }
6746
6809
  function kt() {
6747
- const Z = Fe(), t = [];
6748
- return Object.entries(Z.voices).forEach(([e, n]) => {
6810
+ const X = Ee(), t = [];
6811
+ return Object.entries(X.voices).forEach(([e, n]) => {
6749
6812
  t.push({
6750
6813
  value: n,
6751
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${Z.service})`
6814
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${X.service})`
6752
6815
  });
6753
6816
  }), t;
6754
6817
  }
6755
6818
  const Ve = Me(({
6756
- avatarUrl: Z = "/avatars/brunette.glb",
6819
+ avatarUrl: X = "/avatars/brunette.glb",
6757
6820
  avatarBody: t = "F",
6758
6821
  mood: e = "neutral",
6759
6822
  ttsLang: n = "en",
@@ -6766,222 +6829,222 @@ const Ve = Me(({
6766
6829
  cameraView: u = "upper",
6767
6830
  onReady: a = () => {
6768
6831
  },
6769
- onLoading: c = () => {
6832
+ onLoading: d = () => {
6770
6833
  },
6771
- onError: d = () => {
6834
+ onError: c = () => {
6772
6835
  },
6773
6836
  className: g = "",
6774
6837
  style: b = {},
6775
6838
  animations: x = {}
6776
- }, A) => {
6777
- const B = O(null), p = O(null), E = O(r), I = O(null), y = O(null), H = O(!1), w = O({ remainingText: null, originalText: null, options: null }), D = O([]), $ = O(0), [k, V] = ce(!0), [K, X] = ce(null), [ee, se] = ce(!1), [ae, pe] = ce(!1);
6778
- de(() => {
6779
- H.current = ae;
6780
- }, [ae]), de(() => {
6781
- E.current = r;
6839
+ }, S) => {
6840
+ const G = V(null), p = V(null), P = V(r), H = V(null), y = V(null), I = V(!1), z = V({ remainingText: null, originalText: null, options: null }), A = V([]), Y = V(0), [k, C] = de(!0), [_, B] = de(null), [ee, ie] = de(!1), [oe, he] = de(!1);
6841
+ me(() => {
6842
+ I.current = oe;
6843
+ }, [oe]), me(() => {
6844
+ P.current = r;
6782
6845
  }, [r]);
6783
- const te = Fe(), le = i || te.service;
6784
- let U;
6785
- le === "browser" ? U = {
6846
+ const K = Ee(), Q = i || K.service;
6847
+ let W;
6848
+ Q === "browser" ? W = {
6786
6849
  service: "browser",
6787
6850
  endpoint: "",
6788
6851
  apiKey: null,
6789
6852
  defaultVoice: "Google US English"
6790
- } : le === "elevenlabs" ? U = {
6853
+ } : Q === "elevenlabs" ? W = {
6791
6854
  service: "elevenlabs",
6792
6855
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6793
- apiKey: o || te.apiKey,
6794
- defaultVoice: s || te.defaultVoice || Ie.defaultVoice,
6795
- voices: te.voices || Ie.voices
6796
- } : le === "deepgram" ? U = {
6856
+ apiKey: o || K.apiKey,
6857
+ defaultVoice: s || K.defaultVoice || Ie.defaultVoice,
6858
+ voices: K.voices || Ie.voices
6859
+ } : Q === "deepgram" ? W = {
6797
6860
  service: "deepgram",
6798
6861
  endpoint: "https://api.deepgram.com/v1/speak",
6799
- apiKey: o || te.apiKey,
6800
- defaultVoice: s || te.defaultVoice || Te.defaultVoice,
6801
- voices: te.voices || Te.voices
6802
- } : U = {
6803
- ...te,
6862
+ apiKey: o || K.apiKey,
6863
+ defaultVoice: s || K.defaultVoice || Te.defaultVoice,
6864
+ voices: K.voices || Te.voices
6865
+ } : W = {
6866
+ ...K,
6804
6867
  // Override API key if provided via props
6805
- apiKey: o !== null ? o : te.apiKey
6868
+ apiKey: o !== null ? o : K.apiKey
6806
6869
  };
6807
6870
  const v = {
6808
- url: Z,
6871
+ url: X,
6809
6872
  body: t,
6810
6873
  avatarMood: e,
6811
- ttsLang: le === "browser" ? "en-US" : n,
6812
- ttsVoice: s || U.defaultVoice,
6874
+ ttsLang: Q === "browser" ? "en-US" : n,
6875
+ ttsVoice: s || W.defaultVoice,
6813
6876
  lipsyncLang: "en",
6814
6877
  showFullAvatar: r,
6815
6878
  bodyMovement: l,
6816
6879
  movementIntensity: h
6817
6880
  }, R = {
6818
- ttsEndpoint: U.endpoint,
6819
- ttsApikey: U.apiKey,
6820
- ttsService: le,
6881
+ ttsEndpoint: W.endpoint,
6882
+ ttsApikey: W.apiKey,
6883
+ ttsService: Q,
6821
6884
  lipsyncModules: ["en"],
6822
6885
  cameraView: u
6823
- }, z = F(async () => {
6824
- if (!(!B.current || p.current))
6886
+ }, T = N(async () => {
6887
+ if (!(!G.current || p.current))
6825
6888
  try {
6826
- if (V(!0), X(null), p.current = new Be(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(v, (N) => {
6827
- if (N.lengthComputable) {
6828
- const J = Math.min(100, Math.round(N.loaded / N.total * 100));
6829
- c(J);
6889
+ if (C(!0), B(null), p.current = new Be(G.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(v, (U) => {
6890
+ if (U.lengthComputable) {
6891
+ const ne = Math.min(100, Math.round(U.loaded / U.total * 100));
6892
+ d(ne);
6830
6893
  }
6831
- }), await new Promise((N) => {
6832
- const J = () => {
6833
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? N() : setTimeout(J, 100);
6894
+ }), await new Promise((U) => {
6895
+ const ne = () => {
6896
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? U() : setTimeout(ne, 100);
6834
6897
  };
6835
- J();
6898
+ ne();
6836
6899
  }), p.current && p.current.setShowFullAvatar)
6837
6900
  try {
6838
6901
  p.current.setShowFullAvatar(r);
6839
- } catch (N) {
6840
- console.warn("Error setting full body mode on initialization:", N);
6902
+ } catch (U) {
6903
+ console.warn("Error setting full body mode on initialization:", U);
6841
6904
  }
6842
- 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()), V(!1), se(!0), a(p.current);
6843
- const P = () => {
6905
+ 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()), C(!1), ie(!0), a(p.current);
6906
+ const D = () => {
6844
6907
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6845
6908
  };
6846
- return document.addEventListener("visibilitychange", P), () => {
6847
- document.removeEventListener("visibilitychange", P);
6909
+ return document.addEventListener("visibilitychange", D), () => {
6910
+ document.removeEventListener("visibilitychange", D);
6848
6911
  };
6849
6912
  } catch (L) {
6850
- console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), V(!1), d(L);
6913
+ console.error("Error initializing TalkingHead:", L), B(L.message || "Failed to initialize avatar"), C(!1), c(L);
6851
6914
  }
6852
- }, [Z, t, e, n, i, s, o, r, l, h, u]);
6853
- de(() => (z(), () => {
6915
+ }, [X, t, e, n, i, s, o, r, l, h, u]);
6916
+ me(() => (T(), () => {
6854
6917
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6855
- }), [z]), de(() => {
6856
- if (!B.current || !p.current) return;
6857
- const L = new ResizeObserver((N) => {
6858
- for (const J of N)
6918
+ }), [T]), me(() => {
6919
+ if (!G.current || !p.current) return;
6920
+ const L = new ResizeObserver((U) => {
6921
+ for (const ne of U)
6859
6922
  p.current && p.current.onResize && p.current.onResize();
6860
6923
  });
6861
- L.observe(B.current);
6862
- const P = () => {
6924
+ L.observe(G.current);
6925
+ const D = () => {
6863
6926
  p.current && p.current.onResize && p.current.onResize();
6864
6927
  };
6865
- return window.addEventListener("resize", P), () => {
6866
- L.disconnect(), window.removeEventListener("resize", P);
6928
+ return window.addEventListener("resize", D), () => {
6929
+ L.disconnect(), window.removeEventListener("resize", D);
6867
6930
  };
6868
6931
  }, [ee]);
6869
- const M = F(async () => {
6932
+ const M = N(async () => {
6870
6933
  if (p.current && p.current.audioCtx)
6871
6934
  try {
6872
6935
  (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
6873
6936
  } catch (L) {
6874
6937
  console.warn("Failed to resume audio context:", L);
6875
6938
  }
6876
- }, []), W = F(async (L, P = {}) => {
6939
+ }, []), O = N(async (L, D = {}) => {
6877
6940
  if (p.current && ee)
6878
6941
  try {
6879
- y.current && (clearInterval(y.current), y.current = null), I.current = { text: L, options: P }, w.current = { remainingText: null, originalText: null, options: null };
6880
- const N = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(N).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6881
- D.current = J, $.current = 0, pe(!1), H.current = !1, await M();
6942
+ y.current && (clearInterval(y.current), y.current = null), H.current = { text: L, options: D }, z.current = { remainingText: null, originalText: null, options: null };
6943
+ const U = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = L.split(U).map((j) => j.trim()).filter((j) => j.length > 0);
6944
+ A.current = ne, Y.current = 0, he(!1), I.current = !1, await M();
6882
6945
  const ge = {
6883
- ...P,
6884
- lipsyncLang: P.lipsyncLang || v.lipsyncLang || "en"
6946
+ ...D,
6947
+ lipsyncLang: D.lipsyncLang || v.lipsyncLang || "en"
6885
6948
  };
6886
- if (P.onSpeechEnd && p.current) {
6887
- const Y = p.current;
6888
- let he = null, Se = 0;
6889
- const Ae = 1200;
6949
+ if (D.onSpeechEnd && p.current) {
6950
+ const j = p.current;
6951
+ let ce = null, Se = 0;
6952
+ const Le = 1200;
6890
6953
  let be = !1;
6891
- he = setInterval(() => {
6892
- if (Se++, H.current)
6954
+ ce = setInterval(() => {
6955
+ if (Se++, I.current)
6893
6956
  return;
6894
- if (Se > Ae) {
6895
- if (he && (clearInterval(he), he = null, y.current = null), !be && !H.current) {
6957
+ if (Se > Le) {
6958
+ if (ce && (clearInterval(ce), ce = null, y.current = null), !be && !I.current) {
6896
6959
  be = !0;
6897
6960
  try {
6898
- P.onSpeechEnd();
6961
+ D.onSpeechEnd();
6899
6962
  } catch (Ne) {
6900
6963
  console.error("Error in onSpeechEnd callback (timeout):", Ne);
6901
6964
  }
6902
6965
  }
6903
6966
  return;
6904
6967
  }
6905
- const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6906
- Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !H.current && setTimeout(() => {
6907
- if (Y && !H.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !H.current) {
6908
- be = !0, he && (clearInterval(he), he = null, y.current = null);
6968
+ const ye = !j.speechQueue || j.speechQueue.length === 0, ke = !j.audioPlaylist || j.audioPlaylist.length === 0;
6969
+ j && j.isSpeaking === !1 && ye && ke && j.isAudioPlaying === !1 && !be && !I.current && setTimeout(() => {
6970
+ if (j && !I.current && j.isSpeaking === !1 && (!j.speechQueue || j.speechQueue.length === 0) && (!j.audioPlaylist || j.audioPlaylist.length === 0) && j.isAudioPlaying === !1 && !be && !I.current) {
6971
+ be = !0, ce && (clearInterval(ce), ce = null, y.current = null);
6909
6972
  try {
6910
- P.onSpeechEnd();
6973
+ D.onSpeechEnd();
6911
6974
  } catch (Ze) {
6912
6975
  console.error("Error in onSpeechEnd callback:", Ze);
6913
6976
  }
6914
6977
  }
6915
6978
  }, 100);
6916
- }, 100), y.current = he;
6979
+ }, 100), y.current = ce;
6917
6980
  }
6918
6981
  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 () => {
6919
6982
  await M(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6920
6983
  }, 100);
6921
- } catch (N) {
6922
- console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
6984
+ } catch (U) {
6985
+ console.error("Error speaking text:", U), B(U.message || "Failed to speak text");
6923
6986
  }
6924
- }, [ee, M, v.lipsyncLang]), _ = F(() => {
6925
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), I.current = null, pe(!1));
6926
- }, []), j = F(() => {
6987
+ }, [ee, M, v.lipsyncLang]), te = N(() => {
6988
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), H.current = null, he(!1));
6989
+ }, []), q = N(() => {
6927
6990
  if (p.current && p.current.pauseSpeaking) {
6928
6991
  const L = p.current;
6929
6992
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6930
6993
  y.current && (clearInterval(y.current), y.current = null);
6931
- let N = "";
6932
- if (I.current && D.current.length > 0) {
6933
- const J = D.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;
6934
- if (he > 0 && Se < J && (N = D.current.slice(Se).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
6994
+ let U = "";
6995
+ if (H.current && A.current.length > 0) {
6996
+ const ne = A.current.length, ge = L.speechQueue ? L.speechQueue.filter((Le) => Le && Le.text && Array.isArray(Le.text) && Le.text.length > 0).length : 0, j = L.audioPlaylist && L.audioPlaylist.length > 0, ce = ge + (j ? 1 : 0), Se = ne - ce;
6997
+ if (ce > 0 && Se < ne && (U = A.current.slice(Se).join(". ").trim(), !U && ge > 0 && L.speechQueue)) {
6935
6998
  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(" ");
6936
- be && be.trim() && (N = be.trim());
6999
+ be && be.trim() && (U = be.trim());
6937
7000
  }
6938
7001
  }
6939
- I.current && (w.current = {
6940
- remainingText: N || null,
6941
- originalText: I.current.text,
6942
- options: I.current.options
6943
- }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), H.current = !0, pe(!0);
7002
+ H.current && (z.current = {
7003
+ remainingText: U || null,
7004
+ originalText: H.current.text,
7005
+ options: H.current.options
7006
+ }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0, he(!0);
6944
7007
  }
6945
7008
  }
6946
- }, []), q = F(async () => {
6947
- if (!p.current || !ae)
7009
+ }, []), $ = N(async () => {
7010
+ if (!p.current || !oe)
6948
7011
  return;
6949
- let L = "", P = {};
6950
- if (w.current && w.current.remainingText)
6951
- L = w.current.remainingText, P = w.current.options || {}, w.current = { remainingText: null, originalText: null, options: null };
6952
- else if (I.current && I.current.text)
6953
- L = I.current.text, P = I.current.options || {};
7012
+ let L = "", D = {};
7013
+ if (z.current && z.current.remainingText)
7014
+ L = z.current.remainingText, D = z.current.options || {}, z.current = { remainingText: null, originalText: null, options: null };
7015
+ else if (H.current && H.current.text)
7016
+ L = H.current.text, D = H.current.options || {};
6954
7017
  else {
6955
- console.warn("Resume called but no paused speech found"), pe(!1), H.current = !1;
7018
+ console.warn("Resume called but no paused speech found"), he(!1), I.current = !1;
6956
7019
  return;
6957
7020
  }
6958
- pe(!1), H.current = !1, await M();
6959
- const N = {
6960
- ...P,
6961
- lipsyncLang: P.lipsyncLang || v.lipsyncLang || "en"
7021
+ he(!1), I.current = !1, await M();
7022
+ const U = {
7023
+ ...D,
7024
+ lipsyncLang: D.lipsyncLang || v.lipsyncLang || "en"
6962
7025
  };
6963
7026
  try {
6964
- await W(L, N);
6965
- } catch (J) {
6966
- console.error("Error resuming speech:", J), pe(!1), H.current = !1;
7027
+ await O(L, U);
7028
+ } catch (ne) {
7029
+ console.error("Error resuming speech:", ne), he(!1), I.current = !1;
6967
7030
  }
6968
- }, [M, ae, W, v]), Le = F((L) => {
7031
+ }, [M, oe, O, v]), Ae = N((L) => {
6969
7032
  p.current && p.current.setMood(L);
6970
- }, []), we = F((L) => {
7033
+ }, []), we = N((L) => {
6971
7034
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
6972
- }, []), T = F((L, P = !1) => {
7035
+ }, []), E = N((L, D = !1) => {
6973
7036
  if (p.current && p.current.playAnimation) {
6974
7037
  if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
6975
7038
  try {
6976
- p.current.setShowFullAvatar(E.current);
6977
- } catch (J) {
6978
- console.warn("Error setting full body mode:", J);
7039
+ p.current.setShowFullAvatar(P.current);
7040
+ } catch (ne) {
7041
+ console.warn("Error setting full body mode:", ne);
6979
7042
  }
6980
7043
  if (L.includes("."))
6981
7044
  try {
6982
- p.current.playAnimation(L, null, 10, 0, 0.01, P);
6983
- } catch (J) {
6984
- console.warn(`Failed to play ${L}:`, J);
7045
+ p.current.playAnimation(L, null, 10, 0, 0.01, D);
7046
+ } catch (ne) {
7047
+ console.warn(`Failed to play ${L}:`, ne);
6985
7048
  try {
6986
7049
  p.current.setBodyMovement("idle");
6987
7050
  } catch (ge) {
@@ -6989,11 +7052,11 @@ const Ve = Me(({
6989
7052
  }
6990
7053
  }
6991
7054
  else {
6992
- const J = [".fbx", ".glb", ".gltf"];
7055
+ const ne = [".fbx", ".glb", ".gltf"];
6993
7056
  let ge = !1;
6994
- for (const Y of J)
7057
+ for (const j of ne)
6995
7058
  try {
6996
- p.current.playAnimation(L + Y, null, 10, 0, 0.01, P), ge = !0;
7059
+ p.current.playAnimation(L + j, null, 10, 0, 0.01, D), ge = !0;
6997
7060
  break;
6998
7061
  } catch {
6999
7062
  }
@@ -7001,41 +7064,41 @@ const Ve = Me(({
7001
7064
  console.warn("Animation not found:", L);
7002
7065
  try {
7003
7066
  p.current.setBodyMovement("idle");
7004
- } catch (Y) {
7005
- console.warn("Fallback animation also failed:", Y);
7067
+ } catch (j) {
7068
+ console.warn("Fallback animation also failed:", j);
7006
7069
  }
7007
7070
  }
7008
7071
  }
7009
7072
  }
7010
- }, [x]), ne = F(() => {
7073
+ }, [x]), se = N(() => {
7011
7074
  p.current && p.current.onResize && p.current.onResize();
7012
7075
  }, []);
7013
- return Ee(A, () => ({
7014
- speakText: W,
7015
- stopSpeaking: _,
7016
- pauseSpeaking: j,
7017
- resumeSpeaking: q,
7076
+ return Fe(S, () => ({
7077
+ speakText: O,
7078
+ stopSpeaking: te,
7079
+ pauseSpeaking: q,
7080
+ resumeSpeaking: $,
7018
7081
  resumeAudioContext: M,
7019
- setMood: Le,
7082
+ setMood: Ae,
7020
7083
  setTimingAdjustment: we,
7021
- playAnimation: T,
7084
+ playAnimation: E,
7022
7085
  isReady: ee,
7023
- isPaused: ae,
7086
+ isPaused: oe,
7024
7087
  talkingHead: p.current,
7025
- handleResize: ne,
7088
+ handleResize: se,
7026
7089
  setBodyMovement: (L) => {
7027
7090
  if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7028
7091
  try {
7029
- p.current.setShowFullAvatar(E.current), p.current.setBodyMovement(L);
7030
- } catch (P) {
7031
- console.warn("Error setting body movement:", P);
7092
+ p.current.setShowFullAvatar(P.current), p.current.setBodyMovement(L);
7093
+ } catch (D) {
7094
+ console.warn("Error setting body movement:", D);
7032
7095
  }
7033
7096
  },
7034
7097
  setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
7035
7098
  playRandomDance: () => {
7036
7099
  if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7037
7100
  try {
7038
- p.current.setShowFullAvatar(E.current), p.current.playRandomDance();
7101
+ p.current.setShowFullAvatar(P.current), p.current.playRandomDance();
7039
7102
  } catch (L) {
7040
7103
  console.warn("Error playing random dance:", L);
7041
7104
  }
@@ -7043,15 +7106,15 @@ const Ve = Me(({
7043
7106
  playReaction: (L) => {
7044
7107
  if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7045
7108
  try {
7046
- p.current.setShowFullAvatar(E.current), p.current.playReaction(L);
7047
- } catch (P) {
7048
- console.warn("Error playing reaction:", P);
7109
+ p.current.setShowFullAvatar(P.current), p.current.playReaction(L);
7110
+ } catch (D) {
7111
+ console.warn("Error playing reaction:", D);
7049
7112
  }
7050
7113
  },
7051
7114
  playCelebration: () => {
7052
7115
  if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7053
7116
  try {
7054
- p.current.setShowFullAvatar(E.current), p.current.playCelebration();
7117
+ p.current.setShowFullAvatar(P.current), p.current.playCelebration();
7055
7118
  } catch (L) {
7056
7119
  console.warn("Error playing celebration:", L);
7057
7120
  }
@@ -7059,9 +7122,9 @@ const Ve = Me(({
7059
7122
  setShowFullAvatar: (L) => {
7060
7123
  if (p.current && p.current.setShowFullAvatar)
7061
7124
  try {
7062
- E.current = L, p.current.setShowFullAvatar(L);
7063
- } catch (P) {
7064
- console.warn("Error setting showFullAvatar:", P);
7125
+ P.current = L, p.current.setShowFullAvatar(L);
7126
+ } catch (D) {
7127
+ console.warn("Error setting showFullAvatar:", D);
7065
7128
  }
7066
7129
  },
7067
7130
  lockAvatarPosition: () => {
@@ -7091,10 +7154,10 @@ const Ve = Me(({
7091
7154
  ...b
7092
7155
  },
7093
7156
  children: [
7094
- /* @__PURE__ */ me(
7157
+ /* @__PURE__ */ pe(
7095
7158
  "div",
7096
7159
  {
7097
- ref: B,
7160
+ ref: G,
7098
7161
  className: "talking-head-viewer",
7099
7162
  style: {
7100
7163
  width: "100%",
@@ -7103,7 +7166,7 @@ const Ve = Me(({
7103
7166
  }
7104
7167
  }
7105
7168
  ),
7106
- k && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7169
+ k && /* @__PURE__ */ pe("div", { className: "loading-overlay", style: {
7107
7170
  position: "absolute",
7108
7171
  top: "50%",
7109
7172
  left: "50%",
@@ -7112,7 +7175,7 @@ const Ve = Me(({
7112
7175
  fontSize: "18px",
7113
7176
  zIndex: 10
7114
7177
  }, children: "Loading avatar..." }),
7115
- K && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7178
+ _ && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7116
7179
  position: "absolute",
7117
7180
  top: "50%",
7118
7181
  left: "50%",
@@ -7123,14 +7186,14 @@ const Ve = Me(({
7123
7186
  zIndex: 10,
7124
7187
  padding: "20px",
7125
7188
  borderRadius: "8px"
7126
- }, children: K })
7189
+ }, children: _ })
7127
7190
  ]
7128
7191
  }
7129
7192
  );
7130
7193
  });
7131
7194
  Ve.displayName = "TalkingHeadAvatar";
7132
7195
  const pt = Me(({
7133
- text: Z = "Hello! I'm a talking avatar. How are you today?",
7196
+ text: X = "Hello! I'm a talking avatar. How are you today?",
7134
7197
  onLoading: t = () => {
7135
7198
  },
7136
7199
  onError: e = () => {
@@ -7141,7 +7204,7 @@ const pt = Me(({
7141
7204
  style: s = {},
7142
7205
  avatarConfig: o = {}
7143
7206
  }, l) => {
7144
- const h = O(null), r = O(null), [u, a] = ce(!0), [c, d] = ce(null), [g, b] = ce(!1), x = Fe(), A = o.ttsService || x.service, B = A === "browser" ? {
7207
+ const h = V(null), r = V(null), [u, a] = de(!0), [d, c] = de(null), [g, b] = de(!1), x = Ee(), S = o.ttsService || x.service, G = S === "browser" ? {
7145
7208
  endpoint: "",
7146
7209
  apiKey: null,
7147
7210
  defaultVoice: "Google US English"
@@ -7150,14 +7213,14 @@ const pt = Me(({
7150
7213
  // Override API key if provided via avatarConfig
7151
7214
  apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : x.apiKey,
7152
7215
  // Override endpoint for ElevenLabs if service is explicitly set
7153
- endpoint: A === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
7216
+ endpoint: S === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
7154
7217
  }, p = {
7155
7218
  url: "/avatars/brunette.glb",
7156
7219
  // Use brunette avatar (working glTF file)
7157
7220
  body: "F",
7158
7221
  avatarMood: "neutral",
7159
- ttsLang: A === "browser" ? "en-US" : "en",
7160
- ttsVoice: o.ttsVoice || B.defaultVoice,
7222
+ ttsLang: S === "browser" ? "en-US" : "en",
7223
+ ttsVoice: o.ttsVoice || G.defaultVoice,
7161
7224
  lipsyncLang: "en",
7162
7225
  // English lip-sync
7163
7226
  showFullAvatar: !0,
@@ -7165,81 +7228,81 @@ const pt = Me(({
7165
7228
  bodyMovement: "idle",
7166
7229
  movementIntensity: 0.5,
7167
7230
  ...o
7168
- }, E = {
7169
- ttsEndpoint: B.endpoint,
7170
- ttsApikey: B.apiKey,
7171
- ttsService: A,
7231
+ }, P = {
7232
+ ttsEndpoint: G.endpoint,
7233
+ ttsApikey: G.apiKey,
7234
+ ttsService: S,
7172
7235
  lipsyncModules: ["en"],
7173
7236
  cameraView: "upper"
7174
- }, I = F(async () => {
7237
+ }, H = N(async () => {
7175
7238
  if (!(!h.current || r.current))
7176
7239
  try {
7177
- if (a(!0), d(null), r.current = new Be(h.current, E), await r.current.showAvatar(p, (K) => {
7178
- if (K.lengthComputable) {
7179
- const X = Math.min(100, Math.round(K.loaded / K.total * 100));
7180
- t(X);
7240
+ if (a(!0), c(null), r.current = new Be(h.current, P), await r.current.showAvatar(p, (_) => {
7241
+ if (_.lengthComputable) {
7242
+ const B = Math.min(100, Math.round(_.loaded / _.total * 100));
7243
+ t(B);
7181
7244
  }
7182
7245
  }), r.current.morphs && r.current.morphs.length > 0) {
7183
- const K = r.current.morphs[0].morphTargetDictionary;
7184
- console.log("Available morph targets:", Object.keys(K));
7185
- const X = Object.keys(K).filter((ee) => ee.startsWith("viseme_"));
7186
- 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"));
7246
+ const _ = r.current.morphs[0].morphTargetDictionary;
7247
+ console.log("Available morph targets:", Object.keys(_));
7248
+ const B = Object.keys(_).filter((ee) => ee.startsWith("viseme_"));
7249
+ console.log("Viseme morph targets found:", B), B.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"));
7187
7250
  }
7188
- if (await new Promise((K) => {
7189
- const X = () => {
7190
- 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));
7251
+ if (await new Promise((_) => {
7252
+ const B = () => {
7253
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), _()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(B, 100));
7191
7254
  };
7192
- X();
7255
+ B();
7193
7256
  }), r.current && r.current.setShowFullAvatar)
7194
7257
  try {
7195
7258
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7196
- } catch (K) {
7197
- console.warn("Error setting full body mode on initialization:", K);
7259
+ } catch (_) {
7260
+ console.warn("Error setting full body mode on initialization:", _);
7198
7261
  }
7199
7262
  a(!1), b(!0), n(r.current);
7200
- const V = () => {
7263
+ const C = () => {
7201
7264
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7202
7265
  };
7203
- return document.addEventListener("visibilitychange", V), () => {
7204
- document.removeEventListener("visibilitychange", V);
7266
+ return document.addEventListener("visibilitychange", C), () => {
7267
+ document.removeEventListener("visibilitychange", C);
7205
7268
  };
7206
7269
  } catch (k) {
7207
- console.error("Error initializing TalkingHead:", k), d(k.message || "Failed to initialize avatar"), a(!1), e(k);
7270
+ console.error("Error initializing TalkingHead:", k), c(k.message || "Failed to initialize avatar"), a(!1), e(k);
7208
7271
  }
7209
7272
  }, []);
7210
- de(() => (I(), () => {
7273
+ me(() => (H(), () => {
7211
7274
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7212
- }), [I]);
7213
- const y = F((k) => {
7275
+ }), [H]);
7276
+ const y = N((k) => {
7214
7277
  if (r.current && g)
7215
7278
  try {
7216
7279
  console.log("Speaking text:", k), 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(k)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7217
7280
  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(k)) : console.error("Lip-sync still not ready after waiting");
7218
7281
  }, 500));
7219
- } catch (V) {
7220
- console.error("Error speaking text:", V), d(V.message || "Failed to speak text");
7282
+ } catch (C) {
7283
+ console.error("Error speaking text:", C), c(C.message || "Failed to speak text");
7221
7284
  }
7222
7285
  else
7223
7286
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7224
- }, [g, p]), H = F(() => {
7287
+ }, [g, p]), I = N(() => {
7225
7288
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7226
- }, []), w = F((k) => {
7289
+ }, []), z = N((k) => {
7227
7290
  r.current && r.current.setMood(k);
7228
- }, []), D = F((k) => {
7291
+ }, []), A = N((k) => {
7229
7292
  r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
7230
- }, []), $ = F((k, V = !1) => {
7293
+ }, []), Y = N((k, C = !1) => {
7231
7294
  if (r.current && r.current.playAnimation) {
7232
7295
  if (r.current.setShowFullAvatar)
7233
7296
  try {
7234
7297
  r.current.setShowFullAvatar(!0);
7235
- } catch (X) {
7236
- console.warn("Error setting full body mode:", X);
7298
+ } catch (B) {
7299
+ console.warn("Error setting full body mode:", B);
7237
7300
  }
7238
7301
  if (k.includes("."))
7239
7302
  try {
7240
- r.current.playAnimation(k, null, 10, 0, 0.01, V), console.log("Playing animation:", k);
7241
- } catch (X) {
7242
- console.log(`Failed to play ${k}:`, X);
7303
+ r.current.playAnimation(k, null, 10, 0, 0.01, C), console.log("Playing animation:", k);
7304
+ } catch (B) {
7305
+ console.log(`Failed to play ${k}:`, B);
7243
7306
  try {
7244
7307
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7245
7308
  } catch (ee) {
@@ -7247,41 +7310,41 @@ const pt = Me(({
7247
7310
  }
7248
7311
  }
7249
7312
  else {
7250
- const X = [".fbx", ".glb", ".gltf"];
7313
+ const B = [".fbx", ".glb", ".gltf"];
7251
7314
  let ee = !1;
7252
- for (const se of X)
7315
+ for (const ie of B)
7253
7316
  try {
7254
- r.current.playAnimation(k + se, null, 10, 0, 0.01, V), console.log("Playing animation:", k + se), ee = !0;
7317
+ r.current.playAnimation(k + ie, null, 10, 0, 0.01, C), console.log("Playing animation:", k + ie), ee = !0;
7255
7318
  break;
7256
7319
  } catch {
7257
- console.log(`Failed to play ${k}${se}, trying next format...`);
7320
+ console.log(`Failed to play ${k}${ie}, trying next format...`);
7258
7321
  }
7259
7322
  if (!ee) {
7260
7323
  console.warn("Animation system not available or animation not found:", k);
7261
7324
  try {
7262
7325
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7263
- } catch (se) {
7264
- console.warn("Fallback animation also failed:", se);
7326
+ } catch (ie) {
7327
+ console.warn("Fallback animation also failed:", ie);
7265
7328
  }
7266
7329
  }
7267
7330
  }
7268
7331
  } else
7269
7332
  console.warn("Animation system not available or animation not found:", k);
7270
7333
  }, []);
7271
- return Ee(l, () => ({
7334
+ return Fe(l, () => ({
7272
7335
  speakText: y,
7273
- stopSpeaking: H,
7274
- setMood: w,
7275
- setTimingAdjustment: D,
7276
- playAnimation: $,
7336
+ stopSpeaking: I,
7337
+ setMood: z,
7338
+ setTimingAdjustment: A,
7339
+ playAnimation: Y,
7277
7340
  isReady: g,
7278
7341
  talkingHead: r.current,
7279
7342
  setBodyMovement: (k) => {
7280
7343
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7281
7344
  try {
7282
7345
  r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
7283
- } catch (V) {
7284
- console.warn("Error setting body movement:", V);
7346
+ } catch (C) {
7347
+ console.warn("Error setting body movement:", C);
7285
7348
  }
7286
7349
  },
7287
7350
  setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
@@ -7297,8 +7360,8 @@ const pt = Me(({
7297
7360
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7298
7361
  try {
7299
7362
  r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
7300
- } catch (V) {
7301
- console.warn("Error playing reaction:", V);
7363
+ } catch (C) {
7364
+ console.warn("Error playing reaction:", C);
7302
7365
  }
7303
7366
  },
7304
7367
  playCelebration: () => {
@@ -7313,8 +7376,8 @@ const pt = Me(({
7313
7376
  if (r.current && r.current.setShowFullAvatar)
7314
7377
  try {
7315
7378
  r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
7316
- } catch (V) {
7317
- console.warn("Error setting showFullAvatar:", V);
7379
+ } catch (C) {
7380
+ console.warn("Error setting showFullAvatar:", C);
7318
7381
  }
7319
7382
  },
7320
7383
  lockAvatarPosition: () => {
@@ -7334,7 +7397,7 @@ const pt = Me(({
7334
7397
  }
7335
7398
  }
7336
7399
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
7337
- /* @__PURE__ */ me(
7400
+ /* @__PURE__ */ pe(
7338
7401
  "div",
7339
7402
  {
7340
7403
  ref: h,
@@ -7346,7 +7409,7 @@ const pt = Me(({
7346
7409
  }
7347
7410
  }
7348
7411
  ),
7349
- u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7412
+ u && /* @__PURE__ */ pe("div", { className: "loading-overlay", style: {
7350
7413
  position: "absolute",
7351
7414
  top: "50%",
7352
7415
  left: "50%",
@@ -7355,7 +7418,7 @@ const pt = Me(({
7355
7418
  fontSize: "18px",
7356
7419
  zIndex: 10
7357
7420
  }, children: "Loading avatar..." }),
7358
- c && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7421
+ d && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7359
7422
  position: "absolute",
7360
7423
  top: "50%",
7361
7424
  left: "50%",
@@ -7366,12 +7429,12 @@ const pt = Me(({
7366
7429
  zIndex: 10,
7367
7430
  padding: "20px",
7368
7431
  borderRadius: "8px"
7369
- }, children: c })
7432
+ }, children: d })
7370
7433
  ] });
7371
7434
  });
7372
7435
  pt.displayName = "TalkingHeadComponent";
7373
7436
  const gt = Me(({
7374
- text: Z = null,
7437
+ text: X = null,
7375
7438
  avatarUrl: t = "/avatars/brunette.glb",
7376
7439
  avatarBody: e = "F",
7377
7440
  mood: n = "neutral",
@@ -7383,26 +7446,26 @@ const gt = Me(({
7383
7446
  movementIntensity: r = 0.5,
7384
7447
  showFullAvatar: u = !1,
7385
7448
  cameraView: a = "upper",
7386
- onReady: c = () => {
7449
+ onReady: d = () => {
7387
7450
  },
7388
- onLoading: d = () => {
7451
+ onLoading: c = () => {
7389
7452
  },
7390
7453
  onError: g = () => {
7391
7454
  },
7392
7455
  onSpeechEnd: b = () => {
7393
7456
  },
7394
7457
  className: x = "",
7395
- style: A = {},
7396
- animations: B = {},
7458
+ style: S = {},
7459
+ animations: G = {},
7397
7460
  autoSpeak: p = !1
7398
- }, E) => {
7399
- const I = O(null), y = O(null), H = O(u), w = O(null), D = O(null), $ = O(!1), k = O({ remainingText: null, originalText: null, options: null }), V = O([]), [K, X] = ce(!0), [ee, se] = ce(null), [ae, pe] = ce(!1), [te, le] = ce(!1);
7400
- de(() => {
7401
- $.current = te;
7402
- }, [te]), de(() => {
7403
- H.current = u;
7461
+ }, P) => {
7462
+ const H = V(null), y = V(null), I = V(u), z = V(null), A = V(null), Y = V(!1), k = V({ remainingText: null, originalText: null, options: null }), C = V([]), [_, B] = de(!0), [ee, ie] = de(null), [oe, he] = de(!1), [K, Q] = de(!1);
7463
+ me(() => {
7464
+ Y.current = K;
7465
+ }, [K]), me(() => {
7466
+ I.current = u;
7404
7467
  }, [u]);
7405
- const U = Fe(), v = s || U.service;
7468
+ const W = Ee(), v = s || W.service;
7406
7469
  let R;
7407
7470
  v === "browser" ? R = {
7408
7471
  service: "browser",
@@ -7412,20 +7475,20 @@ const gt = Me(({
7412
7475
  } : v === "elevenlabs" ? R = {
7413
7476
  service: "elevenlabs",
7414
7477
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7415
- apiKey: l || U.apiKey,
7416
- defaultVoice: o || U.defaultVoice || Ie.defaultVoice,
7417
- voices: U.voices || Ie.voices
7478
+ apiKey: l || W.apiKey,
7479
+ defaultVoice: o || W.defaultVoice || Ie.defaultVoice,
7480
+ voices: W.voices || Ie.voices
7418
7481
  } : v === "deepgram" ? R = {
7419
7482
  service: "deepgram",
7420
7483
  endpoint: "https://api.deepgram.com/v1/speak",
7421
- apiKey: l || U.apiKey,
7422
- defaultVoice: o || U.defaultVoice || Te.defaultVoice,
7423
- voices: U.voices || Te.voices
7484
+ apiKey: l || W.apiKey,
7485
+ defaultVoice: o || W.defaultVoice || Te.defaultVoice,
7486
+ voices: W.voices || Te.voices
7424
7487
  } : R = {
7425
- ...U,
7426
- apiKey: l !== null ? l : U.apiKey
7488
+ ...W,
7489
+ apiKey: l !== null ? l : W.apiKey
7427
7490
  };
7428
- const z = {
7491
+ const T = {
7429
7492
  url: t,
7430
7493
  body: e,
7431
7494
  avatarMood: n,
@@ -7441,121 +7504,121 @@ const gt = Me(({
7441
7504
  ttsService: v,
7442
7505
  lipsyncModules: ["en"],
7443
7506
  cameraView: a
7444
- }, W = F(async () => {
7445
- if (!(!I.current || y.current))
7507
+ }, O = N(async () => {
7508
+ if (!(!H.current || y.current))
7446
7509
  try {
7447
- X(!0), se(null), y.current = new Be(I.current, M), console.log("Avatar config being passed:", {
7448
- url: z.url,
7449
- body: z.body,
7450
- avatarMood: z.avatarMood
7451
- }), await y.current.showAvatar(z, (ne) => {
7452
- if (ne.lengthComputable) {
7453
- const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
7454
- d(L);
7510
+ B(!0), ie(null), y.current = new Be(H.current, M), console.log("Avatar config being passed:", {
7511
+ url: T.url,
7512
+ body: T.body,
7513
+ avatarMood: T.avatarMood
7514
+ }), await y.current.showAvatar(T, (se) => {
7515
+ if (se.lengthComputable) {
7516
+ const L = Math.min(100, Math.round(se.loaded / se.total * 100));
7517
+ c(L);
7455
7518
  }
7456
- }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), X(!1), pe(!0), c(y.current);
7457
- const T = () => {
7519
+ }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), B(!1), he(!0), d(y.current);
7520
+ const E = () => {
7458
7521
  document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
7459
7522
  };
7460
- return document.addEventListener("visibilitychange", T), () => {
7461
- document.removeEventListener("visibilitychange", T);
7523
+ return document.addEventListener("visibilitychange", E), () => {
7524
+ document.removeEventListener("visibilitychange", E);
7462
7525
  };
7463
- } catch (T) {
7464
- console.error("Error initializing TalkingHead:", T), se(T.message || "Failed to initialize avatar"), X(!1), g(T);
7526
+ } catch (E) {
7527
+ console.error("Error initializing TalkingHead:", E), ie(E.message || "Failed to initialize avatar"), B(!1), g(E);
7465
7528
  }
7466
7529
  }, []);
7467
- de(() => (W(), () => {
7530
+ me(() => (O(), () => {
7468
7531
  y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7469
- }), [W]);
7470
- const _ = F(async () => {
7532
+ }), [O]);
7533
+ const te = N(async () => {
7471
7534
  if (y.current)
7472
7535
  try {
7473
- const T = y.current.audioCtx || y.current.audioContext;
7474
- T && (T.state === "suspended" || T.state === "interrupted") && (await T.resume(), console.log("Audio context resumed"));
7475
- } catch (T) {
7476
- console.warn("Failed to resume audio context:", T);
7536
+ const E = y.current.audioCtx || y.current.audioContext;
7537
+ E && (E.state === "suspended" || E.state === "interrupted") && (await E.resume(), console.log("Audio context resumed"));
7538
+ } catch (E) {
7539
+ console.warn("Failed to resume audio context:", E);
7477
7540
  }
7478
- }, []), j = F(async (T, ne = {}) => {
7479
- if (!y.current || !ae) {
7541
+ }, []), q = N(async (E, se = {}) => {
7542
+ if (!y.current || !oe) {
7480
7543
  console.warn("Avatar not ready for speaking");
7481
7544
  return;
7482
7545
  }
7483
- if (!T || T.trim() === "") {
7546
+ if (!E || E.trim() === "") {
7484
7547
  console.warn("No text provided to speak");
7485
7548
  return;
7486
7549
  }
7487
- await _(), k.current = { remainingText: null, originalText: null, options: null }, V.current = [], w.current = { text: T, options: ne }, D.current && (clearInterval(D.current), D.current = null), le(!1), $.current = !1;
7488
- const L = T.split(/[.!?]+/).filter((N) => N.trim().length > 0);
7489
- V.current = L;
7490
- const P = {
7491
- lipsyncLang: ne.lipsyncLang || "en",
7550
+ await te(), k.current = { remainingText: null, originalText: null, options: null }, C.current = [], z.current = { text: E, options: se }, A.current && (clearInterval(A.current), A.current = null), Q(!1), Y.current = !1;
7551
+ const L = E.split(/[.!?]+/).filter((U) => U.trim().length > 0);
7552
+ C.current = L;
7553
+ const D = {
7554
+ lipsyncLang: se.lipsyncLang || "en",
7492
7555
  onSpeechEnd: () => {
7493
- D.current && (clearInterval(D.current), D.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), b();
7556
+ A.current && (clearInterval(A.current), A.current = null), se.onSpeechEnd && se.onSpeechEnd(), b();
7494
7557
  }
7495
7558
  };
7496
7559
  try {
7497
- y.current.speakText(T, P);
7498
- } catch (N) {
7499
- console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
7560
+ y.current.speakText(E, D);
7561
+ } catch (U) {
7562
+ console.error("Error speaking text:", U), ie(U.message || "Failed to speak text");
7500
7563
  }
7501
- }, [ae, b, _]);
7502
- de(() => {
7503
- ae && Z && p && y.current && j(Z);
7504
- }, [ae, Z, p, j]);
7505
- const q = F(() => {
7564
+ }, [oe, b, te]);
7565
+ me(() => {
7566
+ oe && X && p && y.current && q(X);
7567
+ }, [oe, X, p, q]);
7568
+ const $ = N(() => {
7506
7569
  if (y.current)
7507
7570
  try {
7508
- const T = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7509
- if (T || ne.length > 0 || L.length > 0) {
7510
- D.current && (clearInterval(D.current), D.current = null);
7511
- let P = "";
7512
- L.length > 0 && (P = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")), k.current = {
7513
- remainingText: P || null,
7514
- originalText: w.current?.text || null,
7515
- options: w.current?.options || null
7516
- }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), $.current = !0;
7571
+ const E = y.current.isSpeaking || !1, se = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7572
+ if (E || se.length > 0 || L.length > 0) {
7573
+ A.current && (clearInterval(A.current), A.current = null);
7574
+ let D = "";
7575
+ L.length > 0 && (D = L.map((U) => U.text && Array.isArray(U.text) ? U.text.map((ne) => ne.word).join(" ") : U.text || "").join(" ")), k.current = {
7576
+ remainingText: D || null,
7577
+ originalText: z.current?.text || null,
7578
+ options: z.current?.options || null
7579
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), Q(!0), Y.current = !0;
7517
7580
  }
7518
- } catch (T) {
7519
- console.warn("Error pausing speech:", T);
7581
+ } catch (E) {
7582
+ console.warn("Error pausing speech:", E);
7520
7583
  }
7521
- }, []), Le = F(async () => {
7522
- if (!(!y.current || !te))
7584
+ }, []), Ae = N(async () => {
7585
+ if (!(!y.current || !K))
7523
7586
  try {
7524
- await _(), le(!1), $.current = !1;
7525
- const T = k.current?.remainingText, ne = k.current?.originalText || w.current?.text, L = k.current?.options || w.current?.options || {}, P = T || ne;
7526
- P && j(P, L);
7527
- } catch (T) {
7528
- console.warn("Error resuming speech:", T), le(!1), $.current = !1;
7587
+ await te(), Q(!1), Y.current = !1;
7588
+ const E = k.current?.remainingText, se = k.current?.originalText || z.current?.text, L = k.current?.options || z.current?.options || {}, D = E || se;
7589
+ D && q(D, L);
7590
+ } catch (E) {
7591
+ console.warn("Error resuming speech:", E), Q(!1), Y.current = !1;
7529
7592
  }
7530
- }, [te, j, _]), we = F(() => {
7531
- y.current && (y.current.stopSpeaking(), D.current && (clearInterval(D.current), D.current = null), le(!1), $.current = !1);
7593
+ }, [K, q, te]), we = N(() => {
7594
+ y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null), Q(!1), Y.current = !1);
7532
7595
  }, []);
7533
- return Ee(E, () => ({
7534
- speakText: j,
7535
- pauseSpeaking: q,
7536
- resumeSpeaking: Le,
7596
+ return Fe(P, () => ({
7597
+ speakText: q,
7598
+ pauseSpeaking: $,
7599
+ resumeSpeaking: Ae,
7537
7600
  stopSpeaking: we,
7538
- resumeAudioContext: _,
7539
- isPaused: () => te,
7540
- setMood: (T) => y.current?.setMood(T),
7541
- setBodyMovement: (T) => {
7542
- y.current && y.current.setBodyMovement(T);
7601
+ resumeAudioContext: te,
7602
+ isPaused: () => K,
7603
+ setMood: (E) => y.current?.setMood(E),
7604
+ setBodyMovement: (E) => {
7605
+ y.current && y.current.setBodyMovement(E);
7543
7606
  },
7544
- playAnimation: (T, ne = !1) => {
7545
- y.current && y.current.playAnimation && y.current.playAnimation(T, null, 10, 0, 0.01, ne);
7607
+ playAnimation: (E, se = !1) => {
7608
+ y.current && y.current.playAnimation && y.current.playAnimation(E, null, 10, 0, 0.01, se);
7546
7609
  },
7547
- playReaction: (T) => y.current?.playReaction(T),
7610
+ playReaction: (E) => y.current?.playReaction(E),
7548
7611
  playCelebration: () => y.current?.playCelebration(),
7549
- setShowFullAvatar: (T) => {
7550
- y.current && (H.current = T, y.current.setShowFullAvatar(T));
7612
+ setShowFullAvatar: (E) => {
7613
+ y.current && (I.current = E, y.current.setShowFullAvatar(E));
7551
7614
  },
7552
- isReady: ae,
7615
+ isReady: oe,
7553
7616
  talkingHead: y.current
7554
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${x}`, style: A, children: [
7555
- /* @__PURE__ */ me(
7617
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${x}`, style: S, children: [
7618
+ /* @__PURE__ */ pe(
7556
7619
  "div",
7557
7620
  {
7558
- ref: I,
7621
+ ref: H,
7559
7622
  className: "talking-head-viewer",
7560
7623
  style: {
7561
7624
  width: "100%",
@@ -7564,7 +7627,7 @@ const gt = Me(({
7564
7627
  }
7565
7628
  }
7566
7629
  ),
7567
- K && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7630
+ _ && /* @__PURE__ */ pe("div", { className: "loading-overlay", style: {
7568
7631
  position: "absolute",
7569
7632
  top: "50%",
7570
7633
  left: "50%",
@@ -7573,7 +7636,7 @@ const gt = Me(({
7573
7636
  fontSize: "18px",
7574
7637
  zIndex: 10
7575
7638
  }, children: "Loading avatar..." }),
7576
- ee && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7639
+ ee && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7577
7640
  position: "absolute",
7578
7641
  top: "50%",
7579
7642
  left: "50%",
@@ -7589,7 +7652,7 @@ const gt = Me(({
7589
7652
  });
7590
7653
  gt.displayName = "SimpleTalkingAvatar";
7591
7654
  const yt = Me(({
7592
- curriculumData: Z = null,
7655
+ curriculumData: X = null,
7593
7656
  avatarConfig: t = {},
7594
7657
  animations: e = {},
7595
7658
  onLessonStart: n = () => {
@@ -7604,7 +7667,7 @@ const yt = Me(({
7604
7667
  },
7605
7668
  autoStart: h = !1
7606
7669
  }, r) => {
7607
- const u = O(null), a = O({
7670
+ const u = V(null), a = V({
7608
7671
  currentModuleIndex: 0,
7609
7672
  currentLessonIndex: 0,
7610
7673
  currentQuestionIndex: 0,
@@ -7614,18 +7677,18 @@ const yt = Me(({
7614
7677
  curriculumCompleted: !1,
7615
7678
  score: 0,
7616
7679
  totalQuestions: 0
7617
- }), c = O({
7680
+ }), d = V({
7618
7681
  onLessonStart: n,
7619
7682
  onLessonComplete: i,
7620
7683
  onQuestionAnswer: s,
7621
7684
  onCurriculumComplete: o,
7622
7685
  onCustomAction: l
7623
- }), d = O(null), g = O(null), b = O(null), x = O(null), A = O(null), B = O(null), p = O(null), E = O(Z?.curriculum || {
7686
+ }), c = V(null), g = V(null), b = V(null), x = V(null), S = V(null), G = V(null), p = V(null), P = V(X?.curriculum || {
7624
7687
  title: "Default Curriculum",
7625
7688
  description: "No curriculum data provided",
7626
7689
  language: "en",
7627
7690
  modules: []
7628
- }), I = O({
7691
+ }), H = V({
7629
7692
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7630
7693
  avatarBody: t.avatarBody || "F",
7631
7694
  mood: t.mood || "happy",
@@ -7639,21 +7702,21 @@ const yt = Me(({
7639
7702
  animations: e,
7640
7703
  lipsyncLang: "en"
7641
7704
  });
7642
- de(() => {
7643
- c.current = {
7705
+ me(() => {
7706
+ d.current = {
7644
7707
  onLessonStart: n,
7645
7708
  onLessonComplete: i,
7646
7709
  onQuestionAnswer: s,
7647
7710
  onCurriculumComplete: o,
7648
7711
  onCustomAction: l
7649
7712
  };
7650
- }, [n, i, s, o, l]), de(() => {
7651
- E.current = Z?.curriculum || {
7713
+ }, [n, i, s, o, l]), me(() => {
7714
+ P.current = X?.curriculum || {
7652
7715
  title: "Default Curriculum",
7653
7716
  description: "No curriculum data provided",
7654
7717
  language: "en",
7655
7718
  modules: []
7656
- }, I.current = {
7719
+ }, H.current = {
7657
7720
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7658
7721
  avatarBody: t.avatarBody || "F",
7659
7722
  mood: t.mood || "happy",
@@ -7667,18 +7730,18 @@ const yt = Me(({
7667
7730
  animations: e,
7668
7731
  lipsyncLang: "en"
7669
7732
  };
7670
- }, [Z, t, e]);
7671
- const y = F(() => (E.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), H = F(() => y()?.questions[a.current.currentQuestionIndex], [y]), w = F((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), D = F(() => {
7733
+ }, [X, t, e]);
7734
+ const y = N(() => (P.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), I = N(() => y()?.questions[a.current.currentQuestionIndex], [y]), z = N((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), A = N(() => {
7672
7735
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7673
7736
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7674
7737
  let R = "Congratulations! You've completed this lesson";
7675
- if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7738
+ if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7676
7739
  moduleIndex: a.current.currentModuleIndex,
7677
7740
  lessonIndex: a.current.currentLessonIndex,
7678
7741
  score: a.current.score,
7679
7742
  totalQuestions: a.current.totalQuestions,
7680
7743
  percentage: v
7681
- }), c.current.onCustomAction({
7744
+ }), d.current.onCustomAction({
7682
7745
  type: "lessonComplete",
7683
7746
  moduleIndex: a.current.currentModuleIndex,
7684
7747
  lessonIndex: a.current.currentLessonIndex,
@@ -7692,28 +7755,28 @@ const yt = Me(({
7692
7755
  } catch {
7693
7756
  u.current.playCelebration();
7694
7757
  }
7695
- const z = E.current || { modules: [] }, M = z.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (z.modules?.length || 0) - 1, j = W || _, q = I.current || { lipsyncLang: "en" };
7758
+ const T = P.current || { modules: [] }, M = T.modules[a.current.currentModuleIndex], O = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (T.modules?.length || 0) - 1, q = O || te, $ = H.current || { lipsyncLang: "en" };
7696
7759
  u.current.speakText(R, {
7697
- lipsyncLang: q.lipsyncLang,
7760
+ lipsyncLang: $.lipsyncLang,
7698
7761
  onSpeechEnd: () => {
7699
- c.current.onCustomAction({
7762
+ d.current.onCustomAction({
7700
7763
  type: "lessonCompleteFeedbackDone",
7701
7764
  moduleIndex: a.current.currentModuleIndex,
7702
7765
  lessonIndex: a.current.currentLessonIndex,
7703
7766
  score: a.current.score,
7704
7767
  totalQuestions: a.current.totalQuestions,
7705
7768
  percentage: v,
7706
- hasNextLesson: j
7769
+ hasNextLesson: q
7707
7770
  });
7708
7771
  }
7709
7772
  });
7710
7773
  }
7711
- }, [e.lessonComplete]), $ = F(() => {
7774
+ }, [e.lessonComplete]), Y = N(() => {
7712
7775
  a.current.curriculumCompleted = !0;
7713
- const v = E.current || { modules: [] };
7714
- if (c.current.onCurriculumComplete({
7776
+ const v = P.current || { modules: [] };
7777
+ if (d.current.onCurriculumComplete({
7715
7778
  modules: v.modules.length,
7716
- totalLessons: v.modules.reduce((R, z) => R + z.lessons.length, 0)
7779
+ totalLessons: v.modules.reduce((R, T) => R + T.lessons.length, 0)
7717
7780
  }), u.current) {
7718
7781
  if (u.current.setMood("celebrating"), e.curriculumComplete)
7719
7782
  try {
@@ -7721,14 +7784,14 @@ const yt = Me(({
7721
7784
  } catch {
7722
7785
  u.current.playCelebration();
7723
7786
  }
7724
- const R = I.current || { lipsyncLang: "en" };
7787
+ const R = H.current || { lipsyncLang: "en" };
7725
7788
  u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7726
7789
  }
7727
- }, [e.curriculumComplete]), k = F(() => {
7790
+ }, [e.curriculumComplete]), k = N(() => {
7728
7791
  const v = y();
7729
7792
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7730
- const R = H();
7731
- R && c.current.onCustomAction({
7793
+ const R = I();
7794
+ R && d.current.onCustomAction({
7732
7795
  type: "questionStart",
7733
7796
  moduleIndex: a.current.currentModuleIndex,
7734
7797
  lessonIndex: a.current.currentLessonIndex,
@@ -7737,36 +7800,36 @@ const yt = Me(({
7737
7800
  question: R,
7738
7801
  score: a.current.score
7739
7802
  });
7740
- const z = () => {
7803
+ const T = () => {
7741
7804
  if (!u.current || !R) return;
7742
7805
  if (u.current.setMood("happy"), e.questionStart)
7743
7806
  try {
7744
7807
  u.current.playAnimation(e.questionStart, !0);
7745
- } catch (W) {
7746
- console.warn("Failed to play questionStart animation:", W);
7808
+ } catch (O) {
7809
+ console.warn("Failed to play questionStart animation:", O);
7747
7810
  }
7748
- const M = I.current || { lipsyncLang: "en" };
7811
+ const M = H.current || { lipsyncLang: "en" };
7749
7812
  R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: M.lipsyncLang });
7750
7813
  };
7751
7814
  if (u.current && u.current.isReady && R)
7752
- z();
7815
+ T();
7753
7816
  else if (u.current && u.current.isReady) {
7754
- const M = I.current || { lipsyncLang: "en" };
7817
+ const M = H.current || { lipsyncLang: "en" };
7755
7818
  u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: M.lipsyncLang });
7756
7819
  } else {
7757
7820
  const M = setInterval(() => {
7758
- u.current && u.current.isReady && (clearInterval(M), R && z());
7821
+ u.current && u.current.isReady && (clearInterval(M), R && T());
7759
7822
  }, 100);
7760
7823
  setTimeout(() => {
7761
7824
  clearInterval(M);
7762
7825
  }, 5e3);
7763
7826
  }
7764
- }, [e.questionStart, y, H]), V = F(() => {
7827
+ }, [e.questionStart, y, I]), C = N(() => {
7765
7828
  const v = y();
7766
7829
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7767
7830
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7768
- const R = H();
7769
- R && c.current.onCustomAction({
7831
+ const R = I();
7832
+ R && d.current.onCustomAction({
7770
7833
  type: "nextQuestion",
7771
7834
  moduleIndex: a.current.currentModuleIndex,
7772
7835
  lessonIndex: a.current.currentLessonIndex,
@@ -7775,109 +7838,109 @@ const yt = Me(({
7775
7838
  question: R,
7776
7839
  score: a.current.score
7777
7840
  });
7778
- const z = () => {
7841
+ const T = () => {
7779
7842
  if (!u.current || !R) return;
7780
7843
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7781
7844
  try {
7782
7845
  u.current.playAnimation(e.nextQuestion, !0);
7783
- } catch (q) {
7784
- console.warn("Failed to play nextQuestion animation:", q);
7846
+ } catch ($) {
7847
+ console.warn("Failed to play nextQuestion animation:", $);
7785
7848
  }
7786
- const M = I.current || { lipsyncLang: "en" }, _ = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7849
+ const M = H.current || { lipsyncLang: "en" }, te = y()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
7787
7850
  if (R.type === "code_test") {
7788
- const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7789
- u.current.speakText(q, {
7851
+ const $ = q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7852
+ u.current.speakText($, {
7790
7853
  lipsyncLang: M.lipsyncLang
7791
7854
  });
7792
7855
  } else if (R.type === "multiple_choice") {
7793
- const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7794
- u.current.speakText(q, {
7856
+ const $ = q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7857
+ u.current.speakText($, {
7795
7858
  lipsyncLang: M.lipsyncLang
7796
7859
  });
7797
7860
  } else if (R.type === "true_false") {
7798
- const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7799
- u.current.speakText(q, {
7861
+ const $ = q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7862
+ u.current.speakText($, {
7800
7863
  lipsyncLang: M.lipsyncLang
7801
7864
  });
7802
7865
  } else {
7803
- const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7804
- u.current.speakText(q, {
7866
+ const $ = q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7867
+ u.current.speakText($, {
7805
7868
  lipsyncLang: M.lipsyncLang
7806
7869
  });
7807
7870
  }
7808
7871
  };
7809
7872
  if (u.current && u.current.isReady && R)
7810
- z();
7873
+ T();
7811
7874
  else if (R) {
7812
7875
  const M = setInterval(() => {
7813
- u.current && u.current.isReady && (clearInterval(M), z());
7876
+ u.current && u.current.isReady && (clearInterval(M), T());
7814
7877
  }, 100);
7815
7878
  setTimeout(() => {
7816
7879
  clearInterval(M);
7817
7880
  }, 5e3);
7818
7881
  }
7819
7882
  } else
7820
- c.current.onCustomAction({
7883
+ d.current.onCustomAction({
7821
7884
  type: "allQuestionsComplete",
7822
7885
  moduleIndex: a.current.currentModuleIndex,
7823
7886
  lessonIndex: a.current.currentLessonIndex,
7824
7887
  totalQuestions: a.current.totalQuestions,
7825
7888
  score: a.current.score
7826
7889
  });
7827
- }, [e.nextQuestion, y, H]), K = F(() => {
7828
- const v = E.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7890
+ }, [e.nextQuestion, y, I]), _ = N(() => {
7891
+ const v = P.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7829
7892
  if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7830
7893
  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;
7831
- const M = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = W || _;
7832
- c.current.onCustomAction({
7894
+ const M = v.modules[a.current.currentModuleIndex], O = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = O || te;
7895
+ d.current.onCustomAction({
7833
7896
  type: "lessonStart",
7834
7897
  moduleIndex: a.current.currentModuleIndex,
7835
7898
  lessonIndex: a.current.currentLessonIndex,
7836
- hasNextLesson: j
7837
- }), c.current.onLessonStart({
7899
+ hasNextLesson: q
7900
+ }), d.current.onLessonStart({
7838
7901
  moduleIndex: a.current.currentModuleIndex,
7839
7902
  lessonIndex: a.current.currentLessonIndex,
7840
7903
  lesson: y()
7841
7904
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7842
7905
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7843
7906
  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;
7844
- const W = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
7845
- c.current.onCustomAction({
7907
+ const O = v.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, $ = te || q;
7908
+ d.current.onCustomAction({
7846
7909
  type: "lessonStart",
7847
7910
  moduleIndex: a.current.currentModuleIndex,
7848
7911
  lessonIndex: a.current.currentLessonIndex,
7849
- hasNextLesson: q
7850
- }), c.current.onLessonStart({
7912
+ hasNextLesson: $
7913
+ }), d.current.onLessonStart({
7851
7914
  moduleIndex: a.current.currentModuleIndex,
7852
7915
  lessonIndex: a.current.currentLessonIndex,
7853
7916
  lesson: y()
7854
7917
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7855
7918
  } else
7856
- A.current && A.current();
7857
- }, []), X = F(() => {
7919
+ S.current && S.current();
7920
+ }, []), B = N(() => {
7858
7921
  const v = y();
7859
7922
  let R = null;
7860
7923
  if (v?.avatar_script && v?.body) {
7861
- const z = v.avatar_script.trim(), M = v.body.trim(), W = z.match(/[.!?]$/) ? " " : ". ";
7862
- R = `${z}${W}${M}`;
7924
+ const T = v.avatar_script.trim(), M = v.body.trim(), O = T.match(/[.!?]$/) ? " " : ". ";
7925
+ R = `${T}${O}${M}`;
7863
7926
  } else
7864
7927
  R = v?.avatar_script || v?.body || null;
7865
7928
  if (u.current && u.current.isReady && R) {
7866
7929
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
7867
- let z = !1;
7930
+ let T = !1;
7868
7931
  if (e.teaching)
7869
7932
  try {
7870
- u.current.playAnimation(e.teaching, !0), z = !0;
7871
- } catch (W) {
7872
- console.warn("Failed to play teaching animation:", W);
7933
+ u.current.playAnimation(e.teaching, !0), T = !0;
7934
+ } catch (O) {
7935
+ console.warn("Failed to play teaching animation:", O);
7873
7936
  }
7874
- z || u.current.setBodyMovement("gesturing");
7875
- const M = I.current || { lipsyncLang: "en" };
7876
- c.current.onLessonStart({
7937
+ T || u.current.setBodyMovement("gesturing");
7938
+ const M = H.current || { lipsyncLang: "en" };
7939
+ d.current.onLessonStart({
7877
7940
  moduleIndex: a.current.currentModuleIndex,
7878
7941
  lessonIndex: a.current.currentLessonIndex,
7879
7942
  lesson: v
7880
- }), c.current.onCustomAction({
7943
+ }), d.current.onCustomAction({
7881
7944
  type: "teachingStart",
7882
7945
  moduleIndex: a.current.currentModuleIndex,
7883
7946
  lessonIndex: a.current.currentLessonIndex,
@@ -7885,13 +7948,13 @@ const yt = Me(({
7885
7948
  }), u.current.speakText(R, {
7886
7949
  lipsyncLang: M.lipsyncLang,
7887
7950
  onSpeechEnd: () => {
7888
- a.current.isTeaching = !1, c.current.onCustomAction({
7951
+ a.current.isTeaching = !1, d.current.onCustomAction({
7889
7952
  type: "teachingComplete",
7890
7953
  moduleIndex: a.current.currentModuleIndex,
7891
7954
  lessonIndex: a.current.currentLessonIndex,
7892
7955
  lesson: v,
7893
7956
  hasQuestions: v.questions && v.questions.length > 0
7894
- }), v?.code_example && c.current.onCustomAction({
7957
+ }), v?.code_example && d.current.onCustomAction({
7895
7958
  type: "codeExampleReady",
7896
7959
  moduleIndex: a.current.currentModuleIndex,
7897
7960
  lessonIndex: a.current.currentLessonIndex,
@@ -7901,17 +7964,17 @@ const yt = Me(({
7901
7964
  }
7902
7965
  });
7903
7966
  }
7904
- }, [e.teaching, y]), ee = F((v) => {
7905
- const R = H(), z = w(v, R);
7906
- if (z && (a.current.score += 1), c.current.onQuestionAnswer({
7967
+ }, [e.teaching, y]), ee = N((v) => {
7968
+ const R = I(), T = z(v, R);
7969
+ if (T && (a.current.score += 1), d.current.onQuestionAnswer({
7907
7970
  moduleIndex: a.current.currentModuleIndex,
7908
7971
  lessonIndex: a.current.currentLessonIndex,
7909
7972
  questionIndex: a.current.currentQuestionIndex,
7910
7973
  answer: v,
7911
- isCorrect: z,
7974
+ isCorrect: T,
7912
7975
  question: R
7913
7976
  }), u.current)
7914
- if (z) {
7977
+ if (T) {
7915
7978
  if (u.current.setMood("happy"), e.correct)
7916
7979
  try {
7917
7980
  u.current.playReaction("happy");
@@ -7919,21 +7982,21 @@ const yt = Me(({
7919
7982
  u.current.setBodyMovement("happy");
7920
7983
  }
7921
7984
  u.current.setBodyMovement("gesturing");
7922
- const W = y()?.questions?.length || 0;
7923
- a.current.currentQuestionIndex >= W - 1;
7924
- const _ = a.current.currentQuestionIndex < W - 1;
7925
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", _);
7926
- const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = I.current || { lipsyncLang: "en" };
7927
- u.current.speakText(j, {
7928
- lipsyncLang: q.lipsyncLang,
7985
+ const O = y()?.questions?.length || 0;
7986
+ a.current.currentQuestionIndex >= O - 1;
7987
+ const te = a.current.currentQuestionIndex < O - 1;
7988
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", O, "hasNextQuestion:", te);
7989
+ const q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, $ = H.current || { lipsyncLang: "en" };
7990
+ u.current.speakText(q, {
7991
+ lipsyncLang: $.lipsyncLang,
7929
7992
  onSpeechEnd: () => {
7930
- c.current.onCustomAction({
7993
+ d.current.onCustomAction({
7931
7994
  type: "answerFeedbackComplete",
7932
7995
  moduleIndex: a.current.currentModuleIndex,
7933
7996
  lessonIndex: a.current.currentLessonIndex,
7934
7997
  questionIndex: a.current.currentQuestionIndex,
7935
7998
  isCorrect: !0,
7936
- hasNextQuestion: _,
7999
+ hasNextQuestion: te,
7937
8000
  score: a.current.score,
7938
8001
  totalQuestions: a.current.totalQuestions
7939
8002
  });
@@ -7947,19 +8010,19 @@ const yt = Me(({
7947
8010
  u.current.setBodyMovement("idle");
7948
8011
  }
7949
8012
  u.current.setBodyMovement("gesturing");
7950
- const W = y()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= W - 1, j = a.current.currentQuestionIndex < W - 1;
7951
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", j);
7952
- const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = I.current || { lipsyncLang: "en" };
7953
- u.current.speakText(q, {
7954
- lipsyncLang: Le.lipsyncLang,
8013
+ const O = y()?.questions?.length || 0, te = a.current.currentQuestionIndex >= O - 1, q = a.current.currentQuestionIndex < O - 1;
8014
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", O, "hasNextQuestion:", q);
8015
+ const $ = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${te ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
8016
+ u.current.speakText($, {
8017
+ lipsyncLang: Ae.lipsyncLang,
7955
8018
  onSpeechEnd: () => {
7956
- c.current.onCustomAction({
8019
+ d.current.onCustomAction({
7957
8020
  type: "answerFeedbackComplete",
7958
8021
  moduleIndex: a.current.currentModuleIndex,
7959
8022
  lessonIndex: a.current.currentLessonIndex,
7960
8023
  questionIndex: a.current.currentQuestionIndex,
7961
8024
  isCorrect: !1,
7962
- hasNextQuestion: j,
8025
+ hasNextQuestion: q,
7963
8026
  score: a.current.score,
7964
8027
  totalQuestions: a.current.totalQuestions
7965
8028
  });
@@ -7967,21 +8030,21 @@ const yt = Me(({
7967
8030
  });
7968
8031
  }
7969
8032
  else {
7970
- const W = y()?.questions?.length || 0;
7971
- c.current.onCustomAction({
8033
+ const O = y()?.questions?.length || 0;
8034
+ d.current.onCustomAction({
7972
8035
  type: "answerFeedbackComplete",
7973
8036
  moduleIndex: a.current.currentModuleIndex,
7974
8037
  lessonIndex: a.current.currentLessonIndex,
7975
8038
  questionIndex: a.current.currentQuestionIndex,
7976
- isCorrect: z,
7977
- hasNextQuestion: a.current.currentQuestionIndex < W - 1,
8039
+ isCorrect: T,
8040
+ hasNextQuestion: a.current.currentQuestionIndex < O - 1,
7978
8041
  score: a.current.score,
7979
8042
  totalQuestions: a.current.totalQuestions,
7980
8043
  avatarNotReady: !0
7981
8044
  });
7982
8045
  }
7983
- }, [e.correct, e.incorrect, H, y, w]), se = F((v) => {
7984
- const R = H();
8046
+ }, [e.correct, e.incorrect, I, y, z]), ie = N((v) => {
8047
+ const R = I();
7985
8048
  if (!v || typeof v != "object") {
7986
8049
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
7987
8050
  return;
@@ -7990,7 +8053,7 @@ const yt = Me(({
7990
8053
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7991
8054
  return;
7992
8055
  }
7993
- const z = {
8056
+ const T = {
7994
8057
  passed: v.passed === !0,
7995
8058
  results: v.results || [],
7996
8059
  output: v.output || "",
@@ -8000,19 +8063,19 @@ const yt = Me(({
8000
8063
  passedCount: v.passedCount || 0,
8001
8064
  failedCount: v.failedCount || 0
8002
8065
  };
8003
- c.current.onCustomAction({
8066
+ d.current.onCustomAction({
8004
8067
  type: "codeTestSubmitted",
8005
8068
  moduleIndex: a.current.currentModuleIndex,
8006
8069
  lessonIndex: a.current.currentLessonIndex,
8007
8070
  questionIndex: a.current.currentQuestionIndex,
8008
- testResult: z,
8071
+ testResult: T,
8009
8072
  question: R
8010
- }), p.current && p.current(z);
8011
- }, [H, w]), ae = F(() => {
8073
+ }), p.current && p.current(T);
8074
+ }, [I, z]), oe = N(() => {
8012
8075
  if (a.current.currentQuestionIndex > 0) {
8013
8076
  a.current.currentQuestionIndex -= 1;
8014
- const v = H();
8015
- v && c.current.onCustomAction({
8077
+ const v = I();
8078
+ v && d.current.onCustomAction({
8016
8079
  type: "questionStart",
8017
8080
  moduleIndex: a.current.currentModuleIndex,
8018
8081
  lessonIndex: a.current.currentLessonIndex,
@@ -8024,82 +8087,82 @@ const yt = Me(({
8024
8087
  const R = () => {
8025
8088
  if (!u.current || !v) return;
8026
8089
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
8027
- const z = I.current || { lipsyncLang: "en" };
8090
+ const T = H.current || { lipsyncLang: "en" };
8028
8091
  v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8029
- lipsyncLang: z.lipsyncLang
8092
+ lipsyncLang: T.lipsyncLang
8030
8093
  }) : u.current.speakText(`Going back to: ${v.question}`, {
8031
- lipsyncLang: z.lipsyncLang
8094
+ lipsyncLang: T.lipsyncLang
8032
8095
  });
8033
8096
  };
8034
8097
  if (u.current && u.current.isReady && v)
8035
8098
  R();
8036
8099
  else if (v) {
8037
- const z = setInterval(() => {
8038
- u.current && u.current.isReady && (clearInterval(z), R());
8100
+ const T = setInterval(() => {
8101
+ u.current && u.current.isReady && (clearInterval(T), R());
8039
8102
  }, 100);
8040
8103
  setTimeout(() => {
8041
- clearInterval(z);
8104
+ clearInterval(T);
8042
8105
  }, 5e3);
8043
8106
  }
8044
8107
  }
8045
- }, [H]), pe = F(() => {
8046
- const v = E.current || { modules: [] };
8108
+ }, [I]), he = N(() => {
8109
+ const v = P.current || { modules: [] };
8047
8110
  if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8048
- 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, c.current.onCustomAction({
8111
+ 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({
8049
8112
  type: "lessonStart",
8050
8113
  moduleIndex: a.current.currentModuleIndex,
8051
8114
  lessonIndex: a.current.currentLessonIndex
8052
- }), c.current.onLessonStart({
8115
+ }), d.current.onLessonStart({
8053
8116
  moduleIndex: a.current.currentModuleIndex,
8054
8117
  lessonIndex: a.current.currentLessonIndex,
8055
8118
  lesson: y()
8056
8119
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8057
8120
  else if (a.current.currentModuleIndex > 0) {
8058
8121
  const M = v.modules[a.current.currentModuleIndex - 1];
8059
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (M?.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, c.current.onCustomAction({
8122
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (M?.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({
8060
8123
  type: "lessonStart",
8061
8124
  moduleIndex: a.current.currentModuleIndex,
8062
8125
  lessonIndex: a.current.currentLessonIndex
8063
- }), c.current.onLessonStart({
8126
+ }), d.current.onLessonStart({
8064
8127
  moduleIndex: a.current.currentModuleIndex,
8065
8128
  lessonIndex: a.current.currentLessonIndex,
8066
8129
  lesson: y()
8067
8130
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8068
8131
  }
8069
- }, [y]), te = F(() => {
8132
+ }, [y]), K = N(() => {
8070
8133
  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;
8071
- }, []), le = F((v) => {
8134
+ }, []), Q = N((v) => {
8072
8135
  console.log("Avatar is ready!", v);
8073
- const R = y(), z = R?.avatar_script || R?.body;
8074
- h && z && setTimeout(() => {
8075
- d.current && d.current();
8136
+ const R = y(), T = R?.avatar_script || R?.body;
8137
+ h && T && setTimeout(() => {
8138
+ c.current && c.current();
8076
8139
  }, 10);
8077
8140
  }, [h, y]);
8078
8141
  Xe(() => {
8079
- d.current = X, g.current = K, b.current = D, x.current = V, A.current = $, B.current = k, p.current = ee;
8080
- }), Ee(r, () => ({
8142
+ c.current = B, g.current = _, b.current = A, x.current = C, S.current = Y, G.current = k, p.current = ee;
8143
+ }), Fe(r, () => ({
8081
8144
  // Curriculum control methods
8082
- startTeaching: X,
8145
+ startTeaching: B,
8083
8146
  startQuestions: k,
8084
8147
  handleAnswerSelect: ee,
8085
- handleCodeTestResult: se,
8086
- nextQuestion: V,
8087
- previousQuestion: ae,
8088
- nextLesson: K,
8089
- previousLesson: pe,
8090
- completeLesson: D,
8091
- completeCurriculum: $,
8092
- resetCurriculum: te,
8148
+ handleCodeTestResult: ie,
8149
+ nextQuestion: C,
8150
+ previousQuestion: oe,
8151
+ nextLesson: _,
8152
+ previousLesson: he,
8153
+ completeLesson: A,
8154
+ completeCurriculum: Y,
8155
+ resetCurriculum: K,
8093
8156
  getState: () => ({ ...a.current }),
8094
- getCurrentQuestion: () => H(),
8157
+ getCurrentQuestion: () => I(),
8095
8158
  getCurrentLesson: () => y(),
8096
8159
  // Direct access to avatar ref (always returns current value)
8097
8160
  getAvatarRef: () => u.current,
8098
8161
  // Convenience methods that delegate to avatar (always check current ref)
8099
8162
  speakText: async (v, R = {}) => {
8100
8163
  await u.current?.resumeAudioContext?.();
8101
- const z = I.current || { lipsyncLang: "en" };
8102
- u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || z.lipsyncLang });
8164
+ const T = H.current || { lipsyncLang: "en" };
8165
+ u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || T.lipsyncLang });
8103
8166
  },
8104
8167
  resumeAudioContext: async () => {
8105
8168
  if (u.current?.resumeAudioContext)
@@ -8110,8 +8173,8 @@ const yt = Me(({
8110
8173
  if (R.state === "suspended" || R.state === "interrupted")
8111
8174
  try {
8112
8175
  await R.resume(), console.log("Audio context resumed via talkingHead");
8113
- } catch (z) {
8114
- console.warn("Failed to resume audio context:", z);
8176
+ } catch (T) {
8177
+ console.warn("Failed to resume audio context:", T);
8115
8178
  }
8116
8179
  } else
8117
8180
  console.warn("Audio context not available yet");
@@ -8133,7 +8196,7 @@ const yt = Me(({
8133
8196
  unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8134
8197
  // Custom action trigger
8135
8198
  triggerCustomAction: (v, R) => {
8136
- c.current.onCustomAction({
8199
+ d.current.onCustomAction({
8137
8200
  type: v,
8138
8201
  ...R,
8139
8202
  state: { ...a.current }
@@ -8143,8 +8206,8 @@ const yt = Me(({
8143
8206
  handleResize: () => u.current?.handleResize(),
8144
8207
  // Avatar readiness check (always returns current value)
8145
8208
  isAvatarReady: () => u.current?.isReady || !1
8146
- }), [X, k, ee, se, V, K, D, $, te, H, y]);
8147
- const U = I.current || {
8209
+ }), [B, k, ee, ie, C, _, A, Y, K, I, y]);
8210
+ const W = H.current || {
8148
8211
  avatarUrl: "/avatars/brunette.glb",
8149
8212
  avatarBody: "F",
8150
8213
  mood: "happy",
@@ -8157,23 +8220,23 @@ const yt = Me(({
8157
8220
  showFullAvatar: !1,
8158
8221
  animations: e
8159
8222
  };
8160
- return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
8223
+ return /* @__PURE__ */ pe("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ pe(
8161
8224
  Ve,
8162
8225
  {
8163
8226
  ref: u,
8164
- avatarUrl: U.avatarUrl,
8165
- avatarBody: U.avatarBody,
8166
- mood: U.mood,
8167
- ttsLang: U.ttsLang,
8168
- ttsService: U.ttsService,
8169
- ttsVoice: U.ttsVoice,
8170
- ttsApiKey: U.ttsApiKey,
8171
- bodyMovement: U.bodyMovement,
8172
- movementIntensity: U.movementIntensity,
8173
- showFullAvatar: U.showFullAvatar,
8227
+ avatarUrl: W.avatarUrl,
8228
+ avatarBody: W.avatarBody,
8229
+ mood: W.mood,
8230
+ ttsLang: W.ttsLang,
8231
+ ttsService: W.ttsService,
8232
+ ttsVoice: W.ttsVoice,
8233
+ ttsApiKey: W.ttsApiKey,
8234
+ bodyMovement: W.bodyMovement,
8235
+ movementIntensity: W.movementIntensity,
8236
+ showFullAvatar: W.showFullAvatar,
8174
8237
  cameraView: "upper",
8175
- animations: U.animations,
8176
- onReady: le,
8238
+ animations: W.animations,
8239
+ onReady: Q,
8177
8240
  onLoading: () => {
8178
8241
  },
8179
8242
  onError: (v) => {
@@ -8286,14 +8349,14 @@ const Ge = {
8286
8349
  duration: 5e3,
8287
8350
  description: "Excited, energetic movement"
8288
8351
  }
8289
- }, wt = (Z) => Ge[Z] || null, zt = (Z) => Ge.hasOwnProperty(Z);
8352
+ }, wt = (X) => Ge[X] || null, zt = (X) => Ge.hasOwnProperty(X);
8290
8353
  export {
8291
8354
  yt as CurriculumLearning,
8292
8355
  gt as SimpleTalkingAvatar,
8293
8356
  Ve as TalkingHeadAvatar,
8294
8357
  pt as TalkingHeadComponent,
8295
8358
  Ge as animations,
8296
- Fe as getActiveTTSConfig,
8359
+ Ee as getActiveTTSConfig,
8297
8360
  wt as getAnimation,
8298
8361
  kt as getVoiceOptions,
8299
8362
  zt as hasAnimation