@sage-rsc/talking-head-react 1.1.2 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
1
  import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as D, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
- import * as f from "three";
2
+ import { forwardRef as Me, useRef as N, useState as ce, useEffect as de, useCallback as P, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
+ import * as b from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
6
6
  import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
7
- import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
7
+ import { FBXLoader as Ne } 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, re, he;
11
- const A = [0, 0, 0, 0], w = new f.Vector3(), ze = new f.Vector3(), ne = new f.Vector3(), Ce = new f.Vector3();
12
- new f.Plane();
13
- new f.Ray();
14
- new f.Euler();
15
- const ie = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
- new f.Vector3();
17
- const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
11
+ const A = [0, 0, 0, 0], z = new b.Vector3(), ze = new b.Vector3(), ie = new b.Vector3(), Ce = new b.Vector3();
12
+ new b.Plane();
13
+ new b.Ray();
14
+ new b.Euler();
15
+ const oe = new b.Quaternion(), Oe = new b.Quaternion(), fe = new b.Matrix4(), xe = new b.Matrix4();
16
+ new b.Vector3();
17
+ const He = new b.Vector3(0, 0, 1), Ke = new b.Vector3(1, 0, 0), Je = new b.Vector3(0, 1, 0), $e = new b.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -321,7 +321,7 @@ class et {
321
321
  /// Bone's parent object
322
322
  vBasis: r.position.clone(),
323
323
  // Original local position
324
- vWorld: r.parent.getWorldPosition(w).clone(),
324
+ vWorld: r.parent.getWorldPosition(z).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
- h.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Oe.setFromUnitVectors(He, w).invert()).normalize(), h.qWorldInverseYaw = ie.clone().normalize(), this.data.push(h), this.dict[u] = h;
341
+ h.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), h.qWorldInverseYaw = oe.clone().normalize(), this.data.push(h), this.dict[u] = h;
342
342
  try {
343
343
  this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
344
344
  } catch (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], w.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), w.applyMatrix4(xe), w.length() > 0.5 && (console.info("Info: Unrealistic jump of " + w.length().toFixed(2) + " meters."), w.setLength(0.5)), w.applyQuaternion(o.bone.quaternion), A[0] = w.x, A[1] = w.y, A[2] = -w.z, A[3] = w.length() / 3, o.children)
359
+ if (o = this.data[e], z.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), z.applyMatrix4(xe), z.length() > 0.5 && (console.info("Info: Unrealistic jump of " + z.length().toFixed(2) + " meters."), z.setLength(0.5)), z.applyQuaternion(o.bone.quaternion), A[0] = z.x, A[1] = z.y, A[2] = -z.z, A[3] = z.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
361
  m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
362
- if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, w.set(
362
+ if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, z.set(
363
363
  o.vBasis.x + A[0],
364
364
  o.vBasis.y + A[1],
365
365
  o.vBasis.z + A[2]
366
- ), w.applyMatrix4(fe), w.x += m[0], w.y += m[1], w.z += m[2], w.applyMatrix4(xe), A[0] += w.x - o.vBasis.x, A[1] += w.y - o.vBasis.y, A[2] += w.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
366
+ ), z.applyMatrix4(fe), z.x += m[0], z.y += m[1], z.z += m[2], z.applyMatrix4(xe), A[0] += z.x - o.vBasis.x, A[1] += z.y - o.vBasis.y, A[2] += z.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
367
367
  o.bone.position.set(
368
368
  o.vBasis.x + A[0],
369
369
  o.vBasis.y + A[1],
370
370
  o.vBasis.z - A[2]
371
371
  );
372
- else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Oe.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
372
+ else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), oe.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(oe)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), oe.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(oe)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), oe.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(oe)), 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], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (he = w.length(), re = ne.length(), !(re > m.radius + he) && (re < Math.abs(m.radius - he) || (re = (re * re + he * he - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(he * he - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), he = ze.dot(w), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
374
+ m = o.excludes[n], ie.set(0, 0, 0), m.deltaLocal && (ie.x += m.deltaLocal[0], ie.y += m.deltaLocal[1], ie.z += m.deltaLocal[2]), ie.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), z.copy(o.bone.position), !(z.distanceToSquared(ie) >= m.radiusSq) && (he = z.length(), re = ie.length(), !(re > m.radius + he) && (re < Math.abs(m.radius - he) || (re = (re * re + he * he - m.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(he * he - re * re), z.subVectors(z, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), he = ze.dot(z), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), z.add(ze)), z.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, z), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
376
376
  this.helpers.isActive && this.updateHelpers();
377
377
  }
@@ -393,7 +393,7 @@ class et {
393
393
  i || (m.excludes.bones.push(n.bone), m.excludes.radii.push(n.radius), m.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), m.excludes.objects.push(null));
394
394
  }));
