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

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,10 +1,10 @@
1
1
  import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
2
+ import { forwardRef as Me, useRef as D, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
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 Oe } from "three/addons/loaders/FBXLoader.js";
7
+ import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
9
  import Ke from "three/addons/libs/stats.module.js";
10
10
  let m, re, ue;
@@ -12,7 +12,7 @@ const A = [0, 0, 0, 0], w = new f.Vector3(), ze = new f.Vector3(), ne = new f.Ve
12
12
  new f.Plane();
13
13
  new f.Ray();
14
14
  new f.Euler();
15
- const ie = new f.Quaternion(), De = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
15
+ const ie = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
16
  new f.Vector3();
17
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);
18
18
  class et {
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(De.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
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;
342
342
  try {
343
343
  this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
344
344
  } catch (a) {
@@ -369,7 +369,7 @@ 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(De.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(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
373
373
  for (n = 0, s = o.excludes.length; n < s; n++)
374
374
  m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (ue = w.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(w), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
@@ -608,8 +608,8 @@ class tt {
608
608
  for (let a = 0; a < i / 2; a++) {
609
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
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, I = r * l + u * o;
612
- r = b, u = I;
611
+ const b = r * o - u * l, R = r * l + u * o;
612
+ r = b, u = R;
613
613
  }
614
614
  }
615
615
  }
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2632
+ }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Ie = new f.Vector3(), We = new f.Box3();
2633
2633
  new f.Matrix4();
2634
2634
  new f.Matrix4();
2635
2635
  new f.Vector3();
@@ -4228,13 +4228,13 @@ class Be {
4228
4228
  const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4229
4229
  l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (h = 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, I = l.getZ(g) + c.getZ(g) * u;
4232
- l.setXYZ(g, x, b, I);
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);
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, I = h.getZ(g) + d.getZ(g) * u;
4237
- h.setXYZ(g, x, b, I);
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);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4666,43 +4666,31 @@ class Be {
4666
4666
  x: this.armature.position.x,
4667
4667
  y: this.armature.position.y,
4668
4668
  z: this.armature.position.z
4669
- }, console.log("Original position stored:", this.originalPosition));
4670
- const t = 2;
4671
- this.lockedPosition = {
4672
- x: 0,
4673
- // Keep centered horizontally
4674
- y: t,
4675
- // Set to the upward offset directly
4676
- z: 0
4677
- // Keep centered horizontally
4678
- }, this.armature.position.set(
4679
- this.lockedPosition.x,
4680
- this.lockedPosition.y,
4681
- this.lockedPosition.z
4682
- ), console.log("BEFORE: Avatar position was:", this.armature.position.x, this.armature.position.y, this.armature.position.z), console.log("AFTER: Avatar position moved up and locked at:", this.lockedPosition), console.log("Current view:", this.viewName);
4669
+ }, console.log("Original position stored:", this.originalPosition)), this.lockedPosition = {
4670
+ x: this.armature.position.x,
4671
+ y: this.armature.position.y,
4672
+ z: this.armature.position.z
4673
+ }, console.log("Avatar position locked at current position:", this.lockedPosition);
4683
4674
  }
4684
4675
  /**
4685
- * Unlock avatar position and reset to center.
4676
+ * Unlock avatar position and restore original position.
4686
4677
  */
4687
4678
  unlockAvatarPosition() {
4688
- this.armature && (this.armature.position.set(0, 0, 0), console.log("Avatar position reset to center (0,0,0)")), this.lockedPosition = null, console.log("Avatar position unlocked");
4679
+ this.armature && this.originalPosition ? (this.armature.position.set(
4680
+ this.originalPosition.x,
4681
+ this.originalPosition.y,
4682
+ this.originalPosition.z
4683
+ ), console.log("Avatar position restored to original:", this.originalPosition)) : this.armature && (this.armature.position.set(0, 0, 0), console.log("Avatar position reset to center (0,0,0)")), this.lockedPosition = null, this.originalPosition = null, console.log("Avatar position unlocked");
4689
4684
  }
4690
4685
  /**
4691
4686
  * Ensure avatar stays at locked position.
4692
4687
  */
4693
4688
  maintainLockedPosition() {
4694
- if (this.lockedPosition && this.armature) {
4695
- const t = this.armature.position.y, e = this.lockedPosition.y - 2, n = this.lockedPosition.y + 0.1;
4696
- t < e ? this.armature.position.set(
4697
- this.lockedPosition.x,
4698
- e,
4699
- this.lockedPosition.z
4700
- ) : t > n && this.armature.position.set(
4701
- this.lockedPosition.x,
4702
- n,
4703
- this.lockedPosition.z
4704
- ), this.armature.position.x = this.lockedPosition.x, this.armature.position.z = this.lockedPosition.z;
4705
- }
4689
+ this.lockedPosition && this.armature && this.armature.position.set(
4690
+ this.lockedPosition.x,
4691
+ this.lockedPosition.y,
4692
+ this.lockedPosition.z
4693
+ );
4706
4694
  }
4707
4695
  /**
4708
4696
  * Create body movement animation.
@@ -5205,7 +5193,7 @@ class Be {
5205
5193
  eyeLookOutRight: [null, 0],
5206
5194
  eyeContact: [0]
5207
5195
  }
5208
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5196
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (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)
5209
5197
  this.stats && this.stats.end();
5210
5198
  else {
5211
5199
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
@@ -5276,10 +5264,10 @@ class Be {
5276
5264
  let u = "", a = "", c = 0, d = [], g = [];
5277
5265
  const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5278
5266
  for (let b = 0; b < x.length; b++) {
5279
- const I = b === x.length - 1, B = x[b].match(l);
5267
+ const R = b === x.length - 1, B = x[b].match(l);
5280
5268
  let p = x[b].match(s);
5281
5269
  const M = x[b].match(h), z = x[b].match(o);
5282
- if (p && !I && !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 || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
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({
5283
5271
  mark: c,
5284
5272
  word: a
5285
5273
  })), u.length && (g.push({
@@ -5305,8 +5293,8 @@ class Be {
5305
5293
  }
5306
5294
  a = "", c++;
5307
5295
  }
5308
- if (p || I) {
5309
- if (d.length || I && g.length) {
5296
+ if (p || R) {
5297
+ if (d.length || R && g.length) {
5310
5298
  const y = {
5311
5299
  anim: g
5312
5300
  };
@@ -5410,10 +5398,10 @@ class Be {
5410
5398
  let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5411
5399
  if (u = Math.min(u, c.visemes.length * 200), d > 0)
5412
5400
  for (let b = 0; b < c.visemes.length; b++) {
5413
- const I = r + c.times[b] / d * u, B = c.durations[b] / d * u;
5401
+ const R = r + c.times[b] / d * u, B = c.durations[b] / d * u;
5414
5402
  o.push({
5415
5403
  template: { name: "viseme" },
5416
- ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
5404
+ ts: [R - Math.min(60, 2 * B / 3), R + Math.min(25, B / 2), R + B + Math.min(60, B / 2)],
5417
5405
  vs: {
5418
5406
  ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5419
5407
  }
@@ -5507,12 +5495,12 @@ class Be {
5507
5495
  hasVisemes: b && b.visemes && b.visemes.length > 0,
5508
5496
  estimatedDuration: c
5509
5497
  });
5510
- const I = [];
5498
+ const R = [];
5511
5499
  if (b && b.visemes && b.visemes.length > 0) {
5512
5500
  const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5513
5501
  for (let M = 0; M < b.visemes.length; M++) {
5514
5502
  const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
5515
- I.push({
5503
+ R.push({
5516
5504
  template: { name: "viseme" },
5517
5505
  ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
5518
5506
  vs: {
@@ -5521,7 +5509,7 @@ class Be {
5521
5509
  });
5522
5510
  }
5523
5511
  }
5524
- const B = [...t.anim, ...I];
5512
+ const B = [...t.anim, ...R];
5525
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 = () => {
5526
5514
  e();
5527
5515
  }, s.onerror = (p) => {
@@ -5589,8 +5577,8 @@ class Be {
5589
5577
  const d = e.toLowerCase().split(/\s+/), g = [];
5590
5578
  for (const x of d)
5591
5579
  for (const b of x) {
5592
- let I = "aa";
5593
- "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);
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);
5594
5582
  }
5595
5583
  r = {
5596
5584
  visemes: g.map((x, b) => ({
@@ -5687,8 +5675,8 @@ class Be {
5687
5675
  const d = e.toLowerCase().split(/\s+/), g = [];
5688
5676
  for (const x of d)
5689
5677
  for (const b of x) {
5690
- let I = "aa";
5691
- "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);
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);
5692
5680
  }
5693
5681
  r = {
5694
5682
  visemes: g.map((x, b) => ({
@@ -6158,7 +6146,7 @@ class Be {
6158
6146
  */
