@sage-rsc/talking-head-react 1.4.5 → 1.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs as Pe, jsx as ye } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as W, useState as pe, useEffect as ce, useCallback as O, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
2
+ import { forwardRef as Me, useRef as G, useState as pe, useEffect as ce, useCallback as D, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
3
3
  import * as y from "three";
4
4
  import { OrbitControls as je } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as Ye } from "three/addons/loaders/GLTFLoader.js";
@@ -8,7 +8,7 @@ import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
9
  import _e from "three/addons/libs/stats.module.js";
10
10
  let m, ue, he;
11
- const C = [0, 0, 0, 0], M = new y.Vector3(), ze = new y.Vector3(), ae = new y.Vector3(), Ce = new y.Vector3();
11
+ const z = [0, 0, 0, 0], T = new y.Vector3(), ze = new y.Vector3(), ae = new y.Vector3(), Ce = new y.Vector3();
12
12
  new y.Plane();
13
13
  new y.Ray();
14
14
  new y.Euler();
@@ -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(M).clone(),
324
+ vWorld: r.parent.getWorldPosition(T).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(M, re, ae), M.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Ne.setFromUnitVectors(He, M).invert()).normalize(), u.qWorldInverseYaw = re.clone().normalize(), this.data.push(u), this.dict[h] = u;
341
+ u.boneParent.matrixWorld.decompose(T, re, ae), T.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Ne.setFromUnitVectors(He, T).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], M.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), M.applyMatrix4(xe), M.length() > 0.5 && (console.info("Info: Unrealistic jump of " + M.length().toFixed(2) + " meters."), M.setLength(0.5)), M.applyQuaternion(o.bone.quaternion), C[0] = M.x, C[1] = M.y, C[2] = -M.z, C[3] = M.length() / 3, o.children)
359
+ if (o = this.data[e], T.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), T.applyMatrix4(xe), T.length() > 0.5 && (console.info("Info: Unrealistic jump of " + T.length().toFixed(2) + " meters."), T.setLength(0.5)), T.applyQuaternion(o.bone.quaternion), z[0] = T.x, z[1] = T.y, z[2] = -T.z, z[3] = T.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
- m = o.children[n], C[0] -= m.v[0] * t / 3, C[1] -= m.v[1] * t / 3, C[2] += m.v[2] * t / 3, C[3] -= m.v[3] * t / 3;
362
- if (m = this.opt.sensitivityFactor, C[0] *= o.ext * m, C[1] *= o.ext * m, C[2] *= o.ext * m, C[3] *= o.ext * m, o.isX && (m = C[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 + C[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 = C[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 + C[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 = C[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 + C[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 = C[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 + C[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), C[0] = o.p[0], C[1] = o.p[1], C[2] = o.p[2], C[3] = o.p[3], m = this.opt.movementFactor, C[0] *= m, C[1] *= m, C[2] *= m, C[3] *= m, o.dl && (m = o.dl, C[0] += m[0], C[1] += m[1], C[2] += m[2]), o.dw && (m = o.dw, M.set(
363
- o.vBasis.x + C[0],
364
- o.vBasis.y + C[1],
365
- o.vBasis.z + C[2]
366
- ), M.applyMatrix4(fe), M.x += m[0], M.y += m[1], M.z += m[2], M.applyMatrix4(xe), C[0] += M.x - o.vBasis.x, C[1] += M.y - o.vBasis.y, C[2] += M.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && C[0] < m[0][0] && (C[0] = m[0][0]), m[0][1] !== null && C[0] > m[0][1] && (C[0] = m[0][1])), m[1] && (m[1][0] !== null && C[1] < m[1][0] && (C[1] = m[1][0]), m[1][1] !== null && C[1] > m[1][1] && (C[1] = m[1][1])), m[2] && (m[2][0] !== null && C[2] < m[2][0] && (C[2] = m[2][0]), m[2][1] !== null && C[2] > m[2][1] && (C[2] = m[2][1])), m[3] && (m[3][0] !== null && C[3] < m[3][0] && (C[3] = m[3][0]), m[3][1] !== null && C[3] > m[3][1] && (C[3] = m[3][1]))), o.isPoint)
361
+ m = o.children[n], z[0] -= m.v[0] * t / 3, z[1] -= m.v[1] * t / 3, z[2] += m.v[2] * t / 3, z[3] -= m.v[3] * t / 3;
362
+ if (m = this.opt.sensitivityFactor, z[0] *= o.ext * m, z[1] *= o.ext * m, z[2] *= o.ext * m, z[3] *= o.ext * m, o.isX && (m = z[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + z[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = z[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + z[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = z[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + z[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = z[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + z[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), z[0] = o.p[0], z[1] = o.p[1], z[2] = o.p[2], z[3] = o.p[3], m = this.opt.movementFactor, z[0] *= m, z[1] *= m, z[2] *= m, z[3] *= m, o.dl && (m = o.dl, z[0] += m[0], z[1] += m[1], z[2] += m[2]), o.dw && (m = o.dw, T.set(
363
+ o.vBasis.x + z[0],
364
+ o.vBasis.y + z[1],
365
+ o.vBasis.z + z[2]
366
+ ), T.applyMatrix4(fe), T.x += m[0], T.y += m[1], T.z += m[2], T.applyMatrix4(xe), z[0] += T.x - o.vBasis.x, z[1] += T.y - o.vBasis.y, z[2] += T.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && z[0] < m[0][0] && (z[0] = m[0][0]), m[0][1] !== null && z[0] > m[0][1] && (z[0] = m[0][1])), m[1] && (m[1][0] !== null && z[1] < m[1][0] && (z[1] = m[1][0]), m[1][1] !== null && z[1] > m[1][1] && (z[1] = m[1][1])), m[2] && (m[2][0] !== null && z[2] < m[2][0] && (z[2] = m[2][0]), m[2][1] !== null && z[2] > m[2][1] && (z[2] = m[2][1])), m[3] && (m[3][0] !== null && z[3] < m[3][0] && (z[3] = m[3][0]), m[3][1] !== null && z[3] > m[3][1] && (z[3] = m[3][1]))), o.isPoint)
367
367
  o.bone.position.set(
368
- o.vBasis.x + C[0],
369
- o.vBasis.y + C[1],
370
- o.vBasis.z - C[2]
368
+ o.vBasis.x + z[0],
369
+ o.vBasis.y + z[1],
370
+ o.vBasis.z - z[2]
371
371
  );
372
- else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(M, re, ae), M.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Ne.setFromUnitVectors(He, M).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(C[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), o.isY && (m = o.l / 3, m = m * Math.tanh(C[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(C[2] / o.l), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(C[3] * 1.5), re.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(re)), 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(T, re, ae), T.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Ne.setFromUnitVectors(He, T).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(z[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), o.isY && (m = o.l / 3, m = m * Math.tanh(z[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(z[2] / o.l), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(z[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], 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), M.copy(o.bone.position), !(M.distanceToSquared(ae) >= m.radiusSq) && (he = M.length(), ue = ae.length(), !(ue > m.radius + he) && (ue < Math.abs(m.radius - he) || (ue = (ue * ue + he * he - m.radiusSq) / (2 * ue), ae.normalize(), Ce.copy(ae).multiplyScalar(ue), ue = Math.sqrt(he * he - ue * ue), M.subVectors(M, Ce).projectOnPlane(ae).normalize().multiplyScalar(ue), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), he = ze.dot(M), he < 0 && (he = Math.sqrt(ue * ue - he * he), ze.multiplyScalar(he), M.add(ze)), M.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, M), o.boneParent.quaternion.premultiply(re), 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), T.copy(o.bone.position), !(T.distanceToSquared(ae) >= m.radiusSq) && (he = T.length(), ue = ae.length(), !(ue > m.radius + he) && (ue < Math.abs(m.radius - he) || (ue = (ue * ue + he * he - m.radiusSq) / (2 * ue), ae.normalize(), Ce.copy(ae).multiplyScalar(ue), ue = Math.sqrt(he * he - ue * ue), T.subVectors(T, Ce).projectOnPlane(ae).normalize().multiplyScalar(ue), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), he = ze.dot(T), he < 0 && (he = Math.sqrt(ue * ue - he * he), ze.multiplyScalar(he), T.add(ze)), T.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, T), 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), M.setFromMatrixPosition(fe), t.setXYZ(e, M.x, M.y, M.z);
448
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), T.setFromMatrixPosition(fe), t.setXYZ(e, T.x, T.y, T.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), M.setFromMatrixPosition(fe), t.setXYZ(n, M.x, M.y, M.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), M.setFromMatrixPosition(fe), t.setXYZ(n + 1, M.x, M.y, M.z);
455
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), T.setFromMatrixPosition(fe), t.setXYZ(n, T.x, T.y, T.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), T.setFromMatrixPosition(fe), t.setXYZ(n + 1, T.x, T.y, T.z);
456
456
  t.needsUpdate = !0, m.object.updateMatrixWorld();
457
457
  }
458
458
  }
@@ -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 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, x = 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 + x, n[(h + a + i / 2) * 2] = d - g, n[(h + a + i / 2) * 2 + 1] = c - x;
611
- const f = r * o - u * l, k = r * l + u * o;
612
- r = f, u = k;
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
  }
@@ -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
- }, $ = new y.Quaternion(), Z = new y.Euler(), ve = new y.Vector3(), Re = new y.Vector3(), We = new y.Box3();
2632
+ }, $ = new y.Quaternion(), j = new y.Euler(), ve = new y.Vector3(), Re = new y.Vector3(), We = new y.Box3();
2633
2633
  new y.Matrix4();
2634
2634
  new y.Matrix4();
2635
2635
  new y.Vector3();
@@ -4228,13 +4228,13 @@ class Be {
4228
4228
  const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], c = o.morphAttributes.normal?.[a];
4229
4229
  l || (l = new y.Float32BufferAttribute(d.count * 3, 3), c && (h = new y.Float32BufferAttribute(d.count * 3, 3)));
4230
4230
  for (let g = 0; g < d.count; g++) {
4231
- const x = l.getX(g) + d.getX(g) * u, f = l.getY(g) + d.getY(g) * u, k = l.getZ(g) + d.getZ(g) * u;
4232
- l.setXYZ(g, x, f, k);
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
4234
  if (c)
4235
4235
  for (let g = 0; g < d.count; g++) {
4236
- const x = h.getX(g) + c.getX(g) * u, f = h.getY(g) + c.getY(g) * u, k = h.getZ(g) + c.getZ(g) * u;
4237
- h.setXYZ(g, x, f, k);
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) {
@@ -4398,14 +4398,14 @@ class Be {
4398
4398
  * This is called from updatePoseBase for pose-based animations
4399
4399
  */
4400
4400
  applyShoulderAdjustment() {
4401
- const t = new y.Euler(), e = 0.8, n = 0.9;
4401
+ const t = new y.Euler(), e = 0.6, n = 0.7;
4402
4402
  if (this.poseAvatar.props["LeftShoulder.quaternion"]) {
4403
4403
  const i = this.poseAvatar.props["LeftShoulder.quaternion"];
4404
- t.setFromQuaternion(i, "XYZ"), t.x > n ? t.x = e : t.x > e && (t.x = e + (t.x - e) * 0.3), i.setFromEuler(t, "XYZ");
4404
+ t.setFromQuaternion(i, "XYZ"), t.x > n ? t.x = e : t.x > e && (t.x = e + (t.x - e) * 0.2), i.setFromEuler(t, "XYZ");
4405
4405
  }
4406
4406
  if (this.poseAvatar.props["RightShoulder.quaternion"]) {
4407
4407
  const i = this.poseAvatar.props["RightShoulder.quaternion"];
4408
- t.setFromQuaternion(i, "XYZ"), t.x > n ? t.x = e : t.x > e && (t.x = e + (t.x - e) * 0.3), i.setFromEuler(t, "XYZ");
4408
+ t.setFromQuaternion(i, "XYZ"), t.x > n ? t.x = e : t.x > e && (t.x = e + (t.x - e) * 0.2), i.setFromEuler(t, "XYZ");
4409
4409
  }
4410
4410
  }
4411
4411
  /**
@@ -4418,8 +4418,17 @@ class Be {
4418
4418
  if (!this.armature) return;
4419
4419
  const t = this.armature.getObjectByName("LeftShoulder"), e = this.armature.getObjectByName("RightShoulder");
4420
4420
  if (!t || !e) return;
4421
- const n = new y.Euler(), i = new y.Quaternion(), s = 0.8, o = 0.9;
4422
- t.quaternion && (n.setFromQuaternion(t.quaternion, "XYZ"), n.x > o ? n.x = s : n.x > s && (n.x = s + (n.x - s) * 0.3), i.setFromEuler(n, "XYZ"), t.quaternion.copy(i), t.updateMatrixWorld(!0)), e.quaternion && (n.setFromQuaternion(e.quaternion, "XYZ"), n.x > o ? n.x = s : n.x > s && (n.x = s + (n.x - s) * 0.3), i.setFromEuler(n, "XYZ"), e.quaternion.copy(i), e.updateMatrixWorld(!0));
4421
+ const n = new y.Euler(), i = new y.Quaternion(), s = 0.6, o = 0.7;
4422
+ if (t.quaternion) {
4423
+ n.setFromQuaternion(t.quaternion, "XYZ");
4424
+ const l = n.x;
4425
+ n.x > o ? n.x = s : n.x > s && (n.x = s + (n.x - s) * 0.2), Math.abs(n.x - l) > 0.01 && (i.setFromEuler(n, "XYZ"), t.quaternion.copy(i), t.updateMatrixWorld(!0));
4426
+ }
4427
+ if (e.quaternion) {
4428
+ n.setFromQuaternion(e.quaternion, "XYZ");
4429
+ const l = n.x;
4430
+ n.x > o ? n.x = s : n.x > s && (n.x = s + (n.x - s) * 0.2), Math.abs(n.x - l) > 0.01 && (i.setFromEuler(n, "XYZ"), e.quaternion.copy(i), e.updateMatrixWorld(!0));
4431
+ }
4423
4432
  }
4424
4433
  /**
4425
4434
  * Update avatar pose deltas
@@ -4427,9 +4436,9 @@ class Be {
4427
4436
  updatePoseDelta() {
4428
4437
  for (const [t, e] of Object.entries(this.poseDelta.props)) {
4429
4438
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4430
- Z.set(e.x, e.y, e.z);
4439
+ j.set(e.x, e.y, e.z);
4431
4440
  const n = this.poseAvatar.props[t];
4432
- n.isQuaternion ? ($.setFromEuler(Z), n.multiply($)) : n.isVector3 && n.add(Z);
4441
+ n.isQuaternion ? ($.setFromEuler(j), n.multiply($)) : n.isVector3 && n.add(j);
4433
4442
  }
4434
4443
  }
4435
4444
  /**
@@ -5136,9 +5145,9 @@ class Be {
5136
5145
  g.newvalue = c[i];
5137
5146
  else {
5138
5147
  g.newvalue = c[i + 1];
5139
- const x = a.ts[i + 1] - a.ts[i];
5140
- let f = 1;
5141
- x > 1e-4 && (f = (this.animClock - a.ts[i]) / x), f < 1 && (g.easing && (f = g.easing(f)), g.newvalue = (1 - f) * c[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
5148
+ const b = a.ts[i + 1] - a.ts[i];
5149
+ let x = 1;
5150
+ 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;
5142
5151
  }
5143
5152
  if (l)
5144
5153
  switch (d) {
@@ -5201,7 +5210,7 @@ class Be {
5201
5210
  }, i.x ? new y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5202
5211
  break;
5203
5212
  }
5204
- 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({
5213
+ if ((h || r) && (j.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), j.x = Math.max(-0.9, Math.min(0.9, 2 * j.x - 0.5)), j.y = Math.max(-0.9, Math.min(0.9, -2.5 * j.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: j.x < 0 ? -j.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: j.x < 0 ? 0 : j.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: j.y < 0 ? -j.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: j.y < 0 ? 0 : j.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: j.y < 0 ? 0 : j.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: j.y < 0 ? -j.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5205
5214
  name: "headmove",
5206
5215
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5207
5216
  vs: {
@@ -5291,12 +5300,12 @@ class Be {
5291
5300
  e = e || {};
5292
5301
  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;
5293
5302
  let u = "", a = "", d = 0, c = [], g = [];
5294
- const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
5295
- for (let f = 0; f < x.length; f++) {
5296
- const k = f === x.length - 1, D = x[f].match(l);
5297
- let p = x[f].match(s);
5298
- const B = x[f].match(h), T = x[f].match(o);
5299
- if (p && !k && !B && x[f + 1].match(s) && (p = !1), n && (u += x[f]), D && (!i || i.every((R) => f < R[0] || f > R[1])) && (a += x[f]), (T || p || k) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5303
+ const b = Array.from(this.segmenter.segment(t), (x) => x.segment);
5304
+ for (let x = 0; x < b.length; x++) {
5305
+ const S = x === b.length - 1, U = b[x].match(l);
5306
+ let p = b[x].match(s);
5307
+ const P = b[x].match(h), H = b[x].match(o);
5308
+ if (p && !S && !P && b[x + 1].match(s) && (p = !1), n && (u += b[x]), U && (!i || i.every((I) => x < I[0] || x > I[1])) && (a += b[x]), (H || p || S) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5300
5309
  mark: d,
5301
5310
  word: a
5302
5311
  })), u.length && (g.push({
@@ -5307,31 +5316,31 @@ class Be {
5307
5316
  subtitles: [u]
5308
5317
  }
5309
5318
  }), u = ""), a.length)) {
5310
- const R = this.lipsyncWordsToVisemes(a, r);
5311
- if (R && R.visemes && R.visemes.length) {
5312
- const L = R.times[R.visemes.length - 1] + R.durations[R.visemes.length - 1];
5313
- for (let I = 0; I < R.visemes.length; I++)
5319
+ const I = this.lipsyncWordsToVisemes(a, r);
5320
+ if (I && I.visemes && I.visemes.length) {
5321
+ const O = I.times[I.visemes.length - 1] + I.durations[I.visemes.length - 1];
5322
+ for (let f = 0; f < I.visemes.length; f++)
5314
5323
  g.push({
5315
5324
  mark: d,
5316
5325
  template: { name: "viseme" },
5317
- ts: [(R.times[I] - 0.6) / L, (R.times[I] + 0.5) / L, (R.times[I] + R.durations[I] + 0.5) / L],
5326
+ ts: [(I.times[f] - 0.6) / O, (I.times[f] + 0.5) / O, (I.times[f] + I.durations[f] + 0.5) / O],
5318
5327
  vs: {
5319
- ["viseme_" + R.visemes[I]]: [null, R.visemes[I] === "PP" || R.visemes[I] === "FF" ? 0.9 : 0.6, 0]
5328
+ ["viseme_" + I.visemes[f]]: [null, I.visemes[f] === "PP" || I.visemes[f] === "FF" ? 0.9 : 0.6, 0]
5320
5329
  }
5321
5330
  });
5322
5331
  }
5323
5332
  a = "", d++;
5324
5333
  }
5325
- if (p || k) {
5326
- if (c.length || k && g.length) {
5327
- const R = {
5334
+ if (p || S) {
5335
+ if (c.length || S && g.length) {
5336
+ const I = {
5328
5337
  anim: g
5329
5338
  };
5330
- n && (R.onSubtitles = n), c.length && !e.avatarMute && (R.text = c, e.avatarMood && (R.mood = e.avatarMood), e.ttsLang && (R.lang = e.ttsLang), e.ttsVoice && (R.voice = e.ttsVoice), e.ttsRate && (R.rate = e.ttsRate), e.ttsVoice && (R.pitch = e.ttsPitch), e.ttsVolume && (R.volume = e.ttsVolume)), this.speechQueue.push(R), c = [], a = "", d = 0, g = [];
5339
+ n && (I.onSubtitles = n), c.length && !e.avatarMute && (I.text = c, e.avatarMood && (I.mood = e.avatarMood), e.ttsLang && (I.lang = e.ttsLang), e.ttsVoice && (I.voice = e.ttsVoice), e.ttsRate && (I.rate = e.ttsRate), e.ttsVoice && (I.pitch = e.ttsPitch), e.ttsVolume && (I.volume = e.ttsVolume)), this.speechQueue.push(I), c = [], a = "", d = 0, g = [];
5331
5340
  }
5332
- if (B) {
5333
- let R = this.animEmojis[x[f]];
5334
- R && R.link && (R = this.animEmojis[R.link]), R && this.speechQueue.push({ emoji: R });
5341
+ if (P) {
5342
+ let I = this.animEmojis[b[x]];
5343
+ I && I.link && (I = this.animEmojis[I.link]), I && this.speechQueue.push({ emoji: I });
5335
5344
  }
5336
5345
  this.speechQueue.push({ break: 100 });
5337
5346
  }
@@ -5424,15 +5433,15 @@ class Be {
5424
5433
  const a = this.lipsyncPreProcessText(h, i), d = this.lipsyncWordsToVisemes(a, i);
5425
5434
  if (d && d.visemes && d.visemes.length) {
5426
5435
  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));
5427
- let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5436
+ let b = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5428
5437
  if (u = Math.min(u, d.visemes.length * 200), c > 0)
5429
- for (let f = 0; f < d.visemes.length; f++) {
5430
- const k = r + d.times[f] / c * u, D = d.durations[f] / c * u;
5438
+ for (let x = 0; x < d.visemes.length; x++) {
5439
+ const S = r + d.times[x] / c * u, U = d.durations[x] / c * u;
5431
5440
  o.push({
5432
5441
  template: { name: "viseme" },
5433
- ts: [k - Math.min(60, 2 * D / 3), k + Math.min(25, D / 2), k + D + Math.min(60, D / 2)],
5442
+ ts: [S - Math.min(60, 2 * U / 3), S + Math.min(25, U / 2), S + U + Math.min(60, U / 2)],
5434
5443
  vs: {
5435
- ["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : x, 0]
5444
+ ["viseme_" + d.visemes[x]]: [null, d.visemes[x] === "PP" || d.visemes[x] === "FF" ? 0.9 : b, 0]
5436
5445
  }
5437
5446
  });
5438
5447
  }
@@ -5512,34 +5521,34 @@ class Be {
5512
5521
  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));
5513
5522
  const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5514
5523
  if (a && u.length > 0) {
5515
- const p = u.find((B) => B.name.includes(a) || B.lang === o);
5524
+ const p = u.find((P) => P.name.includes(a) || P.lang === o);
5516
5525
  p && (s.voice = p);
5517
5526
  }
5518
- 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", x = this.lipsyncPreProcessText(i, g), f = this.lipsyncWordsToVisemes(x, g);
5527
+ 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);
5519
5528
  console.log("Browser TTS Lip-sync Debug:", {
5520
5529
  text: i,
5521
5530
  lipsyncLang: g,
5522
- processedText: x,
5523
- lipsyncData: f,
5524
- hasVisemes: f && f.visemes && f.visemes.length > 0,
5531
+ processedText: b,
5532
+ lipsyncData: x,
5533
+ hasVisemes: x && x.visemes && x.visemes.length > 0,
5525
5534
  estimatedDuration: d
5526
5535
  });
5527
- const k = [];
5528
- if (f && f.visemes && f.visemes.length > 0) {
5529
- const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5530
- for (let B = 0; B < f.visemes.length; B++) {
5531
- const T = f.visemes[B], R = f.times[B] / p, L = f.durations[B] / p, I = R * d, z = L * d;
5532
- k.push({
5536
+ const S = [];
5537
+ if (x && x.visemes && x.visemes.length > 0) {
5538
+ const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5539
+ for (let P = 0; P < x.visemes.length; P++) {
5540
+ const H = x.visemes[P], I = x.times[P] / p, O = x.durations[P] / p, f = I * d, N = O * d;
5541
+ S.push({
5533
5542
  template: { name: "viseme" },
5534
- ts: [I - Math.min(60, 2 * z / 3), I + Math.min(25, z / 2), I + z + Math.min(60, z / 2)],
5543
+ ts: [f - Math.min(60, 2 * N / 3), f + Math.min(25, N / 2), f + N + Math.min(60, N / 2)],
5535
5544
  vs: {
5536
- ["viseme_" + T]: [null, T === "PP" || T === "FF" ? 0.9 : 0.6, 0]
5545
+ ["viseme_" + H]: [null, H === "PP" || H === "FF" ? 0.9 : 0.6, 0]
5537
5546
  }
5538
5547
  });
5539
5548
  }
5540
5549
  }
5541
- const D = [...t.anim, ...k];
5542
- this.audioPlaylist.push({ anim: D, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5550
+ const U = [...t.anim, ...S];
5551
+ this.audioPlaylist.push({ anim: U, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5543
5552
  e();
5544
5553
  }, s.onerror = (p) => {
5545
5554
  console.error("Speech synthesis error:", p.error), n(p.error);
@@ -5588,10 +5597,10 @@ class Be {
5588
5597
  hasVisemes: c && c.visemes && c.visemes.length > 0
5589
5598
  }), c && c.visemes && c.visemes.length > 0)
5590
5599
  r = {
5591
- visemes: c.visemes.map((g, x) => ({
5600
+ visemes: c.visemes.map((g, b) => ({
5592
5601
  viseme: g,
5593
- startTime: x * l.duration / c.visemes.length,
5594
- endTime: (x + 1) * l.duration / c.visemes.length,
5602
+ startTime: b * l.duration / c.visemes.length,
5603
+ endTime: (b + 1) * l.duration / c.visemes.length,
5595
5604
  duration: l.duration / c.visemes.length,
5596
5605
  intensity: 0.7
5597
5606
  })),
@@ -5604,16 +5613,16 @@ class Be {
5604
5613
  } catch (d) {
5605
5614
  console.error("Text-based lip-sync failed, using fallback:", d);
5606
5615
  const c = e.toLowerCase().split(/\s+/), g = [];
5607
- for (const x of c)
5608
- for (const f of x) {
5609
- let k = "aa";
5610
- "aeiou".includes(f) ? k = "aa" : "bp".includes(f) ? k = "PP" : "fv".includes(f) ? k = "FF" : "st".includes(f) ? k = "SS" : "dln".includes(f) ? k = "DD" : "kg".includes(f) ? k = "kk" : "rw".includes(f) && (k = "RR"), g.push(k);
5616
+ for (const b of c)
5617
+ for (const x of b) {
5618
+ let S = "aa";
5619
+ "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);
5611
5620
  }
5612
5621
  r = {
5613
- visemes: g.map((x, f) => ({
5614
- viseme: x,
5615
- startTime: f * l.duration / g.length,
5616
- endTime: (f + 1) * l.duration / g.length,
5622
+ visemes: g.map((b, x) => ({
5623
+ viseme: b,
5624
+ startTime: x * l.duration / g.length,
5625
+ endTime: (x + 1) * l.duration / g.length,
5617
5626
  duration: l.duration / g.length,
5618
5627
  intensity: 0.6
5619
5628
  })),
@@ -5638,12 +5647,12 @@ class Be {
5638
5647
  if (r.visemes && r.visemes.length > 0) {
5639
5648
  console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5640
5649
  for (let d = 0; d < r.visemes.length; d++) {
5641
- const c = r.visemes[d], g = c.startTime * 1e3, x = c.duration * 1e3, f = c.intensity;
5650
+ const c = r.visemes[d], g = c.startTime * 1e3, b = c.duration * 1e3, x = c.intensity;
5642
5651
  u.push({
5643
5652
  template: { name: "viseme" },
5644
- ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5653
+ ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
5645
5654
  vs: {
5646
- ["viseme_" + c.viseme]: [null, f, 0]
5655
+ ["viseme_" + c.viseme]: [null, x, 0]
5647
5656
  }
5648
5657
  });
5649
5658
  }
@@ -5686,10 +5695,10 @@ class Be {
5686
5695
  hasVisemes: c && c.visemes && c.visemes.length > 0
5687
5696
  }), c && c.visemes && c.visemes.length > 0)
5688
5697
  r = {
5689
- visemes: c.visemes.map((g, x) => ({
5698
+ visemes: c.visemes.map((g, b) => ({
5690
5699
  viseme: g,
5691
- startTime: x * l.duration / c.visemes.length,
5692
- endTime: (x + 1) * l.duration / c.visemes.length,
5700
+ startTime: b * l.duration / c.visemes.length,
5701
+ endTime: (b + 1) * l.duration / c.visemes.length,
5693
5702
  duration: l.duration / c.visemes.length,
5694
5703
  intensity: 0.7
5695
5704
  })),
@@ -5702,16 +5711,16 @@ class Be {
5702
5711
  } catch (d) {
5703
5712
  console.error("Text-based lip-sync failed, using fallback:", d);
5704
5713
  const c = e.toLowerCase().split(/\s+/), g = [];
5705
- for (const x of c)
5706
- for (const f of x) {
5707
- let k = "aa";
5708
- "aeiou".includes(f) ? k = "aa" : "bp".includes(f) ? k = "PP" : "fv".includes(f) ? k = "FF" : "st".includes(f) ? k = "SS" : "dln".includes(f) ? k = "DD" : "kg".includes(f) ? k = "kk" : "rw".includes(f) && (k = "RR"), g.push(k);
5714
+ for (const b of c)
5715
+ for (const x of b) {
5716
+ let S = "aa";
5717
+ "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);
5709
5718
  }
5710
5719
  r = {
5711
- visemes: g.map((x, f) => ({
5712
- viseme: x,
5713
- startTime: f * l.duration / g.length,
5714
- endTime: (f + 1) * l.duration / g.length,
5720
+ visemes: g.map((b, x) => ({
5721
+ viseme: b,
5722
+ startTime: x * l.duration / g.length,
5723
+ endTime: (x + 1) * l.duration / g.length,
5715
5724
  duration: l.duration / g.length,
5716
5725
  intensity: 0.6
5717
5726
  })),
@@ -5736,12 +5745,12 @@ class Be {
5736
5745
  if (r.visemes && r.visemes.length > 0) {
5737
5746
  console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5738
5747
  for (let d = 0; d < r.visemes.length; d++) {
5739
- const c = r.visemes[d], g = c.startTime * 1e3, x = c.duration * 1e3, f = c.intensity;
5748
+ const c = r.visemes[d], g = c.startTime * 1e3, b = c.duration * 1e3, x = c.intensity;
5740
5749
  u.push({
5741
5750
  template: { name: "viseme" },
5742
- ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5751
+ ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
5743
5752
  vs: {
5744
- ["viseme_" + c.viseme]: [null, f, 0]
5753
+ ["viseme_" + c.viseme]: [null, x, 0]
5745
5754
  }
5746
5755
  });
5747
5756
  }
@@ -5788,12 +5797,12 @@ class Be {
5788
5797
  });
5789
5798
  const r = [];
5790
5799
  for (let a = 0; a < h.visemes.length; a++) {
5791
- const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, x = d.intensity;
5800
+ const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, b = d.intensity;
5792
5801
  r.push({
5793
5802
  template: { name: "viseme" },
5794
5803
  ts: [c - Math.min(60, 2 * g / 3), c + Math.min(25, g / 2), c + g + Math.min(60, g / 2)],
5795
5804
  vs: {
5796
- ["viseme_" + d.viseme]: [null, x, 0]
5805
+ ["viseme_" + d.viseme]: [null, b, 0]
5797
5806
  }
5798
5807
  });
5799
5808
  }
@@ -6079,10 +6088,10 @@ class Be {
6079
6088
  let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6080
6089
  if (o = Math.min(o, r.visemes.length * 200), u > 0)
6081
6090
  for (let c = 0; c < r.visemes.length; c++) {
6082
- const g = e + s + r.times[c] / u * o, x = r.durations[c] / u * o;
6091
+ const g = e + s + r.times[c] / u * o, b = r.durations[c] / u * o;
6083
6092
  this.animQueue.push({
6084
6093
  template: { name: "viseme" },
6085
- ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
6094
+ ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
6086
6095
  vs: {
6087
6096
  ["viseme_" + r.visemes[c]]: [null, r.visemes[c] === "PP" || r.visemes[c] === "FF" ? 0.9 : d, 0]
6088
6097
  }
@@ -6190,14 +6199,14 @@ class Be {
6190
6199
  }
6191
6200
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]);
6192
6201
  const n = new y.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6193
- Z.set(s, i, 0, "YXZ");
6194
- const l = new y.Quaternion().setFromEuler(Z), h = new y.Quaternion().copy(l).multiply($.clone().invert());
6195
- Z.setFromQuaternion(h, "YXZ");
6196
- 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;
6202
+ j.set(s, i, 0, "YXZ");
6203
+ const l = new y.Quaternion().setFromEuler(j), h = new y.Quaternion().copy(l).multiply($.clone().invert());
6204
+ j.setFromQuaternion(h, "YXZ");
6205
+ let r = j.x / (40 / 24) + 0.2, u = j.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;
6197
6206
  if (t) {
6198
- let x = this.animQueue.findIndex((k) => k.template.name === "lookat");
6199
- x !== -1 && this.animQueue.splice(x, 1);
6200
- const f = {
6207
+ let b = this.animQueue.findIndex((S) => S.template.name === "lookat");
6208
+ b !== -1 && this.animQueue.splice(b, 1);
6209
+ const x = {
6201
6210
  name: "lookat",
6202
6211
  dt: [750, t],
6203
6212
  vs: {
@@ -6212,7 +6221,7 @@ class Be {
6212
6221
  headMove: [0]
6213
6222
  }
6214
6223
  };
6215
- this.animQueue.push(this.animFactory(f));
6224
+ this.animQueue.push(this.animFactory(x));
6216
6225
  }
6217
6226
  }
6218
6227
  /**
@@ -6228,20 +6237,20 @@ class Be {
6228
6237
  const s = new y.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new y.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new y.Vector3().addVectors(s, o).divideScalar(2);
6229
6238
  l.project(this.camera);
6230
6239
  let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6231
- t === null && (t = h), e === null && (e = r), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion($);
6232
- 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), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + d, k = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6233
- f = Math.min(0.6, Math.max(-0.3, f)), k = Math.min(0.8, Math.max(-0.8, k));
6234
- let D = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6240
+ t === null && (t = h), e === null && (e = r), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]), j.setFromQuaternion($);
6241
+ let u = j.x / (40 / 24), a = j.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;
6242
+ x = Math.min(0.6, Math.max(-0.3, x)), S = Math.min(0.8, Math.max(-0.8, S));
6243
+ let U = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6235
6244
  if (n) {
6236
- let B = this.animQueue.findIndex((R) => R.template.name === "lookat");
6237
- B !== -1 && this.animQueue.splice(B, 1);
6238
- const T = {
6245
+ let P = this.animQueue.findIndex((I) => I.template.name === "lookat");
6246
+ P !== -1 && this.animQueue.splice(P, 1);
6247
+ const H = {
6239
6248
  name: "lookat",
6240
6249
  dt: [750, n],
6241
6250
  vs: {
6242
- bodyRotateX: [f + D],
6243
- bodyRotateY: [k + p],
6244
- eyesRotateX: [-3 * D + 0.1],
6251
+ bodyRotateX: [x + U],
6252
+ bodyRotateY: [S + p],
6253
+ eyesRotateX: [-3 * U + 0.1],
6245
6254
  eyesRotateY: [-5 * p],
6246
6255
  browInnerUp: [[0, 0.7]],
6247
6256
  mouthLeft: [[0, 0.7]],
@@ -6250,7 +6259,7 @@ class Be {
6250
6259
  headMove: [0]
6251
6260
  }
6252
6261
  };
6253
- this.animQueue.push(this.animFactory(T));
6262
+ this.animQueue.push(this.animFactory(H));
6254
6263
  }
6255
6264
  }
6256
6265
  /**
@@ -6456,13 +6465,13 @@ class Be {
6456
6465
  suggestion: "Make sure the file is a valid FBX file and the path is correct"
6457
6466
  }), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6458
6467
  try {
6459
- const c = await fetch(t), g = c.headers.get("content-type"), x = await c.text();
6468
+ const c = await fetch(t), g = c.headers.get("content-type"), b = await c.text();
6460
6469
  console.error("Response details:", {
6461
6470
  status: c.status,
6462
6471
  contentType: g,
6463
- firstBytes: x.substring(0, 100),
6464
- isHTML: x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")
6465
- }), (x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6472
+ firstBytes: b.substring(0, 100),
6473
+ isHTML: b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")
6474
+ }), (b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6466
6475
  } catch (c) {
6467
6476
  console.error("Could not fetch file for debugging:", c);
6468
6477
  }
@@ -6471,39 +6480,39 @@ class Be {
6471
6480
  if (a && a.animations && a.animations[i]) {
6472
6481
  let d = a.animations[i];
6473
6482
  const c = /* @__PURE__ */ new Set();
6474
- this.armature && this.armature.traverse((L) => {
6475
- (L.isBone || L.type === "Bone") && c.add(L.name);
6483
+ this.armature && this.armature.traverse((f) => {
6484
+ (f.isBone || f.type === "Bone") && c.add(f.name);
6476
6485
  });
6477
- const g = /* @__PURE__ */ new Map(), x = (L) => {
6478
- if (c.has(L))
6479
- return L;
6480
- let I = L.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
6481
- if (c.has(I))
6482
- return I;
6483
- const z = I.toLowerCase();
6484
- if (z.includes("left") && z.includes("arm")) {
6485
- if (z.includes("fore") || z.includes("lower")) {
6486
+ const g = /* @__PURE__ */ new Map(), b = (f) => {
6487
+ if (c.has(f))
6488
+ return f;
6489
+ let N = f.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
6490
+ if (c.has(N))
6491
+ return N;
6492
+ const w = N.toLowerCase();
6493
+ if (w.includes("left") && w.includes("arm")) {
6494
+ if (w.includes("fore") || w.includes("lower")) {
6486
6495
  if (c.has("LeftForeArm")) return "LeftForeArm";
6487
6496
  if (c.has("LeftForearm")) return "LeftForearm";
6488
- } else if (!z.includes("fore") && !z.includes("hand") && c.has("LeftArm"))
6497
+ } else if (!w.includes("fore") && !w.includes("hand") && c.has("LeftArm"))
6489
6498
  return "LeftArm";
6490
6499
  }
6491
- if (z.includes("right") && z.includes("arm")) {
6492
- if (z.includes("fore") || z.includes("lower")) {
6500
+ if (w.includes("right") && w.includes("arm")) {
6501
+ if (w.includes("fore") || w.includes("lower")) {
6493
6502
  if (c.has("RightForeArm")) return "RightForeArm";
6494
6503
  if (c.has("RightForearm")) return "RightForearm";
6495
- } else if (!z.includes("fore") && !z.includes("hand") && c.has("RightArm"))
6504
+ } else if (!w.includes("fore") && !w.includes("hand") && c.has("RightArm"))
6496
6505
  return "RightArm";
6497
6506
  }
6498
- if (z.includes("left") && z.includes("hand") && !z.includes("index") && !z.includes("thumb") && !z.includes("middle") && !z.includes("ring") && !z.includes("pinky") && c.has("LeftHand"))
6507
+ if (w.includes("left") && w.includes("hand") && !w.includes("index") && !w.includes("thumb") && !w.includes("middle") && !w.includes("ring") && !w.includes("pinky") && c.has("LeftHand"))
6499
6508
  return "LeftHand";
6500
- if (z.includes("right") && z.includes("hand") && !z.includes("index") && !z.includes("thumb") && !z.includes("middle") && !z.includes("ring") && !z.includes("pinky") && c.has("RightHand"))
6509
+ if (w.includes("right") && w.includes("hand") && !w.includes("index") && !w.includes("thumb") && !w.includes("middle") && !w.includes("ring") && !w.includes("pinky") && c.has("RightHand"))
6501
6510
  return "RightHand";
6502
- if (z.includes("left") && (z.includes("shoulder") || z.includes("clavicle")) && c.has("LeftShoulder"))
6511
+ if (w.includes("left") && (w.includes("shoulder") || w.includes("clavicle")) && c.has("LeftShoulder"))
6503
6512
  return "LeftShoulder";
6504
- if (z.includes("right") && (z.includes("shoulder") || z.includes("clavicle")) && c.has("RightShoulder"))
6513
+ if (w.includes("right") && (w.includes("shoulder") || w.includes("clavicle")) && c.has("RightShoulder"))
6505
6514
  return "RightShoulder";
6506
- const Y = {
6515
+ const L = {
6507
6516
  // Arm bones - exact matches
6508
6517
  LeftArm: "LeftArm",
6509
6518
  leftArm: "LeftArm",
@@ -6543,65 +6552,70 @@ class Be {
6543
6552
  Root: "Hips",
6544
6553
  root: "Hips"
6545
6554
  };
6546
- if (Y[I]) {
6547
- const S = Y[I];
6548
- if (c.has(S))
6549
- return S;
6555
+ if (L[N]) {
6556
+ const E = L[N];
6557
+ if (c.has(E))
6558
+ return E;
6550
6559
  }
6551
- for (const S of c)
6552
- if (S.toLowerCase() === z)
6553
- return S;
6554
- for (const S of c) {
6555
- const E = S.toLowerCase();
6556
- if ((z.includes("left") && E.includes("left") || z.includes("right") && E.includes("right")) && (z.includes("arm") && E.includes("arm") && !E.includes("fore") || z.includes("forearm") && E.includes("forearm") || z.includes("hand") && E.includes("hand") && !E.includes("index") && !E.includes("thumb") || z.includes("shoulder") && E.includes("shoulder")))
6557
- return S;
6560
+ for (const E of c)
6561
+ if (E.toLowerCase() === w)
6562
+ return E;
6563
+ for (const E of c) {
6564
+ const B = E.toLowerCase();
6565
+ if ((w.includes("left") && B.includes("left") || w.includes("right") && B.includes("right")) && (w.includes("arm") && B.includes("arm") && !B.includes("fore") || w.includes("forearm") && B.includes("forearm") || w.includes("hand") && B.includes("hand") && !B.includes("index") && !B.includes("thumb") || w.includes("shoulder") && B.includes("shoulder")))
6566
+ return E;
6558
6567
  }
6559
6568
  return null;
6560
- }, f = /* @__PURE__ */ new Set();
6561
- d.tracks.forEach((L) => {
6562
- const I = L.name.split(".");
6563
- f.add(I[0]);
6564
- }), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(f).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
6565
- const k = Array.from(f).filter(
6566
- (L) => L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")
6567
- ), D = Array.from(c).filter(
6568
- (L) => L.includes("Arm") || L.includes("Hand") || L.includes("Shoulder")
6569
+ }, x = /* @__PURE__ */ new Set();
6570
+ d.tracks.forEach((f) => {
6571
+ const N = f.name.split(".");
6572
+ x.add(N[0]);
6573
+ }), 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(", "));
6574
+ const S = Array.from(x).filter(
6575
+ (f) => f.toLowerCase().includes("arm") || f.toLowerCase().includes("hand") || f.toLowerCase().includes("shoulder")
6576
+ ), U = Array.from(c).filter(
6577
+ (f) => f.includes("Arm") || f.includes("Hand") || f.includes("Shoulder")
6569
6578
  );
6570
- console.log("FBX arm/hand/shoulder bones:", k.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", D.sort().join(", "));
6571
- const p = [], B = /* @__PURE__ */ new Set();
6572
- if (d.tracks.forEach((L) => {
6573
- const z = L.name.replaceAll("mixamorig", "").split("."), Y = z[0], S = z[1], E = x(Y);
6574
- if (E && S) {
6575
- const j = `${E}.${S}`, X = L.clone();
6576
- X.name = j, p.push(X), Y !== E && g.set(Y, E);
6579
+ console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", U.sort().join(", "));
6580
+ const p = [], P = /* @__PURE__ */ new Set();
6581
+ let H = 0;
6582
+ if (d.tracks.forEach((f) => {
6583
+ const w = f.name.replaceAll("mixamorig", "").split("."), L = w[0], E = w[1], B = b(L);
6584
+ if (B && (B === "LeftShoulder" || B === "RightShoulder") && (E === "quaternion" || E === "rotation")) {
6585
+ H++;
6586
+ return;
6587
+ }
6588
+ if (B && E) {
6589
+ const Y = `${B}.${E}`, ee = f.clone();
6590
+ ee.name = Y, p.push(ee), L !== B && g.set(L, B);
6577
6591
  } else
6578
- B.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`);
6579
- }), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
6592
+ P.add(L), (L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${L}" could not be mapped to avatar skeleton`);
6593
+ }), H > 0 && console.log(`✓ Filtered out ${H} shoulder rotation track(s) to prevent high shoulders`), P.size > 0 && console.warn(`⚠️ ${P.size} bone(s) could not be mapped:`, Array.from(P).sort().join(", ")), p.length > 0) {
6580
6594
  d = new y.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
6581
6595
  `✓ Mapped ${g.size} bone(s):`,
6582
- Array.from(g.entries()).map(([I, z]) => `${I}→${z}`).join(", ")
6596
+ Array.from(g.entries()).map(([N, w]) => `${N}→${w}`).join(", ")
6583
6597
  );
6584
- const L = Array.from(g.values()).filter(
6585
- (I) => I.includes("Arm") || I.includes("Hand") || I.includes("Shoulder")
6598
+ const f = Array.from(g.values()).filter(
6599
+ (N) => N.includes("Arm") || N.includes("Hand") || N.includes("Shoulder")
6586
6600
  );
6587
- L.length > 0 ? console.log(`✓ Arm bones mapped: ${L.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
6601
+ f.length > 0 ? console.log(`✓ Arm bones mapped: ${f.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
6588
6602
  } else
6589
6603
  console.error("❌ No tracks could be mapped! Animation may not work correctly.");
6590
- const T = {};
6591
- d.tracks.forEach((L) => {
6592
- L.name = L.name.replaceAll("mixamorig", "");
6593
- const I = L.name.split(".");
6594
- if (I[1] === "position") {
6595
- for (let z = 0; z < L.values.length; z++)
6596
- L.values[z] = L.values[z] * s;
6597
- T[L.name] = new y.Vector3(L.values[0], L.values[1], L.values[2]);
6598
- } else I[1] === "quaternion" ? T[L.name] = new y.Quaternion(L.values[0], L.values[1], L.values[2], L.values[3]) : I[1] === "rotation" && (T[I[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(L.values[0], L.values[1], L.values[2], "XYZ")).normalize());
6604
+ const I = {};
6605
+ d.tracks.forEach((f) => {
6606
+ f.name = f.name.replaceAll("mixamorig", "");
6607
+ const N = f.name.split(".");
6608
+ if (N[1] === "position") {
6609
+ for (let w = 0; w < f.values.length; w++)
6610
+ f.values[w] = f.values[w] * s;
6611
+ I[f.name] = new y.Vector3(f.values[0], f.values[1], f.values[2]);
6612
+ } else N[1] === "quaternion" ? I[f.name] = new y.Quaternion(f.values[0], f.values[1], f.values[2], f.values[3]) : N[1] === "rotation" && (I[N[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(f.values[0], f.values[1], f.values[2], "XYZ")).normalize());
6599
6613
  });
6600
- const R = { props: T };
6601
- T["Hips.position"] && (T["Hips.position"].y < 0.5 ? R.lying = !0 : R.standing = !0), this.animClips.push({
6614
+ const O = { props: I };
6615
+ I["Hips.position"] && (I["Hips.position"].y < 0.5 ? O.lying = !0 : O.standing = !0), this.animClips.push({
6602
6616
  url: t + "-" + i,
6603
6617
  clip: d,
6604
- pose: R
6618
+ pose: O
6605
6619
  }), this.playAnimation(t, e, n, i, s);
6606
6620
  } else {
6607
6621
  const d = "Animation " + t + " (ndx=" + i + ") not found";
@@ -6692,9 +6706,9 @@ class Be {
6692
6706
  const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
6693
6707
  if (e * 1e3 - u > 0) {
6694
6708
  const d = [];
6695
- for (let x = 1; x < l.ts.length; x++) d.push(l.ts[x] - l.ts[x - 1]);
6696
- const c = o.template?.rescale || d.map((x) => x / u), g = e * 1e3 - u;
6697
- l.ts = l.ts.map((x, f, k) => f === 0 ? h : k[f - 1] + d[f - 1] + c[f - 1] * g);
6709
+ for (let b = 1; b < l.ts.length; b++) d.push(l.ts[b] - l.ts[b - 1]);
6710
+ const c = o.template?.rescale || d.map((b) => b / u), g = e * 1e3 - u;
6711
+ l.ts = l.ts.map((b, x, S) => x === 0 ? h : S[x - 1] + d[x - 1] + c[x - 1] * g);
6698
6712
  } else {
6699
6713
  const d = e * 1e3 / u;
6700
6714
  l.ts = l.ts.map((c) => h + d * (c - h));
@@ -6729,32 +6743,32 @@ class Be {
6729
6743
  ikSolve(t, e = null, n = !1, i = null) {
6730
6744
  const s = new y.Vector3(), o = new y.Vector3(), l = new y.Vector3(), h = new y.Vector3(), r = new y.Quaternion(), u = new y.Vector3(), a = new y.Vector3(), d = new y.Vector3(), c = this.ikMesh.getObjectByName(t.root);
6731
6745
  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);
6732
- const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6733
- x.forEach((k) => {
6734
- k.bone = this.ikMesh.getObjectByName(k.link), k.bone.quaternion.copy(this.getPoseTemplateProp(k.link + ".quaternion"));
6746
+ const g = this.ikMesh.getObjectByName(t.effector), b = t.links;
6747
+ b.forEach((S) => {
6748
+ S.bone = this.ikMesh.getObjectByName(S.link), S.bone.quaternion.copy(this.getPoseTemplateProp(S.link + ".quaternion"));
6735
6749
  }), c.updateMatrixWorld(!0);
6736
- const f = t.iterations || 10;
6750
+ const x = t.iterations || 10;
6737
6751
  if (e)
6738
- for (let k = 0; k < f; k++) {
6739
- let D = !1;
6740
- for (let p = 0, B = x.length; p < B; p++) {
6741
- const T = x[p].bone;
6742
- T.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();
6743
- let R = s.dot(l);
6744
- R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (x[p].minAngle !== void 0 && R < x[p].minAngle && (R = x[p].minAngle), x[p].maxAngle !== void 0 && R > x[p].maxAngle && (R = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), $.setFromAxisAngle(a, R), T.quaternion.multiply($), T.rotation.setFromVector3(d.setFromEuler(T.rotation).clamp(new y.Vector3(
6745
- x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6746
- x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6747
- x[p].minz !== void 0 ? x[p].minz : -1 / 0
6752
+ for (let S = 0; S < x; S++) {
6753
+ let U = !1;
6754
+ for (let p = 0, P = b.length; p < P; p++) {
6755
+ const H = b[p].bone;
6756
+ 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();
6757
+ let I = s.dot(l);
6758
+ I > 1 ? I = 1 : I < -1 && (I = -1), I = Math.acos(I), !(I < 1e-5) && (b[p].minAngle !== void 0 && I < b[p].minAngle && (I = b[p].minAngle), b[p].maxAngle !== void 0 && I > b[p].maxAngle && (I = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), $.setFromAxisAngle(a, I), H.quaternion.multiply($), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new y.Vector3(
6759
+ b[p].minx !== void 0 ? b[p].minx : -1 / 0,
6760
+ b[p].miny !== void 0 ? b[p].miny : -1 / 0,
6761
+ b[p].minz !== void 0 ? b[p].minz : -1 / 0
6748
6762
  ), new y.Vector3(
6749
- x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6750
- x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6751
- x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6752
- ))), T.updateMatrixWorld(!0), D = !0);
6763
+ b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
6764
+ b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
6765
+ b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
6766
+ ))), H.updateMatrixWorld(!0), U = !0);
6753
6767
  }
6754
- if (!D) break;
6768
+ if (!U) break;
6755
6769
  }
6756
- i && x.forEach((k) => {
6757
- this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = i;
6770
+ i && b.forEach((S) => {
6771
+ 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;
6758
6772
  });
6759
6773
  }
6760
6774
  /**
@@ -6814,16 +6828,16 @@ function Ee() {
6814
6828
  };
6815
6829
  }
6816
6830
  function wt() {
6817
- const V = Ee(), t = [];
6818
- return Object.entries(V.voices).forEach(([e, n]) => {
6831
+ const Z = Ee(), t = [];
6832
+ return Object.entries(Z.voices).forEach(([e, n]) => {
6819
6833
  t.push({
6820
6834
  value: n,
6821
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${V.service})`
6835
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${Z.service})`
6822
6836
  });
6823
6837
  }), t;
6824
6838
  }
6825
6839
  const Ve = Me(({
6826
- avatarUrl: V = "/avatars/brunette.glb",
6840
+ avatarUrl: Z = "/avatars/brunette.glb",
6827
6841
  avatarBody: t = "F",
6828
6842
  mood: e = "neutral",
6829
6843
  ttsLang: n = "en",
@@ -6841,16 +6855,16 @@ const Ve = Me(({
6841
6855
  onError: c = () => {
6842
6856
  },
6843
6857
  className: g = "",
6844
- style: x = {},
6845
- animations: f = {}
6846
- }, k) => {
6847
- const D = W(null), p = W(null), B = W(r), T = W(null), R = W(null), L = W(!1), I = W({ remainingText: null, originalText: null, options: null }), z = W([]), Y = W(0), [S, E] = pe(!0), [j, X] = pe(null), [oe, le] = pe(!1), [ge, de] = pe(!1);
6858
+ style: b = {},
6859
+ animations: x = {}
6860
+ }, S) => {
6861
+ const U = G(null), p = G(null), P = G(r), H = G(null), I = G(null), O = G(!1), f = G({ remainingText: null, originalText: null, options: null }), N = G([]), w = G(0), [L, E] = pe(!0), [B, Y] = pe(null), [ee, le] = pe(!1), [ge, de] = pe(!1);
6848
6862
  ce(() => {
6849
- L.current = ge;
6863
+ O.current = ge;
6850
6864
  }, [ge]), ce(() => {
6851
- B.current = r;
6865
+ P.current = r;
6852
6866
  }, [r]);
6853
- const ee = Ee(), be = i || ee.service;
6867
+ const te = Ee(), be = i || te.service;
6854
6868
  let Q;
6855
6869
  be === "browser" ? Q = {
6856
6870
  service: "browser",
@@ -6860,22 +6874,22 @@ const Ve = Me(({
6860
6874
  } : be === "elevenlabs" ? Q = {
6861
6875
  service: "elevenlabs",
6862
6876
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6863
- apiKey: o || ee.apiKey,
6864
- defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6865
- voices: ee.voices || Ie.voices
6877
+ apiKey: o || te.apiKey,
6878
+ defaultVoice: s || te.defaultVoice || Ie.defaultVoice,
6879
+ voices: te.voices || Ie.voices
6866
6880
  } : be === "deepgram" ? Q = {
6867
6881
  service: "deepgram",
6868
6882
  endpoint: "https://api.deepgram.com/v1/speak",
6869
- apiKey: o || ee.apiKey,
6870
- defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6871
- voices: ee.voices || Te.voices
6883
+ apiKey: o || te.apiKey,
6884
+ defaultVoice: s || te.defaultVoice || Te.defaultVoice,
6885
+ voices: te.voices || Te.voices
6872
6886
  } : Q = {
6873
- ...ee,
6887
+ ...te,
6874
6888
  // Override API key if provided via props
6875
- apiKey: o !== null ? o : ee.apiKey
6889
+ apiKey: o !== null ? o : te.apiKey
6876
6890
  };
6877
- const b = {
6878
- url: V,
6891
+ const v = {
6892
+ url: Z,
6879
6893
  body: t,
6880
6894
  avatarMood: e,
6881
6895
  ttsLang: be === "browser" ? "en-US" : n,
@@ -6884,25 +6898,25 @@ const Ve = Me(({
6884
6898
  showFullAvatar: r,
6885
6899
  bodyMovement: l,
6886
6900
  movementIntensity: h
6887
- }, v = {
6901
+ }, R = {
6888
6902
  ttsEndpoint: Q.endpoint,
6889
6903
  ttsApikey: Q.apiKey,
6890
6904
  ttsService: be,
6891
6905
  lipsyncModules: ["en"],
6892
6906
  cameraView: u
6893
- }, F = O(async () => {
6894
- if (!(!D.current || p.current))
6907
+ }, M = D(async () => {
6908
+ if (!(!U.current || p.current))
6895
6909
  try {
6896
- if (E(!0), X(null), p.current = new Be(D.current, v), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(b, (K) => {
6910
+ if (E(!0), Y(null), p.current = new Be(U.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, (K) => {
6897
6911
  if (K.lengthComputable) {
6898
- const ne = Math.min(100, Math.round(K.loaded / K.total * 100));
6899
- d(ne);
6912
+ const ie = Math.min(100, Math.round(K.loaded / K.total * 100));
6913
+ d(ie);
6900
6914
  }
6901
6915
  }), await new Promise((K) => {
6902
- const ne = () => {
6903
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? K() : setTimeout(ne, 100);
6916
+ const ie = () => {
6917
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? K() : setTimeout(ie, 100);
6904
6918
  };
6905
- ne();
6919
+ ie();
6906
6920
  }), p.current && p.current.setShowFullAvatar)
6907
6921
  try {
6908
6922
  p.current.setShowFullAvatar(r);
@@ -6910,62 +6924,62 @@ const Ve = Me(({
6910
6924
  console.warn("Error setting full body mode on initialization:", K);
6911
6925
  }
6912
6926
  p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), E(!1), le(!0), a(p.current);
6913
- const U = () => {
6927
+ const V = () => {
6914
6928
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6915
6929
  };
6916
- return document.addEventListener("visibilitychange", U), () => {
6917
- document.removeEventListener("visibilitychange", U);
6930
+ return document.addEventListener("visibilitychange", V), () => {
6931
+ document.removeEventListener("visibilitychange", V);
6918
6932
  };
6919
- } catch (w) {
6920
- console.error("Error initializing TalkingHead:", w), X(w.message || "Failed to initialize avatar"), E(!1), c(w);
6933
+ } catch (k) {
6934
+ console.error("Error initializing TalkingHead:", k), Y(k.message || "Failed to initialize avatar"), E(!1), c(k);
6921
6935
  }
6922
- }, [V, t, e, n, i, s, o, r, l, h, u]);
6923
- ce(() => (F(), () => {
6936
+ }, [Z, t, e, n, i, s, o, r, l, h, u]);
6937
+ ce(() => (M(), () => {
6924
6938
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6925
- }), [F]), ce(() => {
6926
- if (!D.current || !p.current) return;
6927
- const w = new ResizeObserver((K) => {
6928
- for (const ne of K)
6939
+ }), [M]), ce(() => {
6940
+ if (!U.current || !p.current) return;
6941
+ const k = new ResizeObserver((K) => {
6942
+ for (const ie of K)
6929
6943
  p.current && p.current.onResize && p.current.onResize();
6930
6944
  });
6931
- w.observe(D.current);
6932
- const U = () => {
6945
+ k.observe(U.current);
6946
+ const V = () => {
6933
6947
  p.current && p.current.onResize && p.current.onResize();
6934
6948
  };
6935
- return window.addEventListener("resize", U), () => {
6936
- w.disconnect(), window.removeEventListener("resize", U);
6949
+ return window.addEventListener("resize", V), () => {
6950
+ k.disconnect(), window.removeEventListener("resize", V);
6937
6951
  };
6938
- }, [oe]);
6939
- const P = O(async () => {
6952
+ }, [ee]);
6953
+ const F = D(async () => {
6940
6954
  if (p.current && p.current.audioCtx)
6941
6955
  try {
6942
6956
  (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
6943
- } catch (w) {
6944
- console.warn("Failed to resume audio context:", w);
6957
+ } catch (k) {
6958
+ console.warn("Failed to resume audio context:", k);
6945
6959
  }
6946
- }, []), N = O(async (w, U = {}) => {
6947
- if (p.current && oe)
6960
+ }, []), W = D(async (k, V = {}) => {
6961
+ if (p.current && ee)
6948
6962
  try {
6949
- R.current && (clearInterval(R.current), R.current = null), T.current = { text: w, options: U }, I.current = { remainingText: null, originalText: null, options: null };
6950
- const K = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = w.split(K).map((A) => A.trim()).filter((A) => A.length > 0);
6951
- z.current = ne, Y.current = 0, de(!1), L.current = !1, await P();
6963
+ I.current && (clearInterval(I.current), I.current = null), H.current = { text: k, options: V }, f.current = { remainingText: null, originalText: null, options: null };
6964
+ const K = /[!\.\?\n\p{Extended_Pictographic}]/ug, ie = k.split(K).map((A) => A.trim()).filter((A) => A.length > 0);
6965
+ N.current = ie, w.current = 0, de(!1), O.current = !1, await F();
6952
6966
  const me = {
6953
- ...U,
6954
- lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
6967
+ ...V,
6968
+ lipsyncLang: V.lipsyncLang || v.lipsyncLang || "en"
6955
6969
  };
6956
- if (U.onSpeechEnd && p.current) {
6970
+ if (V.onSpeechEnd && p.current) {
6957
6971
  const A = p.current;
6958
- let H = null, G = 0;
6972
+ let C = null, X = 0;
6959
6973
  const J = 1200;
6960
- let ie = !1;
6961
- H = setInterval(() => {
6962
- if (G++, L.current)
6974
+ let oe = !1;
6975
+ C = setInterval(() => {
6976
+ if (X++, O.current)
6963
6977
  return;
6964
- if (G > J) {
6965
- if (H && (clearInterval(H), H = null, R.current = null), !ie && !L.current) {
6966
- ie = !0;
6978
+ if (X > J) {
6979
+ if (C && (clearInterval(C), C = null, I.current = null), !oe && !O.current) {
6980
+ oe = !0;
6967
6981
  try {
6968
- U.onSpeechEnd();
6982
+ V.onSpeechEnd();
6969
6983
  } catch (Oe) {
6970
6984
  console.error("Error in onSpeechEnd callback (timeout):", Oe);
6971
6985
  }
@@ -6973,85 +6987,85 @@ const Ve = Me(({
6973
6987
  return;
6974
6988
  }
6975
6989
  const se = !A.speechQueue || A.speechQueue.length === 0, we = !A.audioPlaylist || A.audioPlaylist.length === 0;
6976
- A && A.isSpeaking === !1 && se && we && A.isAudioPlaying === !1 && !ie && !L.current && setTimeout(() => {
6977
- if (A && !L.current && A.isSpeaking === !1 && (!A.speechQueue || A.speechQueue.length === 0) && (!A.audioPlaylist || A.audioPlaylist.length === 0) && A.isAudioPlaying === !1 && !ie && !L.current) {
6978
- ie = !0, H && (clearInterval(H), H = null, R.current = null);
6990
+ A && A.isSpeaking === !1 && se && we && A.isAudioPlaying === !1 && !oe && !O.current && setTimeout(() => {
6991
+ if (A && !O.current && A.isSpeaking === !1 && (!A.speechQueue || A.speechQueue.length === 0) && (!A.audioPlaylist || A.audioPlaylist.length === 0) && A.isAudioPlaying === !1 && !oe && !O.current) {
6992
+ oe = !0, C && (clearInterval(C), C = null, I.current = null);
6979
6993
  try {
6980
- U.onSpeechEnd();
6994
+ V.onSpeechEnd();
6981
6995
  } catch (Ze) {
6982
6996
  console.error("Error in onSpeechEnd callback:", Ze);
6983
6997
  }
6984
6998
  }
6985
6999
  }, 100);
6986
- }, 100), R.current = H;
7000
+ }, 100), I.current = C;
6987
7001
  }
6988
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me)) : setTimeout(async () => {
6989
- await P(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me));
7002
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(k, me)) : setTimeout(async () => {
7003
+ await F(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(k, me));
6990
7004
  }, 100);
6991
7005
  } catch (K) {
6992
- console.error("Error speaking text:", K), X(K.message || "Failed to speak text");
7006
+ console.error("Error speaking text:", K), Y(K.message || "Failed to speak text");
6993
7007
  }
6994
- }, [oe, P, b.lipsyncLang]), te = O(() => {
6995
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), T.current = null, de(!1));
6996
- }, []), q = O(() => {
7008
+ }, [ee, F, v.lipsyncLang]), ne = D(() => {
7009
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), H.current = null, de(!1));
7010
+ }, []), q = D(() => {
6997
7011
  if (p.current && p.current.pauseSpeaking) {
6998
- const w = p.current;
6999
- if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
7000
- R.current && (clearInterval(R.current), R.current = null);
7012
+ const k = p.current;
7013
+ if (k.isSpeaking || k.audioPlaylist && k.audioPlaylist.length > 0 || k.speechQueue && k.speechQueue.length > 0) {
7014
+ I.current && (clearInterval(I.current), I.current = null);
7001
7015
  let K = "";
7002
- if (T.current && z.current.length > 0) {
7003
- const ne = z.current.length, me = w.speechQueue ? w.speechQueue.filter((J) => J && J.text && Array.isArray(J.text) && J.text.length > 0).length : 0, A = w.audioPlaylist && w.audioPlaylist.length > 0, H = me + (A ? 1 : 0), G = ne - H;
7004
- if (H > 0 && G < ne && (K = z.current.slice(G).join(". ").trim(), !K && me > 0 && w.speechQueue)) {
7005
- const ie = w.speechQueue.filter((se) => se && se.text && Array.isArray(se.text) && se.text.length > 0).map((se) => se.text.map((we) => we.word || "").filter((we) => we.length > 0).join(" ")).filter((se) => se.length > 0).join(" ");
7006
- ie && ie.trim() && (K = ie.trim());
7016
+ if (H.current && N.current.length > 0) {
7017
+ const ie = N.current.length, me = k.speechQueue ? k.speechQueue.filter((J) => J && J.text && Array.isArray(J.text) && J.text.length > 0).length : 0, A = k.audioPlaylist && k.audioPlaylist.length > 0, C = me + (A ? 1 : 0), X = ie - C;
7018
+ if (C > 0 && X < ie && (K = N.current.slice(X).join(". ").trim(), !K && me > 0 && k.speechQueue)) {
7019
+ const oe = k.speechQueue.filter((se) => se && se.text && Array.isArray(se.text) && se.text.length > 0).map((se) => se.text.map((we) => we.word || "").filter((we) => we.length > 0).join(" ")).filter((se) => se.length > 0).join(" ");
7020
+ oe && oe.trim() && (K = oe.trim());
7007
7021
  }
7008
7022
  }
7009
- T.current && (I.current = {
7023
+ H.current && (f.current = {
7010
7024
  remainingText: K || null,
7011
- originalText: T.current.text,
7012
- options: T.current.options
7013
- }), w.speechQueue && (w.speechQueue.length = 0), p.current.pauseSpeaking(), L.current = !0, de(!0);
7025
+ originalText: H.current.text,
7026
+ options: H.current.options
7027
+ }), k.speechQueue && (k.speechQueue.length = 0), p.current.pauseSpeaking(), O.current = !0, de(!0);
7014
7028
  }
7015
7029
  }
7016
- }, []), _ = O(async () => {
7030
+ }, []), _ = D(async () => {
7017
7031
  if (!p.current || !ge)
7018
7032
  return;
7019
- let w = "", U = {};
7020
- if (I.current && I.current.remainingText)
7021
- w = I.current.remainingText, U = I.current.options || {}, I.current = { remainingText: null, originalText: null, options: null };
7022
- else if (T.current && T.current.text)
7023
- w = T.current.text, U = T.current.options || {};
7033
+ let k = "", V = {};
7034
+ if (f.current && f.current.remainingText)
7035
+ k = f.current.remainingText, V = f.current.options || {}, f.current = { remainingText: null, originalText: null, options: null };
7036
+ else if (H.current && H.current.text)
7037
+ k = H.current.text, V = H.current.options || {};
7024
7038
  else {
7025
- console.warn("Resume called but no paused speech found"), de(!1), L.current = !1;
7039
+ console.warn("Resume called but no paused speech found"), de(!1), O.current = !1;
7026
7040
  return;
7027
7041
  }
7028
- de(!1), L.current = !1, await P();
7042
+ de(!1), O.current = !1, await F();
7029
7043
  const K = {
7030
- ...U,
7031
- lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
7044
+ ...V,
7045
+ lipsyncLang: V.lipsyncLang || v.lipsyncLang || "en"
7032
7046
  };
7033
7047
  try {
7034
- await N(w, K);
7035
- } catch (ne) {
7036
- console.error("Error resuming speech:", ne), de(!1), L.current = !1;
7048
+ await W(k, K);
7049
+ } catch (ie) {
7050
+ console.error("Error resuming speech:", ie), de(!1), O.current = !1;
7037
7051
  }
7038
- }, [P, ge, N, b]), Ae = O((w) => {
7039
- p.current && p.current.setMood(w);
7040
- }, []), Se = O((w) => {
7041
- p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(w);
7042
- }, []), Le = O((w, U = !1) => {
7052
+ }, [F, ge, W, v]), Ae = D((k) => {
7053
+ p.current && p.current.setMood(k);
7054
+ }, []), Se = D((k) => {
7055
+ p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(k);
7056
+ }, []), Le = D((k, V = !1) => {
7043
7057
  if (p.current && p.current.playAnimation) {
7044
- if (f && f[w] && (w = f[w]), p.current.setShowFullAvatar)
7058
+ if (x && x[k] && (k = x[k]), p.current.setShowFullAvatar)
7045
7059
  try {
7046
- p.current.setShowFullAvatar(B.current);
7047
- } catch (ne) {
7048
- console.warn("Error setting full body mode:", ne);
7060
+ p.current.setShowFullAvatar(P.current);
7061
+ } catch (ie) {
7062
+ console.warn("Error setting full body mode:", ie);
7049
7063
  }
7050
- if (w.includes("."))
7064
+ if (k.includes("."))
7051
7065
  try {
7052
- p.current.playAnimation(w, null, 10, 0, 0.01, U);
7053
- } catch (ne) {
7054
- console.warn(`Failed to play ${w}:`, ne);
7066
+ p.current.playAnimation(k, null, 10, 0, 0.01, V);
7067
+ } catch (ie) {
7068
+ console.warn(`Failed to play ${k}:`, ie);
7055
7069
  try {
7056
7070
  p.current.setBodyMovement("idle");
7057
7071
  } catch (me) {
@@ -7059,16 +7073,16 @@ const Ve = Me(({
7059
7073
  }
7060
7074
  }
7061
7075
  else {
7062
- const ne = [".fbx", ".glb", ".gltf"];
7076
+ const ie = [".fbx", ".glb", ".gltf"];
7063
7077
  let me = !1;
7064
- for (const A of ne)
7078
+ for (const A of ie)
7065
7079
  try {
7066
- p.current.playAnimation(w + A, null, 10, 0, 0.01, U), me = !0;
7080
+ p.current.playAnimation(k + A, null, 10, 0, 0.01, V), me = !0;
7067
7081
  break;
7068
7082
  } catch {
7069
7083
  }
7070
7084
  if (!me) {
7071
- console.warn("Animation not found:", w);
7085
+ console.warn("Animation not found:", k);
7072
7086
  try {
7073
7087
  p.current.setBodyMovement("idle");
7074
7088
  } catch (A) {
@@ -7077,77 +7091,77 @@ const Ve = Me(({
7077
7091
  }
7078
7092
  }
7079
7093
  }
7080
- }, [f]), ke = O(() => {
7094
+ }, [x]), ke = D(() => {
7081
7095
  p.current && p.current.onResize && p.current.onResize();
7082
7096
  }, []);
7083
- return Fe(k, () => ({
7084
- speakText: N,
7085
- stopSpeaking: te,
7097
+ return Fe(S, () => ({
7098
+ speakText: W,
7099
+ stopSpeaking: ne,
7086
7100
  pauseSpeaking: q,
7087
7101
  resumeSpeaking: _,
7088
- resumeAudioContext: P,
7102
+ resumeAudioContext: F,
7089
7103
  setMood: Ae,
7090
7104
  setTimingAdjustment: Se,
7091
7105
  playAnimation: Le,
7092
- isReady: oe,
7106
+ isReady: ee,
7093
7107
  isPaused: ge,
7094
7108
  talkingHead: p.current,
7095
7109
  handleResize: ke,
7096
- setBodyMovement: (w) => {
7110
+ setBodyMovement: (k) => {
7097
7111
  if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7098
7112
  try {
7099
- p.current.setShowFullAvatar(B.current), p.current.setBodyMovement(w);
7100
- } catch (U) {
7101
- console.warn("Error setting body movement:", U);
7113
+ p.current.setShowFullAvatar(P.current), p.current.setBodyMovement(k);
7114
+ } catch (V) {
7115
+ console.warn("Error setting body movement:", V);
7102
7116
  }
7103
7117
  },
7104
- setMovementIntensity: (w) => p.current?.setMovementIntensity(w),
7118
+ setMovementIntensity: (k) => p.current?.setMovementIntensity(k),
7105
7119
  playRandomDance: () => {
7106
7120
  if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7107
7121
  try {
7108
- p.current.setShowFullAvatar(B.current), p.current.playRandomDance();
7109
- } catch (w) {
7110
- console.warn("Error playing random dance:", w);
7122
+ p.current.setShowFullAvatar(P.current), p.current.playRandomDance();
7123
+ } catch (k) {
7124
+ console.warn("Error playing random dance:", k);
7111
7125
  }
7112
7126
  },
7113
- playReaction: (w) => {
7127
+ playReaction: (k) => {
7114
7128
  if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7115
7129
  try {
7116
- p.current.setShowFullAvatar(B.current), p.current.playReaction(w);
7117
- } catch (U) {
7118
- console.warn("Error playing reaction:", U);
7130
+ p.current.setShowFullAvatar(P.current), p.current.playReaction(k);
7131
+ } catch (V) {
7132
+ console.warn("Error playing reaction:", V);
7119
7133
  }
7120
7134
  },
7121
7135
  playCelebration: () => {
7122
7136
  if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7123
7137
  try {
7124
- p.current.setShowFullAvatar(B.current), p.current.playCelebration();
7125
- } catch (w) {
7126
- console.warn("Error playing celebration:", w);
7138
+ p.current.setShowFullAvatar(P.current), p.current.playCelebration();
7139
+ } catch (k) {
7140
+ console.warn("Error playing celebration:", k);
7127
7141
  }
7128
7142
  },
7129
- setShowFullAvatar: (w) => {
7143
+ setShowFullAvatar: (k) => {
7130
7144
  if (p.current && p.current.setShowFullAvatar)
7131
7145
  try {
7132
- B.current = w, p.current.setShowFullAvatar(w);
7133
- } catch (U) {
7134
- console.warn("Error setting showFullAvatar:", U);
7146
+ P.current = k, p.current.setShowFullAvatar(k);
7147
+ } catch (V) {
7148
+ console.warn("Error setting showFullAvatar:", V);
7135
7149
  }
7136
7150
  },
7137
7151
  lockAvatarPosition: () => {
7138
7152
  if (p.current && p.current.lockAvatarPosition)
7139
7153
  try {
7140
7154
  p.current.lockAvatarPosition();
7141
- } catch (w) {
7142
- console.warn("Error locking avatar position:", w);
7155
+ } catch (k) {
7156
+ console.warn("Error locking avatar position:", k);
7143
7157
  }
7144
7158
  },
7145
7159
  unlockAvatarPosition: () => {
7146
7160
  if (p.current && p.current.unlockAvatarPosition)
7147
7161
  try {
7148
7162
  p.current.unlockAvatarPosition();
7149
- } catch (w) {
7150
- console.warn("Error unlocking avatar position:", w);
7163
+ } catch (k) {
7164
+ console.warn("Error unlocking avatar position:", k);
7151
7165
  }
7152
7166
  }
7153
7167
  })), /* @__PURE__ */ Pe(
@@ -7158,13 +7172,13 @@ const Ve = Me(({
7158
7172
  width: "100%",
7159
7173
  height: "100%",
7160
7174
  position: "relative",
7161
- ...x
7175
+ ...b
7162
7176
  },
7163
7177
  children: [
7164
7178
  /* @__PURE__ */ ye(
7165
7179
  "div",
7166
7180
  {
7167
- ref: D,
7181
+ ref: U,
7168
7182
  className: "talking-head-viewer",
7169
7183
  style: {
7170
7184
  width: "100%",
@@ -7173,7 +7187,7 @@ const Ve = Me(({
7173
7187
  }
7174
7188
  }
7175
7189
  ),
7176
- S && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7190
+ L && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7177
7191
  position: "absolute",
7178
7192
  top: "50%",
7179
7193
  left: "50%",
@@ -7182,7 +7196,7 @@ const Ve = Me(({
7182
7196
  fontSize: "18px",
7183
7197
  zIndex: 10
7184
7198
  }, children: "Loading avatar..." }),
7185
- j && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7199
+ B && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7186
7200
  position: "absolute",
7187
7201
  top: "50%",
7188
7202
  left: "50%",
@@ -7193,14 +7207,14 @@ const Ve = Me(({
7193
7207
  zIndex: 10,
7194
7208
  padding: "20px",
7195
7209
  borderRadius: "8px"
7196
- }, children: j })
7210
+ }, children: B })
7197
7211
  ]
7198
7212
  }
7199
7213
  );
7200
7214
  });
7201
7215
  Ve.displayName = "TalkingHeadAvatar";
7202
7216
  const pt = Me(({
7203
- text: V = "Hello! I'm a talking avatar. How are you today?",
7217
+ text: Z = "Hello! I'm a talking avatar. How are you today?",
7204
7218
  onLoading: t = () => {
7205
7219
  },
7206
7220
  onError: e = () => {
@@ -7211,23 +7225,23 @@ const pt = Me(({
7211
7225
  style: s = {},
7212
7226
  avatarConfig: o = {}
7213
7227
  }, l) => {
7214
- const h = W(null), r = W(null), [u, a] = pe(!0), [d, c] = pe(null), [g, x] = pe(!1), f = Ee(), k = o.ttsService || f.service, D = k === "browser" ? {
7228
+ const h = G(null), r = G(null), [u, a] = pe(!0), [d, c] = pe(null), [g, b] = pe(!1), x = Ee(), S = o.ttsService || x.service, U = S === "browser" ? {
7215
7229
  endpoint: "",
7216
7230
  apiKey: null,
7217
7231
  defaultVoice: "Google US English"
7218
7232
  } : {
7219
- ...f,
7233
+ ...x,
7220
7234
  // Override API key if provided via avatarConfig
7221
- apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
7235
+ apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : x.apiKey,
7222
7236
  // Override endpoint for ElevenLabs if service is explicitly set
7223
- endpoint: k === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
7237
+ endpoint: S === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
7224
7238
  }, p = {
7225
7239
  url: "/avatars/brunette.glb",
7226
7240
  // Use brunette avatar (working glTF file)
7227
7241
  body: "F",
7228
7242
  avatarMood: "neutral",
7229
- ttsLang: k === "browser" ? "en-US" : "en",
7230
- ttsVoice: o.ttsVoice || D.defaultVoice,
7243
+ ttsLang: S === "browser" ? "en-US" : "en",
7244
+ ttsVoice: o.ttsVoice || U.defaultVoice,
7231
7245
  lipsyncLang: "en",
7232
7246
  // English lip-sync
7233
7247
  showFullAvatar: !0,
@@ -7235,99 +7249,99 @@ const pt = Me(({
7235
7249
  bodyMovement: "idle",
7236
7250
  movementIntensity: 0.5,
7237
7251
  ...o
7238
- }, B = {
7239
- ttsEndpoint: D.endpoint,
7240
- ttsApikey: D.apiKey,
7241
- ttsService: k,
7252
+ }, P = {
7253
+ ttsEndpoint: U.endpoint,
7254
+ ttsApikey: U.apiKey,
7255
+ ttsService: S,
7242
7256
  lipsyncModules: ["en"],
7243
7257
  cameraView: "upper"
7244
- }, T = O(async () => {
7258
+ }, H = D(async () => {
7245
7259
  if (!(!h.current || r.current))
7246
7260
  try {
7247
- if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (j) => {
7248
- if (j.lengthComputable) {
7249
- const X = Math.min(100, Math.round(j.loaded / j.total * 100));
7250
- t(X);
7261
+ if (a(!0), c(null), r.current = new Be(h.current, P), await r.current.showAvatar(p, (B) => {
7262
+ if (B.lengthComputable) {
7263
+ const Y = Math.min(100, Math.round(B.loaded / B.total * 100));
7264
+ t(Y);
7251
7265
  }
7252
7266
  }), r.current.morphs && r.current.morphs.length > 0) {
7253
- const j = r.current.morphs[0].morphTargetDictionary;
7254
- console.log("Available morph targets:", Object.keys(j));
7255
- const X = Object.keys(j).filter((oe) => oe.startsWith("viseme_"));
7256
- 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"));
7267
+ const B = r.current.morphs[0].morphTargetDictionary;
7268
+ console.log("Available morph targets:", Object.keys(B));
7269
+ const Y = Object.keys(B).filter((ee) => ee.startsWith("viseme_"));
7270
+ console.log("Viseme morph targets found:", Y), Y.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"));
7257
7271
  }
7258
- if (await new Promise((j) => {
7259
- const X = () => {
7260
- r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), j()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
7272
+ if (await new Promise((B) => {
7273
+ const Y = () => {
7274
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), B()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Y, 100));
7261
7275
  };
7262
- X();
7276
+ Y();
7263
7277
  }), r.current && r.current.setShowFullAvatar)
7264
7278
  try {
7265
7279
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7266
- } catch (j) {
7267
- console.warn("Error setting full body mode on initialization:", j);
7280
+ } catch (B) {
7281
+ console.warn("Error setting full body mode on initialization:", B);
7268
7282
  }
7269
- a(!1), x(!0), n(r.current);
7283
+ a(!1), b(!0), n(r.current);
7270
7284
  const E = () => {
7271
7285
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7272
7286
  };
7273
7287
  return document.addEventListener("visibilitychange", E), () => {
7274
7288
  document.removeEventListener("visibilitychange", E);
7275
7289
  };
7276
- } catch (S) {
7277
- console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), a(!1), e(S);
7290
+ } catch (L) {
7291
+ console.error("Error initializing TalkingHead:", L), c(L.message || "Failed to initialize avatar"), a(!1), e(L);
7278
7292
  }
7279
7293
  }, []);
7280
- ce(() => (T(), () => {
7294
+ ce(() => (H(), () => {
7281
7295
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7282
- }), [T]);
7283
- const R = O((S) => {
7296
+ }), [H]);
7297
+ const I = D((L) => {
7284
7298
  if (r.current && g)
7285
7299
  try {
7286
- console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7287
- r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7300
+ console.log("Speaking text:", L), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(L)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7301
+ r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(L)) : console.error("Lip-sync still not ready after waiting");
7288
7302
  }, 500));
7289
7303
  } catch (E) {
7290
7304
  console.error("Error speaking text:", E), c(E.message || "Failed to speak text");
7291
7305
  }
7292
7306
  else
7293
7307
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7294
- }, [g, p]), L = O(() => {
7308
+ }, [g, p]), O = D(() => {
7295
7309
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7296
- }, []), I = O((S) => {
7297
- r.current && r.current.setMood(S);
7298
- }, []), z = O((S) => {
7299
- r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7300
- }, []), Y = O((S, E = !1) => {
7310
+ }, []), f = D((L) => {
7311
+ r.current && r.current.setMood(L);
7312
+ }, []), N = D((L) => {
7313
+ r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(L), console.log("Timing adjustment set to:", L));
7314
+ }, []), w = D((L, E = !1) => {
7301
7315
  if (r.current && r.current.playAnimation) {
7302
7316
  if (r.current.setShowFullAvatar)
7303
7317
  try {
7304
7318
  r.current.setShowFullAvatar(!0);
7305
- } catch (X) {
7306
- console.warn("Error setting full body mode:", X);
7319
+ } catch (Y) {
7320
+ console.warn("Error setting full body mode:", Y);
7307
7321
  }
7308
- if (S.includes("."))
7322
+ if (L.includes("."))
7309
7323
  try {
7310
- r.current.playAnimation(S, null, 10, 0, 0.01, E), console.log("Playing animation:", S);
7311
- } catch (X) {
7312
- console.log(`Failed to play ${S}:`, X);
7324
+ r.current.playAnimation(L, null, 10, 0, 0.01, E), console.log("Playing animation:", L);
7325
+ } catch (Y) {
7326
+ console.log(`Failed to play ${L}:`, Y);
7313
7327
  try {
7314
7328
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7315
- } catch (oe) {
7316
- console.warn("Fallback animation also failed:", oe);
7329
+ } catch (ee) {
7330
+ console.warn("Fallback animation also failed:", ee);
7317
7331
  }
7318
7332
  }
7319
7333
  else {
7320
- const X = [".fbx", ".glb", ".gltf"];
7321
- let oe = !1;
7322
- for (const le of X)
7334
+ const Y = [".fbx", ".glb", ".gltf"];
7335
+ let ee = !1;
7336
+ for (const le of Y)
7323
7337
  try {
7324
- r.current.playAnimation(S + le, null, 10, 0, 0.01, E), console.log("Playing animation:", S + le), oe = !0;
7338
+ r.current.playAnimation(L + le, null, 10, 0, 0.01, E), console.log("Playing animation:", L + le), ee = !0;
7325
7339
  break;
7326
7340
  } catch {
7327
- console.log(`Failed to play ${S}${le}, trying next format...`);
7341
+ console.log(`Failed to play ${L}${le}, trying next format...`);
7328
7342
  }
7329
- if (!oe) {
7330
- console.warn("Animation system not available or animation not found:", S);
7343
+ if (!ee) {
7344
+ console.warn("Animation system not available or animation not found:", L);
7331
7345
  try {
7332
7346
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7333
7347
  } catch (le) {
@@ -7336,37 +7350,37 @@ const pt = Me(({
7336
7350
  }
7337
7351
  }
7338
7352
  } else
7339
- console.warn("Animation system not available or animation not found:", S);
7353
+ console.warn("Animation system not available or animation not found:", L);
7340
7354
  }, []);
7341
7355
  return Fe(l, () => ({
7342
- speakText: R,
7343
- stopSpeaking: L,
7344
- setMood: I,
7345
- setTimingAdjustment: z,
7346
- playAnimation: Y,
7356
+ speakText: I,
7357
+ stopSpeaking: O,
7358
+ setMood: f,
7359
+ setTimingAdjustment: N,
7360
+ playAnimation: w,
7347
7361
  isReady: g,
7348
7362
  talkingHead: r.current,
7349
- setBodyMovement: (S) => {
7363
+ setBodyMovement: (L) => {
7350
7364
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7351
7365
  try {
7352
- r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7366
+ r.current.setShowFullAvatar(!0), r.current.setBodyMovement(L), console.log("Body movement set with full body mode:", L);
7353
7367
  } catch (E) {
7354
7368
  console.warn("Error setting body movement:", E);
7355
7369
  }
7356
7370
  },
7357
- setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
7371
+ setMovementIntensity: (L) => r.current?.setMovementIntensity(L),
7358
7372
  playRandomDance: () => {
7359
7373
  if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
7360
7374
  try {
7361
7375
  r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
7362
- } catch (S) {
7363
- console.warn("Error playing random dance:", S);
7376
+ } catch (L) {
7377
+ console.warn("Error playing random dance:", L);
7364
7378
  }
7365
7379
  },
7366
- playReaction: (S) => {
7380
+ playReaction: (L) => {
7367
7381
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7368
7382
  try {
7369
- r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7383
+ r.current.setShowFullAvatar(!0), r.current.playReaction(L), console.log("Reaction played with full body mode:", L);
7370
7384
  } catch (E) {
7371
7385
  console.warn("Error playing reaction:", E);
7372
7386
  }
@@ -7375,14 +7389,14 @@ const pt = Me(({
7375
7389
  if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
7376
7390
  try {
7377
7391
  r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
7378
- } catch (S) {
7379
- console.warn("Error playing celebration:", S);
7392
+ } catch (L) {
7393
+ console.warn("Error playing celebration:", L);
7380
7394
  }
7381
7395
  },
7382
- setShowFullAvatar: (S) => {
7396
+ setShowFullAvatar: (L) => {
7383
7397
  if (r.current && r.current.setShowFullAvatar)
7384
7398
  try {
7385
- r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7399
+ r.current.setShowFullAvatar(L), console.log("Show full avatar set to:", L);
7386
7400
  } catch (E) {
7387
7401
  console.warn("Error setting showFullAvatar:", E);
7388
7402
  }
@@ -7391,16 +7405,16 @@ const pt = Me(({
7391
7405
  if (r.current && r.current.lockAvatarPosition)
7392
7406
  try {
7393
7407
  r.current.lockAvatarPosition();
7394
- } catch (S) {
7395
- console.warn("Error locking avatar position:", S);
7408
+ } catch (L) {
7409
+ console.warn("Error locking avatar position:", L);
7396
7410
  }
7397
7411
  },
7398
7412
  unlockAvatarPosition: () => {
7399
7413
  if (r.current && r.current.unlockAvatarPosition)
7400
7414
  try {
7401
7415
  r.current.unlockAvatarPosition();
7402
- } catch (S) {
7403
- console.warn("Error unlocking avatar position:", S);
7416
+ } catch (L) {
7417
+ console.warn("Error unlocking avatar position:", L);
7404
7418
  }
7405
7419
  }
7406
7420
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
@@ -7440,10 +7454,10 @@ const pt = Me(({
7440
7454
  ] });
7441
7455
  });
7442
7456
  pt.displayName = "TalkingHeadComponent";
7443
- async function gt(V) {
7457
+ async function gt(Z) {
7444
7458
  try {
7445
- console.log(`📥 Loading animation manifest from: ${V}`);
7446
- const t = await fetch(V);
7459
+ console.log(`📥 Loading animation manifest from: ${Z}`);
7460
+ const t = await fetch(Z);
7447
7461
  if (!t.ok)
7448
7462
  throw new Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);
7449
7463
  const e = await t.json();
@@ -7459,7 +7473,7 @@ async function gt(V) {
7459
7473
  }
7460
7474
  }
7461
7475
  const yt = Me(({
7462
- text: V = null,
7476
+ text: Z = null,
7463
7477
  avatarUrl: t = "/avatars/brunette.glb",
7464
7478
  avatarBody: e = "F",
7465
7479
  mood: n = "neutral",
@@ -7477,68 +7491,68 @@ const yt = Me(({
7477
7491
  },
7478
7492
  onError: g = () => {
7479
7493
  },
7480
- onSpeechEnd: x = () => {
7494
+ onSpeechEnd: b = () => {
7481
7495
  },
7482
- className: f = "",
7483
- style: k = {},
7484
- animations: D = {},
7496
+ className: x = "",
7497
+ style: S = {},
7498
+ animations: U = {},
7485
7499
  autoAnimationGroup: p = null,
7486
7500
  // e.g., "talking" - will randomly select from this group when speaking
7487
- autoIdleGroup: B = null,
7501
+ autoIdleGroup: P = null,
7488
7502
  // e.g., "idle" - will randomly select from this group when idle
7489
- autoSpeak: T = !1
7490
- }, R) => {
7491
- const L = W(null), I = W(null), z = W(u), Y = W(null), S = W(null), E = W(!1), j = W({ remainingText: null, originalText: null, options: null }), X = W([]), [oe, le] = pe(!0), [ge, de] = pe(null), [ee, be] = pe(!1), [Q, b] = pe(!1), [v, F] = pe(D), P = W(null);
7503
+ autoSpeak: H = !1
7504
+ }, I) => {
7505
+ const O = G(null), f = G(null), N = G(u), w = G(null), L = G(null), E = G(!1), B = G({ remainingText: null, originalText: null, options: null }), Y = G([]), [ee, le] = pe(!0), [ge, de] = pe(null), [te, be] = pe(!1), [Q, v] = pe(!1), [R, M] = pe(U), F = G(null);
7492
7506
  ce(() => {
7493
7507
  E.current = Q;
7494
7508
  }, [Q]), ce(() => {
7495
7509
  (async () => {
7496
- if (D.manifest)
7510
+ if (U.manifest)
7497
7511
  try {
7498
- console.log("🔄 Loading animations from manifest:", D.manifest);
7499
- const H = await gt(D.manifest);
7500
- F(H), console.log("✅ Animations loaded and set:", H), H._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
7501
- male: Object.keys(H._genderSpecific.male || {}),
7502
- female: Object.keys(H._genderSpecific.female || {}),
7503
- shared: Object.keys(H._genderSpecific.shared || {})
7512
+ console.log("🔄 Loading animations from manifest:", U.manifest);
7513
+ const C = await gt(U.manifest);
7514
+ M(C), console.log("✅ Animations loaded and set:", C), C._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
7515
+ male: Object.keys(C._genderSpecific.male || {}),
7516
+ female: Object.keys(C._genderSpecific.female || {}),
7517
+ shared: Object.keys(C._genderSpecific.shared || {})
7504
7518
  }) : console.log("⚠️ No gender-specific animations found in manifest");
7505
- } catch (H) {
7506
- console.error("❌ Failed to load animation manifest:", H), F(D);
7519
+ } catch (C) {
7520
+ console.error("❌ Failed to load animation manifest:", C), M(U);
7507
7521
  }
7508
7522
  else
7509
- console.log("📝 Using animations from props (no manifest):", D), F(D);
7523
+ console.log("📝 Using animations from props (no manifest):", U), M(U);
7510
7524
  })();
7511
- }, [D]), ce(() => {
7512
- z.current = u;
7525
+ }, [U]), ce(() => {
7526
+ N.current = u;
7513
7527
  }, [u]);
7514
- const N = Ee(), te = s || N.service;
7528
+ const W = Ee(), ne = s || W.service;
7515
7529
  let q;
7516
- te === "browser" ? q = {
7530
+ ne === "browser" ? q = {
7517
7531
  service: "browser",
7518
7532
  endpoint: "",
7519
7533
  apiKey: null,
7520
7534
  defaultVoice: "Google US English"
7521
- } : te === "elevenlabs" ? q = {
7535
+ } : ne === "elevenlabs" ? q = {
7522
7536
  service: "elevenlabs",
7523
7537
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7524
- apiKey: l || N.apiKey,
7525
- defaultVoice: o || N.defaultVoice || Ie.defaultVoice,
7526
- voices: N.voices || Ie.voices
7527
- } : te === "deepgram" ? q = {
7538
+ apiKey: l || W.apiKey,
7539
+ defaultVoice: o || W.defaultVoice || Ie.defaultVoice,
7540
+ voices: W.voices || Ie.voices
7541
+ } : ne === "deepgram" ? q = {
7528
7542
  service: "deepgram",
7529
7543
  endpoint: "https://api.deepgram.com/v1/speak",
7530
- apiKey: l || N.apiKey,
7531
- defaultVoice: o || N.defaultVoice || Te.defaultVoice,
7532
- voices: N.voices || Te.voices
7544
+ apiKey: l || W.apiKey,
7545
+ defaultVoice: o || W.defaultVoice || Te.defaultVoice,
7546
+ voices: W.voices || Te.voices
7533
7547
  } : q = {
7534
- ...N,
7535
- apiKey: l !== null ? l : N.apiKey
7548
+ ...W,
7549
+ apiKey: l !== null ? l : W.apiKey
7536
7550
  };
7537
7551
  const _ = {
7538
7552
  url: t,
7539
7553
  body: e,
7540
7554
  avatarMood: n,
7541
- ttsLang: te === "browser" ? "en-US" : i,
7555
+ ttsLang: ne === "browser" ? "en-US" : i,
7542
7556
  ttsVoice: o || q.defaultVoice,
7543
7557
  lipsyncLang: "en",
7544
7558
  showFullAvatar: u,
@@ -7547,24 +7561,24 @@ const yt = Me(({
7547
7561
  }, Ae = {
7548
7562
  ttsEndpoint: q.endpoint,
7549
7563
  ttsApikey: q.apiKey,
7550
- ttsService: te,
7564
+ ttsService: ne,
7551
7565
  lipsyncModules: ["en"],
7552
7566
  cameraView: a
7553
- }, Se = O(async () => {
7554
- if (!(!L.current || I.current))
7567
+ }, Se = D(async () => {
7568
+ if (!(!O.current || f.current))
7555
7569
  try {
7556
- le(!0), de(null), I.current = new Be(L.current, Ae), console.log("Avatar config being passed:", {
7570
+ le(!0), de(null), f.current = new Be(O.current, Ae), console.log("Avatar config being passed:", {
7557
7571
  url: _.url,
7558
7572
  body: _.body,
7559
7573
  avatarMood: _.avatarMood
7560
- }), await I.current.showAvatar(_, (H) => {
7561
- if (H.lengthComputable) {
7562
- const G = Math.min(100, Math.round(H.loaded / H.total * 100));
7563
- c(G);
7574
+ }), await f.current.showAvatar(_, (C) => {
7575
+ if (C.lengthComputable) {
7576
+ const X = Math.min(100, Math.round(C.loaded / C.total * 100));
7577
+ c(X);
7564
7578
  }
7565
- }), I.current?.avatar && console.log("Avatar body after initialization:", I.current.avatar.body), le(!1), be(!0), d(I.current);
7579
+ }), f.current?.avatar && console.log("Avatar body after initialization:", f.current.avatar.body), le(!1), be(!0), d(f.current);
7566
7580
  const A = () => {
7567
- document.visibilityState === "visible" ? I.current?.start() : I.current?.stop();
7581
+ document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
7568
7582
  };
7569
7583
  return document.addEventListener("visibilitychange", A), () => {
7570
7584
  document.removeEventListener("visibilitychange", A);
@@ -7574,51 +7588,51 @@ const yt = Me(({
7574
7588
  }
7575
7589
  }, []);
7576
7590
  ce(() => (Se(), () => {
7577
- I.current && (I.current.stop(), I.current.dispose(), I.current = null);
7591
+ f.current && (f.current.stop(), f.current.dispose(), f.current = null);
7578
7592
  }), [Se]);
7579
- const Le = O(async () => {
7580
- if (I.current)
7593
+ const Le = D(async () => {
7594
+ if (f.current)
7581
7595
  try {
7582
- const A = I.current.audioCtx || I.current.audioContext;
7596
+ const A = f.current.audioCtx || f.current.audioContext;
7583
7597
  A && (A.state === "suspended" || A.state === "interrupted") && (await A.resume(), console.log("Audio context resumed"));
7584
7598
  } catch (A) {
7585
7599
  console.warn("Failed to resume audio context:", A);
7586
7600
  }
7587
- }, []), ke = O((A) => {
7588
- if (!v)
7601
+ }, []), ke = D((A) => {
7602
+ if (!R)
7589
7603
  return console.warn("No animations loaded"), null;
7590
- let H = null;
7591
- if (v._genderSpecific) {
7592
- const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female", ie = v._genderSpecific[J];
7593
- ie && ie[A] ? (H = ie[A], console.log(`Using ${J} animations for "${A}":`, H)) : v._genderSpecific.shared && v._genderSpecific.shared[A] && (H = v._genderSpecific.shared[A], console.log(`Using shared animations for "${A}":`, H));
7604
+ let C = null;
7605
+ if (R._genderSpecific) {
7606
+ const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female", oe = R._genderSpecific[J];
7607
+ oe && oe[A] ? (C = oe[A], console.log(`Using ${J} animations for "${A}":`, C)) : R._genderSpecific.shared && R._genderSpecific.shared[A] && (C = R._genderSpecific.shared[A], console.log(`Using shared animations for "${A}":`, C));
7594
7608
  }
7595
- if (!H && v[A] && (H = v[A], console.log(`Using root-level animations for "${A}":`, H)), !H) {
7596
- if (console.warn(`Animation group "${A}" not found. Available groups:`, Object.keys(v).filter((G) => G !== "_genderSpecific")), v._genderSpecific) {
7609
+ if (!C && R[A] && (C = R[A], console.log(`Using root-level animations for "${A}":`, C)), !C) {
7610
+ if (console.warn(`Animation group "${A}" not found. Available groups:`, Object.keys(R).filter((X) => X !== "_genderSpecific")), R._genderSpecific) {
7597
7611
  const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female";
7598
- console.warn(`Gender-specific groups (${J}):`, Object.keys(v._genderSpecific[J] || {}));
7612
+ console.warn(`Gender-specific groups (${J}):`, Object.keys(R._genderSpecific[J] || {}));
7599
7613
  }
7600
7614
  return null;
7601
7615
  }
7602
- if (Array.isArray(H) && H.length > 0) {
7603
- const G = Math.floor(Math.random() * H.length);
7604
- return H[G];
7616
+ if (Array.isArray(C) && C.length > 0) {
7617
+ const X = Math.floor(Math.random() * C.length);
7618
+ return C[X];
7605
7619
  }
7606
- return typeof H == "string" ? H : (console.warn(`Animation group "${A}" is not a valid format (expected array or string):`, H), null);
7607
- }, [v, e]), w = O((A, H = !1) => {
7608
- if (!I.current)
7620
+ return typeof C == "string" ? C : (console.warn(`Animation group "${A}" is not a valid format (expected array or string):`, C), null);
7621
+ }, [R, e]), k = D((A, C = !1) => {
7622
+ if (!f.current)
7609
7623
  return console.warn("TalkingHead not initialized yet"), null;
7610
- const G = ke(A);
7611
- if (G)
7624
+ const X = ke(A);
7625
+ if (X)
7612
7626
  try {
7613
- return I.current.playAnimation(G, null, 10, 0, 0.01, H), console.log(`✅ Playing random animation from "${A}" group:`, G), G;
7627
+ return f.current.playAnimation(X, null, 10, 0, 0.01, C), console.log(`✅ Playing random animation from "${A}" group:`, X), X;
7614
7628
  } catch (J) {
7615
7629
  return console.error(`❌ Failed to play random animation from "${A}" group:`, J), null;
7616
7630
  }
7617
7631
  else
7618
7632
  console.warn(`⚠️ No animation found for group "${A}"`);
7619
7633
  return null;
7620
- }, [ke]), U = O(async (A, H = {}) => {
7621
- if (!I.current || !ee) {
7634
+ }, [ke]), V = D(async (A, C = {}) => {
7635
+ if (!f.current || !te) {
7622
7636
  console.warn("Avatar not ready for speaking");
7623
7637
  return;
7624
7638
  }
@@ -7627,93 +7641,93 @@ const yt = Me(({
7627
7641
  return;
7628
7642
  }
7629
7643
  await Le();
7630
- const G = H.animationGroup || p;
7631
- G && !H.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${G}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, v), w(G)) : console.log(`⏭️ Skipping animation (group: ${G}, skipAnimation: ${H.skipAnimation})`), j.current = { remainingText: null, originalText: null, options: null }, X.current = [], Y.current = { text: A, options: H }, S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1;
7644
+ const X = C.animationGroup || p;
7645
+ X && !C.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${X}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, R), k(X)) : console.log(`⏭️ Skipping animation (group: ${X}, skipAnimation: ${C.skipAnimation})`), B.current = { remainingText: null, originalText: null, options: null }, Y.current = [], w.current = { text: A, options: C }, L.current && (clearInterval(L.current), L.current = null), v(!1), E.current = !1;
7632
7646
  const J = A.split(/[.!?]+/).filter((se) => se.trim().length > 0);
7633
- X.current = J;
7634
- const ie = {
7635
- lipsyncLang: H.lipsyncLang || "en",
7647
+ Y.current = J;
7648
+ const oe = {
7649
+ lipsyncLang: C.lipsyncLang || "en",
7636
7650
  onSpeechEnd: () => {
7637
- S.current && (clearInterval(S.current), S.current = null), H.onSpeechEnd && H.onSpeechEnd(), x();
7651
+ L.current && (clearInterval(L.current), L.current = null), C.onSpeechEnd && C.onSpeechEnd(), b();
7638
7652
  }
7639
7653
  };
7640
7654
  try {
7641
- I.current.speakText(A, ie);
7655
+ f.current.speakText(A, oe);
7642
7656
  } catch (se) {
7643
7657
  console.error("Error speaking text:", se), de(se.message || "Failed to speak text");
7644
7658
  }
7645
- }, [ee, x, Le, p, w]);
7659
+ }, [te, b, Le, p, k]);
7646
7660
  ce(() => {
7647
- if (!ee || !B || !I.current)
7661
+ if (!te || !P || !f.current)
7648
7662
  return;
7649
- P.current && clearInterval(P.current);
7663
+ F.current && clearInterval(F.current);
7650
7664
  const A = () => {
7651
- I.current && !E.current && w(B);
7665
+ f.current && !E.current && k(P);
7652
7666
  };
7653
- return A(), P.current = setInterval(() => {
7667
+ return A(), F.current = setInterval(() => {
7654
7668
  A();
7655
7669
  }, 12e3 + Math.random() * 3e3), () => {
7656
- P.current && (clearInterval(P.current), P.current = null);
7670
+ F.current && (clearInterval(F.current), F.current = null);
7657
7671
  };
7658
- }, [ee, B, w]), ce(() => {
7659
- ee && V && T && I.current && U(V);
7660
- }, [ee, V, T, U]);
7661
- const K = O(() => {
7662
- if (I.current)
7672
+ }, [te, P, k]), ce(() => {
7673
+ te && Z && H && f.current && V(Z);
7674
+ }, [te, Z, H, V]);
7675
+ const K = D(() => {
7676
+ if (f.current)
7663
7677
  try {
7664
- const A = I.current.isSpeaking || !1, H = I.current.audioPlaylist || [], G = I.current.speechQueue || [];
7665
- if (A || H.length > 0 || G.length > 0) {
7666
- S.current && (clearInterval(S.current), S.current = null);
7678
+ const A = f.current.isSpeaking || !1, C = f.current.audioPlaylist || [], X = f.current.speechQueue || [];
7679
+ if (A || C.length > 0 || X.length > 0) {
7680
+ L.current && (clearInterval(L.current), L.current = null);
7667
7681
  let J = "";
7668
- G.length > 0 && (J = G.map((ie) => ie.text && Array.isArray(ie.text) ? ie.text.map((se) => se.word).join(" ") : ie.text || "").join(" ")), j.current = {
7682
+ X.length > 0 && (J = X.map((oe) => oe.text && Array.isArray(oe.text) ? oe.text.map((se) => se.word).join(" ") : oe.text || "").join(" ")), B.current = {
7669
7683
  remainingText: J || null,
7670
- originalText: Y.current?.text || null,
7671
- options: Y.current?.options || null
7672
- }, I.current.speechQueue.length = 0, I.current.pauseSpeaking(), b(!0), E.current = !0;
7684
+ originalText: w.current?.text || null,
7685
+ options: w.current?.options || null
7686
+ }, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), v(!0), E.current = !0;
7673
7687
  }
7674
7688
  } catch (A) {
7675
7689
  console.warn("Error pausing speech:", A);
7676
7690
  }
7677
- }, []), ne = O(async () => {
7678
- if (!(!I.current || !Q))
7691
+ }, []), ie = D(async () => {
7692
+ if (!(!f.current || !Q))
7679
7693
  try {
7680
- await Le(), b(!1), E.current = !1;
7681
- const A = j.current?.remainingText, H = j.current?.originalText || Y.current?.text, G = j.current?.options || Y.current?.options || {}, J = A || H;
7682
- J && U(J, G);
7694
+ await Le(), v(!1), E.current = !1;
7695
+ const A = B.current?.remainingText, C = B.current?.originalText || w.current?.text, X = B.current?.options || w.current?.options || {}, J = A || C;
7696
+ J && V(J, X);
7683
7697
  } catch (A) {
7684
- console.warn("Error resuming speech:", A), b(!1), E.current = !1;
7698
+ console.warn("Error resuming speech:", A), v(!1), E.current = !1;
7685
7699
  }
7686
- }, [Q, U, Le]), me = O(() => {
7687
- I.current && (I.current.stopSpeaking(), S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1);
7700
+ }, [Q, V, Le]), me = D(() => {
7701
+ f.current && (f.current.stopSpeaking(), L.current && (clearInterval(L.current), L.current = null), v(!1), E.current = !1);
7688
7702
  }, []);
7689
- return Fe(R, () => ({
7690
- speakText: U,
7703
+ return Fe(I, () => ({
7704
+ speakText: V,
7691
7705
  pauseSpeaking: K,
7692
- resumeSpeaking: ne,
7706
+ resumeSpeaking: ie,
7693
7707
  stopSpeaking: me,
7694
7708
  resumeAudioContext: Le,
7695
7709
  isPaused: () => Q,
7696
- setMood: (A) => I.current?.setMood(A),
7710
+ setMood: (A) => f.current?.setMood(A),
7697
7711
  setBodyMovement: (A) => {
7698
- I.current && I.current.setBodyMovement(A);
7712
+ f.current && f.current.setBodyMovement(A);
7699
7713
  },
7700
- playAnimation: (A, H = !1) => {
7701
- I.current && I.current.playAnimation && I.current.playAnimation(A, null, 10, 0, 0.01, H);
7714
+ playAnimation: (A, C = !1) => {
7715
+ f.current && f.current.playAnimation && f.current.playAnimation(A, null, 10, 0, 0.01, C);
7702
7716
  },
7703
- playRandomAnimation: (A, H = !1) => w(A, H),
7717
+ playRandomAnimation: (A, C = !1) => k(A, C),
7704
7718
  getRandomAnimation: (A) => ke(A),
7705
- playReaction: (A) => I.current?.playReaction(A),
7706
- playCelebration: () => I.current?.playCelebration(),
7719
+ playReaction: (A) => f.current?.playReaction(A),
7720
+ playCelebration: () => f.current?.playCelebration(),
7707
7721
  setShowFullAvatar: (A) => {
7708
- I.current && (z.current = A, I.current.setShowFullAvatar(A));
7722
+ f.current && (N.current = A, f.current.setShowFullAvatar(A));
7709
7723
  },
7710
- isReady: ee,
7711
- talkingHead: I.current
7712
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: k, children: [
7724
+ isReady: te,
7725
+ talkingHead: f.current
7726
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${x}`, style: S, children: [
7713
7727
  /* @__PURE__ */ ye(
7714
7728
  "div",
7715
7729
  {
7716
- ref: L,
7730
+ ref: O,
7717
7731
  className: "talking-head-viewer",
7718
7732
  style: {
7719
7733
  width: "100%",
@@ -7722,7 +7736,7 @@ const yt = Me(({
7722
7736
  }
7723
7737
  }
7724
7738
  ),
7725
- oe && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7739
+ ee && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7726
7740
  position: "absolute",
7727
7741
  top: "50%",
7728
7742
  left: "50%",
@@ -7747,7 +7761,7 @@ const yt = Me(({
7747
7761
  });
7748
7762
  yt.displayName = "SimpleTalkingAvatar";
7749
7763
  const ft = Me(({
7750
- curriculumData: V = null,
7764
+ curriculumData: Z = null,
7751
7765
  avatarConfig: t = {},
7752
7766
  animations: e = {},
7753
7767
  onLessonStart: n = () => {
@@ -7762,7 +7776,7 @@ const ft = Me(({
7762
7776
  },
7763
7777
  autoStart: h = !1
7764
7778
  }, r) => {
7765
- const u = W(null), a = W({
7779
+ const u = G(null), a = G({
7766
7780
  currentModuleIndex: 0,
7767
7781
  currentLessonIndex: 0,
7768
7782
  currentQuestionIndex: 0,
@@ -7772,18 +7786,18 @@ const ft = Me(({
7772
7786
  curriculumCompleted: !1,
7773
7787
  score: 0,
7774
7788
  totalQuestions: 0
7775
- }), d = W({
7789
+ }), d = G({
7776
7790
  onLessonStart: n,
7777
7791
  onLessonComplete: i,
7778
7792
  onQuestionAnswer: s,
7779
7793
  onCurriculumComplete: o,
7780
7794
  onCustomAction: l
7781
- }), c = W(null), g = W(null), x = W(null), f = W(null), k = W(null), D = W(null), p = W(null), B = W(V?.curriculum || {
7795
+ }), c = G(null), g = G(null), b = G(null), x = G(null), S = G(null), U = G(null), p = G(null), P = G(Z?.curriculum || {
7782
7796
  title: "Default Curriculum",
7783
7797
  description: "No curriculum data provided",
7784
7798
  language: "en",
7785
7799
  modules: []
7786
- }), T = W({
7800
+ }), H = G({
7787
7801
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7788
7802
  avatarBody: t.avatarBody || "F",
7789
7803
  mood: t.mood || "happy",
@@ -7806,12 +7820,12 @@ const ft = Me(({
7806
7820
  onCustomAction: l
7807
7821
  };
7808
7822
  }, [n, i, s, o, l]), ce(() => {
7809
- B.current = V?.curriculum || {
7823
+ P.current = Z?.curriculum || {
7810
7824
  title: "Default Curriculum",
7811
7825
  description: "No curriculum data provided",
7812
7826
  language: "en",
7813
7827
  modules: []
7814
- }, T.current = {
7828
+ }, H.current = {
7815
7829
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7816
7830
  avatarBody: t.avatarBody || "F",
7817
7831
  mood: t.mood || "happy",
@@ -7825,24 +7839,24 @@ const ft = Me(({
7825
7839
  animations: e,
7826
7840
  lipsyncLang: "en"
7827
7841
  };
7828
- }, [V, t, e]);
7829
- const R = O(() => (B.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), L = O(() => R()?.questions[a.current.currentQuestionIndex], [R]), I = O((b, v) => v.type === "multiple_choice" || v.type === "true_false" ? b === v.answer : v.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), z = O(() => {
7842
+ }, [Z, t, e]);
7843
+ const I = D(() => (P.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), O = D(() => I()?.questions[a.current.currentQuestionIndex], [I]), f = D((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, []), N = D(() => {
7830
7844
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7831
- const b = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7832
- let v = "Congratulations! You've completed this lesson";
7833
- if (a.current.totalQuestions > 0 ? v += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${b} percent. ` : v += "! ", b >= 80 ? v += "Excellent work! You have a great understanding of this topic." : b >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7845
+ const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7846
+ let R = "Congratulations! You've completed this lesson";
7847
+ if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7834
7848
  moduleIndex: a.current.currentModuleIndex,
7835
7849
  lessonIndex: a.current.currentLessonIndex,
7836
7850
  score: a.current.score,
7837
7851
  totalQuestions: a.current.totalQuestions,
7838
- percentage: b
7852
+ percentage: v
7839
7853
  }), d.current.onCustomAction({
7840
7854
  type: "lessonComplete",
7841
7855
  moduleIndex: a.current.currentModuleIndex,
7842
7856
  lessonIndex: a.current.currentLessonIndex,
7843
7857
  score: a.current.score,
7844
7858
  totalQuestions: a.current.totalQuestions,
7845
- percentage: b
7859
+ percentage: v
7846
7860
  }), u.current) {
7847
7861
  if (u.current.setMood("happy"), e.lessonComplete)
7848
7862
  try {
@@ -7850,8 +7864,8 @@ const ft = Me(({
7850
7864
  } catch {
7851
7865
  u.current.playCelebration();
7852
7866
  }
7853
- const F = B.current || { modules: [] }, P = F.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (F.modules?.length || 0) - 1, q = N || te, _ = T.current || { lipsyncLang: "en" };
7854
- u.current.speakText(v, {
7867
+ const M = P.current || { modules: [] }, F = M.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (F?.lessons?.length || 0) - 1, ne = a.current.currentModuleIndex < (M.modules?.length || 0) - 1, q = W || ne, _ = H.current || { lipsyncLang: "en" };
7868
+ u.current.speakText(R, {
7855
7869
  lipsyncLang: _.lipsyncLang,
7856
7870
  onSpeechEnd: () => {
7857
7871
  d.current.onCustomAction({
@@ -7860,18 +7874,18 @@ const ft = Me(({
7860
7874
  lessonIndex: a.current.currentLessonIndex,
7861
7875
  score: a.current.score,
7862
7876
  totalQuestions: a.current.totalQuestions,
7863
- percentage: b,
7877
+ percentage: v,
7864
7878
  hasNextLesson: q
7865
7879
  });
7866
7880
  }
7867
7881
  });
7868
7882
  }
7869
- }, [e.lessonComplete]), Y = O(() => {
7883
+ }, [e.lessonComplete]), w = D(() => {
7870
7884
  a.current.curriculumCompleted = !0;
7871
- const b = B.current || { modules: [] };
7885
+ const v = P.current || { modules: [] };
7872
7886
  if (d.current.onCurriculumComplete({
7873
- modules: b.modules.length,
7874
- totalLessons: b.modules.reduce((v, F) => v + F.lessons.length, 0)
7887
+ modules: v.modules.length,
7888
+ totalLessons: v.modules.reduce((R, M) => R + M.lessons.length, 0)
7875
7889
  }), u.current) {
7876
7890
  if (u.current.setMood("celebrating"), e.curriculumComplete)
7877
7891
  try {
@@ -7879,99 +7893,99 @@ const ft = Me(({
7879
7893
  } catch {
7880
7894
  u.current.playCelebration();
7881
7895
  }
7882
- const v = T.current || { lipsyncLang: "en" };
7883
- u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
7896
+ const R = H.current || { lipsyncLang: "en" };
7897
+ u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7884
7898
  }
7885
- }, [e.curriculumComplete]), S = O(() => {
7886
- const b = R();
7887
- a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = b?.questions?.length || 0, a.current.score = 0;
7888
- const v = L();
7889
- v && d.current.onCustomAction({
7899
+ }, [e.curriculumComplete]), L = D(() => {
7900
+ const v = I();
7901
+ a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7902
+ const R = O();
7903
+ R && d.current.onCustomAction({
7890
7904
  type: "questionStart",
7891
7905
  moduleIndex: a.current.currentModuleIndex,
7892
7906
  lessonIndex: a.current.currentLessonIndex,
7893
7907
  questionIndex: a.current.currentQuestionIndex,
7894
7908
  totalQuestions: a.current.totalQuestions,
7895
- question: v,
7909
+ question: R,
7896
7910
  score: a.current.score
7897
7911
  });
7898
- const F = () => {
7899
- if (!u.current || !v) return;
7912
+ const M = () => {
7913
+ if (!u.current || !R) return;
7900
7914
  if (u.current.setMood("happy"), e.questionStart)
7901
7915
  try {
7902
7916
  u.current.playAnimation(e.questionStart, !0);
7903
- } catch (N) {
7904
- console.warn("Failed to play questionStart animation:", N);
7917
+ } catch (W) {
7918
+ console.warn("Failed to play questionStart animation:", W);
7905
7919
  }
7906
- const P = T.current || { lipsyncLang: "en" };
7907
- v.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : v.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : v.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: P.lipsyncLang });
7920
+ const F = H.current || { lipsyncLang: "en" };
7921
+ R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: F.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: F.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: F.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: F.lipsyncLang });
7908
7922
  };
7909
- if (u.current && u.current.isReady && v)
7910
- F();
7923
+ if (u.current && u.current.isReady && R)
7924
+ M();
7911
7925
  else if (u.current && u.current.isReady) {
7912
- const P = T.current || { lipsyncLang: "en" };
7913
- u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: P.lipsyncLang });
7926
+ const F = H.current || { lipsyncLang: "en" };
7927
+ u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: F.lipsyncLang });
7914
7928
  } else {
7915
- const P = setInterval(() => {
7916
- u.current && u.current.isReady && (clearInterval(P), v && F());
7929
+ const F = setInterval(() => {
7930
+ u.current && u.current.isReady && (clearInterval(F), R && M());
7917
7931
  }, 100);
7918
7932
  setTimeout(() => {
7919
- clearInterval(P);
7933
+ clearInterval(F);
7920
7934
  }, 5e3);
7921
7935
  }
7922
- }, [e.questionStart, R, L]), E = O(() => {
7923
- const b = R();
7924
- if (a.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7936
+ }, [e.questionStart, I, O]), E = D(() => {
7937
+ const v = I();
7938
+ if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7925
7939
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7926
- const v = L();
7927
- v && d.current.onCustomAction({
7940
+ const R = O();
7941
+ R && d.current.onCustomAction({
7928
7942
  type: "nextQuestion",
7929
7943
  moduleIndex: a.current.currentModuleIndex,
7930
7944
  lessonIndex: a.current.currentLessonIndex,
7931
7945
  questionIndex: a.current.currentQuestionIndex,
7932
7946
  totalQuestions: a.current.totalQuestions,
7933
- question: v,
7947
+ question: R,
7934
7948
  score: a.current.score
7935
7949
  });
7936
- const F = () => {
7937
- if (!u.current || !v) return;
7950
+ const M = () => {
7951
+ if (!u.current || !R) return;
7938
7952
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7939
7953
  try {
7940
7954
  u.current.playAnimation(e.nextQuestion, !0);
7941
7955
  } catch (_) {
7942
7956
  console.warn("Failed to play nextQuestion animation:", _);
7943
7957
  }
7944
- const P = T.current || { lipsyncLang: "en" }, te = R()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
7945
- if (v.type === "code_test") {
7946
- const _ = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
7958
+ const F = H.current || { lipsyncLang: "en" }, ne = I()?.questions?.length || 0, q = a.current.currentQuestionIndex >= ne - 1;
7959
+ if (R.type === "code_test") {
7960
+ const _ = q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7947
7961
  u.current.speakText(_, {
7948
- lipsyncLang: P.lipsyncLang
7962
+ lipsyncLang: F.lipsyncLang
7949
7963
  });
7950
- } else if (v.type === "multiple_choice") {
7951
- const _ = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
7964
+ } else if (R.type === "multiple_choice") {
7965
+ const _ = q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7952
7966
  u.current.speakText(_, {
7953
- lipsyncLang: P.lipsyncLang
7967
+ lipsyncLang: F.lipsyncLang
7954
7968
  });
7955
- } else if (v.type === "true_false") {
7956
- const _ = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
7969
+ } else if (R.type === "true_false") {
7970
+ const _ = q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7957
7971
  u.current.speakText(_, {
7958
- lipsyncLang: P.lipsyncLang
7972
+ lipsyncLang: F.lipsyncLang
7959
7973
  });
7960
7974
  } else {
7961
- const _ = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
7975
+ const _ = q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7962
7976
  u.current.speakText(_, {
7963
- lipsyncLang: P.lipsyncLang
7977
+ lipsyncLang: F.lipsyncLang
7964
7978
  });
7965
7979
  }
7966
7980
  };
7967
- if (u.current && u.current.isReady && v)
7968
- F();
7969
- else if (v) {
7970
- const P = setInterval(() => {
7971
- u.current && u.current.isReady && (clearInterval(P), F());
7981
+ if (u.current && u.current.isReady && R)
7982
+ M();
7983
+ else if (R) {
7984
+ const F = setInterval(() => {
7985
+ u.current && u.current.isReady && (clearInterval(F), M());
7972
7986
  }, 100);
7973
7987
  setTimeout(() => {
7974
- clearInterval(P);
7988
+ clearInterval(F);
7975
7989
  }, 5e3);
7976
7990
  }
7977
7991
  } else
@@ -7982,11 +7996,11 @@ const ft = Me(({
7982
7996
  totalQuestions: a.current.totalQuestions,
7983
7997
  score: a.current.score
7984
7998
  });
7985
- }, [e.nextQuestion, R, L]), j = O(() => {
7986
- const b = B.current || { modules: [] }, v = b.modules[a.current.currentModuleIndex];
7987
- if (a.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
7999
+ }, [e.nextQuestion, I, O]), B = D(() => {
8000
+ const v = P.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
8001
+ if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7988
8002
  a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7989
- const P = b.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = N || te;
8003
+ const F = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (F?.lessons?.length || 0) - 1, ne = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = W || ne;
7990
8004
  d.current.onCustomAction({
7991
8005
  type: "lessonStart",
7992
8006
  moduleIndex: a.current.currentModuleIndex,
@@ -7995,11 +8009,11 @@ const ft = Me(({
7995
8009
  }), d.current.onLessonStart({
7996
8010
  moduleIndex: a.current.currentModuleIndex,
7997
8011
  lessonIndex: a.current.currentLessonIndex,
7998
- lesson: R()
8012
+ lesson: I()
7999
8013
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8000
- } else if (a.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
8014
+ } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
8001
8015
  a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
8002
- const N = b.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, _ = te || q;
8016
+ const W = v.modules[a.current.currentModuleIndex], ne = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, _ = ne || q;
8003
8017
  d.current.onCustomAction({
8004
8018
  type: "lessonStart",
8005
8019
  moduleIndex: a.current.currentModuleIndex,
@@ -8008,68 +8022,68 @@ const ft = Me(({
8008
8022
  }), d.current.onLessonStart({
8009
8023
  moduleIndex: a.current.currentModuleIndex,
8010
8024
  lessonIndex: a.current.currentLessonIndex,
8011
- lesson: R()
8025
+ lesson: I()
8012
8026
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8013
8027
  } else
8014
- k.current && k.current();
8015
- }, []), X = O(() => {
8016
- const b = R();
8017
- let v = null;
8018
- if (b?.avatar_script && b?.body) {
8019
- const F = b.avatar_script.trim(), P = b.body.trim(), N = F.match(/[.!?]$/) ? " " : ". ";
8020
- v = `${F}${N}${P}`;
8028
+ S.current && S.current();
8029
+ }, []), Y = D(() => {
8030
+ const v = I();
8031
+ let R = null;
8032
+ if (v?.avatar_script && v?.body) {
8033
+ const M = v.avatar_script.trim(), F = v.body.trim(), W = M.match(/[.!?]$/) ? " " : ". ";
8034
+ R = `${M}${W}${F}`;
8021
8035
  } else
8022
- v = b?.avatar_script || b?.body || null;
8023
- if (u.current && u.current.isReady && v) {
8036
+ R = v?.avatar_script || v?.body || null;
8037
+ if (u.current && u.current.isReady && R) {
8024
8038
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
8025
- let F = !1;
8039
+ let M = !1;
8026
8040
  if (e.teaching)
8027
8041
  try {
8028
- u.current.playAnimation(e.teaching, !0), F = !0;
8029
- } catch (N) {
8030
- console.warn("Failed to play teaching animation:", N);
8042
+ u.current.playAnimation(e.teaching, !0), M = !0;
8043
+ } catch (W) {
8044
+ console.warn("Failed to play teaching animation:", W);
8031
8045
  }
8032
- F || u.current.setBodyMovement("gesturing");
8033
- const P = T.current || { lipsyncLang: "en" };
8046
+ M || u.current.setBodyMovement("gesturing");
8047
+ const F = H.current || { lipsyncLang: "en" };
8034
8048
  d.current.onLessonStart({
8035
8049
  moduleIndex: a.current.currentModuleIndex,
8036
8050
  lessonIndex: a.current.currentLessonIndex,
8037
- lesson: b
8051
+ lesson: v
8038
8052
  }), d.current.onCustomAction({
8039
8053
  type: "teachingStart",
8040
8054
  moduleIndex: a.current.currentModuleIndex,
8041
8055
  lessonIndex: a.current.currentLessonIndex,
8042
- lesson: b
8043
- }), u.current.speakText(v, {
8044
- lipsyncLang: P.lipsyncLang,
8056
+ lesson: v
8057
+ }), u.current.speakText(R, {
8058
+ lipsyncLang: F.lipsyncLang,
8045
8059
  onSpeechEnd: () => {
8046
8060
  a.current.isTeaching = !1, d.current.onCustomAction({
8047
8061
  type: "teachingComplete",
8048
8062
  moduleIndex: a.current.currentModuleIndex,
8049
8063
  lessonIndex: a.current.currentLessonIndex,
8050
- lesson: b,
8051
- hasQuestions: b.questions && b.questions.length > 0
8052
- }), b?.code_example && d.current.onCustomAction({
8064
+ lesson: v,
8065
+ hasQuestions: v.questions && v.questions.length > 0
8066
+ }), v?.code_example && d.current.onCustomAction({
8053
8067
  type: "codeExampleReady",
8054
8068
  moduleIndex: a.current.currentModuleIndex,
8055
8069
  lessonIndex: a.current.currentLessonIndex,
8056
- lesson: b,
8057
- codeExample: b.code_example
8070
+ lesson: v,
8071
+ codeExample: v.code_example
8058
8072
  });
8059
8073
  }
8060
8074
  });
8061
8075
  }
8062
- }, [e.teaching, R]), oe = O((b) => {
8063
- const v = L(), F = I(b, v);
8064
- if (F && (a.current.score += 1), d.current.onQuestionAnswer({
8076
+ }, [e.teaching, I]), ee = D((v) => {
8077
+ const R = O(), M = f(v, R);
8078
+ if (M && (a.current.score += 1), d.current.onQuestionAnswer({
8065
8079
  moduleIndex: a.current.currentModuleIndex,
8066
8080
  lessonIndex: a.current.currentLessonIndex,
8067
8081
  questionIndex: a.current.currentQuestionIndex,
8068
- answer: b,
8069
- isCorrect: F,
8070
- question: v
8082
+ answer: v,
8083
+ isCorrect: M,
8084
+ question: R
8071
8085
  }), u.current)
8072
- if (F) {
8086
+ if (M) {
8073
8087
  if (u.current.setMood("happy"), e.correct)
8074
8088
  try {
8075
8089
  u.current.playReaction("happy");
@@ -8077,11 +8091,11 @@ const ft = Me(({
8077
8091
  u.current.setBodyMovement("happy");
8078
8092
  }
8079
8093
  u.current.setBodyMovement("gesturing");
8080
- const N = R()?.questions?.length || 0;
8081
- a.current.currentQuestionIndex >= N - 1;
8082
- const te = a.current.currentQuestionIndex < N - 1;
8083
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", te);
8084
- const q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, _ = T.current || { lipsyncLang: "en" };
8094
+ const W = I()?.questions?.length || 0;
8095
+ a.current.currentQuestionIndex >= W - 1;
8096
+ const ne = a.current.currentQuestionIndex < W - 1;
8097
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", ne);
8098
+ 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" };
8085
8099
  u.current.speakText(q, {
8086
8100
  lipsyncLang: _.lipsyncLang,
8087
8101
  onSpeechEnd: () => {
@@ -8091,7 +8105,7 @@ const ft = Me(({
8091
8105
  lessonIndex: a.current.currentLessonIndex,
8092
8106
  questionIndex: a.current.currentQuestionIndex,
8093
8107
  isCorrect: !0,
8094
- hasNextQuestion: te,
8108
+ hasNextQuestion: ne,
8095
8109
  score: a.current.score,
8096
8110
  totalQuestions: a.current.totalQuestions
8097
8111
  });
@@ -8105,9 +8119,9 @@ const ft = Me(({
8105
8119
  u.current.setBodyMovement("idle");
8106
8120
  }
8107
8121
  u.current.setBodyMovement("gesturing");
8108
- const N = R()?.questions?.length || 0, te = a.current.currentQuestionIndex >= N - 1, q = a.current.currentQuestionIndex < N - 1;
8109
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", q);
8110
- const _ = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${te ? "" : " Let's move on to the next question."}`, Ae = T.current || { lipsyncLang: "en" };
8122
+ const W = I()?.questions?.length || 0, ne = a.current.currentQuestionIndex >= W - 1, q = a.current.currentQuestionIndex < W - 1;
8123
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", q);
8124
+ 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 || ""}${ne ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
8111
8125
  u.current.speakText(_, {
8112
8126
  lipsyncLang: Ae.lipsyncLang,
8113
8127
  onSpeechEnd: () => {
@@ -8125,84 +8139,84 @@ const ft = Me(({
8125
8139
  });
8126
8140
  }
8127
8141
  else {
8128
- const N = R()?.questions?.length || 0;
8142
+ const W = I()?.questions?.length || 0;
8129
8143
  d.current.onCustomAction({
8130
8144
  type: "answerFeedbackComplete",
8131
8145
  moduleIndex: a.current.currentModuleIndex,
8132
8146
  lessonIndex: a.current.currentLessonIndex,
8133
8147
  questionIndex: a.current.currentQuestionIndex,
8134
- isCorrect: F,
8135
- hasNextQuestion: a.current.currentQuestionIndex < N - 1,
8148
+ isCorrect: M,
8149
+ hasNextQuestion: a.current.currentQuestionIndex < W - 1,
8136
8150
  score: a.current.score,
8137
8151
  totalQuestions: a.current.totalQuestions,
8138
8152
  avatarNotReady: !0
8139
8153
  });
8140
8154
  }
8141
- }, [e.correct, e.incorrect, L, R, I]), le = O((b) => {
8142
- const v = L();
8143
- if (!b || typeof b != "object") {
8155
+ }, [e.correct, e.incorrect, O, I, f]), le = D((v) => {
8156
+ const R = O();
8157
+ if (!v || typeof v != "object") {
8144
8158
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
8145
8159
  return;
8146
8160
  }
8147
- if (v?.type !== "code_test") {
8161
+ if (R?.type !== "code_test") {
8148
8162
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
8149
8163
  return;
8150
8164
  }
8151
- const F = {
8152
- passed: b.passed === !0,
8153
- results: b.results || [],
8154
- output: b.output || "",
8155
- error: b.error || null,
8156
- executionTime: b.executionTime || null,
8157
- testCount: b.testCount || 0,
8158
- passedCount: b.passedCount || 0,
8159
- failedCount: b.failedCount || 0
8165
+ const M = {
8166
+ passed: v.passed === !0,
8167
+ results: v.results || [],
8168
+ output: v.output || "",
8169
+ error: v.error || null,
8170
+ executionTime: v.executionTime || null,
8171
+ testCount: v.testCount || 0,
8172
+ passedCount: v.passedCount || 0,
8173
+ failedCount: v.failedCount || 0
8160
8174
  };
8161
8175
  d.current.onCustomAction({
8162
8176
  type: "codeTestSubmitted",
8163
8177
  moduleIndex: a.current.currentModuleIndex,
8164
8178
  lessonIndex: a.current.currentLessonIndex,
8165
8179
  questionIndex: a.current.currentQuestionIndex,
8166
- testResult: F,
8167
- question: v
8168
- }), p.current && p.current(F);
8169
- }, [L, I]), ge = O(() => {
8180
+ testResult: M,
8181
+ question: R
8182
+ }), p.current && p.current(M);
8183
+ }, [O, f]), ge = D(() => {
8170
8184
  if (a.current.currentQuestionIndex > 0) {
8171
8185
  a.current.currentQuestionIndex -= 1;
8172
- const b = L();
8173
- b && d.current.onCustomAction({
8186
+ const v = O();
8187
+ v && d.current.onCustomAction({
8174
8188
  type: "questionStart",
8175
8189
  moduleIndex: a.current.currentModuleIndex,
8176
8190
  lessonIndex: a.current.currentLessonIndex,
8177
8191
  questionIndex: a.current.currentQuestionIndex,
8178
8192
  totalQuestions: a.current.totalQuestions,
8179
- question: b,
8193
+ question: v,
8180
8194
  score: a.current.score
8181
8195
  });
8182
- const v = () => {
8183
- if (!u.current || !b) return;
8196
+ const R = () => {
8197
+ if (!u.current || !v) return;
8184
8198
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
8185
- const F = T.current || { lipsyncLang: "en" };
8186
- b.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${b.question}`, {
8187
- lipsyncLang: F.lipsyncLang
8188
- }) : u.current.speakText(`Going back to: ${b.question}`, {
8189
- lipsyncLang: F.lipsyncLang
8199
+ const M = H.current || { lipsyncLang: "en" };
8200
+ v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8201
+ lipsyncLang: M.lipsyncLang
8202
+ }) : u.current.speakText(`Going back to: ${v.question}`, {
8203
+ lipsyncLang: M.lipsyncLang
8190
8204
  });
8191
8205
  };
8192
- if (u.current && u.current.isReady && b)
8193
- v();
8194
- else if (b) {
8195
- const F = setInterval(() => {
8196
- u.current && u.current.isReady && (clearInterval(F), v());
8206
+ if (u.current && u.current.isReady && v)
8207
+ R();
8208
+ else if (v) {
8209
+ const M = setInterval(() => {
8210
+ u.current && u.current.isReady && (clearInterval(M), R());
8197
8211
  }, 100);
8198
8212
  setTimeout(() => {
8199
- clearInterval(F);
8213
+ clearInterval(M);
8200
8214
  }, 5e3);
8201
8215
  }
8202
8216
  }
8203
- }, [L]), de = O(() => {
8204
- const b = B.current || { modules: [] };
8205
- if (b.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8217
+ }, [O]), de = D(() => {
8218
+ const v = P.current || { modules: [] };
8219
+ if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8206
8220
  a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8207
8221
  type: "lessonStart",
8208
8222
  moduleIndex: a.current.currentModuleIndex,
@@ -8210,66 +8224,66 @@ const ft = Me(({
8210
8224
  }), d.current.onLessonStart({
8211
8225
  moduleIndex: a.current.currentModuleIndex,
8212
8226
  lessonIndex: a.current.currentLessonIndex,
8213
- lesson: R()
8227
+ lesson: I()
8214
8228
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8215
8229
  else if (a.current.currentModuleIndex > 0) {
8216
- const P = b.modules[a.current.currentModuleIndex - 1];
8217
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (P?.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({
8230
+ const F = v.modules[a.current.currentModuleIndex - 1];
8231
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (F?.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({
8218
8232
  type: "lessonStart",
8219
8233
  moduleIndex: a.current.currentModuleIndex,
8220
8234
  lessonIndex: a.current.currentLessonIndex
8221
8235
  }), d.current.onLessonStart({
8222
8236
  moduleIndex: a.current.currentModuleIndex,
8223
8237
  lessonIndex: a.current.currentLessonIndex,
8224
- lesson: R()
8238
+ lesson: I()
8225
8239
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8226
8240
  }
8227
- }, [R]), ee = O(() => {
8241
+ }, [I]), te = D(() => {
8228
8242
  a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
8229
- }, []), be = O((b) => {
8230
- console.log("Avatar is ready!", b);
8231
- const v = R(), F = v?.avatar_script || v?.body;
8232
- h && F && setTimeout(() => {
8243
+ }, []), be = D((v) => {
8244
+ console.log("Avatar is ready!", v);
8245
+ const R = I(), M = R?.avatar_script || R?.body;
8246
+ h && M && setTimeout(() => {
8233
8247
  c.current && c.current();
8234
8248
  }, 10);
8235
- }, [h, R]);
8249
+ }, [h, I]);
8236
8250
  Xe(() => {
8237
- c.current = X, g.current = j, x.current = z, f.current = E, k.current = Y, D.current = S, p.current = oe;
8251
+ c.current = Y, g.current = B, b.current = N, x.current = E, S.current = w, U.current = L, p.current = ee;
8238
8252
  }), Fe(r, () => ({
8239
8253
  // Curriculum control methods
8240
- startTeaching: X,
8241
- startQuestions: S,
8242
- handleAnswerSelect: oe,
8254
+ startTeaching: Y,
8255
+ startQuestions: L,
8256
+ handleAnswerSelect: ee,
8243
8257
  handleCodeTestResult: le,
8244
8258
  nextQuestion: E,
8245
8259
  previousQuestion: ge,
8246
- nextLesson: j,
8260
+ nextLesson: B,
8247
8261
  previousLesson: de,
8248
- completeLesson: z,
8249
- completeCurriculum: Y,
8250
- resetCurriculum: ee,
8262
+ completeLesson: N,
8263
+ completeCurriculum: w,
8264
+ resetCurriculum: te,
8251
8265
  getState: () => ({ ...a.current }),
8252
- getCurrentQuestion: () => L(),
8253
- getCurrentLesson: () => R(),
8266
+ getCurrentQuestion: () => O(),
8267
+ getCurrentLesson: () => I(),
8254
8268
  // Direct access to avatar ref (always returns current value)
8255
8269
  getAvatarRef: () => u.current,
8256
8270
  // Convenience methods that delegate to avatar (always check current ref)
8257
- speakText: async (b, v = {}) => {
8271
+ speakText: async (v, R = {}) => {
8258
8272
  await u.current?.resumeAudioContext?.();
8259
- const F = T.current || { lipsyncLang: "en" };
8260
- u.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || F.lipsyncLang });
8273
+ const M = H.current || { lipsyncLang: "en" };
8274
+ u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || M.lipsyncLang });
8261
8275
  },
8262
8276
  resumeAudioContext: async () => {
8263
8277
  if (u.current?.resumeAudioContext)
8264
8278
  return await u.current.resumeAudioContext();
8265
- const b = u.current?.talkingHead;
8266
- if (b?.audioCtx) {
8267
- const v = b.audioCtx;
8268
- if (v.state === "suspended" || v.state === "interrupted")
8279
+ const v = u.current?.talkingHead;
8280
+ if (v?.audioCtx) {
8281
+ const R = v.audioCtx;
8282
+ if (R.state === "suspended" || R.state === "interrupted")
8269
8283
  try {
8270
- await v.resume(), console.log("Audio context resumed via talkingHead");
8271
- } catch (F) {
8272
- console.warn("Failed to resume audio context:", F);
8284
+ await R.resume(), console.log("Audio context resumed via talkingHead");
8285
+ } catch (M) {
8286
+ console.warn("Failed to resume audio context:", M);
8273
8287
  }
8274
8288
  } else
8275
8289
  console.warn("Audio context not available yet");
@@ -8278,22 +8292,22 @@ const ft = Me(({
8278
8292
  pauseSpeaking: () => u.current?.pauseSpeaking(),
8279
8293
  resumeSpeaking: async () => await u.current?.resumeSpeaking(),
8280
8294
  isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
8281
- setMood: (b) => u.current?.setMood(b),
8282
- playAnimation: (b, v) => u.current?.playAnimation(b, v),
8283
- setBodyMovement: (b) => u.current?.setBodyMovement(b),
8284
- setMovementIntensity: (b) => u.current?.setMovementIntensity(b),
8295
+ setMood: (v) => u.current?.setMood(v),
8296
+ playAnimation: (v, R) => u.current?.playAnimation(v, R),
8297
+ setBodyMovement: (v) => u.current?.setBodyMovement(v),
8298
+ setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
8285
8299
  playRandomDance: () => u.current?.playRandomDance(),
8286
- playReaction: (b) => u.current?.playReaction(b),
8300
+ playReaction: (v) => u.current?.playReaction(v),
8287
8301
  playCelebration: () => u.current?.playCelebration(),
8288
- setShowFullAvatar: (b) => u.current?.setShowFullAvatar(b),
8289
- setTimingAdjustment: (b) => u.current?.setTimingAdjustment(b),
8302
+ setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
8303
+ setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
8290
8304
  lockAvatarPosition: () => u.current?.lockAvatarPosition(),
8291
8305
  unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8292
8306
  // Custom action trigger
8293
- triggerCustomAction: (b, v) => {
8307
+ triggerCustomAction: (v, R) => {
8294
8308
  d.current.onCustomAction({
8295
- type: b,
8296
- ...v,
8309
+ type: v,
8310
+ ...R,
8297
8311
  state: { ...a.current }
8298
8312
  });
8299
8313
  },
@@ -8301,8 +8315,8 @@ const ft = Me(({
8301
8315
  handleResize: () => u.current?.handleResize(),
8302
8316
  // Avatar readiness check (always returns current value)
8303
8317
  isAvatarReady: () => u.current?.isReady || !1
8304
- }), [X, S, oe, le, E, j, z, Y, ee, L, R]);
8305
- const Q = T.current || {
8318
+ }), [Y, L, ee, le, E, B, N, w, te, O, I]);
8319
+ const Q = H.current || {
8306
8320
  avatarUrl: "/avatars/brunette.glb",
8307
8321
  avatarBody: "F",
8308
8322
  mood: "happy",
@@ -8334,8 +8348,8 @@ const ft = Me(({
8334
8348
  onReady: be,
8335
8349
  onLoading: () => {
8336
8350
  },
8337
- onError: (b) => {
8338
- console.error("Avatar error:", b);
8351
+ onError: (v) => {
8352
+ console.error("Avatar error:", v);
8339
8353
  }
8340
8354
  }
8341
8355
  ) });
@@ -8444,7 +8458,7 @@ const Ge = {
8444
8458
  duration: 5e3,
8445
8459
  description: "Excited, energetic movement"
8446
8460
  }
8447
- }, zt = (V) => Ge[V] || null, Ct = (V) => Ge.hasOwnProperty(V);
8461
+ }, zt = (Z) => Ge[Z] || null, Ct = (Z) => Ge.hasOwnProperty(Z);
8448
8462
  export {
8449
8463
  ft as CurriculumLearning,
8450
8464
  yt as SimpleTalkingAvatar,