@sage-rsc/talking-head-react 1.0.59 → 1.0.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs as Te, jsx as he } from "react/jsx-runtime";
2
- import { forwardRef as ve, useRef as Z, useState as ce, useEffect as pe, useCallback as T, useImperativeHandle as Ie, useLayoutEffect as Oe } from "react";
2
+ import { forwardRef as Re, useRef as Z, useState as ce, useEffect as pe, useCallback as T, useImperativeHandle as Ie, useLayoutEffect as Oe } from "react";
3
3
  import * as f from "three";
4
4
  import { OrbitControls as Ne } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as Ue } from "three/addons/loaders/GLTFLoader.js";
@@ -2629,7 +2629,7 @@ const ot = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: et,
2630
2630
  fi: it,
2631
2631
  lt: ot
2632
- }, V = new f.Quaternion(), M = new f.Euler(), ae = new f.Vector3(), le = new f.Vector3(), Ce = new f.Box3();
2632
+ }, W = new f.Quaternion(), M = new f.Euler(), ae = new f.Vector3(), le = new f.Vector3(), Ce = new f.Box3();
2633
2633
  new f.Matrix4();
2634
2634
  new f.Matrix4();
2635
2635
  new f.Vector3();
@@ -4376,7 +4376,7 @@ class Me {
4376
4376
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4377
4377
  M.set(e.x, e.y, e.z);
4378
4378
  const i = this.poseAvatar.props[t];
4379
- i.isQuaternion ? (V.setFromEuler(M), i.multiply(V)) : i.isVector3 && i.add(M);
4379
+ i.isQuaternion ? (W.setFromEuler(M), i.multiply(W)) : i.isVector3 && i.add(M);
4380
4380
  }
4381
4381
  }
