@streamoji/aitwin 0.1.8 → 0.2.0

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/aitwin.js CHANGED
@@ -1,73 +1,75 @@
1
- import { jsxs as Bt, jsx as it } from "react/jsx-runtime";
2
- import { forwardRef as Nt, useRef as R, useState as ke, useCallback as ie, useEffect as Te, useMemo as Vt, useImperativeHandle as $t } from "react";
3
- const Ht = "https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev", St = {
4
- publicBase: Ht
5
- }, Wt = "0.1.8", qt = {
6
- version: Wt
7
- }, Kt = {}, Pe = "https://ai.streamoji.com", jt = `${St.publicBase}/custom-faces`, Gt = `${St.publicBase}/aitwin-workers/v${qt.version}/visemeDiffPreview.worker.js`;
8
- function zt(e) {
1
+ import { jsxs as kn, jsx as At } from "react/jsx-runtime";
2
+ import { forwardRef as En, useRef as L, useState as Be, useCallback as oe, useEffect as Se, useMemo as It, useImperativeHandle as Sn } from "react";
3
+ import { PipecatClient as vn } from "@pipecat-ai/client-js";
4
+ import { WebSocketTransport as bn, DailyMediaManager as Tn } from "@pipecat-ai/websocket-transport";
5
+ const An = "https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev", Yt = {
6
+ publicBase: An
7
+ }, In = "0.2.0", Rn = {
8
+ version: In
9
+ }, Dn = {}, be = "https://ai.streamoji.com", Mn = `${Yt.publicBase}/custom-faces`, xn = `${Yt.publicBase}/aitwin-workers/v${Rn.version}/visemeDiffPreview.worker.js`;
10
+ function Cn(e) {
9
11
  if (e) return e;
10
- const t = typeof import.meta < "u" ? Kt?.VITE_AITWIN_WORKER_URL : void 0;
11
- return t?.trim() ? t.trim() : Gt;
12
- }
13
- const Qt = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin", kt = "eng_a7f2b9c1", Ze = "eng_d4e8f3a2", be = "eng_c9b1e6d4", pe = be, Jt = /* @__PURE__ */ new Set([
14
- Ze,
15
- be
16
- ]), Tt = {
17
- [kt]: "oculus_direct",
18
- [be]: "oculus_direct",
19
- [Ze]: "inworld_word"
20
- }, st = {
21
- google: kt,
22
- inworld: Ze,
23
- cartesia: be
12
+ const t = typeof import.meta < "u" ? Dn?.VITE_AITWIN_WORKER_URL : void 0;
13
+ return t?.trim() ? t.trim() : xn;
14
+ }
15
+ const Pn = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin", Jt = "eng_a7f2b9c1", ut = "eng_d4e8f3a2", Ae = "eng_c9b1e6d4", Te = Ae, Bn = /* @__PURE__ */ new Set([
16
+ ut,
17
+ Ae
18
+ ]), Qt = {
19
+ [Jt]: "oculus_direct",
20
+ [Ae]: "oculus_direct",
21
+ [ut]: "inworld_word"
22
+ }, Rt = {
23
+ google: Jt,
24
+ inworld: ut,
25
+ cartesia: Ae
24
26
  };