6159
6147
  lookAtCamera(t) {
6160
6148
  let e;
6161
- if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6149
+ if (this.speakTo && (e = new 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) {
6162
6150
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6163
6151
  if (this.avatar.avatarIgnoreCamera) {
6164
6152
  this.lookAhead(t);
@@ -6171,14 +6159,14 @@ class Be {
6171
6159
  this.lookAt(null, null, t);
6172
6160
  return;
6173
6161
  }
6174
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
6162
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), 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"]);
6175
6163
  const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6176
6164
  V.set(s, i, 0, "YXZ");
6177
6165
  const l = new f.Quaternion().setFromEuler(V), h = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6178
6166
  V.setFromQuaternion(h, "YXZ");
6179
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;
6180
6168
  if (t) {
6181
- let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6169
+ let x = this.animQueue.findIndex((R) => R.template.name === "lookat");
6182
6170
  x !== -1 && this.animQueue.splice(x, 1);
6183
6171
  const b = {
6184
6172
  name: "lookat",
@@ -6212,8 +6200,8 @@ class Be {
6212
6200
  l.project(this.camera);
6213
6201
  let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6214
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);
6215
- 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, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
6216
- b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
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));
6217
6205
  let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6218
6206
  if (n) {
6219
6207
  let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
@@ -6223,7 +6211,7 @@ class Be {
6223
6211
  dt: [750, n],
6224
6212
  vs: {
6225
6213
  bodyRotateX: [b + B],
6226
- bodyRotateY: [I + p],
6214
+ bodyRotateY: [R + p],
6227
6215
  eyesRotateX: [-3 * B + 0.1],
6228
6216
  eyesRotateY: [-5 * p],
6229
6217
  browInnerUp: [[0, 0.7]],
@@ -6451,7 +6439,7 @@ class Be {
6451
6439
  } catch (c) {
6452
6440
  console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6453
6441
  }
6454
- const u = new Oe();
6442
+ const u = new De();
6455
6443
  let a;
6456
6444
  try {
6457
6445
  a = await u.loadAsync(t, e);
@@ -6483,14 +6471,14 @@ class Be {
6483
6471
  }
6484
6472
  c = g;
6485
6473
  const x = {};
6486
- c.tracks.forEach((I) => {
6487
- I.name = I.name.replaceAll("mixamorig", "");
6488
- const B = I.name.split(".");
6474
+ c.tracks.forEach((R) => {
6475
+ R.name = R.name.replaceAll("mixamorig", "");
6476
+ const B = R.name.split(".");
6489
6477
  if (B[1] === "position") {
6490
- for (let p = 0; p < I.values.length; p++)
6491
- I.values[p] = I.values[p] * s;
6492
- x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6493
- } else B[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : B[1] === "rotation" && (x[B[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
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());
6494
6482
  });
6495
6483
  const b = { props: x };
6496
6484
  x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
@@ -6534,7 +6522,7 @@ class Be {
6534
6522
  let l = this.animQueue.find((h) => h.template.name === "pose");
6535
6523
  l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
6536
6524
  } else {
6537
- let h = await new Oe().loadAsync(t, e);
6525
+ let h = await new De().loadAsync(t, e);
6538
6526
  if (h && h.animations && h.animations[i]) {
6539
6527
  let r = h.animations[i];
6540
6528
  const u = {};
@@ -6589,7 +6577,7 @@ class Be {
6589
6577
  const c = [];
6590
6578
  for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6591
6579
  const d = o.template?.rescale || c.map((x) => x / u), g = e * 1e3 - u;
6592
- l.ts = l.ts.map((x, b, I) => b === 0 ? h : I[b - 1] + c[b - 1] + d[b - 1] * g);
6580
+ l.ts = l.ts.map((x, b, R) => b === 0 ? h : R[b - 1] + c[b - 1] + d[b - 1] * g);
6593
6581
  } else {
6594
6582
  const c = e * 1e3 / u;
6595
6583
  l.ts = l.ts.map((d) => h + c * (d - h));
@@ -6625,12 +6613,12 @@ class Be {
6625
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);
6626
6614
  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);
6627
6615
  const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6628
- x.forEach((I) => {
6629
- I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6616
+ x.forEach((R) => {
6617
+ R.bone = this.ikMesh.getObjectByName(R.link), R.bone.quaternion.copy(this.getPoseTemplateProp(R.link + ".quaternion"));
6630
6618
  }), d.updateMatrixWorld(!0);
6631
6619
  const b = t.iterations || 10;
6632
6620
  if (e)
6633
- for (let I = 0; I < b; I++) {
6621
+ for (let R = 0; R < b; R++) {
6634
6622
  let B = !1;
6635
6623
  for (let p = 0, M = x.length; p < M; p++) {
6636
6624
  const z = x[p].bone;
@@ -6648,8 +6636,8 @@ class Be {
6648
6636
  }
6649
6637
  if (!B) break;
6650
6638
  }
6651
- i && x.forEach((I) => {
6652
- 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;
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;
6653
6641
  });
6654
6642
  }
6655
6643
  /**
@@ -6659,7 +6647,7 @@ class Be {
6659
6647
  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();
6660
6648
  }
6661
6649
  }
6662
- const Ie = {
6650
+ const Re = {
6663
6651
  apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
6664
6652
  // Replace with your actual API key (should start with sk_)
6665
6653
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
@@ -6702,13 +6690,13 @@ const Ie = {
6702
6690
  function Fe() {
6703
6691
  return {
6704
6692
  service: "elevenlabs",
6705
- endpoint: Ie.endpoint,
6706
- apiKey: Ie.apiKey,
6707
- defaultVoice: Ie.defaultVoice,
6708
- voices: Ie.voices
6693
+ endpoint: Re.endpoint,
6694
+ apiKey: Re.apiKey,
6695
+ defaultVoice: Re.defaultVoice,
6696
+ voices: Re.voices
6709
6697
  };
6710
6698
  }
6711
- function St() {
6699
+ function kt() {
6712
6700
  const G = Fe(), t = [];
6713
6701
  return Object.entries(G.voices).forEach(([e, n]) => {
6714
6702
  t.push({
@@ -6738,33 +6726,33 @@ const Ve = Me(({
6738
6726
  className: g = "",
6739
6727
  style: x = {},
6740
6728
  animations: b = {}
6741
- }, I) => {
6742
- const B = O(null), p = O(null), M = O(r), z = O(null), y = O(null), E = O(!1), P = O({ remainingText: null, originalText: null, options: null }), W = O([]), oe = O(0), [k, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
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);
6743
6731
  de(() => {
6744
6732
  E.current = ae;
6745
6733
  }, [ae]), de(() => {
6746
6734
  M.current = r;
6747
6735
  }, [r]);
6748
6736
  const ee = Fe(), le = i || ee.service;
6749
- let D;
6750
- le === "browser" ? D = {
6737
+ let O;
6738
+ le === "browser" ? O = {
6751
6739
  service: "browser",
6752
6740
  endpoint: "",
6753
6741
  apiKey: null,
6754
6742
  defaultVoice: "Google US English"
6755
- } : le === "elevenlabs" ? D = {
6743
+ } : le === "elevenlabs" ? O = {
6756
6744
  service: "elevenlabs",
6757
6745
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6758
6746
  apiKey: o || ee.apiKey,
6759
- defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6760
- voices: ee.voices || Ie.voices
6761
- } : le === "deepgram" ? D = {
6747
+ defaultVoice: s || ee.defaultVoice || Re.defaultVoice,
6748
+ voices: ee.voices || Re.voices
6749
+ } : le === "deepgram" ? O = {
6762
6750
  service: "deepgram",
6763
6751
  endpoint: "https://api.deepgram.com/v1/speak",
6764
6752
  apiKey: o || ee.apiKey,
6765
6753
  defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6766
6754
  voices: ee.voices || Te.voices
6767
- } : D = {
6755
+ } : O = {
6768
6756
  ...ee,
6769
6757
  // Override API key if provided via props
6770
6758
  apiKey: o !== null ? o : ee.apiKey
@@ -6774,21 +6762,21 @@ const Ve = Me(({
6774
6762
  body: t,
6775
6763
  avatarMood: e,
6776
6764
  ttsLang: le === "browser" ? "en-US" : n,
6777
- ttsVoice: s || D.defaultVoice,
6765
+ ttsVoice: s || O.defaultVoice,
6778
6766
  lipsyncLang: "en",
6779
6767
  showFullAvatar: r,
6780
6768
  bodyMovement: l,
6781
6769
  movementIntensity: h
6782
- }, R = {
6783
- ttsEndpoint: D.endpoint,
6784
- ttsApikey: D.apiKey,
6770
+ }, I = {
6771
+ ttsEndpoint: O.endpoint,
6772
+ ttsApikey: O.apiKey,
6785
6773
  ttsService: le,
6786
6774
  lipsyncModules: ["en"],
6787
6775
  cameraView: u
6788
- }, S = T(async () => {
6776
+ }, k = T(async () => {
6789
6777
  if (!(!B.current || p.current))
6790
6778
  try {
6791
- if (Z(!0), X(null), p.current = new Be(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (N) => {
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) => {
6792
6780
  if (N.lengthComputable) {
6793
6781
  const J = Math.min(100, Math.round(N.loaded / N.total * 100));
6794
6782
  c(J);
@@ -6815,9 +6803,9 @@ const Ve = Me(({
6815
6803
  console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
6816
6804
  }
6817
6805
  }, [G, t, e, n, i, s, o, r, l, h, u]);
6818
- de(() => (S(), () => {
6806
+ de(() => (k(), () => {
6819
6807
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6820
- }), [S]), de(() => {
6808
+ }), [k]), de(() => {
6821
6809
  if (!B.current || !p.current) return;
6822
6810
  const L = new ResizeObserver((N) => {
6823
6811
  for (const J of N)
@@ -6850,13 +6838,13 @@ const Ve = Me(({
6850
6838
  };
6851
6839
  if (F.onSpeechEnd && p.current) {
6852
6840
  const Y = p.current;
6853
- let he = null, ke = 0;
6841
+ let he = null, Se = 0;
6854
6842
  const Ae = 1200;
6855
6843
  let be = !1;
6856
6844
  he = setInterval(() => {
6857
- if (ke++, E.current)
6845
+ if (Se++, E.current)
6858
6846
  return;
6859
- if (ke > Ae) {
6847
+ if (Se > Ae) {
6860
6848
  if (he && (clearInterval(he), he = null, y.current = null), !be && !E.current) {
6861
6849
  be = !0;
6862
6850
  try {
@@ -6867,8 +6855,8 @@ const Ve = Me(({
6867
6855
  }
6868
6856
  return;
6869
6857
  }
6870
- const ye = !Y.speechQueue || Y.speechQueue.length === 0, Se = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6871
- Y && Y.isSpeaking === !1 && ye && Se && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6858
+ const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6859
+ Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6872
6860
  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) {
6873
6861
  be = !0, he && (clearInterval(he), he = null, y.current = null);
6874
6862
  try {
@@ -6895,9 +6883,9 @@ const Ve = Me(({
6895
6883
  y.current && (clearInterval(y.current), y.current = null);
6896
6884
  let N = "";
6897
6885
  if (z.current && W.current.length > 0) {
6898
- 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), ke = J - he;
6899
- if (he > 0 && ke < J && (N = W.current.slice(ke).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
6900
- const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((Se) => Se.word || "").filter((Se) => Se.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
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)) {
6888
+ 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(" ");
6901
6889
  be && be.trim() && (N = be.trim());
6902
6890
  }
6903
6891
  }
@@ -6975,7 +6963,7 @@ const Ve = Me(({
6975
6963
  }, [b]), te = T(() => {
6976
6964
  p.current && p.current.onResize && p.current.onResize();
6977
6965
  }, []);
6978
- return Ee(I, () => ({
6966
+ return Ee(R, () => ({
6979
6967
  speakText: U,
6980
6968
  stopSpeaking: _,
6981
6969
  pauseSpeaking: j,
@@ -7068,7 +7056,7 @@ const Ve = Me(({
7068
7056
  }
7069
7057
  }
7070
7058
  ),
7071
- k && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7059
+ S && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7072
7060
  position: "absolute",
7073
7061
  top: "50%",
7074
7062
  left: "50%",
@@ -7106,7 +7094,7 @@ const pt = Me(({
7106
7094
  style: s = {},
7107
7095
  avatarConfig: o = {}
7108
7096
  }, l) => {
7109
- const h = O(null), r = O(null), [u, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, B = I === "browser" ? {
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" ? {
7110
7098
  endpoint: "",
7111
7099
  apiKey: null,
7112
7100
  defaultVoice: "Google US English"
@@ -7115,13 +7103,13 @@ const pt = Me(({
7115
7103
  // Override API key if provided via avatarConfig
7116
7104
  apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
7117
7105
  // Override endpoint for ElevenLabs if service is explicitly set
7118
- endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7106
+ endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7119
7107
  }, p = {
7120
7108
  url: "/avatars/brunette.glb",
7121
7109
  // Use brunette avatar (working glTF file)
7122
7110
  body: "F",
7123
7111
  avatarMood: "neutral",
7124
- ttsLang: I === "browser" ? "en-US" : "en",
7112
+ ttsLang: R === "browser" ? "en-US" : "en",
7125
7113
  ttsVoice: o.ttsVoice || B.defaultVoice,
7126
7114
  lipsyncLang: "en",
7127
7115
  // English lip-sync
@@ -7133,7 +7121,7 @@ const pt = Me(({
7133
7121
  }, M = {
7134
7122
  ttsEndpoint: B.endpoint,
7135
7123
  ttsApikey: B.apiKey,
7136
- ttsService: I,
7124
+ ttsService: R,
7137
7125
  lipsyncModules: ["en"],
7138
7126
  cameraView: "upper"
7139
7127
  }, z = T(async () => {
@@ -7168,18 +7156,18 @@ const pt = Me(({
7168
7156
  return document.addEventListener("visibilitychange", Z), () => {
7169
7157
  document.removeEventListener("visibilitychange", Z);
7170
7158
  };
7171
- } catch (k) {
7172
- console.error("Error initializing TalkingHead:", k), d(k.message || "Failed to initialize avatar"), a(!1), e(k);
7159
+ } catch (S) {
7160
+ console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
7173
7161
  }
7174
7162
  }, []);
7175
7163
  de(() => (z(), () => {
7176
7164
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7177
7165
  }), [z]);
7178
- const y = T((k) => {
7166
+ const y = T((S) => {
7179
7167
  if (r.current && g)
7180
7168
  try {
7181
- console.log("Speaking text:", k), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7182
- r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : console.error("Lip-sync still not ready after waiting");
7169
+ console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7170
+ r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7183
7171
  }, 500));
7184
7172
  } catch (Z) {
7185
7173
  console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
@@ -7188,11 +7176,11 @@ const pt = Me(({
7188
7176
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7189
7177
  }, [g, p]), E = T(() => {
7190
7178
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7191
- }, []), P = T((k) => {
7192
- r.current && r.current.setMood(k);
7193
- }, []), W = T((k) => {
7194
- r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
7195
- }, []), oe = T((k, Z = !1) => {
7179
+ }, []), P = T((S) => {
7180
+ r.current && r.current.setMood(S);
7181
+ }, []), W = T((S) => {
7182
+ r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7183
+ }, []), oe = T((S, Z = !1) => {
7196
7184
  if (r.current && r.current.playAnimation) {
7197
7185
  if (r.current.setShowFullAvatar)
7198
7186
  try {
@@ -7200,11 +7188,11 @@ const pt = Me(({
7200
7188
  } catch (X) {
7201
7189
  console.warn("Error setting full body mode:", X);
7202
7190
  }
7203
- if (k.includes("."))
7191
+ if (S.includes("."))
7204
7192
  try {
7205
- r.current.playAnimation(k, null, 10, 0, 0.01, Z), console.log("Playing animation:", k);
7193
+ r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
7206
7194
  } catch (X) {
7207
- console.log(`Failed to play ${k}:`, X);
7195
+ console.log(`Failed to play ${S}:`, X);
7208
7196
  try {
7209
7197
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7210
7198
  } catch ($) {
@@ -7216,13 +7204,13 @@ const pt = Me(({
7216
7204
  let $ = !1;
7217
7205
  for (const se of X)
7218
7206
  try {
7219
- r.current.playAnimation(k + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", k + se), $ = !0;
7207
+ r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
7220
7208
  break;
7221
7209
  } catch {
7222
- console.log(`Failed to play ${k}${se}, trying next format...`);
7210
+ console.log(`Failed to play ${S}${se}, trying next format...`);
7223
7211
  }
7224
7212
  if (!$) {
7225
- console.warn("Animation system not available or animation not found:", k);
7213
+ console.warn("Animation system not available or animation not found:", S);
7226
7214
  try {
7227
7215
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7228
7216
  } catch (se) {
@@ -7231,7 +7219,7 @@ const pt = Me(({
7231
7219
  }
7232
7220
  }
7233
7221
  } else
7234
- console.warn("Animation system not available or animation not found:", k);
7222
+ console.warn("Animation system not available or animation not found:", S);
7235
7223
  }, []);
7236
7224
  return Ee(l, () => ({
7237
7225
  speakText: y,
@@ -7241,27 +7229,27 @@ const pt = Me(({
7241
7229
  playAnimation: oe,
7242
7230
  isReady: g,
7243
7231
  talkingHead: r.current,
7244
- setBodyMovement: (k) => {
7232
+ setBodyMovement: (S) => {
7245
7233
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7246
7234
  try {
7247
- r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
7235
+ r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7248
7236
  } catch (Z) {
7249
7237
  console.warn("Error setting body movement:", Z);
7250
7238
  }
7251
7239
  },
7252
- setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
7240
+ setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
7253
7241
  playRandomDance: () => {
7254
7242
  if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
7255
7243
  try {
7256
7244
  r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
7257
- } catch (k) {
7258
- console.warn("Error playing random dance:", k);
7245
+ } catch (S) {
7246
+ console.warn("Error playing random dance:", S);
7259
7247
  }
7260
7248
  },
7261
- playReaction: (k) => {
7249
+ playReaction: (S) => {
7262
7250
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7263
7251
  try {
7264
- r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
7252
+ r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7265
7253
  } catch (Z) {
7266
7254
  console.warn("Error playing reaction:", Z);
7267
7255
  }
@@ -7270,14 +7258,14 @@ const pt = Me(({
7270
7258
  if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
7271
7259
  try {
7272
7260
  r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
7273
- } catch (k) {
7274
- console.warn("Error playing celebration:", k);
7261
+ } catch (S) {
7262
+ console.warn("Error playing celebration:", S);
7275
7263
  }
7276
7264
  },
7277
- setShowFullAvatar: (k) => {
7265
+ setShowFullAvatar: (S) => {
7278
7266
  if (r.current && r.current.setShowFullAvatar)
7279
7267
  try {
7280
- r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
7268
+ r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7281
7269
  } catch (Z) {
7282
7270
  console.warn("Error setting showFullAvatar:", Z);
7283
7271
  }
@@ -7286,16 +7274,16 @@ const pt = Me(({
7286
7274
  if (r.current && r.current.lockAvatarPosition)
7287
7275
  try {
7288
7276
  r.current.lockAvatarPosition();
7289
- } catch (k) {
7290
- console.warn("Error locking avatar position:", k);
7277
+ } catch (S) {
7278
+ console.warn("Error locking avatar position:", S);
7291
7279
  }
7292
7280
  },
7293
7281
  unlockAvatarPosition: () => {
7294
7282
  if (r.current && r.current.unlockAvatarPosition)
7295
7283
  try {
7296
7284
  r.current.unlockAvatarPosition();
7297
- } catch (k) {
7298
- console.warn("Error unlocking avatar position:", k);
7285
+ } catch (S) {
7286
+ console.warn("Error unlocking avatar position:", S);
7299
7287
  }
7300
7288
  }
7301
7289
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
@@ -7357,52 +7345,52 @@ const gt = Me(({
7357
7345
  onSpeechEnd: x = () => {
7358
7346
  },
7359
7347
  className: b = "",
7360
- style: I = {},
7348
+ style: R = {},
7361
7349
  animations: B = {},
7362
7350
  autoSpeak: p = !1
7363
7351
  }, M) => {
7364
- const z = O(null), y = O(null), E = O(u), P = O(null), W = O(null), oe = O(!1), k = O({ remainingText: null, originalText: null, options: null }), Z = O([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
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);
7365
7353
  de(() => {
7366
7354
  oe.current = ee;
7367
7355
  }, [ee]), de(() => {
7368
7356
  E.current = u;
7369
7357
  }, [u]);
7370
- const D = Fe(), v = s || D.service;
7371
- let R;
7372
- v === "browser" ? R = {
7358
+ const O = Fe(), v = s || O.service;
7359
+ let I;
7360
+ v === "browser" ? I = {
7373
7361
  service: "browser",
7374
7362
  endpoint: "",
7375
7363
  apiKey: null,
7376
7364
  defaultVoice: "Google US English"
7377
- } : v === "elevenlabs" ? R = {
7365
+ } : v === "elevenlabs" ? I = {
7378
7366
  service: "elevenlabs",
7379
7367
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7380
- apiKey: l || D.apiKey,
7381
- defaultVoice: o || D.defaultVoice || Ie.defaultVoice,
7382
- voices: D.voices || Ie.voices
7383
- } : v === "deepgram" ? R = {
7368
+ apiKey: l || O.apiKey,
7369
+ defaultVoice: o || O.defaultVoice || Re.defaultVoice,
7370
+ voices: O.voices || Re.voices
7371
+ } : v === "deepgram" ? I = {
7384
7372
  service: "deepgram",
7385
7373
  endpoint: "https://api.deepgram.com/v1/speak",
7386
- apiKey: l || D.apiKey,
7387
- defaultVoice: o || D.defaultVoice || Te.defaultVoice,
7388
- voices: D.voices || Te.voices
7389
- } : R = {
7390
- ...D,
7391
- apiKey: l !== null ? l : D.apiKey
7374
+ apiKey: l || O.apiKey,
7375
+ defaultVoice: o || O.defaultVoice || Te.defaultVoice,
7376
+ voices: O.voices || Te.voices
7377
+ } : I = {
7378
+ ...O,
7379
+ apiKey: l !== null ? l : O.apiKey
7392
7380
  };
7393
- const S = {
7381
+ const k = {
7394
7382
  url: t,
7395
7383
  body: e,
7396
7384
  avatarMood: n,
7397
7385
  ttsLang: v === "browser" ? "en-US" : i,
7398
- ttsVoice: o || R.defaultVoice,
7386
+ ttsVoice: o || I.defaultVoice,
7399
7387
  lipsyncLang: "en",
7400
7388
  showFullAvatar: u,
7401
7389
  bodyMovement: h,
7402
7390
  movementIntensity: r
7403
7391
  }, H = {
7404
- ttsEndpoint: R.endpoint,
7405
- ttsApikey: R.apiKey,
7392
+ ttsEndpoint: I.endpoint,
7393
+ ttsApikey: I.apiKey,
7406
7394
  ttsService: v,
7407
7395
  lipsyncModules: ["en"],
7408
7396
  cameraView: a
@@ -7410,10 +7398,10 @@ const gt = Me(({
7410
7398
  if (!(!z.current || y.current))
7411
7399
  try {
7412
7400
  X(!0), se(null), y.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7413
- url: S.url,
7414
- body: S.body,
7415
- avatarMood: S.avatarMood
7416
- }), await y.current.showAvatar(S, (te) => {
7401
+ url: k.url,
7402
+ body: k.body,
7403
+ avatarMood: k.avatarMood
7404
+ }), await y.current.showAvatar(k, (te) => {
7417
7405
  if (te.lengthComputable) {
7418
7406
  const L = Math.min(100, Math.round(te.loaded / te.total * 100));
7419
7407
  d(L);
@@ -7449,7 +7437,7 @@ const gt = Me(({
7449
7437
  console.warn("No text provided to speak");
7450
7438
  return;
7451
7439
  }
7452
- await _(), k.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;
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;
7453
7441
  const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
7454
7442
  Z.current = L;
7455
7443
  const F = {
@@ -7474,7 +7462,7 @@ const gt = Me(({
7474
7462
  if (C || te.length > 0 || L.length > 0) {
7475
7463
  W.current && (clearInterval(W.current), W.current = null);
7476
7464
  let F = "";
7477
- L.length > 0 && (F = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")), k.current = {
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 = {
7478
7466
  remainingText: F || null,
7479
7467
  originalText: P.current?.text || null,
7480
7468
  options: P.current?.options || null
@@ -7487,7 +7475,7 @@ const gt = Me(({
7487
7475
  if (!(!y.current || !ee))
7488
7476
  try {
7489
7477
  await _(), le(!1), oe.current = !1;
7490
- const C = k.current?.remainingText, te = k.current?.originalText || P.current?.text, L = k.current?.options || P.current?.options || {}, F = C || te;
7478
+ const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
7491
7479
  F && j(F, L);
7492
7480
  } catch (C) {
7493
7481
  console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
@@ -7516,7 +7504,7 @@ const gt = Me(({
7516
7504
  },
7517
7505
  isReady: ae,
7518
7506
  talkingHead: y.current
7519
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7507
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: R, children: [
7520
7508
  /* @__PURE__ */ me(
7521
7509
  "div",
7522
7510
  {
@@ -7569,7 +7557,7 @@ const yt = Me(({
7569
7557
  },
7570
7558
  autoStart: h = !1
7571
7559
  }, r) => {
7572
- const u = O(null), a = O({
7560
+ const u = D(null), a = D({
7573
7561
  currentModuleIndex: 0,
7574
7562
  currentLessonIndex: 0,
7575
7563
  currentQuestionIndex: 0,
@@ -7579,18 +7567,18 @@ const yt = Me(({
7579
7567
  curriculumCompleted: !1,
7580
7568
  score: 0,
7581
7569
  totalQuestions: 0
7582
- }), c = O({
7570
+ }), c = D({
7583
7571
  onLessonStart: n,
7584
7572
  onLessonComplete: i,
7585
7573
  onQuestionAnswer: s,
7586
7574
  onCurriculumComplete: o,
7587
7575
  onCustomAction: l
7588
- }), d = O(null), g = O(null), x = O(null), b = O(null), I = O(null), B = O(null), p = O(null), M = O(G?.curriculum || {
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 || {
7589
7577
  title: "Default Curriculum",
7590
7578
  description: "No curriculum data provided",
7591
7579
  language: "en",
7592
7580
  modules: []
7593
- }), z = O({
7581
+ }), z = D({
7594
7582
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7595
7583
  avatarBody: t.avatarBody || "F",
7596
7584
  mood: t.mood || "happy",
@@ -7633,11 +7621,11 @@ const yt = Me(({
7633
7621
  lipsyncLang: "en"
7634
7622
  };
7635
7623
  }, [G, t, e]);
7636
- 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(() => {
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(() => {
7637
7625
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7638
7626
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7639
- let R = "Congratulations! You've completed this lesson";
7640
- 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({
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({
7641
7629
  moduleIndex: a.current.currentModuleIndex,
7642
7630
  lessonIndex: a.current.currentLessonIndex,
7643
7631
  score: a.current.score,
@@ -7657,8 +7645,8 @@ const yt = Me(({
7657
7645
  } catch {
7658
7646
  u.current.playCelebration();
7659
7647
  }
7660
- const S = M.current || { modules: [] }, H = S.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (S.modules?.length || 0) - 1, j = U || _, q = z.current || { lipsyncLang: "en" };
7661
- u.current.speakText(R, {
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, {
7662
7650
  lipsyncLang: q.lipsyncLang,
7663
7651
  onSpeechEnd: () => {
7664
7652
  c.current.onCustomAction({
@@ -7678,7 +7666,7 @@ const yt = Me(({
7678
7666
  const v = M.current || { modules: [] };
7679
7667
  if (c.current.onCurriculumComplete({
7680
7668
  modules: v.modules.length,
7681
- totalLessons: v.modules.reduce((R, S) => R + S.lessons.length, 0)
7669
+ totalLessons: v.modules.reduce((I, k) => I + k.lessons.length, 0)
7682
7670
  }), u.current) {
7683
7671
  if (u.current.setMood("celebrating"), e.curriculumComplete)
7684
7672
  try {
@@ -7686,24 +7674,24 @@ const yt = Me(({
7686
7674
  } catch {
7687
7675
  u.current.playCelebration();
7688
7676
  }
7689
- const R = z.current || { lipsyncLang: "en" };
7690
- u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
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 });
7691
7679
  }
7692
- }, [e.curriculumComplete]), k = T(() => {
7680
+ }, [e.curriculumComplete]), S = T(() => {
7693
7681
  const v = y();
7694
7682
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7695
- const R = E();
7696
- R && c.current.onCustomAction({
7683
+ const I = E();
7684
+ I && c.current.onCustomAction({
7697
7685
  type: "questionStart",
7698
7686
  moduleIndex: a.current.currentModuleIndex,
7699
7687
  lessonIndex: a.current.currentLessonIndex,
7700
7688
  questionIndex: a.current.currentQuestionIndex,
7701
7689
  totalQuestions: a.current.totalQuestions,
7702
- question: R,
7690
+ question: I,
7703
7691
  score: a.current.score
7704
7692
  });
7705
- const S = () => {
7706
- if (!u.current || !R) return;
7693
+ const k = () => {
7694
+ if (!u.current || !I) return;
7707
7695
  if (u.current.setMood("happy"), e.questionStart)
7708
7696
  try {
7709
7697
  u.current.playAnimation(e.questionStart, !0);
@@ -7711,16 +7699,16 @@ const yt = Me(({
7711
7699
  console.warn("Failed to play questionStart animation:", U);
7712
7700
  }
7713
7701
  const H = z.current || { lipsyncLang: "en" };
7714
- R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
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 });
7715
7703
  };
7716
- if (u.current && u.current.isReady && R)
7717
- S();
7704
+ if (u.current && u.current.isReady && I)
7705
+ k();
7718
7706
  else if (u.current && u.current.isReady) {
7719
7707
  const H = z.current || { lipsyncLang: "en" };
7720
7708
  u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7721
7709
  } else {
7722
7710
  const H = setInterval(() => {
7723
- u.current && u.current.isReady && (clearInterval(H), R && S());
7711
+ u.current && u.current.isReady && (clearInterval(H), I && k());
7724
7712
  }, 100);
7725
7713
  setTimeout(() => {
7726
7714
  clearInterval(H);
@@ -7730,18 +7718,18 @@ const yt = Me(({
7730
7718
  const v = y();
7731
7719
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7732
7720
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7733
- const R = E();
7734
- R && c.current.onCustomAction({
7721
+ const I = E();
7722
+ I && c.current.onCustomAction({
7735
7723
  type: "nextQuestion",
7736
7724
  moduleIndex: a.current.currentModuleIndex,
7737
7725
  lessonIndex: a.current.currentLessonIndex,
7738
7726
  questionIndex: a.current.currentQuestionIndex,
7739
7727
  totalQuestions: a.current.totalQuestions,
7740
- question: R,
7728
+ question: I,
7741
7729
  score: a.current.score
7742
7730
  });
7743
- const S = () => {
7744
- if (!u.current || !R) return;
7731
+ const k = () => {
7732
+ if (!u.current || !I) return;
7745
7733
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7746
7734
  try {
7747
7735
  u.current.playAnimation(e.nextQuestion, !0);
@@ -7749,33 +7737,33 @@ const yt = Me(({
7749
7737
  console.warn("Failed to play nextQuestion animation:", q);
7750
7738
  }
7751
7739
  const H = z.current || { lipsyncLang: "en" }, _ = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7752
- if (R.type === "code_test") {
7753
- 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}`;
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}`;
7754
7742
  u.current.speakText(q, {
7755
7743
  lipsyncLang: H.lipsyncLang
7756
7744
  });
7757
- } else if (R.type === "multiple_choice") {
7758
- const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
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}`;
7759
7747
  u.current.speakText(q, {
7760
7748
  lipsyncLang: H.lipsyncLang
7761
7749
  });
7762
- } else if (R.type === "true_false") {
7763
- const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
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}`;
7764
7752
  u.current.speakText(q, {
7765
7753
  lipsyncLang: H.lipsyncLang
7766
7754
  });
7767
7755
  } else {
7768
- const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7756
+ const q = j ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
7769
7757
  u.current.speakText(q, {
7770
7758
  lipsyncLang: H.lipsyncLang
7771
7759
  });
7772
7760
  }
7773
7761
  };
7774
- if (u.current && u.current.isReady && R)
7775
- S();
7776
- else if (R) {
7762
+ if (u.current && u.current.isReady && I)
7763
+ k();
7764
+ else if (I) {
7777
7765
  const H = setInterval(() => {
7778
- u.current && u.current.isReady && (clearInterval(H), S());
7766
+ u.current && u.current.isReady && (clearInterval(H), k());
7779
7767
  }, 100);
7780
7768
  setTimeout(() => {
7781
7769
  clearInterval(H);
@@ -7790,8 +7778,8 @@ const yt = Me(({
7790
7778
  score: a.current.score
7791
7779
  });
7792
7780
  }, [e.nextQuestion, y, E]), K = T(() => {
7793
- const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7794
- if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7781
+ const v = M.current || { modules: [] }, I = v.modules[a.current.currentModuleIndex];
7782
+ if (a.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
7795
7783
  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;
7796
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 || _;
7797
7785
  c.current.onCustomAction({
@@ -7818,25 +7806,25 @@ const yt = Me(({
7818
7806
  lesson: y()
7819
7807
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7820
7808
  } else
7821
- I.current && I.current();
7809
+ R.current && R.current();
7822
7810
  }, []), X = T(() => {
7823
7811
  const v = y();
7824
- let R = null;
7812
+ let I = null;
7825
7813
  if (v?.avatar_script && v?.body) {
7826
- const S = v.avatar_script.trim(), H = v.body.trim(), U = S.match(/[.!?]$/) ? " " : ". ";
7827
- R = `${S}${U}${H}`;
7814
+ const k = v.avatar_script.trim(), H = v.body.trim(), U = k.match(/[.!?]$/) ? " " : ". ";
7815
+ I = `${k}${U}${H}`;
7828
7816
  } else
7829
- R = v?.avatar_script || v?.body || null;
7830
- if (u.current && u.current.isReady && R) {
7817
+ I = v?.avatar_script || v?.body || null;
7818
+ if (u.current && u.current.isReady && I) {
7831
7819
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
7832
- let S = !1;
7820
+ let k = !1;
7833
7821
  if (e.teaching)
7834
7822
  try {
7835
- u.current.playAnimation(e.teaching, !0), S = !0;
7823
+ u.current.playAnimation(e.teaching, !0), k = !0;
7836
7824
  } catch (U) {
7837
7825
  console.warn("Failed to play teaching animation:", U);
7838
7826
  }
7839
- S || u.current.setBodyMovement("gesturing");
7827
+ k || u.current.setBodyMovement("gesturing");
7840
7828
  const H = z.current || { lipsyncLang: "en" };
7841
7829
  c.current.onLessonStart({
7842
7830
  moduleIndex: a.current.currentModuleIndex,
@@ -7847,7 +7835,7 @@ const yt = Me(({
7847
7835
  moduleIndex: a.current.currentModuleIndex,
7848
7836
  lessonIndex: a.current.currentLessonIndex,
7849
7837
  lesson: v
7850
- }), u.current.speakText(R, {
7838
+ }), u.current.speakText(I, {
7851
7839
  lipsyncLang: H.lipsyncLang,
7852
7840
  onSpeechEnd: () => {
7853
7841
  a.current.isTeaching = !1, c.current.onCustomAction({
@@ -7867,16 +7855,16 @@ const yt = Me(({
7867
7855
  });
7868
7856
  }
7869
7857
  }, [e.teaching, y]), $ = T((v) => {
7870
- const R = E(), S = P(v, R);
7871
- if (S && (a.current.score += 1), c.current.onQuestionAnswer({
7858
+ const I = E(), k = P(v, I);
7859
+ if (k && (a.current.score += 1), c.current.onQuestionAnswer({
7872
7860
  moduleIndex: a.current.currentModuleIndex,
7873
7861
  lessonIndex: a.current.currentLessonIndex,
7874
7862
  questionIndex: a.current.currentQuestionIndex,
7875
7863
  answer: v,
7876
- isCorrect: S,
7877
- question: R
7864
+ isCorrect: k,
7865
+ question: I
7878
7866
  }), u.current)
7879
- if (S) {
7867
+ if (k) {
7880
7868
  if (u.current.setMood("happy"), e.correct)
7881
7869
  try {
7882
7870
  u.current.playReaction("happy");
@@ -7888,7 +7876,7 @@ const yt = Me(({
7888
7876
  a.current.currentQuestionIndex >= U - 1;
7889
7877
  const _ = a.current.currentQuestionIndex < U - 1;
7890
7878
  console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", _);
7891
- 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" };
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" };
7892
7880
  u.current.speakText(j, {
7893
7881
  lipsyncLang: q.lipsyncLang,
7894
7882
  onSpeechEnd: () => {
@@ -7914,7 +7902,7 @@ const yt = Me(({
7914
7902
  u.current.setBodyMovement("gesturing");
7915
7903
  const U = y()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
7916
7904
  console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
7917
- const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
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" };
7918
7906
  u.current.speakText(q, {
7919
7907
  lipsyncLang: Le.lipsyncLang,
7920
7908
  onSpeechEnd: () => {
@@ -7938,7 +7926,7 @@ const yt = Me(({
7938
7926
  moduleIndex: a.current.currentModuleIndex,
7939
7927
  lessonIndex: a.current.currentLessonIndex,
7940
7928
  questionIndex: a.current.currentQuestionIndex,
7941
- isCorrect: S,
7929
+ isCorrect: k,
7942
7930
  hasNextQuestion: a.current.currentQuestionIndex < U - 1,
7943
7931
  score: a.current.score,
7944
7932
  totalQuestions: a.current.totalQuestions,
@@ -7946,16 +7934,16 @@ const yt = Me(({
7946
7934
  });
7947
7935
  }
7948
7936
  }, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
7949
- const R = E();
7937
+ const I = E();
7950
7938
  if (!v || typeof v != "object") {
7951
7939
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
7952
7940
  return;
7953
7941
  }
7954
- if (R?.type !== "code_test") {
7942
+ if (I?.type !== "code_test") {
7955
7943
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7956
7944
  return;
7957
7945
  }
7958
- const S = {
7946
+ const k = {
7959
7947
  passed: v.passed === !0,
7960
7948
  results: v.results || [],
7961
7949
  output: v.output || "",
@@ -7970,9 +7958,9 @@ const yt = Me(({
7970
7958
  moduleIndex: a.current.currentModuleIndex,
7971
7959
  lessonIndex: a.current.currentLessonIndex,
7972
7960
  questionIndex: a.current.currentQuestionIndex,
7973
- testResult: S,
7974
- question: R
7975
- }), p.current && p.current(S);
7961
+ testResult: k,
7962
+ question: I
7963
+ }), p.current && p.current(k);
7976
7964
  }, [E, P]), ae = T(() => {
7977
7965
  if (a.current.currentQuestionIndex > 0) {
7978
7966
  a.current.currentQuestionIndex -= 1;
@@ -7986,24 +7974,24 @@ const yt = Me(({
7986
7974
  question: v,
7987
7975
  score: a.current.score
7988
7976
  });
7989
- const R = () => {
7977
+ const I = () => {
7990
7978
  if (!u.current || !v) return;
7991
7979
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
7992
- const S = z.current || { lipsyncLang: "en" };
7980
+ const k = z.current || { lipsyncLang: "en" };
7993
7981
  v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
7994
- lipsyncLang: S.lipsyncLang
7982
+ lipsyncLang: k.lipsyncLang
7995
7983
  }) : u.current.speakText(`Going back to: ${v.question}`, {
7996
- lipsyncLang: S.lipsyncLang
7984
+ lipsyncLang: k.lipsyncLang
7997
7985
  });
7998
7986
  };
7999
7987
  if (u.current && u.current.isReady && v)
8000
- R();
7988
+ I();
8001
7989
  else if (v) {
8002
- const S = setInterval(() => {
8003
- u.current && u.current.isReady && (clearInterval(S), R());
7990
+ const k = setInterval(() => {
7991
+ u.current && u.current.isReady && (clearInterval(k), I());
8004
7992
  }, 100);
8005
7993
  setTimeout(() => {
8006
- clearInterval(S);
7994
+ clearInterval(k);
8007
7995
  }, 5e3);
8008
7996
  }
8009
7997
  }
@@ -8035,17 +8023,17 @@ const yt = Me(({
8035
8023
  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;
8036
8024
  }, []), le = T((v) => {
8037
8025
  console.log("Avatar is ready!", v);
8038
- const R = y(), S = R?.avatar_script || R?.body;
8039
- h && S && setTimeout(() => {
8026
+ const I = y(), k = I?.avatar_script || I?.body;
8027
+ h && k && setTimeout(() => {
8040
8028
  d.current && d.current();
8041
8029
  }, 10);
8042
8030
  }, [h, y]);
8043
8031
  Xe(() => {
8044
- d.current = X, g.current = K, x.current = W, b.current = Z, I.current = oe, B.current = k, p.current = $;
8032
+ d.current = X, g.current = K, x.current = W, b.current = Z, R.current = oe, B.current = S, p.current = $;
8045
8033
  }), Ee(r, () => ({
8046
8034
  // Curriculum control methods
8047
8035
  startTeaching: X,
8048
- startQuestions: k,
8036
+ startQuestions: S,
8049
8037
  handleAnswerSelect: $,
8050
8038
  handleCodeTestResult: se,
8051
8039
  nextQuestion: Z,
@@ -8061,22 +8049,22 @@ const yt = Me(({
8061
8049
  // Direct access to avatar ref (always returns current value)
8062
8050
  getAvatarRef: () => u.current,
8063
8051
  // Convenience methods that delegate to avatar (always check current ref)
8064
- speakText: async (v, R = {}) => {
8052
+ speakText: async (v, I = {}) => {
8065
8053
  await u.current?.resumeAudioContext?.();
8066
- const S = z.current || { lipsyncLang: "en" };
8067
- u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || S.lipsyncLang });
8054
+ const k = z.current || { lipsyncLang: "en" };
8055
+ u.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || k.lipsyncLang });
8068
8056
  },
8069
8057
  resumeAudioContext: async () => {
8070
8058
  if (u.current?.resumeAudioContext)
8071
8059
  return await u.current.resumeAudioContext();
8072
8060
  const v = u.current?.talkingHead;
8073
8061
  if (v?.audioCtx) {
8074
- const R = v.audioCtx;
8075
- if (R.state === "suspended" || R.state === "interrupted")
8062
+ const I = v.audioCtx;
8063
+ if (I.state === "suspended" || I.state === "interrupted")
8076
8064
  try {
8077
- await R.resume(), console.log("Audio context resumed via talkingHead");
8078
- } catch (S) {
8079
- console.warn("Failed to resume audio context:", S);
8065
+ await I.resume(), console.log("Audio context resumed via talkingHead");
8066
+ } catch (k) {
8067
+ console.warn("Failed to resume audio context:", k);
8080
8068
  }
8081
8069
  } else
8082
8070
  console.warn("Audio context not available yet");
@@ -8086,7 +8074,7 @@ const yt = Me(({
8086
8074
  resumeSpeaking: async () => await u.current?.resumeSpeaking(),
8087
8075
  isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
8088
8076
  setMood: (v) => u.current?.setMood(v),
8089
- playAnimation: (v, R) => u.current?.playAnimation(v, R),
8077
+ playAnimation: (v, I) => u.current?.playAnimation(v, I),
8090
8078
  setBodyMovement: (v) => u.current?.setBodyMovement(v),
8091
8079
  setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
8092
8080
  playRandomDance: () => u.current?.playRandomDance(),
@@ -8097,10 +8085,10 @@ const yt = Me(({
8097
8085
  lockAvatarPosition: () => u.current?.lockAvatarPosition(),
8098
8086
  unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8099
8087
  // Custom action trigger
8100
- triggerCustomAction: (v, R) => {
8088
+ triggerCustomAction: (v, I) => {
8101
8089
  c.current.onCustomAction({
8102
8090
  type: v,
8103
- ...R,
8091
+ ...I,
8104
8092
  state: { ...a.current }
8105
8093
  });
8106
8094
  },
@@ -8108,8 +8096,8 @@ const yt = Me(({
8108
8096
  handleResize: () => u.current?.handleResize(),
8109
8097
  // Avatar readiness check (always returns current value)
8110
8098
  isAvatarReady: () => u.current?.isReady || !1
8111
- }), [X, k, $, se, Z, K, W, oe, ee, E, y]);
8112
- const D = z.current || {
8099
+ }), [X, S, $, se, Z, K, W, oe, ee, E, y]);
8100
+ const O = z.current || {
8113
8101
  avatarUrl: "/avatars/brunette.glb",
8114
8102
  avatarBody: "F",
8115
8103
  mood: "happy",
@@ -8126,18 +8114,18 @@ const yt = Me(({
8126
8114
  Ve,
8127
8115
  {
8128
8116
  ref: u,
8129
- avatarUrl: D.avatarUrl,
8130
- avatarBody: D.avatarBody,
8131
- mood: D.mood,
8132
- ttsLang: D.ttsLang,
8133
- ttsService: D.ttsService,
8134
- ttsVoice: D.ttsVoice,
8135
- ttsApiKey: D.ttsApiKey,
8136
- bodyMovement: D.bodyMovement,
8137
- movementIntensity: D.movementIntensity,
8138
- showFullAvatar: D.showFullAvatar,
8117
+ avatarUrl: O.avatarUrl,
8118
+ avatarBody: O.avatarBody,
8119
+ mood: O.mood,
8120
+ ttsLang: O.ttsLang,
8121
+ ttsService: O.ttsService,
8122
+ ttsVoice: O.ttsVoice,
8123
+ ttsApiKey: O.ttsApiKey,
8124
+ bodyMovement: O.bodyMovement,
8125
+ movementIntensity: O.movementIntensity,
8126
+ showFullAvatar: O.showFullAvatar,
8139
8127
  cameraView: "upper",
8140
- animations: D.animations,
8128
+ animations: O.animations,
8141
8129
  onReady: le,
8142
8130
  onLoading: () => {
8143
8131
  },
@@ -8260,6 +8248,6 @@ export {
8260
8248
  Ge as animations,
8261
8249
  Fe as getActiveTTSConfig,
8262
8250
  wt as getAnimation,
8263
- St as getVoiceOptions,
8251
+ kt as getVoiceOptions,
8264
8252
  zt as hasAnimation
8265
8253
  };