395
395
  }), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, n) => {
396
- const i = new f.SphereGeometry(m.radii[n], 6, 6), s = new f.MeshBasicMaterial({
396
+ const i = new b.SphereGeometry(m.radii[n], 6, 6), s = new b.MeshBasicMaterial({
397
397
  depthTest: !1,
398
398
  depthWrite: !1,
399
399
  toneMapped: !1,
@@ -401,18 +401,18 @@ class et {
401
401
  wireframe: !0,
402
402
  color: this.opt.helperExcludesColor
403
403
  });
404
- m.objects[n] = new f.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
404
+ m.objects[n] = new b.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
405
405
  m.deltaLocals[n][0],
406
406
  m.deltaLocals[n][1],
407
407
  m.deltaLocals[n][2]
408
408
  );
409
409
  }), m = this.helpers.points, m.bones.length) {
410
410
  this.helpers.isActive = !0;
411
- const e = new f.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
412
- e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
413
- const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
- e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
415
- const l = new f.PointsMaterial({
411
+ const e = new b.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
412
+ e.setAttribute("position", new b.Float32BufferAttribute(n, 3));
413
+ const i = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
+ e.setAttribute("color", new b.Float32BufferAttribute(o, 3));
415
+ const l = new b.PointsMaterial({
416
416
  depthTest: !1,
417
417
  depthWrite: !1,
418
418
  toneMapped: !1,
@@ -420,21 +420,21 @@ class et {
420
420
  size: 0.2,
421
421
  vertexColors: !0
422
422
  });
423
- m.object = new f.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
423
+ m.object = new b.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
424
424
  }
425
425
  if (m = this.helpers.lines, m.bones.length) {
426
- const e = new f.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
- e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
428
- const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
- e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
430
- const l = new f.LineBasicMaterial({
426
+ const e = new b.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
+ e.setAttribute("position", new b.Float32BufferAttribute(n, 3));
428
+ const i = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
+ e.setAttribute("color", new b.Float32BufferAttribute(o, 3));
430
+ const l = new b.LineBasicMaterial({
431
431
  vertexColors: !0,
432
432
  depthTest: !1,
433
433
  depthWrite: !1,
434
434
  toneMapped: !1,
435
435
  transparent: !0
436
436
  });
437
- m.object = new f.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
437
+ m.object = new b.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
438
438
  }
439
439
  }
440
440
  /**
@@ -445,14 +445,14 @@ class et {
445
445
  xe.copy(this.armature.matrixWorld).invert();
446
446
  const t = m.object.geometry.getAttribute("position");
447
447
  for (let e = 0, n = m.bones.length; e < n; e++)
448
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(e, w.x, w.y, w.z);
448
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(e, z.x, z.y, z.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), w.setFromMatrixPosition(fe), t.setXYZ(n, w.x, w.y, w.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n + 1, w.x, w.y, w.z);
455
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n, z.x, z.y, z.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n + 1, z.x, z.y, z.z);
456
456
  t.needsUpdate = !0, m.object.updateMatrixWorld();
457
457
  }
458
458
  }
@@ -608,8 +608,8 @@ class tt {
608
608
  for (let a = 0; a < i / 2; a++) {
609
609
  const c = n[(u + a) * 2], d = n[(u + a) * 2 + 1], g = n[(u + a + i / 2) * 2] * r - n[(u + a + i / 2) * 2 + 1] * h, x = n[(u + a + i / 2) * 2] * h + n[(u + a + i / 2) * 2 + 1] * r;
610
610
  n[(u + a) * 2] = c + g, n[(u + a) * 2 + 1] = d + x, n[(u + a + i / 2) * 2] = c - g, n[(u + a + i / 2) * 2 + 1] = d - x;
611
- const b = r * o - h * l, I = r * l + h * o;
612
- r = b, h = I;
611
+ const f = r * o - h * l, R = r * l + h * o;
612
+ r = f, h = R;
613
613
  }
614
614
  }
615
615
  }
@@ -2629,14 +2629,14 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ht,
2631
2631
  lt: ct
2632
- }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2633
- new f.Matrix4();
2634
- new f.Matrix4();
2635
- new f.Vector3();
2636
- new f.Vector3(0, 0, 1);
2637
- const mt = new f.Vector3(1, 0, 0);
2638
- new f.Vector3(0, 1, 0);
2639
- new f.Vector3(0, 0, 1);
2632
+ }, Q = new b.Quaternion(), V = new b.Euler(), ve = new b.Vector3(), Re = new b.Vector3(), We = new b.Box3();
2633
+ new b.Matrix4();
2634
+ new b.Matrix4();
2635
+ new b.Vector3();
2636
+ new b.Vector3(0, 0, 1);
2637
+ const mt = new b.Vector3(1, 0, 0);
2638
+ new b.Vector3(0, 1, 0);
2639
+ new b.Vector3(0, 0, 1);
2640
2640
  class Be {
2641
2641
  /**
2642
2642
  * Avatar.
@@ -4073,22 +4073,22 @@ class Be {
4073
4073
  if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
4074
4074
  this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
4075
4075
  else {
4076
- this.renderer = new f.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = f.SRGBColorSpace, this.renderer.toneMapping = f.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new f.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new f.Scene(), this.lightAmbient = new f.AmbientLight(
4077
- new f.Color(this.opt.lightAmbientColor),
4076
+ this.renderer = new b.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = b.SRGBColorSpace, this.renderer.toneMapping = b.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new b.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new b.Scene(), this.lightAmbient = new b.AmbientLight(
4077
+ new b.Color(this.opt.lightAmbientColor),
4078
4078
  this.opt.lightAmbientIntensity
4079
- ), this.lightDirect = new f.DirectionalLight(
4080
- new f.Color(this.opt.lightDirectColor),
4079
+ ), this.lightDirect = new b.DirectionalLight(
4080
+ new b.Color(this.opt.lightDirectColor),
4081
4081
  this.opt.lightDirectIntensity
4082
- ), this.lightSpot = new f.SpotLight(
4083
- new f.Color(this.opt.lightSpotColor),
4082
+ ), this.lightSpot = new b.SpotLight(
4083
+ new b.Color(this.opt.lightSpotColor),
4084
4084
  this.opt.lightSpotIntensity,
4085
4085
  0,
4086
4086
  this.opt.lightSpotDispersion
4087
4087
  ), this.setLighting(this.opt);
4088
- const l = new f.PMREMGenerator(this.renderer);
4088
+ const l = new b.PMREMGenerator(this.renderer);
4089
4089
  l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new qe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
4090
4090
  }
4091
- this.ikMesh = new f.SkinnedMesh();
4091
+ this.ikMesh = new b.SkinnedMesh();
4092
4092
  const s = {
4093
4093
  LeftShoulder: null,
4094
4094
  LeftArm: "LeftShoulder",
@@ -4102,9 +4102,9 @@ class Be {
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, o = [];
4104
4104
  Object.entries(s).forEach((l, u) => {
4105
- const r = new f.Bone();
4105
+ const r = new b.Bone();
4106
4106
  r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
4107
- }), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4107
+ }), this.ikMesh.bind(new b.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4108
4108
  }
4109
4109
  /**
4110
4110
  * Helper that re/creates the audio context and the other nodes.
@@ -4194,7 +4194,7 @@ class Be {
4194
4194
  for (let [n, i] of Object.entries(t)) {
4195
4195
  const s = n.split(".");
4196
4196
  let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, u = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, u, i.w).normalize());
4197
+ s[1] === "position" || s[1] === "scale" ? e[n] = new b.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new b.Quaternion().setFromEuler(new b.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new b.Quaternion(o, l, u, i.w).normalize());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4226,15 +4226,15 @@ class Be {
4226
4226
  for (const [r, h] of Object.entries(n))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4228
4228
  const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4229
- l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
4229
+ l || (l = new b.Float32BufferAttribute(c.count * 3, 3), d && (u = new b.Float32BufferAttribute(c.count * 3, 3)));
4230
4230
  for (let g = 0; g < c.count; g++) {
4231
- const x = l.getX(g) + c.getX(g) * h, b = l.getY(g) + c.getY(g) * h, I = l.getZ(g) + c.getZ(g) * h;
4232
- l.setXYZ(g, x, b, I);
4231
+ const x = l.getX(g) + c.getX(g) * h, f = l.getY(g) + c.getY(g) * h, R = l.getZ(g) + c.getZ(g) * h;
4232
+ l.setXYZ(g, x, f, R);
4233
4233
  }
4234
4234
  if (d)
4235
4235
  for (let g = 0; g < c.count; g++) {
4236
- const x = u.getX(g) + d.getX(g) * h, b = u.getY(g) + d.getY(g) * h, I = u.getZ(g) + d.getZ(g) * h;
4237
- u.setXYZ(g, x, b, I);
4236
+ const x = u.getX(g) + d.getX(g) * h, f = u.getY(g) + d.getY(g) * h, R = u.getZ(g) + d.getZ(g) * h;
4237
+ u.setXYZ(g, x, f, R);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4314,7 +4314,7 @@ class Be {
4314
4314
  console.error("Dynamic bones setup failed: " + r);
4315
4315
  }
4316
4316
  this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
4317
- const u = new f.Vector3();
4317
+ const u = new b.Vector3();
4318
4318
  this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4319
4319
  }
4320
4320
  /**
@@ -4358,14 +4358,14 @@ class Be {
4358
4358
  default:
4359
4359
  a += 12, h = h * a;
4360
4360
  }
4361
- r = r * a, this.controlsEnd = new f.Vector3(r, h, 0), this.cameraEnd = new f.Vector3(r, h, a).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4361
+ r = r * a, this.controlsEnd = new b.Vector3(r, h, 0), this.cameraEnd = new b.Vector3(r, h, a).applyEuler(new b.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4362
4362
  }
4363
4363
  /**
4364
4364
  * Change light colors and intensities.
4365
4365
  * @param {Object} opt Options
4366
4366
  */
4367
4367
  setLighting(t) {
4368
- this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new f.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new f.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new f.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new f.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4368
+ this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new b.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new b.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new b.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new b.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4369
4369
  }
4370
4370
  /**
4371
4371
  * Render scene.
@@ -4480,7 +4480,7 @@ class Be {
4480
4480
  return Object.entries(t).forEach((i, s) => {
4481
4481
  const o = i[0].split(".");
4482
4482
  if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
4483
- const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new b.Euler().setFromQuaternion(i[1]) : i[1];
4484
4484
  n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(u.x * e) / e, n += ", y:" + Math.round(u.y * e) / e, n += ", z:" + Math.round(u.z * e) / e, n += "}";
4485
4485
  }
4486
4486
  }), n += "}", n;
@@ -5108,8 +5108,8 @@ class Be {
5108
5108
  else {
5109
5109
  g.newvalue = d[i + 1];
5110
5110
  const x = a.ts[i + 1] - a.ts[i];
5111
- let b = 1;
5112
- x > 1e-4 && (b = (this.animClock - a.ts[i]) / x), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * d[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5111
+ let f = 1;
5112
+ x > 1e-4 && (f = (this.animClock - a.ts[i]) / x), f < 1 && (g.easing && (f = g.easing(f)), g.newvalue = (1 - f) * d[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5113
5113
  }
5114
5114
  if (l)
5115
5115
  switch (c) {
@@ -5157,7 +5157,7 @@ class Be {
5157
5157
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
5158
5158
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5159
5159
  ]
5160
- }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5160
+ }, i.x ? new b.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5161
5161
  break;
5162
5162
  case "handRight":
5163
5163
  this.ikSolve({
@@ -5169,7 +5169,7 @@ class Be {
5169
5169
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
5170
5170
  { link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5171
5171
  ]
5172
- }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5172
+ }, i.x ? new b.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  }
5175
5175
  if ((u || r) && (V.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), V.x = Math.max(-0.9, Math.min(0.9, 2 * V.x - 0.5)), V.y = Math.max(-0.9, Math.min(0.9, -2.5 * V.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: V.x < 0 ? -V.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: V.x < 0 ? 0 : V.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
@@ -5198,7 +5198,7 @@ class Be {
5198
5198
  else {
5199
5199
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5200
5200
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5201
- let a = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5201
+ let a = new b.Spherical().setFromVector3(this.cameraStart), c = new b.Spherical().setFromVector3(this.cameraEnd);
5202
5202
  a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5203
5203
  }
5204
5204
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
@@ -5262,12 +5262,12 @@ class Be {
5262
5262
  e = e || {};
5263
5263
  const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5264
5264
  let h = "", a = "", c = 0, d = [], g = [];
5265
- const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5266
- for (let b = 0; b < x.length; b++) {
5267
- const I = b === x.length - 1, B = x[b].match(l);
5268
- let p = x[b].match(s);
5269
- const M = x[b].match(u), z = x[b].match(o);
5270
- if (p && !I && !M && x[b + 1].match(s) && (p = !1), n && (h += x[b]), B && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5265
+ const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
5266
+ for (let f = 0; f < x.length; f++) {
5267
+ const R = f === x.length - 1, F = x[f].match(l);
5268
+ let p = x[f].match(s);
5269
+ const H = x[f].match(u), k = x[f].match(o);
5270
+ if (p && !R && !H && x[f + 1].match(s) && (p = !1), n && (h += x[f]), F && (!i || i.every((y) => f < y[0] || f > y[1])) && (a += x[f]), (k || p || R) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5271
5271
  mark: c,
5272
5272
  word: a
5273
5273
  })), h.length && (g.push({
@@ -5280,28 +5280,28 @@ class Be {
5280
5280
  }), h = ""), a.length)) {
5281
5281
  const y = this.lipsyncWordsToVisemes(a, r);
5282
5282
  if (y && y.visemes && y.visemes.length) {
5283
- const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
- for (let P = 0; P < y.visemes.length; P++)
5283
+ const T = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
+ for (let E = 0; E < y.visemes.length; E++)
5285
5285
  g.push({
5286
5286
  mark: c,
5287
5287
  template: { name: "viseme" },
5288
- ts: [(y.times[P] - 0.6) / E, (y.times[P] + 0.5) / E, (y.times[P] + y.durations[P] + 0.5) / E],
5288
+ ts: [(y.times[E] - 0.6) / T, (y.times[E] + 0.5) / T, (y.times[E] + y.durations[E] + 0.5) / T],
5289
5289
  vs: {
5290
- ["viseme_" + y.visemes[P]]: [null, y.visemes[P] === "PP" || y.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5290
+ ["viseme_" + y.visemes[E]]: [null, y.visemes[E] === "PP" || y.visemes[E] === "FF" ? 0.9 : 0.6, 0]
5291
5291
  }
5292
5292
  });
5293
5293
  }
5294
5294
  a = "", c++;
5295
5295
  }
5296
- if (p || I) {
5297
- if (d.length || I && g.length) {
5296
+ if (p || R) {
5297
+ if (d.length || R && g.length) {
5298
5298
  const y = {
5299
5299
  anim: g
5300
5300
  };
5301
5301
  n && (y.onSubtitles = n), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], a = "", c = 0, g = [];
5302
5302
  }
5303
- if (M) {
5304
- let y = this.animEmojis[x[b]];
5303
+ if (H) {
5304
+ let y = this.animEmojis[x[f]];
5305
5305
  y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5306
5306
  }
5307
5307
  this.speechQueue.push({ break: 100 });
@@ -5397,13 +5397,13 @@ class Be {
5397
5397
  const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(h, Math.max(0, h - c.visemes.length * 150));
5398
5398
  let x = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
5399
5399
  if (h = Math.min(h, c.visemes.length * 200), d > 0)
5400
- for (let b = 0; b < c.visemes.length; b++) {
5401
- const I = r + c.times[b] / d * h, B = c.durations[b] / d * h;
5400
+ for (let f = 0; f < c.visemes.length; f++) {
5401
+ const R = r + c.times[f] / d * h, F = c.durations[f] / d * h;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
5404
+ ts: [R - Math.min(60, 2 * F / 3), R + Math.min(25, F / 2), R + F + Math.min(60, F / 2)],
5405
5405
  vs: {
5406
- ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5406
+ ["viseme_" + c.visemes[f]]: [null, c.visemes[f] === "PP" || c.visemes[f] === "FF" ? 0.9 : x, 0]
5407
5407
  }
5408
5408
  });
5409
5409
  }
@@ -5483,34 +5483,34 @@ class Be {
5483
5483
  s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, r));
5484
5484
  const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
5485
  if (a && h.length > 0) {
5486
- const p = h.find((M) => M.name.includes(a) || M.lang === o);
5486
+ const p = h.find((H) => H.name.includes(a) || H.lang === o);
5487
5487
  p && (s.voice = p);
5488
5488
  }
5489
- const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(x, g);
5489
+ const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), f = this.lipsyncWordsToVisemes(x, g);
5490
5490
  console.log("Browser TTS Lip-sync Debug:", {
5491
5491
  text: i,
5492
5492
  lipsyncLang: g,
5493
5493
  processedText: x,
5494
- lipsyncData: b,
5495
- hasVisemes: b && b.visemes && b.visemes.length > 0,
5494
+ lipsyncData: f,
5495
+ hasVisemes: f && f.visemes && f.visemes.length > 0,
5496
5496
  estimatedDuration: c
5497
5497
  });
5498
- const I = [];
5499
- if (b && b.visemes && b.visemes.length > 0) {
5500
- const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5501
- for (let M = 0; M < b.visemes.length; M++) {
5502
- const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
5503
- I.push({
5498
+ const R = [];
5499
+ if (f && f.visemes && f.visemes.length > 0) {
5500
+ const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5501
+ for (let H = 0; H < f.visemes.length; H++) {
5502
+ const k = f.visemes[H], y = f.times[H] / p, T = f.durations[H] / p, E = y * c, O = T * c;
5503
+ R.push({
5504
5504
  template: { name: "viseme" },
5505
- ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
5505
+ ts: [E - Math.min(60, 2 * O / 3), E + Math.min(25, O / 2), E + O + Math.min(60, O / 2)],
5506
5506
  vs: {
5507
- ["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
5507
+ ["viseme_" + k]: [null, k === "PP" || k === "FF" ? 0.9 : 0.6, 0]
5508
5508
  }
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const B = [...t.anim, ...I];
5513
- this.audioPlaylist.push({ anim: B, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5512
+ const F = [...t.anim, ...R];
5513
+ this.audioPlaylist.push({ anim: F, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5514
5514
  e();
5515
5515
  }, s.onerror = (p) => {
5516
5516
  console.error("Speech synthesis error:", p.error), n(p.error);
@@ -5576,15 +5576,15 @@ class Be {
5576
5576
  console.error("Text-based lip-sync failed, using fallback:", c);
5577
5577
  const d = e.toLowerCase().split(/\s+/), g = [];
5578
5578
  for (const x of d)
5579
- for (const b of x) {
5580
- let I = "aa";
5581
- "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5579
+ for (const f of x) {
5580
+ let R = "aa";
5581
+ "aeiou".includes(f) ? R = "aa" : "bp".includes(f) ? R = "PP" : "fv".includes(f) ? R = "FF" : "st".includes(f) ? R = "SS" : "dln".includes(f) ? R = "DD" : "kg".includes(f) ? R = "kk" : "rw".includes(f) && (R = "RR"), g.push(R);
5582
5582
  }
5583
5583
  r = {
5584
- visemes: g.map((x, b) => ({
5584
+ visemes: g.map((x, f) => ({
5585
5585
  viseme: x,
5586
- startTime: b * l.duration / g.length,
5587
- endTime: (b + 1) * l.duration / g.length,
5586
+ startTime: f * l.duration / g.length,
5587
+ endTime: (f + 1) * l.duration / g.length,
5588
5588
  duration: l.duration / g.length,
5589
5589
  intensity: 0.6
5590
5590
  })),
@@ -5609,12 +5609,12 @@ class Be {
5609
5609
  if (r.visemes && r.visemes.length > 0) {
5610
5610
  console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5611
5611
  for (let c = 0; c < r.visemes.length; c++) {
5612
- const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5612
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, f = d.intensity;
5613
5613
  h.push({
5614
5614
  template: { name: "viseme" },
5615
5615
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5616
5616
  vs: {
5617
- ["viseme_" + d.viseme]: [null, b, 0]
5617
+ ["viseme_" + d.viseme]: [null, f, 0]
5618
5618
  }
5619
5619
  });
5620
5620
  }
@@ -5674,15 +5674,15 @@ class Be {
5674
5674
  console.error("Text-based lip-sync failed, using fallback:", c);
5675
5675
  const d = e.toLowerCase().split(/\s+/), g = [];
5676
5676
  for (const x of d)
5677
- for (const b of x) {
5678
- let I = "aa";
5679
- "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5677
+ for (const f of x) {
5678
+ let R = "aa";
5679
+ "aeiou".includes(f) ? R = "aa" : "bp".includes(f) ? R = "PP" : "fv".includes(f) ? R = "FF" : "st".includes(f) ? R = "SS" : "dln".includes(f) ? R = "DD" : "kg".includes(f) ? R = "kk" : "rw".includes(f) && (R = "RR"), g.push(R);
5680
5680
  }
5681
5681
  r = {
5682
- visemes: g.map((x, b) => ({
5682
+ visemes: g.map((x, f) => ({
5683
5683
  viseme: x,
5684
- startTime: b * l.duration / g.length,
5685
- endTime: (b + 1) * l.duration / g.length,
5684
+ startTime: f * l.duration / g.length,
5685
+ endTime: (f + 1) * l.duration / g.length,
5686
5686
  duration: l.duration / g.length,
5687
5687
  intensity: 0.6
5688
5688
  })),
@@ -5707,12 +5707,12 @@ class Be {
5707
5707
  if (r.visemes && r.visemes.length > 0) {
5708
5708
  console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5709
5709
  for (let c = 0; c < r.visemes.length; c++) {
5710
- const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5710
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, f = d.intensity;
5711
5711
  h.push({
5712
5712
  template: { name: "viseme" },
5713
5713
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5714
5714
  vs: {
5715
- ["viseme_" + d.viseme]: [null, b, 0]
5715
+ ["viseme_" + d.viseme]: [null, f, 0]
5716
5716
  }
5717
5717
  });
5718
5718
  }
@@ -6146,7 +6146,7 @@ class Be {
6146
6146
  */
6147
6147
  lookAtCamera(t) {
6148
6148
  let e;
6149
- if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6149
+ if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6150
6150
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6151
6151
  if (this.avatar.avatarIgnoreCamera) {
6152
6152
  this.lookAhead(t);
@@ -6160,15 +6160,15 @@ class Be {
6160
6160
  return;
6161
6161
  }
6162
6162
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
6163
- const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6163
+ const n = new b.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
6164
  V.set(s, i, 0, "YXZ");
6165
- const l = new f.Quaternion().setFromEuler(V), u = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6165
+ const l = new b.Quaternion().setFromEuler(V), u = new b.Quaternion().copy(l).multiply(Q.clone().invert());
6166
6166
  V.setFromQuaternion(u, "YXZ");
6167
6167
  let r = V.x / (40 / 24) + 0.2, h = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6168
6168
  if (t) {
6169
- let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6169
+ let x = this.animQueue.findIndex((R) => R.template.name === "lookat");
6170
6170
  x !== -1 && this.animQueue.splice(x, 1);
6171
- const b = {
6171
+ const f = {
6172
6172
  name: "lookat",
6173
6173
  dt: [750, t],
6174
6174
  vs: {
@@ -6183,7 +6183,7 @@ class Be {
6183
6183
  headMove: [0]
6184
6184
  }
6185
6185
  };
6186
- this.animQueue.push(this.animFactory(b));
6186
+ this.animQueue.push(this.animFactory(f));
6187
6187
  }
6188
6188
  }
6189
6189
  /**
@@ -6196,23 +6196,23 @@ class Be {
6196
6196
  if (!this.camera) return;
6197
6197
  const i = this.nodeAvatar.getBoundingClientRect();
6198
6198
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6199
- const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6199
+ const s = new b.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new b.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new b.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
6201
  let u = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6202
6202
  t === null && (t = u), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(Q);
6203
- let h = V.x / (40 / 24), a = V.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6204
- b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
6205
- let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6203
+ let h = V.x / (40 / 24), a = V.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, R = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6204
+ f = Math.min(0.6, Math.max(-0.3, f)), R = Math.min(0.8, Math.max(-0.8, R));
6205
+ let F = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
- let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
- M !== -1 && this.animQueue.splice(M, 1);
6209
- const z = {
6207
+ let H = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
+ H !== -1 && this.animQueue.splice(H, 1);
6209
+ const k = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [b + B],
6214
- bodyRotateY: [I + p],
6215
- eyesRotateX: [-3 * B + 0.1],
6213
+ bodyRotateX: [f + F],
6214
+ bodyRotateY: [R + p],
6215
+ eyesRotateX: [-3 * F + 0.1],
6216
6216
  eyesRotateY: [-5 * p],
6217
6217
  browInnerUp: [[0, 0.7]],
6218
6218
  mouthLeft: [[0, 0.7]],
@@ -6221,7 +6221,7 @@ class Be {
6221
6221
  headMove: [0]
6222
6222
  }
6223
6223
  };
6224
- this.animQueue.push(this.animFactory(z));
6224
+ this.animQueue.push(this.animFactory(k));
6225
6225
  }
6226
6226
  }
6227
6227
  /**
@@ -6232,14 +6232,14 @@ class Be {
6232
6232
  */
6233
6233
  touchAt(t, e) {
6234
6234
  if (!this.camera) return;
6235
- const n = this.nodeAvatar.getBoundingClientRect(), i = new f.Vector2(
6235
+ const n = this.nodeAvatar.getBoundingClientRect(), i = new b.Vector2(
6236
6236
  (t - n.left) / n.width * 2 - 1,
6237
6237
  -((e - n.top) / n.height) * 2 + 1
6238
- ), s = new f.Raycaster();
6238
+ ), s = new b.Raycaster();
6239
6239
  s.setFromCamera(i, this.camera);
6240
6240
  const o = s.intersectObject(this.armature);
6241
6241
  if (o.length > 0) {
6242
- const l = o[0].point, u = new f.Vector3(), r = new f.Vector3();
6242
+ const l = o[0].point, u = new b.Vector3(), r = new b.Vector3();
6243
6243
  this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(r);
6244
6244
  const h = u.distanceToSquared(l), a = r.distanceToSquared(l);
6245
6245
  h < a ? (this.ikSolve({
@@ -6283,7 +6283,7 @@ class Be {
6283
6283
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
6284
6284
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
6285
6285
  ]
6286
- }, new f.Vector3(
6286
+ }, new b.Vector3(
6287
6287
  this.gaussianRandom(0, 0.5),
6288
6288
  this.gaussianRandom(-0.8, -0.2),
6289
6289
  this.gaussianRandom(0, 0.5)
@@ -6295,15 +6295,15 @@ class Be {
6295
6295
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
6296
6296
  { link: "RightArm" }
6297
6297
  ]
6298
- }, new f.Vector3(
6298
+ }, new b.Vector3(
6299
6299
  this.gaussianRandom(-0.5, 0),
6300
6300
  this.gaussianRandom(-0.8, -0.2),
6301
6301
  this.gaussianRandom(0, 0.5)
6302
6302
  ), !0);
6303
6303
  const n = [], i = [];
6304
6304
  n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
6305
- "LeftHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, -1 - Math.random(), 0)),
6306
- "RightHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, 1 + Math.random(), 0))
6305
+ "LeftHand.quaternion": new b.Quaternion().setFromEuler(new b.Euler(0, -1 - Math.random(), 0)),
6306
+ "RightHand.quaternion": new b.Quaternion().setFromEuler(new b.Euler(0, 1 + Math.random(), 0))
6307
6307
  } }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
6308
6308
  i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
6309
6309
  }), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
@@ -6402,7 +6402,7 @@ class Be {
6402
6402
  let n = t;
6403
6403
  if (n.startsWith("CC_Base_") && (n = n.replace("CC_Base_", "")), n = n.replace(/^mixamorig/i, ""), e.has(n))
6404
6404
  return n;
6405
- if (n.match(/^Spine\d+$/)) {
6405
+ if (this._mappingDebugLog || (this._mappingDebugLog = /* @__PURE__ */ new Set()), this._mappingDebugLog.size < 5 && !this._mappingDebugLog.has(t) && (this._mappingDebugLog.add(t), console.debug(`Mapping attempt: "${t}" -> "${n}" (not found in available bones)`)), n.match(/^Spine\d+$/)) {
6406
6406
  const a = n.match(/\d+/)?.[0];
6407
6407
  if (a) {
6408
6408
  const c = `Spine${parseInt(a)}`;
@@ -6432,6 +6432,9 @@ class Be {
6432
6432
  L_Middle1: "LeftHandMiddle1",
6433
6433
  L_Middle2: "LeftHandMiddle2",
6434
6434
  L_Middle3: "LeftHandMiddle3",
6435
+ L_Mid1: "LeftHandMiddle1",
6436
+ L_Mid2: "LeftHandMiddle2",
6437
+ L_Mid3: "LeftHandMiddle3",
6435
6438
  L_Ring1: "LeftHandRing1",
6436
6439
  L_Ring2: "LeftHandRing2",
6437
6440
  L_Ring3: "LeftHandRing3",
@@ -6452,6 +6455,9 @@ class Be {
6452
6455
  R_Middle1: "RightHandMiddle1",
6453
6456
  R_Middle2: "RightHandMiddle2",
6454
6457
  R_Middle3: "RightHandMiddle3",
6458
+ R_Mid1: "RightHandMiddle1",
6459
+ R_Mid2: "RightHandMiddle2",
6460
+ R_Mid3: "RightHandMiddle3",
6455
6461
  R_Ring1: "RightHandRing1",
6456
6462
  R_Ring2: "RightHandRing2",
6457
6463
  R_Ring3: "RightHandRing3",
@@ -6474,7 +6480,9 @@ class Be {
6474
6480
  if (e.has(a))
6475
6481
  return a;
6476
6482
  }
6477
- const s = n.toLowerCase(), o = s.match(/^[rl]_index(\d+)$/);
6483
+ const s = n.toLowerCase();
6484
+ n.charAt(0).toUpperCase() + n.slice(1).toLowerCase();
6485
+ const o = s.match(/^[rl]_index(\d+)$/);
6478
6486
  if (o) {
6479
6487
  const a = o[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandIndex${a}`;
6480
6488
  if (e.has(d))
@@ -6492,7 +6500,7 @@ class Be {
6492
6500
  if (e.has(d))
6493
6501
  return d;
6494
6502
  }
6495
- const r = s.match(/^[rl]_middle(\d+)$/);
6503
+ const r = s.match(/^[rl]_(?:middle|mid)(\d+)$/);
6496
6504
  if (r) {
6497
6505
  const a = r[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandMiddle${a}`;
6498
6506
  if (e.has(d))
@@ -6509,6 +6517,8 @@ class Be {
6509
6517
  if (e.has(c))
6510
6518
  return c;
6511
6519
  }
6520
+ if (s.includes("upperarmtwist") || s.includes("forearmtwist") || s.includes("ribstwist") || s.includes("breast") || s.includes("twist"))
6521
+ return null;
6512
6522
  if (s.match(/^[rl]_forearm/)) {
6513
6523
  const c = `${s.startsWith("r") ? "Right" : "Left"}ForeArm`;
6514
6524
  if (e.has(c))
@@ -6533,11 +6543,39 @@ class Be {
6533
6543
  */
6534
6544
  filterAnimationTracks(t, e) {
6535
6545
  const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
6536
- return t.tracks.forEach((o) => {
6546
+ return this._loggedAvailableBones || (console.log(
6547
+ "Available avatar bones:",
6548
+ Array.from(e).sort().slice(0, 50).join(", "),
6549
+ e.size > 50 ? `... (${e.size} total)` : ""
6550
+ ), this._loggedAvailableBones = !0), t.tracks.forEach((o) => {
6537
6551
  const l = o.name.split("."), u = l[0], r = l[1], h = this.mapBoneName(u, e);
6538
6552
  if (h) {
6539
6553
  const a = `${h}.${r}`, c = o.clone();
6540
- c.name = a, n.push(c), u !== h && s.set(u, h);
6554
+ c.name = a;
6555
+ const d = h.includes("Arm") || h.includes("Hand") || h.includes("Shoulder"), g = h.includes("ForeArm");
6556
+ if (d && (r === "quaternion" || r === "rotation")) {
6557
+ if (r === "quaternion" && c.values && c.values.length >= 4) {
6558
+ const x = c.times.length;
6559
+ for (let f = 0; f < x; f++) {
6560
+ const R = f * 4;
6561
+ if (R + 3 < c.values.length) {
6562
+ let F = c.values[R], p = c.values[R + 1], H = c.values[R + 2], k = c.values[R + 3];
6563
+ if (g || h.includes("Hand")) {
6564
+ const y = Math.PI, T = Math.cos(y / 2), E = Math.sin(y / 2), O = T * k - E * F, te = T * F + E * k, S = T * p - E * H, G = T * H + E * p;
6565
+ F = te, p = S, H = G, k = O;
6566
+ }
6567
+ c.values[R] = F, c.values[R + 1] = p, c.values[R + 2] = H, c.values[R + 3] = k;
6568
+ }
6569
+ }
6570
+ } else if (r === "rotation" && c.values && c.values.length >= 3) {
6571
+ const x = c.times.length;
6572
+ for (let f = 0; f < x; f++) {
6573
+ const R = f * 3;
6574
+ R + 2 < c.values.length && (g || h.includes("Hand")) && (c.values[R + 1] += Math.PI);
6575
+ }
6576
+ }
6577
+ }
6578
+ n.push(c), u !== h && s.set(u, h);
6541
6579
  } else
6542
6580
  i.add(u);
6543
6581
  }), s.size > 0 && console.info(
@@ -6548,7 +6586,7 @@ class Be {
6548
6586
  `FBX animation "${t.name}" contains tracks for ${i.size} bone(s) that couldn't be mapped:`,
6549
6587
  Array.from(i).slice(0, 10).join(", "),
6550
6588
  i.size > 10 ? "..." : ""
6551
- ), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new f.AnimationClip(t.name, t.duration, n);
6589
+ ), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new b.AnimationClip(t.name, t.duration, n);
6552
6590
  }
6553
6591
  async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
6554
6592
  if (!this.armature) return;
@@ -6558,9 +6596,9 @@ class Be {
6558
6596
  let u = this.animQueue.find((a) => a.template.name === "pose");
6559
6597
  u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6560
6598
  this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
6561
- }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6599
+ }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new b.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6562
6600
  const r = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
6563
- h.setLoop(f.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6601
+ h.setLoop(b.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6564
6602
  try {
6565
6603
  h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6566
6604
  } catch (a) {
@@ -6586,7 +6624,7 @@ class Be {
6586
6624
  } catch (c) {
6587
6625
  console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6588
6626
  }
6589
- const h = new De();
6627
+ const h = new Ne();
6590
6628
  let a;
6591
6629
  try {
6592
6630
  a = await h.loadAsync(t, e);
@@ -6618,20 +6656,20 @@ class Be {
6618
6656
  }
6619
6657
  c = g;
6620
6658
  const x = {};
6621
- c.tracks.forEach((I) => {
6622
- I.name = I.name.replaceAll("mixamorig", "");
6623
- const B = I.name.split(".");
6624
- if (B[1] === "position") {
6625
- for (let p = 0; p < I.values.length; p++)
6626
- I.values[p] = I.values[p] * s;
6627
- x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6628
- } else B[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : B[1] === "rotation" && (x[B[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6659
+ c.tracks.forEach((R) => {
6660
+ R.name = R.name.replaceAll("mixamorig", "");
6661
+ const F = R.name.split(".");
6662
+ if (F[1] === "position") {
6663
+ for (let p = 0; p < R.values.length; p++)
6664
+ R.values[p] = R.values[p] * s;
6665
+ x[R.name] = new b.Vector3(R.values[0], R.values[1], R.values[2]);
6666
+ } else F[1] === "quaternion" ? x[R.name] = new b.Quaternion(R.values[0], R.values[1], R.values[2], R.values[3]) : F[1] === "rotation" && (x[F[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(R.values[0], R.values[1], R.values[2], "XYZ")).normalize());
6629
6667
  });
6630
- const b = { props: x };
6631
- x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
6668
+ const f = { props: x };
6669
+ x["Hips.position"] && (x["Hips.position"].y < 0.5 ? f.lying = !0 : f.standing = !0), this.animClips.push({
6632
6670
  url: t + "-" + i,
6633
6671
  clip: c,
6634
- pose: b
6672
+ pose: f
6635
6673
  }), this.playAnimation(t, e, n, i, s);
6636
6674
  } else {
6637
6675
  const c = "Animation " + t + " (ndx=" + i + ") not found";
@@ -6669,14 +6707,14 @@ class Be {
6669
6707
  let l = this.animQueue.find((u) => u.template.name === "pose");
6670
6708
  l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
6671
6709
  } else {
6672
- let u = await new De().loadAsync(t, e);
6710
+ let u = await new Ne().loadAsync(t, e);
6673
6711
  if (u && u.animations && u.animations[i]) {
6674
6712
  let r = u.animations[i];
6675
6713
  const h = {};
6676
6714
  r.tracks.forEach((c) => {
6677
6715
  c.name = c.name.replaceAll("mixamorig", "");
6678
6716
  const d = c.name.split(".");
6679
- d[1] === "position" ? h[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6717
+ d[1] === "position" ? h[c.name] = new b.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new b.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6680
6718
  });
6681
6719
  const a = { props: h };
6682
6720
  h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6709,7 +6747,7 @@ class Be {
6709
6747
  if (s) {
6710
6748
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6711
6749
  let l = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
6712
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6750
+ l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
6713
6751
  for (let [u, r] of Object.entries(this.gesture))
6714
6752
  r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(r), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
6715
6753
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
@@ -6724,7 +6762,7 @@ class Be {
6724
6762
  const c = [];
6725
6763
  for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6726
6764
  const d = o.template?.rescale || c.map((x) => x / h), g = e * 1e3 - h;
6727
- l.ts = l.ts.map((x, b, I) => b === 0 ? u : I[b - 1] + c[b - 1] + d[b - 1] * g);
6765
+ l.ts = l.ts.map((x, f, R) => f === 0 ? u : R[f - 1] + c[f - 1] + d[f - 1] * g);
6728
6766
  } else {
6729
6767
  const c = e * 1e3 / h;
6730
6768
  l.ts = l.ts.map((d) => u + c * (d - u));
@@ -6757,34 +6795,34 @@ class Be {
6757
6795
  * @param {numeric} [d=null] If set, apply in d milliseconds
6758
6796
  */
6759
6797
  ikSolve(t, e = null, n = !1, i = null) {
6760
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), r = new f.Quaternion(), h = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6798
+ const s = new b.Vector3(), o = new b.Vector3(), l = new b.Vector3(), u = new b.Vector3(), r = new b.Quaternion(), h = new b.Vector3(), a = new b.Vector3(), c = new b.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6761
6799
  d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
6762
6800
  const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6763
- x.forEach((I) => {
6764
- I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6801
+ x.forEach((R) => {
6802
+ R.bone = this.ikMesh.getObjectByName(R.link), R.bone.quaternion.copy(this.getPoseTemplateProp(R.link + ".quaternion"));
6765
6803
  }), d.updateMatrixWorld(!0);
6766
- const b = t.iterations || 10;
6804
+ const f = t.iterations || 10;
6767
6805
  if (e)
6768
- for (let I = 0; I < b; I++) {
6769
- let B = !1;
6770
- for (let p = 0, M = x.length; p < M; p++) {
6771
- const z = x[p].bone;
6772
- z.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
6806
+ for (let R = 0; R < f; R++) {
6807
+ let F = !1;
6808
+ for (let p = 0, H = x.length; p < H; p++) {
6809
+ const k = x[p].bone;
6810
+ k.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
6773
6811
  let y = s.dot(l);
6774
- y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[p].minAngle !== void 0 && y < x[p].minAngle && (y = x[p].minAngle), x[p].maxAngle !== void 0 && y > x[p].maxAngle && (y = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), z.quaternion.multiply(Q), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6812
+ y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[p].minAngle !== void 0 && y < x[p].minAngle && (y = x[p].minAngle), x[p].maxAngle !== void 0 && y > x[p].maxAngle && (y = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), k.quaternion.multiply(Q), k.rotation.setFromVector3(c.setFromEuler(k.rotation).clamp(new b.Vector3(
6775
6813
  x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6776
6814
  x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6777
6815
  x[p].minz !== void 0 ? x[p].minz : -1 / 0
6778
- ), new f.Vector3(
6816
+ ), new b.Vector3(
6779
6817
  x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6780
6818
  x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6781
6819
  x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6782
- ))), z.updateMatrixWorld(!0), B = !0);
6820
+ ))), k.updateMatrixWorld(!0), F = !0);
6783
6821
  }
6784
- if (!B) break;
6822
+ if (!F) break;
6785
6823
  }
6786
- i && x.forEach((I) => {
6787
- this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = i;
6824
+ i && x.forEach((R) => {
6825
+ this.poseTarget.props[R.link + ".quaternion"].copy(R.bone.quaternion), this.poseTarget.props[R.link + ".quaternion"].t = this.animClock, this.poseTarget.props[R.link + ".quaternion"].d = i;
6788
6826
  });
6789
6827
  }
6790
6828
  /**
@@ -6844,16 +6882,16 @@ function Fe() {
6844
6882
  };
6845
6883
  }
6846
6884
  function kt() {
6847
- const G = Fe(), t = [];
6848
- return Object.entries(G.voices).forEach(([e, n]) => {
6885
+ const Z = Fe(), t = [];
6886
+ return Object.entries(Z.voices).forEach(([e, n]) => {
6849
6887
  t.push({
6850
6888
  value: n,
6851
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
6889
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${Z.service})`
6852
6890
  });
6853
6891
  }), t;
6854
6892
  }
6855
6893
  const Ve = Me(({
6856
- avatarUrl: G = "/avatars/brunette.glb",
6894
+ avatarUrl: Z = "/avatars/brunette.glb",
6857
6895
  avatarBody: t = "F",
6858
6896
  mood: e = "neutral",
6859
6897
  ttsLang: n = "en",
@@ -6872,142 +6910,142 @@ const Ve = Me(({
6872
6910
  },
6873
6911
  className: g = "",
6874
6912
  style: x = {},
6875
- animations: b = {}
6876
- }, I) => {
6877
- const B = D(null), p = D(null), M = D(r), z = D(null), y = D(null), E = D(!1), P = D({ remainingText: null, originalText: null, options: null }), W = D([]), oe = D(0), [S, Z] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6913
+ animations: f = {}
6914
+ }, R) => {
6915
+ const F = N(null), p = N(null), H = N(r), k = N(null), y = N(null), T = N(!1), E = N({ remainingText: null, originalText: null, options: null }), O = N([]), te = N(0), [S, G] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6878
6916
  de(() => {
6879
- E.current = ae;
6917
+ T.current = ae;
6880
6918
  }, [ae]), de(() => {
6881
- M.current = r;
6919
+ H.current = r;
6882
6920
  }, [r]);
6883
6921
  const ee = Fe(), le = i || ee.service;
6884
- let O;
6885
- le === "browser" ? O = {
6922
+ let U;
6923
+ le === "browser" ? U = {
6886
6924
  service: "browser",
6887
6925
  endpoint: "",
6888
6926
  apiKey: null,
6889
6927
  defaultVoice: "Google US English"
6890
- } : le === "elevenlabs" ? O = {
6928
+ } : le === "elevenlabs" ? U = {
6891
6929
  service: "elevenlabs",
6892
6930
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6893
6931
  apiKey: o || ee.apiKey,
6894
6932
  defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6895
6933
  voices: ee.voices || Ie.voices
6896
- } : le === "deepgram" ? O = {
6934
+ } : le === "deepgram" ? U = {
6897
6935
  service: "deepgram",
6898
6936
  endpoint: "https://api.deepgram.com/v1/speak",
6899
6937
  apiKey: o || ee.apiKey,
6900
6938
  defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6901
6939
  voices: ee.voices || Te.voices
6902
- } : O = {
6940
+ } : U = {
6903
6941
  ...ee,
6904
6942
  // Override API key if provided via props
6905
6943
  apiKey: o !== null ? o : ee.apiKey
6906
6944
  };
6907
6945
  const v = {
6908
- url: G,
6946
+ url: Z,
6909
6947
  body: t,
6910
6948
  avatarMood: e,
6911
6949
  ttsLang: le === "browser" ? "en-US" : n,
6912
- ttsVoice: s || O.defaultVoice,
6950
+ ttsVoice: s || U.defaultVoice,
6913
6951
  lipsyncLang: "en",
6914
6952
  showFullAvatar: r,
6915
6953
  bodyMovement: l,
6916
6954
  movementIntensity: u
6917
- }, R = {
6918
- ttsEndpoint: O.endpoint,
6919
- ttsApikey: O.apiKey,
6955
+ }, I = {
6956
+ ttsEndpoint: U.endpoint,
6957
+ ttsApikey: U.apiKey,
6920
6958
  ttsService: le,
6921
6959
  lipsyncModules: ["en"],
6922
6960
  cameraView: h
6923
- }, k = T(async () => {
6924
- if (!(!B.current || p.current))
6961
+ }, w = P(async () => {
6962
+ if (!(!F.current || p.current))
6925
6963
  try {
6926
- if (Z(!0), X(null), p.current = new Be(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (N) => {
6927
- if (N.lengthComputable) {
6928
- const J = Math.min(100, Math.round(N.loaded / N.total * 100));
6964
+ if (G(!0), X(null), p.current = new Be(F.current, I), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(v, (D) => {
6965
+ if (D.lengthComputable) {
6966
+ const J = Math.min(100, Math.round(D.loaded / D.total * 100));
6929
6967
  c(J);
6930
6968
  }
6931
- }), await new Promise((N) => {
6969
+ }), await new Promise((D) => {
6932
6970
  const J = () => {
6933
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? N() : setTimeout(J, 100);
6971
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? D() : setTimeout(J, 100);
6934
6972
  };
6935
6973
  J();
6936
6974
  }), p.current && p.current.setShowFullAvatar)
6937
6975
  try {
6938
6976
  p.current.setShowFullAvatar(r);
6939
- } catch (N) {
6940
- console.warn("Error setting full body mode on initialization:", N);
6977
+ } catch (D) {
6978
+ console.warn("Error setting full body mode on initialization:", D);
6941
6979
  }
6942
- p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), Z(!1), se(!0), a(p.current);
6943
- const F = () => {
6980
+ p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), G(!1), se(!0), a(p.current);
6981
+ const B = () => {
6944
6982
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6945
6983
  };
6946
- return document.addEventListener("visibilitychange", F), () => {
6947
- document.removeEventListener("visibilitychange", F);
6984
+ return document.addEventListener("visibilitychange", B), () => {
6985
+ document.removeEventListener("visibilitychange", B);
6948
6986
  };
6949
6987
  } catch (L) {
6950
- console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
6988
+ console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), G(!1), d(L);
6951
6989
  }
6952
- }, [G, t, e, n, i, s, o, r, l, u, h]);
6953
- de(() => (k(), () => {
6990
+ }, [Z, t, e, n, i, s, o, r, l, u, h]);
6991
+ de(() => (w(), () => {
6954
6992
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6955
- }), [k]), de(() => {
6956
- if (!B.current || !p.current) return;
6957
- const L = new ResizeObserver((N) => {
6958
- for (const J of N)
6993
+ }), [w]), de(() => {
6994
+ if (!F.current || !p.current) return;
6995
+ const L = new ResizeObserver((D) => {
6996
+ for (const J of D)
6959
6997
  p.current && p.current.onResize && p.current.onResize();
6960
6998
  });
6961
- L.observe(B.current);
6962
- const F = () => {
6999
+ L.observe(F.current);
7000
+ const B = () => {
6963
7001
  p.current && p.current.onResize && p.current.onResize();
6964
7002
  };
6965
- return window.addEventListener("resize", F), () => {
6966
- L.disconnect(), window.removeEventListener("resize", F);
7003
+ return window.addEventListener("resize", B), () => {
7004
+ L.disconnect(), window.removeEventListener("resize", B);
6967
7005
  };
6968
7006
  }, [$]);
6969
- const H = T(async () => {
7007
+ const M = P(async () => {
6970
7008
  if (p.current && p.current.audioCtx)
6971
7009
  try {
6972
7010
  (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
6973
7011
  } catch (L) {
6974
7012
  console.warn("Failed to resume audio context:", L);
6975
7013
  }
6976
- }, []), U = T(async (L, F = {}) => {
7014
+ }, []), W = P(async (L, B = {}) => {
6977
7015
  if (p.current && $)
6978
7016
  try {
6979
- y.current && (clearInterval(y.current), y.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6980
- const N = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(N).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6981
- W.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
7017
+ y.current && (clearInterval(y.current), y.current = null), k.current = { text: L, options: B }, E.current = { remainingText: null, originalText: null, options: null };
7018
+ const D = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(D).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
7019
+ O.current = J, te.current = 0, pe(!1), T.current = !1, await M();
6982
7020
  const ge = {
6983
- ...F,
6984
- lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
7021
+ ...B,
7022
+ lipsyncLang: B.lipsyncLang || v.lipsyncLang || "en"
6985
7023
  };
6986
- if (F.onSpeechEnd && p.current) {
7024
+ if (B.onSpeechEnd && p.current) {
6987
7025
  const Y = p.current;
6988
7026
  let ue = null, Se = 0;
6989
7027
  const Ae = 1200;
6990
7028
  let be = !1;
6991
7029
  ue = setInterval(() => {
6992
- if (Se++, E.current)
7030
+ if (Se++, T.current)
6993
7031
  return;
6994
7032
  if (Se > Ae) {
6995
- if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !E.current) {
7033
+ if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !T.current) {
6996
7034
  be = !0;
6997
7035
  try {
6998
- F.onSpeechEnd();
6999
- } catch (Ne) {
7000
- console.error("Error in onSpeechEnd callback (timeout):", Ne);
7036
+ B.onSpeechEnd();
7037
+ } catch (De) {
7038
+ console.error("Error in onSpeechEnd callback (timeout):", De);
7001
7039
  }
7002
7040
  }
7003
7041
  return;
7004
7042
  }
7005
7043
  const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
7006
- Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
7007
- if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
7044
+ Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !T.current && setTimeout(() => {
7045
+ if (Y && !T.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !T.current) {
7008
7046
  be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
7009
7047
  try {
7010
- F.onSpeechEnd();
7048
+ B.onSpeechEnd();
7011
7049
  } catch (Ze) {
7012
7050
  console.error("Error in onSpeechEnd callback:", Ze);
7013
7051
  }
@@ -7016,70 +7054,70 @@ const Ve = Me(({
7016
7054
  }, 100), y.current = ue;
7017
7055
  }
7018
7056
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
7019
- await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
7057
+ await M(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
7020
7058
  }, 100);
7021
- } catch (N) {
7022
- console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
7059
+ } catch (D) {
7060
+ console.error("Error speaking text:", D), X(D.message || "Failed to speak text");
7023
7061
  }
7024
- }, [$, H, v.lipsyncLang]), K = T(() => {
7025
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
7026
- }, []), j = T(() => {
7062
+ }, [$, M, v.lipsyncLang]), K = P(() => {
7063
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), k.current = null, pe(!1));
7064
+ }, []), j = P(() => {
7027
7065
  if (p.current && p.current.pauseSpeaking) {
7028
7066
  const L = p.current;
7029
7067
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
7030
7068
  y.current && (clearInterval(y.current), y.current = null);
7031
- let N = "";
7032
- if (z.current && W.current.length > 0) {
7033
- const J = W.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, ue = ge + (Y ? 1 : 0), Se = J - ue;
7034
- if (ue > 0 && Se < J && (N = W.current.slice(Se).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
7069
+ let D = "";
7070
+ if (k.current && O.current.length > 0) {
7071
+ const J = O.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, ue = ge + (Y ? 1 : 0), Se = J - ue;
7072
+ if (ue > 0 && Se < J && (D = O.current.slice(Se).join(". ").trim(), !D && ge > 0 && L.speechQueue)) {
7035
7073
  const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
7036
- be && be.trim() && (N = be.trim());
7074
+ be && be.trim() && (D = be.trim());
7037
7075
  }
7038
7076
  }
7039
- z.current && (P.current = {
7040
- remainingText: N || null,
7041
- originalText: z.current.text,
7042
- options: z.current.options
7043
- }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
7077
+ k.current && (E.current = {
7078
+ remainingText: D || null,
7079
+ originalText: k.current.text,
7080
+ options: k.current.options
7081
+ }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), T.current = !0, pe(!0);
7044
7082
  }
7045
7083
  }
7046
- }, []), q = T(async () => {
7084
+ }, []), q = P(async () => {
7047
7085
  if (!p.current || !ae)
7048
7086
  return;
7049
- let L = "", F = {};
7050
- if (P.current && P.current.remainingText)
7051
- L = P.current.remainingText, F = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
7052
- else if (z.current && z.current.text)
7053
- L = z.current.text, F = z.current.options || {};
7087
+ let L = "", B = {};
7088
+ if (E.current && E.current.remainingText)
7089
+ L = E.current.remainingText, B = E.current.options || {}, E.current = { remainingText: null, originalText: null, options: null };
7090
+ else if (k.current && k.current.text)
7091
+ L = k.current.text, B = k.current.options || {};
7054
7092
  else {
7055
- console.warn("Resume called but no paused speech found"), pe(!1), E.current = !1;
7093
+ console.warn("Resume called but no paused speech found"), pe(!1), T.current = !1;
7056
7094
  return;
7057
7095
  }
7058
- pe(!1), E.current = !1, await H();
7059
- const N = {
7060
- ...F,
7061
- lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
7096
+ pe(!1), T.current = !1, await M();
7097
+ const D = {
7098
+ ...B,
7099
+ lipsyncLang: B.lipsyncLang || v.lipsyncLang || "en"
7062
7100
  };
7063
7101
  try {
7064
- await U(L, N);
7102
+ await W(L, D);
7065
7103
  } catch (J) {
7066
- console.error("Error resuming speech:", J), pe(!1), E.current = !1;
7104
+ console.error("Error resuming speech:", J), pe(!1), T.current = !1;
7067
7105
  }
7068
- }, [H, ae, U, v]), Le = T((L) => {
7106
+ }, [M, ae, W, v]), Le = P((L) => {
7069
7107
  p.current && p.current.setMood(L);
7070
- }, []), we = T((L) => {
7108
+ }, []), we = P((L) => {
7071
7109
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
7072
- }, []), C = T((L, F = !1) => {
7110
+ }, []), C = P((L, B = !1) => {
7073
7111
  if (p.current && p.current.playAnimation) {
7074
- if (b && b[L] && (L = b[L]), p.current.setShowFullAvatar)
7112
+ if (f && f[L] && (L = f[L]), p.current.setShowFullAvatar)
7075
7113
  try {
7076
- p.current.setShowFullAvatar(M.current);
7114
+ p.current.setShowFullAvatar(H.current);
7077
7115
  } catch (J) {
7078
7116
  console.warn("Error setting full body mode:", J);
7079
7117
  }
7080
7118
  if (L.includes("."))
7081
7119
  try {
7082
- p.current.playAnimation(L, null, 10, 0, 0.01, F);
7120
+ p.current.playAnimation(L, null, 10, 0, 0.01, B);
7083
7121
  } catch (J) {
7084
7122
  console.warn(`Failed to play ${L}:`, J);
7085
7123
  try {
@@ -7093,7 +7131,7 @@ const Ve = Me(({
7093
7131
  let ge = !1;
7094
7132
  for (const Y of J)
7095
7133
  try {
7096
- p.current.playAnimation(L + Y, null, 10, 0, 0.01, F), ge = !0;
7134
+ p.current.playAnimation(L + Y, null, 10, 0, 0.01, B), ge = !0;
7097
7135
  break;
7098
7136
  } catch {
7099
7137
  }
@@ -7107,35 +7145,35 @@ const Ve = Me(({
7107
7145
  }
7108
7146
  }
7109
7147
  }
7110
- }, [b]), te = T(() => {
7148
+ }, [f]), ne = P(() => {
7111
7149
  p.current && p.current.onResize && p.current.onResize();
7112
7150
  }, []);
7113
- return Ee(I, () => ({
7114
- speakText: U,
7151
+ return Ee(R, () => ({
7152
+ speakText: W,
7115
7153
  stopSpeaking: K,
7116
7154
  pauseSpeaking: j,
7117
7155
  resumeSpeaking: q,
7118
- resumeAudioContext: H,
7156
+ resumeAudioContext: M,
7119
7157
  setMood: Le,
7120
7158
  setTimingAdjustment: we,
7121
7159
  playAnimation: C,
7122
7160
  isReady: $,
7123
7161
  isPaused: ae,
7124
7162
  talkingHead: p.current,
7125
- handleResize: te,
7163
+ handleResize: ne,
7126
7164
  setBodyMovement: (L) => {
7127
7165
  if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7128
7166
  try {
7129
- p.current.setShowFullAvatar(M.current), p.current.setBodyMovement(L);
7130
- } catch (F) {
7131
- console.warn("Error setting body movement:", F);
7167
+ p.current.setShowFullAvatar(H.current), p.current.setBodyMovement(L);
7168
+ } catch (B) {
7169
+ console.warn("Error setting body movement:", B);
7132
7170
  }
7133
7171
  },
7134
7172
  setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
7135
7173
  playRandomDance: () => {
7136
7174
  if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7137
7175
  try {
7138
- p.current.setShowFullAvatar(M.current), p.current.playRandomDance();
7176
+ p.current.setShowFullAvatar(H.current), p.current.playRandomDance();
7139
7177
  } catch (L) {
7140
7178
  console.warn("Error playing random dance:", L);
7141
7179
  }
@@ -7143,15 +7181,15 @@ const Ve = Me(({
7143
7181
  playReaction: (L) => {
7144
7182
  if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7145
7183
  try {
7146
- p.current.setShowFullAvatar(M.current), p.current.playReaction(L);
7147
- } catch (F) {
7148
- console.warn("Error playing reaction:", F);
7184
+ p.current.setShowFullAvatar(H.current), p.current.playReaction(L);
7185
+ } catch (B) {
7186
+ console.warn("Error playing reaction:", B);
7149
7187
  }
7150
7188
  },
7151
7189
  playCelebration: () => {
7152
7190
  if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7153
7191
  try {
7154
- p.current.setShowFullAvatar(M.current), p.current.playCelebration();
7192
+ p.current.setShowFullAvatar(H.current), p.current.playCelebration();
7155
7193
  } catch (L) {
7156
7194
  console.warn("Error playing celebration:", L);
7157
7195
  }
@@ -7159,9 +7197,9 @@ const Ve = Me(({
7159
7197
  setShowFullAvatar: (L) => {
7160
7198
  if (p.current && p.current.setShowFullAvatar)
7161
7199
  try {
7162
- M.current = L, p.current.setShowFullAvatar(L);
7163
- } catch (F) {
7164
- console.warn("Error setting showFullAvatar:", F);
7200
+ H.current = L, p.current.setShowFullAvatar(L);
7201
+ } catch (B) {
7202
+ console.warn("Error setting showFullAvatar:", B);
7165
7203
  }
7166
7204
  },
7167
7205
  lockAvatarPosition: () => {
@@ -7194,7 +7232,7 @@ const Ve = Me(({
7194
7232
  /* @__PURE__ */ me(
7195
7233
  "div",
7196
7234
  {
7197
- ref: B,
7235
+ ref: F,
7198
7236
  className: "talking-head-viewer",
7199
7237
  style: {
7200
7238
  width: "100%",
@@ -7230,7 +7268,7 @@ const Ve = Me(({
7230
7268
  });
7231
7269
  Ve.displayName = "TalkingHeadAvatar";
7232
7270
  const pt = Me(({
7233
- text: G = "Hello! I'm a talking avatar. How are you today?",
7271
+ text: Z = "Hello! I'm a talking avatar. How are you today?",
7234
7272
  onLoading: t = () => {
7235
7273
  },
7236
7274
  onError: e = () => {
@@ -7241,23 +7279,23 @@ const pt = Me(({
7241
7279
  style: s = {},
7242
7280
  avatarConfig: o = {}
7243
7281
  }, l) => {
7244
- const u = D(null), r = D(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, B = I === "browser" ? {
7282
+ const u = N(null), r = N(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), f = Fe(), R = o.ttsService || f.service, F = R === "browser" ? {
7245
7283
  endpoint: "",
7246
7284
  apiKey: null,
7247
7285
  defaultVoice: "Google US English"
7248
7286
  } : {
7249
- ...b,
7287
+ ...f,
7250
7288
  // Override API key if provided via avatarConfig
7251
- apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
7289
+ apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
7252
7290
  // Override endpoint for ElevenLabs if service is explicitly set
7253
- endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7291
+ endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
7254
7292
  }, p = {
7255
7293
  url: "/avatars/brunette.glb",
7256
7294
  // Use brunette avatar (working glTF file)
7257
7295
  body: "F",
7258
7296
  avatarMood: "neutral",
7259
- ttsLang: I === "browser" ? "en-US" : "en",
7260
- ttsVoice: o.ttsVoice || B.defaultVoice,
7297
+ ttsLang: R === "browser" ? "en-US" : "en",
7298
+ ttsVoice: o.ttsVoice || F.defaultVoice,
7261
7299
  lipsyncLang: "en",
7262
7300
  // English lip-sync
7263
7301
  showFullAvatar: !0,
@@ -7265,16 +7303,16 @@ const pt = Me(({
7265
7303
  bodyMovement: "idle",
7266
7304
  movementIntensity: 0.5,
7267
7305
  ...o
7268
- }, M = {
7269
- ttsEndpoint: B.endpoint,
7270
- ttsApikey: B.apiKey,
7271
- ttsService: I,
7306
+ }, H = {
7307
+ ttsEndpoint: F.endpoint,
7308
+ ttsApikey: F.apiKey,
7309
+ ttsService: R,
7272
7310
  lipsyncModules: ["en"],
7273
7311
  cameraView: "upper"
7274
- }, z = T(async () => {
7312
+ }, k = P(async () => {
7275
7313
  if (!(!u.current || r.current))
7276
7314
  try {
7277
- if (a(!0), d(null), r.current = new Be(u.current, M), await r.current.showAvatar(p, (_) => {
7315
+ if (a(!0), d(null), r.current = new Be(u.current, H), await r.current.showAvatar(p, (_) => {
7278
7316
  if (_.lengthComputable) {
7279
7317
  const X = Math.min(100, Math.round(_.loaded / _.total * 100));
7280
7318
  t(X);
@@ -7297,37 +7335,37 @@ const pt = Me(({
7297
7335
  console.warn("Error setting full body mode on initialization:", _);
7298
7336
  }
7299
7337
  a(!1), x(!0), n(r.current);
7300
- const Z = () => {
7338
+ const G = () => {
7301
7339
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7302
7340
  };
7303
- return document.addEventListener("visibilitychange", Z), () => {
7304
- document.removeEventListener("visibilitychange", Z);
7341
+ return document.addEventListener("visibilitychange", G), () => {
7342
+ document.removeEventListener("visibilitychange", G);
7305
7343
  };
7306
7344
  } catch (S) {
7307
7345
  console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
7308
7346
  }
7309
7347
  }, []);
7310
- de(() => (z(), () => {
7348
+ de(() => (k(), () => {
7311
7349
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7312
- }), [z]);
7313
- const y = T((S) => {
7350
+ }), [k]);
7351
+ const y = P((S) => {
7314
7352
  if (r.current && g)
7315
7353
  try {
7316
7354
  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(() => {
7317
7355
  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");
7318
7356
  }, 500));
7319
- } catch (Z) {
7320
- console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
7357
+ } catch (G) {
7358
+ console.error("Error speaking text:", G), d(G.message || "Failed to speak text");
7321
7359
  }
7322
7360
  else
7323
7361
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7324
- }, [g, p]), E = T(() => {
7362
+ }, [g, p]), T = P(() => {
7325
7363
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7326
- }, []), P = T((S) => {
7364
+ }, []), E = P((S) => {
7327
7365
  r.current && r.current.setMood(S);
7328
- }, []), W = T((S) => {
7366
+ }, []), O = P((S) => {
7329
7367
  r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7330
- }, []), oe = T((S, Z = !1) => {
7368
+ }, []), te = P((S, G = !1) => {
7331
7369
  if (r.current && r.current.playAnimation) {
7332
7370
  if (r.current.setShowFullAvatar)
7333
7371
  try {
@@ -7337,7 +7375,7 @@ const pt = Me(({
7337
7375
  }
7338
7376
  if (S.includes("."))
7339
7377
  try {
7340
- r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
7378
+ r.current.playAnimation(S, null, 10, 0, 0.01, G), console.log("Playing animation:", S);
7341
7379
  } catch (X) {
7342
7380
  console.log(`Failed to play ${S}:`, X);
7343
7381
  try {
@@ -7351,7 +7389,7 @@ const pt = Me(({
7351
7389
  let $ = !1;
7352
7390
  for (const se of X)
7353
7391
  try {
7354
- r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
7392
+ r.current.playAnimation(S + se, null, 10, 0, 0.01, G), console.log("Playing animation:", S + se), $ = !0;
7355
7393
  break;
7356
7394
  } catch {
7357
7395
  console.log(`Failed to play ${S}${se}, trying next format...`);
@@ -7370,18 +7408,18 @@ const pt = Me(({
7370
7408
  }, []);
7371
7409
  return Ee(l, () => ({
7372
7410
  speakText: y,
7373
- stopSpeaking: E,
7374
- setMood: P,
7375
- setTimingAdjustment: W,
7376
- playAnimation: oe,
7411
+ stopSpeaking: T,
7412
+ setMood: E,
7413
+ setTimingAdjustment: O,
7414
+ playAnimation: te,
7377
7415
  isReady: g,
7378
7416
  talkingHead: r.current,
7379
7417
  setBodyMovement: (S) => {
7380
7418
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7381
7419
  try {
7382
7420
  r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7383
- } catch (Z) {
7384
- console.warn("Error setting body movement:", Z);
7421
+ } catch (G) {
7422
+ console.warn("Error setting body movement:", G);
7385
7423
  }
7386
7424
  },
7387
7425
  setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
@@ -7397,8 +7435,8 @@ const pt = Me(({
7397
7435
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7398
7436
  try {
7399
7437
  r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7400
- } catch (Z) {
7401
- console.warn("Error playing reaction:", Z);
7438
+ } catch (G) {
7439
+ console.warn("Error playing reaction:", G);
7402
7440
  }
7403
7441
  },
7404
7442
  playCelebration: () => {
@@ -7413,8 +7451,8 @@ const pt = Me(({
7413
7451
  if (r.current && r.current.setShowFullAvatar)
7414
7452
  try {
7415
7453
  r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7416
- } catch (Z) {
7417
- console.warn("Error setting showFullAvatar:", Z);
7454
+ } catch (G) {
7455
+ console.warn("Error setting showFullAvatar:", G);
7418
7456
  }
7419
7457
  },
7420
7458
  lockAvatarPosition: () => {
@@ -7471,7 +7509,7 @@ const pt = Me(({
7471
7509
  });
7472
7510
  pt.displayName = "TalkingHeadComponent";
7473
7511
  const gt = Me(({
7474
- text: G = null,
7512
+ text: Z = null,
7475
7513
  avatarUrl: t = "/avatars/brunette.glb",
7476
7514
  avatarBody: e = "F",
7477
7515
  mood: n = "neutral",
@@ -7491,66 +7529,66 @@ const gt = Me(({
7491
7529
  },
7492
7530
  onSpeechEnd: x = () => {
7493
7531
  },
7494
- className: b = "",
7495
- style: I = {},
7496
- animations: B = {},
7532
+ className: f = "",
7533
+ style: R = {},
7534
+ animations: F = {},
7497
7535
  autoSpeak: p = !1
7498
- }, M) => {
7499
- const z = D(null), y = D(null), E = D(h), P = D(null), W = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7536
+ }, H) => {
7537
+ const k = N(null), y = N(null), T = N(h), E = N(null), O = N(null), te = N(!1), S = N({ remainingText: null, originalText: null, options: null }), G = N([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7500
7538
  de(() => {
7501
- oe.current = ee;
7539
+ te.current = ee;
7502
7540
  }, [ee]), de(() => {
7503
- E.current = h;
7541
+ T.current = h;
7504
7542
  }, [h]);
7505
- const O = Fe(), v = s || O.service;
7506
- let R;
7507
- v === "browser" ? R = {
7543
+ const U = Fe(), v = s || U.service;
7544
+ let I;
7545
+ v === "browser" ? I = {
7508
7546
  service: "browser",
7509
7547
  endpoint: "",
7510
7548
  apiKey: null,
7511
7549
  defaultVoice: "Google US English"
7512
- } : v === "elevenlabs" ? R = {
7550
+ } : v === "elevenlabs" ? I = {
7513
7551
  service: "elevenlabs",
7514
7552
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7515
- apiKey: l || O.apiKey,
7516
- defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
7517
- voices: O.voices || Ie.voices
7518
- } : v === "deepgram" ? R = {
7553
+ apiKey: l || U.apiKey,
7554
+ defaultVoice: o || U.defaultVoice || Ie.defaultVoice,
7555
+ voices: U.voices || Ie.voices
7556
+ } : v === "deepgram" ? I = {
7519
7557
  service: "deepgram",
7520
7558
  endpoint: "https://api.deepgram.com/v1/speak",
7521
- apiKey: l || O.apiKey,
7522
- defaultVoice: o || O.defaultVoice || Te.defaultVoice,
7523
- voices: O.voices || Te.voices
7524
- } : R = {
7525
- ...O,
7526
- apiKey: l !== null ? l : O.apiKey
7559
+ apiKey: l || U.apiKey,
7560
+ defaultVoice: o || U.defaultVoice || Te.defaultVoice,
7561
+ voices: U.voices || Te.voices
7562
+ } : I = {
7563
+ ...U,
7564
+ apiKey: l !== null ? l : U.apiKey
7527
7565
  };
7528
- const k = {
7566
+ const w = {
7529
7567
  url: t,
7530
7568
  body: e,
7531
7569
  avatarMood: n,
7532
7570
  ttsLang: v === "browser" ? "en-US" : i,
7533
- ttsVoice: o || R.defaultVoice,
7571
+ ttsVoice: o || I.defaultVoice,
7534
7572
  lipsyncLang: "en",
7535
7573
  showFullAvatar: h,
7536
7574
  bodyMovement: u,
7537
7575
  movementIntensity: r
7538
- }, H = {
7539
- ttsEndpoint: R.endpoint,
7540
- ttsApikey: R.apiKey,
7576
+ }, M = {
7577
+ ttsEndpoint: I.endpoint,
7578
+ ttsApikey: I.apiKey,
7541
7579
  ttsService: v,
7542
7580
  lipsyncModules: ["en"],
7543
7581
  cameraView: a
7544
- }, U = T(async () => {
7545
- if (!(!z.current || y.current))
7582
+ }, W = P(async () => {
7583
+ if (!(!k.current || y.current))
7546
7584
  try {
7547
- X(!0), se(null), y.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7548
- url: k.url,
7549
- body: k.body,
7550
- avatarMood: k.avatarMood
7551
- }), await y.current.showAvatar(k, (te) => {
7552
- if (te.lengthComputable) {
7553
- const L = Math.min(100, Math.round(te.loaded / te.total * 100));
7585
+ X(!0), se(null), y.current = new Be(k.current, M), console.log("Avatar config being passed:", {
7586
+ url: w.url,
7587
+ body: w.body,
7588
+ avatarMood: w.avatarMood
7589
+ }), await y.current.showAvatar(w, (ne) => {
7590
+ if (ne.lengthComputable) {
7591
+ const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
7554
7592
  d(L);
7555
7593
  }
7556
7594
  }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), X(!1), pe(!0), c(y.current);
@@ -7564,10 +7602,10 @@ const gt = Me(({
7564
7602
  console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
7565
7603
  }
7566
7604
  }, []);
7567
- de(() => (U(), () => {
7605
+ de(() => (W(), () => {
7568
7606
  y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7569
- }), [U]);
7570
- const K = T(async () => {
7607
+ }), [W]);
7608
+ const K = P(async () => {
7571
7609
  if (y.current)
7572
7610
  try {
7573
7611
  const C = y.current.audioCtx || y.current.audioContext;
@@ -7575,7 +7613,7 @@ const gt = Me(({
7575
7613
  } catch (C) {
7576
7614
  console.warn("Failed to resume audio context:", C);
7577
7615
  }
7578
- }, []), j = T(async (C, te = {}) => {
7616
+ }, []), j = P(async (C, ne = {}) => {
7579
7617
  if (!y.current || !ae) {
7580
7618
  console.warn("Avatar not ready for speaking");
7581
7619
  return;
@@ -7584,53 +7622,53 @@ const gt = Me(({
7584
7622
  console.warn("No text provided to speak");
7585
7623
  return;
7586
7624
  }
7587
- await K(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1;
7588
- const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
7589
- Z.current = L;
7590
- const F = {
7591
- lipsyncLang: te.lipsyncLang || "en",
7625
+ await K(), S.current = { remainingText: null, originalText: null, options: null }, G.current = [], E.current = { text: C, options: ne }, O.current && (clearInterval(O.current), O.current = null), le(!1), te.current = !1;
7626
+ const L = C.split(/[.!?]+/).filter((D) => D.trim().length > 0);
7627
+ G.current = L;
7628
+ const B = {
7629
+ lipsyncLang: ne.lipsyncLang || "en",
7592
7630
  onSpeechEnd: () => {
7593
- W.current && (clearInterval(W.current), W.current = null), te.onSpeechEnd && te.onSpeechEnd(), x();
7631
+ O.current && (clearInterval(O.current), O.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), x();
7594
7632
  }
7595
7633
  };
7596
7634
  try {
7597
- y.current.speakText(C, F);
7598
- } catch (N) {
7599
- console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
7635
+ y.current.speakText(C, B);
7636
+ } catch (D) {
7637
+ console.error("Error speaking text:", D), se(D.message || "Failed to speak text");
7600
7638
  }
7601
7639
  }, [ae, x, K]);
7602
7640
  de(() => {
7603
- ae && G && p && y.current && j(G);
7604
- }, [ae, G, p, j]);
7605
- const q = T(() => {
7641
+ ae && Z && p && y.current && j(Z);
7642
+ }, [ae, Z, p, j]);
7643
+ const q = P(() => {
7606
7644
  if (y.current)
7607
7645
  try {
7608
- const C = y.current.isSpeaking || !1, te = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7609
- if (C || te.length > 0 || L.length > 0) {
7610
- W.current && (clearInterval(W.current), W.current = null);
7611
- let F = "";
7612
- L.length > 0 && (F = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")), S.current = {
7613
- remainingText: F || null,
7614
- originalText: P.current?.text || null,
7615
- options: P.current?.options || null
7616
- }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), oe.current = !0;
7646
+ const C = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7647
+ if (C || ne.length > 0 || L.length > 0) {
7648
+ O.current && (clearInterval(O.current), O.current = null);
7649
+ let B = "";
7650
+ L.length > 0 && (B = L.map((D) => D.text && Array.isArray(D.text) ? D.text.map((J) => J.word).join(" ") : D.text || "").join(" ")), S.current = {
7651
+ remainingText: B || null,
7652
+ originalText: E.current?.text || null,
7653
+ options: E.current?.options || null
7654
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), te.current = !0;
7617
7655
  }
7618
7656
  } catch (C) {
7619
7657
  console.warn("Error pausing speech:", C);
7620
7658
  }
7621
- }, []), Le = T(async () => {
7659
+ }, []), Le = P(async () => {
7622
7660
  if (!(!y.current || !ee))
7623
7661
  try {
7624
- await K(), le(!1), oe.current = !1;
7625
- const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
7626
- F && j(F, L);
7662
+ await K(), le(!1), te.current = !1;
7663
+ const C = S.current?.remainingText, ne = S.current?.originalText || E.current?.text, L = S.current?.options || E.current?.options || {}, B = C || ne;
7664
+ B && j(B, L);
7627
7665
  } catch (C) {
7628
- console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
7666
+ console.warn("Error resuming speech:", C), le(!1), te.current = !1;
7629
7667
  }
7630
- }, [ee, j, K]), we = T(() => {
7631
- y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
7668
+ }, [ee, j, K]), we = P(() => {
7669
+ y.current && (y.current.stopSpeaking(), O.current && (clearInterval(O.current), O.current = null), le(!1), te.current = !1);
7632
7670
  }, []);
7633
- return Ee(M, () => ({
7671
+ return Ee(H, () => ({
7634
7672
  speakText: j,
7635
7673
  pauseSpeaking: q,
7636
7674
  resumeSpeaking: Le,
@@ -7641,21 +7679,21 @@ const gt = Me(({
7641
7679
  setBodyMovement: (C) => {
7642
7680
  y.current && y.current.setBodyMovement(C);
7643
7681
  },
7644
- playAnimation: (C, te = !1) => {
7645
- y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, te);
7682
+ playAnimation: (C, ne = !1) => {
7683
+ y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, ne);
7646
7684
  },
7647
7685
  playReaction: (C) => y.current?.playReaction(C),
7648
7686
  playCelebration: () => y.current?.playCelebration(),
7649
7687
  setShowFullAvatar: (C) => {
7650
- y.current && (E.current = C, y.current.setShowFullAvatar(C));
7688
+ y.current && (T.current = C, y.current.setShowFullAvatar(C));
7651
7689
  },
7652
7690
  isReady: ae,
7653
7691
  talkingHead: y.current
7654
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7692
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: R, children: [
7655
7693
  /* @__PURE__ */ me(
7656
7694
  "div",
7657
7695
  {
7658
- ref: z,
7696
+ ref: k,
7659
7697
  className: "talking-head-viewer",
7660
7698
  style: {
7661
7699
  width: "100%",
@@ -7689,7 +7727,7 @@ const gt = Me(({
7689
7727
  });
7690
7728
  gt.displayName = "SimpleTalkingAvatar";
7691
7729
  const yt = Me(({
7692
- curriculumData: G = null,
7730
+ curriculumData: Z = null,
7693
7731
  avatarConfig: t = {},
7694
7732
  animations: e = {},
7695
7733
  onLessonStart: n = () => {
@@ -7704,7 +7742,7 @@ const yt = Me(({
7704
7742
  },
7705
7743
  autoStart: u = !1
7706
7744
  }, r) => {
7707
- const h = D(null), a = D({
7745
+ const h = N(null), a = N({
7708
7746
  currentModuleIndex: 0,
7709
7747
  currentLessonIndex: 0,
7710
7748
  currentQuestionIndex: 0,
@@ -7714,18 +7752,18 @@ const yt = Me(({
7714
7752
  curriculumCompleted: !1,
7715
7753
  score: 0,
7716
7754
  totalQuestions: 0
7717
- }), c = D({
7755
+ }), c = N({
7718
7756
  onLessonStart: n,
7719
7757
  onLessonComplete: i,
7720
7758
  onQuestionAnswer: s,
7721
7759
  onCurriculumComplete: o,
7722
7760
  onCustomAction: l
7723
- }), d = D(null), g = D(null), x = D(null), b = D(null), I = D(null), B = D(null), p = D(null), M = D(G?.curriculum || {
7761
+ }), d = N(null), g = N(null), x = N(null), f = N(null), R = N(null), F = N(null), p = N(null), H = N(Z?.curriculum || {
7724
7762
  title: "Default Curriculum",
7725
7763
  description: "No curriculum data provided",
7726
7764
  language: "en",
7727
7765
  modules: []
7728
- }), z = D({
7766
+ }), k = N({
7729
7767
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7730
7768
  avatarBody: t.avatarBody || "F",
7731
7769
  mood: t.mood || "happy",
@@ -7748,12 +7786,12 @@ const yt = Me(({
7748
7786
  onCustomAction: l
7749
7787
  };
7750
7788
  }, [n, i, s, o, l]), de(() => {
7751
- M.current = G?.curriculum || {
7789
+ H.current = Z?.curriculum || {
7752
7790
  title: "Default Curriculum",
7753
7791
  description: "No curriculum data provided",
7754
7792
  language: "en",
7755
7793
  modules: []
7756
- }, z.current = {
7794
+ }, k.current = {
7757
7795
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7758
7796
  avatarBody: t.avatarBody || "F",
7759
7797
  mood: t.mood || "happy",
@@ -7767,12 +7805,12 @@ const yt = Me(({
7767
7805
  animations: e,
7768
7806
  lipsyncLang: "en"
7769
7807
  };
7770
- }, [G, t, e]);
7771
- const y = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = T((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, []), W = T(() => {
7808
+ }, [Z, t, e]);
7809
+ const y = P(() => (H.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), T = P(() => y()?.questions[a.current.currentQuestionIndex], [y]), E = P((v, I) => I.type === "multiple_choice" || I.type === "true_false" ? v === I.answer : I.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), O = P(() => {
7772
7810
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7773
7811
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7774
- let R = "Congratulations! You've completed this lesson";
7775
- if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7812
+ let I = "Congratulations! You've completed this lesson";
7813
+ if (a.current.totalQuestions > 0 ? I += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : I += "! ", v >= 80 ? I += "Excellent work! You have a great understanding of this topic." : v >= 60 ? I += "Good job! You understand most of the concepts." : I += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7776
7814
  moduleIndex: a.current.currentModuleIndex,
7777
7815
  lessonIndex: a.current.currentLessonIndex,
7778
7816
  score: a.current.score,
@@ -7792,8 +7830,8 @@ const yt = Me(({
7792
7830
  } catch {
7793
7831
  h.current.playCelebration();
7794
7832
  }
7795
- const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = U || K, q = z.current || { lipsyncLang: "en" };
7796
- h.current.speakText(R, {
7833
+ const w = H.current || { modules: [] }, M = w.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (w.modules?.length || 0) - 1, j = W || K, q = k.current || { lipsyncLang: "en" };
7834
+ h.current.speakText(I, {
7797
7835
  lipsyncLang: q.lipsyncLang,
7798
7836
  onSpeechEnd: () => {
7799
7837
  c.current.onCustomAction({
@@ -7808,12 +7846,12 @@ const yt = Me(({
7808
7846
  }
7809
7847
  });
7810
7848
  }
7811
- }, [e.lessonComplete]), oe = T(() => {
7849
+ }, [e.lessonComplete]), te = P(() => {
7812
7850
  a.current.curriculumCompleted = !0;
7813
- const v = M.current || { modules: [] };
7851
+ const v = H.current || { modules: [] };
7814
7852
  if (c.current.onCurriculumComplete({
7815
7853
  modules: v.modules.length,
7816
- totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
7854
+ totalLessons: v.modules.reduce((I, w) => I + w.lessons.length, 0)
7817
7855
  }), h.current) {
7818
7856
  if (h.current.setMood("celebrating"), e.curriculumComplete)
7819
7857
  try {
@@ -7821,99 +7859,99 @@ const yt = Me(({
7821
7859
  } catch {
7822
7860
  h.current.playCelebration();
7823
7861
  }
7824
- const R = z.current || { lipsyncLang: "en" };
7825
- h.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 });
7862
+ const I = k.current || { lipsyncLang: "en" };
7863
+ h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: I.lipsyncLang });
7826
7864
  }
7827
- }, [e.curriculumComplete]), S = T(() => {
7865
+ }, [e.curriculumComplete]), S = P(() => {
7828
7866
  const v = y();
7829
7867
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7830
- const R = E();
7831
- R && c.current.onCustomAction({
7868
+ const I = T();
7869
+ I && c.current.onCustomAction({
7832
7870
  type: "questionStart",
7833
7871
  moduleIndex: a.current.currentModuleIndex,
7834
7872
  lessonIndex: a.current.currentLessonIndex,
7835
7873
  questionIndex: a.current.currentQuestionIndex,
7836
7874
  totalQuestions: a.current.totalQuestions,
7837
- question: R,
7875
+ question: I,
7838
7876
  score: a.current.score
7839
7877
  });
7840
- const k = () => {
7841
- if (!h.current || !R) return;
7878
+ const w = () => {
7879
+ if (!h.current || !I) return;
7842
7880
  if (h.current.setMood("happy"), e.questionStart)
7843
7881
  try {
7844
7882
  h.current.playAnimation(e.questionStart, !0);
7845
- } catch (U) {
7846
- console.warn("Failed to play questionStart animation:", U);
7883
+ } catch (W) {
7884
+ console.warn("Failed to play questionStart animation:", W);
7847
7885
  }
7848
- const H = z.current || { lipsyncLang: "en" };
7849
- R.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
7886
+ const M = k.current || { lipsyncLang: "en" };
7887
+ I.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : I.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : I.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: M.lipsyncLang });
7850
7888
  };
7851
- if (h.current && h.current.isReady && R)
7852
- k();
7889
+ if (h.current && h.current.isReady && I)
7890
+ w();
7853
7891
  else if (h.current && h.current.isReady) {
7854
- const H = z.current || { lipsyncLang: "en" };
7855
- h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7892
+ const M = k.current || { lipsyncLang: "en" };
7893
+ h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: M.lipsyncLang });
7856
7894
  } else {
7857
- const H = setInterval(() => {
7858
- h.current && h.current.isReady && (clearInterval(H), R && k());
7895
+ const M = setInterval(() => {
7896
+ h.current && h.current.isReady && (clearInterval(M), I && w());
7859
7897
  }, 100);
7860
7898
  setTimeout(() => {
7861
- clearInterval(H);
7899
+ clearInterval(M);
7862
7900
  }, 5e3);
7863
7901
  }
7864
- }, [e.questionStart, y, E]), Z = T(() => {
7902
+ }, [e.questionStart, y, T]), G = P(() => {
7865
7903
  const v = y();
7866
7904
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7867
7905
  h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7868
- const R = E();
7869
- R && c.current.onCustomAction({
7906
+ const I = T();
7907
+ I && c.current.onCustomAction({
7870
7908
  type: "nextQuestion",
7871
7909
  moduleIndex: a.current.currentModuleIndex,
7872
7910
  lessonIndex: a.current.currentLessonIndex,
7873
7911
  questionIndex: a.current.currentQuestionIndex,
7874
7912
  totalQuestions: a.current.totalQuestions,
7875
- question: R,
7913
+ question: I,
7876
7914
  score: a.current.score
7877
7915
  });
7878
- const k = () => {
7879
- if (!h.current || !R) return;
7916
+ const w = () => {
7917
+ if (!h.current || !I) return;
7880
7918
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7881
7919
  try {
7882
7920
  h.current.playAnimation(e.nextQuestion, !0);
7883
7921
  } catch (q) {
7884
7922
  console.warn("Failed to play nextQuestion animation:", q);
7885
7923
  }
7886
- const H = z.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7887
- if (R.type === "code_test") {
7888
- const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7924
+ const M = k.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7925
+ if (I.type === "code_test") {
7926
+ const q = j ? `Great! Here's your final coding challenge: ${I.question}` : `Great! Now let's move on to your next coding challenge: ${I.question}`;
7889
7927
  h.current.speakText(q, {
7890
- lipsyncLang: H.lipsyncLang
7928
+ lipsyncLang: M.lipsyncLang
7891
7929
  });
7892
- } else if (R.type === "multiple_choice") {
7893
- const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7930
+ } else if (I.type === "multiple_choice") {
7931
+ const q = j ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
7894
7932
  h.current.speakText(q, {
7895
- lipsyncLang: H.lipsyncLang
7933
+ lipsyncLang: M.lipsyncLang
7896
7934
  });
7897
- } else if (R.type === "true_false") {
7898
- const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7935
+ } else if (I.type === "true_false") {
7936
+ const q = j ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
7899
7937
  h.current.speakText(q, {
7900
- lipsyncLang: H.lipsyncLang
7938
+ lipsyncLang: M.lipsyncLang
7901
7939
  });
7902
7940
  } else {
7903
- const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7941
+ const q = j ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
7904
7942
  h.current.speakText(q, {
7905
- lipsyncLang: H.lipsyncLang
7943
+ lipsyncLang: M.lipsyncLang
7906
7944
  });
7907
7945
  }
7908
7946
  };
7909
- if (h.current && h.current.isReady && R)
7910
- k();
7911
- else if (R) {
7912
- const H = setInterval(() => {
7913
- h.current && h.current.isReady && (clearInterval(H), k());
7947
+ if (h.current && h.current.isReady && I)
7948
+ w();
7949
+ else if (I) {
7950
+ const M = setInterval(() => {
7951
+ h.current && h.current.isReady && (clearInterval(M), w());
7914
7952
  }, 100);
7915
7953
  setTimeout(() => {
7916
- clearInterval(H);
7954
+ clearInterval(M);
7917
7955
  }, 5e3);
7918
7956
  }
7919
7957
  } else
@@ -7924,11 +7962,11 @@ const yt = Me(({
7924
7962
  totalQuestions: a.current.totalQuestions,
7925
7963
  score: a.current.score
7926
7964
  });
7927
- }, [e.nextQuestion, y, E]), _ = T(() => {
7928
- const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7929
- if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7965
+ }, [e.nextQuestion, y, T]), _ = P(() => {
7966
+ const v = H.current || { modules: [] }, I = v.modules[a.current.currentModuleIndex];
7967
+ if (a.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
7930
7968
  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;
7931
- const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = U || K;
7969
+ const M = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = W || K;
7932
7970
  c.current.onCustomAction({
7933
7971
  type: "lessonStart",
7934
7972
  moduleIndex: a.current.currentModuleIndex,
@@ -7941,7 +7979,7 @@ const yt = Me(({
7941
7979
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7942
7980
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7943
7981
  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;
7944
- const U = v.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = K || j;
7982
+ const W = v.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = K || j;
7945
7983
  c.current.onCustomAction({
7946
7984
  type: "lessonStart",
7947
7985
  moduleIndex: a.current.currentModuleIndex,
@@ -7953,26 +7991,26 @@ const yt = Me(({
7953
7991
  lesson: y()
7954
7992
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7955
7993
  } else
7956
- I.current && I.current();
7957
- }, []), X = T(() => {
7994
+ R.current && R.current();
7995
+ }, []), X = P(() => {
7958
7996
  const v = y();
7959
- let R = null;
7997
+ let I = null;
7960
7998
  if (v?.avatar_script && v?.body) {
7961
- const k = v.avatar_script.trim(), H = v.body.trim(), U = k.match(/[.!?]$/) ? " " : ". ";
7962
- R = `${k}${U}${H}`;
7999
+ const w = v.avatar_script.trim(), M = v.body.trim(), W = w.match(/[.!?]$/) ? " " : ". ";
8000
+ I = `${w}${W}${M}`;
7963
8001
  } else
7964
- R = v?.avatar_script || v?.body || null;
7965
- if (h.current && h.current.isReady && R) {
8002
+ I = v?.avatar_script || v?.body || null;
8003
+ if (h.current && h.current.isReady && I) {
7966
8004
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
7967
- let k = !1;
8005
+ let w = !1;
7968
8006
  if (e.teaching)
7969
8007
  try {
7970
- h.current.playAnimation(e.teaching, !0), k = !0;
7971
- } catch (U) {
7972
- console.warn("Failed to play teaching animation:", U);
8008
+ h.current.playAnimation(e.teaching, !0), w = !0;
8009
+ } catch (W) {
8010
+ console.warn("Failed to play teaching animation:", W);
7973
8011
  }
7974
- k || h.current.setBodyMovement("gesturing");
7975
- const H = z.current || { lipsyncLang: "en" };
8012
+ w || h.current.setBodyMovement("gesturing");
8013
+ const M = k.current || { lipsyncLang: "en" };
7976
8014
  c.current.onLessonStart({
7977
8015
  moduleIndex: a.current.currentModuleIndex,
7978
8016
  lessonIndex: a.current.currentLessonIndex,
@@ -7982,8 +8020,8 @@ const yt = Me(({
7982
8020
  moduleIndex: a.current.currentModuleIndex,
7983
8021
  lessonIndex: a.current.currentLessonIndex,
7984
8022
  lesson: v
7985
- }), h.current.speakText(R, {
7986
- lipsyncLang: H.lipsyncLang,
8023
+ }), h.current.speakText(I, {
8024
+ lipsyncLang: M.lipsyncLang,
7987
8025
  onSpeechEnd: () => {
7988
8026
  a.current.isTeaching = !1, c.current.onCustomAction({
7989
8027
  type: "teachingComplete",
@@ -8001,17 +8039,17 @@ const yt = Me(({
8001
8039
  }
8002
8040
  });
8003
8041
  }
8004
- }, [e.teaching, y]), $ = T((v) => {
8005
- const R = E(), k = P(v, R);
8006
- if (k && (a.current.score += 1), c.current.onQuestionAnswer({
8042
+ }, [e.teaching, y]), $ = P((v) => {
8043
+ const I = T(), w = E(v, I);
8044
+ if (w && (a.current.score += 1), c.current.onQuestionAnswer({
8007
8045
  moduleIndex: a.current.currentModuleIndex,
8008
8046
  lessonIndex: a.current.currentLessonIndex,
8009
8047
  questionIndex: a.current.currentQuestionIndex,
8010
8048
  answer: v,
8011
- isCorrect: k,
8012
- question: R
8049
+ isCorrect: w,
8050
+ question: I
8013
8051
  }), h.current)
8014
- if (k) {
8052
+ if (w) {
8015
8053
  if (h.current.setMood("happy"), e.correct)
8016
8054
  try {
8017
8055
  h.current.playReaction("happy");
@@ -8019,11 +8057,11 @@ const yt = Me(({
8019
8057
  h.current.setBodyMovement("happy");
8020
8058
  }
8021
8059
  h.current.setBodyMovement("gesturing");
8022
- const U = y()?.questions?.length || 0;
8023
- a.current.currentQuestionIndex >= U - 1;
8024
- const K = a.current.currentQuestionIndex < U - 1;
8025
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", K);
8026
- const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
8060
+ const W = y()?.questions?.length || 0;
8061
+ a.current.currentQuestionIndex >= W - 1;
8062
+ const K = a.current.currentQuestionIndex < W - 1;
8063
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", K);
8064
+ const j = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, q = k.current || { lipsyncLang: "en" };
8027
8065
  h.current.speakText(j, {
8028
8066
  lipsyncLang: q.lipsyncLang,
8029
8067
  onSpeechEnd: () => {
@@ -8047,9 +8085,9 @@ const yt = Me(({
8047
8085
  h.current.setBodyMovement("idle");
8048
8086
  }
8049
8087
  h.current.setBodyMovement("gesturing");
8050
- const U = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
8051
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
8052
- const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${K ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
8088
+ const W = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= W - 1, j = a.current.currentQuestionIndex < W - 1;
8089
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", j);
8090
+ const q = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${K ? "" : " Let's move on to the next question."}`, Le = k.current || { lipsyncLang: "en" };
8053
8091
  h.current.speakText(q, {
8054
8092
  lipsyncLang: Le.lipsyncLang,
8055
8093
  onSpeechEnd: () => {
@@ -8067,30 +8105,30 @@ const yt = Me(({
8067
8105
  });
8068
8106
  }
8069
8107
  else {
8070
- const U = y()?.questions?.length || 0;
8108
+ const W = y()?.questions?.length || 0;
8071
8109
  c.current.onCustomAction({
8072
8110
  type: "answerFeedbackComplete",
8073
8111
  moduleIndex: a.current.currentModuleIndex,
8074
8112
  lessonIndex: a.current.currentLessonIndex,
8075
8113
  questionIndex: a.current.currentQuestionIndex,
8076
- isCorrect: k,
8077
- hasNextQuestion: a.current.currentQuestionIndex < U - 1,
8114
+ isCorrect: w,
8115
+ hasNextQuestion: a.current.currentQuestionIndex < W - 1,
8078
8116
  score: a.current.score,
8079
8117
  totalQuestions: a.current.totalQuestions,
8080
8118
  avatarNotReady: !0
8081
8119
  });
8082
8120
  }
8083
- }, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
8084
- const R = E();
8121
+ }, [e.correct, e.incorrect, T, y, E]), se = P((v) => {
8122
+ const I = T();
8085
8123
  if (!v || typeof v != "object") {
8086
8124
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
8087
8125
  return;
8088
8126
  }
8089
- if (R?.type !== "code_test") {
8127
+ if (I?.type !== "code_test") {
8090
8128
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
8091
8129
  return;
8092
8130
  }
8093
- const k = {
8131
+ const w = {
8094
8132
  passed: v.passed === !0,
8095
8133
  results: v.results || [],
8096
8134
  output: v.output || "",
@@ -8105,13 +8143,13 @@ const yt = Me(({
8105
8143
  moduleIndex: a.current.currentModuleIndex,
8106
8144
  lessonIndex: a.current.currentLessonIndex,
8107
8145
  questionIndex: a.current.currentQuestionIndex,
8108
- testResult: k,
8109
- question: R
8110
- }), p.current && p.current(k);
8111
- }, [E, P]), ae = T(() => {
8146
+ testResult: w,
8147
+ question: I
8148
+ }), p.current && p.current(w);
8149
+ }, [T, E]), ae = P(() => {
8112
8150
  if (a.current.currentQuestionIndex > 0) {
8113
8151
  a.current.currentQuestionIndex -= 1;
8114
- const v = E();
8152
+ const v = T();
8115
8153
  v && c.current.onCustomAction({
8116
8154
  type: "questionStart",
8117
8155
  moduleIndex: a.current.currentModuleIndex,
@@ -8121,29 +8159,29 @@ const yt = Me(({
8121
8159
  question: v,
8122
8160
  score: a.current.score
8123
8161
  });
8124
- const R = () => {
8162
+ const I = () => {
8125
8163
  if (!h.current || !v) return;
8126
8164
  h.current.setMood("happy"), h.current.setBodyMovement("idle");
8127
- const k = z.current || { lipsyncLang: "en" };
8165
+ const w = k.current || { lipsyncLang: "en" };
8128
8166
  v.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8129
- lipsyncLang: k.lipsyncLang
8167
+ lipsyncLang: w.lipsyncLang
8130
8168
  }) : h.current.speakText(`Going back to: ${v.question}`, {
8131
- lipsyncLang: k.lipsyncLang
8169
+ lipsyncLang: w.lipsyncLang
8132
8170
  });
8133
8171
  };
8134
8172
  if (h.current && h.current.isReady && v)
8135
- R();
8173
+ I();
8136
8174
  else if (v) {
8137
- const k = setInterval(() => {
8138
- h.current && h.current.isReady && (clearInterval(k), R());
8175
+ const w = setInterval(() => {
8176
+ h.current && h.current.isReady && (clearInterval(w), I());
8139
8177
  }, 100);
8140
8178
  setTimeout(() => {
8141
- clearInterval(k);
8179
+ clearInterval(w);
8142
8180
  }, 5e3);
8143
8181
  }
8144
8182
  }
8145
- }, [E]), pe = T(() => {
8146
- const v = M.current || { modules: [] };
8183
+ }, [T]), pe = P(() => {
8184
+ const v = H.current || { modules: [] };
8147
8185
  if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8148
8186
  a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
8149
8187
  type: "lessonStart",
@@ -8155,8 +8193,8 @@ const yt = Me(({
8155
8193
  lesson: y()
8156
8194
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8157
8195
  else if (a.current.currentModuleIndex > 0) {
8158
- const H = v.modules[a.current.currentModuleIndex - 1];
8159
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
8196
+ const M = v.modules[a.current.currentModuleIndex - 1];
8197
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (M?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
8160
8198
  type: "lessonStart",
8161
8199
  moduleIndex: a.current.currentModuleIndex,
8162
8200
  lessonIndex: a.current.currentLessonIndex
@@ -8166,52 +8204,52 @@ const yt = Me(({
8166
8204
  lesson: y()
8167
8205
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8168
8206
  }
8169
- }, [y]), ee = T(() => {
8207
+ }, [y]), ee = P(() => {
8170
8208
  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;
8171
- }, []), le = T((v) => {
8209
+ }, []), le = P((v) => {
8172
8210
  console.log("Avatar is ready!", v);
8173
- const R = y(), k = R?.avatar_script || R?.body;
8174
- u && k && setTimeout(() => {
8211
+ const I = y(), w = I?.avatar_script || I?.body;
8212
+ u && w && setTimeout(() => {
8175
8213
  d.current && d.current();
8176
8214
  }, 10);
8177
8215
  }, [u, y]);
8178
8216
  Xe(() => {
8179
- d.current = X, g.current = _, x.current = W, b.current = Z, I.current = oe, B.current = S, p.current = $;
8217
+ d.current = X, g.current = _, x.current = O, f.current = G, R.current = te, F.current = S, p.current = $;
8180
8218
  }), Ee(r, () => ({
8181
8219
  // Curriculum control methods
8182
8220
  startTeaching: X,
8183
8221
  startQuestions: S,
8184
8222
  handleAnswerSelect: $,
8185
8223
  handleCodeTestResult: se,
8186
- nextQuestion: Z,
8224
+ nextQuestion: G,
8187
8225
  previousQuestion: ae,
8188
8226
  nextLesson: _,
8189
8227
  previousLesson: pe,
8190
- completeLesson: W,
8191
- completeCurriculum: oe,
8228
+ completeLesson: O,
8229
+ completeCurriculum: te,
8192
8230
  resetCurriculum: ee,
8193
8231
  getState: () => ({ ...a.current }),
8194
- getCurrentQuestion: () => E(),
8232
+ getCurrentQuestion: () => T(),
8195
8233
  getCurrentLesson: () => y(),
8196
8234
  // Direct access to avatar ref (always returns current value)
8197
8235
  getAvatarRef: () => h.current,
8198
8236
  // Convenience methods that delegate to avatar (always check current ref)
8199
- speakText: async (v, R = {}) => {
8237
+ speakText: async (v, I = {}) => {
8200
8238
  await h.current?.resumeAudioContext?.();
8201
- const k = z.current || { lipsyncLang: "en" };
8202
- h.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
8239
+ const w = k.current || { lipsyncLang: "en" };
8240
+ h.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || w.lipsyncLang });
8203
8241
  },
8204
8242
  resumeAudioContext: async () => {
8205
8243
  if (h.current?.resumeAudioContext)
8206
8244
  return await h.current.resumeAudioContext();
8207
8245
  const v = h.current?.talkingHead;
8208
8246
  if (v?.audioCtx) {
8209
- const R = v.audioCtx;
8210
- if (R.state === "suspended" || R.state === "interrupted")
8247
+ const I = v.audioCtx;
8248
+ if (I.state === "suspended" || I.state === "interrupted")
8211
8249
  try {
8212
- await R.resume(), console.log("Audio context resumed via talkingHead");
8213
- } catch (k) {
8214
- console.warn("Failed to resume audio context:", k);
8250
+ await I.resume(), console.log("Audio context resumed via talkingHead");
8251
+ } catch (w) {
8252
+ console.warn("Failed to resume audio context:", w);
8215
8253
  }
8216
8254
  } else
8217
8255
  console.warn("Audio context not available yet");
@@ -8221,7 +8259,7 @@ const yt = Me(({
8221
8259
  resumeSpeaking: async () => await h.current?.resumeSpeaking(),
8222
8260
  isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
8223
8261
  setMood: (v) => h.current?.setMood(v),
8224
- playAnimation: (v, R) => h.current?.playAnimation(v, R),
8262
+ playAnimation: (v, I) => h.current?.playAnimation(v, I),
8225
8263
  setBodyMovement: (v) => h.current?.setBodyMovement(v),
8226
8264
  setMovementIntensity: (v) => h.current?.setMovementIntensity(v),
8227
8265
  playRandomDance: () => h.current?.playRandomDance(),
@@ -8232,10 +8270,10 @@ const yt = Me(({
8232
8270
  lockAvatarPosition: () => h.current?.lockAvatarPosition(),
8233
8271
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
8234
8272
  // Custom action trigger
8235
- triggerCustomAction: (v, R) => {
8273
+ triggerCustomAction: (v, I) => {
8236
8274
  c.current.onCustomAction({
8237
8275
  type: v,
8238
- ...R,
8276
+ ...I,
8239
8277
  state: { ...a.current }
8240
8278
  });
8241
8279
  },
@@ -8243,8 +8281,8 @@ const yt = Me(({
8243
8281
  handleResize: () => h.current?.handleResize(),
8244
8282
  // Avatar readiness check (always returns current value)
8245
8283
  isAvatarReady: () => h.current?.isReady || !1
8246
- }), [X, S, $, se, Z, _, W, oe, ee, E, y]);
8247
- const O = z.current || {
8284
+ }), [X, S, $, se, G, _, O, te, ee, T, y]);
8285
+ const U = k.current || {
8248
8286
  avatarUrl: "/avatars/brunette.glb",
8249
8287
  avatarBody: "F",
8250
8288
  mood: "happy",
@@ -8261,18 +8299,18 @@ const yt = Me(({
8261
8299
  Ve,
8262
8300
  {
8263
8301
  ref: h,
8264
- avatarUrl: O.avatarUrl,
8265
- avatarBody: O.avatarBody,
8266
- mood: O.mood,
8267
- ttsLang: O.ttsLang,
8268
- ttsService: O.ttsService,
8269
- ttsVoice: O.ttsVoice,
8270
- ttsApiKey: O.ttsApiKey,
8271
- bodyMovement: O.bodyMovement,
8272
- movementIntensity: O.movementIntensity,
8273
- showFullAvatar: O.showFullAvatar,
8302
+ avatarUrl: U.avatarUrl,
8303
+ avatarBody: U.avatarBody,
8304
+ mood: U.mood,
8305
+ ttsLang: U.ttsLang,
8306
+ ttsService: U.ttsService,
8307
+ ttsVoice: U.ttsVoice,
8308
+ ttsApiKey: U.ttsApiKey,
8309
+ bodyMovement: U.bodyMovement,
8310
+ movementIntensity: U.movementIntensity,
8311
+ showFullAvatar: U.showFullAvatar,
8274
8312
  cameraView: "upper",
8275
- animations: O.animations,
8313
+ animations: U.animations,
8276
8314
  onReady: le,
8277
8315
  onLoading: () => {
8278
8316
  },
@@ -8386,7 +8424,7 @@ const Ge = {
8386
8424
  duration: 5e3,
8387
8425
  description: "Excited, energetic movement"
8388
8426
  }
8389
- }, wt = (G) => Ge[G] || null, zt = (G) => Ge.hasOwnProperty(G);
8427
+ }, wt = (Z) => Ge[Z] || null, zt = (Z) => Ge.hasOwnProperty(Z);
8390
8428
  export {
8391
8429
  yt as CurriculumLearning,
8392
8430
  gt as SimpleTalkingAvatar,