@streamoji/aitwin 0.2.9 → 0.3.1

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