@sage-rsc/talking-head-react 1.1.1 → 1.1.3

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";
2
+ import { forwardRef as Me, useRef as N, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
3
  import * as f from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
6
6
  import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
7
- 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
- import Ke from "three/addons/libs/stats.module.js";
10
- let m, re, ue;
9
+ import _e from "three/addons/libs/stats.module.js";
10
+ let m, re, he;
11
11
  const A = [0, 0, 0, 0], w = new f.Vector3(), ze = new f.Vector3(), ne = new f.Vector3(), Ce = new f.Vector3();
12
12
  new f.Plane();
13
13
  new f.Ray();
14
14
  new f.Euler();
15
15
  const ie = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
16
  new f.Vector3();
17
- const He = new f.Vector3(0, 0, 1), _e = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
17
+ const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -192,7 +192,7 @@ class et {
192
192
  const l = this.armature.getObjectByName(s.bone);
193
193
  if (!l) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
194
194
  if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
195
- const h = {
195
+ const u = {
196
196
  bone: l,
197
197
  // Bone object
198
198
  radius: s.radius,
@@ -203,9 +203,9 @@ class et {
203
203
  };
204
204
  if (s.deltaLocal) {
205
205
  if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((r) => Number.isNaN(r))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
206
- h.deltaLocal = [...s.deltaLocal];
206
+ u.deltaLocal = [...s.deltaLocal];
207
207
  }
208
- i.excludes.push(h);
208
+ i.excludes.push(u);
209
209
  });
210
210
  }
211
211
  this.showHelpers();
@@ -282,8 +282,8 @@ class et {
282
282
  m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
283
283
  }), this.objectsUpdate = [];