25
- function Yt(e) {
26
- return Tt[e];
27
+ function On(e) {
28
+ return Qt[e];
27
29
  }
28
- function Xt(e) {
29
- return e === be;
30
+ function Fn(e) {
31
+ return e === Ae;
30
32
  }
31
- function Zt(e) {
32
- if (e.ttsEngineId && e.ttsEngineId in Tt)
33
+ function Ln(e) {
34
+ if (e.ttsEngineId && e.ttsEngineId in Qt)
33
35
  return e.ttsEngineId;
34
36
  const t = e.tts?.toLowerCase();
35
- return t && t in st ? st[t] : pe;
37
+ return t && t in Rt ? Rt[t] : Te;
36
38
  }
37
- class Ke extends Error {
39
+ class nt extends Error {
38
40
  constructor(t = "AI twin not found") {
39
41
  super(t), this.name = "AiTwinNotFoundError";
40
42
  }
41
43
  }
42
- async function en(e, t = Qt) {
44
+ async function Un(e, t = Pn) {
43
45
  const n = new URL(t);
44
46
  n.searchParams.set("id", e);
45
47
  const r = await fetch(n.toString());
46
48
  if (r.status === 404)
47
- throw new Ke();
49
+ throw new nt();
48
50
  if (!r.ok)
49
51
  throw new Error(`getAiTwin failed (${r.status})`);
50
- const i = await r.json();
51
- if (!i.success)
52
- throw new Ke(i.error ?? "AI twin not found");
53
- const { tts: s, ...c } = i.data;
52
+ const s = await r.json();
53
+ if (!s.success)
54
+ throw new nt(s.error ?? "AI twin not found");
55
+ const { tts: i, ...o } = s.data;
54
56
  return {
55
- ...c,
56
- ttsEngineId: Zt(i.data)
57
+ ...o,
58
+ ttsEngineId: Ln(s.data)
57
59
  };
58
60
  }
59
- const tn = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken", nn = "client_6TNvp3SCs4Og0a1ijm9TommXLql1", rn = "kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1", sn = "6TNvp3SCs4Og0a1ijm9TommXLql1", on = "Swaraj Mali";
60
- async function ot() {
61
- const e = await fetch(tn, {
61
+ const Nn = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken", Vn = "client_6TNvp3SCs4Og0a1ijm9TommXLql1", $n = "kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1", Hn = "6TNvp3SCs4Og0a1ijm9TommXLql1", Wn = "Swaraj Mali";
62
+ async function et() {
63
+ const e = await fetch(Nn, {
62
64
  method: "POST",
63
65
  headers: {
64
66
  "Content-Type": "application/json",
65
- "Client-Id": nn,
66
- "Client-Secret": rn
67
+ "Client-Id": Vn,
68
+ "Client-Secret": $n
67
69
  },
68
70
  body: JSON.stringify({
69
- userId: sn,
70
- userName: on
71
+ userId: Hn,
72
+ userName: Wn
71
73
  })
72
74
  });
73
75
  if (!e.ok)
@@ -77,7 +79,7 @@ async function ot() {
77
79
  throw new Error("getAuthToken returned no token");
78
80
  return n;
79
81
  }
80
- async function an(e, t = Pe) {
82
+ async function qn(e, t = be) {
81
83
  const n = await fetch(`${t.replace(/\/$/, "")}/api/session-value`, {
82
84
  headers: { Authorization: `Bearer ${e}` }
83
85
  });
@@ -87,7 +89,7 @@ async function an(e, t = Pe) {
87
89
  if (!r.value) throw new Error("Session value response missing value");
88
90
  return r;
89
91
  }
90
- function cn(e) {
92
+ function Kn(e) {
91
93
  const t = e.trim();
92
94
  if (t.length % 2 !== 0) throw new Error("Invalid hex key");
93
95
  const n = new Uint8Array(t.length / 2);
@@ -95,20 +97,20 @@ function cn(e) {
95
97
  n[r / 2] = Number.parseInt(t.slice(r, r + 2), 16);
96
98
  return n;
97
99
  }
98
- function Ce(e) {
100
+ function Ve(e) {
99
101
  return Uint8Array.from(e);
100
102
  }
101
- function un(e, t) {
103
+ function jn(e, t) {
102
104
  const n = new Uint8Array(e.length + t.length);
103
105
  return n.set(e, 0), n.set(t, e.length), n;
104
106
  }
105
- async function ln(e, t) {
107
+ async function Gn(e, t) {
106
108
  if (!t) throw new Error("Asset key is required for encrypted assets");
107
109
  if (e.byteLength < 28)
108
110
  throw new Error("Encrypted payload too small");
109
- const n = new Uint8Array(e), r = Ce(n.subarray(0, 12)), i = Ce(n.subarray(12, 28)), s = Ce(n.subarray(28)), c = Ce(un(s, i)), a = await crypto.subtle.importKey(
111
+ const n = new Uint8Array(e), r = Ve(n.subarray(0, 12)), s = Ve(n.subarray(12, 28)), i = Ve(n.subarray(28)), o = Ve(jn(i, s)), a = await crypto.subtle.importKey(
110
112
  "raw",
111
- cn(t),
113
+ Kn(t),
112
114
  { name: "AES-GCM" },
113
115
  !1,
114
116
  ["decrypt"]
@@ -116,82 +118,98 @@ async function ln(e, t) {
116
118
  return crypto.subtle.decrypt(
117
119
  { name: "AES-GCM", iv: r, tagLength: 128 },
118
120
  a,
119
- c
121
+ o
120
122
  );
121
123
  }
122
- let je = null;
123
- const Ge = /* @__PURE__ */ new Set();
124
- function fn(e, t = jt) {
124
+ let rt = null;
125
+ const st = /* @__PURE__ */ new Set();
126
+ function $e(e) {
127
+ return e.includes("/custom-faces/");
128
+ }
129
+ function qe(e) {
130
+ const t = e.binBase.trim().replace(/\/$/, ""), n = e.twinBase.trim().replace(/\/$/, "");
131
+ if (!(e.encrypted || $e(t) || $e(n)))
132
+ return { twinBase: n, binBase: t, encrypted: !1 };
133
+ const s = $e(t) ? t : $e(n) ? n : t;
134
+ return { twinBase: s, binBase: s, encrypted: !0 };
135
+ }
136
+ function Ie(e) {
137
+ return qe(e).encrypted;
138
+ }
139
+ function Dt(e, t = Mn) {
125
140
  const n = `${t.replace(/\/$/, "")}/${e}`;
126
141
  return { twinBase: n, binBase: n, encrypted: !0 };
127
142
  }
128
- function dn(e) {
129
- je = e;
130
- for (const t of Ge) t();
143
+ function zn(e, t) {
144
+ return (e ?? t)?.trim() || void 0;
145
+ }
146
+ function Yn(e) {
147
+ rt = qe(e);
148
+ for (const t of st) t();
131
149
  }
132
- function hn(e, t) {
150
+ function Jn(e, t) {
133
151
  const n = typeof globalThis.location < "u" ? globalThis.location.href : void 0;
134
- if (!n) return e;
135
- const r = (i) => {
152
+ if (!n) return qe(e);
153
+ const r = (s) => {
136
154
  try {
137
- return new URL(i, n).href.replace(/\/$/, "");
155
+ return new URL(s, n).href.replace(/\/$/, "");
138
156
  } catch {
139
- return i;
157
+ return s;
140
158
  }
141
159
  };
142
- return {
160
+ return qe({
143
161
  twinBase: r(e.twinBase),
144
162
  binBase: r(e.binBase),
145
163
  encrypted: e.encrypted
146
- };
164
+ });
147
165
  }
148
- function he() {
149
- if (!je)
166
+ function ke() {
167
+ if (!rt)
150
168
  throw new Error("Twin assets not configured; call setActiveTwinAssets first");
151
- return je;
169
+ return rt;
152
170
  }
153
- function mn(e) {
154
- return Ge.add(e), () => Ge.delete(e);
171
+ function Qn(e) {
172
+ return st.add(e), () => st.delete(e);
155
173
  }
156
- function at() {
157
- const { encrypted: e, binBase: t, twinBase: n } = he();
158
- return e ? `${t}/sil.bin` : `${n}/sil.png`;
174
+ function Mt() {
175
+ const e = ke();
176
+ return Ie(e) ? `${e.binBase}/sil.bin` : `${e.twinBase}/sil.png`;
159
177
  }
160
- function _n() {
161
- const { encrypted: e, binBase: t, twinBase: n } = he();
162
- return e ? `${t}/idle.bin` : `${n}/idle.mp4`;
178
+ function Xn() {
179
+ const e = ke();
180
+ return Ie(e) ? `${e.binBase}/idle.bin` : `${e.twinBase}/idle.mp4`;
163
181
  }
164
- function wn() {
165
- const { encrypted: e, binBase: t, twinBase: n } = he();
166
- return e ? t : n;
182
+ function Zn() {
183
+ const e = ke();
184
+ return Ie(e) ? e.binBase : e.twinBase;
167
185
  }
168
- function Be() {
169
- return he().encrypted;
186
+ function Ge() {
187
+ return Ie(ke());
170
188
  }
171
- function gn() {
172
- const { binBase: e, twinBase: t, encrypted: n } = he();
173
- return n ? `${e}/atlas.bin` : `${t}/atlas.json`;
189
+ function er() {
190
+ const e = ke();
191
+ return Ie(e) ? `${e.binBase}/atlas.bin` : `${e.twinBase}/atlas.json`;
174
192
  }
175
- function yn() {
176
- const { binBase: e, twinBase: t, encrypted: n } = he();
177
- return n ? `${e}/expression_atlas.bin` : `${t}/expression_atlas.json`;
193
+ function tr() {
194
+ const e = ke();
195
+ return Ie(e) ? `${e.binBase}/expression_atlas.bin` : `${e.twinBase}/expression_atlas.json`;
178
196
  }
179
- function pn(e) {
197
+ function nr(e) {
180
198
  const t = e.split(/\r?\n/);
181
199
  let n = "", r = "";
182
- for (const s of t)
183
- s.startsWith("event:") ? n = s.slice(6).trim() : s.startsWith("data:") && (r = s.slice(5).trim());
200
+ for (const i of t)
201
+ i.startsWith("event:") ? n = i.slice(6).trim() : i.startsWith("data:") && (r = i.slice(5).trim());
184
202
  if (!n) return null;
185
- let i = {};
203
+ let s = {};
186
204
  if (r)
187
205
  try {
188
- i = JSON.parse(r);
206
+ s = JSON.parse(r);
189
207
  } catch {
190
- i = { raw: r };
208
+ s = { raw: r };
191
209
  }
192
- return { event: n, data: i };
210
+ return { event: n, data: s };
193
211
  }
194
- const En = [
212
+ const rr = [
195
213
  "aa",
196
214
  "CH",
197
215
  "DD",
@@ -207,14 +225,14 @@ const En = [
207
225
  "kk",
208
226
  "nn",
209
227
  "sil"
210
- ], Sn = new Map(
211
- En.map((e) => [e.toLowerCase(), e])
228
+ ], sr = new Map(
229
+ rr.map((e) => [e.toLowerCase(), e])
212
230
  );
213
- function kn(e) {
231
+ function ir(e) {
214
232
  const t = (e ?? "").trim();
215
- return t ? Sn.get(t.toLowerCase()) ?? "sil" : "sil";
233
+ return t ? sr.get(t.toLowerCase()) ?? "sil" : "sil";
216
234
  }
217
- const Tn = {
235
+ const or = {
218
236
  aei: ["aa", "E", "I"],
219
237
  o: ["O", "U"],
220
238
  ee: ["I"],
@@ -226,46 +244,46 @@ const Tn = {
226
244
  qw: ["U", "O"],
227
245
  cdgknstxyz: ["DD", "SS", "kk", "CH"]
228
246
  };
229
- function vn(e) {
247
+ function ar(e) {
230
248
  if (!e) return ["sil"];
231
249
  const t = e.toLowerCase();
232
- return Tn[t] ?? ["sil"];
250
+ return or[t] ?? ["sil"];
233
251
  }
234
- function In(e, t) {
252
+ function cr(e, t) {
235
253
  const n = e.word.length;
236
254
  if (n <= 0) return 0;
237
255
  const r = e.wduration;
238
256
  if (r <= 0) return 0;
239
- const i = Math.max(0, Math.min(1, (t - e.wtime) / r));
240
- return Math.min(n - 1, Math.floor(i * n));
257
+ const s = Math.max(0, Math.min(1, (t - e.wtime) / r));
258
+ return Math.min(n - 1, Math.floor(s * n));
241
259
  }
242
- function Ne(e, t) {
260
+ function ze(e, t) {
243
261
  const n = Math.max(0, Math.min(e.length - 1, t));
244
262
  return e[n] ?? "";
245
263
  }
246
- function An(e, t) {
247
- const n = e.toLowerCase(), r = Ne(n, t), i = n.slice(Math.max(0, t - 1), t + 2);
248
- return r === "i" || r === "y" ? "I" : i.includes("ee") || r === "e" || n.includes("ea") ? "E" : "aa";
264
+ function ur(e, t) {
265
+ const n = e.toLowerCase(), r = ze(n, t), s = n.slice(Math.max(0, t - 1), t + 2);
266
+ return r === "i" || r === "y" ? "I" : s.includes("ee") || r === "e" || n.includes("ea") ? "E" : "aa";
249
267
  }
250
- function bn(e, t) {
268
+ function lr(e, t) {
251
269
  const n = e.toLowerCase(), r = n.slice(
252
270
  Math.max(0, t - 1),
253
271
  Math.min(n.length, t + 3)
254
272
  );
255
273
  if (/oo|ou|uw/.test(r)) return "U";
256
- const i = Ne(n, t);
257
- return i === "u" || i === "w" ? "U" : "O";
274
+ const s = ze(n, t);
275
+ return s === "u" || s === "w" ? "U" : "O";
258
276
  }
259
- function Rn(e, t) {
277
+ function fr(e, t) {
260
278
  const n = e.toLowerCase(), r = n.slice(Math.max(0, t - 2), t + 1);
261
279
  if (/qu/.test(r)) return "U";
262
- const i = n.slice(
280
+ const s = n.slice(
263
281
  Math.max(0, t - 1),
264
282
  Math.min(n.length, t + 3)
265
283
  );
266
- return /wo|wh/.test(i) || Ne(n, t) === "o" ? "O" : "U";
284
+ return /wo|wh/.test(s) || ze(n, t) === "o" ? "O" : "U";
267
285
  }
268
- const Fe = {
286
+ const He = {
269
287
  d: "DD",
270
288
  t: "DD",
271
289
  n: "DD",
@@ -277,65 +295,65 @@ const Fe = {
277
295
  x: "CH",
278
296
  j: "CH"
279
297
  };
280
- function Dn(e, t) {
281
- const n = e.toLowerCase(), r = Ne(n, t);
282
- if (Fe[r]) return Fe[r];
283
- for (let i = 0; i < n.length; i++) {
284
- const s = n[i];
285
- if (Fe[s]) return Fe[s];
298
+ function dr(e, t) {
299
+ const n = e.toLowerCase(), r = ze(n, t);
300
+ if (He[r]) return He[r];
301
+ for (let s = 0; s < n.length; s++) {
302
+ const i = n[s];
303
+ if (He[i]) return He[i];
286
304
  }
287
305
  return "DD";
288
306
  }
289
- function xn(e, t, n) {
290
- const r = vn(e);
307
+ function hr(e, t, n) {
308
+ const r = ar(e);
291
309
  if (r.length === 1) return r[0];
292
- const i = t.trim();
293
- if (!i) return r[0];
294
- const s = (e ?? "").toLowerCase(), c = Math.max(0, n);
295
- switch (s) {
310
+ const s = t.trim();
311
+ if (!s) return r[0];
312
+ const i = (e ?? "").toLowerCase(), o = Math.max(0, n);
313
+ switch (i) {
296
314
  case "aei":
297
- return An(i, c);
315
+ return ur(s, o);
298
316
  case "o":
299
- return bn(i, c);
317
+ return lr(s, o);
300
318
  case "qw":
301
- return Rn(i, c);
319
+ return fr(s, o);
302
320
  case "cdgknstxyz":
303
- return Dn(i, c);
321
+ return dr(s, o);
304
322
  default:
305
323
  return r[0];
306
324
  }
307
325
  }
308
- function Mn(e) {
326
+ const mr = 24e3;
327
+ function wr(e) {
309
328
  let t = e.trim();
310
329
  const n = t.indexOf(",");
311
330
  t.startsWith("data:") && n >= 0 && (t = t.slice(n + 1)), t = t.replace(/\s+/g, "").replace(/-/g, "+").replace(/_/g, "/");
312
331
  const r = t.length % 4;
313
332
  return r !== 0 && (t += "=".repeat(4 - r)), t;
314
333
  }
315
- const Cn = 24e3;
316
- function Fn(e) {
334
+ function gr(e) {
317
335
  return e.length >= 4 && e[0] === 82 && e[1] === 73 && e[2] === 70 && e[3] === 70;
318
336
  }
319
- function ct(e, t, n = Cn) {
320
- const r = t.byteOffset % 2 === 0 ? t : t.slice(), i = new Int16Array(
337
+ function xt(e, t, n = mr) {
338
+ const r = t.byteOffset % 2 === 0 ? t : t.slice(), s = new Int16Array(
321
339
  r.buffer,
322
340
  r.byteOffset,
323
341
  r.byteLength / 2
324
- ), s = new Float32Array(i.length);
325
- for (let a = 0; a < i.length; a++)
326
- s[a] = i[a] >= 32768 ? -(65536 - i[a]) / 32768 : i[a] / 32767;
327
- const c = e.createBuffer(1, s.length, n);
328
- return c.copyToChannel(s, 0), c;
329
- }
330
- function Ln(e) {
331
- const t = Mn(e), n = window.atob(t), r = new Uint8Array(n.length);
332
- for (let i = 0; i < n.length; i++)
333
- r[i] = n.charCodeAt(i);
342
+ ), i = new Float32Array(s.length);
343
+ for (let a = 0; a < s.length; a++)
344
+ i[a] = s[a] >= 32768 ? -(65536 - s[a]) / 32768 : s[a] / 32767;
345
+ const o = e.createBuffer(1, i.length, n);
346
+ return o.copyToChannel(i, 0), o;
347
+ }
348
+ function _r(e) {
349
+ const t = wr(e), n = window.atob(t), r = new Uint8Array(n.length);
350
+ for (let s = 0; s < n.length; s++)
351
+ r[s] = n.charCodeAt(s);
334
352
  return r;
335
353
  }
336
- async function On(e, t) {
337
- const n = Ln(t);
338
- if (Fn(n)) {
354
+ async function pr(e, t) {
355
+ const n = _r(t);
356
+ if (gr(n)) {
339
357
  const r = n.buffer.slice(
340
358
  n.byteOffset,
341
359
  n.byteOffset + n.byteLength
@@ -343,7 +361,7 @@ async function On(e, t) {
343
361
  return e.decodeAudioData(r);
344
362
  }
345
363
  if (n.length >= 2 && n.length % 2 === 0)
346
- return ct(e, n);
364
+ return xt(e, n);
347
365
  try {
348
366
  const r = n.buffer.slice(
349
367
  n.byteOffset,
@@ -351,241 +369,327 @@ async function On(e, t) {
351
369
  );
352
370
  return await e.decodeAudioData(r);
353
371
  } catch {
354
- return ct(e, n);
372
+ return xt(e, n);
355
373
  }
356
374
  }
357
- function vt(e, t) {
358
- let n = null;
359
- for (const r of e)
360
- t < r.vtime || t >= r.vtime + r.vduration || (!n || r.vtime >= n.vtime) && (n = r);
361
- return n ? n.viseme : "sil";
375
+ function Ct(e) {
376
+ let t = 0;
377
+ for (const n of e)
378
+ t = Math.max(t, n.vtime + n.vduration);
379
+ return t;
362
380
  }
363
- function Pn(e, t) {
381
+ function yr(e, t) {
364
382
  for (const n of e)
365
383
  if (t >= n.wtime && t < n.wtime + n.wduration)
366
384
  return n;
367
385
  return null;
368
386
  }
369
- function ut(e) {
370
- let t = 0;
371
- for (const n of e)
372
- t = Math.max(t, n.vtime + n.vduration);
373
- return t;
374
- }
375
- const Un = 0.5, Bn = 1.5, It = "Olivia", Nn = "f786b574-daa5-4673-aa0c-cbe3e8534c02", At = 0.85;
376
- function Vn(e, t = Pe) {
377
- const n = `${t.replace(/\/$/, "")}/avatar_ttsWithPoses`, r = [], i = [], s = [];
378
- let c = "neutral";
379
- const a = [], l = [];
380
- let d = null, _ = !1, m = !1, S = !1, o = !1, F = 0, w = 0, u = 0, g = 0, y = null, v = 1, H = "", h = pe, E = pe, D = !1;
381
- const L = /* @__PURE__ */ new Set(), z = () => {
382
- for (const p of l)
383
- p.playbackRate.value = v;
384
- }, U = () => L.forEach((p) => p()), ae = () => {
385
- y != null && (clearTimeout(y), y = null);
386
- }, me = () => {
387
- for (const p of l)
387
+ function Xt(e, t) {
388
+ const n = [], r = [];
389
+ let s = null, i = !1, o = !1, a = !1, f = !1, l = 0, w = 0, _ = 0, m = 0, S = null, E = 1, u = t, p = !1;
390
+ const d = () => {
391
+ S != null && (clearTimeout(S), S = null);
392
+ }, I = () => {
393
+ for (const g of r)
388
394
  try {
389
- p.stop();
395
+ g.stop();
390
396
  } catch {
391
397
  }
392
- l.length = 0;
393
- }, N = () => {
394
- D = !0, ae(), me(), a.length = 0, _ = !1, m = !1, S = !1, o = !1, r.length = 0, i.length = 0, s.length = 0, c = "neutral", u = 0, g = 0, w = 0, e("idle"), U();
395
- }, X = () => {
396
- !o || _ || l.length > 0 || a.length > 0 || (m = !1, ae(), e("done"), U());
397
- }, Re = () => {
398
- const p = ut(r);
399
- if (p <= 0) {
400
- e("done"), U();
398
+ r.length = 0;
399
+ }, k = () => {
400
+ for (const g of r)
401
+ g.playbackRate.value = E;
402
+ }, R = () => {
403
+ !f || i || r.length > 0 || n.length > 0 || (o = !1, d(), e.onSpeakingDone(), e.onNotify());
404
+ }, W = (g) => {
405
+ const x = Ct(g);
406
+ if (x <= 0) {
407
+ e.onSpeakingDone(), e.onNotify();
401
408
  return;
402
409
  }
403
- m = !0, F = performance.now(), e("speaking"), U(), ae();
404
- const V = v > 0 ? p / v : p;
405
- y = setTimeout(() => {
406
- D || (m = !1, y = null, e("done"), U());
407
- }, V);
408
- }, He = (p, V, W) => {
409
- p.length !== 0 && (W && (u = V), p.forEach((x) => {
410
- const I = String(x.word ?? "").trim();
411
- if (!I) return;
412
- const Q = Math.round((x.start ?? 0) * 1e3), J = Math.round((x.duration ?? 0) * 1e3);
413
- i.push({
414
- word: I,
415
- wtime: u + Q,
416
- wduration: J,
417
- queueIndex: i.length
410
+ o = !0, l = performance.now(), e.onSpeakingStart(), e.onNotify(), d();
411
+ const b = E > 0 ? x / E : x;
412
+ S = setTimeout(() => {
413
+ p || (o = !1, S = null, e.onSpeakingDone(), e.onNotify());
414
+ }, b);
415
+ }, V = (g, x, b, D) => {
416
+ x.length !== 0 && (D && (_ = b), x.forEach((A) => {
417
+ const B = String(A.word ?? "").trim();
418
+ if (!B) return;
419
+ const $ = Math.round((A.start ?? 0) * 1e3), U = A.duration != null ? Math.round(A.duration * 1e3) : A.end != null ? Math.max(1, Math.round((A.end - (A.start ?? 0)) * 1e3)) : 0;
420
+ g.push({
421
+ word: B,
422
+ wtime: _ + $,
423
+ wduration: U,
424
+ queueIndex: g.length,
425
+ gesture: A.gesture ?? null,
426
+ emphasis: A.emphasis === !0
418
427
  });
419
428
  }));
420
- }, De = (p, V, W, x) => {
421
- p.length !== 0 && (W && (u = V), p.forEach((M) => {
422
- const I = String(M.symbol ?? "").trim();
423
- if (!I) return;
424
- const Q = Math.round((M.start ?? 0) * 1e3), J = Math.max(
425
- 1,
426
- Math.round((M.duration ?? 0) * 1e3)
427
- ), P = u + Q;
428
- let O;
429
- if (Yt(x) === "oculus_direct")
430
- O = kn(I);
429
+ }, H = (g, x, b, D, A, P) => {
430
+ b.length !== 0 && (A && (_ = D), b.forEach((B) => {
431
+ const $ = String(B.symbol ?? B.viseme ?? "").trim();
432
+ if (!$) return;
433
+ const U = Math.round((B.start ?? 0) * 1e3), X = Math.max(1, Math.round((B.duration ?? 0) * 1e3)), se = _ + U;
434
+ let Z;
435
+ if (On(P) === "oculus_direct")
436
+ Z = ir($);
431
437
  else {
432
- const q = Pn(i, P), ce = q ? In(q, P) : 0;
433
- O = xn(
434
- I,
435
- q?.word ?? "",
436
- ce
438
+ const ce = yr(x, se), J = ce ? cr(ce, se) : 0;
439
+ Z = hr(
440
+ $,
441
+ ce?.word ?? "",
442
+ J
437
443
  );
438
444
  }
439
- r.push({
440
- viseme: O,
445
+ g.push({
446
+ viseme: Z,
441
447
  weight: 1,
442
- vtime: P,
443
- vduration: J
448
+ vtime: se,
449
+ vduration: X
444
450
  });
445
- }), U());
446
- }, ue = (p, V, W, x, M) => {
447
- He(V, W, x), De(p, W, x, M);
448
- }, se = async (p, V, W, x) => {
449
- if (D || !p?.trim()) {
450
- (V.length > 0 || W.length > 0) && !S && ue(
451
- V,
452
- W,
453
- u,
451
+ }), e.onNotify());
452
+ }, j = (g, x, b, D, A, P, B) => {
453
+ V(x, D, A, P), H(
454
+ g,
455
+ x,
456
+ b,
457
+ A,
458
+ P,
459
+ B
460
+ );
461
+ }, y = async (g, x, b, D, A, P, B) => {
462
+ if (p || !b?.trim()) {
463
+ (D.length > 0 || A.length > 0) && !a && j(
464
+ g,
454
465
  x,
455
- E
466
+ D,
467
+ A,
468
+ _,
469
+ P,
470
+ u
456
471
  );
457
472
  return;
458
473
  }
459
- if (_) {
460
- a.push({
461
- audio: p,
462
- visemes: V,
463
- words: W,
464
- isNewSegment: x
474
+ if (i) {
475
+ n.push({
476
+ audio: b,
477
+ visemes: D,
478
+ words: A,
479
+ isNewSegment: P
465
480
  });
466
481
  return;
467
482
  }
468
- _ = !0;
483
+ i = !0;
469
484
  try {
470
- const M = window.AudioContext || window.webkitAudioContext, I = d ?? new M();
471
- I.state === "suspended" && await I.resume(), d = I;
472
- const Q = await On(I, p);
473
- S = !0;
474
- const J = I.currentTime;
475
- let P = g;
476
- const O = !m;
477
- P < J && (P = J + 0.1), g = P + Q.duration;
478
- const q = I.createBufferSource();
479
- if (q.buffer = Q, q.playbackRate.value = v, q.connect(I.destination), l.push(q), D) {
480
- l.pop();
485
+ const $ = window.AudioContext || window.webkitAudioContext;
486
+ s || (s = new $());
487
+ const U = s;
488
+ U.state === "suspended" && await U.resume();
489
+ const X = await pr(U, b);
490
+ a = !0;
491
+ const se = U.currentTime;
492
+ let Z = m;
493
+ const ce = !o;
494
+ Z < se && (Z = se + 0.1), m = Z + X.duration;
495
+ const J = U.createBufferSource();
496
+ if (J.buffer = X, J.playbackRate.value = E, J.connect(U.destination), r.push(J), p) {
497
+ r.pop();
481
498
  return;
482
499
  }
483
- if (O) {
484
- m = !0, e("speaking"), w = P, u = 0, r.length = 0, i.length = 0;
485
- const $ = (P - J) * 1e3;
486
- F = performance.now() + $;
500
+ if (ce) {
501
+ o = !0, e.onSpeakingStart(), w = Z, _ = 0, g.length = 0, x.length = 0, B?.();
502
+ const v = (Z - se) * 1e3;
503
+ l = performance.now() + v;
487
504
  }
488
- q.onended = () => {
489
- const $ = l.indexOf(q);
490
- $ >= 0 && l.splice($, 1), X(), U();
491
- }, q.start(P);
492
- const ce = (P - w) * 1e3;
493
- ue(
494
- V,
495
- W,
496
- ce,
505
+ J.onended = () => {
506
+ const v = r.indexOf(J);
507
+ v >= 0 && r.splice(v, 1), R(), e.onNotify();
508
+ }, J.start(Z);
509
+ const c = (Z - w) * 1e3;
510
+ j(
511
+ g,
497
512
  x,
498
- E
513
+ D,
514
+ A,
515
+ c,
516
+ P,
517
+ u
499
518
  );
500
- } catch (M) {
501
- console.error("[avatarTtsLipsync] audio chunk failed:", M);
519
+ } catch ($) {
520
+ console.error("[avatarChunkPlayback] audio chunk failed:", $);
502
521
  } finally {
503
- _ = !1;
504
- const M = a.shift();
505
- M ? await se(
506
- M.audio,
507
- M.visemes,
508
- M.words,
509
- M.isNewSegment
510
- ) : X();
522
+ i = !1;
523
+ const $ = n.shift();
524
+ $ ? await y(
525
+ g,
526
+ x,
527
+ $.audio,
528
+ $.visemes,
529
+ $.words,
530
+ $.isNewSegment,
531
+ B
532
+ ) : R();
511
533
  }
512
- }, xe = () => {
513
- if (o = !0, !S && r.length > 0) {
514
- Re();
515
- return;
534
+ };
535
+ return {
536
+ setStreamTtsEngineId: (g) => {
537
+ u = g;
538
+ },
539
+ setPlaybackSpeed: (g) => {
540
+ E = Math.max(0.1, Math.min(1, g)), k();
541
+ },
542
+ getPlaybackSpeed: () => E,
543
+ resetForNewStream: (g) => {
544
+ p = !1, f = !1, u = g;
545
+ },
546
+ /** Call from a user gesture before bot audio (connect / unlock). */
547
+ primeAudioContext: async () => {
548
+ const g = window.AudioContext || window.webkitAudioContext;
549
+ s || (s = new g()), s.state === "suspended" && await s.resume();
550
+ },
551
+ stop: () => {
552
+ p = !0, d(), I(), n.length = 0, i = !1, o = !1, a = !1, f = !1, _ = 0, m = 0, w = 0, l = 0;
553
+ },
554
+ markStreamComplete: (g) => {
555
+ if (f = !0, !a && g.length > 0) {
556
+ W(g);
557
+ return;
558
+ }
559
+ R();
560
+ },
561
+ playAudioChunk: y,
562
+ queueTimingsOnly: (g, x, b, D, A) => {
563
+ let P = _;
564
+ A && g.length > 0 && (P = Ct(g)), j(
565
+ g,
566
+ x,
567
+ b,
568
+ D,
569
+ P,
570
+ A,
571
+ u
572
+ );
573
+ },
574
+ getPlaybackElapsedMs: () => o ? a && s && w > 0 ? Math.max(
575
+ 0,
576
+ (s.currentTime - w) * 1e3
577
+ ) : Math.max(0, (performance.now() - l) * E) : 0,
578
+ isSpeaking: () => o,
579
+ getPlaybackStartPerf: () => l,
580
+ /** User spoke over the bot — drop in-flight chunks until the next utterance. */
581
+ bargeIn: () => {
582
+ p = !0, I(), n.length = 0, i = !1, o = !1, a = !1, m = 0, w = 0, l = 0, d();
583
+ },
584
+ interrupt: () => {
585
+ I(), n.length = 0, i = !1, o = !1, a = !1, m = 0, w = 0, l = 0, d();
516
586
  }
517
- X();
587
+ };
588
+ }
589
+ function lt(e, t) {
590
+ let n = null;
591
+ for (const r of e)
592
+ t < r.vtime || t >= r.vtime + r.vduration || (!n || r.vtime >= n.vtime) && (n = r);
593
+ return n ? n.viseme : "sil";
594
+ }
595
+ function Hs(e, t) {
596
+ for (const n of e)
597
+ if (t >= n.wtime && t < n.wtime + n.wduration)
598
+ return n;
599
+ return null;
600
+ }
601
+ const Zt = 0.5, en = 1.5, tn = "Olivia", kr = "f786b574-daa5-4673-aa0c-cbe3e8534c02", ft = 0.85;
602
+ function Pt(e, t = be) {
603
+ const n = `${t.replace(/\/$/, "")}/avatar_ttsWithPoses`, r = [], s = [], i = [];
604
+ let o = "neutral", a = "", f = Te;
605
+ const l = /* @__PURE__ */ new Set(), w = () => l.forEach((E) => E()), _ = Xt(
606
+ {
607
+ onSpeakingStart: () => e("speaking"),
608
+ onSpeakingDone: () => e("done"),
609
+ onNotify: w
610
+ },
611
+ Te
612
+ ), m = () => {
613
+ _.stop(), r.length = 0, s.length = 0, i.length = 0, o = "neutral", e("idle"), w();
518
614
  };
519
615
  return {
520
- setDeveloperToken: (p) => {
521
- H = p;
616
+ setDeveloperToken: (E) => {
617
+ a = E;
522
618
  },
523
- setTtsEngineId: (p) => {
524
- h = p;
619
+ setTtsEngineId: (E) => {
620
+ f = E;
525
621
  },
526
- getTtsEngineId: () => h,
527
- speak: async (p, V) => {
528
- N(), D = !1, e("loading");
529
- const W = H.trim();
530
- if (!W)
622
+ getTtsEngineId: () => f,
623
+ speak: async (E, u) => {
624
+ m(), e("loading");
625
+ const p = a.trim();
626
+ if (!p)
531
627
  throw new Error("Developer token required for avatar_ttsWithPoses");
532
- const x = V?.ttsEngineId ?? h ?? pe;
533
- E = x;
534
- const M = V?.voiceId ?? It, I = V?.speakingRate ?? At, Q = Math.max(
535
- Un,
536
- Math.min(Bn, I)
537
- ), J = {
538
- user_query: p,
539
- ttsEngineId: x,
540
- speakingRate: Q
628
+ const d = u?.ttsEngineId ?? f ?? Te;
629
+ _.resetForNewStream(d), _.setStreamTtsEngineId(d);
630
+ const I = u?.voiceId ?? tn, k = u?.speakingRate ?? ft, R = Math.max(
631
+ Zt,
632
+ Math.min(en, k)
633
+ ), W = {
634
+ user_query: E,
635
+ ttsEngineId: d,
636
+ speakingRate: R
541
637
  };
542
- Jt.has(x) && (J.voice_id = M);
638
+ Bn.has(d) && (W.voice_id = I);
543
639
  try {
544
- const P = await fetch(n, {
640
+ const V = await fetch(n, {
545
641
  method: "POST",
546
642
  headers: {
547
643
  "Content-Type": "application/json",
548
- Authorization: `Bearer ${W}`
644
+ Authorization: `Bearer ${p}`
549
645
  },
550
- body: JSON.stringify(J)
646
+ body: JSON.stringify(W)
551
647
  });
552
- if (!P.ok)
553
- throw new Error(`avatar_ttsWithPoses failed (${P.status})`);
554
- const O = P.body;
555
- if (!O) throw new Error("No response body");
556
- const q = O.getReader(), ce = new TextDecoder();
557
- let $ = "";
558
- const Me = async (B) => {
559
- const b = pn(B);
648
+ if (!V.ok)
649
+ throw new Error(`avatar_ttsWithPoses failed (${V.status})`);
650
+ const H = V.body;
651
+ if (!H) throw new Error("No response body");
652
+ const j = H.getReader(), y = new TextDecoder();
653
+ let T = "";
654
+ const g = async (x) => {
655
+ const b = nr(x);
560
656
  if (b) {
561
657
  if (b.event === "audio") {
562
- const K = b.data.chunk, te = b.data.visemes ?? [], Z = b.data.words ?? [], j = b.data.is_new_segment ?? !1;
563
- if (K)
564
- await se(K, te, Z, j);
565
- else if (te.length > 0 || Z.length > 0) {
566
- const _e = j && r.length > 0 ? ut(r) : u;
567
- ue(te, Z, _e, j, x);
568
- }
658
+ const D = b.data.chunk, A = b.data.visemes ?? [], P = b.data.words ?? [], B = b.data.is_new_segment ?? !1;
659
+ D ? await _.playAudioChunk(
660
+ r,
661
+ s,
662
+ D,
663
+ A,
664
+ P,
665
+ B
666
+ ) : (A.length > 0 || P.length > 0) && _.queueTimingsOnly(
667
+ r,
668
+ s,
669
+ A,
670
+ P,
671
+ B
672
+ );
569
673
  } else if (b.event === "metadata") {
570
- const K = b.data.mood;
571
- typeof K == "string" && K.trim() && (c = K.trim());
572
- const te = b.data.sentence_emotions;
573
- if (Array.isArray(te)) {
574
- s.length = 0;
575
- for (const Z of te) {
576
- if (!Z || typeof Z != "object") continue;
577
- const j = Z;
578
- s.push({
579
- sentence_index: Number(j.sentence_index ?? 0),
580
- text: String(j.text ?? ""),
581
- sentiment: typeof j.sentiment == "string" ? j.sentiment : void 0,
582
- emotion: String(j.emotion ?? c),
583
- start_word: Number(j.start_word ?? 0),
584
- end_word: Number(j.end_word ?? 0)
674
+ const D = b.data.mood;
675
+ typeof D == "string" && D.trim() && (o = D.trim());
676
+ const A = b.data.sentence_emotions;
677
+ if (Array.isArray(A)) {
678
+ i.length = 0;
679
+ for (const P of A) {
680
+ if (!P || typeof P != "object") continue;
681
+ const B = P;
682
+ i.push({
683
+ sentence_index: Number(B.sentence_index ?? 0),
684
+ text: String(B.text ?? ""),
685
+ sentiment: typeof B.sentiment == "string" ? B.sentiment : void 0,
686
+ emotion: String(B.emotion ?? o),
687
+ start_word: Number(B.start_word ?? 0),
688
+ end_word: Number(B.end_word ?? 0)
585
689
  });
586
690
  }
587
691
  }
588
- U();
692
+ w();
589
693
  } else if (b.event === "error")
590
694
  throw new Error(
591
695
  String(b.data.message ?? "avatar_ttsWithPoses stream error")
@@ -593,46 +697,357 @@ function Vn(e, t = Pe) {
593
697
  }
594
698
  };
595
699
  for (; ; ) {
596
- const { done: B, value: b } = await q.read();
597
- b && ($ += ce.decode(b, { stream: !0 }));
598
- const K = $.split(`
700
+ const { done: x, value: b } = await j.read();
701
+ b && (T += y.decode(b, { stream: !0 }));
702
+ const D = T.split(`
599
703
 
600
704
  `);
601
- $ = K.pop() ?? "";
602
- for (const te of K) await Me(te);
603
- if (B) {
604
- $.trim() && await Me($.trim()), D || xe();
705
+ T = D.pop() ?? "";
706
+ for (const A of D) await g(A);
707
+ if (x) {
708
+ T.trim() && await g(T.trim()), _.markStreamComplete(r);
605
709
  break;
606
710
  }
607
711
  }
608
- } catch (P) {
609
- throw console.error("[avatarTtsLipsync]", P), N(), e("error"), P;
712
+ } catch (V) {
713
+ throw console.error("[avatarTtsLipsync]", V), m(), e("error"), V;
610
714
  }
611
715
  },
612
- stop: N,
716
+ stop: m,
613
717
  getVisemeQueue: () => r,
614
- getWordQueue: () => i,
718
+ getWordQueue: () => s,
719
+ getSentenceEmotions: () => i,
720
+ getStreamMood: () => o,
721
+ getPlaybackElapsedMs: () => _.getPlaybackElapsedMs(),
722
+ isSpeaking: () => _.isSpeaking(),
723
+ setPlaybackSpeed: (E) => {
724
+ _.setPlaybackSpeed(E);
725
+ },
726
+ getPlaybackSpeed: () => _.getPlaybackSpeed(),
727
+ subscribe: (E) => (l.add(E), () => l.delete(E))
728
+ };
729
+ }
730
+ const nn = 16e3, rn = 24e3;
731
+ class Er extends Tn {
732
+ constructor() {
733
+ super(
734
+ !0,
735
+ !0,
736
+ void 0,
737
+ void 0,
738
+ 512,
739
+ nn,
740
+ rn
741
+ );
742
+ }
743
+ /** Pipecat protobuf bot audio is unused — playback comes from avatar_audio_chunk. */
744
+ bufferBotAudio(t, n) {
745
+ }
746
+ }
747
+ const Sr = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
748
+ function vr(e) {
749
+ return Sr.test(e.trim());
750
+ }
751
+ function br(e) {
752
+ const t = e.replace(/\/$/, "");
753
+ return t.startsWith("https://") ? `wss://${t.slice(8)}` : t.startsWith("http://") ? `ws://${t.slice(7)}` : t;
754
+ }
755
+ function Tr(e) {
756
+ if (e.wsUrl?.trim()) return e.wsUrl.trim();
757
+ const t = e.authToken?.trim();
758
+ if (!t)
759
+ throw new Error(
760
+ "Voice connect requires authToken (same JWT as SSE Authorization Bearer)."
761
+ );
762
+ const n = e.apiBase ?? be, r = new URL(`${br(n)}/ws/voice`);
763
+ r.searchParams.set("authToken", t);
764
+ const s = e.voiceId?.trim();
765
+ s && vr(s) && r.searchParams.set("voiceId", s);
766
+ const i = e.speakingRate ?? ft;
767
+ return r.searchParams.set(
768
+ "speaking_rate",
769
+ String(Math.max(Zt, Math.min(en, i)))
770
+ ), e.ttsStream === !1 ? r.searchParams.set("tts_stream", "false") : r.searchParams.set("tts_stream", "true"), r.toString();
771
+ }
772
+ function Bt(e, t) {
773
+ if (!Array.isArray(e)) return [];
774
+ const n = [];
775
+ for (const r of e)
776
+ !r || typeof r != "object" || n.push({
777
+ sentence_index: Number(r.sentence_index ?? 0),
778
+ text: String(r.text ?? ""),
779
+ sentiment: typeof r.sentiment == "string" ? r.sentiment : void 0,
780
+ emotion: String(r.emotion ?? t),
781
+ start_word: Number(r.start_word ?? 0),
782
+ end_word: Number(r.end_word ?? 0)
783
+ });
784
+ return n;
785
+ }
786
+ function Ar(e) {
787
+ if (!e || typeof e != "object") return null;
788
+ const t = e, n = t.data;
789
+ return n && typeof n == "object" ? n : t;
790
+ }
791
+ function Ir(e, t = {}) {
792
+ const n = [], r = [], s = [], i = [];
793
+ let o = "", a = "neutral", f = Ae, l = !1, w = null, _ = null, m = { ...t }, S = 0, E = null;
794
+ const u = /* @__PURE__ */ new Set(), p = [];
795
+ let d = !1, I = null;
796
+ const k = () => u.forEach((c) => c()), R = Xt(
797
+ {
798
+ onSpeakingStart: () => e("speaking"),
799
+ onSpeakingDone: () => e("done"),
800
+ onNotify: k
801
+ },
802
+ f
803
+ ), W = () => {
804
+ if (I) return I;
805
+ const c = new MessageChannel();
806
+ return c.port1.onmessage = () => {
807
+ const v = p.shift();
808
+ v !== void 0 && $(v), p.length > 0 ? c.port2.postMessage(null) : d = !1;
809
+ }, I = c, c;
810
+ }, V = (c) => {
811
+ p.push(c), !d && (d = !0, W().port2.postMessage(null));
812
+ }, H = () => R.getPlaybackElapsedMs(), j = (c, v = o) => {
813
+ if (!m.onLipsyncDebug) return;
814
+ const O = H(), z = n;
815
+ m.onLipsyncDebug({
816
+ event: c,
817
+ spokenText: v,
818
+ mood: a,
819
+ playbackAnchorPerf: R.getPlaybackStartPerf(),
820
+ playbackElapsedMs: O,
821
+ queueLength: z.length,
822
+ activeViseme: lt(z, O),
823
+ segments: i.map((ne) => ({
824
+ ...ne,
825
+ visemes: [...ne.visemes]
826
+ }))
827
+ });
828
+ }, y = (c, v) => {
829
+ m.onLipsyncDebug && (E = { event: c, spokenText: v }, S === 0 && (S = requestAnimationFrame(() => {
830
+ S = 0;
831
+ const O = E;
832
+ E = null, O && j(O.event, O.spokenText);
833
+ })));
834
+ }, T = () => {
835
+ n.length = 0, r.length = 0, i.length = 0, o = "", a = "neutral", s.length = 0;
836
+ }, g = () => {
837
+ R.stop(), T(), y("reset"), k();
838
+ }, x = () => {
839
+ g(), e("idle"), k();
840
+ }, b = (c, v) => {
841
+ typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), Array.isArray(c.sentence_emotions) && c.sentence_emotions.length > 0 && (v && (s.length = 0), s.push(
842
+ ...Bt(c.sentence_emotions, a)
843
+ ));
844
+ }, D = (c) => {
845
+ const v = String(c.spoken_text ?? c.text ?? "").trim();
846
+ v && (o = v), R.resetForNewStream(f), typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), s.length = 0, s.push(
847
+ ...Bt(c.sentence_emotions, a)
848
+ ), Array.isArray(c.gestures) && c.gestures, y("metadata", v), k();
849
+ }, A = (c, v, O, z) => {
850
+ if (!m.onLipsyncDebug) return;
851
+ const ne = n.slice(O), Re = z.filter(
852
+ (G) => String(G.symbol ?? G.viseme ?? "").trim()
853
+ );
854
+ i.push({
855
+ spokenText: v,
856
+ audioOffsetMs: ne[0]?.vtime ?? 0,
857
+ isNewSegment: !!c.is_new_segment,
858
+ chunkDurationMs: c.chunk_duration_ms != null ? Number(c.chunk_duration_ms) : null,
859
+ receivedAtMs: performance.now(),
860
+ visemes: ne.map((G, Ee) => {
861
+ const Y = Re[Ee];
862
+ return {
863
+ rawSymbol: String(Y?.symbol ?? Y?.viseme ?? G.viseme).trim(),
864
+ viseme: G.viseme,
865
+ startSec: Number(Y?.start ?? 0),
866
+ durationSec: Number(Y?.duration ?? 0),
867
+ vtimeMs: G.vtime,
868
+ vdurationMs: G.vduration
869
+ };
870
+ })
871
+ });
872
+ }, P = (c) => {
873
+ const v = String(c.spoken_text ?? c.text ?? "").trim(), O = !!c.is_new_segment || Number(c.chunk_index ?? -1) === 0, z = c.visemes ?? [], ne = c.words ?? [], Re = String(c.chunk ?? "").trim();
874
+ v && (o = v), b(c, O), O && R.resetForNewStream(f);
875
+ const G = n.length;
876
+ R.playAudioChunk(
877
+ n,
878
+ r,
879
+ Re,
880
+ z,
881
+ ne,
882
+ O,
883
+ () => {
884
+ i.length = 0;
885
+ }
886
+ ).then(() => {
887
+ A(c, v, G, z), y("audio_chunk", v);
888
+ });
889
+ }, B = (c) => {
890
+ console.warn(
891
+ "[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk"
892
+ );
893
+ const v = String(c.spoken_text ?? c.text ?? "").trim();
894
+ v && (o = v), b(c, !!c.is_new_segment);
895
+ const O = n.length;
896
+ R.queueTimingsOnly(
897
+ n,
898
+ r,
899
+ c.visemes ?? [],
900
+ c.words ?? [],
901
+ !!c.is_new_segment
902
+ ), A(
903
+ c,
904
+ v,
905
+ O,
906
+ c.visemes ?? []
907
+ ), y("lipsync", v), k();
908
+ }, $ = (c) => {
909
+ const v = Ar(c);
910
+ if (!v) {
911
+ console.warn("[realtimeVoice] server message with no payload", c);
912
+ return;
913
+ }
914
+ const O = String(v.type ?? "unknown");
915
+ switch (O !== "avatar_metadata" && O !== "avatar_audio_chunk" && O !== "avatar_lipsync" && O !== "error" && console.debug("[realtimeVoice] server message", O, v), O) {
916
+ case "avatar_metadata":
917
+ D(v);
918
+ break;
919
+ case "avatar_audio_chunk":
920
+ P(v);
921
+ break;
922
+ case "avatar_lipsync":
923
+ B(v);
924
+ break;
925
+ case "error": {
926
+ const z = String(v.message ?? "Voice session error");
927
+ console.error("[realtimeVoice] server error:", z), e("error"), k();
928
+ break;
929
+ }
930
+ case "avatar_speak":
931
+ console.warn(
932
+ "[realtimeVoice] avatar_speak received; tts_stream=false Mode B is not wired yet:",
933
+ v.text
934
+ );
935
+ break;
936
+ }
937
+ }, U = () => w || (_ = new Er(), w = new vn({
938
+ transport: new bn({
939
+ mediaManager: _,
940
+ recorderSampleRate: nn,
941
+ playerSampleRate: rn
942
+ }),
943
+ enableCam: !1,
944
+ enableMic: !0,
945
+ callbacks: {
946
+ onBotReady: () => {
947
+ l = !0, e("idle"), k();
948
+ },
949
+ onDisconnected: () => {
950
+ l = !1, x();
951
+ },
952
+ onError: (c) => {
953
+ const v = typeof c == "object" && c !== null && "data" in c ? String(c.data ?? c) : String(c);
954
+ console.error("[realtimeVoice]", v, c), e("error"), k();
955
+ },
956
+ onTransportStateChanged: (c) => {
957
+ c === "error" && (e("error"), k());
958
+ },
959
+ onServerMessage: (c) => {
960
+ V(c);
961
+ },
962
+ onUserStartedSpeaking: () => {
963
+ R.bargeIn(), T(), e("idle"), y("user_started"), k();
964
+ },
965
+ onBotStartedSpeaking: () => {
966
+ y("bot_started");
967
+ },
968
+ onBotStoppedSpeaking: () => {
969
+ R.markStreamComplete(n), y("bot_stopped");
970
+ },
971
+ onUserTranscript: (c) => {
972
+ m.onUserTranscript?.(c.text, !!c.final);
973
+ },
974
+ onBotOutput: (c) => {
975
+ m.onBotOutput?.(c.text);
976
+ }
977
+ }
978
+ }), w);
979
+ return {
980
+ setDeveloperToken: (c) => {
981
+ },
982
+ setTtsEngineId: (c) => {
983
+ f = c, R.setStreamTtsEngineId(c);
984
+ },
985
+ getTtsEngineId: () => f,
986
+ speak: async (c, v) => {
987
+ const O = c.trim();
988
+ if (O) {
989
+ if (!w || !l)
990
+ throw new Error(
991
+ "Realtime voice is not connected. Call connect() first."
992
+ );
993
+ g(), await w.sendText(O);
994
+ }
995
+ },
996
+ stop: () => {
997
+ g(), e("idle"), k();
998
+ },
999
+ connect: async (c) => {
1000
+ if (c && (m = { ...m, ...c }), !m.authToken?.trim())
1001
+ throw new Error(
1002
+ "Voice connect requires authToken (same JWT as SSE Authorization Bearer)."
1003
+ );
1004
+ e("loading");
1005
+ const v = U();
1006
+ await v.initDevices();
1007
+ const O = Tr(m);
1008
+ console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):", O);
1009
+ try {
1010
+ await v.connect({ wsUrl: O });
1011
+ } catch (z) {
1012
+ l = !1, e("error"), k();
1013
+ const ne = z instanceof Error ? z.message : "Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";
1014
+ throw new Error(`${ne} — ${O}`);
1015
+ }
1016
+ l = !0, e("idle"), k();
1017
+ },
1018
+ disconnect: async () => {
1019
+ if (p.length = 0, d = !1, w)
1020
+ try {
1021
+ await w.disconnect();
1022
+ } catch (c) {
1023
+ console.error("[realtimeVoice] disconnect failed:", c);
1024
+ }
1025
+ l = !1, x();
1026
+ },
1027
+ isConnected: () => l,
1028
+ unlockAudio: async () => {
1029
+ await R.primeAudioContext();
1030
+ },
1031
+ getVisemeQueue: () => n,
1032
+ getWordQueue: () => r,
615
1033
  getSentenceEmotions: () => s,
616
- getStreamMood: () => c,
617
- getPlaybackElapsedMs: () => m ? S && d && w > 0 ? Math.max(
618
- 0,
619
- (d.currentTime - w) * 1e3
620
- ) : Math.max(0, (performance.now() - F) * v) : 0,
621
- isSpeaking: () => m,
622
- setPlaybackSpeed: (p) => {
623
- v = Math.max(0.1, Math.min(1, p)), z();
1034
+ getStreamMood: () => a,
1035
+ getPlaybackElapsedMs: H,
1036
+ isSpeaking: () => R.isSpeaking(),
1037
+ setPlaybackSpeed: (c) => {
1038
+ R.setPlaybackSpeed(c);
624
1039
  },
625
- getPlaybackSpeed: () => v,
626
- subscribe: (p) => (L.add(p), () => L.delete(p))
1040
+ getPlaybackSpeed: () => R.getPlaybackSpeed(),
1041
+ subscribe: (c) => (u.add(c), () => u.delete(c))
627
1042
  };
628
1043
  }
629
- function $n(e, t, n) {
1044
+ function Rr(e, t, n) {
630
1045
  return {
631
1046
  width: e.crop?.source_width ?? t,
632
1047
  height: e.crop?.source_height ?? n
633
1048
  };
634
1049
  }
635
- function Hn(e, t) {
1050
+ function Dr(e, t) {
636
1051
  const n = e.crop;
637
1052
  return {
638
1053
  x: t?.source_x ?? n?.x ?? 0,
@@ -641,57 +1056,64 @@ function Hn(e, t) {
641
1056
  height: t?.source_h ?? n?.height ?? e.frame_height ?? 0
642
1057
  };
643
1058
  }
644
- function Wn(e) {
1059
+ function Mr(e) {
645
1060
  return e ? (e.w ?? 0) > 0 && (e.h ?? 0) > 0 : !1;
646
1061
  }
647
- async function Ve(e, t) {
1062
+ async function Ye(e, t) {
648
1063
  const n = await fetch(e);
649
1064
  if (!n.ok) throw new Error(`Failed to load encrypted asset: ${e}`);
650
1065
  const r = await n.arrayBuffer();
651
- return ln(r, t);
1066
+ return Gn(r, t);
652
1067
  }
653
- async function qn(e, t) {
1068
+ async function xr(e, t) {
654
1069
  if (!t) throw new Error("Missing asset key for encrypted JSON");
655
- const n = await Ve(e, t), r = new TextDecoder().decode(n);
1070
+ const n = await Ye(e, t), r = new TextDecoder().decode(n);
656
1071
  return JSON.parse(r);
657
1072
  }
658
- async function Kn(e) {
1073
+ async function Cr(e) {
659
1074
  const t = new Blob([e], { type: "image/webp" }), n = URL.createObjectURL(t);
660
- return new Promise((r, i) => {
661
- const s = new Image();
662
- s.decoding = "async", s.onload = () => {
663
- URL.revokeObjectURL(n), r(s);
664
- }, s.onerror = () => {
665
- URL.revokeObjectURL(n), i(new Error("Failed to decode decrypted image"));
666
- }, s.src = n;
1075
+ return new Promise((r, s) => {
1076
+ const i = new Image();
1077
+ i.decoding = "async", i.onload = () => {
1078
+ URL.revokeObjectURL(n), r(i);
1079
+ }, i.onerror = () => {
1080
+ URL.revokeObjectURL(n), s(new Error("Failed to decode decrypted image"));
1081
+ }, i.src = n;
667
1082
  });
668
1083
  }
669
- async function jn(e) {
1084
+ async function Pr(e) {
670
1085
  const t = new Blob([e], { type: "image/png" }), n = URL.createObjectURL(t);
671
- return new Promise((r, i) => {
672
- const s = new Image();
673
- s.decoding = "async", s.onload = () => {
674
- URL.revokeObjectURL(n), r(s);
675
- }, s.onerror = () => {
676
- URL.revokeObjectURL(n), i(new Error("Failed to decode decrypted PNG"));
677
- }, s.src = n;
1086
+ return new Promise((r, s) => {
1087
+ const i = new Image();
1088
+ i.decoding = "async", i.onload = () => {
1089
+ URL.revokeObjectURL(n), r(i);
1090
+ }, i.onerror = () => {
1091
+ URL.revokeObjectURL(n), s(new Error("Failed to decode decrypted PNG"));
1092
+ }, i.src = n;
678
1093
  });
679
1094
  }
680
- function Gn(e) {
1095
+ function Br(e) {
681
1096
  const t = new Blob([e], { type: "video/mp4" });
682
1097
  return URL.createObjectURL(t);
683
1098
  }
684
- async function zn(e) {
685
- const t = _n();
686
- if (!Be()) return t;
1099
+ async function Or(e) {
1100
+ const t = Xn();
1101
+ if (!Ge()) return t;
687
1102
  if (!e) throw new Error("Missing asset key for encrypted idle video");
688
- const n = await Ve(t, e);
689
- return Gn(n);
1103
+ const n = await Ye(t, e);
1104
+ return Br(n);
690
1105
  }
691
- function bt(e, t) {
1106
+ function dt(e, t) {
692
1107
  return `${e}/${t}_minus_sil.png`;
693
1108
  }
694
- const et = 15, Gr = [
1109
+ const sn = 5;
1110
+ function on(e) {
1111
+ const t = e?.composite_threshold;
1112
+ if (typeof t == "number" && t > 0) return t;
1113
+ const n = e?.crop?.content_threshold;
1114
+ return typeof n == "number" && n > 0 ? n : sn;
1115
+ }
1116
+ const Ws = [
695
1117
  "aa",
696
1118
  "E",
697
1119
  "I",
@@ -706,13 +1128,13 @@ const et = 15, Gr = [
706
1128
  "RR",
707
1129
  "kk",
708
1130
  "nn"
709
- ], ze = [
1131
+ ], it = [
710
1132
  "t01_0.17",
711
1133
  "t02_0.33",
712
1134
  "t03_0.50",
713
1135
  "t04_0.67",
714
1136
  "t05_0.83"
715
- ], Qn = ze.length, lt = /* @__PURE__ */ new Set([
1137
+ ], Fr = it.length, Ot = /* @__PURE__ */ new Set([
716
1138
  "aa__kk",
717
1139
  "aa__nn",
718
1140
  "aa__sil",
@@ -819,59 +1241,101 @@ const et = 15, Gr = [
819
1241
  "U__nn",
820
1242
  "U__sil"
821
1243
  ]);
822
- function ft(e, t) {
1244
+ function Ft(e, t) {
823
1245
  return `${e}__${t}`;
824
1246
  }
825
- function dt(e, t) {
1247
+ function Lt(e, t) {
826
1248
  return `pairs/${e}/${t}_minus_sil.png`;
827
1249
  }
828
- function Qe(e) {
1250
+ function Ke(e) {
829
1251
  return `${e}_minus_sil.png`;
830
1252
  }
831
- function Rt(e, t) {
1253
+ function Lr(e, t) {
1254
+ if (t.has(e)) return e;
1255
+ const n = /^pairs\/([^/]+)\//.exec(e);
1256
+ if (!n) return null;
1257
+ const r = n[1].split("__")[1];
1258
+ if (!r || r === "sil") return null;
1259
+ const s = Ke(r);
1260
+ return t.has(s) ? s : null;
1261
+ }
1262
+ function an(e, t) {
1263
+ return e.filter((n) => t.has(n));
1264
+ }
1265
+ function Ur(e, t, n) {
1266
+ const r = ht(e, t);
1267
+ return an(r, n).length > 0;
1268
+ }
1269
+ function ht(e, t) {
832
1270
  if (e === t) return [];
833
- const n = [], r = ft(e, t);
834
- if (lt.has(r)) {
835
- for (const s of ze)
836
- n.push(dt(r, s));
1271
+ const n = [], r = Ft(e, t);
1272
+ if (Ot.has(r)) {
1273
+ for (const i of it)
1274
+ n.push(Lt(r, i));
837
1275
  return n;
838
1276
  }
839
- const i = ft(t, e);
840
- if (lt.has(i)) {
841
- for (let s = Qn - 1; s >= 0; s--)
842
- n.push(dt(i, ze[s]));
1277
+ const s = Ft(t, e);
1278
+ if (Ot.has(s)) {
1279
+ for (let i = Fr - 1; i >= 0; i--)
1280
+ n.push(Lt(s, it[i]));
843
1281
  return n;
844
1282
  }
845
1283
  return [];
846
1284
  }
847
- function Jn(e) {
1285
+ function Nr(e) {
848
1286
  return e < 16 ? [] : e < 35 ? [2] : e < 51 ? [0, 4] : e < 67 ? [0, 2, 4] : e < 83 ? [0, 1, 2, 3] : [0, 1, 2, 3, 4];
849
1287
  }
850
- function Yn(e, t) {
851
- return Jn(t).map((r) => e[r]).filter((r) => r != null);
1288
+ function Vr(e, t) {
1289
+ return Nr(t).map((r) => e[r]).filter((r) => r != null);
852
1290
  }
853
- function Xn(e, t, n, r) {
1291
+ function $r(e, t, n, r) {
854
1292
  if (r <= 0) return 0;
855
- const s = Math.max(1, n - t) / r, c = e - t, a = Math.floor(c / s);
1293
+ const i = Math.max(1, n - t) / r, o = e - t, a = Math.floor(o / i);
856
1294
  return Math.min(r - 1, Math.max(0, a));
857
1295
  }
858
- function Zn(e, t, n) {
1296
+ function Hr(e, t, n) {
859
1297
  if (!n) return `${e}/${t}`;
860
- const r = t.split("/").pop() ?? t, i = r.includes(".") ? r.slice(0, r.lastIndexOf(".")) : r;
861
- return `${e}/${i}.bin`;
1298
+ const r = t.split("/").pop() ?? t, s = r.includes(".") ? r.slice(0, r.lastIndexOf(".")) : r;
1299
+ return `${e}/${s}.bin`;
862
1300
  }
863
- const er = [0.32, 0.24, 0.16, 0.08, 0], $e = er.map(
1301
+ const Wr = [0.32, 0.24, 0.16, 0.08, 0], qr = Wr.map(
864
1302
  (e) => `eyes_${e.toFixed(2)}`
865
- ), tr = [
1303
+ ), Kr = [
866
1304
  "eyes_0.32",
867
1305
  "eyes_0.16",
868
1306
  "eyes_0.00"
869
- ], nr = [
1307
+ ], jr = [
870
1308
  "eyes_0.32",
871
1309
  "eyes_0.16",
872
1310
  "eyes_0.08",
873
1311
  "eyes_0.00"
874
- ], rr = {
1312
+ ], Ut = 2, Gr = -30, ot = 20, zr = {
1313
+ fear: -30,
1314
+ anger: -20,
1315
+ sad: -10,
1316
+ neutral: 0,
1317
+ love: 10,
1318
+ happy: 0,
1319
+ disgust: 20
1320
+ };
1321
+ function mt(e) {
1322
+ return `brow_${e}`;
1323
+ }
1324
+ function wt(e) {
1325
+ return zr[e];
1326
+ }
1327
+ function ye(e) {
1328
+ return Math.max(Gr, Math.min(ot, e));
1329
+ }
1330
+ function Yr(e, t) {
1331
+ if (e === t) return [];
1332
+ const n = e < t ? Ut : -Ut, r = [];
1333
+ let s = e;
1334
+ for (; s !== t; )
1335
+ s += n, r.push(s);
1336
+ return r;
1337
+ }
1338
+ const Jr = {
875
1339
  fear: "fear",
876
1340
  afraid: "fear",
877
1341
  anxiety: "fear",
@@ -894,219 +1358,220 @@ const er = [0.32, 0.24, 0.16, 0.08, 0], $e = er.map(
894
1358
  disgust: "disgust",
895
1359
  disgusted: "disgust"
896
1360
  };
897
- function ye(e, t = "neutral") {
1361
+ function ve(e, t = "neutral") {
898
1362
  const n = String(e ?? "").trim().toLowerCase();
899
- return n ? rr[n] ?? t : t;
1363
+ return n ? Jr[n] ?? t : t;
900
1364
  }
901
- function ee(e) {
902
- return e === "neutral" ? null : bt(e, "eyes_standard");
903
- }
904
- function Je(e, t) {
905
- return !t || t === "eyes_standard" ? ee(e) : e === "neutral" && t === "eyes_standard" ? null : bt(e, t);
1365
+ function cn(e) {
1366
+ return e === 0 ? null : dt(mt(e), "eyes_standard");
906
1367
  }
907
- function ir(e) {
908
- if (!e) return "open";
909
- const t = e.match(/\/(eyes_[^/]+)_minus_sil\.png$/);
910
- if (!t?.[1]) return "open";
911
- const n = t[1];
912
- return $e.includes(n) ? n : "open";
1368
+ function un(e) {
1369
+ return cn(wt(e));
913
1370
  }
914
- function sr(e) {
915
- return e === "open" ? -1 : $e.indexOf(e);
1371
+ function Nt(e, t) {
1372
+ const n = mt(wt(e));
1373
+ return !t || t === "eyes_standard" ? un(e) : e === "neutral" && t === "eyes_standard" ? null : dt(n, t);
916
1374
  }
917
- function or(e, t) {
1375
+ function Qr(e, t) {
918
1376
  const n = [];
919
1377
  for (const r of t)
920
- n.push(Je(e, r));
1378
+ n.push(Nt(e, r));
921
1379
  for (let r = t.length - 2; r >= 0; r--)
922
- n.push(Je(e, t[r]));
923
- return n.push(ee(e)), n;
924
- }
925
- function ar(e, t) {
926
- if (t === "open") return [ee(e)];
927
- const n = sr(t);
928
- if (n < 0) return [ee(e)];
929
- const r = [];
930
- for (let i = n; i >= 0; i--)
931
- r.push(Je(e, $e[i]));
932
- return r.push(ee(e)), r;
933
- }
934
- const cr = [
935
- "t01_0.20",
936
- "t02_0.40",
937
- "t03_0.60",
938
- "t04_0.80"
939
- ];
940
- function ur(e, t) {
941
- return `${e}__${t}`;
1380
+ n.push(Nt(e, t[r]));
1381
+ return n.push(un(e)), n;
942
1382
  }
943
- function lr(e, t, n) {
944
- return `pairs/${ur(e, t)}/${n}_minus_sil.png`;
1383
+ function Xr(e) {
1384
+ return dt(mt(e), "eyes_standard");
945
1385
  }
946
- function fr(e, t) {
947
- return cr.map(
948
- (n) => lr(e, t, n)
949
- );
1386
+ function Zr(e, t) {
1387
+ return Yr(e, t).map(Xr);
1388
+ }
1389
+ const es = 6;
1390
+ function ts(e, t) {
1391
+ for (const n of e)
1392
+ if (t >= n.wtime && t < n.wtime + n.wduration)
1393
+ return n;
1394
+ return null;
1395
+ }
1396
+ function ns(e) {
1397
+ const t = ye(e);
1398
+ return t >= ot ? ot : ye(t + es);
950
1399
  }
951
- function ve(e, t) {
1400
+ function rs(e, t, n) {
1401
+ const r = ye(n);
1402
+ return ts(t, e)?.emphasis ? ns(r) : r;
1403
+ }
1404
+ function Vt(e) {
1405
+ if (!e) return 0;
1406
+ const t = e.match(/^brow_(-?\d+)\//);
1407
+ if (!t?.[1]) return null;
1408
+ const n = Number.parseInt(t[1], 10);
1409
+ return Number.isFinite(n) ? ye(n) : null;
1410
+ }
1411
+ function Fe(e, t) {
952
1412
  return e + Math.random() * (t - e);
953
1413
  }
954
- function Le() {
955
- return ve(14, 32);
1414
+ function We() {
1415
+ return Fe(14, 32);
956
1416
  }
957
- function dr(e = {}) {
1417
+ function ss(e = {}) {
958
1418
  const {
959
1419
  initialDelayMs: t = 800 + Math.random() * 1200,
960
1420
  intervalMinMs: n = 2200,
961
1421
  intervalMaxMs: r = 5800,
962
- doubleBlinkChance: i = 0.18,
963
- doubleBlinkGapMinMs: s = 120,
964
- doubleBlinkGapMaxMs: c = 220,
1422
+ doubleBlinkChance: s = 0.18,
1423
+ doubleBlinkGapMinMs: i = 120,
1424
+ doubleBlinkGapMaxMs: o = 220,
965
1425
  fullBlinkChance: a = 0.75,
966
- postEmotionChangeDelayMs: l = 380,
967
- minDwellMs: d = 550
1426
+ postEmotionChangeDelayMs: f = 380,
1427
+ minDwellMs: l = 550
968
1428
  } = e;
969
- let _ = "neutral", m = "neutral", S = 0, o = {
1429
+ let w = "neutral", _ = "neutral", m = 0, S = 0, E = 0, u = {
970
1430
  kind: "idle",
971
1431
  nextBlinkAt: performance.now() + t
972
- }, F = null, w = "__eyes_open__|neutral";
973
- function u(h, E) {
974
- F = h, w = `${h ?? "__eyes_open__"}|${E}`;
1432
+ }, p = null, d = "__eyes_open__|neutral|brow:0";
1433
+ function I(y = w) {
1434
+ d = `${p ?? "__eyes_open__"}|${y}|brow:${S}`;
1435
+ }
1436
+ function k(y, T = w) {
1437
+ p = y;
1438
+ const g = Vt(y);
1439
+ g != null ? S = g : y == null && (S = 0), I(T);
1440
+ }
1441
+ function R(y) {
1442
+ return cn(y);
1443
+ }
1444
+ function W(y, T, g) {
1445
+ const x = ye(T), b = ye(g);
1446
+ if (m = b, x === b) {
1447
+ k(R(b));
1448
+ return;
1449
+ }
1450
+ const D = [
1451
+ ...Zr(x, b),
1452
+ R(b)
1453
+ ];
1454
+ u = {
1455
+ kind: "browBlend",
1456
+ paths: D,
1457
+ index: 0,
1458
+ holdUntil: y + We(),
1459
+ targetBrow: b
1460
+ }, k(D[0] ?? null);
975
1461
  }
976
- function g(h, E) {
977
- o = {
1462
+ function V(y, T) {
1463
+ u = {
978
1464
  kind: "idle",
979
- nextBlinkAt: h + ve(n, r)
980
- }, m = E, u(ee(E), E);
1465
+ nextBlinkAt: y + Fe(n, r)
1466
+ }, _ = T, k(R(m), T);
981
1467
  }
982
- function y(h, E, D) {
983
- const L = D ? tr : Math.random() < a ? $e : nr;
984
- o = {
1468
+ function H(y, T, g) {
1469
+ const x = g ? Kr : Math.random() < a ? qr : jr;
1470
+ u = {
985
1471
  kind: "playing",
986
- paths: or(E, L),
1472
+ paths: Qr(T, x),
987
1473
  index: 0,
988
- holdUntil: h + Le(),
1474
+ holdUntil: y + We(),
989
1475
  after: "idle",
990
- blinkEmotion: E
991
- }, m = E, u(o.paths[0] ?? null, E);
992
- }
993
- function v(h, E, D) {
994
- const L = ir(F), z = [];
995
- if (L !== "open") {
996
- const U = ar(E, L);
997
- z.push(...U.slice(0, -1));
998
- }
999
- z.push(...fr(E, D)), z.push(ee(D)), o = {
1000
- kind: "emotionBlend",
1001
- paths: z,
1002
- index: 0,
1003
- holdUntil: h + Le(),
1004
- thenEmotion: D
1005
- }, u(z[0] ?? null, E);
1476
+ blinkEmotion: T
1477
+ }, _ = T, k(u.paths[0] ?? null, T);
1006
1478
  }
1007
- function H(h) {
1008
- if (o.kind === "emotionBlend") {
1009
- for (; h >= o.holdUntil && o.index < o.paths.length - 1; )
1010
- o.index += 1, o.holdUntil = h + Le();
1011
- const E = o.paths[o.index] ?? null;
1012
- u(E, o.thenEmotion), h >= o.holdUntil && o.index >= o.paths.length - 1 && (_ = o.thenEmotion, m = o.thenEmotion, u(ee(o.thenEmotion), o.thenEmotion), o = {
1479
+ function j(y) {
1480
+ if (u.kind === "browBlend") {
1481
+ for (; y >= u.holdUntil && u.index < u.paths.length - 1; )
1482
+ u.index += 1, u.holdUntil = y + We();
1483
+ const T = u.paths[u.index] ?? null;
1484
+ k(T), y >= u.holdUntil && u.index >= u.paths.length - 1 && (S = u.targetBrow, m = u.targetBrow, k(R(u.targetBrow)), u = {
1013
1485
  kind: "idle",
1014
- nextBlinkAt: h + l
1486
+ nextBlinkAt: y + f
1015
1487
  });
1016
1488
  return;
1017
1489
  }
1018
- if (o.kind === "idle") {
1019
- u(ee(m), m), h >= o.nextBlinkAt && y(h, m, !1);
1490
+ if (u.kind === "idle") {
1491
+ k(R(m), _), y >= u.nextBlinkAt && H(y, _, !1);
1020
1492
  return;
1021
1493
  }
1022
- if (o.kind === "doublePause") {
1023
- u(ee(o.blinkEmotion), o.blinkEmotion), h >= o.resumeAt && y(h, o.blinkEmotion, !0);
1494
+ if (u.kind === "doublePause") {
1495
+ k(R(m), u.blinkEmotion), y >= u.resumeAt && H(y, u.blinkEmotion, !0);
1024
1496
  return;
1025
1497
  }
1026
- if (o.kind === "playing") {
1027
- for (; h >= o.holdUntil && o.index < o.paths.length - 1; )
1028
- o.index += 1, o.holdUntil = h + Le();
1029
- if (u(o.paths[o.index] ?? null, o.blinkEmotion), h >= o.holdUntil && o.index >= o.paths.length - 1) {
1030
- if (o.after === "resumeIdle") {
1031
- g(h + l, _);
1498
+ if (u.kind === "playing") {
1499
+ for (; y >= u.holdUntil && u.index < u.paths.length - 1; )
1500
+ u.index += 1, u.holdUntil = y + We();
1501
+ if (k(u.paths[u.index] ?? null, u.blinkEmotion), y >= u.holdUntil && u.index >= u.paths.length - 1) {
1502
+ if (u.after === "resumeIdle") {
1503
+ V(y + f, w);
1032
1504
  return;
1033
1505
  }
1034
- if (o.after === "doublePause") {
1035
- o = {
1506
+ if (u.after === "doublePause") {
1507
+ u = {
1036
1508
  kind: "doublePause",
1037
- resumeAt: h + ve(s, c),
1038
- blinkEmotion: o.blinkEmotion
1039
- }, u(ee(o.blinkEmotion), o.blinkEmotion);
1509
+ resumeAt: y + Fe(i, o),
1510
+ blinkEmotion: u.blinkEmotion
1511
+ }, k(R(m), u.blinkEmotion);
1040
1512
  return;
1041
1513
  }
1042
- if (o.after === "idle" && Math.random() < i) {
1043
- o = {
1514
+ if (u.after === "idle" && Math.random() < s) {
1515
+ u = {
1044
1516
  kind: "doublePause",
1045
- resumeAt: h + ve(s, c),
1046
- blinkEmotion: o.blinkEmotion
1047
- }, u(ee(o.blinkEmotion), o.blinkEmotion);
1517
+ resumeAt: y + Fe(i, o),
1518
+ blinkEmotion: u.blinkEmotion
1519
+ }, k(R(m), u.blinkEmotion);
1048
1520
  return;
1049
1521
  }
1050
- g(h, o.blinkEmotion);
1522
+ V(y, u.blinkEmotion);
1051
1523
  }
1052
1524
  }
1053
1525
  }
1054
1526
  return {
1055
- advance: H,
1056
- setTargetEmotion(h) {
1057
- const E = ye(h, _);
1058
- if (E === _ && o.kind !== "emotionBlend") return;
1059
- const D = performance.now();
1060
- if (d > 0 && E !== _ && o.kind !== "emotionBlend" && !(_ === "neutral" && E !== "neutral") && D - S < d)
1061
- return;
1062
- const L = _;
1063
- if (_ = E, S = D, o.kind === "playing") {
1064
- v(D, m, E);
1065
- return;
1066
- }
1067
- if (o.kind === "emotionBlend") {
1068
- o = {
1069
- ...o,
1070
- thenEmotion: E
1071
- };
1072
- return;
1073
- }
1074
- v(D, L, E);
1527
+ advance: j,
1528
+ setTargetEmotion(y) {
1529
+ const T = ve(y, w);
1530
+ if (T === w) return;
1531
+ const g = performance.now();
1532
+ l > 0 && T !== w && !(w === "neutral" && T !== "neutral") && g - E < l || (w = T, _ = T, E = g);
1533
+ },
1534
+ setTargetEyebrow(y) {
1535
+ const T = ye(y);
1536
+ if (T === m && u.kind !== "browBlend") return;
1537
+ const g = performance.now(), x = u.kind === "browBlend" ? Vt(p) ?? S : S;
1538
+ m = T, !(T === x && u.kind !== "browBlend") && (u.kind === "playing" || u.kind === "doublePause" || W(g, x, T));
1075
1539
  },
1076
- getTargetEmotion: () => _,
1077
- getExpressionPath: () => F,
1078
- getDrawKey: () => w,
1540
+ getTargetEmotion: () => w,
1541
+ getTargetEyebrow: () => m,
1542
+ getExpressionPath: () => p,
1543
+ getDrawKey: () => d,
1079
1544
  reset() {
1080
- _ = "neutral", m = "neutral", S = 0, g(
1081
- performance.now() + ve(n, r),
1545
+ w = "neutral", _ = "neutral", m = 0, S = 0, E = 0, V(
1546
+ performance.now() + Fe(n, r),
1082
1547
  "neutral"
1083
1548
  );
1084
1549
  }
1085
1550
  };
1086
1551
  }
1087
- function hr() {
1552
+ function is() {
1088
1553
  const e = document.createElement("video");
1089
1554
  e.muted = !0, e.playsInline = !0, e.preload = "auto", e.setAttribute("playsinline", ""), e.loop = !0;
1090
1555
  let t = !1, n = null, r = "";
1091
- const i = () => {
1556
+ const s = () => {
1092
1557
  n && (URL.revokeObjectURL(n), n = null);
1093
1558
  };
1094
1559
  return {
1095
- async load(s) {
1096
- t && r === s || (i(), t = !1, r = s, s.startsWith("blob:") && (n = s), await new Promise((c, a) => {
1097
- const l = () => {
1098
- const d = e.duration;
1099
- if (!Number.isFinite(d) || d <= 0) {
1100
- a(new Error(`Idle video has invalid duration: ${s}`));
1560
+ async load(i) {
1561
+ t && r === i || (s(), t = !1, r = i, i.startsWith("blob:") && (n = i), await new Promise((o, a) => {
1562
+ const f = () => {
1563
+ const l = e.duration;
1564
+ if (!Number.isFinite(l) || l <= 0) {
1565
+ a(new Error(`Idle video has invalid duration: ${i}`));
1101
1566
  return;
1102
1567
  }
1103
- t = !0, e.currentTime = 0, c();
1568
+ t = !0, e.currentTime = 0, o();
1104
1569
  };
1105
- e.addEventListener("loadeddata", l, { once: !0 }), e.addEventListener(
1570
+ e.addEventListener("loadeddata", f, { once: !0 }), e.addEventListener(
1106
1571
  "error",
1107
- () => a(new Error(`Failed to load idle video: ${s}`)),
1572
+ () => a(new Error(`Failed to load idle video: ${i}`)),
1108
1573
  { once: !0 }
1109
- ), e.src = s, e.load();
1574
+ ), e.src = i, e.load();
1110
1575
  }));
1111
1576
  },
1112
1577
  isReady() {
@@ -1115,136 +1580,139 @@ function hr() {
1115
1580
  getVideo() {
1116
1581
  return e;
1117
1582
  },
1118
- setActive(s) {
1119
- t && (s ? e.paused && e.play().catch(() => {
1583
+ setActive(i) {
1584
+ t && (i ? e.paused && e.play().catch(() => {
1120
1585
  }) : e.paused || e.pause());
1121
1586
  },
1122
1587
  restart() {
1123
1588
  t && (e.currentTime = 0);
1124
1589
  },
1125
1590
  dispose() {
1126
- e.pause(), e.removeAttribute("src"), e.load(), i(), t = !1, r = "";
1591
+ e.pause(), e.removeAttribute("src"), e.load(), s(), t = !1, r = "";
1127
1592
  }
1128
1593
  };
1129
1594
  }
1130
- const mr = 50, Dt = 400;
1131
- function _r(e, t, n) {
1595
+ const os = 50, ln = 400;
1596
+ function as(e, t, n) {
1132
1597
  return e.filter((r) => {
1133
- const i = r.queueIndex ?? -1;
1134
- return i >= t && i <= n;
1598
+ const s = r.queueIndex ?? -1;
1599
+ return s >= t && s <= n;
1135
1600
  });
1136
1601
  }
1137
- function wr(e, t) {
1602
+ function cs(e, t) {
1138
1603
  const n = [];
1139
1604
  for (const r of e) {
1140
- const i = _r(
1605
+ const s = as(
1141
1606
  t,
1142
1607
  r.start_word,
1143
1608
  r.end_word
1144
1609
  );
1145
- if (i.length === 0) continue;
1146
- const s = i[0], c = i[i.length - 1];
1610
+ if (s.length === 0) continue;
1611
+ const i = s[0], o = s[s.length - 1];
1147
1612
  n.push({
1148
1613
  sentence: r,
1149
- startMs: Math.max(0, s.wtime - mr),
1150
- endMs: c.wtime + c.wduration + Dt
1614
+ startMs: Math.max(0, i.wtime - os),
1615
+ endMs: o.wtime + o.wduration + ln
1151
1616
  });
1152
1617
  }
1153
- return n.sort((r, i) => r.startMs - i.startMs);
1618
+ return n.sort((r, s) => r.startMs - s.startMs);
1154
1619
  }
1155
- function gr(e, t, n, r = "neutral") {
1156
- const i = ye(r);
1157
- if (t.length === 0) return i;
1620
+ function us(e, t, n, r = "neutral") {
1621
+ const s = ve(r);
1622
+ if (t.length === 0) return s;
1158
1623
  if (n.length === 0 || e < n[0].wtime)
1159
- return ye(t[0]?.emotion, i);
1160
- const s = wr(t, n);
1161
- let c = null;
1162
- for (const d of s)
1163
- e >= d.startMs && e <= d.endMs && (c = d);
1164
- if (c)
1165
- return ye(c.sentence.emotion, i);
1166
- const a = n[n.length - 1], l = a.wtime + a.wduration;
1167
- return e > l + Dt ? ye(
1624
+ return ve(t[0]?.emotion, s);
1625
+ const i = cs(t, n);
1626
+ let o = null;
1627
+ for (const l of i)
1628
+ e >= l.startMs && e <= l.endMs && (o = l);
1629
+ if (o)
1630
+ return ve(o.sentence.emotion, s);
1631
+ const a = n[n.length - 1], f = a.wtime + a.wduration;
1632
+ return e > f + ln ? ve(
1168
1633
  t[t.length - 1]?.emotion,
1169
- i
1170
- ) : i;
1171
- }
1172
- function xt(e, t, n, r, i = et) {
1173
- const s = new OffscreenCanvas(n, r), c = s.getContext("2d", { willReadFrequently: !0 });
1174
- c.drawImage(e, 0, 0, n, r);
1175
- const a = c.getImageData(0, 0, n, r), l = c.createImageData(n, r);
1176
- l.data.set(a.data);
1177
- const _ = new OffscreenCanvas(n, r).getContext("2d", { willReadFrequently: !0 });
1178
- for (const m of t) {
1179
- _.clearRect(0, 0, n, r), _.drawImage(m, 0, 0, n, r);
1180
- const S = _.getImageData(0, 0, n, r);
1181
- for (let o = 0; o < l.data.length; o += 4) {
1182
- const F = S.data[o], w = S.data[o + 1], u = S.data[o + 2];
1183
- Math.max(F, w, u) > i && (l.data[o] = F, l.data[o + 1] = w, l.data[o + 2] = u, l.data[o + 3] = 255);
1634
+ s
1635
+ ) : s;
1636
+ }
1637
+ function fn(e, t, n, r, s = sn) {
1638
+ const i = new OffscreenCanvas(n, r), o = i.getContext("2d", { willReadFrequently: !0 });
1639
+ o.drawImage(e, 0, 0, n, r);
1640
+ const a = o.getImageData(0, 0, n, r), f = o.createImageData(n, r);
1641
+ f.data.set(a.data);
1642
+ const w = new OffscreenCanvas(n, r).getContext("2d", { willReadFrequently: !0 });
1643
+ for (const _ of t) {
1644
+ w.clearRect(0, 0, n, r), w.drawImage(_, 0, 0, n, r);
1645
+ const m = w.getImageData(0, 0, n, r);
1646
+ for (let S = 0; S < f.data.length; S += 4) {
1647
+ const E = m.data[S], u = m.data[S + 1], p = m.data[S + 2];
1648
+ Math.max(E, u, p) > s && (f.data[S] = E, f.data[S + 1] = u, f.data[S + 2] = p, f.data[S + 3] = 255);
1184
1649
  }
1185
1650
  }
1186
- return c.putImageData(l, 0, 0), s;
1651
+ return o.putImageData(f, 0, 0), i;
1187
1652
  }
1188
- let de = null, Ie = null;
1189
- const Ue = /* @__PURE__ */ new Map();
1190
- function yr() {
1191
- de = null, Ie = null, Ue.clear();
1653
+ let pe = null, Le = null;
1654
+ const je = /* @__PURE__ */ new Map();
1655
+ function ls() {
1656
+ pe = null, Le = null, je.clear();
1192
1657
  }
1193
- mn(yr);
1194
- function pr(e) {
1195
- return e ?? Ie ?? void 0;
1658
+ Qn(ls);
1659
+ function fs(e) {
1660
+ return e ?? Le ?? void 0;
1196
1661
  }
1197
- function tt(e) {
1662
+ function gt(e) {
1198
1663
  return new Promise((t, n) => {
1199
1664
  const r = new Image();
1200
1665
  r.decoding = "async", r.onload = () => t(r), r.onerror = () => n(new Error(`Failed to load image: ${e}`)), r.src = e;
1201
1666
  });
1202
1667
  }
1203
- async function Er(e) {
1204
- return Be() ? jn(
1205
- await Ve(at(), e ?? "")
1206
- ) : tt(at());
1207
- }
1208
- async function ht(e, t, n, r) {
1209
- const i = n ? await qn(e, r) : await fetch(e).then((d) => {
1210
- if (!d.ok) throw new Error(`Failed to load ${e}`);
1211
- return d.json();
1212
- }), s = i.sheets?.[0];
1213
- if (!s?.path) throw new Error(`${e} has no sheets[0].path`);
1214
- const c = n ? await Kn(
1215
- await Ve(
1216
- Zn(t, s.path, n),
1668
+ async function ds(e) {
1669
+ return Ge() ? Pr(
1670
+ await Ye(Mt(), e ?? "")
1671
+ ) : gt(Mt());
1672
+ }
1673
+ async function $t(e, t, n, r) {
1674
+ const s = n ? await xr(e, r) : await fetch(e).then((l) => {
1675
+ if (!l.ok) throw new Error(`Failed to load ${e}`);
1676
+ return l.json();
1677
+ }), i = s.sheets?.[0];
1678
+ if (!i?.path) throw new Error(`${e} has no sheets[0].path`);
1679
+ const o = n ? await Cr(
1680
+ await Ye(
1681
+ Hr(t, i.path, n),
1217
1682
  r ?? ""
1218
1683
  )
1219
- ) : await tt(`${t}/${s.path}`), a = /* @__PURE__ */ new Map();
1220
- for (const d of i.cells ?? [])
1221
- d.path && a.set(d.path, d);
1222
- const l = /* @__PURE__ */ new Map();
1223
- for (const d of i.sheets ?? [])
1224
- l.set(d.index, d);
1225
- return { atlas: c, atlasMeta: i, cellByPath: a, sheetByIndex: l, diffBase: t };
1226
- }
1227
- async function Ye(e) {
1228
- const t = pr(e), n = Be();
1684
+ ) : await gt(`${t}/${i.path}`), a = /* @__PURE__ */ new Map();
1685
+ for (const l of s.cells ?? [])
1686
+ l.path && a.set(l.path, l);
1687
+ const f = /* @__PURE__ */ new Map();
1688
+ for (const l of s.sheets ?? [])
1689
+ f.set(l.index, l);
1690
+ return { atlas: o, atlasMeta: s, cellByPath: a, sheetByIndex: f, diffBase: t };
1691
+ }
1692
+ async function at(e) {
1693
+ const t = fs(e), n = Ge();
1229
1694
  if (n && !t)
1230
1695
  throw new Error("Encrypted assets enabled but no key provided");
1231
- if (de && (!n || Ie === (t ?? null))) {
1232
- const s = await de;
1233
- return Ae(s);
1696
+ if (pe && (!n || Le === (t ?? null))) {
1697
+ const i = await pe;
1698
+ return {
1699
+ ...Ue(i),
1700
+ visemePaths: [...i.viseme.cellByPath.keys()]
1701
+ };
1234
1702
  }
1235
- Ie = t ?? null, Ue.clear();
1236
- const r = wn();
1237
- de = (async () => {
1238
- const s = await Er(t), c = await ht(
1239
- gn(),
1703
+ Le = t ?? null, je.clear();
1704
+ const r = Zn();
1705
+ pe = (async () => {
1706
+ const i = await ds(t), o = await $t(
1707
+ er(),
1240
1708
  r,
1241
1709
  n,
1242
1710
  t
1243
1711
  );
1244
1712
  let a = null;
1245
1713
  try {
1246
- a = await ht(
1247
- yn(),
1714
+ a = await $t(
1715
+ tr(),
1248
1716
  r,
1249
1717
  n,
1250
1718
  t
@@ -1252,212 +1720,224 @@ async function Ye(e) {
1252
1720
  } catch {
1253
1721
  a = null;
1254
1722
  }
1255
- return { sil: s, viseme: c, expression: a };
1723
+ return { sil: i, viseme: o, expression: a };
1256
1724
  })();
1257
- const i = await de;
1258
- return Ae(i);
1725
+ const s = await pe;
1726
+ return { ...Ue(s), visemePaths: [...s.viseme.cellByPath.keys()] };
1259
1727
  }
1260
- async function Mt(e) {
1261
- if (await Ye(e), !de) throw new Error("Assets not loaded");
1262
- return de;
1728
+ async function dn(e) {
1729
+ if (await at(e), !pe) throw new Error("Assets not loaded");
1730
+ return pe;
1263
1731
  }
1264
- function Ae(e) {
1265
- return $n(
1732
+ function Ue(e) {
1733
+ return Rr(
1266
1734
  e.viseme.atlasMeta,
1267
1735
  e.sil.naturalWidth,
1268
1736
  e.sil.naturalHeight
1269
1737
  );
1270
1738
  }
1271
- function Sr(e, t) {
1739
+ function hs(e, t) {
1272
1740
  const n = document.createElement("canvas");
1273
1741
  return n.width = t.w, n.height = t.h, n.getContext("2d", { willReadFrequently: !0 }).drawImage(e.atlas, t.x, t.y, t.w, t.h, 0, 0, t.w, t.h), n;
1274
1742
  }
1275
- async function mt(e, t, n) {
1276
- const r = `${t.diffBase}::${n}`, i = Ue.get(r);
1277
- if (i) return i;
1278
- const s = (async () => {
1279
- const c = t.cellByPath.get(n);
1280
- if (!c) throw new Error(`No atlas cell for path: ${n}`);
1281
- const a = Hn(t.atlasMeta, c), l = Ae(e);
1282
- if (Wn(c)) {
1283
- const m = Sr(t, c), S = document.createElement("canvas");
1284
- S.width = l.width, S.height = l.height;
1285
- const o = S.getContext("2d");
1286
- return o.fillStyle = "#000", o.fillRect(0, 0, l.width, l.height), o.drawImage(m, a.x, a.y), S;
1743
+ async function Ht(e, t, n) {
1744
+ const r = `${t.diffBase}::${n}`, s = je.get(r);
1745
+ if (s) return s;
1746
+ const i = (async () => {
1747
+ const o = t.cellByPath.get(n);
1748
+ if (!o) throw new Error(`No atlas cell for path: ${n}`);
1749
+ const a = Dr(t.atlasMeta, o), f = Ue(e);
1750
+ if (Mr(o)) {
1751
+ const _ = hs(t, o), m = document.createElement("canvas");
1752
+ m.width = f.width, m.height = f.height;
1753
+ const S = m.getContext("2d");
1754
+ return S.fillStyle = "#000", S.fillRect(0, 0, f.width, f.height), S.drawImage(_, a.x, a.y), m;
1287
1755
  }
1288
- const d = `${t.diffBase}/${n}`, _ = await tt(d);
1289
- if (_.naturalWidth === l.width && _.naturalHeight === l.height)
1290
- return _;
1756
+ const l = `${t.diffBase}/${n}`, w = await gt(l);
1757
+ if (w.naturalWidth === f.width && w.naturalHeight === f.height)
1758
+ return w;
1291
1759
  throw new Error(`Diff PNG wrong size for ${n}`);
1292
1760
  })();
1293
- return Ue.set(r, s), s;
1761
+ return je.set(r, i), i;
1294
1762
  }
1295
- async function _t(e, t, n, r = et, i, s) {
1296
- if (i) {
1297
- const { width: S, height: o } = i;
1298
- if (s && !s() || t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA)
1763
+ async function Wt(e, t, n, r, s, i) {
1764
+ if (s) {
1765
+ const { width: S, height: E } = s;
1766
+ if (i && !i() || t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA)
1299
1767
  return;
1300
- const F = document.createElement("canvas");
1301
- F.width = S, F.height = o;
1302
- const w = F.getContext("2d");
1303
- if (w.clearRect(0, 0, S, o), w.drawImage(t, 0, 0, S, o), s && !s()) return;
1304
- (e.width !== S || e.height !== o) && (e.width = S, e.height = o);
1305
- const u = e.getContext("2d");
1306
- u.clearRect(0, 0, S, o), u.drawImage(F, 0, 0);
1768
+ const u = document.createElement("canvas");
1769
+ u.width = S, u.height = E;
1770
+ const p = u.getContext("2d");
1771
+ if (p.clearRect(0, 0, S, E), p.drawImage(t, 0, 0, S, E), i && !i()) return;
1772
+ (e.width !== S || e.height !== E) && (e.width = S, e.height = E);
1773
+ const d = e.getContext("2d");
1774
+ d.clearRect(0, 0, S, E), d.drawImage(u, 0, 0);
1307
1775
  return;
1308
1776
  }
1309
- const c = await Mt(), { width: a, height: l } = Ae(c);
1310
- (e.width !== a || e.height !== l) && (e.width = a, e.height = l);
1311
- const d = [], _ = e.getContext("2d");
1312
- if (_.clearRect(0, 0, a, l), t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) {
1313
- const S = c.sil;
1314
- _.drawImage(S, 0, 0, a, l);
1777
+ const o = await dn(), a = on(o.viseme.atlasMeta), { width: f, height: l } = Ue(o);
1778
+ (e.width !== f || e.height !== l) && (e.width = f, e.height = l);
1779
+ const w = [], _ = e.getContext("2d");
1780
+ if (_.clearRect(0, 0, f, l), t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) {
1781
+ const S = o.sil;
1782
+ _.drawImage(S, 0, 0, f, l);
1315
1783
  return;
1316
1784
  }
1317
- if (d.length === 0) {
1318
- _.drawImage(t, 0, 0, a, l);
1785
+ if (w.length === 0) {
1786
+ _.drawImage(t, 0, 0, f, l);
1319
1787
  return;
1320
1788
  }
1321
- const m = xt(t, d, a, l, r);
1789
+ const m = fn(t, w, f, l, a);
1322
1790
  _.drawImage(m, 0, 0);
1323
1791
  }
1324
- async function Xe(e, t, n = et) {
1325
- const r = await Mt(Ie ?? void 0), { width: i, height: s } = Ae(r);
1326
- (e.width !== i || e.height !== s) && (e.width = i, e.height = s);
1327
- const c = [];
1328
- t.mouthPath && c.push(await mt(r, r.viseme, t.mouthPath)), t.expressionPath && r.expression && c.push(
1329
- await mt(r, r.expression, t.expressionPath)
1792
+ async function ct(e, t, n) {
1793
+ const r = await dn(Le ?? void 0), s = on(r.viseme.atlasMeta), { width: i, height: o } = Ue(r);
1794
+ (e.width !== i || e.height !== o) && (e.width = i, e.height = o);
1795
+ const a = [];
1796
+ if (t.mouthPath) {
1797
+ const w = new Set(r.viseme.cellByPath.keys()), _ = Lr(t.mouthPath, w) ?? (w.has(t.mouthPath) ? t.mouthPath : null);
1798
+ _ && a.push(await Ht(r, r.viseme, _));
1799
+ }
1800
+ t.expressionPath && r.expression && a.push(
1801
+ await Ht(r, r.expression, t.expressionPath)
1330
1802
  );
1331
- const a = e.getContext("2d");
1332
- if (a.clearRect(0, 0, i, s), c.length === 0) {
1333
- a.drawImage(r.sil, 0, 0, i, s);
1803
+ const f = e.getContext("2d");
1804
+ if (f.clearRect(0, 0, i, o), a.length === 0) {
1805
+ f.drawImage(r.sil, 0, 0, i, o);
1334
1806
  return;
1335
1807
  }
1336
- const l = xt(
1808
+ const l = fn(
1337
1809
  r.sil,
1338
- c,
1810
+ a,
1339
1811
  i,
1340
- s,
1341
- n
1812
+ o,
1813
+ s
1342
1814
  );
1343
- a.drawImage(l, 0, 0);
1815
+ f.drawImage(l, 0, 0);
1344
1816
  }
1345
- async function kr(e) {
1346
- await Xe(e, { mouthPath: null, expressionPath: null });
1817
+ async function ms(e) {
1818
+ await ct(e, { mouthPath: null, expressionPath: null });
1347
1819
  }
1348
- function Tr(e) {
1820
+ function ws(e) {
1349
1821
  const t = /* @__PURE__ */ new Map();
1350
1822
  for (const n of e)
1351
1823
  t.has(n.vtime) || t.set(n.vtime, n);
1352
1824
  return [...t.values()].sort((n, r) => n.vtime - r.vtime);
1353
1825
  }
1354
- function vr(e) {
1355
- const t = Tr(e), n = [];
1826
+ function gs(e) {
1827
+ const t = ws(e), n = [];
1356
1828
  for (let r = 0; r < t.length - 1; r++) {
1357
- const i = t[r].viseme, s = t[r + 1].viseme, c = t[r].vtime, a = t[r + 1].vtime;
1358
- i === s || a <= c || n.push({ from: i, to: s, fromVtime: c, toVtime: a });
1829
+ const s = t[r].viseme, i = t[r + 1].viseme, o = t[r].vtime, a = t[r + 1].vtime;
1830
+ s === i || a <= o || n.push({ from: s, to: i, fromVtime: o, toVtime: a });
1359
1831
  }
1360
1832
  return n;
1361
1833
  }
1362
- function Ir(e, t) {
1834
+ function _s(e, t) {
1363
1835
  let n = null;
1364
1836
  for (const r of e)
1365
1837
  t >= r.fromVtime && t < r.toVtime && (n = r);
1366
1838
  return n;
1367
1839
  }
1368
- function Ar(e, t) {
1840
+ function ps(e, t) {
1369
1841
  return { gapMs: Math.max(0, t - e), holdEnd: e, transStart: e };
1370
1842
  }
1371
- const Ct = 400, br = 200, Rr = 600, Dr = "__sil__";
1372
- function xr() {
1843
+ const hn = 400, ys = 200, ks = 600, Es = "__sil__";
1844
+ function Ss() {
1373
1845
  return { lastDrawnKey: "" };
1374
1846
  }
1375
- function ge(e) {
1376
- e.lastDrawnKey = "";
1847
+ function me(e) {
1848
+ e.lastDrawnKey = "", e.transitionCache = void 0;
1377
1849
  }
1378
- function Mr(e) {
1850
+ function vs(e, t) {
1851
+ if (t?.transitionCache && t.transitionCache.queueLength === e.length)
1852
+ return t.transitionCache.transitions;
1853
+ const n = gs(e);
1854
+ return t && (t.transitionCache = { queueLength: e.length, transitions: n }), n;
1855
+ }
1856
+ function bs(e) {
1379
1857
  let t = "sil";
1380
1858
  for (const n of e)
1381
1859
  n.viseme !== "sil" && (t = n.viseme);
1382
1860
  return t;
1383
1861
  }
1384
- function Cr(e) {
1385
- return e === "sil" ? !1 : Rt(e, "sil").length > 0;
1862
+ function Ts(e, t) {
1863
+ return e === "sil" ? !1 : t ? Ur(e, "sil", t) : ht(e, "sil").length > 0;
1386
1864
  }
1387
- function Fr() {
1388
- return Ct + Rr;
1865
+ function As() {
1866
+ return hn + ks;
1389
1867
  }
1390
- function wt(e) {
1391
- return e ?? Dr;
1868
+ function qt(e) {
1869
+ return e ?? Es;
1392
1870
  }
1393
- function Lr(e, t) {
1871
+ function Is(e, t, n, r) {
1394
1872
  if (e.length === 0)
1395
1873
  return { diffPath: null, label: "sil" };
1396
- const n = vr(e), r = Ir(n, t);
1397
- if (r) {
1398
- const s = r.toVtime - r.fromVtime, c = Ar(r.fromVtime, r.toVtime);
1399
- if (t >= c.transStart && t < r.toVtime) {
1400
- const a = Rt(r.from, r.to), l = Yn(a, s);
1401
- if (l.length > 0) {
1402
- const d = Xn(
1874
+ const s = vs(e, r), i = _s(s, t);
1875
+ if (i) {
1876
+ const a = i.toVtime - i.fromVtime, f = ps(i.fromVtime, i.toVtime);
1877
+ if (t >= f.transStart && t < i.toVtime) {
1878
+ let l = ht(i.from, i.to);
1879
+ n && (l = an(l, n));
1880
+ const w = Vr(l, a);
1881
+ if (w.length > 0) {
1882
+ const _ = $r(
1403
1883
  t,
1404
- c.transStart,
1405
- r.toVtime,
1406
- l.length
1884
+ f.transStart,
1885
+ i.toVtime,
1886
+ w.length
1407
1887
  );
1408
- return { diffPath: l[d] ?? l[l.length - 1], label: `${r.from}→${r.to}` };
1888
+ return { diffPath: w[_] ?? w[w.length - 1], label: `${i.from}→${i.to}` };
1409
1889
  }
1410
- return { diffPath: Qe(r.to), label: r.to };
1890
+ return { diffPath: Ke(i.to), label: i.to };
1411
1891
  }
1412
1892
  }
1413
- const i = vt(e, t);
1414
- return i === "sil" ? { diffPath: null, label: "sil" } : { diffPath: Qe(i), label: i };
1893
+ const o = lt(e, t);
1894
+ return o === "sil" ? { diffPath: null, label: "sil" } : { diffPath: Ke(o), label: o };
1415
1895
  }
1416
- function Ft(e, t) {
1417
- const n = t ?? wt(e.expressionPath);
1418
- return `${wt(e.mouthPath)}|${n}`;
1896
+ function mn(e, t) {
1897
+ const n = t ?? qt(e.expressionPath);
1898
+ return `${qt(e.mouthPath)}|${n}`;
1419
1899
  }
1420
- function Or(e, t, n, r, i, s, c, a) {
1421
- const l = Lr(t, n), d = {
1422
- mouthPath: l.diffPath,
1900
+ function Rs(e, t, n, r, s, i, o, a, f, l) {
1901
+ const w = Is(t, n, f, i), _ = {
1902
+ mouthPath: w.diffPath,
1423
1903
  expressionPath: r
1424
- }, _ = Ft(d, i);
1425
- _ !== s.lastDrawnKey && (a(l.label), c(e, d, _, (m) => {
1426
- m === _ && (s.lastDrawnKey = _);
1904
+ }, m = mn(_, s);
1905
+ m !== i.lastDrawnKey && (a(w.label), o(e, _, m, (S) => {
1906
+ S === m && (i.lastDrawnKey = m);
1427
1907
  }));
1428
1908
  }
1429
- function gt(e, t, n, r, i, s, c = null) {
1430
- const a = { mouthPath: null, expressionPath: t }, l = c != null ? `|idle@${Math.round(c * 1e3)}` : "", d = Ft(a, n) + l;
1431
- !(c != null) && d === r.lastDrawnKey || (s(
1432
- c != null ? "idle" : "sil"
1433
- ), i(e, a, d, (m) => {
1434
- m === d && (r.lastDrawnKey = d);
1909
+ function Kt(e, t, n, r, s, i, o = null) {
1910
+ const a = { mouthPath: null, expressionPath: t }, f = o != null ? `|idle@${Math.round(o * 1e3)}` : "", l = mn(a, n) + f;
1911
+ !(o != null) && l === r.lastDrawnKey || (i(
1912
+ o != null ? "idle" : "sil"
1913
+ ), s(e, a, l, (_) => {
1914
+ _ === l && (r.lastDrawnKey = l);
1435
1915
  }));
1436
1916
  }
1437
- function Lt(e) {
1438
- let t = 0, n = null, r = !1, i = !1;
1439
- const s = async () => {
1917
+ function wn(e) {
1918
+ let t = 0, n = null, r = !1, s = !1;
1919
+ const i = async () => {
1440
1920
  if (!r) {
1441
1921
  r = !0;
1442
1922
  try {
1443
1923
  for (; n; ) {
1444
1924
  const a = n;
1445
1925
  n = null;
1446
- const l = ++t, d = await e(a.diffs, l, a);
1447
- n || d && l === t && a.onDisplayed?.(a.drawKey);
1926
+ const f = ++t, l = await e(a.diffs, f, a);
1927
+ n || l && f === t && a.onDisplayed?.(a.drawKey);
1448
1928
  }
1449
1929
  } finally {
1450
- r = !1, n && s();
1930
+ r = !1, n && i();
1451
1931
  }
1452
1932
  }
1453
- }, c = () => {
1454
- i || (i = !0, queueMicrotask(() => {
1455
- i = !1, s();
1933
+ }, o = () => {
1934
+ s || (s = !0, queueMicrotask(() => {
1935
+ s = !1, i();
1456
1936
  }));
1457
1937
  };
1458
1938
  return {
1459
- enqueue(a, l, d) {
1460
- n = { diffs: a, drawKey: l, onDisplayed: d }, c();
1939
+ enqueue(a, f, l) {
1940
+ n = { diffs: a, drawKey: f, onDisplayed: l }, o();
1461
1941
  },
1462
1942
  reset() {
1463
1943
  t += 1, n = null;
@@ -1470,9 +1950,9 @@ function Lt(e) {
1470
1950
  }
1471
1951
  };
1472
1952
  }
1473
- const yt = -1, pt = /* @__PURE__ */ new Map();
1474
- async function Pr(e) {
1475
- let t = pt.get(e);
1953
+ const jt = -1, Gt = /* @__PURE__ */ new Map();
1954
+ async function Ds(e) {
1955
+ let t = Gt.get(e);
1476
1956
  if (!t) {
1477
1957
  const n = await fetch(e);
1478
1958
  if (!n.ok)
@@ -1480,239 +1960,246 @@ async function Pr(e) {
1480
1960
  `Failed to fetch worker script (${n.status}): ${e}`
1481
1961
  );
1482
1962
  const r = await n.blob();
1483
- t = URL.createObjectURL(r), pt.set(e, t);
1963
+ t = URL.createObjectURL(r), Gt.set(e, t);
1484
1964
  }
1485
1965
  return new Worker(t, { name: "visemeDiffPreview" });
1486
1966
  }
1487
- function Ur() {
1967
+ function Ms() {
1488
1968
  return typeof Worker < "u" && typeof OffscreenCanvas < "u";
1489
1969
  }
1490
- function Br(e, t) {
1970
+ function xs(e, t) {
1491
1971
  (e.width !== t.width || e.height !== t.height) && (e.width = t.width, e.height = t.height);
1492
1972
  const n = e.getContext("2d");
1493
1973
  n && n.drawImage(t, 0, 0);
1494
1974
  }
1495
- function Et(e, t) {
1496
- let n = 0;
1497
- const r = Lt(async (i, s) => (await Ye(), await Xe(e, i), r.isLatestSeq(s)));
1975
+ function zt(e, t) {
1976
+ let n = 0, r = null;
1977
+ const s = wn(async (i, o) => (await at(), await ct(e, i), s.isLatestSeq(o)));
1498
1978
  return {
1499
1979
  usesWorker: !1,
1500
1980
  async loadAssets(i) {
1501
- return await Ye(i);
1981
+ const o = await at(i);
1982
+ return r = o.visemePaths ? new Set(o.visemePaths) : null, o;
1983
+ },
1984
+ getVisemeAtlasPaths() {
1985
+ return r;
1502
1986
  },
1503
1987
  async renderSilOnly() {
1504
- n += 1, r.reset(), await kr(e);
1988
+ n += 1, s.reset(), await ms(e);
1505
1989
  },
1506
- drawLiveFrame(i, s, c, a) {
1507
- r.enqueue(s, c, a);
1990
+ drawLiveFrame(i, o, a, f) {
1991
+ s.enqueue(o, a, f);
1508
1992
  },
1509
- async renderViseme(i, s) {
1993
+ async renderViseme(i, o) {
1510
1994
  n += 1;
1511
- const c = n;
1512
- t.onStatus?.(s), await Xe(i, {
1513
- mouthPath: Qe(s),
1995
+ const a = n;
1996
+ t.onStatus?.(o), await ct(i, {
1997
+ mouthPath: Ke(o),
1514
1998
  expressionPath: null
1515
1999
  });
1516
2000
  },
1517
2001
  dispose() {
1518
- n += 1, r.reset();
2002
+ n += 1, s.reset();
1519
2003
  }
1520
2004
  };
1521
2005
  }
1522
- function Nr(e, t, n) {
1523
- let r = null, i = 1, s = 0, c = !1, a = !1;
1524
- const l = /* @__PURE__ */ new Map(), d = Lt(async (w, u, g) => (l.set(u, {
1525
- drawKey: g.drawKey,
1526
- onDisplayed: g.onDisplayed
1527
- }), await o(
2006
+ function Cs(e, t, n) {
2007
+ let r = null, s = 1, i = 0, o = !1, a = !1, f = null;
2008
+ const l = /* @__PURE__ */ new Map(), w = wn(async (p, d, I) => (l.set(d, {
2009
+ drawKey: I.drawKey,
2010
+ onDisplayed: I.onDisplayed
2011
+ }), await E(
1528
2012
  {
1529
2013
  type: "drawFrame",
1530
- diffPath: w.mouthPath,
1531
- expressionDiffPath: w.expressionPath,
1532
- liveSeq: u
2014
+ diffPath: p.mouthPath,
2015
+ expressionDiffPath: p.expressionPath,
2016
+ liveSeq: d
1533
2017
  },
1534
2018
  void 0,
1535
2019
  !0
1536
- ), !1)), _ = (w) => {
1537
- if (w === yt) {
1538
- let y = -1, v;
1539
- for (const [H, h] of l)
1540
- H >= y && (y = H, v = h);
1541
- y >= 0 && l.delete(y), v?.onDisplayed?.(v.drawKey);
2020
+ ), !1)), _ = (p) => {
2021
+ if (p === jt) {
2022
+ let k = -1, R;
2023
+ for (const [W, V] of l)
2024
+ W >= k && (k = W, R = V);
2025
+ k >= 0 && l.delete(k), R?.onDisplayed?.(R.drawKey);
1542
2026
  return;
1543
2027
  }
1544
- const u = -w, g = l.get(u);
1545
- l.delete(u), g?.onDisplayed?.(g.drawKey);
1546
- }, m = /* @__PURE__ */ new Map(), S = (w, u) => {
1547
- a || !r || r.postMessage(w, []);
1548
- }, o = (w, u, g = !1) => {
2028
+ const d = -p, I = l.get(d);
2029
+ l.delete(d), I?.onDisplayed?.(I.drawKey);
2030
+ }, m = /* @__PURE__ */ new Map(), S = (p, d) => {
2031
+ a || !r || r.postMessage(p, []);
2032
+ }, E = (p, d, I = !1) => {
1549
2033
  if (a) return Promise.resolve();
1550
- const y = i++;
1551
- return new Promise((v, H) => {
1552
- m.set(y, {
1553
- resolve: (h) => v(h),
1554
- reject: H,
1555
- generation: typeof w.generation == "number" ? w.generation : void 0,
1556
- expectRenderDone: g
1557
- }), S({ ...w, requestId: y });
2034
+ const k = s++;
2035
+ return new Promise((R, W) => {
2036
+ m.set(k, {
2037
+ resolve: (V) => R(V),
2038
+ reject: W,
2039
+ generation: typeof p.generation == "number" ? p.generation : void 0,
2040
+ expectRenderDone: I
2041
+ }), S({ ...p, requestId: k });
1558
2042
  });
1559
- }, F = (async () => {
1560
- r = await Pr(n), r.onmessage = (w) => {
2043
+ }, u = (async () => {
2044
+ r = await Ds(n), r.onmessage = (p) => {
1561
2045
  if (a) return;
1562
- const u = w.data;
1563
- if (u.type === "status") {
1564
- t.onStatus?.(u.label);
2046
+ const d = p.data;
2047
+ if (d.type === "status") {
2048
+ t.onStatus?.(d.label);
1565
2049
  return;
1566
2050
  }
1567
- if (u.type === "frame") {
1568
- const y = u.generation < 0;
1569
- if (!y && u.generation !== s) {
1570
- u.bitmap.close();
2051
+ if (d.type === "frame") {
2052
+ const k = d.generation < 0;
2053
+ if (!k && d.generation !== i) {
2054
+ d.bitmap.close();
1571
2055
  return;
1572
2056
  }
1573
- if (y && !(u.generation === yt)) {
1574
- const H = -u.generation;
1575
- if (!d.isLatestSeq(H)) {
1576
- u.bitmap.close();
2057
+ if (k && !(d.generation === jt)) {
2058
+ const W = -d.generation;
2059
+ if (!w.isLatestSeq(W)) {
2060
+ d.bitmap.close();
1577
2061
  return;
1578
2062
  }
1579
2063
  }
1580
- if (y && t.shouldAcceptLiveFrame && !t.shouldAcceptLiveFrame()) {
1581
- u.bitmap.close();
2064
+ if (k && t.shouldAcceptLiveFrame && !t.shouldAcceptLiveFrame()) {
2065
+ d.bitmap.close();
1582
2066
  return;
1583
2067
  }
1584
- Br(e, u.bitmap), u.bitmap.close(), y && _(u.generation);
2068
+ xs(e, d.bitmap), d.bitmap.close(), k && _(d.generation);
1585
2069
  return;
1586
2070
  }
1587
- const g = m.get(u.requestId);
1588
- if (g)
1589
- switch (u.type) {
2071
+ const I = m.get(d.requestId);
2072
+ if (I)
2073
+ switch (d.type) {
1590
2074
  case "ready":
1591
- m.delete(u.requestId), g.resolve();
2075
+ m.delete(d.requestId), I.resolve();
1592
2076
  break;
1593
2077
  case "loadAssetsDone":
1594
- m.delete(u.requestId), g.resolve({ width: u.width, height: u.height });
2078
+ m.delete(d.requestId), f = d.visemePaths?.length ? new Set(d.visemePaths) : null, I.resolve({ width: d.width, height: d.height, visemePaths: d.visemePaths });
1595
2079
  break;
1596
2080
  case "renderDone":
1597
- if (g.expectRenderDone && g.generation != null && u.generation !== g.generation)
2081
+ if (I.expectRenderDone && I.generation != null && d.generation !== I.generation)
1598
2082
  return;
1599
- m.delete(u.requestId), g.resolve();
2083
+ m.delete(d.requestId), I.resolve();
1600
2084
  break;
1601
2085
  case "renderAborted":
1602
- m.delete(u.requestId), g.resolve();
2086
+ m.delete(d.requestId), I.resolve();
1603
2087
  break;
1604
2088
  case "error":
1605
- m.delete(u.requestId), t.onError?.(u.message), g.reject(new Error(u.message));
2089
+ m.delete(d.requestId), t.onError?.(d.message), I.reject(new Error(d.message));
1606
2090
  break;
1607
2091
  }
1608
- }, r.onerror = (w) => {
2092
+ }, r.onerror = (p) => {
1609
2093
  if (a) return;
1610
- const u = w.message || "Worker error";
1611
- t.onError?.(u);
1612
- for (const [, g] of m)
1613
- g.reject(new Error(u));
2094
+ const d = p.message || "Worker error";
2095
+ t.onError?.(d);
2096
+ for (const [, I] of m)
2097
+ I.reject(new Error(d));
1614
2098
  m.clear();
1615
- }, await o({ type: "init" }), c = !0;
2099
+ }, await E({ type: "init" }), o = !0;
1616
2100
  })();
1617
2101
  return {
1618
2102
  usesWorker: !0,
1619
- async loadAssets(w) {
2103
+ async loadAssets(p) {
1620
2104
  if (a) return { width: 842, height: 1264 };
1621
- if (await F, a) return { width: 842, height: 1264 };
1622
- if (!c) throw new Error("Worker init failed");
1623
- return await o({
2105
+ if (await u, a) return { width: 842, height: 1264 };
2106
+ if (!o) throw new Error("Worker init failed");
2107
+ return await E({
1624
2108
  type: "loadAssets",
1625
- keyHex: w,
1626
- urls: hn(he())
2109
+ keyHex: p,
2110
+ urls: Jn(ke())
1627
2111
  }) ?? { width: 842, height: 1264 };
1628
2112
  },
2113
+ getVisemeAtlasPaths() {
2114
+ return f;
2115
+ },
1629
2116
  async renderSilOnly() {
1630
- if (a || (await F, a)) return;
1631
- s += 1, d.reset(), l.clear();
1632
- const w = s;
1633
- await o({ type: "cancelLiveDraws" }), await o(
1634
- { type: "renderSil", generation: w },
2117
+ if (a || (await u, a)) return;
2118
+ i += 1, w.reset(), l.clear();
2119
+ const p = i;
2120
+ await E({ type: "cancelLiveDraws" }), await E(
2121
+ { type: "renderSil", generation: p },
1635
2122
  void 0,
1636
2123
  !0
1637
2124
  );
1638
2125
  },
1639
- drawLiveFrame(w, u, g, y) {
1640
- a || F.then(() => {
1641
- a || d.enqueue(u, g, y);
2126
+ drawLiveFrame(p, d, I, k) {
2127
+ a || u.then(() => {
2128
+ a || w.enqueue(d, I, k);
1642
2129
  });
1643
2130
  },
1644
- async renderViseme(w, u, g = {}) {
1645
- if (a || (await F, a)) return;
1646
- s += 1, d.reset(), l.clear();
1647
- const y = s;
2131
+ async renderViseme(p, d, I = {}) {
2132
+ if (a || (await u, a)) return;
2133
+ i += 1, w.reset(), l.clear();
2134
+ const k = i;
1648
2135
  try {
1649
- await o({ type: "cancelLiveDraws" }), await o(
2136
+ await E({ type: "cancelLiveDraws" }), await E(
1650
2137
  {
1651
2138
  type: "renderViseme",
1652
- generation: y,
1653
- to: u,
1654
- from: g.from,
1655
- transitionDurationMs: g.transitionDurationMs,
1656
- gapMs: g.gapMs,
1657
- threshold: g.threshold
2139
+ generation: k,
2140
+ to: d,
2141
+ from: I.from,
2142
+ transitionDurationMs: I.transitionDurationMs,
2143
+ gapMs: I.gapMs,
2144
+ threshold: I.threshold
1658
2145
  },
1659
2146
  void 0,
1660
2147
  !0
1661
2148
  );
1662
- } catch (v) {
1663
- if (v?.name === "AbortError") return;
1664
- throw v;
2149
+ } catch (R) {
2150
+ if (R?.name === "AbortError") return;
2151
+ throw R;
1665
2152
  }
1666
2153
  },
1667
2154
  dispose() {
1668
2155
  if (!a) {
1669
- a = !0, s += 1, d.reset(), l.clear();
1670
- for (const [, w] of m)
1671
- w.resolve();
2156
+ a = !0, i += 1, w.reset(), l.clear();
2157
+ for (const [, p] of m)
2158
+ p.resolve();
1672
2159
  m.clear(), r?.terminate(), r = null;
1673
2160
  }
1674
2161
  }
1675
2162
  };
1676
2163
  }
1677
- function Vr(e, t = {}) {
1678
- if (!Ur())
1679
- return Et(e, t);
1680
- const n = zt(t.workerScriptUrl);
2164
+ function Ps(e, t = {}) {
2165
+ if (!Ms())
2166
+ return zt(e, t);
2167
+ const n = Cn(t.workerScriptUrl);
1681
2168
  try {
1682
- return Nr(e, t, n);
2169
+ return Cs(e, t, n);
1683
2170
  } catch {
1684
- return Et(e, t);
2171
+ return zt(e, t);
1685
2172
  }
1686
2173
  }
1687
- class $r extends Error {
2174
+ class Bs extends Error {
1688
2175
  constructor(t, n) {
1689
2176
  super(`${t} timed out after ${Math.round(n / 1e3)}s`), this.name = "LoadTimeoutError";
1690
2177
  }
1691
2178
  }
1692
- function qe(e, t, n) {
1693
- return new Promise((r, i) => {
1694
- const s = globalThis.setTimeout(() => {
1695
- i(new $r(n, t));
2179
+ function tt(e, t, n) {
2180
+ return new Promise((r, s) => {
2181
+ const i = globalThis.setTimeout(() => {
2182
+ s(new Bs(n, t));
1696
2183
  }, t);
1697
2184
  e.then(
1698
- (c) => {
1699
- globalThis.clearTimeout(s), r(c);
2185
+ (o) => {
2186
+ globalThis.clearTimeout(i), r(o);
1700
2187
  },
1701
- (c) => {
1702
- globalThis.clearTimeout(s), i(c);
2188
+ (o) => {
2189
+ globalThis.clearTimeout(i), s(o);
1703
2190
  }
1704
2191
  );
1705
2192
  });
1706
2193
  }
1707
- const Hr = {
2194
+ const Os = {
1708
2195
  position: "relative",
1709
2196
  display: "inline-block",
1710
2197
  lineHeight: 0
1711
- }, Wr = {
2198
+ }, Fs = {
1712
2199
  display: "block",
1713
2200
  maxWidth: "100%",
1714
2201
  height: "auto"
1715
- }, qr = {
2202
+ }, Ls = {
1716
2203
  position: "absolute",
1717
2204
  inset: 0,
1718
2205
  display: "flex",
@@ -1725,393 +2212,489 @@ const Hr = {
1725
2212
  textAlign: "center"
1726
2213
  };
1727
2214
  function Oe(e) {
1728
- return Xt(e) ? Nn : It;
2215
+ return Fn(e) ? kr : tn;
1729
2216
  }
1730
- const zr = Nt(function({
2217
+ function we(e, t) {
2218
+ return t?.isSpeaking() ? t : e.isSpeaking() ? e : t?.isConnected() ? t : e;
2219
+ }
2220
+ const qs = En(function({
1731
2221
  id: t,
1732
- assets: n,
1733
- authToken: r,
1734
- ttsEngineId: i = pe,
1735
- voiceId: s,
1736
- speakingRate: c = At,
1737
- className: a,
1738
- style: l,
1739
- canvasStyle: d,
1740
- onStatusChange: _,
1741
- onDisplayStatus: m,
1742
- onError: S,
1743
- onReady: o,
1744
- showErrorOverlay: F = !0
1745
- }, w) {
1746
- const u = R(null), g = R(null), y = R(xr()), v = R(dr()), H = R(0), h = R(0), E = R(null), D = R(null), L = R(!1), z = R(!1), U = R(!1), ae = R("sil"), me = R(!1), N = R(
2222
+ avatarId: n,
2223
+ faceId: r,
2224
+ assets: s,
2225
+ authToken: i,
2226
+ ttsEngineId: o = Te,
2227
+ voiceId: a,
2228
+ speakingRate: f = ft,
2229
+ className: l,
2230
+ style: w,
2231
+ canvasStyle: _,
2232
+ onStatusChange: m,
2233
+ onDisplayStatus: S,
2234
+ onError: E,
2235
+ onReady: u,
2236
+ showErrorOverlay: p = !0,
2237
+ onUserTranscript: d,
2238
+ onBotOutput: I,
2239
+ onRealtimeLipsyncDebug: k
2240
+ }, R) {
2241
+ const W = L(null), V = L(null), H = L(Ss()), j = L(ss()), y = L(0), T = L(0), g = L(0), x = L(null), b = L(null), D = L(!1), A = L(!1), P = L(!1), B = L("sil"), $ = L(!1), U = L(
1747
2242
  null
1748
- ), X = R(!1), [Re, He] = ke("idle"), [De, ue] = ke(null), [se, xe] = ke(!1), [nt, p] = ke(!1), [V, W] = ke({ width: 842, height: 1264 }), x = R(r ?? null), M = R(null), I = R(null), Q = R(!1), J = R({ width: 842, height: 1264 }), P = R(o), O = R(m), q = R(S);
1749
- P.current = o, O.current = m, q.current = S;
1750
- const ce = ie(
1751
- (f) => {
1752
- const k = f?.ttsEngineId ?? i ?? I.current?.ttsEngineId ?? pe, T = f?.voiceId ?? s ?? I.current?.voiceId ?? Oe(k);
1753
- return { ttsEngineId: k, voiceId: T };
2243
+ ), X = L(!1), [se, Z] = Be("idle"), [ce, J] = Be(null), [c, v] = Be(!1), [O, z] = Be(!1), [ne, Re] = Be({ width: 842, height: 1264 }), G = L(i ?? null), Ee = L(null), Y = L(null), De = L(!1), Je = L({ width: 842, height: 1264 }), Qe = L(null), _t = L(u), ee = L(S), pt = L(E), yt = L(d), kt = L(I), Et = L(k);
2244
+ _t.current = u, ee.current = S, pt.current = E, yt.current = d, kt.current = I, Et.current = k;
2245
+ const St = oe(
2246
+ (h) => {
2247
+ const M = h?.ttsEngineId ?? o ?? Y.current?.ttsEngineId ?? Te, C = h?.voiceId ?? a ?? Y.current?.voiceId ?? Oe(M);
2248
+ return { ttsEngineId: M, voiceId: C };
1754
2249
  },
1755
- [i, s]
1756
- ), $ = ie((f) => {
1757
- ue(f), q.current?.(f);
1758
- }, []), Me = ie(
1759
- (f) => {
1760
- He(f), _?.(f);
2250
+ [o, a]
2251
+ ), fe = oe((h) => {
2252
+ J(h), pt.current?.(h);
2253
+ }, []), Me = oe(
2254
+ (h) => {
2255
+ Z(h), m?.(h);
1761
2256
  },
1762
- [_]
1763
- ), B = R(
1764
- Vn(Me, Pe)
1765
- ), b = ie(() => {
1766
- E.current != null && (clearTimeout(E.current), E.current = null);
1767
- }, []), K = ie(() => {
1768
- D.current != null && (clearTimeout(D.current), D.current = null), U.current = !1;
1769
- }, []), te = ie(() => {
1770
- !X.current || !N.current || (K(), U.current = !0, D.current = setTimeout(() => {
1771
- if (D.current = null, B.current.isSpeaking()) {
1772
- U.current = !1;
2257
+ [m]
2258
+ ), q = L(
2259
+ Pt(Me, be)
2260
+ ), K = L(null);
2261
+ Se(() => (q.current = Pt(
2262
+ Me,
2263
+ be
2264
+ ), i && q.current.setDeveloperToken(i), q.current.setTtsEngineId(o), () => {
2265
+ q.current.stop();
2266
+ const h = K.current;
2267
+ h && (h.disconnect(), K.current = null);
2268
+ }), [Me, i, o]);
2269
+ const vt = oe(() => (K.current || (K.current = Ir(
2270
+ Me,
2271
+ {
2272
+ speakingRate: f,
2273
+ onUserTranscript: (h, M) => yt.current?.(h, M),
2274
+ onBotOutput: (h) => kt.current?.(h),
2275
+ onLipsyncDebug: (h) => Et.current?.(h)
2276
+ }
2277
+ ), K.current.setTtsEngineId(o)), K.current), [Me, f, o]), ie = oe(() => {
2278
+ x.current != null && (clearTimeout(x.current), x.current = null);
2279
+ }, []), ue = oe(() => {
2280
+ b.current != null && (clearTimeout(b.current), b.current = null), P.current = !1;
2281
+ }, []), bt = oe(() => {
2282
+ !X.current || !U.current || (ue(), P.current = !0, b.current = setTimeout(() => {
2283
+ if (b.current = null, we(
2284
+ q.current,
2285
+ K.current
2286
+ ).isSpeaking()) {
2287
+ P.current = !1;
1773
2288
  return;
1774
2289
  }
1775
- if (L.current) {
1776
- U.current = !1;
2290
+ if (D.current) {
2291
+ P.current = !1;
1777
2292
  return;
1778
2293
  }
1779
- const f = N.current;
1780
- if (!f) {
1781
- U.current = !1;
2294
+ const h = U.current;
2295
+ if (!h) {
2296
+ P.current = !1;
1782
2297
  return;
1783
2298
  }
1784
- f.restart(), f.setActive(!0);
1785
- const k = f.getVideo();
1786
- let T = !1;
1787
- const A = () => {
1788
- T || (T = !0, k.removeEventListener("playing", C), U.current = !1);
1789
- }, C = () => {
1790
- A();
2299
+ h.restart(), h.setActive(!0);
2300
+ const M = h.getVideo();
2301
+ let C = !1;
2302
+ const F = () => {
2303
+ C || (C = !0, M.removeEventListener("playing", N), P.current = !1);
2304
+ }, N = () => {
2305
+ F();
1791
2306
  };
1792
- if (k.addEventListener("playing", C, { once: !0 }), k.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && !k.paused) {
1793
- A();
2307
+ if (M.addEventListener("playing", N, { once: !0 }), M.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && !M.paused) {
2308
+ F();
1794
2309
  return;
1795
2310
  }
1796
- setTimeout(A, 300);
1797
- }, br));
1798
- }, [K]), Z = ie(() => {
1799
- if (b(), O.current?.("sil"), L.current = !1, !X.current || !N.current) {
1800
- U.current = !1;
2311
+ setTimeout(F, 300);
2312
+ }, ys));
2313
+ }, [ue]), Ne = oe(() => {
2314
+ if (ie(), ee.current?.("sil"), D.current = !1, !X.current || !U.current) {
2315
+ P.current = !1;
1801
2316
  return;
1802
2317
  }
1803
- te();
1804
- }, [b, te]), j = ie(
1805
- async (f) => {
1806
- const k = h.current, T = g.current, A = u.current, C = () => {
1807
- f?.fallbackOnly || (L.current = !1);
2318
+ bt();
2319
+ }, [ie, bt]), Xe = oe(
2320
+ async (h) => {
2321
+ const M = T.current, C = V.current, F = W.current, N = () => {
2322
+ h?.fallbackOnly || (D.current = !1);
1808
2323
  };
1809
- if (!T || !A || !se) {
1810
- C();
2324
+ if (!C || !F || !c) {
2325
+ N();
1811
2326
  return;
1812
2327
  }
1813
- if (B.current.isSpeaking()) {
1814
- C();
2328
+ if (we(
2329
+ q.current,
2330
+ K.current
2331
+ ).isSpeaking()) {
2332
+ N();
1815
2333
  return;
1816
2334
  }
1817
- if (f?.fallbackOnly) {
1818
- if (!L.current || (ge(y.current), await T.renderSilOnly(), k !== h.current) || B.current.isSpeaking()) return;
1819
- Z();
2335
+ if (h?.fallbackOnly) {
2336
+ if (!D.current || (me(H.current), await C.renderSilOnly(), M !== T.current) || we(
2337
+ q.current,
2338
+ K.current
2339
+ ).isSpeaking())
2340
+ return;
2341
+ Ne();
1820
2342
  return;
1821
2343
  }
1822
- const Y = ae.current !== "sil" ? ae.current : Mr(B.current.getVisemeQueue()), ne = Cr(Y);
1823
- if (ge(y.current), !ne) {
1824
- if (await T.renderSilOnly(), k !== h.current || B.current.isSpeaking()) return;
1825
- Z();
2344
+ const te = B.current !== "sil" ? B.current : bs(
2345
+ we(
2346
+ q.current,
2347
+ K.current
2348
+ ).getVisemeQueue()
2349
+ ), ae = Ts(
2350
+ te,
2351
+ Qe.current
2352
+ );
2353
+ if (me(H.current), !ae) {
2354
+ if (await C.renderSilOnly(), M !== T.current || we(
2355
+ q.current,
2356
+ K.current
2357
+ ).isSpeaking())
2358
+ return;
2359
+ Ne();
1826
2360
  return;
1827
2361
  }
1828
2362
  try {
1829
- await T.renderViseme(A, "sil", {
1830
- from: Y,
1831
- transitionDurationMs: Ct
2363
+ await C.renderViseme(F, "sil", {
2364
+ from: te,
2365
+ transitionDurationMs: hn
1832
2366
  });
1833
- } catch (oe) {
1834
- if (oe?.name !== "AbortError")
1835
- throw oe;
2367
+ } catch (de) {
2368
+ if (de?.name !== "AbortError")
2369
+ throw de;
1836
2370
  }
1837
- if (k !== h.current) {
1838
- C();
2371
+ if (M !== T.current) {
2372
+ N();
1839
2373
  return;
1840
2374
  }
1841
- if (B.current.isSpeaking()) {
1842
- C();
2375
+ if (we(
2376
+ q.current,
2377
+ K.current
2378
+ ).isSpeaking()) {
2379
+ N();
1843
2380
  return;
1844
2381
  }
1845
- Z();
2382
+ Ne();
1846
2383
  },
1847
- [se, Z]
1848
- ), _e = ie(() => {
1849
- if (z.current || L.current) return;
1850
- z.current = !0, L.current = !0, b();
1851
- const f = h.current;
1852
- j().finally(() => {
1853
- z.current = !1;
1854
- }), E.current = setTimeout(() => {
1855
- E.current = null, f === h.current && j({ fallbackOnly: !0 });
1856
- }, Fr());
1857
- }, [b, j]), rt = ie(async () => {
1858
- const f = Math.floor(Date.now() / 1e3);
1859
- if (M.current && f < M.current.expiresAt - 60)
1860
- return M.current.key;
1861
- const k = x.current ?? await ot();
1862
- x.current = k, B.current.setDeveloperToken(k);
1863
- const T = await an(k, Pe);
1864
- return M.current = {
1865
- key: T.value,
1866
- expiresAt: T.expiresAt
1867
- }, T.value;
2384
+ [c, Ne]
2385
+ ), xe = oe(() => {
2386
+ if (A.current || D.current) return;
2387
+ A.current = !0, D.current = !0, ie();
2388
+ const h = T.current;
2389
+ Xe().finally(() => {
2390
+ A.current = !1;
2391
+ }), x.current = setTimeout(() => {
2392
+ x.current = null, h === T.current && Xe({ fallbackOnly: !0 });
2393
+ }, As());
2394
+ }, [ie, Xe]), Tt = oe(async () => {
2395
+ const h = Math.floor(Date.now() / 1e3);
2396
+ if (Ee.current && h < Ee.current.expiresAt - 60)
2397
+ return Ee.current.key;
2398
+ const M = G.current ?? await et();
2399
+ G.current = M, q.current.setDeveloperToken(M);
2400
+ const C = await qn(M, be);
2401
+ return Ee.current = {
2402
+ key: C.value,
2403
+ expiresAt: C.expiresAt
2404
+ }, C.value;
1868
2405
  }, []);
1869
- Te(() => {
1870
- r && (x.current = r, B.current.setDeveloperToken(r));
1871
- }, [r]), Te(() => {
1872
- B.current.setTtsEngineId(i), I.current && (I.current.ttsEngineId = i);
1873
- }, [i]), Te(() => {
1874
- const f = s ?? Oe(i);
1875
- I.current && (I.current.voiceId = f);
1876
- }, [s, i]);
1877
- const Ot = Vt(
1878
- () => n ? JSON.stringify(n) : `id:${t ?? ""}`,
1879
- [n, t]
1880
- );
1881
- return Te(() => {
1882
- if (!t && !n) {
1883
- $("AiTwin requires either `id` or `assets`");
2406
+ Se(() => {
2407
+ i && (G.current = i, q.current.setDeveloperToken(i));
2408
+ }, [i]), Se(() => {
2409
+ q.current.setTtsEngineId(o), K.current?.setTtsEngineId(o), Y.current && (Y.current.ttsEngineId = o);
2410
+ }, [o]), Se(() => {
2411
+ const h = a ?? Oe(o);
2412
+ Y.current && (Y.current.voiceId = h);
2413
+ }, [a, o]);
2414
+ const ge = It(
2415
+ () => zn(n, r),
2416
+ [n, r]
2417
+ ), gn = It(() => s ? JSON.stringify(s) : ge ? `face:${ge}` : `id:${t ?? ""}`, [s, ge, t]);
2418
+ return Se(() => {
2419
+ if (!t && !s && !ge) {
2420
+ fe("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");
1884
2421
  return;
1885
2422
  }
1886
- let f = !1;
1887
- Q.current = !1, xe(!1), p(!1), ue(null), I.current = null, N.current = null, X.current = !1;
1888
- const k = u.current;
1889
- if (!k) return;
1890
- let T = null;
2423
+ let h = !1;
2424
+ De.current = !1, v(!1), z(!1), J(null), Y.current = null, U.current = null, X.current = !1;
2425
+ const M = W.current;
2426
+ if (!M) return;
2427
+ let C = null;
1891
2428
  return (async () => {
1892
2429
  try {
1893
- let A, C, Y;
1894
- if (n)
1895
- A = n, C = i, Y = s ?? Oe(C);
2430
+ let F, N, te;
2431
+ if (s)
2432
+ F = s, N = o, te = a ?? Oe(N);
2433
+ else if (ge)
2434
+ ee.current?.("loadFace"), F = Dt(ge), N = o, te = a ?? Oe(N);
1896
2435
  else {
1897
- O.current?.("getAiTwin");
1898
- const G = await qe(
1899
- en(t),
2436
+ ee.current?.("getAiTwin");
2437
+ const Q = await tt(
2438
+ Un(t),
1900
2439
  3e4,
1901
2440
  "getAiTwin"
1902
2441
  );
1903
- if (f) return;
1904
- if (!G.faceId?.trim())
2442
+ if (h) return;
2443
+ if (!Q.faceId?.trim())
1905
2444
  throw new Error("getAiTwin returned no faceId");
1906
- C = G.ttsEngineId, Y = s ?? G.voiceId ?? Oe(C), A = fn(G.faceId);
2445
+ N = Q.ttsEngineId, te = a ?? Q.voiceId ?? Oe(N), F = Dt(Q.faceId);
1907
2446
  }
1908
- I.current = { ttsEngineId: C, voiceId: Y }, dn(A), N.current = hr(), T = Vr(k, {
1909
- onStatus: (G) => {
1910
- f || O.current?.(G);
2447
+ Y.current = { ttsEngineId: N, voiceId: te }, Yn(F), U.current = is(), C = Ps(M, {
2448
+ onStatus: (Q) => {
2449
+ h || ee.current?.(Q);
1911
2450
  },
1912
- onError: (G) => {
1913
- f || $(G);
2451
+ onError: (Q) => {
2452
+ h || fe(Q);
1914
2453
  },
1915
- shouldAcceptLiveFrame: () => B.current.isSpeaking() && !L.current
1916
- }), g.current = T, O.current?.("auth");
1917
- const ne = x.current ?? r ?? await qe(ot(), 3e4, "getAuthToken");
1918
- if (f) return;
1919
- x.current = ne, B.current.setDeveloperToken(ne), B.current.setTtsEngineId(C);
1920
- const oe = Be() ? await rt() : void 0;
1921
- if (f) return;
1922
- O.current?.("loadAssets");
1923
- const we = await qe(
1924
- T.loadAssets(oe),
2454
+ shouldAcceptLiveFrame: () => we(
2455
+ q.current,
2456
+ K.current
2457
+ ).isSpeaking() && !D.current
2458
+ }), V.current = C, ee.current?.("auth");
2459
+ const ae = G.current ?? i ?? await tt(et(), 3e4, "getAuthToken");
2460
+ if (h) return;
2461
+ G.current = ae, q.current.setDeveloperToken(ae), q.current.setTtsEngineId(N);
2462
+ const de = Ge() ? await Tt() : void 0;
2463
+ if (h) return;
2464
+ ee.current?.("loadAssets");
2465
+ const le = await tt(
2466
+ C.loadAssets(de),
1925
2467
  18e4,
1926
2468
  "load face assets"
1927
2469
  );
1928
- if (!f && we.width > 0 && we.height > 0 && (J.current = we, W(we)), f) return;
1929
- Q.current = !0, xe(!0), P.current?.(), T.renderSilOnly().then(() => {
1930
- f || O.current?.("sil");
2470
+ if (!h && le.width > 0 && le.height > 0 && (Je.current = le, Re(le)), h) return;
2471
+ Qe.current = C.getVisemeAtlasPaths(), De.current = !0, v(!0), _t.current?.(), C.renderSilOnly().then(() => {
2472
+ h || ee.current?.("sil");
1931
2473
  }), (async () => {
1932
2474
  try {
1933
- const G = await zn(oe);
1934
- if (await N.current.load(G), f) return;
1935
- X.current = !0, p(!0), ge(y.current), N.current.setActive(!0);
1936
- const re = N.current.getVideo();
1937
- await _t(
1938
- k,
2475
+ const Q = await Or(de);
2476
+ if (await U.current.load(Q), h) return;
2477
+ X.current = !0, z(!0), me(H.current), U.current.setActive(!0);
2478
+ const re = U.current.getVideo();
2479
+ await Wt(
2480
+ M,
1939
2481
  re,
1940
2482
  null,
1941
2483
  void 0,
1942
- J.current
1943
- ), f || O.current?.("idle");
1944
- } catch (G) {
1945
- if (f) return;
1946
- X.current = !1, p(!1), console.warn("[AiTwin] Idle video unavailable:", G);
2484
+ Je.current
2485
+ ), h || ee.current?.("idle");
2486
+ } catch (Q) {
2487
+ if (h) return;
2488
+ X.current = !1, z(!1), console.warn("[AiTwin] Idle video unavailable:", Q);
1947
2489
  }
1948
2490
  })();
1949
- } catch (A) {
1950
- if (f) return;
1951
- if (A instanceof Ke) {
1952
- $(A.message);
2491
+ } catch (F) {
2492
+ if (h) return;
2493
+ if (F instanceof nt) {
2494
+ fe(F.message);
1953
2495
  return;
1954
2496
  }
1955
- $(A instanceof Error ? A.message : "Failed to load AI twin");
2497
+ fe(F instanceof Error ? F.message : "Failed to load AI twin");
1956
2498
  }
1957
2499
  })(), () => {
1958
- f = !0, N.current?.dispose(), T?.dispose(), g.current = null;
2500
+ h = !0, U.current?.dispose(), C?.dispose(), V.current = null;
1959
2501
  };
1960
- }, [Ot, n, i, s, r, rt, $]), Te(() => {
1961
- const f = B.current, k = { current: !1 }, T = () => {
1962
- const A = u.current, C = g.current;
1963
- if (!A || !C || !se) {
1964
- H.current = requestAnimationFrame(T);
2502
+ }, [gn, s, ge, t, o, a, i, Tt, fe]), Se(() => {
2503
+ const h = { current: !1 }, M = () => {
2504
+ const C = W.current, F = V.current, N = we(
2505
+ q.current,
2506
+ K.current
2507
+ );
2508
+ if (!C || !F || !c) {
2509
+ y.current = requestAnimationFrame(M);
1965
2510
  return;
1966
2511
  }
1967
- const Y = f.isSpeaking(), ne = me.current && !Y;
1968
- ne && (v.current.reset(), N.current?.setActive(!1), _e());
1969
- const oe = f.getPlaybackElapsedMs(), we = Y ? gr(
1970
- oe,
1971
- f.getSentenceEmotions(),
1972
- f.getWordQueue(),
1973
- f.getStreamMood()
1974
- ) : f.getStreamMood(), G = ne || L.current || U.current;
1975
- if (Y) {
1976
- X.current && N.current?.setActive(!1);
1977
- const re = f.getVisemeQueue();
1978
- if (re.length === 0) {
1979
- H.current = requestAnimationFrame(T);
1980
- return;
1981
- }
1982
- const le = vt(re, oe);
1983
- le !== "sil" && (ae.current = le), v.current.setTargetEmotion(we), v.current.advance(performance.now());
1984
- const fe = v.current.getExpressionPath(), Ee = v.current.getDrawKey();
1985
- Or(
1986
- A,
1987
- f.getVisemeQueue(),
1988
- oe,
1989
- fe,
1990
- Ee,
1991
- y.current,
1992
- (Se, We, Pt, Ut) => C.drawLiveFrame(Se, We, Pt, Ut),
1993
- (Se) => O.current?.(Se)
2512
+ const te = N.isSpeaking(), ae = te && !$.current, de = $.current && !te;
2513
+ ae && (ie(), ue(), D.current = !1, A.current = !1, me(H.current), g.current = 0, B.current = "sil", U.current?.setActive(!1)), de && (j.current.reset(), U.current?.setActive(!1), xe());
2514
+ const le = N.getPlaybackElapsedMs(), Q = de || D.current || P.current;
2515
+ if (te) {
2516
+ X.current && U.current?.setActive(!1);
2517
+ const re = N.getVisemeQueue(), _e = re.length > 0 ? lt(re, le) : "sil";
2518
+ _e !== "sil" && (B.current = _e);
2519
+ const he = us(
2520
+ le,
2521
+ N.getSentenceEmotions(),
2522
+ N.getWordQueue(),
2523
+ N.getStreamMood()
1994
2524
  );
1995
- } else if (!G && X.current && N.current) {
1996
- const re = N.current, le = re.getVideo();
1997
- le.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA ? (re.setActive(!0), k.current || (k.current = !0, _t(
1998
- A,
2525
+ j.current.setTargetEmotion(he), j.current.setTargetEyebrow(
2526
+ rs(
2527
+ le,
2528
+ N.getWordQueue(),
2529
+ wt(he)
2530
+ )
2531
+ ), j.current.advance(performance.now());
2532
+ const Ce = j.current.getExpressionPath(), Ze = j.current.getDrawKey();
2533
+ Rs(
2534
+ C,
2535
+ re,
1999
2536
  le,
2537
+ Ce,
2538
+ Ze,
2539
+ H.current,
2540
+ (Pe, _n, pn, yn) => F.drawLiveFrame(Pe, _n, pn, yn),
2541
+ (Pe) => ee.current?.(Pe),
2542
+ Qe.current
2543
+ );
2544
+ } else if (!Q && X.current && U.current) {
2545
+ const re = U.current, _e = re.getVideo();
2546
+ _e.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA ? (re.setActive(!0), h.current || (h.current = !0, Wt(
2547
+ C,
2548
+ _e,
2000
2549
  null,
2001
2550
  void 0,
2002
- J.current,
2003
- () => !f.isSpeaking() && !L.current && !U.current
2004
- ).then(() => O.current?.("idle")).finally(() => {
2005
- k.current = !1;
2006
- }))) : gt(
2007
- A,
2551
+ Je.current,
2552
+ () => !N.isSpeaking() && !D.current && !P.current
2553
+ ).then(() => ee.current?.("idle")).finally(() => {
2554
+ h.current = !1;
2555
+ }))) : Kt(
2556
+ C,
2008
2557
  null,
2009
2558
  "__sil__",
2010
- y.current,
2011
- (fe, Ee, Se, We) => C.drawLiveFrame(fe, Ee, Se, We),
2012
- (fe) => O.current?.(fe)
2559
+ H.current,
2560
+ (he, Ce, Ze, Pe) => F.drawLiveFrame(he, Ce, Ze, Pe),
2561
+ (he) => ee.current?.(he)
2013
2562
  );
2014
- } else G || gt(
2015
- A,
2563
+ } else Q || Kt(
2564
+ C,
2016
2565
  null,
2017
2566
  "__sil__",
2018
- y.current,
2019
- (re, le, fe, Ee) => C.drawLiveFrame(re, le, fe, Ee),
2020
- (re) => O.current?.(re)
2567
+ H.current,
2568
+ (re, _e, he, Ce) => F.drawLiveFrame(re, _e, he, Ce),
2569
+ (re) => ee.current?.(re)
2021
2570
  );
2022
- me.current = Y, H.current = requestAnimationFrame(T);
2571
+ $.current = te, y.current = requestAnimationFrame(M);
2023
2572
  };
2024
- return H.current = requestAnimationFrame(T), () => {
2025
- cancelAnimationFrame(H.current), b(), K(), f.stop();
2573
+ return y.current = requestAnimationFrame(M), () => {
2574
+ cancelAnimationFrame(y.current), ie(), ue(), q.current.stop(), K.current?.stop();
2026
2575
  };
2027
2576
  }, [
2028
- se,
2029
- nt,
2030
- _e,
2031
- b,
2032
- K
2033
- ]), $t(
2034
- w,
2577
+ c,
2578
+ O,
2579
+ xe,
2580
+ ie,
2581
+ ue
2582
+ ]), Sn(
2583
+ R,
2035
2584
  () => ({
2036
- speakText: async (f, k) => {
2037
- const T = f.trim();
2038
- if (!T) return;
2039
- const A = g.current;
2040
- if (!A || !Q.current && !se)
2585
+ speakText: async (h, M) => {
2586
+ const C = h.trim();
2587
+ if (!C) return;
2588
+ const F = V.current;
2589
+ if (!F || !De.current && !c)
2041
2590
  throw new Error("AI twin is not ready");
2042
- const { ttsEngineId: C, voiceId: Y } = ce(k);
2043
- ue(null), h.current += 1, b(), K(), L.current = !1, z.current = !1, ae.current = "sil", ge(y.current), v.current.reset(), me.current = !1;
2591
+ const { ttsEngineId: N, voiceId: te } = St(M);
2592
+ J(null), T.current += 1, ie(), ue(), D.current = !1, A.current = !1, B.current = "sil", me(H.current), j.current.reset(), $.current = !1;
2044
2593
  try {
2045
- X.current ? (N.current?.setActive(!1), N.current?.restart(), ge(y.current)) : await A.renderSilOnly(), await B.current.speak(T, {
2046
- voiceId: Y,
2047
- speakingRate: k?.speakingRate ?? c,
2048
- ttsEngineId: C
2594
+ X.current ? (U.current?.setActive(!1), U.current?.restart(), me(H.current)) : await F.renderSilOnly(), await q.current.speak(C, {
2595
+ voiceId: te,
2596
+ speakingRate: M?.speakingRate ?? f,
2597
+ ttsEngineId: N
2049
2598
  });
2050
- } catch (ne) {
2051
- throw $(ne instanceof Error ? ne.message : "TTS failed"), ne;
2599
+ } catch (ae) {
2600
+ throw fe(ae instanceof Error ? ae.message : "TTS failed"), ae;
2052
2601
  }
2053
2602
  },
2054
2603
  stop: () => {
2055
- h.current += 1, b(), K(), L.current = !1, z.current = !1, B.current.stop(), ge(y.current), me.current = !1, _e();
2604
+ T.current += 1, ie(), ue(), D.current = !1, A.current = !1, q.current.stop(), K.current?.stop(), me(H.current), $.current = !1, xe();
2056
2605
  },
2057
- setTtsEngineId: (f) => {
2058
- B.current.setTtsEngineId(f), I.current && (I.current.ttsEngineId = f);
2606
+ setTtsEngineId: (h) => {
2607
+ q.current.setTtsEngineId(h), K.current?.setTtsEngineId(h), Y.current && (Y.current.ttsEngineId = h);
2059
2608
  },
2060
- renderViseme: async (f, k) => {
2061
- const T = g.current, A = u.current;
2062
- if (!T || !A || !Q.current)
2609
+ renderViseme: async (h, M) => {
2610
+ const C = V.current, F = W.current;
2611
+ if (!C || !F || !De.current)
2063
2612
  throw new Error("AI twin is not ready");
2064
- await T.renderViseme(A, f, {
2065
- from: k?.from,
2066
- transitionDurationMs: k?.transitionDurationMs,
2067
- gapMs: k?.gapMs,
2068
- onStatus: (C) => O.current?.(C)
2613
+ await C.renderViseme(F, h, {
2614
+ from: M?.from,
2615
+ transitionDurationMs: M?.transitionDurationMs,
2616
+ gapMs: M?.gapMs,
2617
+ onStatus: (N) => ee.current?.(N)
2069
2618
  });
2070
2619
  },
2071
- isReady: () => Q.current,
2072
- getStatus: () => Re
2620
+ isReady: () => De.current,
2621
+ getStatus: () => se,
2622
+ connect: async (h = {}) => {
2623
+ J(null);
2624
+ try {
2625
+ let M = h.authToken?.trim();
2626
+ M || (M = G.current ?? i ?? await et(), G.current = M);
2627
+ const C = h.voiceId?.trim() ?? a ?? Y.current?.voiceId, F = vt();
2628
+ await F.unlockAudio(), await F.connect({
2629
+ ...h,
2630
+ authToken: M,
2631
+ voiceId: C,
2632
+ speakingRate: h.speakingRate ?? f
2633
+ });
2634
+ } catch (M) {
2635
+ throw fe(
2636
+ M instanceof Error ? M.message : "Voice connect failed"
2637
+ ), M;
2638
+ }
2639
+ },
2640
+ disconnect: async () => {
2641
+ const h = K.current;
2642
+ h && (T.current += 1, ie(), ue(), D.current = !1, A.current = !1, me(H.current), $.current = !1, await h.disconnect(), xe());
2643
+ },
2644
+ isConnected: () => K.current?.isConnected() ?? !1
2073
2645
  }),
2074
2646
  [
2075
- se,
2076
2647
  c,
2077
- b,
2078
- _e,
2079
- $,
2080
- ce,
2081
- Re
2648
+ f,
2649
+ i,
2650
+ a,
2651
+ ie,
2652
+ ue,
2653
+ xe,
2654
+ fe,
2655
+ St,
2656
+ vt,
2657
+ se
2082
2658
  ]
2083
- ), /* @__PURE__ */ Bt("div", { className: a, style: { ...Hr, ...l }, children: [
2084
- /* @__PURE__ */ it(
2659
+ ), /* @__PURE__ */ kn("div", { className: l, style: { ...Os, ...w }, children: [
2660
+ /* @__PURE__ */ At(
2085
2661
  "canvas",
2086
2662
  {
2087
- ref: u,
2088
- width: V.width,
2089
- height: V.height,
2090
- style: { ...Wr, ...d },
2663
+ ref: W,
2664
+ width: ne.width,
2665
+ height: ne.height,
2666
+ style: { ...Fs, ..._ },
2091
2667
  "aria-label": t ? `AI twin ${t}` : "AI twin face"
2092
2668
  }
2093
2669
  ),
2094
- F && De ? /* @__PURE__ */ it("div", { style: qr, children: De }) : null
2670
+ p && ce ? /* @__PURE__ */ At("div", { style: Ls, children: ce }) : null
2095
2671
  ] });
2096
2672
  });
2097
2673
  export {
2098
- zr as AiTwin,
2099
- Ke as AiTwinNotFoundError,
2100
- pe as DEFAULT_TTS_ENGINE_ID,
2101
- En as OCULUS_VISEME_IDS,
2102
- Bn as SPEAKING_RATE_MAX,
2103
- Un as SPEAKING_RATE_MIN,
2104
- be as TTS_ENGINE_CARTESIA,
2105
- kt as TTS_ENGINE_GOOGLE,
2106
- Ze as TTS_ENGINE_INWORLD,
2107
- Gr as VISEME_IDS,
2108
- Nn as VISEME_TEST_CARTESIA_VOICE_ID,
2109
- At as VISEME_TEST_SPEAKING_RATE,
2110
- It as VISEME_TEST_VOICE_ID,
2111
- Vn as createAvatarTtsLipsyncController,
2112
- en as fetchAiTwin,
2113
- ot as fetchDevAuthToken,
2114
- kn as normalizeOculusViseme,
2115
- vt as resolveVisemeAtTime,
2116
- Pn as resolveWordAtTime
2674
+ qs as AiTwin,
2675
+ nt as AiTwinNotFoundError,
2676
+ Te as DEFAULT_TTS_ENGINE_ID,
2677
+ nn as MIC_SAMPLE_RATE,
2678
+ rr as OCULUS_VISEME_IDS,
2679
+ rn as PLAYBACK_SAMPLE_RATE,
2680
+ en as SPEAKING_RATE_MAX,
2681
+ Zt as SPEAKING_RATE_MIN,
2682
+ Ae as TTS_ENGINE_CARTESIA,
2683
+ Jt as TTS_ENGINE_GOOGLE,
2684
+ ut as TTS_ENGINE_INWORLD,
2685
+ Ws as VISEME_IDS,
2686
+ kr as VISEME_TEST_CARTESIA_VOICE_ID,
2687
+ ft as VISEME_TEST_SPEAKING_RATE,
2688
+ tn as VISEME_TEST_VOICE_ID,
2689
+ Tr as buildVoiceWebSocketUrl,
2690
+ Pt as createAvatarTtsLipsyncController,
2691
+ Ir as createRealtimeVoiceLipsyncController,
2692
+ Dt as faceAssetUrls,
2693
+ Un as fetchAiTwin,
2694
+ et as fetchDevAuthToken,
2695
+ ir as normalizeOculusViseme,
2696
+ zn as resolveDirectFaceId,
2697
+ lt as resolveVisemeAtTime,
2698
+ Hs as resolveWordAtTime,
2699
+ Yn as setActiveTwinAssets
2117
2700
  };