4382
4382
  /**
@@ -5180,7 +5180,7 @@ class Me {
5180
5180
  eyeLookOutRight: [null, 0],
5181
5181
  eyeContact: [0]
5182
5182
  }
5183
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 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), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (V.setFromAxisAngle(at, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(V)), Ce.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ae), ae.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(le), le.sub(this.armature.position), this.objectHips.position.y -= Ce.min.y / 2, this.objectHips.position.x -= (ae.x + le.x) / 4, this.objectHips.position.z -= (ae.z + le.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5183
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 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), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (W.setFromAxisAngle(at, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(W)), Ce.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ae), ae.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(le), le.sub(this.armature.position), this.objectHips.position.y -= Ce.min.y / 2, this.objectHips.position.x -= (ae.x + le.x) / 4, this.objectHips.position.z -= (ae.z + le.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5184
5184
  this.stats && this.stats.end();
5185
5185
  else {
5186
5186
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
@@ -5254,7 +5254,7 @@ class Me {
5254
5254
  const I = x === y.length - 1, P = y[x].match(l);
5255
5255
  let p = y[x].match(s);
5256
5256
  const H = y[x].match(u), z = y[x].match(o);
5257
- if (p && !I && !H && y[x + 1].match(s) && (p = !1), i && (h += y[x]), P && (!n || n.every((v) => x < v[0] || x > v[1])) && (r += y[x]), (z || p || I) && (r.length && (r = this.lipsyncPreProcessText(r, a), r.length && d.push({
5257
+ if (p && !I && !H && y[x + 1].match(s) && (p = !1), i && (h += y[x]), P && (!n || n.every((R) => x < R[0] || x > R[1])) && (r += y[x]), (z || p || I) && (r.length && (r = this.lipsyncPreProcessText(r, a), r.length && d.push({
5258
5258
  mark: c,
5259
5259
  word: r
5260
5260
  })), h.length && (g.push({
@@ -5265,16 +5265,16 @@ class Me {
5265
5265
  subtitles: [h]
5266
5266
  }
5267
5267
  }), h = ""), r.length)) {
5268
- const v = this.lipsyncWordsToVisemes(r, a);
5269
- if (v && v.visemes && v.visemes.length) {
5270
- const D = v.times[v.visemes.length - 1] + v.durations[v.visemes.length - 1];
5271
- for (let U = 0; U < v.visemes.length; U++)
5268
+ const R = this.lipsyncWordsToVisemes(r, a);
5269
+ if (R && R.visemes && R.visemes.length) {
5270
+ const D = R.times[R.visemes.length - 1] + R.durations[R.visemes.length - 1];
5271
+ for (let N = 0; N < R.visemes.length; N++)
5272
5272
  g.push({
5273
5273
  mark: c,
5274
5274
  template: { name: "viseme" },
5275
- ts: [(v.times[U] - 0.6) / D, (v.times[U] + 0.5) / D, (v.times[U] + v.durations[U] + 0.5) / D],
5275
+ ts: [(R.times[N] - 0.6) / D, (R.times[N] + 0.5) / D, (R.times[N] + R.durations[N] + 0.5) / D],
5276
5276
  vs: {
5277
- ["viseme_" + v.visemes[U]]: [null, v.visemes[U] === "PP" || v.visemes[U] === "FF" ? 0.9 : 0.6, 0]
5277
+ ["viseme_" + R.visemes[N]]: [null, R.visemes[N] === "PP" || R.visemes[N] === "FF" ? 0.9 : 0.6, 0]
5278
5278
  }
5279
5279
  });
5280
5280
  }
@@ -5282,14 +5282,14 @@ class Me {
5282
5282
  }
5283
5283
  if (p || I) {
5284
5284
  if (d.length || I && g.length) {
5285
- const v = {
5285
+ const R = {
5286
5286
  anim: g
5287
5287
  };
5288
- i && (v.onSubtitles = i), d.length && !e.avatarMute && (v.text = d, e.avatarMood && (v.mood = e.avatarMood), e.ttsLang && (v.lang = e.ttsLang), e.ttsVoice && (v.voice = e.ttsVoice), e.ttsRate && (v.rate = e.ttsRate), e.ttsVoice && (v.pitch = e.ttsPitch), e.ttsVolume && (v.volume = e.ttsVolume)), this.speechQueue.push(v), d = [], r = "", c = 0, g = [];
5288
+ i && (R.onSubtitles = i), d.length && !e.avatarMute && (R.text = d, e.avatarMood && (R.mood = e.avatarMood), e.ttsLang && (R.lang = e.ttsLang), e.ttsVoice && (R.voice = e.ttsVoice), e.ttsRate && (R.rate = e.ttsRate), e.ttsVoice && (R.pitch = e.ttsPitch), e.ttsVolume && (R.volume = e.ttsVolume)), this.speechQueue.push(R), d = [], r = "", c = 0, g = [];
5289
5289
  }
5290
5290
  if (H) {
5291
- let v = this.animEmojis[y[x]];
5292
- v && v.link && (v = this.animEmojis[v.link]), v && this.speechQueue.push({ emoji: v });
5291
+ let R = this.animEmojis[y[x]];
5292
+ R && R.link && (R = this.animEmojis[R.link]), R && this.speechQueue.push({ emoji: R });
5293
5293
  }
5294
5294
  this.speechQueue.push({ break: 100 });
5295
5295
  }
@@ -5486,10 +5486,10 @@ class Me {
5486
5486
  if (x && x.visemes && x.visemes.length > 0) {
5487
5487
  const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5488
5488
  for (let H = 0; H < x.visemes.length; H++) {
5489
- const z = x.visemes[H], v = x.times[H] / p, D = x.durations[H] / p, U = v * c, _ = D * c;
5489
+ const z = x.visemes[H], R = x.times[H] / p, D = x.durations[H] / p, N = R * c, _ = D * c;
5490
5490
  I.push({
5491
5491
  template: { name: "viseme" },
5492
- ts: [U - Math.min(60, 2 * _ / 3), U + Math.min(25, _ / 2), U + _ + Math.min(60, _ / 2)],
5492
+ ts: [N - Math.min(60, 2 * _ / 3), N + Math.min(25, _ / 2), N + _ + Math.min(60, _ / 2)],
5493
5493
  vs: {
5494
5494
  ["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
5495
5495
  }
@@ -6146,10 +6146,10 @@ class Me {
6146
6146
  this.lookAt(null, null, t);
6147
6147
  return;
6148
6148
  }
6149
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ae.setFromMatrixPosition(this.objectLeftEye.matrixWorld), le.setFromMatrixPosition(this.objectRightEye.matrixWorld), ae.add(le).divideScalar(2), V.copy(this.armature.quaternion), V.multiply(this.poseTarget.props["Hips.quaternion"]), V.multiply(this.poseTarget.props["Spine.quaternion"]), V.multiply(this.poseTarget.props["Spine1.quaternion"]), V.multiply(this.poseTarget.props["Spine2.quaternion"]), V.multiply(this.poseTarget.props["Neck.quaternion"]), V.multiply(this.poseTarget.props["Head.quaternion"]);
6149
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ae.setFromMatrixPosition(this.objectLeftEye.matrixWorld), le.setFromMatrixPosition(this.objectRightEye.matrixWorld), ae.add(le).divideScalar(2), W.copy(this.armature.quaternion), W.multiply(this.poseTarget.props["Hips.quaternion"]), W.multiply(this.poseTarget.props["Spine.quaternion"]), W.multiply(this.poseTarget.props["Spine1.quaternion"]), W.multiply(this.poseTarget.props["Spine2.quaternion"]), W.multiply(this.poseTarget.props["Neck.quaternion"]), W.multiply(this.poseTarget.props["Head.quaternion"]);
6150
6150
  const i = new f.Vector3().subVectors(e, ae).normalize(), n = Math.atan2(i.x, i.z), s = Math.asin(-i.y);
6151
6151
  M.set(s, n, 0, "YXZ");
6152
- const l = new f.Quaternion().setFromEuler(M), u = new f.Quaternion().copy(l).multiply(V.clone().invert());
6152
+ const l = new f.Quaternion().setFromEuler(M), u = new f.Quaternion().copy(l).multiply(W.clone().invert());
6153
6153
  M.setFromQuaternion(u, "YXZ");
6154
6154
  let a = M.x / (40 / 24) + 0.2, h = M.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, a)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6155
6155
  if (t) {
@@ -6186,12 +6186,12 @@ class Me {
6186
6186
  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);
6187
6187
  l.project(this.camera);
6188
6188
  let u = (l.x + 1) / 2 * n.width + n.left, a = -(l.y - 1) / 2 * n.height + n.top;
6189
- t === null && (t = u), e === null && (e = a), V.copy(this.armature.quaternion), V.multiply(this.poseTarget.props["Hips.quaternion"]), V.multiply(this.poseTarget.props["Spine.quaternion"]), V.multiply(this.poseTarget.props["Spine1.quaternion"]), V.multiply(this.poseTarget.props["Spine2.quaternion"]), V.multiply(this.poseTarget.props["Neck.quaternion"]), V.multiply(this.poseTarget.props["Head.quaternion"]), M.setFromQuaternion(V);
6189
+ t === null && (t = u), e === null && (e = a), W.copy(this.armature.quaternion), W.multiply(this.poseTarget.props["Hips.quaternion"]), W.multiply(this.poseTarget.props["Spine.quaternion"]), W.multiply(this.poseTarget.props["Spine1.quaternion"]), W.multiply(this.poseTarget.props["Spine2.quaternion"]), W.multiply(this.poseTarget.props["Neck.quaternion"]), W.multiply(this.poseTarget.props["Head.quaternion"]), M.setFromQuaternion(W);
6190
6190
  let h = M.x / (40 / 24), r = M.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), y = Math.max(window.innerHeight - a, a), x = this.convertRange(e, [a - y, a + y], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - r + d;
6191
6191
  x = Math.min(0.6, Math.max(-0.3, x)), I = Math.min(0.8, Math.max(-0.8, I));
6192
6192
  let P = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6193
6193
  if (i) {
6194
- let H = this.animQueue.findIndex((v) => v.template.name === "lookat");
6194
+ let H = this.animQueue.findIndex((R) => R.template.name === "lookat");
6195
6195
  H !== -1 && this.animQueue.splice(H, 1);
6196
6196
  const z = {
6197
6197
  name: "lookat",
@@ -6581,8 +6581,8 @@ class Me {
6581
6581
  for (let p = 0, H = y.length; p < H; p++) {
6582
6582
  const z = y[p].bone;
6583
6583
  z.matrixWorld.decompose(u, a, h), a.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(a), l.normalize(), s.subVectors(e, u), s.applyQuaternion(a), s.normalize();
6584
- let v = s.dot(l);
6585
- v > 1 ? v = 1 : v < -1 && (v = -1), v = Math.acos(v), !(v < 1e-5) && (y[p].minAngle !== void 0 && v < y[p].minAngle && (v = y[p].minAngle), y[p].maxAngle !== void 0 && v > y[p].maxAngle && (v = y[p].maxAngle), r.crossVectors(l, s), r.normalize(), V.setFromAxisAngle(r, v), z.quaternion.multiply(V), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6584
+ let R = s.dot(l);
6585
+ R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (y[p].minAngle !== void 0 && R < y[p].minAngle && (R = y[p].minAngle), y[p].maxAngle !== void 0 && R > y[p].maxAngle && (R = y[p].maxAngle), r.crossVectors(l, s), r.normalize(), W.setFromAxisAngle(r, R), z.quaternion.multiply(W), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6586
6586
  y[p].minx !== void 0 ? y[p].minx : -1 / 0,
6587
6587
  y[p].miny !== void 0 ? y[p].miny : -1 / 0,
6588
6588
  y[p].minz !== void 0 ? y[p].minz : -1 / 0
@@ -6655,16 +6655,16 @@ function Le() {
6655
6655
  };
6656
6656
  }
6657
6657
  function xt() {
6658
- const N = Le(), t = [];
6659
- return Object.entries(N.voices).forEach(([e, i]) => {
6658
+ const O = Le(), t = [];
6659
+ return Object.entries(O.voices).forEach(([e, i]) => {
6660
6660
  t.push({
6661
6661
  value: i,
6662
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${N.service})`
6662
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${O.service})`
6663
6663
  });
6664
6664
  }), t;
6665
6665
  }
6666
- const Ee = ve(({
6667
- avatarUrl: N = "/avatars/brunette.glb",
6666
+ const Ee = Re(({
6667
+ avatarUrl: O = "/avatars/brunette.glb",
6668
6668
  avatarBody: t = "F",
6669
6669
  mood: e = "neutral",
6670
6670
  ttsLang: i = "en",
@@ -6685,7 +6685,7 @@ const Ee = ve(({
6685
6685
  style: y = {},
6686
6686
  animations: x = {}
6687
6687
  }, I) => {
6688
- const P = Z(null), p = Z(null), H = Z(a), z = Z(null), [v, D] = ce(!0), [U, _] = ce(null), [ne, S] = ce(!1), [W, G] = ce(!1);
6688
+ const P = Z(null), p = Z(null), H = Z(a), z = Z(null), [R, D] = ce(!0), [N, _] = ce(null), [ne, S] = ce(!1), [U, V] = ce(!1);
6689
6689
  pe(() => {
6690
6690
  H.current = a;
6691
6691
  }, [a]);
@@ -6714,7 +6714,7 @@ const Ee = ve(({
6714
6714
  apiKey: o !== null ? o : E.apiKey
6715
6715
  };
6716
6716
  const ue = {
6717
- url: N,
6717
+ url: O,
6718
6718
  body: t,
6719
6719
  avatarMood: e,
6720
6720
  ttsLang: X === "browser" ? "en-US" : i,
@@ -6723,7 +6723,7 @@ const Ee = ve(({
6723
6723
  showFullAvatar: a,
6724
6724
  bodyMovement: l,
6725
6725
  movementIntensity: u
6726
- }, Re = {
6726
+ }, ve = {
6727
6727
  ttsEndpoint: Y.endpoint,
6728
6728
  ttsApikey: Y.apiKey,
6729
6729
  ttsService: X,
@@ -6732,7 +6732,7 @@ const Ee = ve(({
6732
6732
  }, ge = T(async () => {
6733
6733
  if (!(!P.current || p.current))
6734
6734
  try {
6735
- if (D(!0), _(null), p.current = new Me(P.current, Re), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(ue, (j) => {
6735
+ if (D(!0), _(null), p.current = new Me(P.current, ve), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(ue, (j) => {
6736
6736
  if (j.lengthComputable) {
6737
6737
  const B = Math.min(100, Math.round(j.loaded / j.total * 100));
6738
6738
  c(B);
@@ -6758,7 +6758,7 @@ const Ee = ve(({
6758
6758
  } catch (A) {
6759
6759
  console.error("Error initializing TalkingHead:", A), _(A.message || "Failed to initialize avatar"), D(!1), d(A);
6760
6760
  }
6761
- }, [N, t, e, i, n, s, o, a, l, u, h]);
6761
+ }, [O, t, e, i, n, s, o, a, l, u, h]);
6762
6762
  pe(() => (ge(), () => {
6763
6763
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6764
6764
  }), [ge]), pe(() => {
@@ -6785,7 +6785,7 @@ const Ee = ve(({
6785
6785
  }, []), J = T(async (A, F = {}) => {
6786
6786
  if (p.current && ne)
6787
6787
  try {
6788
- z.current = { text: A, options: F }, G(!1), await re();
6788
+ z.current = { text: A, options: F }, V(!1), await re();
6789
6789
  const j = {
6790
6790
  ...F,
6791
6791
  lipsyncLang: F.lipsyncLang || ue.lipsyncLang || "en"
@@ -6827,15 +6827,15 @@ const Ee = ve(({
6827
6827
  console.error("Error speaking text:", j), _(j.message || "Failed to speak text");
6828
6828
  }
6829
6829
  }, [ne, re, ue.lipsyncLang]), b = T(() => {
6830
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, G(!1));
6831
- }, []), R = T(() => {
6830
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, V(!1));
6831
+ }, []), v = T(() => {
6832
6832
  if (p.current && p.current.pauseSpeaking) {
6833
6833
  const A = p.current, F = A.isSpeaking || A.audioPlaylist && A.audioPlaylist.length > 0 || A.speechQueue && A.speechQueue.length > 0;
6834
- (F && z.current && z.current.text || F) && (p.current.pauseSpeaking(), G(!0));
6834
+ (F && z.current && z.current.text || F) && (p.current.pauseSpeaking(), V(!0));
6835
6835
  }
6836
6836
  }, []), w = T(async () => {
6837
- if (p.current && W)
6838
- if (G(!1), await re(), z.current && z.current.text) {
6837
+ if (p.current && U)
6838
+ if (V(!1), await re(), z.current && z.current.text) {
6839
6839
  const A = z.current;
6840
6840
  z.current = null;
6841
6841
  const F = {
@@ -6845,9 +6845,9 @@ const Ee = ve(({
6845
6845
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(A.text, F));
6846
6846
  } else
6847
6847
  z.current = null;
6848
- }, [re, W]), C = T((A) => {
6848
+ }, [re, U]), C = T((A) => {
6849
6849
  p.current && p.current.setMood(A);
6850
- }, []), O = T((A) => {
6850
+ }, []), G = T((A) => {
6851
6851
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(A);
6852
6852
  }, []), te = T((A, F = !1) => {
6853
6853
  if (p.current && p.current.playAnimation) {
@@ -6893,14 +6893,14 @@ const Ee = ve(({
6893
6893
  return Ie(I, () => ({
6894
6894
  speakText: J,
6895
6895
  stopSpeaking: b,
6896
- pauseSpeaking: R,
6896
+ pauseSpeaking: v,
6897
6897
  resumeSpeaking: w,
6898
6898
  resumeAudioContext: re,
6899
6899
  setMood: C,
6900
- setTimingAdjustment: O,
6900
+ setTimingAdjustment: G,
6901
6901
  playAnimation: te,
6902
6902
  isReady: ne,
6903
- isPaused: W,
6903
+ isPaused: U,
6904
6904
  talkingHead: p.current,
6905
6905
  handleResize: ie,
6906
6906
  setBodyMovement: (A) => {
@@ -6983,7 +6983,7 @@ const Ee = ve(({
6983
6983
  }
6984
6984
  }
6985
6985
  ),
6986
- v && /* @__PURE__ */ he("div", { className: "loading-overlay", style: {
6986
+ R && /* @__PURE__ */ he("div", { className: "loading-overlay", style: {
6987
6987
  position: "absolute",
6988
6988
  top: "50%",
6989
6989
  left: "50%",
@@ -6992,7 +6992,7 @@ const Ee = ve(({
6992
6992
  fontSize: "18px",
6993
6993
  zIndex: 10
6994
6994
  }, children: "Loading avatar..." }),
6995
- U && /* @__PURE__ */ he("div", { className: "error-overlay", style: {
6995
+ N && /* @__PURE__ */ he("div", { className: "error-overlay", style: {
6996
6996
  position: "absolute",
6997
6997
  top: "50%",
6998
6998
  left: "50%",
@@ -7003,14 +7003,14 @@ const Ee = ve(({
7003
7003
  zIndex: 10,
7004
7004
  padding: "20px",
7005
7005
  borderRadius: "8px"
7006
- }, children: U })
7006
+ }, children: N })
7007
7007
  ]
7008
7008
  }
7009
7009
  );
7010
7010
  });
7011
7011
  Ee.displayName = "TalkingHeadAvatar";
7012
- const rt = ve(({
7013
- text: N = "Hello! I'm a talking avatar. How are you today?",
7012
+ const rt = Re(({
7013
+ text: O = "Hello! I'm a talking avatar. How are you today?",
7014
7014
  onLoading: t = () => {
7015
7015
  },
7016
7016
  onError: e = () => {
@@ -7054,34 +7054,34 @@ const rt = ve(({
7054
7054
  }, z = T(async () => {
7055
7055
  if (!(!u.current || a.current))
7056
7056
  try {
7057
- if (r(!0), d(null), a.current = new Me(u.current, H), await a.current.showAvatar(p, (G) => {
7058
- if (G.lengthComputable) {
7059
- const E = Math.min(100, Math.round(G.loaded / G.total * 100));
7057
+ if (r(!0), d(null), a.current = new Me(u.current, H), await a.current.showAvatar(p, (V) => {
7058
+ if (V.lengthComputable) {
7059
+ const E = Math.min(100, Math.round(V.loaded / V.total * 100));
7060
7060
  t(E);
7061
7061
  }
7062
7062
  }), a.current.morphs && a.current.morphs.length > 0) {
7063
- const G = a.current.morphs[0].morphTargetDictionary;
7064
- console.log("Available morph targets:", Object.keys(G));
7065
- const E = Object.keys(G).filter((X) => X.startsWith("viseme_"));
7063
+ const V = a.current.morphs[0].morphTargetDictionary;
7064
+ console.log("Available morph targets:", Object.keys(V));
7065
+ const E = Object.keys(V).filter((X) => X.startsWith("viseme_"));
7066
7066
  console.log("Viseme morph targets found:", E), E.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"));
7067
7067
  }
7068
- if (await new Promise((G) => {
7068
+ if (await new Promise((V) => {
7069
7069
  const E = () => {
7070
- a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), G()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(E, 100));
7070
+ a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), V()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(E, 100));
7071
7071
  };
7072
7072
  E();
7073
7073
  }), a.current && a.current.setShowFullAvatar)
7074
7074
  try {
7075
7075
  a.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7076
- } catch (G) {
7077
- console.warn("Error setting full body mode on initialization:", G);
7076
+ } catch (V) {
7077
+ console.warn("Error setting full body mode on initialization:", V);
7078
7078
  }
7079
7079
  r(!1), y(!0), i(a.current);
7080
- const W = () => {
7080
+ const U = () => {
7081
7081
  document.visibilityState === "visible" ? a.current?.start() : a.current?.stop();
7082
7082
  };
7083
- return document.addEventListener("visibilitychange", W), () => {
7084
- document.removeEventListener("visibilitychange", W);
7083
+ return document.addEventListener("visibilitychange", U), () => {
7084
+ document.removeEventListener("visibilitychange", U);
7085
7085
  };
7086
7086
  } catch (S) {
7087
7087
  console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), r(!1), e(S);
@@ -7090,24 +7090,24 @@ const rt = ve(({
7090
7090
  pe(() => (z(), () => {
7091
7091
  a.current && (a.current.stop(), a.current.dispose(), a.current = null);
7092
7092
  }), [z]);
7093
- const v = T((S) => {
7093
+ const R = T((S) => {
7094
7094
  if (a.current && g)
7095
7095
  try {
7096
7096
  console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", a.current), a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7097
7097
  a.current && a.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7098
7098
  }, 500));
7099
- } catch (W) {
7100
- console.error("Error speaking text:", W), d(W.message || "Failed to speak text");
7099
+ } catch (U) {
7100
+ console.error("Error speaking text:", U), d(U.message || "Failed to speak text");
7101
7101
  }
7102
7102
  else
7103
7103
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!a.current);
7104
7104
  }, [g, p]), D = T(() => {
7105
7105
  a.current && (a.current.stopSpeaking(), a.current.setSlowdownRate && (a.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7106
- }, []), U = T((S) => {
7106
+ }, []), N = T((S) => {
7107
7107
  a.current && a.current.setMood(S);
7108
7108
  }, []), _ = T((S) => {
7109
7109
  a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7110
- }, []), ne = T((S, W = !1) => {
7110
+ }, []), ne = T((S, U = !1) => {
7111
7111
  if (a.current && a.current.playAnimation) {
7112
7112
  if (a.current.setShowFullAvatar)
7113
7113
  try {
@@ -7117,7 +7117,7 @@ const rt = ve(({
7117
7117
  }
7118
7118
  if (S.includes("."))
7119
7119
  try {
7120
- a.current.playAnimation(S, null, 10, 0, 0.01, W), console.log("Playing animation:", S);
7120
+ a.current.playAnimation(S, null, 10, 0, 0.01, U), console.log("Playing animation:", S);
7121
7121
  } catch (E) {
7122
7122
  console.log(`Failed to play ${S}:`, E);
7123
7123
  try {
@@ -7131,7 +7131,7 @@ const rt = ve(({
7131
7131
  let X = !1;
7132
7132
  for (const Y of E)
7133
7133
  try {
7134
- a.current.playAnimation(S + Y, null, 10, 0, 0.01, W), console.log("Playing animation:", S + Y), X = !0;
7134
+ a.current.playAnimation(S + Y, null, 10, 0, 0.01, U), console.log("Playing animation:", S + Y), X = !0;
7135
7135
  break;
7136
7136
  } catch {
7137
7137
  console.log(`Failed to play ${S}${Y}, trying next format...`);
@@ -7149,9 +7149,9 @@ const rt = ve(({
7149
7149
  console.warn("Animation system not available or animation not found:", S);
7150
7150
  }, []);
7151
7151
  return Ie(l, () => ({
7152
- speakText: v,
7152
+ speakText: R,
7153
7153
  stopSpeaking: D,
7154
- setMood: U,
7154
+ setMood: N,
7155
7155
  setTimingAdjustment: _,
7156
7156
  playAnimation: ne,
7157
7157
  isReady: g,
@@ -7160,8 +7160,8 @@ const rt = ve(({
7160
7160
  if (a.current && a.current.setShowFullAvatar && a.current.setBodyMovement)
7161
7161
  try {
7162
7162
  a.current.setShowFullAvatar(!0), a.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7163
- } catch (W) {
7164
- console.warn("Error setting body movement:", W);
7163
+ } catch (U) {
7164
+ console.warn("Error setting body movement:", U);
7165
7165
  }
7166
7166
  },
7167
7167
  setMovementIntensity: (S) => a.current?.setMovementIntensity(S),
@@ -7177,8 +7177,8 @@ const rt = ve(({
7177
7177
  if (a.current && a.current.setShowFullAvatar && a.current.playReaction)
7178
7178
  try {
7179
7179
  a.current.setShowFullAvatar(!0), a.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7180
- } catch (W) {
7181
- console.warn("Error playing reaction:", W);
7180
+ } catch (U) {
7181
+ console.warn("Error playing reaction:", U);
7182
7182
  }
7183
7183
  },
7184
7184
  playCelebration: () => {
@@ -7193,8 +7193,8 @@ const rt = ve(({
7193
7193
  if (a.current && a.current.setShowFullAvatar)
7194
7194
  try {
7195
7195
  a.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7196
- } catch (W) {
7197
- console.warn("Error setting showFullAvatar:", W);
7196
+ } catch (U) {
7197
+ console.warn("Error setting showFullAvatar:", U);
7198
7198
  }
7199
7199
  },
7200
7200
  lockAvatarPosition: () => {
@@ -7250,8 +7250,8 @@ const rt = ve(({
7250
7250
  ] });
7251
7251
  });
7252
7252
  rt.displayName = "TalkingHeadComponent";
7253
- const lt = ve(({
7254
- curriculumData: N = null,
7253
+ const lt = Re(({
7254
+ curriculumData: O = null,
7255
7255
  avatarConfig: t = {},
7256
7256
  animations: e = {},
7257
7257
  onLessonStart: i = () => {
@@ -7282,7 +7282,7 @@ const lt = ve(({
7282
7282
  onQuestionAnswer: s,
7283
7283
  onCurriculumComplete: o,
7284
7284
  onCustomAction: l
7285
- }), d = Z(null), g = Z(null), y = Z(null), x = Z(null), I = Z(null), P = Z(null), p = Z(null), H = Z(N?.curriculum || {
7285
+ }), d = Z(null), g = Z(null), y = Z(null), x = Z(null), I = Z(null), P = Z(null), p = Z(null), H = Z(O?.curriculum || {
7286
7286
  title: "Default Curriculum",
7287
7287
  description: "No curriculum data provided",
7288
7288
  language: "en",
@@ -7310,7 +7310,7 @@ const lt = ve(({
7310
7310
  onCustomAction: l
7311
7311
  };
7312
7312
  }, [i, n, s, o, l]), pe(() => {
7313
- H.current = N?.curriculum || {
7313
+ H.current = O?.curriculum || {
7314
7314
  title: "Default Curriculum",
7315
7315
  description: "No curriculum data provided",
7316
7316
  language: "en",
@@ -7329,17 +7329,12 @@ const lt = ve(({
7329
7329
  animations: e,
7330
7330
  lipsyncLang: "en"
7331
7331
  };
7332
- }, [N, t, e]);
7333
- const v = T(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), D = T(() => v()?.questions[r.current.currentQuestionIndex], [v]), U = T((b, R) => R.type === "multiple_choice" || R.type === "true_false" ? b === R.answer : R.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), _ = T(() => {
7332
+ }, [O, t, e]);
7333
+ const R = T(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), D = T(() => R()?.questions[r.current.currentQuestionIndex], [R]), N = T((b, v) => v.type === "multiple_choice" || v.type === "true_false" ? b === v.answer : v.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), _ = T(() => {
7334
7334
  r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
7335
7335
  const b = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
7336
- let R = "Congratulations! You've completed this lesson";
7337
- if (r.current.totalQuestions > 0) {
7338
- const w = r.current.score === 1 ? "one" : r.current.score, C = r.current.totalQuestions === 1 ? "one" : r.current.totalQuestions, O = b === 50 ? "fifty" : `${b}`;
7339
- R += ` You got ${w} correct out of ${C} question${r.current.totalQuestions === 1 ? "" : "s"}, which is ${O} percent. `;
7340
- } else
7341
- R += "! ";
7342
- if (b >= 80 ? R += "Excellent work! You have a great understanding of this topic." : b >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7336
+ let v = "Congratulations! You've completed this lesson";
7337
+ if (r.current.totalQuestions > 0 ? v += ` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${b} percent. ` : v += "! ", b >= 80 ? v += "Excellent work! You have a great understanding of this topic." : b >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7343
7338
  moduleIndex: r.current.currentModuleIndex,
7344
7339
  lessonIndex: r.current.currentLessonIndex,
7345
7340
  score: r.current.score,
@@ -7359,8 +7354,8 @@ const lt = ve(({
7359
7354
  } catch {
7360
7355
  h.current.playCelebration();
7361
7356
  }
7362
- const w = H.current || { modules: [] }, C = w.modules[r.current.currentModuleIndex], O = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (w.modules?.length || 0) - 1, ie = O || te, A = z.current || { lipsyncLang: "en" };
7363
- h.current.speakText(R, {
7357
+ const w = H.current || { modules: [] }, C = w.modules[r.current.currentModuleIndex], G = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (w.modules?.length || 0) - 1, ie = G || te, A = z.current || { lipsyncLang: "en" };
7358
+ h.current.speakText(v, {
7364
7359
  lipsyncLang: A.lipsyncLang,
7365
7360
  onSpeechEnd: () => {
7366
7361
  c.current.onCustomAction({
@@ -7380,7 +7375,7 @@ const lt = ve(({
7380
7375
  const b = H.current || { modules: [] };
7381
7376
  if (c.current.onCurriculumComplete({
7382
7377
  modules: b.modules.length,
7383
- totalLessons: b.modules.reduce((R, w) => R + w.lessons.length, 0)
7378
+ totalLessons: b.modules.reduce((v, w) => v + w.lessons.length, 0)
7384
7379
  }), h.current) {
7385
7380
  if (h.current.setMood("celebrating"), e.curriculumComplete)
7386
7381
  try {
@@ -7388,82 +7383,82 @@ const lt = ve(({
7388
7383
  } catch {
7389
7384
  h.current.playCelebration();
7390
7385
  }
7391
- const R = z.current || { lipsyncLang: "en" };
7392
- 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 });
7386
+ const v = z.current || { lipsyncLang: "en" };
7387
+ h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
7393
7388
  }
7394
7389
  }, [e.curriculumComplete]), S = T(() => {
7395
- const b = v();
7390
+ const b = R();
7396
7391
  r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = b?.questions?.length || 0, r.current.score = 0;
7397
- const R = D();
7398
- R && c.current.onCustomAction({
7392
+ const v = D();
7393
+ v && c.current.onCustomAction({
7399
7394
  type: "questionStart",
7400
7395
  moduleIndex: r.current.currentModuleIndex,
7401
7396
  lessonIndex: r.current.currentLessonIndex,
7402
7397
  questionIndex: r.current.currentQuestionIndex,
7403
7398
  totalQuestions: r.current.totalQuestions,
7404
- question: R,
7399
+ question: v,
7405
7400
  score: r.current.score
7406
7401
  });
7407
7402
  const w = () => {
7408
- if (!h.current || !R) return;
7403
+ if (!h.current || !v) return;
7409
7404
  if (h.current.setMood("happy"), e.questionStart)
7410
7405
  try {
7411
7406
  h.current.playAnimation(e.questionStart, !0);
7412
- } catch (O) {
7413
- console.warn("Failed to play questionStart animation:", O);
7407
+ } catch (G) {
7408
+ console.warn("Failed to play questionStart animation:", G);
7414
7409
  }
7415
7410
  const C = z.current || { lipsyncLang: "en" };
7416
- R.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : R.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : R.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: C.lipsyncLang });
7411
+ v.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : v.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : v.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: C.lipsyncLang });
7417
7412
  };
7418
- if (h.current && h.current.isReady && R)
7413
+ if (h.current && h.current.isReady && v)
7419
7414
  w();
7420
7415
  else if (h.current && h.current.isReady) {
7421
7416
  const C = z.current || { lipsyncLang: "en" };
7422
7417
  h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: C.lipsyncLang });
7423
7418
  } else {
7424
7419
  const C = setInterval(() => {
7425
- h.current && h.current.isReady && (clearInterval(C), R && w());
7420
+ h.current && h.current.isReady && (clearInterval(C), v && w());
7426
7421
  }, 100);
7427
7422
  setTimeout(() => {
7428
7423
  clearInterval(C);
7429
7424
  }, 5e3);
7430
7425
  }
7431
- }, [e.questionStart, v, D]), W = T(() => {
7432
- const b = v();
7426
+ }, [e.questionStart, R, D]), U = T(() => {
7427
+ const b = R();
7433
7428
  if (r.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7434
7429
  h.current && h.current.stopSpeaking && h.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
7435
- const R = D();
7436
- R && c.current.onCustomAction({
7430
+ const v = D();
7431
+ v && c.current.onCustomAction({
7437
7432
  type: "nextQuestion",
7438
7433
  moduleIndex: r.current.currentModuleIndex,
7439
7434
  lessonIndex: r.current.currentLessonIndex,
7440
7435
  questionIndex: r.current.currentQuestionIndex,
7441
7436
  totalQuestions: r.current.totalQuestions,
7442
- question: R,
7437
+ question: v,
7443
7438
  score: r.current.score
7444
7439
  });
7445
7440
  const w = () => {
7446
- if (!h.current || !R) return;
7441
+ if (!h.current || !v) return;
7447
7442
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7448
7443
  try {
7449
7444
  h.current.playAnimation(e.nextQuestion, !0);
7450
- } catch (O) {
7451
- console.warn("Failed to play nextQuestion animation:", O);
7445
+ } catch (G) {
7446
+ console.warn("Failed to play nextQuestion animation:", G);
7452
7447
  }
7453
7448
  const C = z.current || { lipsyncLang: "en" };
7454
- R.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${R.question}`, {
7449
+ v.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${v.question}`, {
7455
7450
  lipsyncLang: C.lipsyncLang
7456
- }) : R.type === "multiple_choice" ? h.current.speakText(`Alright! Here's your next question: ${R.question}`, {
7451
+ }) : v.type === "multiple_choice" ? h.current.speakText(`Alright! Here's your next question: ${v.question}`, {
7457
7452
  lipsyncLang: C.lipsyncLang
7458
- }) : R.type === "true_false" ? h.current.speakText(`Now let's try this one: ${R.question}`, {
7453
+ }) : v.type === "true_false" ? h.current.speakText(`Now let's try this one: ${v.question}`, {
7459
7454
  lipsyncLang: C.lipsyncLang
7460
- }) : h.current.speakText(`Here's the next question: ${R.question}`, {
7455
+ }) : h.current.speakText(`Here's the next question: ${v.question}`, {
7461
7456
  lipsyncLang: C.lipsyncLang
7462
7457
  });
7463
7458
  };
7464
- if (h.current && h.current.isReady && R)
7459
+ if (h.current && h.current.isReady && v)
7465
7460
  w();
7466
- else if (R) {
7461
+ else if (v) {
7467
7462
  const C = setInterval(() => {
7468
7463
  h.current && h.current.isReady && (clearInterval(C), w());
7469
7464
  }, 100);
@@ -7479,11 +7474,11 @@ const lt = ve(({
7479
7474
  totalQuestions: r.current.totalQuestions,
7480
7475
  score: r.current.score
7481
7476
  });
7482
- }, [e.nextQuestion, v, D]), G = T(() => {
7483
- const b = H.current || { modules: [] }, R = b.modules[r.current.currentModuleIndex];
7484
- if (r.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7477
+ }, [e.nextQuestion, R, D]), V = T(() => {
7478
+ const b = H.current || { modules: [] }, v = b.modules[r.current.currentModuleIndex];
7479
+ if (r.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
7485
7480
  r.current.currentLessonIndex += 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
7486
- const C = b.modules[r.current.currentModuleIndex], O = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, ie = O || te;
7481
+ const C = b.modules[r.current.currentModuleIndex], G = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, ie = G || te;
7487
7482
  c.current.onCustomAction({
7488
7483
  type: "lessonStart",
7489
7484
  moduleIndex: r.current.currentModuleIndex,
@@ -7492,11 +7487,11 @@ const lt = ve(({
7492
7487
  }), c.current.onLessonStart({
7493
7488
  moduleIndex: r.current.currentModuleIndex,
7494
7489
  lessonIndex: r.current.currentLessonIndex,
7495
- lesson: v()
7490
+ lesson: R()
7496
7491
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7497
7492
  } else if (r.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7498
7493
  r.current.currentModuleIndex += 1, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
7499
- const O = b.modules[r.current.currentModuleIndex], te = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, ie = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, A = te || ie;
7494
+ const G = b.modules[r.current.currentModuleIndex], te = r.current.currentLessonIndex < (G?.lessons?.length || 0) - 1, ie = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, A = te || ie;
7500
7495
  c.current.onCustomAction({
7501
7496
  type: "lessonStart",
7502
7497
  moduleIndex: r.current.currentModuleIndex,
@@ -7505,26 +7500,26 @@ const lt = ve(({
7505
7500
  }), c.current.onLessonStart({
7506
7501
  moduleIndex: r.current.currentModuleIndex,
7507
7502
  lessonIndex: r.current.currentLessonIndex,
7508
- lesson: v()
7503
+ lesson: R()
7509
7504
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7510
7505
  } else
7511
7506
  I.current && I.current();
7512
7507
  }, []), E = T(() => {
7513
- const b = v();
7514
- let R = null;
7508
+ const b = R();
7509
+ let v = null;
7515
7510
  if (b?.avatar_script && b?.body) {
7516
- const w = b.avatar_script.trim(), C = b.body.trim(), O = w.match(/[.!?]$/) ? " " : ". ";
7517
- R = `${w}${O}${C}`;
7511
+ const w = b.avatar_script.trim(), C = b.body.trim(), G = w.match(/[.!?]$/) ? " " : ". ";
7512
+ v = `${w}${G}${C}`;
7518
7513
  } else
7519
- R = b?.avatar_script || b?.body || null;
7520
- if (h.current && h.current.isReady && R) {
7514
+ v = b?.avatar_script || b?.body || null;
7515
+ if (h.current && h.current.isReady && v) {
7521
7516
  r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.setMood("happy");
7522
7517
  let w = !1;
7523
7518
  if (e.teaching)
7524
7519
  try {
7525
7520
  h.current.playAnimation(e.teaching, !0), w = !0;
7526
- } catch (O) {
7527
- console.warn("Failed to play teaching animation:", O);
7521
+ } catch (G) {
7522
+ console.warn("Failed to play teaching animation:", G);
7528
7523
  }
7529
7524
  w || h.current.setBodyMovement("gesturing");
7530
7525
  const C = z.current || { lipsyncLang: "en" };
@@ -7537,7 +7532,7 @@ const lt = ve(({
7537
7532
  moduleIndex: r.current.currentModuleIndex,
7538
7533
  lessonIndex: r.current.currentLessonIndex,
7539
7534
  lesson: b
7540
- }), h.current.speakText(R, {
7535
+ }), h.current.speakText(v, {
7541
7536
  lipsyncLang: C.lipsyncLang,
7542
7537
  onSpeechEnd: () => {
7543
7538
  r.current.isTeaching = !1, c.current.onCustomAction({
@@ -7550,15 +7545,15 @@ const lt = ve(({
7550
7545
  }
7551
7546
  });
7552
7547
  }
7553
- }, [e.teaching, v]), X = T((b) => {
7554
- const R = D(), w = U(b, R);
7548
+ }, [e.teaching, R]), X = T((b) => {
7549
+ const v = D(), w = N(b, v);
7555
7550
  if (w && (r.current.score += 1), c.current.onQuestionAnswer({
7556
7551
  moduleIndex: r.current.currentModuleIndex,
7557
7552
  lessonIndex: r.current.currentLessonIndex,
7558
7553
  questionIndex: r.current.currentQuestionIndex,
7559
7554
  answer: b,
7560
7555
  isCorrect: w,
7561
- question: R
7556
+ question: v
7562
7557
  }), h.current)
7563
7558
  if (w) {
7564
7559
  if (h.current.setMood("happy"), e.correct)
@@ -7568,11 +7563,11 @@ const lt = ve(({
7568
7563
  h.current.setBodyMovement("happy");
7569
7564
  }
7570
7565
  h.current.setBodyMovement("gesturing");
7571
- const C = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, O = z.current || { lipsyncLang: "en" };
7566
+ const C = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, G = z.current || { lipsyncLang: "en" };
7572
7567
  h.current.speakText(C, {
7573
- lipsyncLang: O.lipsyncLang,
7568
+ lipsyncLang: G.lipsyncLang,
7574
7569
  onSpeechEnd: () => {
7575
- const ie = v()?.questions?.length || 0;
7570
+ const ie = R()?.questions?.length || 0;
7576
7571
  c.current.onCustomAction({
7577
7572
  type: "answerFeedbackComplete",
7578
7573
  moduleIndex: r.current.currentModuleIndex,
@@ -7593,11 +7588,11 @@ const lt = ve(({
7593
7588
  h.current.setBodyMovement("idle");
7594
7589
  }
7595
7590
  h.current.setBodyMovement("gesturing");
7596
- const C = 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.`, O = z.current || { lipsyncLang: "en" };
7591
+ const C = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""} Let's move on to the next question.`, G = z.current || { lipsyncLang: "en" };
7597
7592
  h.current.speakText(C, {
7598
- lipsyncLang: O.lipsyncLang,
7593
+ lipsyncLang: G.lipsyncLang,
7599
7594
  onSpeechEnd: () => {
7600
- const ie = v()?.questions?.length || 0;
7595
+ const ie = R()?.questions?.length || 0;
7601
7596
  c.current.onCustomAction({
7602
7597
  type: "answerFeedbackComplete",
7603
7598
  moduleIndex: r.current.currentModuleIndex,
@@ -7612,26 +7607,26 @@ const lt = ve(({
7612
7607
  });
7613
7608
  }
7614
7609
  else {
7615
- const O = v()?.questions?.length || 0;
7610
+ const G = R()?.questions?.length || 0;
7616
7611
  c.current.onCustomAction({
7617
7612
  type: "answerFeedbackComplete",
7618
7613
  moduleIndex: r.current.currentModuleIndex,
7619
7614
  lessonIndex: r.current.currentLessonIndex,
7620
7615
  questionIndex: r.current.currentQuestionIndex,
7621
7616
  isCorrect: w,
7622
- hasNextQuestion: r.current.currentQuestionIndex < O - 1,
7617
+ hasNextQuestion: r.current.currentQuestionIndex < G - 1,
7623
7618
  score: r.current.score,
7624
7619
  totalQuestions: r.current.totalQuestions,
7625
7620
  avatarNotReady: !0
7626
7621
  });
7627
7622
  }
7628
- }, [e.correct, e.incorrect, D, v, U]), Y = T((b) => {
7629
- const R = D();
7623
+ }, [e.correct, e.incorrect, D, R, N]), Y = T((b) => {
7624
+ const v = D();
7630
7625
  if (!b || typeof b != "object") {
7631
7626
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
7632
7627
  return;
7633
7628
  }
7634
- if (R?.type !== "code_test") {
7629
+ if (v?.type !== "code_test") {
7635
7630
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7636
7631
  return;
7637
7632
  }
@@ -7651,9 +7646,9 @@ const lt = ve(({
7651
7646
  lessonIndex: r.current.currentLessonIndex,
7652
7647
  questionIndex: r.current.currentQuestionIndex,
7653
7648
  testResult: w,
7654
- question: R
7649
+ question: v
7655
7650
  }), p.current && p.current(w);
7656
- }, [D, U]), ue = T(() => {
7651
+ }, [D, N]), ue = T(() => {
7657
7652
  if (r.current.currentQuestionIndex > 0) {
7658
7653
  r.current.currentQuestionIndex -= 1;
7659
7654
  const b = D();
@@ -7666,7 +7661,7 @@ const lt = ve(({
7666
7661
  question: b,
7667
7662
  score: r.current.score
7668
7663
  });
7669
- const R = () => {
7664
+ const v = () => {
7670
7665
  if (!h.current || !b) return;
7671
7666
  h.current.setMood("happy"), h.current.setBodyMovement("idle");
7672
7667
  const w = z.current || { lipsyncLang: "en" };
@@ -7677,17 +7672,17 @@ const lt = ve(({
7677
7672
  });
7678
7673
  };
7679
7674
  if (h.current && h.current.isReady && b)
7680
- R();
7675
+ v();
7681
7676
  else if (b) {
7682
7677
  const w = setInterval(() => {
7683
- h.current && h.current.isReady && (clearInterval(w), R());
7678
+ h.current && h.current.isReady && (clearInterval(w), v());
7684
7679
  }, 100);
7685
7680
  setTimeout(() => {
7686
7681
  clearInterval(w);
7687
7682
  }, 5e3);
7688
7683
  }
7689
7684
  }
7690
- }, [D]), Re = T(() => {
7685
+ }, [D]), ve = T(() => {
7691
7686
  const b = H.current || { modules: [] };
7692
7687
  if (b.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
7693
7688
  r.current.currentLessonIndex -= 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.onCustomAction({
@@ -7697,7 +7692,7 @@ const lt = ve(({
7697
7692
  }), c.current.onLessonStart({
7698
7693
  moduleIndex: r.current.currentModuleIndex,
7699
7694
  lessonIndex: r.current.currentLessonIndex,
7700
- lesson: v()
7695
+ lesson: R()
7701
7696
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7702
7697
  else if (r.current.currentModuleIndex > 0) {
7703
7698
  const C = b.modules[r.current.currentModuleIndex - 1];
@@ -7708,53 +7703,53 @@ const lt = ve(({
7708
7703
  }), c.current.onLessonStart({
7709
7704
  moduleIndex: r.current.currentModuleIndex,
7710
7705
  lessonIndex: r.current.currentLessonIndex,
7711
- lesson: v()
7706
+ lesson: R()
7712
7707
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7713
7708
  }
7714
- }, [v]), ge = T(() => {
7709
+ }, [R]), ge = T(() => {
7715
7710
  r.current.currentModuleIndex = 0, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.isTeaching = !1, r.current.isQuestionMode = !1, r.current.lessonCompleted = !1, r.current.curriculumCompleted = !1, r.current.score = 0, r.current.totalQuestions = 0;
7716
7711
  }, []), re = T((b) => {
7717
7712
  console.log("Avatar is ready!", b);
7718
- const R = v(), w = R?.avatar_script || R?.body;
7713
+ const v = R(), w = v?.avatar_script || v?.body;
7719
7714
  u && w && setTimeout(() => {
7720
7715
  d.current && d.current();
7721
7716
  }, 10);
7722
- }, [u, v]);
7717
+ }, [u, R]);
7723
7718
  Oe(() => {
7724
- d.current = E, g.current = G, y.current = _, x.current = W, I.current = ne, P.current = S, p.current = X;
7719
+ d.current = E, g.current = V, y.current = _, x.current = U, I.current = ne, P.current = S, p.current = X;
7725
7720
  }), Ie(a, () => ({
7726
7721
  // Curriculum control methods
7727
7722
  startTeaching: E,
7728
7723
  startQuestions: S,
7729
7724
  handleAnswerSelect: X,
7730
7725
  handleCodeTestResult: Y,
7731
- nextQuestion: W,
7726
+ nextQuestion: U,
7732
7727
  previousQuestion: ue,
7733
- nextLesson: G,
7734
- previousLesson: Re,
7728
+ nextLesson: V,
7729
+ previousLesson: ve,
7735
7730
  completeLesson: _,
7736
7731
  completeCurriculum: ne,
7737
7732
  resetCurriculum: ge,
7738
7733
  getState: () => ({ ...r.current }),
7739
7734
  getCurrentQuestion: () => D(),
7740
- getCurrentLesson: () => v(),
7735
+ getCurrentLesson: () => R(),
7741
7736
  // Direct access to avatar ref (always returns current value)
7742
7737
  getAvatarRef: () => h.current,
7743
7738
  // Convenience methods that delegate to avatar (always check current ref)
7744
- speakText: async (b, R = {}) => {
7739
+ speakText: async (b, v = {}) => {
7745
7740
  await h.current?.resumeAudioContext?.();
7746
7741
  const w = z.current || { lipsyncLang: "en" };
7747
- h.current?.speakText(b, { ...R, lipsyncLang: R.lipsyncLang || w.lipsyncLang });
7742
+ h.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || w.lipsyncLang });
7748
7743
  },
7749
7744
  resumeAudioContext: async () => {
7750
7745
  if (h.current?.resumeAudioContext)
7751
7746
  return await h.current.resumeAudioContext();
7752
7747
  const b = h.current?.talkingHead;
7753
7748
  if (b?.audioCtx) {
7754
- const R = b.audioCtx;
7755
- if (R.state === "suspended" || R.state === "interrupted")
7749
+ const v = b.audioCtx;
7750
+ if (v.state === "suspended" || v.state === "interrupted")
7756
7751
  try {
7757
- await R.resume(), console.log("Audio context resumed via talkingHead");
7752
+ await v.resume(), console.log("Audio context resumed via talkingHead");
7758
7753
  } catch (w) {
7759
7754
  console.warn("Failed to resume audio context:", w);
7760
7755
  }
@@ -7766,7 +7761,7 @@ const lt = ve(({
7766
7761
  resumeSpeaking: async () => await h.current?.resumeSpeaking(),
7767
7762
  isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
7768
7763
  setMood: (b) => h.current?.setMood(b),
7769
- playAnimation: (b, R) => h.current?.playAnimation(b, R),
7764
+ playAnimation: (b, v) => h.current?.playAnimation(b, v),
7770
7765
  setBodyMovement: (b) => h.current?.setBodyMovement(b),
7771
7766
  setMovementIntensity: (b) => h.current?.setMovementIntensity(b),
7772
7767
  playRandomDance: () => h.current?.playRandomDance(),
@@ -7777,10 +7772,10 @@ const lt = ve(({
7777
7772
  lockAvatarPosition: () => h.current?.lockAvatarPosition(),
7778
7773
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
7779
7774
  // Custom action trigger
7780
- triggerCustomAction: (b, R) => {
7775
+ triggerCustomAction: (b, v) => {
7781
7776
  c.current.onCustomAction({
7782
7777
  type: b,
7783
- ...R,
7778
+ ...v,
7784
7779
  state: { ...r.current }
7785
7780
  });
7786
7781
  },
@@ -7788,7 +7783,7 @@ const lt = ve(({
7788
7783
  handleResize: () => h.current?.handleResize(),
7789
7784
  // Avatar readiness check (always returns current value)
7790
7785
  isAvatarReady: () => h.current?.isReady || !1
7791
- }), [E, S, X, Y, W, G, _, ne, ge, D, v]);
7786
+ }), [E, S, X, Y, U, V, _, ne, ge, D, R]);
7792
7787
  const J = z.current || {
7793
7788
  avatarUrl: "/avatars/brunette.glb",
7794
7789
  avatarBody: "F",
@@ -7931,7 +7926,7 @@ const Fe = {
7931
7926
  duration: 5e3,
7932
7927
  description: "Excited, energetic movement"
7933
7928
  }
7934
- }, bt = (N) => Fe[N] || null, Rt = (N) => Fe.hasOwnProperty(N);
7929
+ }, bt = (O) => Fe[O] || null, vt = (O) => Fe.hasOwnProperty(O);
7935
7930
  export {
7936
7931
  lt as CurriculumLearning,
7937
7932
  Ee as TalkingHeadAvatar,
@@ -7940,5 +7935,5 @@ export {
7940
7935
  Le as getActiveTTSConfig,
7941
7936
  bt as getAnimation,
7942
7937
  xt as getVoiceOptions,
7943
- Rt as hasAnimation
7938
+ vt as hasAnimation
7944
7939
  };