284
284
  const n = /* @__PURE__ */ new WeakSet(), i = (o) => o.parent?.isBone ? [o, ...i(o.parent)] : [o], s = (o) => {
285
- i(o).forEach((h) => {
286
- n.has(h) || (this.objectsUpdate.push(h), n.add(h));
285
+ i(o).forEach((u) => {
286
+ n.has(u) || (this.objectsUpdate.push(u), n.add(u));
287
287
  });
288
288
  };
289
289
  this.data.forEach((o) => {
@@ -308,12 +308,12 @@ class et {
308
308
  i(t?.isScene, "First parameter must be Scene."), this.scene = t, i(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, i(Array.isArray(n), "Third parameter must be an array of bone configs."), this.config = n, this.config.forEach((s, o) => {
309
309
  const l = "Config item #" + o + ": ";
310
310
  i(s.bone, l + "Bone not specified.");
311
- const h = s.bone;
312
- i(typeof h == "string" && h.length > 0, l + "Bone name must be a non-empty string.");
313
- const r = this.armature.getObjectByName(h);
314
- i(r, l + "Bone '" + h + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + h + "' already exists."), r.updateMatrixWorld(!0);
315
- const u = {
316
- name: h,
311
+ const u = s.bone;
312
+ i(typeof u == "string" && u.length > 0, l + "Bone name must be a non-empty string.");
313
+ const r = this.armature.getObjectByName(u);
314
+ i(r, l + "Bone '" + u + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + u + "' already exists."), r.updateMatrixWorld(!0);
315
+ const h = {
316
+ name: u,
317
317
  // Bone name
318
318
  bone: r,
319
319
  // Bone object
@@ -338,9 +338,9 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Oe.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
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;
342
342
  try {
343
- this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
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) {
345
345
  i(!1, l + a);
346
346
  }
@@ -369,9 +369,9 @@ class et {
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(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
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)
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) && (ue = w.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(w), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
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))));
375
375
  }
376
376
  this.helpers.isActive && this.updateHelpers();
377
377
  }
@@ -408,9 +408,9 @@ class et {
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((h) => [0, 0, 0]).flat();
411
+ const e = new f.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
412
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((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
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
414
  e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
415
415
  const l = new f.PointsMaterial({
416
416
  depthTest: !1,
@@ -423,9 +423,9 @@ class et {
423
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);
424
424
  }
425
425
  if (m = this.helpers.lines, m.bones.length) {
426
- const e = new f.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
426
+ const e = new f.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
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((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
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
429
  e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
430
430
  const l = new f.LineBasicMaterial({
431
431
  vertexColors: !0,
@@ -519,13 +519,13 @@ class tt {
519
519
  phonemeBoundaries: []
520
520
  }, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
521
521
  for (let l = 0; l < o; l++) {
522
- const h = l * s, r = Math.min(h + i, t.length), u = t.slice(h, r), a = this.calculateEnergy(u);
522
+ const u = l * s, r = Math.min(u + i, t.length), h = t.slice(u, r), a = this.calculateEnergy(h);
523
523
  n.energy.push(a);
524
- const c = this.calculateSpectralCentroid(u);
524
+ const c = this.calculateSpectralCentroid(h);
525
525
  n.spectralCentroid.push(c);
526
- const d = this.calculateZeroCrossingRate(u);
526
+ const d = this.calculateZeroCrossingRate(h);
527
527
  n.zeroCrossingRate.push(d);
528
- const g = this.calculateMFCC(u);
528
+ const g = this.calculateMFCC(h);
529
529
  n.mfcc.push(g);
530
530
  }
531
531
  return n.onsets = this.detectOnsets(n.energy), n.phonemeBoundaries = this.detectPhonemeBoundaries(n), n;
@@ -597,19 +597,19 @@ class tt {
597
597
  for (; s & o; )
598
598
  s ^= o, o >>= 1;
599
599
  if (s ^= o, i < s) {
600
- const l = n[i * 2], h = n[i * 2 + 1];
601
- n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] = h;
600
+ const l = n[i * 2], u = n[i * 2 + 1];
601
+ n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] = u;
602
602
  }
603
603
  }
604
604
  for (let i = 2; i <= e; i <<= 1) {
605
605
  const s = -2 * Math.PI / i, o = Math.cos(s), l = Math.sin(s);
606
- for (let h = 0; h < e; h += i) {
607
- let r = 1, u = 0;
606
+ for (let u = 0; u < e; u += i) {
607
+ let r = 1, h = 0;
608
608
  for (let a = 0; a < i / 2; a++) {
609
- const c = n[(h + a) * 2], d = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, x = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
- n[(h + a) * 2] = c + g, n[(h + a) * 2 + 1] = d + x, n[(h + a + i / 2) * 2] = c - g, n[(h + a + i / 2) * 2 + 1] = d - x;
611
- const b = r * o - u * l, R = r * l + u * o;
612
- r = b, u = R;
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
+ 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;
613
613
  }
614
614
  }
615
615
  }
@@ -624,8 +624,8 @@ class tt {
624
624
  const e = [];
625
625
  let s = -0.1;
626
626
  for (let o = 1; o < t.length; o++) {
627
- const l = t[o] - t[o - 1], h = o * 0.023;
628
- l > 0.1 && h - s > 0.1 && (e.push(h), s = h);
627
+ const l = t[o] - t[o - 1], u = o * 0.023;
628
+ l > 0.1 && u - s > 0.1 && (e.push(u), s = u);
629
629
  }
630
630
  return e;
631
631
  }
@@ -637,8 +637,8 @@ class tt {
637
637
  detectPhonemeBoundaries(t) {
638
638
  const e = [], { energy: n, spectralCentroid: i, zeroCrossingRate: s } = t;
639
639
  for (let o = 1; o < n.length; o++) {
640
- const l = o * 0.023, h = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), u = Math.abs(s[o] - s[o - 1]);
641
- h + r * 0.1 + u * 0.5 > 0.2 && e.push(l);
640
+ const l = o * 0.023, u = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), h = Math.abs(s[o] - s[o - 1]);
641
+ u + r * 0.1 + h * 0.5 > 0.2 && e.push(l);
642
642
  }
643
643
  return e;
644
644
  }
@@ -654,14 +654,14 @@ class tt {
654
654
  t.phonemeBoundaries, t.onsets;
655
655
  const s = [];
656
656
  let o = 0;
657
- for (let h = 0; h < i.length; h++) {
658
- const r = i[h], u = this.estimateWordDuration(r, n / i.length);
657
+ for (let u = 0; u < i.length; u++) {
658
+ const r = i[u], h = this.estimateWordDuration(r, n / i.length);
659
659
  s.push({
660
660
  word: r,
661
661
  startTime: o,
662
- endTime: o + u,
663
- duration: u
664
- }), o += u;
662
+ endTime: o + h,
663
+ duration: h
664
+ }), o += h;
665
665
  }
666
666
  const l = this.generateVisemeTimings(t, e, n);
667
667
  return {
@@ -701,27 +701,27 @@ class tt {
701
701
  const i = [], s = t.phonemeBoundaries;
702
702
  t.onsets;
703
703
  const o = this.textToVisemes(e);
704
- let l = 0, h = 0;
704
+ let l = 0, u = 0;
705
705
  for (let r = 0; r < s.length && l < o.length; r++) {
706
- const u = s[r], a = o[l], c = t.energy[Math.floor(u / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
706
+ const h = s[r], a = o[l], c = t.energy[Math.floor(h / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
707
707
  i.push({
708
708
  viseme: a,
709
- startTime: h,
710
- endTime: h + d,
709
+ startTime: u,
710
+ endTime: u + d,
711
711
  duration: d,
712
712
  intensity: Math.min(1, c * 2)
713
713
  // Map energy to viseme intensity
714
- }), h += d, l++;
714
+ }), u += d, l++;
715
715
  }
716
716
  for (; l < o.length; ) {
717
- const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
717
+ const r = o[l], h = this.calculateVisemeDuration(r, 0.5);
718
718
  i.push({
719
719
  viseme: r,
720
- startTime: h,
721
- endTime: h + u,
722
- duration: u,
720
+ startTime: u,
721
+ endTime: u + h,
722
+ duration: h,
723
723
  intensity: 0.6
724
- }), h += u, l++;
724
+ }), u += h, l++;
725
725
  }
726
726
  return i;
727
727
  }
@@ -775,16 +775,16 @@ class tt {
775
775
  let o = 0;
776
776
  for (; o < s.length; ) {
777
777
  let l = !1;
778
- for (let h = 3; h >= 2; h--) {
779
- const r = s.substr(o, h);
778
+ for (let u = 3; u >= 2; u--) {
779
+ const r = s.substr(o, u);
780
780
  if (e[r]) {
781
- n.push(e[r]), o += h, l = !0;
781
+ n.push(e[r]), o += u, l = !0;
782
782
  break;
783
783
  }
784
784
  }
785
785
  if (!l) {
786
- const h = s[o];
787
- e[h] && n.push(e[h]), o++;
786
+ const u = s[o];
787
+ e[u] && n.push(e[u]), o++;
788
788
  }
789
789
  }
790
790
  }
@@ -1206,11 +1206,11 @@ class nt {
1206
1206
  };
1207
1207
  Object.keys(this.rules).forEach((e) => {
1208
1208
  this.rules[e] = this.rules[e].map((n) => {
1209
- const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1209
+ const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1210
1210
  let c = "";
1211
1211
  c += [...l].map((g) => t[g] || g).join("");
1212
- const d = [...h];
1213
- return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
1212
+ const d = [...u];
1213
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1214
1214
  a.visemes.push(g);
1215
1215
  }), a;
1216
1216
  });
@@ -1324,8 +1324,8 @@ class nt {
1324
1324
  */
1325
1325
  convertDecade(t) {
1326
1326
  const e = parseInt(t), n = !isNaN(e) && t.length === 2, i = !isNaN(e) && t.length > 2 && e > 0 && e <= 3e3, s = i && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, o = i && !s ? Math.floor(e / 100) : null, l = n || i ? Math.floor(e % 100 / 10) * 10 : null;
1327
- let h = [];
1328
- return s ? h.push(this.convertNumberToWords(s).trim(), "thousands") : (o && h.push(this.convertNumberToWords(o).trim()), l ? h.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? h.push("hundreds") : h.push(t)), h.join(" ");
1327
+ let u = [];
1328
+ return s ? u.push(this.convertNumberToWords(s).trim(), "thousands") : (o && u.push(this.convertNumberToWords(o).trim()), l ? u.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? u.push("hundreds") : u.push(t)), u.join(" ");
1329
1329
  }
1330
1330
  /**
1331
1331
  * Convert ordinal number to text.
@@ -1376,9 +1376,9 @@ class nt {
1376
1376
  const s = i[e.i], o = this.rules[s];
1377
1377
  if (o)
1378
1378
  for (let l = 0; l < o.length; l++) {
1379
- const h = o[l];
1380
- if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(h.regex)) {
1381
- h.visemes.forEach((a) => {
1379
+ const u = o[l];
1380
+ if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
1381
+ u.visemes.forEach((a) => {
1382
1382
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
1383
1383
  const c = 0.7 * (this.visemeDurations[a] || 1);
1384
1384
  e.durations[e.durations.length - 1] += c, n += c;
@@ -1386,7 +1386,7 @@ class nt {
1386
1386
  const c = this.visemeDurations[a] || 1;
1387
1387
  e.visemes.push(a), e.times.push(n), e.durations.push(c), n += c;
1388
1388
  }
1389
- }), e.i += h.move;
1389
+ }), e.i += u.move;
1390
1390
  break;
1391
1391
  }
1392
1392
  }
@@ -1616,11 +1616,11 @@ class ot {
1616
1616
  };
1617
1617
  Object.keys(this.rules).forEach((e) => {
1618
1618
  this.rules[e] = this.rules[e].map((n) => {
1619
- const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1619
+ const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1620
1620
  let c = "";
1621
1621
  c += [...l].map((g) => t[g] || g).join("");
1622
- const d = [...h];
1623
- return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
1622
+ const d = [...u];
1623
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1624
1624
  a.visemes.push(g);
1625
1625
  }), a;
1626
1626
  });
@@ -1732,8 +1732,8 @@ class ot {
1732
1732
  const s = i[e.i], o = this.rules[s];
1733
1733
  if (o) {
1734
1734
  let l = !1;
1735
- for (let h = 0; h < o.length; h++) {
1736
- const r = o[h];
1735
+ for (let u = 0; u < o.length; u++) {
1736
+ const r = o[u];
1737
1737
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
1738
1738
  r.visemes.forEach((c) => {
1739
1739
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
@@ -2131,11 +2131,11 @@ class at {
2131
2131
  };
2132
2132
  Object.keys(this.rules).forEach((e) => {
2133
2133
  this.rules[e] = this.rules[e].map((n) => {
2134
- const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
2134
+ const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
2135
2135
  let c = "";
2136
2136
  c += [...l].map((g) => t[g] || g).join("");
2137
- const d = [...h];
2138
- return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), u.length && u.split(" ").forEach((g) => {
2137
+ const d = [...u];
2138
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), h.length && h.split(" ").forEach((g) => {
2139
2139
  g && a.visemes.push(g);
2140
2140
  }), a;
2141
2141
  });
@@ -2267,8 +2267,8 @@ class at {
2267
2267
  const s = i[e.i], o = this.rules[s];
2268
2268
  if (o) {
2269
2269
  let l = !1;
2270
- for (let h = 0; h < o.length; h++) {
2271
- const r = o[h];
2270
+ for (let u = 0; u < o.length; u++) {
2271
+ const r = o[u];
2272
2272
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
2273
2273
  r.visemes.forEach((c) => {
2274
2274
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
@@ -2381,10 +2381,10 @@ class lt {
2381
2381
  const e = [];
2382
2382
  let n = parseFloat(t);
2383
2383
  if (n === void 0) return t;
2384
- let i = (s, o, l, h, r) => {
2384
+ let i = (s, o, l, u, r) => {
2385
2385
  if (s < o) return s;
2386
- const u = Math.floor(s / o);
2387
- return e.push(l + (u === 1 ? h : this.numberToFinnishWords(u.toString()) + r)), s - u * o;
2386
+ const h = Math.floor(s / o);
2387
+ return e.push(l + (h === 1 ? u : this.numberToFinnishWords(h.toString()) + r)), s - h * o;
2388
2388
  };
2389
2389
  if (n < 0 && (e.push("miinus "), n = Math.abs(n)), n = i(n, 1e9, " ", "miljardi", " miljardia"), n = i(n, 1e6, " ", "miljoona", " miljoonaa"), n = i(n, 1e3, "", "tuhat", "tuhatta"), n = i(n, 100, " ", "sata", "sataa"), n > 20 && (n = i(n, 10, "", "", "kymmentä")), n >= 1) {
2390
2390
  let s = Math.floor(n);
@@ -2436,11 +2436,11 @@ class lt {
2436
2436
  return e;
2437
2437
  }
2438
2438
  }
2439
- const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2439
+ const ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2440
2440
  __proto__: null,
2441
2441
  LipsyncFi: lt
2442
2442
  }, Symbol.toStringTag, { value: "Module" }));
2443
- class ht {
2443
+ class ut {
2444
2444
  /**
2445
2445
  * @constructor
2446
2446
  */
@@ -2559,10 +2559,10 @@ class ht {
2559
2559
  const e = [];
2560
2560
  let n = parseFloat(t);
2561
2561
  if (n === void 0) return t;
2562
- let i = (s, o, l, h, r) => {
2562
+ let i = (s, o, l, u, r) => {
2563
2563
  if (s < o) return s;
2564
- const u = Math.floor(s / o);
2565
- return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(l) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(r) : e.push(h), s - u * o;
2564
+ const h = Math.floor(s / o);
2565
+ return h === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(h.toString())), h % 10 === 1 ? e.push(l) : h % 10 === 0 || h % 100 > 10 && h % 100 < 20 ? e.push(r) : e.push(u), s - h * o;
2566
2566
  };
2567
2567
  n < 0 && (e.push("minus"), n = Math.abs(n)), n = i(n, 1e9, "milijardas", "milijardai", "milijardų"), n = i(n, 1e6, "milijonas", "milijonai", "milijonų"), n = i(n, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), n = i(n, 100, "šimtas", "šimtai", "šimtų");
2568
2568
  for (let s = this.tens.length - 1; s >= 1; s--)
@@ -2608,11 +2608,11 @@ class ht {
2608
2608
  const o = i[s].toLowerCase(), l = this.visemes[o];
2609
2609
  if (l)
2610
2610
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
2611
- const h = 0.7 * (this.durations[o] || 1);
2612
- e.durations[e.durations.length - 1] += h, n += h;
2611
+ const u = 0.7 * (this.durations[o] || 1);
2612
+ e.durations[e.durations.length - 1] += u, n += u;
2613
2613
  } else {
2614
- const h = this.durations[o] || 1;
2615
- e.visemes.push(l), e.times.push(n), e.durations.push(h), n += h;
2614
+ const u = this.durations[o] || 1;
2615
+ e.visemes.push(l), e.times.push(n), e.durations.push(u), n += u;
2616
2616
  }
2617
2617
  else
2618
2618
  n += this.pauses[i[s]] || 0;
@@ -2622,14 +2622,14 @@ class ht {
2622
2622
  }
2623
2623
  const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2624
2624
  __proto__: null,
2625
- LipsyncLt: ht
2625
+ LipsyncLt: ut
2626
2626
  }, Symbol.toStringTag, { value: "Module" })), dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
2627
2627
  en: it,
2628
2628
  de: st,
2629
2629
  fr: rt,
2630
- fi: ut,
2630
+ fi: ht,
2631
2631
  lt: ct
2632
- }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Ie = new f.Vector3(), We = new f.Box3();
2632
+ }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2633
2633
  new f.Matrix4();
2634
2634
  new f.Matrix4();
2635
2635
  new f.Vector3();
@@ -2637,7 +2637,7 @@ new f.Vector3(0, 0, 1);
2637
2637
  const mt = new f.Vector3(1, 0, 0);
2638
2638
  new f.Vector3(0, 1, 0);
2639
2639
  new f.Vector3(0, 0, 1);
2640
- class Be {
2640
+ class De {
2641
2641
  /**
2642
2642
  * Avatar.
2643
2643
  * @typedef {Object} Avatar
@@ -2763,7 +2763,7 @@ class Be {
2763
2763
  avatarOnlyCamera: null,
2764
2764
  statsNode: null,
2765
2765
  statsStyle: null
2766
- }, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new Ke(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
2766
+ }, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new _e(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
2767
2767
  side: {
2768
2768
  standing: !0,
2769
2769
  props: {
@@ -3569,15 +3569,15 @@ class Be {
3569
3569
  "RightArm.scale": { x: 0, y: 0, z: 0 }
3570
3570
  }
3571
3571
  }, ["Left", "Right"].forEach((l) => {
3572
- ["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((h) => {
3573
- this.poseDelta.props[l + h + ".quaternion"] = { x: 0, y: 0, z: 0 };
3574
- }), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((h) => {
3575
- this.poseDelta.props[l + h + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + h + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + h + "3.quaternion"] = { x: 0, y: 0, z: 0 };
3572
+ ["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
3573
+ this.poseDelta.props[l + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
3574
+ }), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
3575
+ this.poseDelta.props[l + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
3576
3576
  });
3577
3577
  });
3578
3578
  const n = /* @__PURE__ */ new Set();
3579
3579
  Object.values(this.poseTemplates).forEach((l) => {
3580
- Object.keys(this.propsToThreeObjects(l.props)).forEach((h) => n.add(h));
3580
+ Object.keys(this.propsToThreeObjects(l.props)).forEach((u) => n.add(u));
3581
3581
  }), Object.keys(this.poseDelta.props).forEach((l) => {
3582
3582
  n.add(l);
3583
3583
  }), this.posePropNames = [...n], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
@@ -4101,7 +4101,7 @@ class Be {
4101
4101
  RightHand: "RightForeArm",
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, o = [];
4104
- Object.entries(s).forEach((l, h) => {
4104
+ Object.entries(s).forEach((l, u) => {
4105
4105
  const r = new f.Bone();
4106
4106
  r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
4107
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 = [];
@@ -4150,9 +4150,9 @@ class Be {
4150
4150
  let e = 3 * t.length / 4;
4151
4151
  t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
4152
4152
  const n = new ArrayBuffer(e), i = new Uint8Array(n);
4153
- let s, o = 0, l, h, r, u;
4153
+ let s, o = 0, l, u, r, h;
4154
4154
  for (s = 0; s < t.length; s += 4)
4155
- l = this.b64Lookup[t.charCodeAt(s)], h = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], u = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | h >> 4, i[o++] = (h & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | u & 63;
4155
+ l = this.b64Lookup[t.charCodeAt(s)], u = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], h = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | u >> 4, i[o++] = (u & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | h & 63;
4156
4156
  return n;
4157
4157
  }
4158
4158
  /**
@@ -4193,8 +4193,8 @@ class Be {
4193
4193
  const e = {};
4194
4194
  for (let [n, i] of Object.entries(t)) {
4195
4195
  const s = n.split(".");
4196
- let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, h = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, h, i.w).normalize());
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());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4222,23 +4222,23 @@ class Be {
4222
4222
  t.forEach((s) => {
4223
4223
  if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
4224
4224
  const o = s.geometry;
4225
- let l = null, h = null;
4226
- for (const [r, u] of Object.entries(n))
4225
+ let l = null, u = null;
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 && (h = new f.Float32BufferAttribute(c.count * 3, 3)));
4229
+ l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
4230
4230
  for (let g = 0; g < c.count; g++) {
4231
- const x = l.getX(g) + c.getX(g) * u, b = l.getY(g) + c.getY(g) * u, R = l.getZ(g) + c.getZ(g) * u;
4232
- l.setXYZ(g, x, b, R);
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);
4233
4233
  }
4234
4234
  if (d)
4235
4235
  for (let g = 0; g < c.count; g++) {
4236
- const x = h.getX(g) + d.getX(g) * u, b = h.getY(g) + d.getY(g) * u, R = h.getZ(g) + d.getZ(g) * u;
4237
- h.setXYZ(g, x, b, R);
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);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
4241
- o.morphAttributes.position.push(l), h && o.morphAttributes.normal.push(h);
4241
+ o.morphAttributes.position.push(l), u && o.morphAttributes.normal.push(u);
4242
4242
  const r = o.morphAttributes.position.length - 1;
4243
4243
  s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
4244
4244
  }
@@ -4268,7 +4268,7 @@ class Be {
4268
4268
  throw new Error("Blend shapes not found");
4269
4269
  const o = new Set(this.mtCustoms);
4270
4270
  this.morphs.forEach((r) => {
4271
- Object.keys(r.morphTargetDictionary).forEach((u) => o.add(u));
4271
+ Object.keys(r.morphTargetDictionary).forEach((h) => o.add(h));
4272
4272
  }), this.mtExtras.forEach((r) => {
4273
4273
  o.has(r.key) || (this.addMixedMorphTarget(this.morphs, r.key, r.mix), o.add(r.key));
4274
4274
  });
@@ -4295,16 +4295,16 @@ class Be {
4295
4295
  ms: [],
4296
4296
  is: []
4297
4297
  }, l[r].value = l[r].baseline, l[r].applied = l[r].baseline;
4298
- const u = this.mtAvatar[r];
4299
- u && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
4300
- l[r][a] = u[a];
4298
+ const h = this.mtAvatar[r];
4299
+ h && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
4300
+ l[r][a] = h[a];
4301
4301
  }), this.morphs.forEach((a) => {
4302
4302
  const c = a.morphTargetDictionary[r];
4303
4303
  c !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(c), a.morphTargetInfluences[c] = l[r].applied);
4304
4304
  });
4305
4305
  }), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((r) => {
4306
- const u = r.split("."), a = this.armature.getObjectByName(u[0]);
4307
- this.poseAvatar.props[r] = a[u[1]], this.poseBase.props.hasOwnProperty(r) ? this.poseAvatar.props[r].copy(this.poseBase.props[r]) : this.poseBase.props[r] = this.poseAvatar.props[r].clone(), this.poseDelta.props.hasOwnProperty(r) && !this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r] = this.poseAvatar.props[r].clone()), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = 2e3;
4306
+ const h = r.split("."), a = this.armature.getObjectByName(h[0]);
4307
+ this.poseAvatar.props[r] = a[h[1]], this.poseBase.props.hasOwnProperty(r) ? this.poseAvatar.props[r].copy(this.poseBase.props[r]) : this.poseBase.props[r] = this.poseAvatar.props[r].clone(), this.poseDelta.props.hasOwnProperty(r) && !this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r] = this.poseAvatar.props[r].clone()), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = 2e3;
4308
4308
  }), this.ikMesh.traverse((r) => {
4309
4309
  r.isBone && r.position.copy(this.armature.getObjectByName(r.name).position);
4310
4310
  }), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(i.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), t.hasOwnProperty("modelDynamicBones"))
@@ -4314,8 +4314,8 @@ class Be {
4314
4314
  console.error("Dynamic bones setup failed: " + r);
4315
4315
  }
4316
4316
  this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
4317
- const h = new f.Vector3();
4318
- this.objectLeftEye.getWorldPosition(h), this.avatarHeight = h.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4317
+ const u = new f.Vector3();
4318
+ this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4319
4319
  }
4320
4320
  /**
4321
4321
  * Get view names.
@@ -4343,22 +4343,22 @@ class Be {
4343
4343
  return;
4344
4344
  }
4345
4345
  if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
4346
- const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, h = this.camera.fov * (Math.PI / 180);
4347
- let r = -n * Math.tan(h / 2), u = (1 - i) * Math.tan(h / 2), a = s;
4346
+ const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
4347
+ let r = -n * Math.tan(u / 2), h = (1 - i) * Math.tan(u / 2), a = s;
4348
4348
  switch (this.viewName) {
4349
4349
  case "head":
4350
- a += 2, u = u * a + 4 * this.avatarHeight / 5;
4350
+ a += 2, h = h * a + 4 * this.avatarHeight / 5;
4351
4351
  break;
4352
4352
  case "upper":
4353
- a += 4.5, u = u * a + 2 * this.avatarHeight / 3;
4353
+ a += 4.5, h = h * a + 2 * this.avatarHeight / 3;
4354
4354
  break;
4355
4355
  case "mid":
4356
- a += 8, u = u * a + this.avatarHeight / 3;
4356
+ a += 8, h = h * a + this.avatarHeight / 3;
4357
4357
  break;
4358
4358
  default:
4359
- a += 12, u = u * a;
4359
+ a += 12, h = h * a;
4360
4360
  }
4361
- r = r * a, this.controlsEnd = new f.Vector3(r, u, 0), this.cameraEnd = new f.Vector3(r, u, 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 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;
4362
4362
  }
4363
4363
  /**
4364
4364
  * Change light colors and intensities.
@@ -4455,17 +4455,17 @@ class Be {
4455
4455
  "HandMiddle",
4456
4456
  "HandRing",
4457
4457
  "HandPinky"
4458
- ].forEach((u, a) => {
4459
- a === 0 ? (this.poseDelta.props[o + u + "1.quaternion"].x = 0, this.poseDelta.props[o + u + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + u + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + u + "1.quaternion"].x = n.applied, this.poseDelta.props[o + u + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + u + "3.quaternion"].x = 1.5 * n.applied);
4458
+ ].forEach((h, a) => {
4459
+ a === 0 ? (this.poseDelta.props[o + h + "1.quaternion"].x = 0, this.poseDelta.props[o + h + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + h + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + h + "1.quaternion"].x = n.applied, this.poseDelta.props[o + h + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + h + "3.quaternion"].x = 1.5 * n.applied);
4460
4460
  });
4461
4461
  break;
4462
4462
  case "chestInhale":
4463
- const l = n.applied / 20, h = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
4464
- this.poseDelta.props["Spine1.scale"] = h, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
4463
+ const l = n.applied / 20, u = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
4464
+ this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
4465
4465
  break;
4466
4466
  default:
4467
- for (let u = 0, a = n.ms.length; u < a; u++)
4468
- n.ms[u][n.is[u]] = n.applied;
4467
+ for (let h = 0, a = n.ms.length; h < a; h++)
4468
+ n.ms[h][n.is[h]] = n.applied;
4469
4469
  }
4470
4470
  }
4471
4471
  }
@@ -4480,8 +4480,8 @@ class Be {
4480
4480
  return Object.entries(t).forEach((i, s) => {
4481
4481
  const o = i[0].split(".");
4482
4482
  if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
4483
- const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4484
- n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(h.x * e) / e, n += ", y:" + Math.round(h.y * e) / e, n += ", z:" + Math.round(h.z * e) / e, n += "}";
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
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;
4487
4487
  }
@@ -4551,8 +4551,8 @@ class Be {
4551
4551
  if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
4552
4552
  this.setPoseFromTemplate(t, e);
4553
4553
  }, o)) : this.poseCurrentTemplate = t || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, o), this.poseWeightOnLeft = !0, (!i && !s || i && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
4554
- for (let [l, h] of Object.entries(this.gesture))
4555
- this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(h), this.poseTarget.props[l].t = h.t, this.poseTarget.props[l].d = h.d);
4554
+ for (let [l, u] of Object.entries(this.gesture))
4555
+ this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(u), this.poseTarget.props[l].t = u.t, this.poseTarget.props[l].d = u.d);
4556
4556
  Object.keys(this.poseDelta.props).forEach((l) => {
4557
4557
  this.poseTarget.props.hasOwnProperty(l) || (this.poseTarget.props[l] = this.poseBase.props[l].clone(), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = o);
4558
4558
  });
@@ -4985,11 +4985,11 @@ class Be {
4985
4985
  else if (l.hasOwnProperty("alt")) {
4986
4986
  let r = l.alt[0];
4987
4987
  if (l.alt.length > 1) {
4988
- const u = Math.random();
4988
+ const h = Math.random();
4989
4989
  let a = 0;
4990
4990
  for (let c = 0; c < l.alt.length; c++) {
4991
4991
  let d = this.valueFn(l.alt[c].p);
4992
- if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, u < a) {
4992
+ if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, h < a) {
4993
4993
  r = l.alt[c];
4994
4994
  break;
4995
4995
  }
@@ -4999,19 +4999,19 @@ class Be {
4999
4999
  continue;
5000
5000
  } else
5001
5001
  break;
5002
- let h = this.valueFn(l.delay) || 0;
5003
- if (Array.isArray(h) && (h = this.gaussianRandom(...h)), l.hasOwnProperty("dt"))
5004
- l.dt.forEach((r, u) => {
5002
+ let u = this.valueFn(l.delay) || 0;
5003
+ if (Array.isArray(u) && (u = this.gaussianRandom(...u)), l.hasOwnProperty("dt"))
5004
+ l.dt.forEach((r, h) => {
5005
5005
  let a = this.valueFn(r);
5006
- Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[u + 1] = o.ts[u] + a;
5006
+ Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[h + 1] = o.ts[h] + a;
5007
5007
  });
5008
5008
  else {
5009
- let r = Object.values(l.vs).reduce((u, a) => a.length > u ? a.length : u, 0);
5009
+ let r = Object.values(l.vs).reduce((h, a) => a.length > h ? a.length : h, 0);
5010
5010
  o.ts = Array(r + 1).fill(0);
5011
5011
  }
5012
- s ? o.ts = o.ts.map((r) => h + r * n) : o.ts = o.ts.map((r) => this.animClock + h + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
5013
- for (let [r, u] of Object.entries(l.vs)) {
5014
- const a = this.getBaselineValue(r), c = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? (console.log("Intercepting pose", d, "in animation factory, overriding to wide for male avatar"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5012
+ s ? o.ts = o.ts.map((r) => u + r * n) : o.ts = o.ts.map((r) => this.animClock + u + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
5013
+ for (let [r, h] of Object.entries(l.vs)) {
5014
+ const a = this.getBaselineValue(r), c = h.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? (console.log("Intercepting pose", d, "in animation factory, overriding to wide for male avatar"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5015
5015
  r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
5016
5016
  }
5017
5017
  for (let r of Object.keys(o.vs))
@@ -5093,8 +5093,8 @@ class Be {
5093
5093
  if (this.isSpeaking)
5094
5094
  for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
5095
5095
  this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
5096
- let h = null, r = null;
5097
- const u = [];
5096
+ let u = null, r = null;
5097
+ const h = [];
5098
5098
  for (n = 0, s = this.animQueue.length; n < s; n++) {
5099
5099
  const a = this.animQueue[n];
5100
5100
  if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
@@ -5121,12 +5121,12 @@ class Be {
5121
5121
  g.newvalue *= 1 + l / 255 - 0.5;
5122
5122
  }
5123
5123
  g.needsUpdate = !0;
5124
- } else c === "eyeContact" && d[i] !== null && h !== !1 ? h = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (u.push({ mt: c, val: d[i] }), d[i] = null);
5124
+ } else c === "eyeContact" && d[i] !== null && u !== !1 ? u = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (h.push({ mt: c, val: d[i] }), d[i] = null);
5125
5125
  i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
5126
5126
  }
5127
5127
  }
5128
- for (let a = 0, c = u.length; a < c; a++)
5129
- switch (i = u[a].val, u[a].mt) {
5128
+ for (let a = 0, c = h.length; a < c; a++)
5129
+ switch (i = h[a].val, h[a].mt) {
5130
5130
  case "speak":
5131
5131
  this.speakText(i);
5132
5132
  break;
@@ -5172,7 +5172,7 @@ class Be {
5172
5172
  }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  }
5175
- if ((h || r) && (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)), h ? (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({
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({
5176
5176
  name: "headmove",
5177
5177
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5178
5178
  vs: {
@@ -5193,7 +5193,7 @@ class Be {
5193
5193
  eyeLookOutRight: [null, 0],
5194
5194
  eyeContact: [0]
5195
5195
  }
5196
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Ie), Ie.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Ie.x) / 4, this.objectHips.position.z -= (ve.z + Ie.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5196
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5197
5197
  this.stats && this.stats.end();
5198
5198
  else {
5199
5199
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
@@ -5260,24 +5260,24 @@ class Be {
5260
5260
  */
5261
5261
  speakText(t, e = null, n = null, i = null) {
5262
5262
  e = e || {};
5263
- const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, h = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5264
- let u = "", a = "", c = 0, d = [], g = [];
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
+ let h = "", a = "", c = 0, d = [], g = [];
5265
5265
  const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5266
5266
  for (let b = 0; b < x.length; b++) {
5267
- const R = b === x.length - 1, B = x[b].match(l);
5267
+ const I = b === x.length - 1, D = x[b].match(l);
5268
5268
  let p = x[b].match(s);
5269
- const M = x[b].match(h), z = x[b].match(o);
5270
- if (p && !R && !M && x[b + 1].match(s) && (p = !1), n && (u += x[b]), B && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (z || p || R) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
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]), D && (!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({
5271
5271
  mark: c,
5272
5272
  word: a
5273
- })), u.length && (g.push({
5273
+ })), h.length && (g.push({
5274
5274
  mark: c,
5275
5275
  template: { name: "subtitles" },
5276
5276
  ts: [0],
5277
5277
  vs: {
5278
- subtitles: [u]
5278
+ subtitles: [h]
5279
5279
  }
5280
- }), u = ""), a.length)) {
5280
+ }), h = ""), a.length)) {
5281
5281
  const y = this.lipsyncWordsToVisemes(a, r);
5282
5282
  if (y && y.visemes && y.visemes.length) {
5283
5283
  const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
@@ -5293,8 +5293,8 @@ class Be {
5293
5293
  }
5294
5294
  a = "", c++;
5295
5295
  }
5296
- if (p || R) {
5297
- if (d.length || R && g.length) {
5296
+ if (p || I) {
5297
+ if (d.length || I && g.length) {
5298
5298
  const y = {
5299
5299
  anim: g
5300
5300
  };
@@ -5383,25 +5383,25 @@ class Be {
5383
5383
  if (t.words) {
5384
5384
  let o = [];
5385
5385
  for (let l = 0; l < t.words.length; l++) {
5386
- const h = t.words[l], r = t.wtimes[l];
5387
- let u = t.wdurations[l];
5388
- if (h.length && (n && o.push({
5386
+ const u = t.words[l], r = t.wtimes[l];
5387
+ let h = t.wdurations[l];
5388
+ if (u.length && (n && o.push({
5389
5389
  template: { name: "subtitles" },
5390
5390
  ts: [r],
5391
5391
  vs: {
5392
- subtitles: [" " + h]
5392
+ subtitles: [" " + u]
5393
5393
  }
5394
5394
  }), !t.visemes)) {
5395
- const a = this.lipsyncPreProcessText(h, i), c = this.lipsyncWordsToVisemes(a, i);
5395
+ const a = this.lipsyncPreProcessText(u, i), c = this.lipsyncWordsToVisemes(a, i);
5396
5396
  if (c && c.visemes && c.visemes.length) {
5397
- const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(u, Math.max(0, u - c.visemes.length * 150));
5398
- let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5399
- if (u = Math.min(u, c.visemes.length * 200), d > 0)
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
+ let x = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
5399
+ if (h = Math.min(h, c.visemes.length * 200), d > 0)
5400
5400
  for (let b = 0; b < c.visemes.length; b++) {
5401
- const R = r + c.times[b] / d * u, B = c.durations[b] / d * u;
5401
+ const I = r + c.times[b] / d * h, D = c.durations[b] / d * h;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [R - Math.min(60, 2 * B / 3), R + Math.min(25, B / 2), R + B + Math.min(60, B / 2)],
5404
+ ts: [I - Math.min(60, 2 * D / 3), I + Math.min(25, D / 2), I + D + Math.min(60, D / 2)],
5405
5405
  vs: {
5406
5406
  ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5407
5407
  }
@@ -5412,22 +5412,22 @@ class Be {
5412
5412
  }
5413
5413
  if (t.visemes)
5414
5414
  for (let l = 0; l < t.visemes.length; l++) {
5415
- const h = t.visemes[l], r = t.vtimes[l], u = t.vdurations[l];
5415
+ const u = t.visemes[l], r = t.vtimes[l], h = t.vdurations[l];
5416
5416
  o.push({
5417
5417
  template: { name: "viseme" },
5418
- ts: [r - 2 * u / 3, r + u / 2, r + u + u / 2],
5418
+ ts: [r - 2 * h / 3, r + h / 2, r + h + h / 2],
5419
5419
  vs: {
5420
- ["viseme_" + h]: [null, h === "PP" || h === "FF" ? 0.9 : 0.6, 0]
5420
+ ["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
5421
5421
  }
5422
5422
  });
5423
5423
  }
5424
5424
  if (t.markers)
5425
5425
  for (let l = 0; l < t.markers.length; l++) {
5426
- const h = t.markers[l], r = t.mtimes[l];
5426
+ const u = t.markers[l], r = t.mtimes[l];
5427
5427
  o.push({
5428
5428
  template: { name: "markers" },
5429
5429
  ts: [r],
5430
- vs: { function: [h] }
5430
+ vs: { function: [u] }
5431
5431
  });
5432
5432
  }
5433
5433
  o.length && (s.anim = o);
@@ -5447,7 +5447,7 @@ class Be {
5447
5447
  if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
5448
5448
  const e = this.audioPlaylist.shift();
5449
5449
  if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
5450
- const s = this.audioCtx.resume(), o = new Promise((l, h) => setTimeout(() => h("p2"), 1e3));
5450
+ const s = this.audioCtx.resume(), o = new Promise((l, u) => setTimeout(() => u("p2"), 1e3));
5451
5451
  try {
5452
5452
  await Promise.race([s, o]);
5453
5453
  } catch {
@@ -5479,11 +5479,11 @@ class Be {
5479
5479
  */
5480
5480
  async synthesizeWithBrowserTTS(t) {
5481
5481
  return new Promise((e, n) => {
5482
- const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, h = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5483
- s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, h)), s.volume = Math.max(0, Math.min(1, r));
5484
- const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
- if (a && u.length > 0) {
5486
- const p = u.find((M) => M.name.includes(a) || M.lang === o);
5482
+ const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5483
+ s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, r));
5484
+ const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
+ if (a && h.length > 0) {
5486
+ const p = h.find((M) => M.name.includes(a) || M.lang === o);
5487
5487
  p && (s.voice = p);
5488
5488
  }
5489
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);
@@ -5495,12 +5495,12 @@ class Be {
5495
5495
  hasVisemes: b && b.visemes && b.visemes.length > 0,
5496
5496
  estimatedDuration: c
5497
5497
  });
5498
- const R = [];
5498
+ const I = [];
5499
5499
  if (b && b.visemes && b.visemes.length > 0) {
5500
5500
  const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5501
5501
  for (let M = 0; M < b.visemes.length; M++) {
5502
5502
  const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
5503
- R.push({
5503
+ I.push({
5504
5504
  template: { name: "viseme" },
5505
5505
  ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
5506
5506
  vs: {
@@ -5509,8 +5509,8 @@ class Be {
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const B = [...t.anim, ...R];
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 D = [...t.anim, ...I];
5513
+ this.audioPlaylist.push({ anim: D, 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);
@@ -5544,15 +5544,15 @@ class Be {
5544
5544
  throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
5545
5545
  const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
5546
5546
  console.log("Using text-based lip-sync for debugging...");
5547
- const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5547
+ const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5548
5548
  let r;
5549
5549
  try {
5550
5550
  console.log("Lip-sync modules available:", {
5551
5551
  hasLipsync: !!this.lipsync,
5552
5552
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5553
- lipsyncLang: h
5553
+ lipsyncLang: u
5554
5554
  });
5555
- const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
5555
+ const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
5556
5556
  if (console.log("Lip-sync data:", {
5557
5557
  processedText: c,
5558
5558
  lipsyncData: d,
@@ -5577,8 +5577,8 @@ class Be {
5577
5577
  const d = e.toLowerCase().split(/\s+/), g = [];
5578
5578
  for (const x of d)
5579
5579
  for (const b of x) {
5580
- let R = "aa";
5581
- "aeiou".includes(b) ? R = "aa" : "bp".includes(b) ? R = "PP" : "fv".includes(b) ? R = "FF" : "st".includes(b) ? R = "SS" : "dln".includes(b) ? R = "DD" : "kg".includes(b) ? R = "kk" : "rw".includes(b) && (R = "RR"), g.push(R);
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);
5582
5582
  }
5583
5583
  r = {
5584
5584
  visemes: g.map((x, b) => ({
@@ -5605,12 +5605,12 @@ class Be {
5605
5605
  visemes: r.visemes ? r.visemes.slice(0, 3) : []
5606
5606
  // Show first 3 visemes for debugging
5607
5607
  });
5608
- const u = [];
5608
+ const h = [];
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
5612
  const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5613
- u.push({
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: {
@@ -5618,11 +5618,11 @@ class Be {
5618
5618
  }
5619
5619
  });
5620
5620
  }
5621
- console.log("ElevenLabs: Generated", u.length, "lip-sync animation frames");
5621
+ console.log("ElevenLabs: Generated", h.length, "lip-sync animation frames");
5622
5622
  } else
5623
5623
  console.warn("ElevenLabs: No visemes available for lip-sync animation");
5624
- const a = [...t.anim, ...u];
5625
- console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5624
+ const a = [...t.anim, ...h];
5625
+ console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5626
5626
  }
5627
5627
  /**
5628
5628
  * Synthesize speech using Deepgram Aura-2 TTS
@@ -5642,15 +5642,15 @@ class Be {
5642
5642
  throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
5643
5643
  const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
5644
5644
  console.log("Using text-based lip-sync for Deepgram...");
5645
- const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5645
+ const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5646
5646
  let r;
5647
5647
  try {
5648
5648
  console.log("Lip-sync modules available:", {
5649
5649
  hasLipsync: !!this.lipsync,
5650
5650
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5651
- lipsyncLang: h
5651
+ lipsyncLang: u
5652
5652
  });
5653
- const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
5653
+ const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
5654
5654
  if (console.log("Lip-sync data:", {
5655
5655
  processedText: c,
5656
5656
  lipsyncData: d,
@@ -5675,8 +5675,8 @@ class Be {
5675
5675
  const d = e.toLowerCase().split(/\s+/), g = [];
5676
5676
  for (const x of d)
5677
5677
  for (const b of x) {
5678
- let R = "aa";
5679
- "aeiou".includes(b) ? R = "aa" : "bp".includes(b) ? R = "PP" : "fv".includes(b) ? R = "FF" : "st".includes(b) ? R = "SS" : "dln".includes(b) ? R = "DD" : "kg".includes(b) ? R = "kk" : "rw".includes(b) && (R = "RR"), g.push(R);
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);
5680
5680
  }
5681
5681
  r = {
5682
5682
  visemes: g.map((x, b) => ({
@@ -5703,12 +5703,12 @@ class Be {
5703
5703
  visemes: r.visemes ? r.visemes.slice(0, 3) : []
5704
5704
  // Show first 3 visemes for debugging
5705
5705
  });
5706
- const u = [];
5706
+ const h = [];
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
5710
  const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5711
- u.push({
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: {
@@ -5716,11 +5716,11 @@ class Be {
5716
5716
  }
5717
5717
  });
5718
5718
  }
5719
- console.log("Deepgram: Generated", u.length, "lip-sync animation frames");
5719
+ console.log("Deepgram: Generated", h.length, "lip-sync animation frames");
5720
5720
  } else
5721
5721
  console.warn("Deepgram: No visemes available for lip-sync animation");
5722
- const a = [...t.anim, ...u];
5723
- console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5722
+ const a = [...t.anim, ...h];
5723
+ console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5724
5724
  }
5725
5725
  /**
5726
5726
  * Synthesize speech using Azure TTS
@@ -5746,20 +5746,20 @@ class Be {
5746
5746
  throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
5747
5747
  const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
5748
5748
  console.log("Analyzing audio for precise lip-sync...");
5749
- const h = await this.audioAnalyzer.analyzeAudio(l, e);
5749
+ const u = await this.audioAnalyzer.analyzeAudio(l, e);
5750
5750
  console.log("Azure TTS Audio Analysis:", {
5751
5751
  text: e,
5752
5752
  audioDuration: l.duration,
5753
- visemeCount: h.visemes.length,
5754
- wordCount: h.words.length,
5753
+ visemeCount: u.visemes.length,
5754
+ wordCount: u.words.length,
5755
5755
  features: {
5756
- onsets: h.features.onsets.length,
5757
- boundaries: h.features.phonemeBoundaries.length
5756
+ onsets: u.features.onsets.length,
5757
+ boundaries: u.features.phonemeBoundaries.length
5758
5758
  }
5759
5759
  });
5760
5760
  const r = [];
5761
- for (let a = 0; a < h.visemes.length; a++) {
5762
- const c = h.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, x = c.intensity;
5761
+ for (let a = 0; a < u.visemes.length; a++) {
5762
+ const c = u.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, x = c.intensity;
5763
5763
  r.push({
5764
5764
  template: { name: "viseme" },
5765
5765
  ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
@@ -5768,8 +5768,8 @@ class Be {
5768
5768
  }
5769
5769
  });
5770
5770
  }
5771
- const u = [...t.anim, ...r];
5772
- this.audioPlaylist.push({ anim: u, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5771
+ const h = [...t.anim, ...r];
5772
+ this.audioPlaylist.push({ anim: h, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5773
5773
  }
5774
5774
  /**
5775
5775
  * Synthesize speech using external TTS service (Google Cloud, etc.)
@@ -5808,24 +5808,24 @@ class Be {
5808
5808
  if (i.status === 200 && s && s.audioContent) {
5809
5809
  const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
5810
5810
  this.speakWithHands();
5811
- const h = [0];
5811
+ const u = [0];
5812
5812
  let r = 0;
5813
5813
  t.text.forEach((c, d) => {
5814
5814
  if (d > 0) {
5815
- let g = h[h.length - 1];
5816
- s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), h.push(g);
5815
+ let g = u[u.length - 1];
5816
+ s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), u.push(g);
5817
5817
  }
5818
5818
  });
5819
- const u = [{ mark: 0, time: 0 }];
5820
- h.forEach((c, d) => {
5819
+ const h = [{ mark: 0, time: 0 }];
5820
+ u.forEach((c, d) => {
5821
5821
  if (d > 0) {
5822
- let g = c - h[d - 1];
5823
- u[d - 1].duration = g, u.push({ mark: d, time: c });
5822
+ let g = c - u[d - 1];
5823
+ h[d - 1].duration = g, h.push({ mark: d, time: c });
5824
5824
  }
5825
5825
  });
5826
5826
  let a = 1e3 * l.duration;
5827
- a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((c) => {
5828
- const d = u[c.mark];
5827
+ a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), h[h.length - 1].duration = a - h[h.length - 1].time, t.anim.forEach((c) => {
5828
+ const d = h[c.mark];
5829
5829
  if (d)
5830
5830
  for (let g = 0; g < c.ts.length; g++)
5831
5831
  c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
@@ -5908,10 +5908,10 @@ class Be {
5908
5908
  }
5909
5909
  if (!this.workletLoaded)
5910
5910
  try {
5911
- const l = this.audioCtx.audioWorklet.addModule(dt.href), h = new Promise(
5912
- (r, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
5911
+ const l = this.audioCtx.audioWorklet.addModule(dt.href), u = new Promise(
5912
+ (r, h) => setTimeout(() => h(new Error("Worklet loading timed out")), 5e3)
5913
5913
  );
5914
- await Promise.race([l, h]), this.workletLoaded = !0;
5914
+ await Promise.race([l, u]), this.workletLoaded = !0;
5915
5915
  } catch (l) {
5916
5916
  throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
5917
5917
  }
@@ -5924,8 +5924,8 @@ class Be {
5924
5924
  if (l.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
5925
5925
  try {
5926
5926
  this.onAudioStart?.();
5927
- } catch (h) {
5928
- console.error(h);
5927
+ } catch (u) {
5928
+ console.error(u);
5929
5929
  }
5930
5930
  if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
5931
5931
  try {
@@ -5945,9 +5945,9 @@ class Be {
5945
5945
  } catch {
5946
5946
  }
5947
5947
  if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
5948
- const l = this.audioCtx.resume(), h = new Promise((r, u) => setTimeout(() => u("p2"), 1e3));
5948
+ const l = this.audioCtx.resume(), u = new Promise((r, h) => setTimeout(() => h("p2"), 1e3));
5949
5949
  try {
5950
- await Promise.race([l, h]);
5950
+ await Promise.race([l, u]);
5951
5951
  } catch {
5952
5952
  console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");
5953
5953
  return;
@@ -6044,13 +6044,13 @@ class Be {
6044
6044
  subtitles: [" " + i]
6045
6045
  }
6046
6046
  }), this.streamLipsyncType == "words")) {
6047
- const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, h = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(h, l);
6047
+ const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(u, l);
6048
6048
  if (r && r.visemes && r.visemes.length) {
6049
- const u = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
6049
+ const h = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
6050
6050
  let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6051
- if (o = Math.min(o, r.visemes.length * 200), u > 0)
6051
+ if (o = Math.min(o, r.visemes.length * 200), h > 0)
6052
6052
  for (let d = 0; d < r.visemes.length; d++) {
6053
- const g = e + s + r.times[d] / u * o, x = r.durations[d] / u * o;
6053
+ const g = e + s + r.times[d] / h * o, x = r.durations[d] / h * o;
6054
6054
  this.animQueue.push({
6055
6055
  template: { name: "viseme" },
6056
6056
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
@@ -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), Ie.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Ie).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
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) {
6150
6150
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6151
6151
  if (this.avatar.avatarIgnoreCamera) {
6152
6152
  this.lookAhead(t);
@@ -6159,14 +6159,14 @@ class Be {
6159
6159
  this.lookAt(null, null, t);
6160
6160
  return;
6161
6161
  }
6162
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Ie.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Ie).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
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
6163
  const n = new f.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), h = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6166
- V.setFromQuaternion(h, "YXZ");
6167
- let r = V.x / (40 / 24) + 0.2, u = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6165
+ const l = new f.Quaternion().setFromEuler(V), u = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6166
+ V.setFromQuaternion(u, "YXZ");
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((R) => R.template.name === "lookat");
6169
+ let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6170
6170
  x !== -1 && this.animQueue.splice(x, 1);
6171
6171
  const b = {
6172
6172
  name: "lookat",
@@ -6198,11 +6198,11 @@ class Be {
6198
6198
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6199
6199
  const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
- let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6202
- t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(Q);
6203
- let u = 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 - h, h), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + c, R = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
6204
- b = Math.min(0.6, Math.max(-0.3, b)), R = Math.min(0.8, Math.max(-0.8, R));
6205
- let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6201
+ let u = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
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 D = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
6207
  let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
6208
  M !== -1 && this.animQueue.splice(M, 1);
@@ -6210,9 +6210,9 @@ class Be {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [b + B],
6214
- bodyRotateY: [R + p],
6215
- eyesRotateX: [-3 * B + 0.1],
6213
+ bodyRotateX: [b + D],
6214
+ bodyRotateY: [I + p],
6215
+ eyesRotateX: [-3 * D + 0.1],
6216
6216
  eyesRotateY: [-5 * p],
6217
6217
  browInnerUp: [[0, 0.7]],
6218
6218
  mouthLeft: [[0, 0.7]],
@@ -6239,10 +6239,10 @@ class Be {
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, h = new f.Vector3(), r = new f.Vector3();
6243
- this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(r);
6244
- const u = h.distanceToSquared(l), a = r.distanceToSquared(l);
6245
- u < a ? (this.ikSolve({
6242
+ const l = o[0].point, u = new f.Vector3(), r = new f.Vector3();
6243
+ this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(r);
6244
+ const h = u.distanceToSquared(l), a = r.distanceToSquared(l);
6245
+ h < a ? (this.ikSolve({
6246
6246
  iterations: 20,
6247
6247
  root: "LeftShoulder",
6248
6248
  effector: "LeftHandMiddle1",
@@ -6263,8 +6263,8 @@ class Be {
6263
6263
  }, l, !1, 1e3), this.setValue("handFistRight", 0));
6264
6264
  } else
6265
6265
  ["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
6266
- let h = l + ".quaternion";
6267
- this.poseTarget.props[h].copy(this.getPoseTemplateProp(h)), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = 1e3;
6266
+ let u = l + ".quaternion";
6267
+ this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
6268
6268
  });
6269
6269
  return o.length > 0;
6270
6270
  }
@@ -6390,37 +6390,192 @@ class Be {
6390
6390
  (e.isBone || e.type === "Bone") && t.add(e.name);
6391
6391
  }), t;
6392
6392
  }
6393
+ /**
6394
+ * Map bone names from different naming conventions to avatar bone names
6395
+ * @param {string} fbxBoneName - Bone name from FBX animation
6396
+ * @param {Set<string>} availableBones - Set of available bone names in avatar
6397
+ * @returns {string|null} Mapped bone name or null if no match found
6398
+ */
6399
+ mapBoneName(t, e) {
6400
+ if (e.has(t))
6401
+ return t;
6402
+ let n = t;
6403
+ if (n.startsWith("CC_Base_") && (n = n.replace("CC_Base_", "")), n = n.replace(/^mixamorig/i, ""), e.has(n))
6404
+ return n;
6405
+ if (this._mappingDebugLog || (this._mappingDebugLog = /* @__PURE__ */ new Set()), this._mappingDebugLog.size < 5 && !this._mappingDebugLog.has(t) && (this._mappingDebugLog.add(t), console.debug(`Mapping attempt: "${t}" -> "${n}" (not found in available bones)`)), n.match(/^Spine\d+$/)) {
6406
+ const a = n.match(/\d+/)?.[0];
6407
+ if (a) {
6408
+ const c = `Spine${parseInt(a)}`;
6409
+ if (e.has(c))
6410
+ return c;
6411
+ if (a === "01" && e.has("Spine1"))
6412
+ return "Spine1";
6413
+ if (parseInt(a) >= 2 && e.has("Spine2"))
6414
+ return "Spine2";
6415
+ }
6416
+ }
6417
+ if (n.includes("Twist"))
6418
+ return null;
6419
+ const i = {
6420
+ // Spine mapping
6421
+ Spine01: "Spine1",
6422
+ Spine02: "Spine2",
6423
+ Spine03: "Spine2",
6424
+ // Left arm mapping
6425
+ L_Upperarm: "LeftArm",
6426
+ L_Forearm: "LeftForeArm",
6427
+ L_Hand: "LeftHand",
6428
+ L_Shoulder: "LeftShoulder",
6429
+ L_Index1: "LeftHandIndex1",
6430
+ L_Index2: "LeftHandIndex2",
6431
+ L_Index3: "LeftHandIndex3",
6432
+ L_Middle1: "LeftHandMiddle1",
6433
+ L_Middle2: "LeftHandMiddle2",
6434
+ L_Middle3: "LeftHandMiddle3",
6435
+ L_Ring1: "LeftHandRing1",
6436
+ L_Ring2: "LeftHandRing2",
6437
+ L_Ring3: "LeftHandRing3",
6438
+ L_Pinky1: "LeftHandPinky1",
6439
+ L_Pinky2: "LeftHandPinky2",
6440
+ L_Pinky3: "LeftHandPinky3",
6441
+ L_Thumb1: "LeftHandThumb1",
6442
+ L_Thumb2: "LeftHandThumb2",
6443
+ L_Thumb3: "LeftHandThumb3",
6444
+ // Right arm mapping
6445
+ R_Upperarm: "RightArm",
6446
+ R_Forearm: "RightForeArm",
6447
+ R_Hand: "RightHand",
6448
+ R_Shoulder: "RightShoulder",
6449
+ R_Index1: "RightHandIndex1",
6450
+ R_Index2: "RightHandIndex2",
6451
+ R_Index3: "RightHandIndex3",
6452
+ R_Middle1: "RightHandMiddle1",
6453
+ R_Middle2: "RightHandMiddle2",
6454
+ R_Middle3: "RightHandMiddle3",
6455
+ R_Ring1: "RightHandRing1",
6456
+ R_Ring2: "RightHandRing2",
6457
+ R_Ring3: "RightHandRing3",
6458
+ R_Pinky1: "RightHandPinky1",
6459
+ R_Pinky2: "RightHandPinky2",
6460
+ R_Pinky3: "RightHandPinky3",
6461
+ R_Thumb1: "RightHandThumb1",
6462
+ R_Thumb2: "RightHandThumb2",
6463
+ R_Thumb3: "RightHandThumb3",
6464
+ // Leg mapping
6465
+ L_Thigh: "LeftUpLeg",
6466
+ L_Calf: "LeftLeg",
6467
+ L_Foot: "LeftFoot",
6468
+ R_Thigh: "RightUpLeg",
6469
+ R_Calf: "RightLeg",
6470
+ R_Foot: "RightFoot"
6471
+ };
6472
+ if (i[n]) {
6473
+ const a = i[n];
6474
+ if (e.has(a))
6475
+ return a;
6476
+ }
6477
+ const s = n.toLowerCase();
6478
+ n.charAt(0).toUpperCase() + n.slice(1).toLowerCase();
6479
+ const o = s.match(/^[rl]_index(\d+)$/);
6480
+ if (o) {
6481
+ const a = o[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandIndex${a}`;
6482
+ if (e.has(d))
6483
+ return d;
6484
+ }
6485
+ const l = s.match(/^[rl]_pinky(\d+)$/);
6486
+ if (l) {
6487
+ const a = l[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandPinky${a}`;
6488
+ if (e.has(d))
6489
+ return d;
6490
+ }
6491
+ const u = s.match(/^[rl]_ring(\d+)$/);
6492
+ if (u) {
6493
+ const a = u[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandRing${a}`;
6494
+ if (e.has(d))
6495
+ return d;
6496
+ }
6497
+ const r = s.match(/^[rl]_middle(\d+)$/);
6498
+ if (r) {
6499
+ const a = r[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandMiddle${a}`;
6500
+ if (e.has(d))
6501
+ return d;
6502
+ }
6503
+ const h = s.match(/^[rl]_thumb(\d+)$/);
6504
+ if (h) {
6505
+ const a = h[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandThumb${a}`;
6506
+ if (e.has(d))
6507
+ return d;
6508
+ }
6509
+ if (s.match(/^[rl]_upperarm/)) {
6510
+ const c = `${s.startsWith("r") ? "Right" : "Left"}Arm`;
6511
+ if (e.has(c))
6512
+ return c;
6513
+ }
6514
+ if (s.includes("upperarmtwist") || s.includes("forearmtwist"))
6515
+ return null;
6516
+ if (s.match(/^[rl]_forearm/)) {
6517
+ const c = `${s.startsWith("r") ? "Right" : "Left"}ForeArm`;
6518
+ if (e.has(c))
6519
+ return c;
6520
+ }
6521
+ if (s.match(/^[rl]_hand$/)) {
6522
+ const c = `${s.startsWith("r") ? "Right" : "Left"}Hand`;
6523
+ if (e.has(c))
6524
+ return c;
6525
+ }
6526
+ for (const a of e)
6527
+ if (a.toLowerCase() === s)
6528
+ return a;
6529
+ return null;
6530
+ }
6393
6531
  /**
6394
6532
  * Filter animation tracks to only include bones that exist in the avatar
6533
+ * Maps bone names from different naming conventions to avatar bone names
6395
6534
  * @param {THREE.AnimationClip} clip - Animation clip to filter
6396
6535
  * @param {Set<string>} availableBones - Set of available bone names
6397
- * @returns {THREE.AnimationClip} Filtered animation clip
6536
+ * @returns {THREE.AnimationClip} Filtered animation clip with mapped bone names
6398
6537
  */
6399
6538
  filterAnimationTracks(t, e) {
6400
- const n = [], i = /* @__PURE__ */ new Set();
6401
- return t.tracks.forEach((s) => {
6402
- const l = s.name.split(".")[0];
6403
- e.has(l) ? n.push(s) : i.add(l);
6404
- }), i.size > 0 ? (console.warn(`FBX animation "${t.name}" contains tracks for ${i.size} bone(s) not found in avatar skeleton:`, Array.from(i).slice(0, 10).join(", "), i.size > 10 ? "..." : ""), console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks`)) : n.length > 0 && console.info(`FBX animation "${t.name}" is fully compatible: all ${n.length} tracks match avatar skeleton`), n.length === 0 ? (console.error(`No valid tracks found for animation "${t.name}". All bones are missing from avatar skeleton.`), null) : new f.AnimationClip(t.name, t.duration, n);
6539
+ const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
6540
+ return this._loggedAvailableBones || (console.log(
6541
+ "Available avatar bones:",
6542
+ Array.from(e).sort().slice(0, 50).join(", "),
6543
+ e.size > 50 ? `... (${e.size} total)` : ""
6544
+ ), this._loggedAvailableBones = !0), t.tracks.forEach((o) => {
6545
+ const l = o.name.split("."), u = l[0], r = l[1], h = this.mapBoneName(u, e);
6546
+ if (h) {
6547
+ const a = `${h}.${r}`, c = o.clone();
6548
+ c.name = a, n.push(c), u !== h && s.set(u, h);
6549
+ } else
6550
+ i.add(u);
6551
+ }), s.size > 0 && console.info(
6552
+ `FBX animation "${t.name}": Mapped ${s.size} bone(s) to avatar skeleton:`,
6553
+ Array.from(s.entries()).slice(0, 5).map(([o, l]) => `${o} → ${l}`).join(", "),
6554
+ s.size > 5 ? "..." : ""
6555
+ ), i.size > 0 && console.warn(
6556
+ `FBX animation "${t.name}" contains tracks for ${i.size} bone(s) that couldn't be mapped:`,
6557
+ Array.from(i).slice(0, 10).join(", "),
6558
+ i.size > 10 ? "..." : ""
6559
+ ), 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);
6405
6560
  }
6406
6561
  async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
6407
6562
  if (!this.armature) return;
6408
6563
  this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
6409
- let l = this.animClips.find((h) => h.url === t + "-" + i);
6564
+ let l = this.animClips.find((u) => u.url === t + "-" + i);
6410
6565
  if (l) {
6411
- let h = this.animQueue.find((a) => a.template.name === "pose");
6412
- h && (h.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6566
+ let u = this.animQueue.find((a) => a.template.name === "pose");
6567
+ u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6413
6568
  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;
6414
6569
  }), 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 });
6415
- const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
6416
- u.setLoop(f.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6570
+ const r = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
6571
+ h.setLoop(f.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6417
6572
  try {
6418
- u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6573
+ h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6419
6574
  } catch (a) {
6420
6575
  console.warn("FBX animation failed to start:", a), this.stopAnimation();
6421
6576
  return;
6422
6577
  }
6423
- if (u.getClip().tracks.length === 0) {
6578
+ if (h.getClip().tracks.length === 0) {
6424
6579
  console.warn("FBX animation has no valid tracks, stopping"), this.stopAnimation();
6425
6580
  return;
6426
6581
  }
@@ -6439,10 +6594,10 @@ class Be {
6439
6594
  } catch (c) {
6440
6595
  console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6441
6596
  }
6442
- const u = new De();
6597
+ const h = new Ne();
6443
6598
  let a;
6444
6599
  try {
6445
- a = await u.loadAsync(t, e);
6600
+ a = await h.loadAsync(t, e);
6446
6601
  } catch (c) {
6447
6602
  console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
6448
6603
  message: c.message,
@@ -6471,14 +6626,14 @@ class Be {
6471
6626
  }
6472
6627
  c = g;
6473
6628
  const x = {};
6474
- c.tracks.forEach((R) => {
6475
- R.name = R.name.replaceAll("mixamorig", "");
6476
- const B = R.name.split(".");
6477
- if (B[1] === "position") {
6478
- for (let p = 0; p < R.values.length; p++)
6479
- R.values[p] = R.values[p] * s;
6480
- x[R.name] = new f.Vector3(R.values[0], R.values[1], R.values[2]);
6481
- } else B[1] === "quaternion" ? x[R.name] = new f.Quaternion(R.values[0], R.values[1], R.values[2], R.values[3]) : B[1] === "rotation" && (x[B[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(R.values[0], R.values[1], R.values[2], "XYZ")).normalize());
6629
+ c.tracks.forEach((I) => {
6630
+ I.name = I.name.replaceAll("mixamorig", "");
6631
+ const D = I.name.split(".");
6632
+ if (D[1] === "position") {
6633
+ for (let p = 0; p < I.values.length; p++)
6634
+ I.values[p] = I.values[p] * s;
6635
+ x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6636
+ } else D[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : D[1] === "rotation" && (x[D[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6482
6637
  });
6483
6638
  const b = { props: x };
6484
6639
  x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
@@ -6514,25 +6669,25 @@ class Be {
6514
6669
  if (!this.armature) return;
6515
6670
  let o = this.poseTemplates[t];
6516
6671
  if (!o) {
6517
- const l = this.animPoses.find((h) => h.url === t + "-" + i);
6672
+ const l = this.animPoses.find((u) => u.url === t + "-" + i);
6518
6673
  l && (o = l.pose);
6519
6674
  }
6520
6675
  if (o) {
6521
6676
  this.poseName = t, this.mixer = null;
6522
- let l = this.animQueue.find((h) => h.template.name === "pose");
6677
+ let l = this.animQueue.find((u) => u.template.name === "pose");
6523
6678
  l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
6524
6679
  } else {
6525
- let h = await new De().loadAsync(t, e);
6526
- if (h && h.animations && h.animations[i]) {
6527
- let r = h.animations[i];
6528
- const u = {};
6680
+ let u = await new Ne().loadAsync(t, e);
6681
+ if (u && u.animations && u.animations[i]) {
6682
+ let r = u.animations[i];
6683
+ const h = {};
6529
6684
  r.tracks.forEach((c) => {
6530
6685
  c.name = c.name.replaceAll("mixamorig", "");
6531
6686
  const d = c.name.split(".");
6532
- d[1] === "position" ? u[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6687
+ 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());
6533
6688
  });
6534
- const a = { props: u };
6535
- u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
6689
+ const a = { props: h };
6690
+ h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
6536
6691
  url: t + "-" + i,
6537
6692
  pose: a
6538
6693
  }), this.playPose(t, e, n, i, s);
@@ -6561,10 +6716,10 @@ class Be {
6561
6716
  let s = this.gestureTemplates[t];
6562
6717
  if (s) {
6563
6718
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6564
- let l = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
6565
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6566
- for (let [h, r] of Object.entries(this.gesture))
6567
- r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(r), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = i);
6719
+ let l = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
6720
+ 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));
6721
+ for (let [u, r] of Object.entries(this.gesture))
6722
+ 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);
6568
6723
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
6569
6724
  }
6570
6725
  let o = this.animEmojis[t];
@@ -6572,15 +6727,15 @@ class Be {
6572
6727
  this.lookAtCamera(500);
6573
6728
  const l = this.animFactory(o);
6574
6729
  if (l.gesture = !0, e && Number.isFinite(e)) {
6575
- const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
6576
- if (e * 1e3 - u > 0) {
6730
+ const u = l.ts[0], h = l.ts[l.ts.length - 1] - u;
6731
+ if (e * 1e3 - h > 0) {
6577
6732
  const c = [];
6578
6733
  for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6579
- const d = o.template?.rescale || c.map((x) => x / u), g = e * 1e3 - u;
6580
- l.ts = l.ts.map((x, b, R) => b === 0 ? h : R[b - 1] + c[b - 1] + d[b - 1] * g);
6734
+ const d = o.template?.rescale || c.map((x) => x / h), g = e * 1e3 - h;
6735
+ l.ts = l.ts.map((x, b, I) => b === 0 ? u : I[b - 1] + c[b - 1] + d[b - 1] * g);
6581
6736
  } else {
6582
- const c = e * 1e3 / u;
6583
- l.ts = l.ts.map((d) => h + c * (d - h));
6737
+ const c = e * 1e3 / h;
6738
+ l.ts = l.ts.map((d) => u + c * (d - u));
6584
6739
  }
6585
6740
  }
6586
6741
  this.animQueue.push(l);
@@ -6610,19 +6765,19 @@ class Be {
6610
6765
  * @param {numeric} [d=null] If set, apply in d milliseconds
6611
6766
  */
6612
6767
  ikSolve(t, e = null, n = !1, i = null) {
6613
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), h = new f.Vector3(), r = new f.Quaternion(), u = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6768
+ 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);
6614
6769
  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);
6615
6770
  const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6616
- x.forEach((R) => {
6617
- R.bone = this.ikMesh.getObjectByName(R.link), R.bone.quaternion.copy(this.getPoseTemplateProp(R.link + ".quaternion"));
6771
+ x.forEach((I) => {
6772
+ I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6618
6773
  }), d.updateMatrixWorld(!0);
6619
6774
  const b = t.iterations || 10;
6620
6775
  if (e)
6621
- for (let R = 0; R < b; R++) {
6622
- let B = !1;
6776
+ for (let I = 0; I < b; I++) {
6777
+ let D = !1;
6623
6778
  for (let p = 0, M = x.length; p < M; p++) {
6624
6779
  const z = x[p].bone;
6625
- z.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6780
+ 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();
6626
6781
  let y = s.dot(l);
6627
6782
  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(
6628
6783
  x[p].minx !== void 0 ? x[p].minx : -1 / 0,
@@ -6632,12 +6787,12 @@ class Be {
6632
6787
  x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6633
6788
  x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6634
6789
  x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6635
- ))), z.updateMatrixWorld(!0), B = !0);
6790
+ ))), z.updateMatrixWorld(!0), D = !0);
6636
6791
  }
6637
- if (!B) break;
6792
+ if (!D) break;
6638
6793
  }
6639
- i && x.forEach((R) => {
6640
- 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;
6794
+ i && x.forEach((I) => {
6795
+ 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;
6641
6796
  });
6642
6797
  }
6643
6798
  /**
@@ -6647,7 +6802,7 @@ class Be {
6647
6802
  this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
6648
6803
  }
6649
6804
  }
6650
- const Re = {
6805
+ const Ie = {
6651
6806
  apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
6652
6807
  // Replace with your actual API key (should start with sk_)
6653
6808
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
@@ -6690,10 +6845,10 @@ const Re = {
6690
6845
  function Fe() {
6691
6846
  return {
6692
6847
  service: "elevenlabs",
6693
- endpoint: Re.endpoint,
6694
- apiKey: Re.apiKey,
6695
- defaultVoice: Re.defaultVoice,
6696
- voices: Re.voices
6848
+ endpoint: Ie.endpoint,
6849
+ apiKey: Ie.apiKey,
6850
+ defaultVoice: Ie.defaultVoice,
6851
+ voices: Ie.voices
6697
6852
  };
6698
6853
  }
6699
6854
  function kt() {
@@ -6714,9 +6869,9 @@ const Ve = Me(({
6714
6869
  ttsVoice: s = null,
6715
6870
  ttsApiKey: o = null,
6716
6871
  bodyMovement: l = "idle",
6717
- movementIntensity: h = 0.5,
6872
+ movementIntensity: u = 0.5,
6718
6873
  showFullAvatar: r = !0,
6719
- cameraView: u = "upper",
6874
+ cameraView: h = "upper",
6720
6875
  onReady: a = () => {
6721
6876
  },
6722
6877
  onLoading: c = () => {
@@ -6726,8 +6881,8 @@ const Ve = Me(({
6726
6881
  className: g = "",
6727
6882
  style: x = {},
6728
6883
  animations: b = {}
6729
- }, R) => {
6730
- 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), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6884
+ }, I) => {
6885
+ const D = N(null), p = N(null), M = N(r), z = N(null), y = N(null), E = N(!1), P = N({ remainingText: null, originalText: null, options: null }), W = N([]), oe = N(0), [S, Z] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6731
6886
  de(() => {
6732
6887
  E.current = ae;
6733
6888
  }, [ae]), de(() => {
@@ -6744,8 +6899,8 @@ const Ve = Me(({
6744
6899
  service: "elevenlabs",
6745
6900
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6746
6901
  apiKey: o || ee.apiKey,
6747
- defaultVoice: s || ee.defaultVoice || Re.defaultVoice,
6748
- voices: ee.voices || Re.voices
6902
+ defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6903
+ voices: ee.voices || Ie.voices
6749
6904
  } : le === "deepgram" ? O = {
6750
6905
  service: "deepgram",
6751
6906
  endpoint: "https://api.deepgram.com/v1/speak",
@@ -6766,31 +6921,31 @@ const Ve = Me(({
6766
6921
  lipsyncLang: "en",
6767
6922
  showFullAvatar: r,
6768
6923
  bodyMovement: l,
6769
- movementIntensity: h
6770
- }, I = {
6924
+ movementIntensity: u
6925
+ }, R = {
6771
6926
  ttsEndpoint: O.endpoint,
6772
6927
  ttsApikey: O.apiKey,
6773
6928
  ttsService: le,
6774
6929
  lipsyncModules: ["en"],
6775
- cameraView: u
6930
+ cameraView: h
6776
6931
  }, k = T(async () => {
6777
- if (!(!B.current || p.current))
6932
+ if (!(!D.current || p.current))
6778
6933
  try {
6779
- if (Z(!0), X(null), p.current = new Be(B.current, I), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (N) => {
6780
- if (N.lengthComputable) {
6781
- const J = Math.min(100, Math.round(N.loaded / N.total * 100));
6934
+ if (Z(!0), X(null), p.current = new De(D.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, (B) => {
6935
+ if (B.lengthComputable) {
6936
+ const J = Math.min(100, Math.round(B.loaded / B.total * 100));
6782
6937
  c(J);
6783
6938
  }
6784
- }), await new Promise((N) => {
6939
+ }), await new Promise((B) => {
6785
6940
  const J = () => {
6786
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? N() : setTimeout(J, 100);
6941
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
6787
6942
  };
6788
6943
  J();
6789
6944
  }), p.current && p.current.setShowFullAvatar)
6790
6945
  try {
6791
6946
  p.current.setShowFullAvatar(r);
6792
- } catch (N) {
6793
- console.warn("Error setting full body mode on initialization:", N);
6947
+ } catch (B) {
6948
+ console.warn("Error setting full body mode on initialization:", B);
6794
6949
  }
6795
6950
  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);
6796
6951
  const F = () => {
@@ -6802,16 +6957,16 @@ const Ve = Me(({
6802
6957
  } catch (L) {
6803
6958
  console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
6804
6959
  }
6805
- }, [G, t, e, n, i, s, o, r, l, h, u]);
6960
+ }, [G, t, e, n, i, s, o, r, l, u, h]);
6806
6961
  de(() => (k(), () => {
6807
6962
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6808
6963
  }), [k]), de(() => {
6809
- if (!B.current || !p.current) return;
6810
- const L = new ResizeObserver((N) => {
6811
- for (const J of N)
6964
+ if (!D.current || !p.current) return;
6965
+ const L = new ResizeObserver((B) => {
6966
+ for (const J of B)
6812
6967
  p.current && p.current.onResize && p.current.onResize();
6813
6968
  });
6814
- L.observe(B.current);
6969
+ L.observe(D.current);
6815
6970
  const F = () => {
6816
6971
  p.current && p.current.onResize && p.current.onResize();
6817
6972
  };
@@ -6830,7 +6985,7 @@ const Ve = Me(({
6830
6985
  if (p.current && $)
6831
6986
  try {
6832
6987
  y.current && (clearInterval(y.current), y.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6833
- const N = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(N).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6988
+ const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6834
6989
  W.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
6835
6990
  const ge = {
6836
6991
  ...F,
@@ -6838,19 +6993,19 @@ const Ve = Me(({
6838
6993
  };
6839
6994
  if (F.onSpeechEnd && p.current) {
6840
6995
  const Y = p.current;
6841
- let he = null, Se = 0;
6996
+ let ue = null, Se = 0;
6842
6997
  const Ae = 1200;
6843
6998
  let be = !1;
6844
- he = setInterval(() => {
6999
+ ue = setInterval(() => {
6845
7000
  if (Se++, E.current)
6846
7001
  return;
6847
7002
  if (Se > Ae) {
6848
- if (he && (clearInterval(he), he = null, y.current = null), !be && !E.current) {
7003
+ if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !E.current) {
6849
7004
  be = !0;
6850
7005
  try {
6851
7006
  F.onSpeechEnd();
6852
- } catch (Ne) {
6853
- console.error("Error in onSpeechEnd callback (timeout):", Ne);
7007
+ } catch (Be) {
7008
+ console.error("Error in onSpeechEnd callback (timeout):", Be);
6854
7009
  }
6855
7010
  }
6856
7011
  return;
@@ -6858,7 +7013,7 @@ const Ve = Me(({
6858
7013
  const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6859
7014
  Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6860
7015
  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) {
6861
- be = !0, he && (clearInterval(he), he = null, y.current = null);
7016
+ be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
6862
7017
  try {
6863
7018
  F.onSpeechEnd();
6864
7019
  } catch (Ze) {
@@ -6866,31 +7021,31 @@ const Ve = Me(({
6866
7021
  }
6867
7022
  }
6868
7023
  }, 100);
6869
- }, 100), y.current = he;
7024
+ }, 100), y.current = ue;
6870
7025
  }
6871
7026
  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 () => {
6872
7027
  await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6873
7028
  }, 100);
6874
- } catch (N) {
6875
- console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
7029
+ } catch (B) {
7030
+ console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
6876
7031
  }
6877
- }, [$, H, v.lipsyncLang]), _ = T(() => {
7032
+ }, [$, H, v.lipsyncLang]), K = T(() => {
6878
7033
  p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
6879
7034
  }, []), j = T(() => {
6880
7035
  if (p.current && p.current.pauseSpeaking) {
6881
7036
  const L = p.current;
6882
7037
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6883
7038
  y.current && (clearInterval(y.current), y.current = null);
6884
- let N = "";
7039
+ let B = "";
6885
7040
  if (z.current && W.current.length > 0) {
6886
- 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, he = ge + (Y ? 1 : 0), Se = J - he;
6887
- if (he > 0 && Se < J && (N = W.current.slice(Se).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
7041
+ 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;
7042
+ if (ue > 0 && Se < J && (B = W.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
6888
7043
  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(" ");
6889
- be && be.trim() && (N = be.trim());
7044
+ be && be.trim() && (B = be.trim());
6890
7045
  }
6891
7046
  }
6892
7047
  z.current && (P.current = {
6893
- remainingText: N || null,
7048
+ remainingText: B || null,
6894
7049
  originalText: z.current.text,
6895
7050
  options: z.current.options
6896
7051
  }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
@@ -6909,12 +7064,12 @@ const Ve = Me(({
6909
7064
  return;
6910
7065
  }
6911
7066
  pe(!1), E.current = !1, await H();
6912
- const N = {
7067
+ const B = {
6913
7068
  ...F,
6914
7069
  lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
6915
7070
  };
6916
7071
  try {
6917
- await U(L, N);
7072
+ await U(L, B);
6918
7073
  } catch (J) {
6919
7074
  console.error("Error resuming speech:", J), pe(!1), E.current = !1;
6920
7075
  }
@@ -6963,9 +7118,9 @@ const Ve = Me(({
6963
7118
  }, [b]), te = T(() => {
6964
7119
  p.current && p.current.onResize && p.current.onResize();
6965
7120
  }, []);
6966
- return Ee(R, () => ({
7121
+ return Ee(I, () => ({
6967
7122
  speakText: U,
6968
- stopSpeaking: _,
7123
+ stopSpeaking: K,
6969
7124
  pauseSpeaking: j,
6970
7125
  resumeSpeaking: q,
6971
7126
  resumeAudioContext: H,
@@ -7047,7 +7202,7 @@ const Ve = Me(({
7047
7202
  /* @__PURE__ */ me(
7048
7203
  "div",
7049
7204
  {
7050
- ref: B,
7205
+ ref: D,
7051
7206
  className: "talking-head-viewer",
7052
7207
  style: {
7053
7208
  width: "100%",
@@ -7065,7 +7220,7 @@ const Ve = Me(({
7065
7220
  fontSize: "18px",
7066
7221
  zIndex: 10
7067
7222
  }, children: "Loading avatar..." }),
7068
- K && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7223
+ _ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7069
7224
  position: "absolute",
7070
7225
  top: "50%",
7071
7226
  left: "50%",
@@ -7076,7 +7231,7 @@ const Ve = Me(({
7076
7231
  zIndex: 10,
7077
7232
  padding: "20px",
7078
7233
  borderRadius: "8px"
7079
- }, children: K })
7234
+ }, children: _ })
7080
7235
  ]
7081
7236
  }
7082
7237
  );
@@ -7094,7 +7249,7 @@ const pt = Me(({
7094
7249
  style: s = {},
7095
7250
  avatarConfig: o = {}
7096
7251
  }, l) => {
7097
- const h = D(null), r = D(null), [u, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), R = o.ttsService || b.service, B = R === "browser" ? {
7252
+ const u = N(null), r = N(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, D = I === "browser" ? {
7098
7253
  endpoint: "",
7099
7254
  apiKey: null,
7100
7255
  defaultVoice: "Google US English"
@@ -7103,14 +7258,14 @@ const pt = Me(({
7103
7258
  // Override API key if provided via avatarConfig
7104
7259
  apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
7105
7260
  // Override endpoint for ElevenLabs if service is explicitly set
7106
- endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7261
+ endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7107
7262
  }, p = {
7108
7263
  url: "/avatars/brunette.glb",
7109
7264
  // Use brunette avatar (working glTF file)
7110
7265
  body: "F",
7111
7266
  avatarMood: "neutral",
7112
- ttsLang: R === "browser" ? "en-US" : "en",
7113
- ttsVoice: o.ttsVoice || B.defaultVoice,
7267
+ ttsLang: I === "browser" ? "en-US" : "en",
7268
+ ttsVoice: o.ttsVoice || D.defaultVoice,
7114
7269
  lipsyncLang: "en",
7115
7270
  // English lip-sync
7116
7271
  showFullAvatar: !0,
@@ -7119,35 +7274,35 @@ const pt = Me(({
7119
7274
  movementIntensity: 0.5,
7120
7275
  ...o
7121
7276
  }, M = {
7122
- ttsEndpoint: B.endpoint,
7123
- ttsApikey: B.apiKey,
7124
- ttsService: R,
7277
+ ttsEndpoint: D.endpoint,
7278
+ ttsApikey: D.apiKey,
7279
+ ttsService: I,
7125
7280
  lipsyncModules: ["en"],
7126
7281
  cameraView: "upper"
7127
7282
  }, z = T(async () => {
7128
- if (!(!h.current || r.current))
7283
+ if (!(!u.current || r.current))
7129
7284
  try {
7130
- if (a(!0), d(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
7131
- if (K.lengthComputable) {
7132
- const X = Math.min(100, Math.round(K.loaded / K.total * 100));
7285
+ if (a(!0), d(null), r.current = new De(u.current, M), await r.current.showAvatar(p, (_) => {
7286
+ if (_.lengthComputable) {
7287
+ const X = Math.min(100, Math.round(_.loaded / _.total * 100));
7133
7288
  t(X);
7134
7289
  }
7135
7290
  }), r.current.morphs && r.current.morphs.length > 0) {
7136
- const K = r.current.morphs[0].morphTargetDictionary;
7137
- console.log("Available morph targets:", Object.keys(K));
7138
- const X = Object.keys(K).filter(($) => $.startsWith("viseme_"));
7291
+ const _ = r.current.morphs[0].morphTargetDictionary;
7292
+ console.log("Available morph targets:", Object.keys(_));
7293
+ const X = Object.keys(_).filter(($) => $.startsWith("viseme_"));
7139
7294
  console.log("Viseme morph targets found:", X), X.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7140
7295
  }
7141
- if (await new Promise((K) => {
7296
+ if (await new Promise((_) => {
7142
7297
  const X = () => {
7143
- r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), K()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
7298
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), _()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
7144
7299
  };
7145
7300
  X();
7146
7301
  }), r.current && r.current.setShowFullAvatar)
7147
7302
  try {
7148
7303
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7149
- } catch (K) {
7150
- console.warn("Error setting full body mode on initialization:", K);
7304
+ } catch (_) {
7305
+ console.warn("Error setting full body mode on initialization:", _);
7151
7306
  }
7152
7307
  a(!1), x(!0), n(r.current);
7153
7308
  const Z = () => {
@@ -7290,7 +7445,7 @@ const pt = Me(({
7290
7445
  /* @__PURE__ */ me(
7291
7446
  "div",
7292
7447
  {
7293
- ref: h,
7448
+ ref: u,
7294
7449
  className: "talking-head-viewer",
7295
7450
  style: {
7296
7451
  width: "100%",
@@ -7299,7 +7454,7 @@ const pt = Me(({
7299
7454
  }
7300
7455
  }
7301
7456
  ),
7302
- u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7457
+ h && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7303
7458
  position: "absolute",
7304
7459
  top: "50%",
7305
7460
  left: "50%",
@@ -7332,9 +7487,9 @@ const gt = Me(({
7332
7487
  ttsService: s = null,
7333
7488
  ttsVoice: o = null,
7334
7489
  ttsApiKey: l = null,
7335
- bodyMovement: h = "idle",
7490
+ bodyMovement: u = "idle",
7336
7491
  movementIntensity: r = 0.5,
7337
- showFullAvatar: u = !1,
7492
+ showFullAvatar: h = !1,
7338
7493
  cameraView: a = "upper",
7339
7494
  onReady: c = () => {
7340
7495
  },
@@ -7345,36 +7500,36 @@ const gt = Me(({
7345
7500
  onSpeechEnd: x = () => {
7346
7501
  },
7347
7502
  className: b = "",
7348
- style: R = {},
7349
- animations: B = {},
7503
+ style: I = {},
7504
+ animations: D = {},
7350
7505
  autoSpeak: p = !1
7351
7506
  }, M) => {
7352
- const z = D(null), y = D(null), E = D(u), P = D(null), W = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7507
+ const z = N(null), y = N(null), E = N(h), P = N(null), W = N(null), oe = N(!1), S = N({ remainingText: null, originalText: null, options: null }), Z = N([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7353
7508
  de(() => {
7354
7509
  oe.current = ee;
7355
7510
  }, [ee]), de(() => {
7356
- E.current = u;
7357
- }, [u]);
7511
+ E.current = h;
7512
+ }, [h]);
7358
7513
  const O = Fe(), v = s || O.service;
7359
- let I;
7360
- v === "browser" ? I = {
7514
+ let R;
7515
+ v === "browser" ? R = {
7361
7516
  service: "browser",
7362
7517
  endpoint: "",
7363
7518
  apiKey: null,
7364
7519
  defaultVoice: "Google US English"
7365
- } : v === "elevenlabs" ? I = {
7520
+ } : v === "elevenlabs" ? R = {
7366
7521
  service: "elevenlabs",
7367
7522
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7368
7523
  apiKey: l || O.apiKey,
7369
- defaultVoice: o || O.defaultVoice || Re.defaultVoice,
7370
- voices: O.voices || Re.voices
7371
- } : v === "deepgram" ? I = {
7524
+ defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
7525
+ voices: O.voices || Ie.voices
7526
+ } : v === "deepgram" ? R = {
7372
7527
  service: "deepgram",
7373
7528
  endpoint: "https://api.deepgram.com/v1/speak",
7374
7529
  apiKey: l || O.apiKey,
7375
7530
  defaultVoice: o || O.defaultVoice || Te.defaultVoice,
7376
7531
  voices: O.voices || Te.voices
7377
- } : I = {
7532
+ } : R = {
7378
7533
  ...O,
7379
7534
  apiKey: l !== null ? l : O.apiKey
7380
7535
  };
@@ -7383,21 +7538,21 @@ const gt = Me(({
7383
7538
  body: e,
7384
7539
  avatarMood: n,
7385
7540
  ttsLang: v === "browser" ? "en-US" : i,
7386
- ttsVoice: o || I.defaultVoice,
7541
+ ttsVoice: o || R.defaultVoice,
7387
7542
  lipsyncLang: "en",
7388
- showFullAvatar: u,
7389
- bodyMovement: h,
7543
+ showFullAvatar: h,
7544
+ bodyMovement: u,
7390
7545
  movementIntensity: r
7391
7546
  }, H = {
7392
- ttsEndpoint: I.endpoint,
7393
- ttsApikey: I.apiKey,
7547
+ ttsEndpoint: R.endpoint,
7548
+ ttsApikey: R.apiKey,
7394
7549
  ttsService: v,
7395
7550
  lipsyncModules: ["en"],
7396
7551
  cameraView: a
7397
7552
  }, U = T(async () => {
7398
7553
  if (!(!z.current || y.current))
7399
7554
  try {
7400
- X(!0), se(null), y.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7555
+ X(!0), se(null), y.current = new De(z.current, H), console.log("Avatar config being passed:", {
7401
7556
  url: k.url,
7402
7557
  body: k.body,
7403
7558
  avatarMood: k.avatarMood
@@ -7420,7 +7575,7 @@ const gt = Me(({
7420
7575
  de(() => (U(), () => {
7421
7576
  y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7422
7577
  }), [U]);
7423
- const _ = T(async () => {
7578
+ const K = T(async () => {
7424
7579
  if (y.current)
7425
7580
  try {
7426
7581
  const C = y.current.audioCtx || y.current.audioContext;
@@ -7437,8 +7592,8 @@ const gt = Me(({
7437
7592
  console.warn("No text provided to speak");
7438
7593
  return;
7439
7594
  }
7440
- await _(), 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;
7441
- const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
7595
+ 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;
7596
+ const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
7442
7597
  Z.current = L;
7443
7598
  const F = {
7444
7599
  lipsyncLang: te.lipsyncLang || "en",
@@ -7448,10 +7603,10 @@ const gt = Me(({
7448
7603
  };
7449
7604
  try {
7450
7605
  y.current.speakText(C, F);
7451
- } catch (N) {
7452
- console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
7606
+ } catch (B) {
7607
+ console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
7453
7608
  }
7454
- }, [ae, x, _]);
7609
+ }, [ae, x, K]);
7455
7610
  de(() => {
7456
7611
  ae && G && p && y.current && j(G);
7457
7612
  }, [ae, G, p, j]);
@@ -7462,7 +7617,7 @@ const gt = Me(({
7462
7617
  if (C || te.length > 0 || L.length > 0) {
7463
7618
  W.current && (clearInterval(W.current), W.current = null);
7464
7619
  let F = "";
7465
- 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 = {
7620
+ L.length > 0 && (F = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map((J) => J.word).join(" ") : B.text || "").join(" ")), S.current = {
7466
7621
  remainingText: F || null,
7467
7622
  originalText: P.current?.text || null,
7468
7623
  options: P.current?.options || null
@@ -7474,13 +7629,13 @@ const gt = Me(({
7474
7629
  }, []), Le = T(async () => {
7475
7630
  if (!(!y.current || !ee))
7476
7631
  try {
7477
- await _(), le(!1), oe.current = !1;
7632
+ await K(), le(!1), oe.current = !1;
7478
7633
  const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
7479
7634
  F && j(F, L);
7480
7635
  } catch (C) {
7481
7636
  console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
7482
7637
  }
7483
- }, [ee, j, _]), we = T(() => {
7638
+ }, [ee, j, K]), we = T(() => {
7484
7639
  y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
7485
7640
  }, []);
7486
7641
  return Ee(M, () => ({
@@ -7488,7 +7643,7 @@ const gt = Me(({
7488
7643
  pauseSpeaking: q,
7489
7644
  resumeSpeaking: Le,
7490
7645
  stopSpeaking: we,
7491
- resumeAudioContext: _,
7646
+ resumeAudioContext: K,
7492
7647
  isPaused: () => ee,
7493
7648
  setMood: (C) => y.current?.setMood(C),
7494
7649
  setBodyMovement: (C) => {
@@ -7504,7 +7659,7 @@ const gt = Me(({
7504
7659
  },
7505
7660
  isReady: ae,
7506
7661
  talkingHead: y.current
7507
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: R, children: [
7662
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7508
7663
  /* @__PURE__ */ me(
7509
7664
  "div",
7510
7665
  {
@@ -7517,7 +7672,7 @@ const gt = Me(({
7517
7672
  }
7518
7673
  }
7519
7674
  ),
7520
- K && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7675
+ _ && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7521
7676
  position: "absolute",
7522
7677
  top: "50%",
7523
7678
  left: "50%",
@@ -7555,9 +7710,9 @@ const yt = Me(({
7555
7710
  },
7556
7711
  onCustomAction: l = () => {
7557
7712
  },
7558
- autoStart: h = !1
7713
+ autoStart: u = !1
7559
7714
  }, r) => {
7560
- const u = D(null), a = D({
7715
+ const h = N(null), a = N({
7561
7716
  currentModuleIndex: 0,
7562
7717
  currentLessonIndex: 0,
7563
7718
  currentQuestionIndex: 0,
@@ -7567,18 +7722,18 @@ const yt = Me(({
7567
7722
  curriculumCompleted: !1,
7568
7723
  score: 0,
7569
7724
  totalQuestions: 0
7570
- }), c = D({
7725
+ }), c = N({
7571
7726
  onLessonStart: n,
7572
7727
  onLessonComplete: i,
7573
7728
  onQuestionAnswer: s,
7574
7729
  onCurriculumComplete: o,
7575
7730
  onCustomAction: l
7576
- }), d = D(null), g = D(null), x = D(null), b = D(null), R = D(null), B = D(null), p = D(null), M = D(G?.curriculum || {
7731
+ }), d = N(null), g = N(null), x = N(null), b = N(null), I = N(null), D = N(null), p = N(null), M = N(G?.curriculum || {
7577
7732
  title: "Default Curriculum",
7578
7733
  description: "No curriculum data provided",
7579
7734
  language: "en",
7580
7735
  modules: []
7581
- }), z = D({
7736
+ }), z = N({
7582
7737
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7583
7738
  avatarBody: t.avatarBody || "F",
7584
7739
  mood: t.mood || "happy",
@@ -7621,11 +7776,11 @@ const yt = Me(({
7621
7776
  lipsyncLang: "en"
7622
7777
  };
7623
7778
  }, [G, t, e]);
7624
- 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, 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, []), W = T(() => {
7779
+ 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(() => {
7625
7780
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7626
7781
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7627
- let I = "Congratulations! You've completed this lesson";
7628
- 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({
7782
+ let R = "Congratulations! You've completed this lesson";
7783
+ 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({
7629
7784
  moduleIndex: a.current.currentModuleIndex,
7630
7785
  lessonIndex: a.current.currentLessonIndex,
7631
7786
  score: a.current.score,
@@ -7638,15 +7793,15 @@ const yt = Me(({
7638
7793
  score: a.current.score,
7639
7794
  totalQuestions: a.current.totalQuestions,
7640
7795
  percentage: v
7641
- }), u.current) {
7642
- if (u.current.setMood("happy"), e.lessonComplete)
7796
+ }), h.current) {
7797
+ if (h.current.setMood("happy"), e.lessonComplete)
7643
7798
  try {
7644
- u.current.playAnimation(e.lessonComplete, !0);
7799
+ h.current.playAnimation(e.lessonComplete, !0);
7645
7800
  } catch {
7646
- u.current.playCelebration();
7801
+ h.current.playCelebration();
7647
7802
  }
7648
- const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = U || _, q = z.current || { lipsyncLang: "en" };
7649
- u.current.speakText(I, {
7803
+ 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" };
7804
+ h.current.speakText(R, {
7650
7805
  lipsyncLang: q.lipsyncLang,
7651
7806
  onSpeechEnd: () => {
7652
7807
  c.current.onCustomAction({
@@ -7666,49 +7821,49 @@ const yt = Me(({
7666
7821
  const v = M.current || { modules: [] };
7667
7822
  if (c.current.onCurriculumComplete({
7668
7823
  modules: v.modules.length,
7669
- totalLessons: v.modules.reduce((I, k) => I + k.lessons.length, 0)
7670
- }), u.current) {
7671
- if (u.current.setMood("celebrating"), e.curriculumComplete)
7824
+ totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
7825
+ }), h.current) {
7826
+ if (h.current.setMood("celebrating"), e.curriculumComplete)
7672
7827
  try {
7673
- u.current.playAnimation(e.curriculumComplete, !0);
7828
+ h.current.playAnimation(e.curriculumComplete, !0);
7674
7829
  } catch {
7675
- u.current.playCelebration();
7830
+ h.current.playCelebration();
7676
7831
  }
7677
- const I = z.current || { lipsyncLang: "en" };
7678
- u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: I.lipsyncLang });
7832
+ const R = z.current || { lipsyncLang: "en" };
7833
+ 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 });
7679
7834
  }
7680
7835
  }, [e.curriculumComplete]), S = T(() => {
7681
7836
  const v = y();
7682
7837
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7683
- const I = E();
7684
- I && c.current.onCustomAction({
7838
+ const R = E();
7839
+ R && c.current.onCustomAction({
7685
7840
  type: "questionStart",
7686
7841
  moduleIndex: a.current.currentModuleIndex,
7687
7842
  lessonIndex: a.current.currentLessonIndex,
7688
7843
  questionIndex: a.current.currentQuestionIndex,
7689
7844
  totalQuestions: a.current.totalQuestions,
7690
- question: I,
7845
+ question: R,
7691
7846
  score: a.current.score
7692
7847
  });
7693
7848
  const k = () => {
7694
- if (!u.current || !I) return;
7695
- if (u.current.setMood("happy"), e.questionStart)
7849
+ if (!h.current || !R) return;
7850
+ if (h.current.setMood("happy"), e.questionStart)
7696
7851
  try {
7697
- u.current.playAnimation(e.questionStart, !0);
7852
+ h.current.playAnimation(e.questionStart, !0);
7698
7853
  } catch (U) {
7699
7854
  console.warn("Failed to play questionStart animation:", U);
7700
7855
  }
7701
7856
  const H = z.current || { lipsyncLang: "en" };
7702
- I.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: H.lipsyncLang }) : I.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: H.lipsyncLang }) : I.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: H.lipsyncLang });
7857
+ 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 });
7703
7858
  };
7704
- if (u.current && u.current.isReady && I)
7859
+ if (h.current && h.current.isReady && R)
7705
7860
  k();
7706
- else if (u.current && u.current.isReady) {
7861
+ else if (h.current && h.current.isReady) {
7707
7862
  const H = z.current || { lipsyncLang: "en" };
7708
- u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7863
+ h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7709
7864
  } else {
7710
7865
  const H = setInterval(() => {
7711
- u.current && u.current.isReady && (clearInterval(H), I && k());
7866
+ h.current && h.current.isReady && (clearInterval(H), R && k());
7712
7867
  }, 100);
7713
7868
  setTimeout(() => {
7714
7869
  clearInterval(H);
@@ -7717,53 +7872,53 @@ const yt = Me(({
7717
7872
  }, [e.questionStart, y, E]), Z = T(() => {
7718
7873
  const v = y();
7719
7874
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7720
- u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7721
- const I = E();
7722
- I && c.current.onCustomAction({
7875
+ h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7876
+ const R = E();
7877
+ R && c.current.onCustomAction({
7723
7878
  type: "nextQuestion",
7724
7879
  moduleIndex: a.current.currentModuleIndex,
7725
7880
  lessonIndex: a.current.currentLessonIndex,
7726
7881
  questionIndex: a.current.currentQuestionIndex,
7727
7882
  totalQuestions: a.current.totalQuestions,
7728
- question: I,
7883
+ question: R,
7729
7884
  score: a.current.score
7730
7885
  });
7731
7886
  const k = () => {
7732
- if (!u.current || !I) return;
7733
- if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7887
+ if (!h.current || !R) return;
7888
+ if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7734
7889
  try {
7735
- u.current.playAnimation(e.nextQuestion, !0);
7890
+ h.current.playAnimation(e.nextQuestion, !0);
7736
7891
  } catch (q) {
7737
7892
  console.warn("Failed to play nextQuestion animation:", q);
7738
7893
  }
7739
- const H = z.current || { lipsyncLang: "en" }, _ = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7740
- if (I.type === "code_test") {
7741
- 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}`;
7742
- u.current.speakText(q, {
7894
+ const H = z.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7895
+ if (R.type === "code_test") {
7896
+ 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}`;
7897
+ h.current.speakText(q, {
7743
7898
  lipsyncLang: H.lipsyncLang
7744
7899
  });
7745
- } else if (I.type === "multiple_choice") {
7746
- const q = j ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
7747
- u.current.speakText(q, {
7900
+ } else if (R.type === "multiple_choice") {
7901
+ const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7902
+ h.current.speakText(q, {
7748
7903
  lipsyncLang: H.lipsyncLang
7749
7904
  });
7750
- } else if (I.type === "true_false") {
7751
- const q = j ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
7752
- u.current.speakText(q, {
7905
+ } else if (R.type === "true_false") {
7906
+ const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7907
+ h.current.speakText(q, {
7753
7908
  lipsyncLang: H.lipsyncLang
7754
7909
  });
7755
7910
  } else {
7756
- const q = j ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
7757
- u.current.speakText(q, {
7911
+ const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7912
+ h.current.speakText(q, {
7758
7913
  lipsyncLang: H.lipsyncLang
7759
7914
  });
7760
7915
  }
7761
7916
  };
7762
- if (u.current && u.current.isReady && I)
7917
+ if (h.current && h.current.isReady && R)
7763
7918
  k();
7764
- else if (I) {
7919
+ else if (R) {
7765
7920
  const H = setInterval(() => {
7766
- u.current && u.current.isReady && (clearInterval(H), k());
7921
+ h.current && h.current.isReady && (clearInterval(H), k());
7767
7922
  }, 100);
7768
7923
  setTimeout(() => {
7769
7924
  clearInterval(H);
@@ -7777,11 +7932,11 @@ const yt = Me(({
7777
7932
  totalQuestions: a.current.totalQuestions,
7778
7933
  score: a.current.score
7779
7934
  });
7780
- }, [e.nextQuestion, y, E]), K = T(() => {
7781
- const v = M.current || { modules: [] }, I = v.modules[a.current.currentModuleIndex];
7782
- if (a.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
7935
+ }, [e.nextQuestion, y, E]), _ = T(() => {
7936
+ const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7937
+ if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7783
7938
  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;
7784
- const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = U || _;
7939
+ 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;
7785
7940
  c.current.onCustomAction({
7786
7941
  type: "lessonStart",
7787
7942
  moduleIndex: a.current.currentModuleIndex,
@@ -7791,10 +7946,10 @@ const yt = Me(({
7791
7946
  moduleIndex: a.current.currentModuleIndex,
7792
7947
  lessonIndex: a.current.currentLessonIndex,
7793
7948
  lesson: y()
7794
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7949
+ }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7795
7950
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7796
7951
  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;
7797
- const U = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
7952
+ 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;
7798
7953
  c.current.onCustomAction({
7799
7954
  type: "lessonStart",
7800
7955
  moduleIndex: a.current.currentModuleIndex,
@@ -7804,27 +7959,27 @@ const yt = Me(({
7804
7959
  moduleIndex: a.current.currentModuleIndex,
7805
7960
  lessonIndex: a.current.currentLessonIndex,
7806
7961
  lesson: y()
7807
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7962
+ }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7808
7963
  } else
7809
- R.current && R.current();
7964
+ I.current && I.current();
7810
7965
  }, []), X = T(() => {
7811
7966
  const v = y();
7812
- let I = null;
7967
+ let R = null;
7813
7968
  if (v?.avatar_script && v?.body) {
7814
7969
  const k = v.avatar_script.trim(), H = v.body.trim(), U = k.match(/[.!?]$/) ? " " : ". ";
7815
- I = `${k}${U}${H}`;
7970
+ R = `${k}${U}${H}`;
7816
7971
  } else
7817
- I = v?.avatar_script || v?.body || null;
7818
- if (u.current && u.current.isReady && I) {
7819
- a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
7972
+ R = v?.avatar_script || v?.body || null;
7973
+ if (h.current && h.current.isReady && R) {
7974
+ a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
7820
7975
  let k = !1;
7821
7976
  if (e.teaching)
7822
7977
  try {
7823
- u.current.playAnimation(e.teaching, !0), k = !0;
7978
+ h.current.playAnimation(e.teaching, !0), k = !0;
7824
7979
  } catch (U) {
7825
7980
  console.warn("Failed to play teaching animation:", U);
7826
7981
  }
7827
- k || u.current.setBodyMovement("gesturing");
7982
+ k || h.current.setBodyMovement("gesturing");
7828
7983
  const H = z.current || { lipsyncLang: "en" };
7829
7984
  c.current.onLessonStart({
7830
7985
  moduleIndex: a.current.currentModuleIndex,
@@ -7835,7 +7990,7 @@ const yt = Me(({
7835
7990
  moduleIndex: a.current.currentModuleIndex,
7836
7991
  lessonIndex: a.current.currentLessonIndex,
7837
7992
  lesson: v
7838
- }), u.current.speakText(I, {
7993
+ }), h.current.speakText(R, {
7839
7994
  lipsyncLang: H.lipsyncLang,
7840
7995
  onSpeechEnd: () => {
7841
7996
  a.current.isTeaching = !1, c.current.onCustomAction({
@@ -7855,29 +8010,29 @@ const yt = Me(({
7855
8010
  });
7856
8011
  }
7857
8012
  }, [e.teaching, y]), $ = T((v) => {
7858
- const I = E(), k = P(v, I);
8013
+ const R = E(), k = P(v, R);
7859
8014
  if (k && (a.current.score += 1), c.current.onQuestionAnswer({
7860
8015
  moduleIndex: a.current.currentModuleIndex,
7861
8016
  lessonIndex: a.current.currentLessonIndex,
7862
8017
  questionIndex: a.current.currentQuestionIndex,
7863
8018
  answer: v,
7864
8019
  isCorrect: k,
7865
- question: I
7866
- }), u.current)
8020
+ question: R
8021
+ }), h.current)
7867
8022
  if (k) {
7868
- if (u.current.setMood("happy"), e.correct)
8023
+ if (h.current.setMood("happy"), e.correct)
7869
8024
  try {
7870
- u.current.playReaction("happy");
8025
+ h.current.playReaction("happy");
7871
8026
  } catch {
7872
- u.current.setBodyMovement("happy");
8027
+ h.current.setBodyMovement("happy");
7873
8028
  }
7874
- u.current.setBodyMovement("gesturing");
8029
+ h.current.setBodyMovement("gesturing");
7875
8030
  const U = y()?.questions?.length || 0;
7876
8031
  a.current.currentQuestionIndex >= U - 1;
7877
- const _ = a.current.currentQuestionIndex < U - 1;
7878
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", _);
7879
- const j = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
7880
- u.current.speakText(j, {
8032
+ const K = a.current.currentQuestionIndex < U - 1;
8033
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", K);
8034
+ 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" };
8035
+ h.current.speakText(j, {
7881
8036
  lipsyncLang: q.lipsyncLang,
7882
8037
  onSpeechEnd: () => {
7883
8038
  c.current.onCustomAction({
@@ -7886,24 +8041,24 @@ const yt = Me(({
7886
8041
  lessonIndex: a.current.currentLessonIndex,
7887
8042
  questionIndex: a.current.currentQuestionIndex,
7888
8043
  isCorrect: !0,
7889
- hasNextQuestion: _,
8044
+ hasNextQuestion: K,
7890
8045
  score: a.current.score,
7891
8046
  totalQuestions: a.current.totalQuestions
7892
8047
  });
7893
8048
  }
7894
8049
  });
7895
8050
  } else {
7896
- if (u.current.setMood("sad"), e.incorrect)
8051
+ if (h.current.setMood("sad"), e.incorrect)
7897
8052
  try {
7898
- u.current.playAnimation(e.incorrect, !0);
8053
+ h.current.playAnimation(e.incorrect, !0);
7899
8054
  } catch {
7900
- u.current.setBodyMovement("idle");
8055
+ h.current.setBodyMovement("idle");
7901
8056
  }
7902
- u.current.setBodyMovement("gesturing");
7903
- const U = y()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
8057
+ h.current.setBodyMovement("gesturing");
8058
+ const U = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
7904
8059
  console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
7905
- const q = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
7906
- u.current.speakText(q, {
8060
+ 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" };
8061
+ h.current.speakText(q, {
7907
8062
  lipsyncLang: Le.lipsyncLang,
7908
8063
  onSpeechEnd: () => {
7909
8064
  c.current.onCustomAction({
@@ -7934,12 +8089,12 @@ const yt = Me(({
7934
8089
  });
7935
8090
  }
7936
8091
  }, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
7937
- const I = E();
8092
+ const R = E();
7938
8093
  if (!v || typeof v != "object") {
7939
8094
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
7940
8095
  return;
7941
8096
  }
7942
- if (I?.type !== "code_test") {
8097
+ if (R?.type !== "code_test") {
7943
8098
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7944
8099
  return;
7945
8100
  }
@@ -7959,7 +8114,7 @@ const yt = Me(({
7959
8114
  lessonIndex: a.current.currentLessonIndex,
7960
8115
  questionIndex: a.current.currentQuestionIndex,
7961
8116
  testResult: k,
7962
- question: I
8117
+ question: R
7963
8118
  }), p.current && p.current(k);
7964
8119
  }, [E, P]), ae = T(() => {
7965
8120
  if (a.current.currentQuestionIndex > 0) {
@@ -7974,21 +8129,21 @@ const yt = Me(({
7974
8129
  question: v,
7975
8130
  score: a.current.score
7976
8131
  });
7977
- const I = () => {
7978
- if (!u.current || !v) return;
7979
- u.current.setMood("happy"), u.current.setBodyMovement("idle");
8132
+ const R = () => {
8133
+ if (!h.current || !v) return;
8134
+ h.current.setMood("happy"), h.current.setBodyMovement("idle");
7980
8135
  const k = z.current || { lipsyncLang: "en" };
7981
- v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8136
+ v.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
7982
8137
  lipsyncLang: k.lipsyncLang
7983
- }) : u.current.speakText(`Going back to: ${v.question}`, {
8138
+ }) : h.current.speakText(`Going back to: ${v.question}`, {
7984
8139
  lipsyncLang: k.lipsyncLang
7985
8140
  });
7986
8141
  };
7987
- if (u.current && u.current.isReady && v)
7988
- I();
8142
+ if (h.current && h.current.isReady && v)
8143
+ R();
7989
8144
  else if (v) {
7990
8145
  const k = setInterval(() => {
7991
- u.current && u.current.isReady && (clearInterval(k), I());
8146
+ h.current && h.current.isReady && (clearInterval(k), R());
7992
8147
  }, 100);
7993
8148
  setTimeout(() => {
7994
8149
  clearInterval(k);
@@ -8006,7 +8161,7 @@ const yt = Me(({
8006
8161
  moduleIndex: a.current.currentModuleIndex,
8007
8162
  lessonIndex: a.current.currentLessonIndex,
8008
8163
  lesson: y()
8009
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8164
+ }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8010
8165
  else if (a.current.currentModuleIndex > 0) {
8011
8166
  const H = v.modules[a.current.currentModuleIndex - 1];
8012
8167
  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({
@@ -8017,19 +8172,19 @@ const yt = Me(({
8017
8172
  moduleIndex: a.current.currentModuleIndex,
8018
8173
  lessonIndex: a.current.currentLessonIndex,
8019
8174
  lesson: y()
8020
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8175
+ }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8021
8176
  }
8022
8177
  }, [y]), ee = T(() => {
8023
8178
  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;
8024
8179
  }, []), le = T((v) => {
8025
8180
  console.log("Avatar is ready!", v);
8026
- const I = y(), k = I?.avatar_script || I?.body;
8027
- h && k && setTimeout(() => {
8181
+ const R = y(), k = R?.avatar_script || R?.body;
8182
+ u && k && setTimeout(() => {
8028
8183
  d.current && d.current();
8029
8184
  }, 10);
8030
- }, [h, y]);
8185
+ }, [u, y]);
8031
8186
  Xe(() => {
8032
- d.current = X, g.current = K, x.current = W, b.current = Z, R.current = oe, B.current = S, p.current = $;
8187
+ d.current = X, g.current = _, x.current = W, b.current = Z, I.current = oe, D.current = S, p.current = $;
8033
8188
  }), Ee(r, () => ({
8034
8189
  // Curriculum control methods
8035
8190
  startTeaching: X,
@@ -8038,7 +8193,7 @@ const yt = Me(({
8038
8193
  handleCodeTestResult: se,
8039
8194
  nextQuestion: Z,
8040
8195
  previousQuestion: ae,
8041
- nextLesson: K,
8196
+ nextLesson: _,
8042
8197
  previousLesson: pe,
8043
8198
  completeLesson: W,
8044
8199
  completeCurriculum: oe,
@@ -8047,56 +8202,56 @@ const yt = Me(({
8047
8202
  getCurrentQuestion: () => E(),
8048
8203
  getCurrentLesson: () => y(),
8049
8204
  // Direct access to avatar ref (always returns current value)
8050
- getAvatarRef: () => u.current,
8205
+ getAvatarRef: () => h.current,
8051
8206
  // Convenience methods that delegate to avatar (always check current ref)
8052
- speakText: async (v, I = {}) => {
8053
- await u.current?.resumeAudioContext?.();
8207
+ speakText: async (v, R = {}) => {
8208
+ await h.current?.resumeAudioContext?.();
8054
8209
  const k = z.current || { lipsyncLang: "en" };
8055
- u.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || k.lipsyncLang });
8210
+ h.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
8056
8211
  },
8057
8212
  resumeAudioContext: async () => {
8058
- if (u.current?.resumeAudioContext)
8059
- return await u.current.resumeAudioContext();
8060
- const v = u.current?.talkingHead;
8213
+ if (h.current?.resumeAudioContext)
8214
+ return await h.current.resumeAudioContext();
8215
+ const v = h.current?.talkingHead;
8061
8216
  if (v?.audioCtx) {
8062
- const I = v.audioCtx;
8063
- if (I.state === "suspended" || I.state === "interrupted")
8217
+ const R = v.audioCtx;
8218
+ if (R.state === "suspended" || R.state === "interrupted")
8064
8219
  try {
8065
- await I.resume(), console.log("Audio context resumed via talkingHead");
8220
+ await R.resume(), console.log("Audio context resumed via talkingHead");
8066
8221
  } catch (k) {
8067
8222
  console.warn("Failed to resume audio context:", k);
8068
8223
  }
8069
8224
  } else
8070
8225
  console.warn("Audio context not available yet");
8071
8226
  },
8072
- stopSpeaking: () => u.current?.stopSpeaking(),
8073
- pauseSpeaking: () => u.current?.pauseSpeaking(),
8074
- resumeSpeaking: async () => await u.current?.resumeSpeaking(),
8075
- isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
8076
- setMood: (v) => u.current?.setMood(v),
8077
- playAnimation: (v, I) => u.current?.playAnimation(v, I),
8078
- setBodyMovement: (v) => u.current?.setBodyMovement(v),
8079
- setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
8080
- playRandomDance: () => u.current?.playRandomDance(),
8081
- playReaction: (v) => u.current?.playReaction(v),
8082
- playCelebration: () => u.current?.playCelebration(),
8083
- setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
8084
- setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
8085
- lockAvatarPosition: () => u.current?.lockAvatarPosition(),
8086
- unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8227
+ stopSpeaking: () => h.current?.stopSpeaking(),
8228
+ pauseSpeaking: () => h.current?.pauseSpeaking(),
8229
+ resumeSpeaking: async () => await h.current?.resumeSpeaking(),
8230
+ isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
8231
+ setMood: (v) => h.current?.setMood(v),
8232
+ playAnimation: (v, R) => h.current?.playAnimation(v, R),
8233
+ setBodyMovement: (v) => h.current?.setBodyMovement(v),
8234
+ setMovementIntensity: (v) => h.current?.setMovementIntensity(v),
8235
+ playRandomDance: () => h.current?.playRandomDance(),
8236
+ playReaction: (v) => h.current?.playReaction(v),
8237
+ playCelebration: () => h.current?.playCelebration(),
8238
+ setShowFullAvatar: (v) => h.current?.setShowFullAvatar(v),
8239
+ setTimingAdjustment: (v) => h.current?.setTimingAdjustment(v),
8240
+ lockAvatarPosition: () => h.current?.lockAvatarPosition(),
8241
+ unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
8087
8242
  // Custom action trigger
8088
- triggerCustomAction: (v, I) => {
8243
+ triggerCustomAction: (v, R) => {
8089
8244
  c.current.onCustomAction({
8090
8245
  type: v,
8091
- ...I,
8246
+ ...R,
8092
8247
  state: { ...a.current }
8093
8248
  });
8094
8249
  },
8095
8250
  // Responsive resize handler
8096
- handleResize: () => u.current?.handleResize(),
8251
+ handleResize: () => h.current?.handleResize(),
8097
8252
  // Avatar readiness check (always returns current value)
8098
- isAvatarReady: () => u.current?.isReady || !1
8099
- }), [X, S, $, se, Z, K, W, oe, ee, E, y]);
8253
+ isAvatarReady: () => h.current?.isReady || !1
8254
+ }), [X, S, $, se, Z, _, W, oe, ee, E, y]);
8100
8255
  const O = z.current || {
8101
8256
  avatarUrl: "/avatars/brunette.glb",
8102
8257
  avatarBody: "F",
@@ -8113,7 +8268,7 @@ const yt = Me(({
8113
8268
  return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
8114
8269
  Ve,
8115
8270
  {
8116
- ref: u,
8271
+ ref: h,
8117
8272
  avatarUrl: O.avatarUrl,
8118
8273
  avatarBody: O.avatarBody,
8119
8274
  mood: O.mood,