@streamoji/aitwin 0.6.4 → 0.6.7

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.cjs CHANGED
@@ -1,8 +1,8 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("react/jsx-runtime"),h=require("react"),us=require("@pipecat-ai/client-js"),Hn=require("@pipecat-ai/websocket-transport"),we=require("pixi.js");var xn=typeof document<"u"?document.currentScript:null;const ds="https://aitwin.bubu.social",ri={publicBase:ds},fs="0.6.4",ms={version:fs},hs={},ht="https://ai.aitwin.me",$n=`${ri.publicBase}/custom-faces`,gs=`${ri.publicBase}/aitwin-workers/v${ms.version}/visemeDiffPreview.worker.js`;function ws(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:xn&&xn.tagName.toUpperCase()==="SCRIPT"&&xn.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?hs?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():gs}const ps="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",In=3e3,Ot=16,Er=3e3,ys=4e3,vs=.85,_s=8,jn=400,Kn="eng_a7f2b9c1",un="eng_d4e8f3a2",tt="eng_c9b1e6d4",nt="visemetts",dt=tt,dn="eve",ii=new Set([un,tt,nt]),Gn={[Kn]:"oculus_direct",[tt]:"oculus_direct",[nt]:"oculus_direct",[un]:"inworld_word"},Dn={google:Kn,inworld:un,cartesia:tt,visemetts:nt};function bs(e){const t=e.trim();if(t)return t in Gn?t:Dn[t.toLowerCase()]}function si(e){const t=e?.trim();if(!t)return{};const n=t.indexOf(":");if(n<=0)return{voiceId:t};const r=bs(t.slice(0,n));if(!r)return{voiceId:t};const i=t.slice(n+1).trim();return{ttsEngineId:r,voiceId:i||void 0}}function et(e,t){const n=si(t);return{ttsEngineId:e??n.ttsEngineId,voiceId:n.voiceId}}function ai(e){return Gn[e]}function Ss(e){return e===tt}function oi(e){return e===nt}function Ts(e){if(e.ttsEngineId&&e.ttsEngineId in Gn)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in Dn?Dn[t]:dt}class nn extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}function qn(e,...t){const n=typeof e=="string"?e:e?.brainId?.trim()||e?.knowledgeContextId?.trim();for(const r of[n,...t]){const i=r?.trim();if(i)return i}}async function ci(e,t=ps){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new nn;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const i=await r.json();if(!i.success)throw new nn(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,u=String(a.authToken??o??"").trim()||void 0,d=qn(a);return{...a,ttsEngineId:Ts(i.data),authToken:u,brainId:d,knowledgeContextId:d}}const Yn="thumbnail.webp";function li(e,t=$n){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${Yn}`}function xr(e){const t=e?.trim();if(!t)return null;try{return li(t)}catch{return null}}function ks(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${Yn}`:null}const Es="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",xs="client_6TNvp3SCs4Og0a1ijm9TommXLql1",Is="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",As="6TNvp3SCs4Og0a1ijm9TommXLql1",Ms="Swaraj Mali";async function Nt(){const e=await fetch(Es,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":xs,"Client-Secret":Is},body:JSON.stringify({userId:As,userName:Ms})});if(!e.ok)throw new Error(`getAuthToken failed (${e.status})`);const t=await e.json(),n=t.authToken??t.token??"";if(!n.trim())throw new Error("getAuthToken returned no token");return n}async function Ps(e,t=ht){const n=await fetch(`${t.replace(/\/$/,"")}/api/session-value`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new Error(`/api/session-value failed (${n.status})`);const r=await n.json();if(!r.value)throw new Error("Session value response missing value");return r}function Cs(e){const t=e.trim();if(t.length%2!==0)throw new Error("Invalid hex key");const n=new Uint8Array(t.length/2);for(let r=0;r<t.length;r+=2)n[r/2]=Number.parseInt(t.slice(r,r+2),16);return n}function Xt(e){return Uint8Array.from(e)}function Rs(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Ds(e,t){if(!t)throw new Error("Asset key is required for encrypted assets");if(e.byteLength<28)throw new Error("Encrypted payload too small");const n=new Uint8Array(e),r=Xt(n.subarray(0,12)),i=Xt(n.subarray(12,28)),s=Xt(n.subarray(28)),o=Xt(Rs(s,i)),a=await crypto.subtle.importKey("raw",Cs(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},a,o)}let Bn=null;const Fn=new Set;function Jt(e){return e.includes("/custom-faces/")}function rn(e){const t=e.binBase.trim().replace(/\/$/,""),n=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||Jt(t)||Jt(n)))return{twinBase:n,binBase:t,encrypted:!1};const i=Jt(t)?t:Jt(n)?n:t;return{twinBase:i,binBase:i,encrypted:!0}}function gt(e){return rn(e).encrypted}function Ln(e,t=$n){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function ui(e,t){return(e??t)?.trim()||void 0}function di(e){Bn=rn(e);for(const t of Fn)t()}function Bs(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return rn(e);const r=i=>{try{return new URL(i,n).href.replace(/\/$/,"")}catch{return i}};return rn({twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted})}function wt(){if(!Bn)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return Bn}function fi(e){return Fn.add(e),()=>Fn.delete(e)}function sn(){const e=wt();return gt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function Fs(){const e=wt();return gt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function mi(){const e=wt();return gt(e)?e.binBase:e.twinBase}function Wt(){return gt(wt())}function hi(){const e=wt();return gt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function gi(){const e=wt();return gt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}const ft=[{code:"en",label:"English",visemetts:!0,cartesia:!0},{code:"es",label:"Spanish",visemetts:!0,cartesia:!0},{code:"es-MX",label:"Spanish (Mexico)",visemetts:!0,cartesia:!0},{code:"es-ES",label:"Spanish (Spain)",visemetts:!0,cartesia:!0},{code:"pt",label:"Portuguese",visemetts:!0,cartesia:!0},{code:"pt-BR",label:"Portuguese (Brazil)",visemetts:!0,cartesia:!0},{code:"pt-PT",label:"Portuguese (Portugal)",visemetts:!0,cartesia:!0},{code:"fr",label:"French",visemetts:!0,cartesia:!0},{code:"de",label:"German",visemetts:!0,cartesia:!0},{code:"it",label:"Italian",visemetts:!0,cartesia:!0},{code:"zh",label:"Chinese",visemetts:!0,cartesia:!0},{code:"ja",label:"Japanese",visemetts:!0,cartesia:!0},{code:"hi",label:"Hindi",visemetts:!0,cartesia:!0},{code:"ko",label:"Korean",visemetts:!0,cartesia:!0},{code:"ru",label:"Russian",visemetts:!0,cartesia:!0},{code:"tr",label:"Turkish",visemetts:!0,cartesia:!0},{code:"id",label:"Indonesian",visemetts:!0,cartesia:!0},{code:"ar",label:"Arabic",visemetts:!0,cartesia:!0},{code:"ar-EG",label:"Arabic (Egypt)",visemetts:!0,cartesia:!0},{code:"ar-AE",label:"Arabic (UAE)",visemetts:!0,cartesia:!0},{code:"vi",label:"Vietnamese",visemetts:!0,cartesia:!0},{code:"bn",label:"Bengali",visemetts:!0,cartesia:!0},{code:"auto",label:"Auto-detect",visemetts:!0,cartesia:!1},{code:"nl",label:"Dutch",visemetts:!1,cartesia:!0},{code:"pl",label:"Polish",visemetts:!1,cartesia:!0},{code:"sv",label:"Swedish",visemetts:!1,cartesia:!0},{code:"tl",label:"Tagalog",visemetts:!1,cartesia:!0},{code:"bg",label:"Bulgarian",visemetts:!1,cartesia:!0},{code:"ro",label:"Romanian",visemetts:!1,cartesia:!0},{code:"cs",label:"Czech",visemetts:!1,cartesia:!0},{code:"el",label:"Greek",visemetts:!1,cartesia:!0},{code:"fi",label:"Finnish",visemetts:!1,cartesia:!0},{code:"hr",label:"Croatian",visemetts:!1,cartesia:!0},{code:"ms",label:"Malay",visemetts:!1,cartesia:!0},{code:"sk",label:"Slovak",visemetts:!1,cartesia:!0},{code:"da",label:"Danish",visemetts:!1,cartesia:!0},{code:"ta",label:"Tamil",visemetts:!1,cartesia:!0},{code:"uk",label:"Ukrainian",visemetts:!1,cartesia:!0},{code:"hu",label:"Hungarian",visemetts:!1,cartesia:!0},{code:"no",label:"Norwegian",visemetts:!1,cartesia:!0},{code:"th",label:"Thai",visemetts:!1,cartesia:!0},{code:"he",label:"Hebrew",visemetts:!1,cartesia:!0},{code:"ka",label:"Georgian",visemetts:!1,cartesia:!0},{code:"te",label:"Telugu",visemetts:!1,cartesia:!0},{code:"gu",label:"Gujarati",visemetts:!1,cartesia:!0},{code:"kn",label:"Kannada",visemetts:!1,cartesia:!0},{code:"ml",label:"Malayalam",visemetts:!1,cartesia:!0},{code:"mr",label:"Marathi",visemetts:!1,cartesia:!0},{code:"pa",label:"Punjabi",visemetts:!1,cartesia:!0}],wi=ft.map(e=>e.code),Ls=new Set(wi),Os=new Set(ft.filter(e=>e.visemetts).map(e=>e.code)),Ns=new Set(ft.filter(e=>e.cartesia).map(e=>e.code)),Vs="en";function pi(e){return Ls.has(e)}function fn(e){const t=e?.trim();if(t)return t}function Us(e){return e===nt?ft.filter(t=>t.visemetts).map(t=>t.code):e===tt?ft.filter(t=>t.cartesia).map(t=>t.code):ft.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Ws(e,t){const n=t.trim();return n?e===nt?Os.has(n):e===tt?Ns.has(n):pi(n):!1}function yi(e){const t=e.split(/\r?\n/);let n="",r="";for(const s of t)s.startsWith("event:")?n=s.slice(6).trim():s.startsWith("data:")&&(r=s.slice(5).trim());if(!n)return null;let i={};if(r)try{i=JSON.parse(r)}catch{i={raw:r}}return{event:n,data:i}}const vi=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],zs=new Map(vi.map(e=>[e.toLowerCase(),e]));function mn(e){const t=(e??"").trim();return t?zs.get(t.toLowerCase())??"sil":"sil"}const Hs={aei:["aa","E","I"],o:["O","U"],ee:["I"],bmp:["PP"],fv:["FF"],l:["nn"],r:["RR"],th:["TH"],qw:["U","O"],cdgknstxyz:["DD","SS","kk","CH"]};function $s(e){if(!e)return["sil"];const t=e.toLowerCase();return Hs[t]??["sil"]}function _i(e,t){const n=e.word.length;if(n<=0)return 0;const r=e.wduration;if(r<=0)return 0;const i=Math.max(0,Math.min(1,(t-e.wtime)/r));return Math.min(n-1,Math.floor(i*n))}function Et(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function hn(e,t){const n=e.toLowerCase().replace(/[^a-z']/g,"");return!n||Et(n,t)!=="w"||t>0&&Et(n,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(n)}function js(e,t){const n=e.toLowerCase(),r=Et(n,t),i=n.slice(Math.max(0,t-1),t+2);return r==="i"||r==="y"?"I":i.includes("ee")||r==="e"||n.includes("ea")?"E":"aa"}function Ks(e,t){const n=e.toLowerCase(),r=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));if(/oo|ou|uw/.test(r))return"U";if(hn(n,t))return"FF";const i=Et(n,t);return i==="u"||i==="w"?"U":"O"}function Gs(e,t){const n=e.toLowerCase();if(hn(n,t))return"FF";const r=n.slice(Math.max(0,t-2),t+1);if(/qu/.test(r))return"U";const i=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));return/wo|wh/.test(i)||Et(n,t)==="o"?"O":"U"}const Zt={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function qs(e,t){const n=e.toLowerCase(),r=Et(n,t);if(Zt[r])return Zt[r];for(let i=0;i<n.length;i++){const s=n[i];if(Zt[s])return Zt[s]}return"DD"}function bi(e,t,n){const r=$s(e);if(r.length===1)return r[0];const i=t.trim();if(!i)return r[0];const s=(e??"").toLowerCase(),o=Math.max(0,n);switch(s){case"aei":return js(i,o);case"o":return Ks(i,o);case"qw":return Gs(i,o);case"cdgknstxyz":return qs(i,o);default:return r[0]}}const Qn=16,On=47,Si=new Set(["aa","E","I"]),Ti=new Set(["DD","SS","kk","CH"]),Ys=[Si,Ti];function Qs(e){for(const t of Ys)if(t.has(e))return t;return null}function Xs(e){return Qs(e)!=null}function ki(e,t=Qn){return t<=0?e:Math.round(e/t)*t}function Xn(e,t=Qn){return e.map(n=>({...n,vtime:ki(n.vtime,t)}))}function Ei(e){const t=new Map;for(const n of e)t.has(n.vtime)||t.set(n.vtime,n);return[...t.values()].sort((n,r)=>n.vtime-r.vtime)}function Jn(e){if(e.length<=2)return[...e];const t=[e[0]];for(let n=1;n<e.length-1;n++){const r=e[n],i=e[n+1],s=t[t.length-1];if(!Xs(r.viseme)){t.push(r);continue}const o=r.vtime-s.vtime,a=i.vtime-r.vtime;o<On||a<On||t.push(r)}return t.push(e[e.length-1]),t}function gn(e){return Jn(Ei(Xn(e)))}function xi(e,t){let n="sil";for(const r of e){if(r.vtime>t)break;r.viseme!=="sil"&&(n=r.viseme)}return n}function wn(e){const t=Ei(Xn(e)),n=Jn(t),r=new Set(n.map(s=>s.vtime)),i=[];for(const s of t)r.has(s.vtime)||i.push({viseme:s.viseme,vtime:s.vtime});return i}function Js(e){return wn(e).map(t=>t.viseme)}const Zs=32,Ir=48;function Ii(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}function Ai(e){let t=null,n=-1;for(const r of e){if(r.viseme==="sil")continue;const i=r.vtime+r.vduration;i>n&&(t=r,n=i)}return t}function ea(e){return gn(e).find(n=>n.viseme!=="sil")??null}function lt(e){const t=Ii(e);return Ai(e)?t+jn:t}function ta(e){const t=[],n=ea(e);n&&n.vtime>0&&t.push({from:"sil",to:n.viseme,fromVtime:0,toVtime:n.vtime});const r=Ai(e),i=Ii(e);return r&&t.push({from:r.viseme,to:"sil",fromVtime:i,toVtime:i+jn}),t}function Mi(e){const t=gn(e),n=[];for(let r=0;r<t.length-1;r++){const i=t[r].viseme,s=t[r+1].viseme,o=t[r].vtime,a=t[r+1].vtime;i===s||a<=o||n.push({from:i,to:s,fromVtime:o,toVtime:a})}return n}function Pi(e){return e.length===0?[]:[...ta(e),...Mi(e)]}function na(e,t){let n=null;for(const r of e){const{transStart:i,transEnd:s}=Ci(r.fromVtime,r.toVtime,r.from,r.to);t>=i&&t<s&&(n=r)}return n}function Ci(e,t,n,r){const i=Math.max(0,t-e);if((n==="PP"||r==="PP")&&i>Ir){const d=Ir,l=t,c=l-d;return{gapMs:i,effectiveGapMs:d,holdEnd:c,transStart:c,transEnd:l}}const o=i>0?Math.max(i,Zs):0,a=e,u=e+o;return{gapMs:i,effectiveGapMs:o,holdEnd:e,transStart:a,transEnd:u}}function Ri(e,t,n,r,i,s){r.forEach(o=>{const u=String(o.word??"").trim();if(!u)return;const d=Math.round((o.start??0)*1e3),l=o.duration!=null?Math.round(o.duration*1e3):o.end!=null?Math.max(1,Math.round((o.end-(o.start??0))*1e3)):0;t.push({word:u,wtime:i+d,wduration:l,queueIndex:t.length,gesture:o.gesture??null,emphasis:o.emphasis===!0})}),n.forEach(o=>{const a=String(o.symbol??o.viseme??"").trim();if(!a)return;const u=Math.round((o.start??0)*1e3),d=Math.max(1,Math.round((o.duration??0)*1e3)),l=i+u,c=Fi(t,l),m=c?_i(c,l):0;let w;ai(s)==="oculus_direct"?(w=mn(a),w==="U"&&c&&hn(c.word,m)&&(w="FF")):w=bi(a,c?.word??"",m),e.push({viseme:w,weight:1,vtime:l,vduration:d})})}function Di(e,t){let n=t;for(const r of e){const i=Math.round((r.start??0)*1e3),s=Math.max(1,Math.round((r.duration??0)*1e3));n=Math.max(n,t+i+s)}return n}const Zn=16e3;function Bi(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:Zn}function ra(e){let t=e.trim();const n=t.indexOf(",");t.startsWith("data:")&&n>=0&&(t=t.slice(n+1)),t=t.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/");const r=t.length%4;return r!==0&&(t+="=".repeat(4-r)),t}function ia(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function Ar(e,t,n=Zn){const r=t.byteOffset%2===0?t:t.slice(),i=new Int16Array(r.buffer,r.byteOffset,r.byteLength/2),s=new Float32Array(i.length);for(let a=0;a<i.length;a++)s[a]=i[a]>=32768?-(65536-i[a])/32768:i[a]/32767;const o=e.createBuffer(1,s.length,n);return o.copyToChannel(s,0),o}function sa(e){const t=ra(e),n=window.atob(t),r=new Uint8Array(n.length);for(let i=0;i<n.length;i++)r[i]=n.charCodeAt(i);return r}async function Mr(e,t,n=Zn){const r=sa(t),i=Bi(n);if(ia(r)){const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return e.decodeAudioData(s)}if(r.length>=2&&r.length%2===0)return Ar(e,r,i);try{const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return await e.decodeAudioData(s)}catch{return Ar(e,r,i)}}function Fi(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Li(e,t){const n=[],r=[];let i=null,s=!1,o=!1,a=!1,u=!1,d=0,l=0,c=0,m=null,w=1,T=t,f=!1,E=null,D=0,B=!1,v=!1,k=0,L=null,A=null,ie=null;const de=()=>({visemes:[],words:[],segmentOffsetMs:0}),I=()=>{v=!1,k=0},V=()=>{m!=null&&(clearTimeout(m),m=null)},G=()=>{for(const b of r){try{b.onended=null,b.stop(0)}catch{}try{b.disconnect()}catch{}}r.length=0},ae=()=>{for(const b of r)b.playbackRate.value=w},se=()=>{if(!(f||!u||s||v||r.length>0||n.length>0)){if(a&&i&&l>0){const b=(i.currentTime-l)*1e3;if(b<D){V();const P=w>0?(D-b)/w:D-b;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,P));return}}o=!1,V(),e.onSpeakingDone(),e.onNotify()}},re=b=>{const P=lt(b);if(P<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,d=performance.now(),e.onSpeakingStart(),e.onNotify(),V();const H=w>0?P/w:P;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},H)},O=(b,P,H,le)=>{P.length!==0&&(c=H,P.forEach(j=>{const p=String(j.word??"").trim();if(!p)return;const S=Math.round((j.start??0)*1e3),x=j.duration!=null?Math.round(j.duration*1e3):j.end!=null?Math.max(1,Math.round((j.end-(j.start??0))*1e3)):0;b.push({word:p,wtime:c+S,wduration:x,queueIndex:b.length,gesture:j.gesture??null,emphasis:j.emphasis===!0})}))},J=(b,P,H,le,j,q)=>{H.length!==0&&(c=le,H.forEach(p=>{const S=String(p.symbol??p.viseme??"").trim();if(!S)return;const x=Math.round((p.start??0)*1e3),_=Math.max(1,Math.round((p.duration??0)*1e3)),U=c+x,Z=Fi(P,U),te=Z?_i(Z,U):0;let z;ai(q)==="oculus_direct"?(z=mn(S),z==="U"&&Z&&hn(Z.word,te)&&(z="FF")):z=bi(S,Z?.word??"",te),b.push({viseme:z,weight:1,vtime:U,vduration:_})}),e.onNotify())},W=(b,P,H,le,j,q,p)=>{O(P,le,j),J(b,P,H,j,q,p)},he=(b,P,H)=>{ie===b&&b.visemes===P||(P.length=0,H.length=0,b.visemes=P,b.words=H,b.segmentOffsetMs=0,ie=b,c=0,D=0)},K=async()=>{const b=window.AudioContext||window.webkitAudioContext;return i||(i=new b),i.state==="suspended"&&await i.resume(),E||(E=i.createMediaStreamDestination()),i},ee=(b,P)=>{if(!i)return 0;const H=i,le=H.currentTime,j=le+.02;if(P.isFirstAudio){l<=0&&(l=j);const p=(j-le)*1e3;d=performance.now()+p}P.onBeforeStart?.(j);const q=H.createBufferSource();return q.buffer=b,q.playbackRate.value=w,q.connect(H.destination),E&&q.connect(E),r.push(q),f?(r.pop(),j):(P.isFirstAudio&&(o=!0,e.onSpeakingStart()),q.onended=()=>{const p=r.indexOf(q);p>=0&&r.splice(p,1),e.onNotify(),!f&&(L&&A?$(L,A):se())},q.start(j),j)},$=async(b,P)=>{if(f||s||r.length>0)return;if(n.length===0){se();return}s=!0;let H=!1;try{const le=await K();if(f)return;const j=n[0];if(!j)return;const q=!o;if(B&&(e.shouldHoldForWarmup?.()??!1)&&(v||q&&j.newStream)||v){he(j.utterance,b,P);for(const x of n){if(f)return;x.audioBuffer||(x.audioBuffer=await Mr(le,x.audio,x.sampleRate)),a=!0,v||(v=!0,k=0,x.newStream&&x.onNewStream?.()),x.visemesQueued||(W(b,P,x.visemes,x.words,k,!0,T),x.visemesQueued=!0,k+=Math.round(x.audioBuffer.duration*1e3),D=Math.max(D,lt(b)))}e.onNotify();return}const S=n.shift();if(!S||(S.audioBuffer||(S.audioBuffer=await Mr(le,S.audio,S.sampleRate)),f))return;a=!0,V(),he(S.utterance,b,P),S.visemesQueued=!1,S.newStream&&S.onNewStream?.(),ee(S.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:x=>{l=x,c=0,d=performance.now()+(x-le.currentTime)*1e3,b.length=0,P.length=0,W(b,P,S.visemes,S.words,0,!0,T),S.visemesQueued=!0,S.utterance.segmentOffsetMs=0}}),H=r.length>0,D=lt(b),e.onNotify()}catch(le){console.error("[avatarChunkPlayback] audio chunk failed:",le)}finally{if(s=!1,f)return;if(v){n.some(j=>!j.audioBuffer||!j.visemesQueued)&&$(b,P);return}!H&&r.length===0&&n.length>0?$(b,P):r.length===0&&n.length===0&&se()}};return{setStreamTtsEngineId:b=>{T=b},setPlaybackSpeed:b=>{w=Math.max(.1,Math.min(1,b)),ae()},getPlaybackSpeed:()=>w,setLipsyncWarmupHoldEnabled:b=>{B=b,b||I()},isWarmingUp:()=>v,releaseWarmupHold:()=>{if(v){v=!1,k=0;for(const b of n)b.newStream=!1;L&&A&&$(L,A),e.onNotify()}},resetForNewStream:b=>{f=!1,u=!1,T=b,D=0},resumeBotStream:()=>{f=!1,u=!1},clearAborted:()=>{f=!1},primeAudioContext:async()=>{const b=window.AudioContext||window.webkitAudioContext;i||(i=new b),i.state==="suspended"&&await i.resume(),i&&!E&&(E=i.createMediaStreamDestination())},stop:()=>{f=!0,V(),G(),n.length=0,s=!1,o=!1,a=!1,u=!1,c=0,l=0,d=0,D=0,L=null,A=null,ie=null,I()},markStreamComplete:b=>{if(D=Math.max(D,lt(b)),u=!0,!a&&b.length>0){re(b);return}se()},playAudioChunk:async(b,P,H,le,j,q,p)=>{if(f)return;L=b,A=P;const S=Bi(p?.sampleRate),x=p?.newStream===!0,_=de();if(!H?.trim()){if(le.length===0&&j.length===0)return;he(_,b,P),x&&p?.onNewStream?.(),W(b,P,le,j,0,!0,T),D=lt(b),!o&&D>0&&re(b),e.onNotify();return}n.push({audio:H,audioBuffer:null,utterance:_,visemes:le,words:j,isNewSegment:q,sampleRate:S,newStream:x,onNewStream:p?.onNewStream,visemesQueued:!1}),await $(b,P)},queueTimingsOnly:(b,P,H,le,j,q)=>{if(f)return;const p=de();he(p,b,P),W(b,P,H,le,0,!0,T),p.segmentOffsetMs=0,D=lt(b)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*w):o?Math.max(0,(performance.now()-d)*w):0,isSpeaking:()=>o?!0:!a||!i||l<=0?!1:(i.currentTime-l)*1e3<D,getVoiceStream:()=>E?E.stream:null,getPlaybackStartPerf:()=>d,bargeIn:()=>{f=!0,u=!1,V(),G(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,L=null,A=null,ie=null,I()},interrupt:()=>{f=!0,u=!1,V(),G(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,L=null,A=null,ie=null,I()}}}function zt(e,t){let n=null;for(const r of e)t<r.vtime||t>=r.vtime+r.vduration||(!n||r.vtime>=n.vtime)&&(n=r);return n?n.viseme:"sil"}function Oi(e,t,n=120){const r=zt(e,t);if(r!=="sil")return r;let i=null;for(const s of e){if(s.vtime>t)break;const o=s.vtime+s.vduration;o<=t&&t-o<=n&&(i=s)}return i?.viseme??"sil"}function aa(e,t,n=400){const r=t-n;let i=0;for(const s of e)if(s.vtime+s.vduration<r)i+=1;else break;i>0&&e.splice(0,i)}function oa(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Pr(e,t){const n=e.trim();if(!n)return null;try{const r=n.replace(/\s+/g,""),i=atob(r).length,s=Number.isFinite(t)&&(t??0)>0?Number(t):16e3;return i/2/s*1e3}catch{return null}}const pn=.5,yn=1.5,er="Olivia",tr="f786b574-daa5-4673-aa0c-cbe3e8534c02",Ht=.85;function Nn(e,t=ht,n={}){const r=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let u=0;const d=[],l=[];let c="",m="neutral",w="",T=dt;const f=new Set;let E=0,D=null,B=0,v=null;const k=()=>f.forEach(O=>O());let L=()=>!1;const A=Li({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:k,shouldHoldForWarmup:()=>L()},dt),ie=()=>A.getPlaybackElapsedMs(),de=(O,J=c)=>{if(!n.onLipsyncDebug)return;const W=ie(),he=i,K=wn(o).map(ee=>({viseme:ee.viseme,vtimeMs:ee.vtime}));n.onLipsyncDebug({event:O,spokenText:J,mood:m,playbackAnchorPerf:A.getPlaybackStartPerf(),playbackElapsedMs:W,queueLength:he.length,activeViseme:zt(he,W),segments:l.map(ee=>({...ee,visemes:[...ee.visemes]})),fullQueueLength:o.length,compactionSkipped:K})},I=(O,J)=>{n.onLipsyncDebug&&(D={event:O,spokenText:J},E===0&&(E=requestAnimationFrame(()=>{E=0;const W=D;D=null,W&&de(W.event,W.spokenText)})))},V=(O,J,W,he,K)=>{if(!n.onLipsyncDebug)return;const ee=i.slice(J),$=W.filter(X=>String(X.symbol??X.viseme??"").trim());l.push({spokenText:O,audioOffsetMs:ee[0]?.vtime??0,isNewSegment:he,chunkDurationMs:K,receivedAtMs:performance.now(),visemes:ee.map((X,_e)=>{const oe=$[_e];return{rawSymbol:String(oe?.symbol??oe?.viseme??X.viseme).trim(),viseme:X.viseme,startSec:Number(oe?.start??0),durationSec:Number(oe?.duration??0),vtimeMs:X.vtime,vdurationMs:X.vduration}})})},G=()=>{o.length=0,a.length=0,u=0},ae=(O,J,W,he,K)=>{if(O.length===0&&J.length===0)return;Ri(o,a,O,J,u,K);const ee=Di(O,u),$=W?Pr(W,he):null;u=Math.max(ee,$!=null?u+$:u)},se=()=>{B+=1,v?.abort(),v=null,A.stop(),i.length=0,s.length=0,G(),d.length=0,m="neutral",l.length=0,c="",e("idle"),I("reset"),k()};return{setDeveloperToken:O=>{w=O},setTtsEngineId:O=>{T=O},getTtsEngineId:()=>T,speak:async(O,J)=>{se();const W=B;v=new AbortController,e("loading"),c=O,l.length=0,G();const he=w.trim();if(!he)throw new Error("Developer token required for avatar_ttsWithPoses");const K=et(J?.ttsEngineId,J?.voiceId),ee=K.ttsEngineId??T??dt;A.resetForNewStream(ee),A.setStreamTtsEngineId(ee);const $=K.voiceId??(ee===nt?dn:er),X=J?.speakingRate??Ht,_e=Math.max(pn,Math.min(yn,X)),oe={user_query:O,ttsEngineId:ee,speakingRate:_e,tenant:"aiTwin"};ii.has(ee)&&(oe.voice_id=$);const b=fn(J?.language);b&&(oe.language=b);try{const P=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${he}`},body:JSON.stringify(oe),signal:v.signal});if(!P.ok)throw new Error(`avatar_ttsWithPoses failed (${P.status})`);const H=P.body;if(!H)throw new Error("No response body");const le=H.getReader(),j=new TextDecoder;let q="",p=!0;const S=async x=>{if(W!==B)return;const _=yi(x);if(_){if(_.event==="audio"){const U=_.data.chunk,Z=_.data.visemes??[],te=_.data.words??[],z=_.data.is_new_segment??!1,be=_.data.sample_rate,Xe=Number(_.data.audio_offset_ms??0),Pt=i.length;if(ae(Z,te,U,be,ee),U){const pt=p;p=!1,await A.playAudioChunk(i,s,U,Z,te,z,{sampleRate:be,newStream:pt,audioOffsetMs:Xe}),V(O,Pt,Z,z,Pr(U,be)),I("audio_chunk",O)}else(Z.length>0||te.length>0)&&(A.queueTimingsOnly(i,s,Z,te,z,{audioOffsetMs:Xe,newStream:p}),V(O,Pt,Z,z,null),I("audio_chunk",O))}else if(_.event==="metadata"){const U=_.data.mood;typeof U=="string"&&U.trim()&&(m=U.trim());const Z=_.data.sentence_emotions;if(Array.isArray(Z)){d.length=0;for(const te of Z){if(!te||typeof te!="object")continue;const z=te;d.push({sentence_index:Number(z.sentence_index??0),text:String(z.text??""),sentiment:typeof z.sentiment=="string"?z.sentiment:void 0,emotion:String(z.emotion??m),start_word:Number(z.start_word??0),end_word:Number(z.end_word??0)})}}k(),I("metadata",O)}else if(_.event==="error")throw new Error(String(_.data.message??"avatar_ttsWithPoses stream error"))}};for(;W===B;){const{done:x,value:_}=await le.read();_&&(q+=j.decode(_,{stream:!0}));const U=q.split(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("react/jsx-runtime"),h=require("react"),ds=require("@pipecat-ai/client-js"),Hn=require("@pipecat-ai/websocket-transport"),we=require("pixi.js");var xn=typeof document<"u"?document.currentScript:null;const fs="https://aitwin.bubu.social",ii={publicBase:fs},ms="0.6.7",hs={version:ms},gs={},gt="https://ai.aitwin.me",$n=`${ii.publicBase}/custom-faces`,ws=`${ii.publicBase}/aitwin-workers/v${hs.version}/visemeDiffPreview.worker.js`;function ps(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:xn&&xn.tagName.toUpperCase()==="SCRIPT"&&xn.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?gs?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():ws}const ys="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",In=3e3,Ot=16,xr=3e3,vs=4e3,_s=.85,bs=8,jn=400,Kn="eng_a7f2b9c1",un="eng_d4e8f3a2",tt="eng_c9b1e6d4",nt="visemetts",ft=tt,dn="eve",si=new Set([un,tt,nt]),Gn={[Kn]:"oculus_direct",[tt]:"oculus_direct",[nt]:"oculus_direct",[un]:"inworld_word"},Dn={google:Kn,inworld:un,cartesia:tt,visemetts:nt};function Ss(e){const t=e.trim();if(t)return t in Gn?t:Dn[t.toLowerCase()]}function ai(e){const t=e?.trim();if(!t)return{};const n=t.indexOf(":");if(n<=0)return{voiceId:t};const r=Ss(t.slice(0,n));if(!r)return{voiceId:t};const i=t.slice(n+1).trim();return{ttsEngineId:r,voiceId:i||void 0}}function et(e,t){const n=ai(t);return{ttsEngineId:e??n.ttsEngineId,voiceId:n.voiceId}}function oi(e){return Gn[e]}function Ts(e){return e===tt}function ci(e){return e===nt}function ks(e){if(e.ttsEngineId&&e.ttsEngineId in Gn)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in Dn?Dn[t]:ft}class nn extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}function qn(e,...t){const n=typeof e=="string"?e:e?.brainId?.trim()||e?.knowledgeContextId?.trim();for(const r of[n,...t]){const i=r?.trim();if(i)return i}}function Yn(e,...t){const n=typeof e=="string"?e:e?.brainUrl?.trim();for(const r of[n,...t]){const i=r?.trim();if(i)return i}}function Es(e){const t=(e??"").trim();if(!t)return;let n;try{n=new URL(t)}catch{throw new Error("brainUrl must be an http or https URL")}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error("brainUrl must be an http or https URL");if(!n.host)throw new Error("brainUrl must be an http or https URL");if(n.hash)throw new Error("brainUrl must not include a fragment");return t}async function li(e,t=ys){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new nn;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const i=await r.json();if(!i.success)throw new nn(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,u=String(a.authToken??o??"").trim()||void 0,d=qn(a),l=Yn(a);return{...a,ttsEngineId:ks(i.data),authToken:u,brainId:d,knowledgeContextId:d,brainUrl:l}}const Qn="thumbnail.webp";function ui(e,t=$n){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${Qn}`}function Ir(e){const t=e?.trim();if(!t)return null;try{return ui(t)}catch{return null}}function xs(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${Qn}`:null}const Is="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",As="client_6TNvp3SCs4Og0a1ijm9TommXLql1",Ms="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",Ps="6TNvp3SCs4Og0a1ijm9TommXLql1",Rs="Swaraj Mali";async function Nt(){const e=await fetch(Is,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":As,"Client-Secret":Ms},body:JSON.stringify({userId:Ps,userName:Rs})});if(!e.ok)throw new Error(`getAuthToken failed (${e.status})`);const t=await e.json(),n=t.authToken??t.token??"";if(!n.trim())throw new Error("getAuthToken returned no token");return n}async function Cs(e,t=gt){const n=await fetch(`${t.replace(/\/$/,"")}/api/session-value`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new Error(`/api/session-value failed (${n.status})`);const r=await n.json();if(!r.value)throw new Error("Session value response missing value");return r}function Ds(e){const t=e.trim();if(t.length%2!==0)throw new Error("Invalid hex key");const n=new Uint8Array(t.length/2);for(let r=0;r<t.length;r+=2)n[r/2]=Number.parseInt(t.slice(r,r+2),16);return n}function Xt(e){return Uint8Array.from(e)}function Bs(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Fs(e,t){if(!t)throw new Error("Asset key is required for encrypted assets");if(e.byteLength<28)throw new Error("Encrypted payload too small");const n=new Uint8Array(e),r=Xt(n.subarray(0,12)),i=Xt(n.subarray(12,28)),s=Xt(n.subarray(28)),o=Xt(Bs(s,i)),a=await crypto.subtle.importKey("raw",Ds(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},a,o)}let Bn=null;const Fn=new Set;function Jt(e){return e.includes("/custom-faces/")}function rn(e){const t=e.binBase.trim().replace(/\/$/,""),n=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||Jt(t)||Jt(n)))return{twinBase:n,binBase:t,encrypted:!1};const i=Jt(t)?t:Jt(n)?n:t;return{twinBase:i,binBase:i,encrypted:!0}}function wt(e){return rn(e).encrypted}function Ln(e,t=$n){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function di(e,t){return(e??t)?.trim()||void 0}function fi(e){Bn=rn(e);for(const t of Fn)t()}function Ls(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return rn(e);const r=i=>{try{return new URL(i,n).href.replace(/\/$/,"")}catch{return i}};return rn({twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted})}function pt(){if(!Bn)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return Bn}function mi(e){return Fn.add(e),()=>Fn.delete(e)}function sn(){const e=pt();return wt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function Os(){const e=pt();return wt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function hi(){const e=pt();return wt(e)?e.binBase:e.twinBase}function Wt(){return wt(pt())}function gi(){const e=pt();return wt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function wi(){const e=pt();return wt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}const mt=[{code:"en",label:"English",visemetts:!0,cartesia:!0},{code:"es",label:"Spanish",visemetts:!0,cartesia:!0},{code:"es-MX",label:"Spanish (Mexico)",visemetts:!0,cartesia:!0},{code:"es-ES",label:"Spanish (Spain)",visemetts:!0,cartesia:!0},{code:"pt",label:"Portuguese",visemetts:!0,cartesia:!0},{code:"pt-BR",label:"Portuguese (Brazil)",visemetts:!0,cartesia:!0},{code:"pt-PT",label:"Portuguese (Portugal)",visemetts:!0,cartesia:!0},{code:"fr",label:"French",visemetts:!0,cartesia:!0},{code:"de",label:"German",visemetts:!0,cartesia:!0},{code:"it",label:"Italian",visemetts:!0,cartesia:!0},{code:"zh",label:"Chinese",visemetts:!0,cartesia:!0},{code:"ja",label:"Japanese",visemetts:!0,cartesia:!0},{code:"hi",label:"Hindi",visemetts:!0,cartesia:!0},{code:"ko",label:"Korean",visemetts:!0,cartesia:!0},{code:"ru",label:"Russian",visemetts:!0,cartesia:!0},{code:"tr",label:"Turkish",visemetts:!0,cartesia:!0},{code:"id",label:"Indonesian",visemetts:!0,cartesia:!0},{code:"ar",label:"Arabic",visemetts:!0,cartesia:!0},{code:"ar-EG",label:"Arabic (Egypt)",visemetts:!0,cartesia:!0},{code:"ar-AE",label:"Arabic (UAE)",visemetts:!0,cartesia:!0},{code:"vi",label:"Vietnamese",visemetts:!0,cartesia:!0},{code:"bn",label:"Bengali",visemetts:!0,cartesia:!0},{code:"auto",label:"Auto-detect",visemetts:!0,cartesia:!1},{code:"nl",label:"Dutch",visemetts:!1,cartesia:!0},{code:"pl",label:"Polish",visemetts:!1,cartesia:!0},{code:"sv",label:"Swedish",visemetts:!1,cartesia:!0},{code:"tl",label:"Tagalog",visemetts:!1,cartesia:!0},{code:"bg",label:"Bulgarian",visemetts:!1,cartesia:!0},{code:"ro",label:"Romanian",visemetts:!1,cartesia:!0},{code:"cs",label:"Czech",visemetts:!1,cartesia:!0},{code:"el",label:"Greek",visemetts:!1,cartesia:!0},{code:"fi",label:"Finnish",visemetts:!1,cartesia:!0},{code:"hr",label:"Croatian",visemetts:!1,cartesia:!0},{code:"ms",label:"Malay",visemetts:!1,cartesia:!0},{code:"sk",label:"Slovak",visemetts:!1,cartesia:!0},{code:"da",label:"Danish",visemetts:!1,cartesia:!0},{code:"ta",label:"Tamil",visemetts:!1,cartesia:!0},{code:"uk",label:"Ukrainian",visemetts:!1,cartesia:!0},{code:"hu",label:"Hungarian",visemetts:!1,cartesia:!0},{code:"no",label:"Norwegian",visemetts:!1,cartesia:!0},{code:"th",label:"Thai",visemetts:!1,cartesia:!0},{code:"he",label:"Hebrew",visemetts:!1,cartesia:!0},{code:"ka",label:"Georgian",visemetts:!1,cartesia:!0},{code:"te",label:"Telugu",visemetts:!1,cartesia:!0},{code:"gu",label:"Gujarati",visemetts:!1,cartesia:!0},{code:"kn",label:"Kannada",visemetts:!1,cartesia:!0},{code:"ml",label:"Malayalam",visemetts:!1,cartesia:!0},{code:"mr",label:"Marathi",visemetts:!1,cartesia:!0},{code:"pa",label:"Punjabi",visemetts:!1,cartesia:!0}],pi=mt.map(e=>e.code),Ns=new Set(pi),Us=new Set(mt.filter(e=>e.visemetts).map(e=>e.code)),Vs=new Set(mt.filter(e=>e.cartesia).map(e=>e.code)),Ws="en";function yi(e){return Ns.has(e)}function fn(e){const t=e?.trim();if(t)return t}function zs(e){return e===nt?mt.filter(t=>t.visemetts).map(t=>t.code):e===tt?mt.filter(t=>t.cartesia).map(t=>t.code):mt.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Hs(e,t){const n=t.trim();return n?e===nt?Us.has(n):e===tt?Vs.has(n):yi(n):!1}function vi(e){const t=e.split(/\r?\n/);let n="",r="";for(const s of t)s.startsWith("event:")?n=s.slice(6).trim():s.startsWith("data:")&&(r=s.slice(5).trim());if(!n)return null;let i={};if(r)try{i=JSON.parse(r)}catch{i={raw:r}}return{event:n,data:i}}const _i=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],$s=new Map(_i.map(e=>[e.toLowerCase(),e]));function mn(e){const t=(e??"").trim();return t?$s.get(t.toLowerCase())??"sil":"sil"}const js={aei:["aa","E","I"],o:["O","U"],ee:["I"],bmp:["PP"],fv:["FF"],l:["nn"],r:["RR"],th:["TH"],qw:["U","O"],cdgknstxyz:["DD","SS","kk","CH"]};function Ks(e){if(!e)return["sil"];const t=e.toLowerCase();return js[t]??["sil"]}function bi(e,t){const n=e.word.length;if(n<=0)return 0;const r=e.wduration;if(r<=0)return 0;const i=Math.max(0,Math.min(1,(t-e.wtime)/r));return Math.min(n-1,Math.floor(i*n))}function xt(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function hn(e,t){const n=e.toLowerCase().replace(/[^a-z']/g,"");return!n||xt(n,t)!=="w"||t>0&&xt(n,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(n)}function Gs(e,t){const n=e.toLowerCase(),r=xt(n,t),i=n.slice(Math.max(0,t-1),t+2);return r==="i"||r==="y"?"I":i.includes("ee")||r==="e"||n.includes("ea")?"E":"aa"}function qs(e,t){const n=e.toLowerCase(),r=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));if(/oo|ou|uw/.test(r))return"U";if(hn(n,t))return"FF";const i=xt(n,t);return i==="u"||i==="w"?"U":"O"}function Ys(e,t){const n=e.toLowerCase();if(hn(n,t))return"FF";const r=n.slice(Math.max(0,t-2),t+1);if(/qu/.test(r))return"U";const i=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));return/wo|wh/.test(i)||xt(n,t)==="o"?"O":"U"}const Zt={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function Qs(e,t){const n=e.toLowerCase(),r=xt(n,t);if(Zt[r])return Zt[r];for(let i=0;i<n.length;i++){const s=n[i];if(Zt[s])return Zt[s]}return"DD"}function Si(e,t,n){const r=Ks(e);if(r.length===1)return r[0];const i=t.trim();if(!i)return r[0];const s=(e??"").toLowerCase(),o=Math.max(0,n);switch(s){case"aei":return Gs(i,o);case"o":return qs(i,o);case"qw":return Ys(i,o);case"cdgknstxyz":return Qs(i,o);default:return r[0]}}const Xn=16,On=47,Ti=new Set(["aa","E","I"]),ki=new Set(["DD","SS","kk","CH"]),Xs=[Ti,ki];function Js(e){for(const t of Xs)if(t.has(e))return t;return null}function Zs(e){return Js(e)!=null}function Ei(e,t=Xn){return t<=0?e:Math.round(e/t)*t}function Jn(e,t=Xn){return e.map(n=>({...n,vtime:Ei(n.vtime,t)}))}function xi(e){const t=new Map;for(const n of e)t.has(n.vtime)||t.set(n.vtime,n);return[...t.values()].sort((n,r)=>n.vtime-r.vtime)}function Zn(e){if(e.length<=2)return[...e];const t=[e[0]];for(let n=1;n<e.length-1;n++){const r=e[n],i=e[n+1],s=t[t.length-1];if(!Zs(r.viseme)){t.push(r);continue}const o=r.vtime-s.vtime,a=i.vtime-r.vtime;o<On||a<On||t.push(r)}return t.push(e[e.length-1]),t}function gn(e){return Zn(xi(Jn(e)))}function Ii(e,t){let n="sil";for(const r of e){if(r.vtime>t)break;r.viseme!=="sil"&&(n=r.viseme)}return n}function wn(e){const t=xi(Jn(e)),n=Zn(t),r=new Set(n.map(s=>s.vtime)),i=[];for(const s of t)r.has(s.vtime)||i.push({viseme:s.viseme,vtime:s.vtime});return i}function ea(e){return wn(e).map(t=>t.viseme)}const ta=32,Ar=48;function Ai(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}function Mi(e){let t=null,n=-1;for(const r of e){if(r.viseme==="sil")continue;const i=r.vtime+r.vduration;i>n&&(t=r,n=i)}return t}function na(e){return gn(e).find(n=>n.viseme!=="sil")??null}function ut(e){const t=Ai(e);return Mi(e)?t+jn:t}function ra(e){const t=[],n=na(e);n&&n.vtime>0&&t.push({from:"sil",to:n.viseme,fromVtime:0,toVtime:n.vtime});const r=Mi(e),i=Ai(e);return r&&t.push({from:r.viseme,to:"sil",fromVtime:i,toVtime:i+jn}),t}function Pi(e){const t=gn(e),n=[];for(let r=0;r<t.length-1;r++){const i=t[r].viseme,s=t[r+1].viseme,o=t[r].vtime,a=t[r+1].vtime;i===s||a<=o||n.push({from:i,to:s,fromVtime:o,toVtime:a})}return n}function Ri(e){return e.length===0?[]:[...ra(e),...Pi(e)]}function ia(e,t){let n=null;for(const r of e){const{transStart:i,transEnd:s}=Ci(r.fromVtime,r.toVtime,r.from,r.to);t>=i&&t<s&&(n=r)}return n}function Ci(e,t,n,r){const i=Math.max(0,t-e);if((n==="PP"||r==="PP")&&i>Ar){const d=Ar,l=t,c=l-d;return{gapMs:i,effectiveGapMs:d,holdEnd:c,transStart:c,transEnd:l}}const o=i>0?Math.max(i,ta):0,a=e,u=e+o;return{gapMs:i,effectiveGapMs:o,holdEnd:e,transStart:a,transEnd:u}}function Di(e,t,n,r,i,s){r.forEach(o=>{const u=String(o.word??"").trim();if(!u)return;const d=Math.round((o.start??0)*1e3),l=o.duration!=null?Math.round(o.duration*1e3):o.end!=null?Math.max(1,Math.round((o.end-(o.start??0))*1e3)):0;t.push({word:u,wtime:i+d,wduration:l,queueIndex:t.length,gesture:o.gesture??null,emphasis:o.emphasis===!0})}),n.forEach(o=>{const a=String(o.symbol??o.viseme??"").trim();if(!a)return;const u=Math.round((o.start??0)*1e3),d=Math.max(1,Math.round((o.duration??0)*1e3)),l=i+u,c=Li(t,l),m=c?bi(c,l):0;let w;oi(s)==="oculus_direct"?(w=mn(a),w==="U"&&c&&hn(c.word,m)&&(w="FF")):w=Si(a,c?.word??"",m),e.push({viseme:w,weight:1,vtime:l,vduration:d})})}function Bi(e,t){let n=t;for(const r of e){const i=Math.round((r.start??0)*1e3),s=Math.max(1,Math.round((r.duration??0)*1e3));n=Math.max(n,t+i+s)}return n}const er=16e3;function Fi(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:er}function sa(e){let t=e.trim();const n=t.indexOf(",");t.startsWith("data:")&&n>=0&&(t=t.slice(n+1)),t=t.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/");const r=t.length%4;return r!==0&&(t+="=".repeat(4-r)),t}function aa(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function Mr(e,t,n=er){const r=t.byteOffset%2===0?t:t.slice(),i=new Int16Array(r.buffer,r.byteOffset,r.byteLength/2),s=new Float32Array(i.length);for(let a=0;a<i.length;a++)s[a]=i[a]>=32768?-(65536-i[a])/32768:i[a]/32767;const o=e.createBuffer(1,s.length,n);return o.copyToChannel(s,0),o}function oa(e){const t=sa(e),n=window.atob(t),r=new Uint8Array(n.length);for(let i=0;i<n.length;i++)r[i]=n.charCodeAt(i);return r}async function Pr(e,t,n=er){const r=oa(t),i=Fi(n);if(aa(r)){const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return e.decodeAudioData(s)}if(r.length>=2&&r.length%2===0)return Mr(e,r,i);try{const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return await e.decodeAudioData(s)}catch{return Mr(e,r,i)}}function Li(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Oi(e,t){const n=[],r=[];let i=null,s=!1,o=!1,a=!1,u=!1,d=0,l=0,c=0,m=null,w=1,S=t,f=!1,E=null,D=0,B=!1,v=!1,k=0,O=null,A=null,se=null;const le=()=>({visemes:[],words:[],segmentOffsetMs:0}),I=()=>{v=!1,k=0},U=()=>{m!=null&&(clearTimeout(m),m=null)},q=()=>{for(const _ of r){try{_.onended=null,_.stop(0)}catch{}try{_.disconnect()}catch{}}r.length=0},oe=()=>{for(const _ of r)_.playbackRate.value=w},ae=()=>{if(!(f||!u||s||v||r.length>0||n.length>0)){if(a&&i&&l>0){const _=(i.currentTime-l)*1e3;if(_<D){U();const C=w>0?(D-_)/w:D-_;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,C));return}}o=!1,U(),e.onSpeakingDone(),e.onNotify()}},ie=_=>{const C=ut(_);if(C<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,d=performance.now(),e.onSpeakingStart(),e.onNotify(),U();const $=w>0?C/w:C;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},$)},L=(_,C,$,re)=>{C.length!==0&&(c=$,C.forEach(K=>{const p=String(K.word??"").trim();if(!p)return;const b=Math.round((K.start??0)*1e3),x=K.duration!=null?Math.round(K.duration*1e3):K.end!=null?Math.max(1,Math.round((K.end-(K.start??0))*1e3)):0;_.push({word:p,wtime:c+b,wduration:x,queueIndex:_.length,gesture:K.gesture??null,emphasis:K.emphasis===!0})}))},Z=(_,C,$,re,K,Y)=>{$.length!==0&&(c=re,$.forEach(p=>{const b=String(p.symbol??p.viseme??"").trim();if(!b)return;const x=Math.round((p.start??0)*1e3),W=Math.max(1,Math.round((p.duration??0)*1e3)),ee=c+x,T=Li(C,ee),Q=T?bi(T,ee):0;let V;oi(Y)==="oculus_direct"?(V=mn(b),V==="U"&&T&&hn(T.word,Q)&&(V="FF")):V=Si(b,T?.word??"",Q),_.push({viseme:V,weight:1,vtime:ee,vduration:W})}),e.onNotify())},H=(_,C,$,re,K,Y,p)=>{L(C,re,K),Z(_,C,$,K,Y,p)},me=(_,C,$)=>{se===_&&_.visemes===C||(C.length=0,$.length=0,_.visemes=C,_.words=$,_.segmentOffsetMs=0,se=_,c=0,D=0)},z=async()=>{const _=window.AudioContext||window.webkitAudioContext;return i||(i=new _),i.state==="suspended"&&await i.resume(),E||(E=i.createMediaStreamDestination()),i},te=(_,C)=>{if(!i)return 0;const $=i,re=$.currentTime,K=re+.02;if(C.isFirstAudio){l<=0&&(l=K);const p=(K-re)*1e3;d=performance.now()+p}C.onBeforeStart?.(K);const Y=$.createBufferSource();return Y.buffer=_,Y.playbackRate.value=w,Y.connect($.destination),E&&Y.connect(E),r.push(Y),f?(r.pop(),K):(C.isFirstAudio&&(o=!0,e.onSpeakingStart()),Y.onended=()=>{const p=r.indexOf(Y);p>=0&&r.splice(p,1),e.onNotify(),!f&&(O&&A?j(O,A):ae())},Y.start(K),K)},j=async(_,C)=>{if(f||s||r.length>0)return;if(n.length===0){ae();return}s=!0;let $=!1;try{const re=await z();if(f)return;const K=n[0];if(!K)return;const Y=!o;if(B&&(e.shouldHoldForWarmup?.()??!1)&&(v||Y&&K.newStream)||v){me(K.utterance,_,C);for(const x of n){if(f)return;x.audioBuffer||(x.audioBuffer=await Pr(re,x.audio,x.sampleRate)),a=!0,v||(v=!0,k=0,x.newStream&&x.onNewStream?.()),x.visemesQueued||(H(_,C,x.visemes,x.words,k,!0,S),x.visemesQueued=!0,k+=Math.round(x.audioBuffer.duration*1e3),D=Math.max(D,ut(_)))}e.onNotify();return}const b=n.shift();if(!b||(b.audioBuffer||(b.audioBuffer=await Pr(re,b.audio,b.sampleRate)),f))return;a=!0,U(),me(b.utterance,_,C),b.visemesQueued=!1,b.newStream&&b.onNewStream?.(),te(b.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:x=>{l=x,c=0,d=performance.now()+(x-re.currentTime)*1e3,_.length=0,C.length=0,H(_,C,b.visemes,b.words,0,!0,S),b.visemesQueued=!0,b.utterance.segmentOffsetMs=0}}),$=r.length>0,D=ut(_),e.onNotify()}catch(re){console.error("[avatarChunkPlayback] audio chunk failed:",re)}finally{if(s=!1,f)return;if(v){n.some(K=>!K.audioBuffer||!K.visemesQueued)&&j(_,C);return}!$&&r.length===0&&n.length>0?j(_,C):r.length===0&&n.length===0&&ae()}};return{setStreamTtsEngineId:_=>{S=_},setPlaybackSpeed:_=>{w=Math.max(.1,Math.min(1,_)),oe()},getPlaybackSpeed:()=>w,setLipsyncWarmupHoldEnabled:_=>{B=_,_||I()},isWarmingUp:()=>v,releaseWarmupHold:()=>{if(v){v=!1,k=0;for(const _ of n)_.newStream=!1;O&&A&&j(O,A),e.onNotify()}},resetForNewStream:_=>{f=!1,u=!1,S=_,D=0},resumeBotStream:()=>{f=!1,u=!1},clearAborted:()=>{f=!1},primeAudioContext:async()=>{const _=window.AudioContext||window.webkitAudioContext;i||(i=new _),i.state==="suspended"&&await i.resume(),i&&!E&&(E=i.createMediaStreamDestination())},stop:()=>{f=!0,U(),q(),n.length=0,s=!1,o=!1,a=!1,u=!1,c=0,l=0,d=0,D=0,O=null,A=null,se=null,I()},markStreamComplete:_=>{if(D=Math.max(D,ut(_)),u=!0,!a&&_.length>0){ie(_);return}ae()},playAudioChunk:async(_,C,$,re,K,Y,p)=>{if(f)return;O=_,A=C;const b=Fi(p?.sampleRate),x=p?.newStream===!0,W=le();if(!$?.trim()){if(re.length===0&&K.length===0)return;me(W,_,C),x&&p?.onNewStream?.(),H(_,C,re,K,0,!0,S),D=ut(_),!o&&D>0&&ie(_),e.onNotify();return}n.push({audio:$,audioBuffer:null,utterance:W,visemes:re,words:K,isNewSegment:Y,sampleRate:b,newStream:x,onNewStream:p?.onNewStream,visemesQueued:!1}),await j(_,C)},queueTimingsOnly:(_,C,$,re,K,Y)=>{if(f)return;const p=le();me(p,_,C),H(_,C,$,re,0,!0,S),p.segmentOffsetMs=0,D=ut(_)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*w):o?Math.max(0,(performance.now()-d)*w):0,isSpeaking:()=>o?!0:!a||!i||l<=0?!1:(i.currentTime-l)*1e3<D,getVoiceStream:()=>E?E.stream:null,getPlaybackStartPerf:()=>d,bargeIn:()=>{f=!0,u=!1,U(),q(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,O=null,A=null,se=null,I()},interrupt:()=>{f=!0,u=!1,U(),q(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,O=null,A=null,se=null,I()}}}function zt(e,t){let n=null;for(const r of e)t<r.vtime||t>=r.vtime+r.vduration||(!n||r.vtime>=n.vtime)&&(n=r);return n?n.viseme:"sil"}function Ni(e,t,n=120){const r=zt(e,t);if(r!=="sil")return r;let i=null;for(const s of e){if(s.vtime>t)break;const o=s.vtime+s.vduration;o<=t&&t-o<=n&&(i=s)}return i?.viseme??"sil"}function ca(e,t,n=400){const r=t-n;let i=0;for(const s of e)if(s.vtime+s.vduration<r)i+=1;else break;i>0&&e.splice(0,i)}function la(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Rr(e,t){const n=e.trim();if(!n)return null;try{const r=n.replace(/\s+/g,""),i=atob(r).length,s=Number.isFinite(t)&&(t??0)>0?Number(t):16e3;return i/2/s*1e3}catch{return null}}const pn=.5,yn=1.5,tr="Olivia",nr="f786b574-daa5-4673-aa0c-cbe3e8534c02",Ht=.85;function Nn(e,t=gt,n={}){const r=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let u=0;const d=[],l=[];let c="",m="neutral",w="",S=ft;const f=new Set;let E=0,D=null,B=0,v=null;const k=()=>f.forEach(L=>L());let O=()=>!1;const A=Oi({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:k,shouldHoldForWarmup:()=>O()},ft),se=()=>A.getPlaybackElapsedMs(),le=(L,Z=c)=>{if(!n.onLipsyncDebug)return;const H=se(),me=i,z=wn(o).map(te=>({viseme:te.viseme,vtimeMs:te.vtime}));n.onLipsyncDebug({event:L,spokenText:Z,mood:m,playbackAnchorPerf:A.getPlaybackStartPerf(),playbackElapsedMs:H,queueLength:me.length,activeViseme:zt(me,H),segments:l.map(te=>({...te,visemes:[...te.visemes]})),fullQueueLength:o.length,compactionSkipped:z})},I=(L,Z)=>{n.onLipsyncDebug&&(D={event:L,spokenText:Z},E===0&&(E=requestAnimationFrame(()=>{E=0;const H=D;D=null,H&&le(H.event,H.spokenText)})))},U=(L,Z,H,me,z)=>{if(!n.onLipsyncDebug)return;const te=i.slice(Z),j=H.filter(J=>String(J.symbol??J.viseme??"").trim());l.push({spokenText:L,audioOffsetMs:te[0]?.vtime??0,isNewSegment:me,chunkDurationMs:z,receivedAtMs:performance.now(),visemes:te.map((J,Se)=>{const ue=j[Se];return{rawSymbol:String(ue?.symbol??ue?.viseme??J.viseme).trim(),viseme:J.viseme,startSec:Number(ue?.start??0),durationSec:Number(ue?.duration??0),vtimeMs:J.vtime,vdurationMs:J.vduration}})})},q=()=>{o.length=0,a.length=0,u=0},oe=(L,Z,H,me,z)=>{if(L.length===0&&Z.length===0)return;Di(o,a,L,Z,u,z);const te=Bi(L,u),j=H?Rr(H,me):null;u=Math.max(te,j!=null?u+j:u)},ae=()=>{B+=1,v?.abort(),v=null,A.stop(),i.length=0,s.length=0,q(),d.length=0,m="neutral",l.length=0,c="",e("idle"),I("reset"),k()};return{setDeveloperToken:L=>{w=L},setTtsEngineId:L=>{S=L},getTtsEngineId:()=>S,speak:async(L,Z)=>{ae();const H=B;v=new AbortController,e("loading"),c=L,l.length=0,q();const me=w.trim();if(!me)throw new Error("Developer token required for avatar_ttsWithPoses");const z=et(Z?.ttsEngineId,Z?.voiceId),te=z.ttsEngineId??S??ft;A.resetForNewStream(te),A.setStreamTtsEngineId(te);const j=z.voiceId??(te===nt?dn:tr),J=Z?.speakingRate??Ht,Se=Math.max(pn,Math.min(yn,J)),ue={user_query:L,ttsEngineId:te,speakingRate:Se,tenant:"aiTwin"};si.has(te)&&(ue.voice_id=j);const _=fn(Z?.language);_&&(ue.language=_);try{const C=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${me}`},body:JSON.stringify(ue),signal:v.signal});if(!C.ok)throw new Error(`avatar_ttsWithPoses failed (${C.status})`);const $=C.body;if(!$)throw new Error("No response body");const re=$.getReader(),K=new TextDecoder;let Y="",p=!0;const b=async x=>{if(H!==B)return;const W=vi(x);if(W){if(W.event==="audio"){const ee=W.data.chunk,T=W.data.visemes??[],Q=W.data.words??[],V=W.data.is_new_segment??!1,he=W.data.sample_rate,De=Number(W.data.audio_offset_ms??0),ot=i.length;if(oe(T,Q,ee,he,te),ee){const yt=p;p=!1,await A.playAudioChunk(i,s,ee,T,Q,V,{sampleRate:he,newStream:yt,audioOffsetMs:De}),U(L,ot,T,V,Rr(ee,he)),I("audio_chunk",L)}else(T.length>0||Q.length>0)&&(A.queueTimingsOnly(i,s,T,Q,V,{audioOffsetMs:De,newStream:p}),U(L,ot,T,V,null),I("audio_chunk",L))}else if(W.event==="metadata"){const ee=W.data.mood;typeof ee=="string"&&ee.trim()&&(m=ee.trim());const T=W.data.sentence_emotions;if(Array.isArray(T)){d.length=0;for(const Q of T){if(!Q||typeof Q!="object")continue;const V=Q;d.push({sentence_index:Number(V.sentence_index??0),text:String(V.text??""),sentiment:typeof V.sentiment=="string"?V.sentiment:void 0,emotion:String(V.emotion??m),start_word:Number(V.start_word??0),end_word:Number(V.end_word??0)})}}k(),I("metadata",L)}else if(W.event==="error")throw new Error(String(W.data.message??"avatar_ttsWithPoses stream error"))}};for(;H===B;){const{done:x,value:W}=await re.read();W&&(Y+=K.decode(W,{stream:!0}));const ee=Y.split(`
2
2
 
3
- `);q=U.pop()??"";for(const Z of U)await S(Z);if(x){q.trim()&&await S(q.trim()),A.markStreamComplete(i),I("bot_stopped",O);break}}}catch(P){if(W!==B||P instanceof DOMException&&P.name==="AbortError")return;throw console.error("[avatarTtsLipsync]",P),se(),e("error"),P}},stop:se,getVisemeQueue:()=>i,getWordQueue:()=>s,getFullVisemeQueue:()=>o,getFullWordQueue:()=>a,getSentenceEmotions:()=>d,getStreamMood:()=>m,getPlaybackElapsedMs:()=>A.getPlaybackElapsedMs(),isSpeaking:()=>A.isSpeaking(),isWarmingUp:()=>A.isWarmingUp(),releaseWarmupHold:()=>A.releaseWarmupHold(),setLipsyncWarmupHold:(O,J)=>{J&&(L=J),A.setLipsyncWarmupHoldEnabled(O)},getVoiceStream:()=>A.getVoiceStream(),setPlaybackSpeed:O=>{A.setPlaybackSpeed(O)},getPlaybackSpeed:()=>A.getPlaybackSpeed(),subscribe:O=>(f.add(O),()=>f.delete(O))}}const nr=16e3,rr=16e3;class ca extends Hn.ProtobufFrameSerializer{async deserialize(t){try{return await super.deserialize(t)}catch(n){if(n instanceof Error&&n.message==="Unknown frame kind")return{type:"raw",message:null};throw n}}}class la extends Hn.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,nr,rr)}bufferBotAudio(t,n){}}const ua=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Cr(e){return ua.test(e.trim())}function da(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function Ni(e){if(e.wsUrl?.trim())return e.wsUrl.trim();const t=e.authToken?.trim();if(!t)throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");const n=e.apiBase??ht,r=new URL(`${da(n)}/ws/voice`);r.searchParams.set("authToken",t),r.searchParams.set("tenant","aiTwin");const i=et(e.ttsEngineId,e.voiceId),s=i.ttsEngineId;s&&r.searchParams.set("ttsEngineId",s);const o=i.voiceId?.trim();o&&(s&&oi(s)?Cr(o)||r.searchParams.set("voiceId",o):Cr(o)&&r.searchParams.set("voiceId",o));const a=fn(e.language);a&&r.searchParams.set("language",a);const u=e.brainId?.trim()||e.personaId?.trim();u&&r.searchParams.set("brainId",u);const d=e.speakingRate??Ht;r.searchParams.set("speaking_rate",String(Math.max(pn,Math.min(yn,d)))),e.ttsStream===!1?r.searchParams.set("tts_stream","false"):r.searchParams.set("tts_stream","true"),e.speakOnlyWhenSpokenTo&&r.searchParams.set("speakOnlyWhenSpokenTo","true");const l=e.avatarName?.trim();return l&&r.searchParams.set("avatarName",l),r.toString()}function An(e,t){if(!Array.isArray(e))return[];const n=[];for(const r of e)!r||typeof r!="object"||n.push({sentence_index:Number(r.sentence_index??0),text:String(r.text??""),sentiment:typeof r.sentiment=="string"?r.sentiment:void 0,emotion:String(r.emotion??t),start_word:Number(r.start_word??0),end_word:Number(r.end_word??0)});return n}function fa(e){if(!e||typeof e!="object")return null;const t=e,r=(t.data&&typeof t.data=="object"&&!Array.isArray(t.data)?t.data:null)||t;return{...r,type:String(r.type??t.type??"server-message")}}function Rr(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function ma(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function Vi(e,t={}){const n=[],r=[],i=[],s=[];let o=0;const a=[],u=[];let d="",l="neutral",c=tt,m=!1,w=null,T=null,f={...t},E=0,D=null;const B=new Set,v=[];let k=!1,L=null,A=!0,ie="default";const de=new Set;let I=null,V=0,G=!1,ae=!1,se=null,re=!1;const O=()=>{se!=null&&(clearTimeout(se),se=null)},J=()=>{O(),se=setTimeout(()=>{se=null,A&&(K.markStreamComplete(n),oe("bot_stopped"))},450)},W=()=>B.forEach(g=>g());let he=()=>!1;const K=Li({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{re=!1,ae=!1,e("done")},onNotify:W,shouldHoldForWarmup:()=>he()},c),ee=()=>{if(L)return L;const g=new MessageChannel;return g.port1.onmessage=()=>{const C=v.shift();C!==void 0&&be(C),v.length>0?g.port2.postMessage(null):k=!1},L=g,g},$=g=>{v.push(g),!k&&(k=!0,ee().port2.postMessage(null))},X=()=>K.getPlaybackElapsedMs(),_e=(g,C=d)=>{if(!f.onLipsyncDebug)return;const ne=X(),ue=n,Te=wn(i).map(ve=>({viseme:ve.viseme,vtimeMs:ve.vtime}));f.onLipsyncDebug({event:g,spokenText:C,mood:l,playbackAnchorPerf:K.getPlaybackStartPerf(),playbackElapsedMs:ne,queueLength:ue.length,activeViseme:zt(ue,ne),segments:u.map(ve=>({...ve,visemes:[...ve.visemes]})),fullQueueLength:i.length,compactionSkipped:Te})},oe=(g,C)=>{f.onLipsyncDebug&&(D={event:g,spokenText:C},E===0&&(E=requestAnimationFrame(()=>{E=0;const ne=D;D=null,ne&&_e(ne.event,ne.spokenText)})))},b=()=>{A=!0,de.clear(),K.clearAborted()},P=()=>{const g=ma(w);if(g){ie=`bot-${Date.now()}`,g.interruptedTrackIds={[ie]:!0};try{g.interrupt?.()}catch{}}const C=T;try{C?.interrupt?.()}catch{}},H=g=>{if(re&&K.isSpeaking())return!0;const C=g.context_id?.trim();return C&&de.has(C)?!0:A?!1:!(g.type==="avatar_metadata"||Rr(g))},le=g=>{A=!1,re=!1;const C=g.context_id?.trim();C&&de.add(C),O(),G=!1,ae=!1,v.length=0,k=!1,I?.abort(),I=null,V+=1,P(),K.bargeIn(),j(),e("idle"),oe("interrupt"),W()},j=()=>{n.length=0,r.length=0,i.length=0,s.length=0,o=0,u.length=0,d="",l="neutral",a.length=0},q=()=>{O(),ae=!1,G=!1,K.stop(),j(),oe("reset"),W()},p=()=>{q(),e("idle"),W()},S=(g,C)=>{typeof g.mood=="string"&&g.mood.trim()&&(l=g.mood.trim()),Array.isArray(g.sentence_emotions)&&g.sentence_emotions.length>0&&(C&&(a.length=0),a.push(...An(g.sentence_emotions,l)))},x=g=>{if(H({...g,type:"avatar_metadata"}))return;b(),G=!0;const C=String(g.spoken_text??g.text??"").trim();C&&(d=C),K.resetForNewStream(c),typeof g.mood=="string"&&g.mood.trim()&&(l=g.mood.trim()),a.length=0,a.push(...An(g.sentence_emotions,l)),Array.isArray(g.gestures)&&g.gestures,oe("metadata",C),W()},_=(g,C,ne,ue)=>{if(!f.onLipsyncDebug)return;const Te=n.slice(ne),ve=ue.filter(ke=>String(ke.symbol??ke.viseme??"").trim());u.push({spokenText:C,audioOffsetMs:Te[0]?.vtime??0,isNewSegment:!!g.is_new_segment,chunkDurationMs:g.chunk_duration_ms!=null?Number(g.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:Te.map((ke,We)=>{const Fe=ve[We];return{rawSymbol:String(Fe?.symbol??Fe?.viseme??ke.viseme).trim(),viseme:ke.viseme,startSec:Number(Fe?.start??0),durationSec:Number(Fe?.duration??0),vtimeMs:ke.vtime,vdurationMs:ke.vduration}})})},U=(g,C,ne,ue)=>{if(g.length===0&&C.length===0)return;Ri(i,s,g,C,o,c);const Te=Di(g,o);let ve=null;const ke=ne.trim();if(ke)try{const We=atob(ke.replace(/\s+/g,"")).length,Fe=Number.isFinite(ue)&&(ue??0)>0?Number(ue):16e3;ve=We/2/Fe*1e3}catch{ve=null}o=Math.max(Te,ve!=null?o+ve:o)},Z=g=>{if(H(g))return;const C=Rr(g);C&&(O(),b());const ne=String(g.spoken_text??g.text??"").trim(),ue=g.visemes??[],Te=g.words??[],ve=String(g.chunk??"").trim(),ke=G||C||!ae;G&&(G=!1),ke&&(ae=!0),ne&&(d=ne),S(g,C),ke?(K.resetForNewStream(c),i.length=0,s.length=0,o=0):C&&K.resumeBotStream(),U(ue,Te,ve,g.sample_rate);const We=n.length;K.playAudioChunk(n,r,ve,ue,Te,C,{sampleRate:g.sample_rate,newStream:ke,audioOffsetMs:Number(g.audio_offset_ms??0),onNewStream:()=>{u.length=0}}).then(()=>{_(g,ne,We,ue),oe("audio_chunk",ne),J()})},te=g=>{if(H(g))return;(g.is_new_segment||Number(g.audio_offset_ms??-1)===0)&&b(),console.warn("[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk");const C=String(g.spoken_text??g.text??"").trim();C&&(d=C),S(g,!!g.is_new_segment),U(g.visemes??[],g.words??[],"",void 0);const ne=n.length;K.queueTimingsOnly(n,r,g.visemes??[],g.words??[],!!g.is_new_segment,{audioOffsetMs:Number(g.audio_offset_ms??0)}),_(g,C,ne,g.visemes??[]),oe("lipsync",C),W()},z=async g=>{const C=String(g.text??"").trim();if(!C)return;const ne=f.authToken?.trim();if(!ne){console.error("[realtimeVoice] avatar_speak requires authToken");return}I?.abort();const ue=new AbortController;I=ue;const Te=++V;b(),K.resetForNewStream(c),d=C;const ke=`${(f.apiBase??ht).replace(/\/$/,"")}/avatar_ttsWithPoses`,We=et(c,f.voiceId);We.ttsEngineId&&(c=We.ttsEngineId,K.setStreamTtsEngineId(c));const Fe=We.voiceId?.trim()||(c===nt?dn:tr),$t=f.speakingRate??Ht,bn=Math.max(pn,Math.min(yn,$t)),Rt={user_query:C,ttsEngineId:c,speakingRate:bn,tenant:"aiTwin"};ii.has(c)&&(Rt.voice_id=Fe);const yt=fn(f.language);yt&&(Rt.language=yt);try{const Ce=await fetch(ke,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${ne}`},body:JSON.stringify(Rt),signal:ue.signal});if(!Ce.ok)throw new Error(`avatar_ttsWithPoses failed (${Ce.status})`);const He=Ce.body;if(!He)throw new Error("No response body");const vt=He.getReader(),Ie=new TextDecoder;let xe="",$e=!0;const je=async rt=>{if(Te!==V||ue.signal.aborted||!A)return;const pe=yi(rt);if(pe){if(pe.event==="audio"){const Le=pe.data.chunk,Pe=pe.data.visemes??[],Oe=pe.data.words??[],Ne=pe.data.is_new_segment??!1,Dt=pe.data.sample_rate,ct=Number(pe.data.audio_offset_ms??0);if(Le){const Bt=$e;$e=!1,await K.playAudioChunk(n,r,Le,Pe,Oe,Ne,{sampleRate:Dt,newStream:Bt,audioOffsetMs:ct})}else(Pe.length>0||Oe.length>0)&&K.queueTimingsOnly(n,r,Pe,Oe,Ne,{audioOffsetMs:ct,newStream:$e})}else if(pe.event==="metadata"){const Le=pe.data.mood;typeof Le=="string"&&Le.trim()&&(l=Le.trim());const Pe=pe.data.sentence_emotions;Array.isArray(Pe)&&(a.length=0,a.push(...An(Pe,l))),W()}else if(pe.event==="error")throw new Error(String(pe.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(Te!==V||ue.signal.aborted||!A);){const{done:rt,value:pe}=await vt.read();pe&&(xe+=Ie.decode(pe,{stream:!0}));const Le=xe.split(`
3
+ `);Y=ee.pop()??"";for(const T of ee)await b(T);if(x){Y.trim()&&await b(Y.trim()),A.markStreamComplete(i),I("bot_stopped",L);break}}}catch(C){if(H!==B||C instanceof DOMException&&C.name==="AbortError")return;throw console.error("[avatarTtsLipsync]",C),ae(),e("error"),C}},stop:ae,getVisemeQueue:()=>i,getWordQueue:()=>s,getFullVisemeQueue:()=>o,getFullWordQueue:()=>a,getSentenceEmotions:()=>d,getStreamMood:()=>m,getPlaybackElapsedMs:()=>A.getPlaybackElapsedMs(),isSpeaking:()=>A.isSpeaking(),isWarmingUp:()=>A.isWarmingUp(),releaseWarmupHold:()=>A.releaseWarmupHold(),setLipsyncWarmupHold:(L,Z)=>{Z&&(O=Z),A.setLipsyncWarmupHoldEnabled(L)},getVoiceStream:()=>A.getVoiceStream(),setPlaybackSpeed:L=>{A.setPlaybackSpeed(L)},getPlaybackSpeed:()=>A.getPlaybackSpeed(),subscribe:L=>(f.add(L),()=>f.delete(L))}}const rr=16e3,ir=16e3;class ua extends Hn.ProtobufFrameSerializer{async deserialize(t){try{return await super.deserialize(t)}catch(n){if(n instanceof Error&&n.message==="Unknown frame kind")return{type:"raw",message:null};throw n}}}class da extends Hn.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,rr,ir)}bufferBotAudio(t,n){}}const fa=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Cr(e){return fa.test(e.trim())}function ma(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function Ui(e){if(e.wsUrl?.trim())return e.wsUrl.trim();const t=e.authToken?.trim();if(!t)throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");const n=e.apiBase??gt,r=new URL(`${ma(n)}/ws/voice`);r.searchParams.set("authToken",t),r.searchParams.set("tenant","aiTwin");const i=et(e.ttsEngineId,e.voiceId),s=i.ttsEngineId;s&&r.searchParams.set("ttsEngineId",s);const o=i.voiceId?.trim();o&&(s&&ci(s)?Cr(o)||r.searchParams.set("voiceId",o):Cr(o)&&r.searchParams.set("voiceId",o));const a=fn(e.language);a&&r.searchParams.set("language",a);const u=e.brainId?.trim()||e.personaId?.trim();u&&r.searchParams.set("brainId",u);const d=e.brainUrl?.trim();d&&r.searchParams.set("brainUrl",d);const l=e.speakingRate??Ht;r.searchParams.set("speaking_rate",String(Math.max(pn,Math.min(yn,l)))),e.ttsStream===!1?r.searchParams.set("tts_stream","false"):r.searchParams.set("tts_stream","true"),e.speakOnlyWhenSpokenTo&&r.searchParams.set("speakOnlyWhenSpokenTo","true");const c=e.avatarName?.trim();return c&&r.searchParams.set("avatarName",c),r.toString()}function An(e,t){if(!Array.isArray(e))return[];const n=[];for(const r of e)!r||typeof r!="object"||n.push({sentence_index:Number(r.sentence_index??0),text:String(r.text??""),sentiment:typeof r.sentiment=="string"?r.sentiment:void 0,emotion:String(r.emotion??t),start_word:Number(r.start_word??0),end_word:Number(r.end_word??0)});return n}function ha(e){if(!e||typeof e!="object")return null;const t=e,r=(t.data&&typeof t.data=="object"&&!Array.isArray(t.data)?t.data:null)||t;return{...r,type:String(r.type??t.type??"server-message")}}function Dr(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function ga(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function Vi(e,t={}){const n=[],r=[],i=[],s=[];let o=0;const a=[],u=[];let d="",l="neutral",c=tt,m=!1,w=null,S=null,f={...t},E=0,D=null;const B=new Set,v=[];let k=!1,O=null,A=!0,se="default";const le=new Set;let I=null,U=0,q=!1,oe=!1,ae=null,ie=!1;const L=()=>{ae!=null&&(clearTimeout(ae),ae=null)},Z=()=>{L(),ae=setTimeout(()=>{ae=null,A&&(z.markStreamComplete(n),ue("bot_stopped"))},450)},H=()=>B.forEach(g=>g());let me=()=>!1;const z=Oi({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{ie=!1,oe=!1,e("done")},onNotify:H,shouldHoldForWarmup:()=>me()},c),te=()=>{if(O)return O;const g=new MessageChannel;return g.port1.onmessage=()=>{const P=v.shift();P!==void 0&&he(P),v.length>0?g.port2.postMessage(null):k=!1},O=g,g},j=g=>{v.push(g),!k&&(k=!0,te().port2.postMessage(null))},J=()=>z.getPlaybackElapsedMs(),Se=(g,P=d)=>{if(!f.onLipsyncDebug)return;const ne=J(),ce=n,Te=wn(i).map(be=>({viseme:be.viseme,vtimeMs:be.vtime}));f.onLipsyncDebug({event:g,spokenText:P,mood:l,playbackAnchorPerf:z.getPlaybackStartPerf(),playbackElapsedMs:ne,queueLength:ce.length,activeViseme:zt(ce,ne),segments:u.map(be=>({...be,visemes:[...be.visemes]})),fullQueueLength:i.length,compactionSkipped:Te})},ue=(g,P)=>{f.onLipsyncDebug&&(D={event:g,spokenText:P},E===0&&(E=requestAnimationFrame(()=>{E=0;const ne=D;D=null,ne&&Se(ne.event,ne.spokenText)})))},_=()=>{A=!0,le.clear(),z.clearAborted()},C=()=>{const g=ga(w);if(g){se=`bot-${Date.now()}`,g.interruptedTrackIds={[se]:!0};try{g.interrupt?.()}catch{}}const P=S;try{P?.interrupt?.()}catch{}},$=g=>{if(ie&&z.isSpeaking())return!0;const P=g.context_id?.trim();return P&&le.has(P)?!0:A?!1:!(g.type==="avatar_metadata"||Dr(g))},re=g=>{A=!1,ie=!1;const P=g.context_id?.trim();P&&le.add(P),L(),q=!1,oe=!1,v.length=0,k=!1,I?.abort(),I=null,U+=1,C(),z.bargeIn(),K(),e("idle"),ue("interrupt"),H()},K=()=>{n.length=0,r.length=0,i.length=0,s.length=0,o=0,u.length=0,d="",l="neutral",a.length=0},Y=()=>{L(),oe=!1,q=!1,z.stop(),K(),ue("reset"),H()},p=()=>{Y(),e("idle"),H()},b=(g,P)=>{typeof g.mood=="string"&&g.mood.trim()&&(l=g.mood.trim()),Array.isArray(g.sentence_emotions)&&g.sentence_emotions.length>0&&(P&&(a.length=0),a.push(...An(g.sentence_emotions,l)))},x=g=>{if($({...g,type:"avatar_metadata"}))return;_(),q=!0;const P=String(g.spoken_text??g.text??"").trim();P&&(d=P),z.resetForNewStream(c),typeof g.mood=="string"&&g.mood.trim()&&(l=g.mood.trim()),a.length=0,a.push(...An(g.sentence_emotions,l)),Array.isArray(g.gestures)&&g.gestures,ue("metadata",P),H()},W=(g,P,ne,ce)=>{if(!f.onLipsyncDebug)return;const Te=n.slice(ne),be=ce.filter(ke=>String(ke.symbol??ke.viseme??"").trim());u.push({spokenText:P,audioOffsetMs:Te[0]?.vtime??0,isNewSegment:!!g.is_new_segment,chunkDurationMs:g.chunk_duration_ms!=null?Number(g.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:Te.map((ke,ze)=>{const Ne=be[ze];return{rawSymbol:String(Ne?.symbol??Ne?.viseme??ke.viseme).trim(),viseme:ke.viseme,startSec:Number(Ne?.start??0),durationSec:Number(Ne?.duration??0),vtimeMs:ke.vtime,vdurationMs:ke.vduration}})})},ee=(g,P,ne,ce)=>{if(g.length===0&&P.length===0)return;Di(i,s,g,P,o,c);const Te=Bi(g,o);let be=null;const ke=ne.trim();if(ke)try{const ze=atob(ke.replace(/\s+/g,"")).length,Ne=Number.isFinite(ce)&&(ce??0)>0?Number(ce):16e3;be=ze/2/Ne*1e3}catch{be=null}o=Math.max(Te,be!=null?o+be:o)},T=g=>{if($(g))return;const P=Dr(g);P&&(L(),_());const ne=String(g.spoken_text??g.text??"").trim(),ce=g.visemes??[],Te=g.words??[],be=String(g.chunk??"").trim(),ke=q||P||!oe;q&&(q=!1),ke&&(oe=!0),ne&&(d=ne),b(g,P),ke?(z.resetForNewStream(c),i.length=0,s.length=0,o=0):P&&z.resumeBotStream(),ee(ce,Te,be,g.sample_rate);const ze=n.length;z.playAudioChunk(n,r,be,ce,Te,P,{sampleRate:g.sample_rate,newStream:ke,audioOffsetMs:Number(g.audio_offset_ms??0),onNewStream:()=>{u.length=0}}).then(()=>{W(g,ne,ze,ce),ue("audio_chunk",ne),Z()})},Q=g=>{if($(g))return;(g.is_new_segment||Number(g.audio_offset_ms??-1)===0)&&_(),console.warn("[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk");const P=String(g.spoken_text??g.text??"").trim();P&&(d=P),b(g,!!g.is_new_segment),ee(g.visemes??[],g.words??[],"",void 0);const ne=n.length;z.queueTimingsOnly(n,r,g.visemes??[],g.words??[],!!g.is_new_segment,{audioOffsetMs:Number(g.audio_offset_ms??0)}),W(g,P,ne,g.visemes??[]),ue("lipsync",P),H()},V=async g=>{const P=String(g.text??"").trim();if(!P)return;const ne=f.authToken?.trim();if(!ne){console.error("[realtimeVoice] avatar_speak requires authToken");return}I?.abort();const ce=new AbortController;I=ce;const Te=++U;_(),z.resetForNewStream(c),d=P;const ke=`${(f.apiBase??gt).replace(/\/$/,"")}/avatar_ttsWithPoses`,ze=et(c,f.voiceId);ze.ttsEngineId&&(c=ze.ttsEngineId,z.setStreamTtsEngineId(c));const Ne=ze.voiceId?.trim()||(c===nt?dn:nr),$t=f.speakingRate??Ht,bn=Math.max(pn,Math.min(yn,$t)),Ct={user_query:P,ttsEngineId:c,speakingRate:bn,tenant:"aiTwin"};si.has(c)&&(Ct.voice_id=Ne);const vt=fn(f.language);vt&&(Ct.language=vt);try{const Be=await fetch(ke,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${ne}`},body:JSON.stringify(Ct),signal:ce.signal});if(!Be.ok)throw new Error(`avatar_ttsWithPoses failed (${Be.status})`);const $e=Be.body;if(!$e)throw new Error("No response body");const _t=$e.getReader(),Ee=new TextDecoder;let Ie="",je=!0;const Ke=async rt=>{if(Te!==U||ce.signal.aborted||!A)return;const ye=vi(rt);if(ye){if(ye.event==="audio"){const Ue=ye.data.chunk,Re=ye.data.visemes??[],Ve=ye.data.words??[],We=ye.data.is_new_segment??!1,Dt=ye.data.sample_rate,lt=Number(ye.data.audio_offset_ms??0);if(Ue){const Bt=je;je=!1,await z.playAudioChunk(n,r,Ue,Re,Ve,We,{sampleRate:Dt,newStream:Bt,audioOffsetMs:lt})}else(Re.length>0||Ve.length>0)&&z.queueTimingsOnly(n,r,Re,Ve,We,{audioOffsetMs:lt,newStream:je})}else if(ye.event==="metadata"){const Ue=ye.data.mood;typeof Ue=="string"&&Ue.trim()&&(l=Ue.trim());const Re=ye.data.sentence_emotions;Array.isArray(Re)&&(a.length=0,a.push(...An(Re,l))),H()}else if(ye.event==="error")throw new Error(String(ye.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(Te!==U||ce.signal.aborted||!A);){const{done:rt,value:ye}=await _t.read();ye&&(Ie+=Ee.decode(ye,{stream:!0}));const Ue=Ie.split(`
4
4
 
5
- `);xe=Le.pop()??"";for(const Pe of Le)await je(Pe);if(rt){xe.trim()&&await je(xe.trim()),Te===V&&!ue.signal.aborted&&A&&K.markStreamComplete(n);break}}}catch(Ce){if(ue.signal.aborted||!A)return;console.error("[realtimeVoice] avatar_speak failed:",Ce),e("error"),W()}finally{I===ue&&(I=null)}},be=g=>{const C=fa(g);if(!C){console.warn("[realtimeVoice] server message with no payload",g);return}const ne=String(C.type??"unknown");switch(ne!=="avatar_metadata"&&ne!=="avatar_audio_chunk"&&ne!=="avatar_lipsync"&&ne!=="avatar_interrupt"&&ne!=="error"&&console.debug("[realtimeVoice] server message",ne,C),ne){case"avatar_metadata":x(C);break;case"avatar_audio_chunk":Z(C);break;case"avatar_lipsync":te(C);break;case"avatar_interrupt":le(C);break;case"error":{const ue=String(C.message??"Voice session error");console.error("[realtimeVoice] server error:",ue),e("error"),W();break}case"avatar_speak":z(C);break}},Xe=()=>w||(T=new la,w=new us.PipecatClient({transport:new Hn.WebSocketTransport({mediaManager:T,serializer:new ca,recorderSampleRate:nr,playerSampleRate:rr}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{m=!0,e("idle"),W()},onDisconnected:()=>{m=!1,p()},onError:g=>{const C=typeof g=="object"&&g!==null&&"data"in g?String(g.data??g):String(g);console.error("[realtimeVoice]",C,g),e("error"),W()},onTransportStateChanged:g=>{g==="error"&&(e("error"),W())},onServerMessage:g=>{$(g)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{b(),oe("bot_started")},onBotStoppedSpeaking:()=>{A&&J()},onUserTranscript:g=>{String(g.text??""),f.onUserTranscript?.(g.text,!!g.final)},onBotOutput:g=>{f.onBotOutput?.(g.text)}}}),w);return{setDeveloperToken:g=>{},setTtsEngineId:g=>{c=g,K.setStreamTtsEngineId(g)},getTtsEngineId:()=>c,speak:async(g,C)=>{const ne=g.trim();if(ne){if(!w||!m)throw new Error("Realtime voice is not connected. Call connect() first.");q(),await w.sendText(ne)}},stop:()=>{I?.abort(),I=null,V+=1,b(),q(),e("idle"),W()},connect:async g=>{g&&(f={...f,...g});const C=et(f.ttsEngineId,f.voiceId);if(C.ttsEngineId&&(c=C.ttsEngineId,K.setStreamTtsEngineId(c)),f={...f,ttsEngineId:c,...C.voiceId?{voiceId:C.voiceId}:{}},!f.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const ne=Xe();await ne.initDevices();const ue=Ni({...f,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",ue);try{await ne.connect({wsUrl:ue})}catch(Te){m=!1,e("error"),W();const ve=Te instanceof Error?Te.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${ve} — ${ue}`)}m=!0,e("idle"),W()},disconnect:async()=>{if(O(),G=!1,ae=!1,v.length=0,k=!1,I?.abort(),I=null,V+=1,b(),w)try{await w.disconnect()}catch(g){console.error("[realtimeVoice] disconnect failed:",g)}m=!1,p()},isConnected:()=>m,unlockAudio:async()=>{await K.primeAudioContext()},getVisemeQueue:()=>n,getWordQueue:()=>r,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:X,isSpeaking:()=>K.isSpeaking(),isWarmingUp:()=>K.isWarmingUp(),releaseWarmupHold:()=>K.releaseWarmupHold(),setLipsyncWarmupHold:(g,C)=>{C&&(he=C),K.setLipsyncWarmupHoldEnabled(g)},getVoiceStream:()=>K.getVoiceStream(),setPlaybackSpeed:g=>{K.setPlaybackSpeed(g)},getPlaybackSpeed:()=>K.getPlaybackSpeed(),subscribe:g=>(B.add(g),()=>B.delete(g))}}function Ui(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function Wi(e,t){const n=e.crop;return{x:t?.source_x??n?.x??0,y:t?.source_y??n?.y??0,width:t?.source_w??n?.width??e.frame_width??0,height:t?.source_h??n?.height??e.frame_height??0}}function zi(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Mt(e,t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to load encrypted asset: ${e}`);const r=await n.arrayBuffer();return Ds(r,t)}async function Hi(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Mt(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function ha(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function ga(e){const t=new Blob([e],{type:"image/webp"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted image"))},s.src=n})}async function wa(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function pa(e){const t=new Blob([e],{type:"image/png"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted PNG"))},s.src=n})}function ya(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function va(e){const t=Fs();if(!Wt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Mt(t,e);return ya(n)}function kt(e,t){return`${e}/${t}_minus_sil.png`}const $i=5;function vn(e){const t=e?.composite_threshold;if(typeof t=="number"&&t>0)return t;const n=e?.crop?.content_threshold;return typeof n=="number"&&n>0?n:$i}const _a=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Vn=["t01_0.25","t02_0.50","t03_0.75"],ba=Vn.length,Dr=new Set(["aa__kk","aa__nn","aa__sil","CH__aa","CH__DD","CH__E","CH__FF","CH__I","CH__kk","CH__nn","CH__O","CH__PP","CH__RR","CH__sil","CH__SS","CH__TH","CH__U","DD__aa","DD__E","DD__FF","DD__I","DD__kk","DD__nn","DD__O","DD__PP","DD__RR","DD__sil","DD__SS","DD__TH","DD__U","E__aa","E__FF","E__I","E__kk","E__nn","E__O","E__PP","E__RR","E__sil","E__SS","E__TH","E__U","FF__aa","FF__I","FF__kk","FF__nn","FF__O","FF__PP","FF__RR","FF__sil","FF__SS","FF__TH","FF__U","I__aa","I__kk","I__nn","I__O","I__PP","I__RR","I__sil","I__SS","I__TH","I__U","kk__nn","kk__sil","nn__sil","O__aa","O__kk","O__nn","O__PP","O__RR","O__sil","O__SS","O__TH","O__U","PP__aa","PP__kk","PP__nn","PP__RR","PP__sil","PP__SS","PP__TH","PP__U","RR__aa","RR__kk","RR__nn","RR__sil","RR__SS","RR__TH","RR__U","SS__aa","SS__kk","SS__nn","SS__sil","SS__TH","SS__U","TH__aa","TH__kk","TH__nn","TH__sil","TH__U","U__aa","U__kk","U__nn","U__sil"]);function Br(e,t){return`${e}__${t}`}function Fr(e,t){return`pairs/${e}/${t}_minus_sil.png`}function xt(e){return`${e}_minus_sil.png`}function ir(e,t){if(t.has(e))return e;const n=/^pairs\/([^/]+)\//.exec(e);if(!n)return null;const r=n[1].split("__")[1];if(!r||r==="sil")return null;const i=xt(r);return t.has(i)?i:null}function ji(e,t){return e.filter(n=>t.has(n))}function Sa(e,t,n){const r=sr(e,t);return ji(r,n).length>0}function sr(e,t){if(e===t)return[];const n=[],r=Br(e,t);if(Dr.has(r)){for(const s of Vn)n.push(Fr(r,s));return n}const i=Br(t,e);if(Dr.has(i)){for(let s=ba-1;s>=0;s--)n.push(Fr(i,Vn[s]));return n}return[]}function Ta(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function ka(e,t){return Ta(t).map(r=>e[r]).filter(r=>r!=null)}function Ea(e,t,n,r){if(r<=0)return 0;const s=Math.max(1,n-t)/r,o=e-t,a=Math.floor(o/s);return Math.min(r-1,Math.max(0,a))}function Ki(e,t,n){if(!n)return`${e}/${t}`;const r=t.split("/").pop()??t,i=r.includes(".")?r.slice(0,r.lastIndexOf(".")):r;return`${e}/${i}.bin`}const xa=[.32,.24,.16,.08,0],Ia=xa.map(e=>`eyes_${e.toFixed(2)}`),Aa=["eyes_0.32","eyes_0.16","eyes_0.00"],Ma=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],ze=2,Pa=-20,an=16,Gi={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function Vt(e){return`brow_${e}`}function mt(e){return Gi[e]}function Qe(e){return Math.max(Pa,Math.min(an,e))}function Ca(e,t){if(e===t)return[];const n=e<t,r=n?ze:-ze,i=[];let s=e;if(s%ze!==0){const o=n?Math.ceil(s/ze)*ze:Math.floor(s/ze)*ze,a=Qe(o);if(n?a>=t:a<=t)return[t];s=a,i.push(s)}for(;;){const o=s+r;if(n?o>=t:o<=t){t!==s&&i.push(t);break}s=o,i.push(s)}return i}function Lr(e){const t=Qe(e);if(t%ze===0)return[t];const n=Math.floor(t/ze)*ze,r=Math.min(an,n+ze),i=Qe(n);return t-i<=r-t?i===r?[i]:[i,r]:i===r?[r]:[r,i]}const Ra=["fear","anger","sad","neutral","love","happy","disgust"],Da={fear:"fear",afraid:"fear",anxiety:"fear",anger:"anger",angry:"anger",mad:"anger",sad:"sad",sadness:"sad",sorrow:"sad",neutral:"neutral",calm:"neutral",love:"love",loving:"love",affection:"love",happy:"happy",happiness:"happy",joy:"happy",joyful:"happy",excited:"happy",disgust:"disgust",disgusted:"disgust"};function Ze(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?Da[n]??t:t}function qi(e){return e===0?null:kt(Vt(e),"eyes_standard")}function Yi(e){return qi(mt(e))}const Ba={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function ar(e,t){if(!e)return null;if(t(e))return e;const n=e.match(/^brow_(-?\d+)\/(eyes_[^/]+)_minus_sil\.png$/);if(n){const i=Number(n[1]),s=n[2];for(const a of Lr(i)){if(a===i)continue;const u=kt(Vt(a),s);if(t(u))return u}const o=Ba[i];if(o){const a=kt(o,s);if(t(a))return a}return null}const r=e.match(/^(fear|anger|sad|neutral|love|happy|disgust)\/(eyes_[^/]+)_minus_sil\.png$/);if(r){const i=r[1],s=r[2],o=mt(i);for(const a of[o,...Lr(o)]){const u=kt(Vt(a),s);if(t(u))return u}}return null}function Or(e,t){const n=Vt(mt(e));return!t||t==="eyes_standard"?Yi(e):e==="neutral"&&t==="eyes_standard"?null:kt(n,t)}function Fa(e,t){const n=[];for(const r of t)n.push(Or(e,r));for(let r=t.length-2;r>=0;r--)n.push(Or(e,t[r]));return n.push(Yi(e)),n}function La(e){return kt(Vt(e),"eyes_standard")}function Oa(e,t){return Ca(e,t).map(La)}const Na=6;function Va(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Ua(e){const t=Qe(e);return t>=an?an:Qe(t+Na)}function Wa(e,t,n){const r=Qe(n);return Va(t,e)?.emphasis?Ua(r):r}function Nr(e){if(!e)return 0;const t=e.match(/^brow_(-?\d+)\//);if(!t?.[1])return null;const n=Number.parseInt(t[1],10);return Number.isFinite(n)?Qe(n):null}function Ye(e,t){return e+Math.random()*(t-e)}function Vr(){return Ye(14,32)}function za(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:Ye(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:Ye(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?Ye(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function Ur(e,t){const n=Ye(e.holdMinMs,e.holdMaxMs);return t?n+e.closedExtraMs:n}function Ha(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:n=2200,intervalMaxMs:r=5800,doubleBlinkChance:i=.18,doubleBlinkGapMinMs:s=120,doubleBlinkGapMaxMs:o=220,fullBlinkChance:a=.75,postEmotionChangeDelayMs:u=380,minDwellMs:d=550}=e;let l="neutral",c="neutral",m=0,w=0,T=0,f={kind:"idle",nextBlinkAt:performance.now()+t},E=null,D="__eyes_open__|neutral|brow:0";function B(I=l){D=`${E??"__eyes_open__"}|${I}|brow:${w}`}function v(I,V=l){E=I;const G=Nr(I);G!=null?w=G:I==null&&(w=0),B(V)}function k(I){return qi(I)}function L(I,V,G){const ae=Qe(V),se=Qe(G);if(m=se,ae===se){v(k(se));return}const re=[...Oa(ae,se),k(se)];f={kind:"browBlend",paths:re,index:0,holdUntil:I+Vr(),targetBrow:se},v(re[0]??null)}function A(I,V){f={kind:"idle",nextBlinkAt:I+Ye(n,r)},c=V,v(k(m),V)}function ie(I,V,G){const ae=G?Aa:Math.random()<a?Ia:Ma,se=za(G),re=ae.length-1;f={kind:"playing",paths:Fa(V,ae),index:0,holdUntil:I+Ur(se,re===0),after:"idle",blinkEmotion:V,pace:se,closedFrameIndex:re},c=V,v(f.paths[0]??null,V)}function de(I){if(f.kind==="browBlend"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Vr();const V=f.paths[f.index]??null;v(V),I>=f.holdUntil&&f.index>=f.paths.length-1&&(w=f.targetBrow,m=f.targetBrow,v(k(f.targetBrow)),f={kind:"idle",nextBlinkAt:I+u});return}if(f.kind==="idle"){v(k(m),c),I>=f.nextBlinkAt&&ie(I,c,!1);return}if(f.kind==="doublePause"){v(k(m),f.blinkEmotion),I>=f.resumeAt&&ie(I,f.blinkEmotion,!0);return}if(f.kind==="playing"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Ur(f.pace,f.index===f.closedFrameIndex);if(v(f.paths[f.index]??null,f.blinkEmotion),I>=f.holdUntil&&f.index>=f.paths.length-1){if(f.after==="resumeIdle"){A(I+u,l);return}if(f.after==="doublePause"){f={kind:"doublePause",resumeAt:I+Ye(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}if(f.after==="idle"&&Math.random()<i){f={kind:"doublePause",resumeAt:I+Ye(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}A(I,f.blinkEmotion)}}}return{advance:de,setTargetEmotion(I,V){const G=Ze(I,l);if(G===l)return;const ae=performance.now();!V?.force&&d>0&&!(l==="neutral"&&G!=="neutral")&&ae-T<d||(l=G,c=G,T=ae)},setTargetEyebrow(I){const V=Qe(I);if(V===m)return;const G=performance.now(),ae=f.kind==="browBlend"?Nr(E)??w:w;m=V,!(V===ae&&f.kind!=="browBlend")&&(f.kind==="playing"||f.kind==="doublePause"||L(G,ae,V))},snapToEmotion(I){const V=Ze(I),G=mt(V);l=V,c=V,m=G,w=G,T=performance.now(),f={kind:"idle",nextBlinkAt:performance.now()+Ye(4e3,7e3)},v(k(G),V)},getTargetEmotion:()=>l,getTargetEyebrow:()=>m,getExpressionPath:()=>E,getDrawKey:()=>D,reset(){l="neutral",c="neutral",m=0,w=0,T=0,A(performance.now()+Ye(n,r),"neutral")}}}function $a(){const e=document.createElement("video");e.muted=!0,e.playsInline=!0,e.preload="auto",e.setAttribute("playsinline",""),e.loop=!0;let t=!1,n=null,r="";const i=()=>{n&&(URL.revokeObjectURL(n),n=null)};return{async load(s){t&&r===s||(i(),t=!1,r=s,s.startsWith("blob:")&&(n=s),await new Promise((o,a)=>{const u=()=>{const d=e.duration;if(!Number.isFinite(d)||d<=0){a(new Error(`Idle video has invalid duration: ${s}`));return}t=!0,e.currentTime=0,o()};e.addEventListener("loadeddata",u,{once:!0}),e.addEventListener("error",()=>a(new Error(`Failed to load idle video: ${s}`)),{once:!0}),e.src=s,e.load()}))},isReady(){return t},getVideo(){return e},setActive(s){t&&(s?e.paused&&e.play().catch(()=>{}):e.paused||e.pause())},restart(){t&&(e.currentTime=0)},dispose(){e.pause(),e.removeAttribute("src"),e.load(),i(),t=!1,r=""}}}const ja=50,Qi=400;function Ka(e,t,n){return e.filter(r=>{const i=r.queueIndex??-1;return i>=t&&i<=n})}function Ga(e,t){const n=[];for(const r of e){const i=Ka(t,r.start_word,r.end_word);if(i.length===0)continue;const s=i[0],o=i[i.length-1];n.push({sentence:r,startMs:Math.max(0,s.wtime-ja),endMs:o.wtime+o.wduration+Qi})}return n.sort((r,i)=>r.startMs-i.startMs)}function qa(e,t,n,r="neutral"){const i=Ze(r);if(t.length===0)return i;if(n.length===0||e<n[0].wtime)return Ze(t[0]?.emotion,i);const s=Ga(t,n);let o=null;for(const d of s)e>=d.startMs&&e<=d.endMs&&(o=d);if(o)return Ze(o.sentence.emotion,i);const a=n[n.length-1],u=a.wtime+a.wduration;return e>u+Qi?Ze(t[t.length-1]?.emotion,i):i}function or(e,t,n,r,i=$i){const s=new OffscreenCanvas(n,r),o=s.getContext("2d",{willReadFrequently:!0});o.drawImage(e,0,0,n,r);const a=o.getImageData(0,0,n,r),u=o.createImageData(n,r);u.data.set(a.data);const l=new OffscreenCanvas(n,r).getContext("2d",{willReadFrequently:!0});for(const c of t){l.clearRect(0,0,n,r),l.drawImage(c,0,0,n,r);const m=l.getImageData(0,0,n,r);for(let w=0;w<u.data.length;w+=4){const T=m.data[w],f=m.data[w+1],E=m.data[w+2];Math.max(T,f,E)>i&&(u.data[w]=T,u.data[w+1]=f,u.data[w+2]=E,u.data[w+3]=255)}}return o.putImageData(u,0,0),s}let ut=null,It=null;const on=new Map;function Ya(){ut=null,It=null,on.clear()}fi(Ya);function Qa(e){return e??It??void 0}function cr(e){return new Promise((t,n)=>{const r=new Image;r.decoding="async",r.onload=()=>t(r),r.onerror=()=>n(new Error(`Failed to load image: ${e}`)),r.src=e})}async function Xa(e){return Wt()?pa(await Mt(sn(),e??"")):cr(sn())}async function Wr(e,t,n,r){const i=n?await Hi(e,r):await fetch(e).then(d=>{if(!d.ok)throw new Error(`Failed to load ${e}`);return d.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=n?await ga(await Mt(Ki(t,s.path,n),r??"")):await cr(`${t}/${s.path}`),a=new Map;for(const d of i.cells??[])d.path&&a.set(d.path,d);const u=new Map;for(const d of i.sheets??[])u.set(d.index,d);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:u,diffBase:t}}async function Un(e){const t=Qa(e),n=Wt();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(ut&&(!n||It===(t??null))){const s=await ut;return{...At(s),visemePaths:[...s.viseme.cellByPath.keys()]}}It=t??null,on.clear();const r=mi();ut=(async()=>{const s=await Xa(t),o=await Wr(hi(),r,n,t);let a=null;try{a=await Wr(gi(),r,n,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await ut;return{...At(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function lr(e){if(await Un(e),!ut)throw new Error("Assets not loaded");return ut}function At(e){return Ui(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Ja(e,t){const n=document.createElement("canvas");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}async function cn(e,t,n){const r=`${t.diffBase}::${n}`,i=on.get(r);if(i)return i;const s=(async()=>{const o=t.cellByPath.get(n);if(!o)throw new Error(`No atlas cell for path: ${n}`);const a=Wi(t.atlasMeta,o),u=At(e);if(zi(o)){const c=Ja(t,o),m=document.createElement("canvas");m.width=u.width,m.height=u.height;const w=m.getContext("2d");return w.fillStyle="#000",w.fillRect(0,0,u.width,u.height),w.drawImage(c,a.x,a.y),m}const d=`${t.diffBase}/${n}`,l=await cr(d);if(l.naturalWidth===u.width&&l.naturalHeight===u.height)return l;throw new Error(`Diff PNG wrong size for ${n}`)})();return on.set(r,s),s}async function Mn(e,t,n,r,i,s){if(i){const{width:w,height:T}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const f=document.createElement("canvas");f.width=w,f.height=T;const E=f.getContext("2d");if(E.clearRect(0,0,w,T),E.drawImage(t,0,0,w,T),s&&!s())return;(e.width!==w||e.height!==T)&&(e.width=w,e.height=T);const D=e.getContext("2d");D.clearRect(0,0,w,T),D.drawImage(f,0,0);return}const o=await lr(),a=vn(o.viseme.atlasMeta),{width:u,height:d}=At(o);(e.width!==u||e.height!==d)&&(e.width=u,e.height=d);const l=[],c=e.getContext("2d");if(c.clearRect(0,0,u,d),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const w=o.sil;c.drawImage(w,0,0,u,d);return}if(l.length===0){c.drawImage(t,0,0,u,d);return}const m=or(t,l,u,d,a);c.drawImage(m,0,0)}async function Wn(e,t,n){const r=await lr(It??void 0),i=vn(r.viseme.atlasMeta),{width:s,height:o}=At(r);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];if(t.mouthPath){const l=new Set(r.viseme.cellByPath.keys()),c=ir(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await cn(r,r.viseme,c))}if(t.expressionPath&&r.expression){const l=ar(t.expressionPath,c=>r.expression.cellByPath.has(c));l&&a.push(await cn(r,r.expression,l))}const u=e.getContext("2d");if(u.clearRect(0,0,s,o),a.length===0){u.drawImage(r.sil,0,0,s,o);return}const d=or(r.sil,a,s,o,i);u.drawImage(d,0,0)}async function Za(e,t){const n=await lr(It??void 0),r=vn(n.viseme.atlasMeta),{width:i,height:s}=At(n),o=[];if(e.mouthPath){const l=new Set(n.viseme.cellByPath.keys()),c=ir(e.mouthPath,l)??(l.has(e.mouthPath)?e.mouthPath:null);c&&o.push(await cn(n,n.viseme,c))}if(e.expressionPath&&n.expression){const l=ar(e.expressionPath,c=>n.expression.cellByPath.has(c));l&&o.push(await cn(n,n.expression,l))}const a=new OffscreenCanvas(i,s),u=a.getContext("2d");if(o.length===0)return u.drawImage(n.sil,0,0,i,s),a.transferToImageBitmap();const d=or(n.sil,o,i,s,r);return u.drawImage(d,0,0),a.transferToImageBitmap()}async function eo(e){await Wn(e,{mouthPath:null,expressionPath:null})}const en={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function to(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function no(e){if(!e)return{enabled:!1,style:en};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??en.fontFamily,fontSize:t.fontSize??en.fontSize,color:t.color??en.color}}}const ro={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},io={display:"inline-block",maxWidth:"100%",padding:"0.45rem 0.85rem",borderRadius:"0.75rem",background:"rgba(0,0,0,0.55)",lineHeight:1.4,textAlign:"center"},so={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function ao({text:e,style:t}){return R.jsx("div",{style:ro,"aria-live":"polite","aria-atomic":"true",children:R.jsx("div",{style:{...io,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:R.jsx("p",{style:so,children:e})})})}const oo={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},co={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},lo={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function uo({thumbnailUrl:e}){const[t,n]=h.useState(!1);h.useEffect(()=>{n(!1)},[e]);const r=!!e&&t;return R.jsxs("div",{style:oo,"aria-hidden":!0,children:[e?R.jsx("img",{src:e,alt:"",style:{...co,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,R.jsx("div",{style:{...lo,background:r?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Xi=null;function zr(e){Xi=e}function at(){return Xi}function fo(e){return`${e.from}→${e.to}@${e.fromVtime}`}function Hr(){return{rafTicksSpeaking:0,rafTicksDeduped:0,drawsRequested:0,drawsDisplayed:0,queueSuperseded:0,workerStale:0,rifeFramesOmittedByGap:0,transitionFramesSampled:0,transitionFramesDisplayed:0,transitionFramesMissed:0,bufferTicks:0,bufferHits:0,bufferUnderruns:0,bufferPrefetched:0}}function mo(){let e=Hr();const t=new Set,n=new Set,r=new Set;let i="",s=-1,o="";const a=()=>{e=Hr(),t.clear(),n.clear(),r.clear(),i="",s=-1,o=""},u=l=>{t.add(l)},d=l=>{l&&r.add(l)};return{reset:a,onRafTickSpeaking(){e.rafTicksSpeaking+=1},onDrawDeduped(){e.rafTicksDeduped+=1},onDrawRequested(){e.drawsRequested+=1},onQueueSuperseded(){e.queueSuperseded+=1},onWorkerStale(){e.workerStale+=1},onTransitionSample(l,c){const m=fo(l);e.transitionFramesSampled+=1,m!==i&&(i=m,s=-1,o!==m&&(o=m,e.rifeFramesOmittedByGap+=l.omittedByGap)),c&&n.add(c),s>=0&&l.frameIdx>s+1&&(e.transitionFramesMissed+=l.frameIdx-s-1),s=l.frameIdx},onBufferTick(){e.bufferTicks+=1},onBufferHit(){e.bufferHits+=1},onBufferUnderrun(){e.bufferUnderruns+=1},onBufferPrefetched(){e.bufferPrefetched+=1},onBufferReset(){},onDrawDisplayed(l,c){if(e.drawsDisplayed+=1,l.transitionMeta){e.transitionFramesDisplayed+=1;const w=l.transitionMeta;u(w.fromVtime),u(w.toVtime),d(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const m=l.label.trim();if(!(!m||m==="sil")){for(const w of c)if(w.viseme===m&&l.elapsedMs>=w.vtime&&l.elapsedMs<w.vtime+w.vduration){u(w.vtime);break}}},snapshot(l,c){let m=0,w=0;for(const B of l)if(B.viseme!=="sil"){if(B.vtime>=c)break;m+=1,t.has(B.vtime)&&(w+=1)}const T=m>0?Math.round(w/m*100):100,f=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),E=m-w,D=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:D,renderLoss:f,visemeSlotsTotal:m,visemeSlotsCovered:w,visemeCoveragePct:T,transitionFramesUniqueSampled:n.size,transitionFramesUniquePainted:r.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+f,visemesShown:w,visemesSkipped:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Ji=jn,ho=200,$r=300,go=100,wo=600,Zi="__sil__";function jr(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===Zi:!1}function ur(){return{lastDrawnKey:""}}function Be(e){e.lastDrawnKey="",e.transitionCache=void 0}function po(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const n=Pi(e);return t&&(t.transitionCache={queueLength:e.length,transitions:n}),n}function yo(e,t){let n="sil";for(const r of e)r.viseme!=="sil"&&(t!=null&&r.vtime>t||(n=r.viseme));return n}function vo(e,t,n,r=120){if(n!=="sil")return n;const i=Oi(e,t,r);return i!=="sil"?i:yo(e,t)}function _o(e,t){return e==="sil"?!1:t?Sa(e,"sil",t):sr(e,"sil").length>0}function bo(){return Ji+wo}function ln(e){return e??Zi}function dr(e,t,n,r,i=go){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=lt(e))return{diffPath:null,label:"sil"};const s=po(e,r),o=na(s,t);if(o){const d=Ci(o.fromVtime,o.toVtime,o.from,o.to);if(t>=d.transStart&&t<d.transEnd){let l=sr(o.from,o.to);n&&(l=ji(l,n));const c=ka(l,d.effectiveGapMs);if(c.length>0){const m=Ea(t,d.transStart,d.transEnd,c.length);return{diffPath:c[m]??c[c.length-1],label:`${o.from}→${o.to}`,transitionMeta:{from:o.from,to:o.to,fromVtime:o.fromVtime,toVtime:o.toVtime,frameIdx:m,frameCount:c.length,fullFrameCount:l.length,omittedByGap:Math.max(0,l.length-c.length)}}}return{diffPath:xt(o.to),label:o.to}}}const a=gn(e);let u=xi(a,t);return u==="sil"&&(u=Oi(e,t,i)),u==="sil"?{diffPath:null,label:"sil"}:{diffPath:xt(u),label:u}}function Ut(e,t){const n=t??ln(e.expressionPath);return`${ln(e.mouthPath)}|${n}`}function Kr(e,t,n,r,i,s,o,a,u,d){const l=dr(t,n,u,s),c={mouthPath:l.diffPath,expressionPath:r},m=Ut(c,i),w=at();if(l.transitionMeta&&w?.onTransitionSample(l.transitionMeta,l.diffPath),m===s.lastDrawnKey){w?.onDrawDeduped();return}w?.onDrawRequested(),a(l),s.lastDrawnKey=m,o(e,c,m,T=>{T===m&&(s.lastDrawnKey=m)})}function Pn(e,t,n,r,i,s,o=null,a=null){const u={mouthPath:a,expressionPath:t},d=o!=null?`|idle@${Math.round(o*1e3)}`:"",l=Ut(u,n)+d;!(o!=null)&&l===r.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,u,l,m=>{m===l&&(r.lastDrawnKey=l)}))}function es(e,t,n,r,i=Ot,s){if(n<=t||e.length===0)return[];const o=s??ur(),a=[];let u="";for(let d=t;d<n;d+=i){const l=dr(e,d,r,o),c=ln(l.diffPath);c!==u&&(u=c,a.push({displayAtMs:d,mouthPath:l.diffPath,mouthKey:c,label:l.label}))}return a}const So=3;function fr(e){let t=0;const n=[];let r=!1,i=!1;const s=async()=>{if(!r){r=!0;try{for(;n.length>0;){const a=n.shift(),u=++t;await e(a.diffs,u,a)&&u===t&&a.onDisplayed?.(a.drawKey)}}finally{r=!1,n.length>0&&s()}}},o=()=>{i||(i=!0,queueMicrotask(()=>{i=!1,s()}))};return{enqueue(a,u,d){const l=n.findIndex(c=>c.drawKey===u);l>=0?n[l]={diffs:a,drawKey:u,onDisplayed:d}:(n.length>=So&&(n.shift(),at()?.onQueueSuperseded()),n.push({diffs:a,drawKey:u,onDisplayed:d})),o()},reset(){t+=1,n.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function To(e,t=2){const n=[],r=new Set;let i=0,s=!1,o=0;const a=(d,l)=>`${d}|${l}`,u=async()=>{if(!s){s=!0;try{for(;i<t&&n.length>0;){const d=n.shift(),l=a(d.displayAtMs,d.drawKey);if(r.has(l))continue;r.add(l),i+=1;const c=o;try{await e(d)}finally{if(r.delete(l),i-=1,c!==o)return}}}finally{s=!1,n.length>0&&i<t&&u()}}};return{enqueue(d){const l=a(d.displayAtMs,d.drawKey);r.has(l)||n.some(c=>a(c.displayAtMs,c.drawKey)===l)||(n.push(d),u())},isQueuedOrInflight(d,l){const c=a(d,l);return r.has(c)?!0:n.some(m=>a(m.displayAtMs,m.drawKey)===c)},reset(){o+=1,n.length=0,r.clear(),i=0},pendingCount(){return n.length+i}}}function ko(){const e=new Map,t=n=>{n.bitmap.close()};return{has(n,r){return e.has(r)},markRendered(n,r,i,s,o){const a=e.get(r);a&&t(a),e.set(r,{displayAtMs:n,mouthKey:r,label:i,mouthPath:s,bitmap:o})},findForMouthKey(n){return e.get(n)??null},removeThrough(n){},pruneBefore(n){},reset(){for(const n of e.values())t(n);e.clear()},size(){return e.size}}}function Eo(e,t,n,r,i,s){const o=es(t,n,r,i,Ot,s);if(o.length===0)return{ready:0,total:0};let a=0;for(const u of o)e.has(u.displayAtMs,u.mouthKey)&&(a+=1);return{ready:a,total:o.length}}function xo(e){const t=ko(),n=ur(),r=new Set;let i="",s=null;const o=To(async c=>{try{if(!e.supportsBufferedPlayback)return;const m=await e.compositePrefetchFrame(c.diffs,c.mouthKey);if(!m)return;t.markRendered(c.displayAtMs,c.mouthKey,c.label,c.mouthPath,m),at()?.onBufferPrefetched()}finally{r.delete(c.mouthKey)}},_s),a=c=>{for(const m of c)t.has(m.displayAtMs,m.mouthKey)||r.has(m.mouthKey)||o.isQueuedOrInflight(0,m.mouthKey)||(r.add(m.mouthKey),o.enqueue({...m,displayAtMs:0,drawKey:m.mouthKey,diffs:{mouthPath:m.mouthPath,expressionPath:null}}))},u=(c,m,w,T=In)=>{if(!e.supportsBufferedPlayback)return;const f=Math.max(0,m-Ot*4),E=es(c,f,m+T,w,Ot,n);a(E)},d=(c,m)=>{i=c,s=m},l=(c,m)=>!(i!==c||s!==m);return{reset(){t.reset(),o.reset(),r.clear(),Be(n),i="",s=null,at()?.onBufferReset()},markExternallyDisplayed(c,m){d(c.split("|")[0]??c,m)},warmupTick(c){e.supportsBufferedPlayback&&u(c.queue,0,c.availablePaths,Math.max(Er,In))},isWarmupReady(c,m=Er){if(!e.supportsBufferedPlayback)return!0;const{ready:w,total:T}=Eo(t,c.queue,0,m,c.availablePaths,n);return T===0?!1:w/T>=vs},getBufferedFrameCount:()=>t.size(),tick(c){const m=at();m?.onBufferTick(),u(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-In);const w=dr(c.queue,c.elapsedMs,c.availablePaths,n),T=ln(w.diffPath),f=Ut({mouthPath:w.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),E=()=>(d(T,c.expressionPath),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(T,c.expressionPath)||c.playbackState.lastDrawnKey===f)return E();const D=t.findForMouthKey(T,c.elapsedMs,Ot);return D&&c.expressionPath!=null?(m?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):D?(e.blitBitmap(c.canvas,D.bitmap),d(D.mouthKey,c.expressionPath),c.playbackState.lastDrawnKey=f,c.onStatus({diffPath:D.mouthPath,label:D.label}),c.onDisplayed(f,D.mouthPath,D.label),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(m?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const Io=`
5
+ `);Ie=Ue.pop()??"";for(const Re of Ue)await Ke(Re);if(rt){Ie.trim()&&await Ke(Ie.trim()),Te===U&&!ce.signal.aborted&&A&&z.markStreamComplete(n);break}}}catch(Be){if(ce.signal.aborted||!A)return;console.error("[realtimeVoice] avatar_speak failed:",Be),e("error"),H()}finally{I===ce&&(I=null)}},he=g=>{const P=ha(g);if(!P){console.warn("[realtimeVoice] server message with no payload",g);return}const ne=String(P.type??"unknown");switch(ne!=="avatar_metadata"&&ne!=="avatar_audio_chunk"&&ne!=="avatar_lipsync"&&ne!=="avatar_interrupt"&&ne!=="error"&&console.debug("[realtimeVoice] server message",ne,P),ne){case"avatar_metadata":x(P);break;case"avatar_audio_chunk":T(P);break;case"avatar_lipsync":Q(P);break;case"avatar_interrupt":re(P);break;case"error":{const ce=String(P.message??"Voice session error");console.error("[realtimeVoice] server error:",ce),e("error"),H();break}case"avatar_speak":V(P);break}},De=()=>w||(S=new da,w=new ds.PipecatClient({transport:new Hn.WebSocketTransport({mediaManager:S,serializer:new ua,recorderSampleRate:rr,playerSampleRate:ir}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{m=!0,e("idle"),H()},onDisconnected:()=>{m=!1,p()},onError:g=>{const P=typeof g=="object"&&g!==null&&"data"in g?String(g.data??g):String(g);console.error("[realtimeVoice]",P,g),e("error"),H()},onTransportStateChanged:g=>{g==="error"&&(e("error"),H())},onServerMessage:g=>{j(g)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{_(),ue("bot_started")},onBotStoppedSpeaking:()=>{A&&Z()},onUserTranscript:g=>{String(g.text??""),f.onUserTranscript?.(g.text,!!g.final)},onBotOutput:g=>{f.onBotOutput?.(g.text)}}}),w);return{setDeveloperToken:g=>{},setTtsEngineId:g=>{c=g,z.setStreamTtsEngineId(g)},getTtsEngineId:()=>c,speak:async(g,P)=>{const ne=g.trim();if(ne){if(!w||!m)throw new Error("Realtime voice is not connected. Call connect() first.");Y(),await w.sendText(ne)}},stop:()=>{I?.abort(),I=null,U+=1,_(),Y(),e("idle"),H()},connect:async g=>{g&&(f={...f,...g});const P=et(f.ttsEngineId,f.voiceId);if(P.ttsEngineId&&(c=P.ttsEngineId,z.setStreamTtsEngineId(c)),f={...f,ttsEngineId:c,...P.voiceId?{voiceId:P.voiceId}:{}},!f.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const ne=De();await ne.initDevices();const ce=Ui({...f,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",ce);try{await ne.connect({wsUrl:ce})}catch(Te){m=!1,e("error"),H();const be=Te instanceof Error?Te.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${be} — ${ce}`)}m=!0,e("idle"),H()},disconnect:async()=>{if(L(),q=!1,oe=!1,v.length=0,k=!1,I?.abort(),I=null,U+=1,_(),w)try{await w.disconnect()}catch(g){console.error("[realtimeVoice] disconnect failed:",g)}m=!1,p()},isConnected:()=>m,unlockAudio:async()=>{await z.primeAudioContext()},getVisemeQueue:()=>n,getWordQueue:()=>r,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:J,isSpeaking:()=>z.isSpeaking(),isWarmingUp:()=>z.isWarmingUp(),releaseWarmupHold:()=>z.releaseWarmupHold(),setLipsyncWarmupHold:(g,P)=>{P&&(me=P),z.setLipsyncWarmupHoldEnabled(g)},getVoiceStream:()=>z.getVoiceStream(),setPlaybackSpeed:g=>{z.setPlaybackSpeed(g)},getPlaybackSpeed:()=>z.getPlaybackSpeed(),subscribe:g=>(B.add(g),()=>B.delete(g))}}function Wi(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function zi(e,t){const n=e.crop;return{x:t?.source_x??n?.x??0,y:t?.source_y??n?.y??0,width:t?.source_w??n?.width??e.frame_width??0,height:t?.source_h??n?.height??e.frame_height??0}}function Hi(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Pt(e,t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to load encrypted asset: ${e}`);const r=await n.arrayBuffer();return Fs(r,t)}async function $i(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Pt(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function wa(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function pa(e){const t=new Blob([e],{type:"image/webp"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted image"))},s.src=n})}async function ya(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function va(e){const t=new Blob([e],{type:"image/png"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted PNG"))},s.src=n})}function _a(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function ba(e){const t=Os();if(!Wt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Pt(t,e);return _a(n)}function Et(e,t){return`${e}/${t}_minus_sil.png`}const ji=5;function vn(e){const t=e?.composite_threshold;if(typeof t=="number"&&t>0)return t;const n=e?.crop?.content_threshold;return typeof n=="number"&&n>0?n:ji}const Sa=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Un=["t01_0.25","t02_0.50","t03_0.75"],Ta=Un.length,Br=new Set(["aa__kk","aa__nn","aa__sil","CH__aa","CH__DD","CH__E","CH__FF","CH__I","CH__kk","CH__nn","CH__O","CH__PP","CH__RR","CH__sil","CH__SS","CH__TH","CH__U","DD__aa","DD__E","DD__FF","DD__I","DD__kk","DD__nn","DD__O","DD__PP","DD__RR","DD__sil","DD__SS","DD__TH","DD__U","E__aa","E__FF","E__I","E__kk","E__nn","E__O","E__PP","E__RR","E__sil","E__SS","E__TH","E__U","FF__aa","FF__I","FF__kk","FF__nn","FF__O","FF__PP","FF__RR","FF__sil","FF__SS","FF__TH","FF__U","I__aa","I__kk","I__nn","I__O","I__PP","I__RR","I__sil","I__SS","I__TH","I__U","kk__nn","kk__sil","nn__sil","O__aa","O__kk","O__nn","O__PP","O__RR","O__sil","O__SS","O__TH","O__U","PP__aa","PP__kk","PP__nn","PP__RR","PP__sil","PP__SS","PP__TH","PP__U","RR__aa","RR__kk","RR__nn","RR__sil","RR__SS","RR__TH","RR__U","SS__aa","SS__kk","SS__nn","SS__sil","SS__TH","SS__U","TH__aa","TH__kk","TH__nn","TH__sil","TH__U","U__aa","U__kk","U__nn","U__sil"]);function Fr(e,t){return`${e}__${t}`}function Lr(e,t){return`pairs/${e}/${t}_minus_sil.png`}function It(e){return`${e}_minus_sil.png`}function sr(e,t){if(t.has(e))return e;const n=/^pairs\/([^/]+)\//.exec(e);if(!n)return null;const r=n[1].split("__")[1];if(!r||r==="sil")return null;const i=It(r);return t.has(i)?i:null}function Ki(e,t){return e.filter(n=>t.has(n))}function ka(e,t,n){const r=ar(e,t);return Ki(r,n).length>0}function ar(e,t){if(e===t)return[];const n=[],r=Fr(e,t);if(Br.has(r)){for(const s of Un)n.push(Lr(r,s));return n}const i=Fr(t,e);if(Br.has(i)){for(let s=Ta-1;s>=0;s--)n.push(Lr(i,Un[s]));return n}return[]}function Ea(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function xa(e,t){return Ea(t).map(r=>e[r]).filter(r=>r!=null)}function Ia(e,t,n,r){if(r<=0)return 0;const s=Math.max(1,n-t)/r,o=e-t,a=Math.floor(o/s);return Math.min(r-1,Math.max(0,a))}function Gi(e,t,n){if(!n)return`${e}/${t}`;const r=t.split("/").pop()??t,i=r.includes(".")?r.slice(0,r.lastIndexOf(".")):r;return`${e}/${i}.bin`}const Aa=[.32,.24,.16,.08,0],Ma=Aa.map(e=>`eyes_${e.toFixed(2)}`),Pa=["eyes_0.32","eyes_0.16","eyes_0.00"],Ra=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],He=2,Ca=-20,an=16,qi={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function Ut(e){return`brow_${e}`}function ht(e){return qi[e]}function Xe(e){return Math.max(Ca,Math.min(an,e))}function Da(e,t){if(e===t)return[];const n=e<t,r=n?He:-He,i=[];let s=e;if(s%He!==0){const o=n?Math.ceil(s/He)*He:Math.floor(s/He)*He,a=Xe(o);if(n?a>=t:a<=t)return[t];s=a,i.push(s)}for(;;){const o=s+r;if(n?o>=t:o<=t){t!==s&&i.push(t);break}s=o,i.push(s)}return i}function Or(e){const t=Xe(e);if(t%He===0)return[t];const n=Math.floor(t/He)*He,r=Math.min(an,n+He),i=Xe(n);return t-i<=r-t?i===r?[i]:[i,r]:i===r?[r]:[r,i]}const Ba=["fear","anger","sad","neutral","love","happy","disgust"],Fa={fear:"fear",afraid:"fear",anxiety:"fear",anger:"anger",angry:"anger",mad:"anger",sad:"sad",sadness:"sad",sorrow:"sad",neutral:"neutral",calm:"neutral",love:"love",loving:"love",affection:"love",happy:"happy",happiness:"happy",joy:"happy",joyful:"happy",excited:"happy",disgust:"disgust",disgusted:"disgust"};function Ze(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?Fa[n]??t:t}function Yi(e){return e===0?null:Et(Ut(e),"eyes_standard")}function Qi(e){return Yi(ht(e))}const La={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function or(e,t){if(!e)return null;if(t(e))return e;const n=e.match(/^brow_(-?\d+)\/(eyes_[^/]+)_minus_sil\.png$/);if(n){const i=Number(n[1]),s=n[2];for(const a of Or(i)){if(a===i)continue;const u=Et(Ut(a),s);if(t(u))return u}const o=La[i];if(o){const a=Et(o,s);if(t(a))return a}return null}const r=e.match(/^(fear|anger|sad|neutral|love|happy|disgust)\/(eyes_[^/]+)_minus_sil\.png$/);if(r){const i=r[1],s=r[2],o=ht(i);for(const a of[o,...Or(o)]){const u=Et(Ut(a),s);if(t(u))return u}}return null}function Nr(e,t){const n=Ut(ht(e));return!t||t==="eyes_standard"?Qi(e):e==="neutral"&&t==="eyes_standard"?null:Et(n,t)}function Oa(e,t){const n=[];for(const r of t)n.push(Nr(e,r));for(let r=t.length-2;r>=0;r--)n.push(Nr(e,t[r]));return n.push(Qi(e)),n}function Na(e){return Et(Ut(e),"eyes_standard")}function Ua(e,t){return Da(e,t).map(Na)}const Va=6;function Wa(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function za(e){const t=Xe(e);return t>=an?an:Xe(t+Va)}function Ha(e,t,n){const r=Xe(n);return Wa(t,e)?.emphasis?za(r):r}function Ur(e){if(!e)return 0;const t=e.match(/^brow_(-?\d+)\//);if(!t?.[1])return null;const n=Number.parseInt(t[1],10);return Number.isFinite(n)?Xe(n):null}function Qe(e,t){return e+Math.random()*(t-e)}function Vr(){return Qe(14,32)}function $a(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:Qe(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:Qe(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?Qe(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function Wr(e,t){const n=Qe(e.holdMinMs,e.holdMaxMs);return t?n+e.closedExtraMs:n}function ja(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:n=2200,intervalMaxMs:r=5800,doubleBlinkChance:i=.18,doubleBlinkGapMinMs:s=120,doubleBlinkGapMaxMs:o=220,fullBlinkChance:a=.75,postEmotionChangeDelayMs:u=380,minDwellMs:d=550}=e;let l="neutral",c="neutral",m=0,w=0,S=0,f={kind:"idle",nextBlinkAt:performance.now()+t},E=null,D="__eyes_open__|neutral|brow:0";function B(I=l){D=`${E??"__eyes_open__"}|${I}|brow:${w}`}function v(I,U=l){E=I;const q=Ur(I);q!=null?w=q:I==null&&(w=0),B(U)}function k(I){return Yi(I)}function O(I,U,q){const oe=Xe(U),ae=Xe(q);if(m=ae,oe===ae){v(k(ae));return}const ie=[...Ua(oe,ae),k(ae)];f={kind:"browBlend",paths:ie,index:0,holdUntil:I+Vr(),targetBrow:ae},v(ie[0]??null)}function A(I,U){f={kind:"idle",nextBlinkAt:I+Qe(n,r)},c=U,v(k(m),U)}function se(I,U,q){const oe=q?Pa:Math.random()<a?Ma:Ra,ae=$a(q),ie=oe.length-1;f={kind:"playing",paths:Oa(U,oe),index:0,holdUntil:I+Wr(ae,ie===0),after:"idle",blinkEmotion:U,pace:ae,closedFrameIndex:ie},c=U,v(f.paths[0]??null,U)}function le(I){if(f.kind==="browBlend"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Vr();const U=f.paths[f.index]??null;v(U),I>=f.holdUntil&&f.index>=f.paths.length-1&&(w=f.targetBrow,m=f.targetBrow,v(k(f.targetBrow)),f={kind:"idle",nextBlinkAt:I+u});return}if(f.kind==="idle"){v(k(m),c),I>=f.nextBlinkAt&&se(I,c,!1);return}if(f.kind==="doublePause"){v(k(m),f.blinkEmotion),I>=f.resumeAt&&se(I,f.blinkEmotion,!0);return}if(f.kind==="playing"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Wr(f.pace,f.index===f.closedFrameIndex);if(v(f.paths[f.index]??null,f.blinkEmotion),I>=f.holdUntil&&f.index>=f.paths.length-1){if(f.after==="resumeIdle"){A(I+u,l);return}if(f.after==="doublePause"){f={kind:"doublePause",resumeAt:I+Qe(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}if(f.after==="idle"&&Math.random()<i){f={kind:"doublePause",resumeAt:I+Qe(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}A(I,f.blinkEmotion)}}}return{advance:le,setTargetEmotion(I,U){const q=Ze(I,l);if(q===l)return;const oe=performance.now();!U?.force&&d>0&&!(l==="neutral"&&q!=="neutral")&&oe-S<d||(l=q,c=q,S=oe)},setTargetEyebrow(I){const U=Xe(I);if(U===m)return;const q=performance.now(),oe=f.kind==="browBlend"?Ur(E)??w:w;m=U,!(U===oe&&f.kind!=="browBlend")&&(f.kind==="playing"||f.kind==="doublePause"||O(q,oe,U))},snapToEmotion(I){const U=Ze(I),q=ht(U);l=U,c=U,m=q,w=q,S=performance.now(),f={kind:"idle",nextBlinkAt:performance.now()+Qe(4e3,7e3)},v(k(q),U)},getTargetEmotion:()=>l,getTargetEyebrow:()=>m,getExpressionPath:()=>E,getDrawKey:()=>D,reset(){l="neutral",c="neutral",m=0,w=0,S=0,A(performance.now()+Qe(n,r),"neutral")}}}function Ka(){const e=document.createElement("video");e.muted=!0,e.playsInline=!0,e.preload="auto",e.setAttribute("playsinline",""),e.loop=!0;let t=!1,n=null,r="";const i=()=>{n&&(URL.revokeObjectURL(n),n=null)};return{async load(s){t&&r===s||(i(),t=!1,r=s,s.startsWith("blob:")&&(n=s),await new Promise((o,a)=>{const u=()=>{const d=e.duration;if(!Number.isFinite(d)||d<=0){a(new Error(`Idle video has invalid duration: ${s}`));return}t=!0,e.currentTime=0,o()};e.addEventListener("loadeddata",u,{once:!0}),e.addEventListener("error",()=>a(new Error(`Failed to load idle video: ${s}`)),{once:!0}),e.src=s,e.load()}))},isReady(){return t},getVideo(){return e},setActive(s){t&&(s?e.paused&&e.play().catch(()=>{}):e.paused||e.pause())},restart(){t&&(e.currentTime=0)},dispose(){e.pause(),e.removeAttribute("src"),e.load(),i(),t=!1,r=""}}}const Ga=50,Xi=400;function qa(e,t,n){return e.filter(r=>{const i=r.queueIndex??-1;return i>=t&&i<=n})}function Ya(e,t){const n=[];for(const r of e){const i=qa(t,r.start_word,r.end_word);if(i.length===0)continue;const s=i[0],o=i[i.length-1];n.push({sentence:r,startMs:Math.max(0,s.wtime-Ga),endMs:o.wtime+o.wduration+Xi})}return n.sort((r,i)=>r.startMs-i.startMs)}function Qa(e,t,n,r="neutral"){const i=Ze(r);if(t.length===0)return i;if(n.length===0||e<n[0].wtime)return Ze(t[0]?.emotion,i);const s=Ya(t,n);let o=null;for(const d of s)e>=d.startMs&&e<=d.endMs&&(o=d);if(o)return Ze(o.sentence.emotion,i);const a=n[n.length-1],u=a.wtime+a.wduration;return e>u+Xi?Ze(t[t.length-1]?.emotion,i):i}function cr(e,t,n,r,i=ji){const s=new OffscreenCanvas(n,r),o=s.getContext("2d",{willReadFrequently:!0});o.drawImage(e,0,0,n,r);const a=o.getImageData(0,0,n,r),u=o.createImageData(n,r);u.data.set(a.data);const l=new OffscreenCanvas(n,r).getContext("2d",{willReadFrequently:!0});for(const c of t){l.clearRect(0,0,n,r),l.drawImage(c,0,0,n,r);const m=l.getImageData(0,0,n,r);for(let w=0;w<u.data.length;w+=4){const S=m.data[w],f=m.data[w+1],E=m.data[w+2];Math.max(S,f,E)>i&&(u.data[w]=S,u.data[w+1]=f,u.data[w+2]=E,u.data[w+3]=255)}}return o.putImageData(u,0,0),s}let dt=null,At=null;const on=new Map;function Xa(){dt=null,At=null,on.clear()}mi(Xa);function Ja(e){return e??At??void 0}function lr(e){return new Promise((t,n)=>{const r=new Image;r.decoding="async",r.onload=()=>t(r),r.onerror=()=>n(new Error(`Failed to load image: ${e}`)),r.src=e})}async function Za(e){return Wt()?va(await Pt(sn(),e??"")):lr(sn())}async function zr(e,t,n,r){const i=n?await $i(e,r):await fetch(e).then(d=>{if(!d.ok)throw new Error(`Failed to load ${e}`);return d.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=n?await pa(await Pt(Gi(t,s.path,n),r??"")):await lr(`${t}/${s.path}`),a=new Map;for(const d of i.cells??[])d.path&&a.set(d.path,d);const u=new Map;for(const d of i.sheets??[])u.set(d.index,d);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:u,diffBase:t}}async function Vn(e){const t=Ja(e),n=Wt();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(dt&&(!n||At===(t??null))){const s=await dt;return{...Mt(s),visemePaths:[...s.viseme.cellByPath.keys()]}}At=t??null,on.clear();const r=hi();dt=(async()=>{const s=await Za(t),o=await zr(gi(),r,n,t);let a=null;try{a=await zr(wi(),r,n,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await dt;return{...Mt(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function ur(e){if(await Vn(e),!dt)throw new Error("Assets not loaded");return dt}function Mt(e){return Wi(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function eo(e,t){const n=document.createElement("canvas");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}async function cn(e,t,n){const r=`${t.diffBase}::${n}`,i=on.get(r);if(i)return i;const s=(async()=>{const o=t.cellByPath.get(n);if(!o)throw new Error(`No atlas cell for path: ${n}`);const a=zi(t.atlasMeta,o),u=Mt(e);if(Hi(o)){const c=eo(t,o),m=document.createElement("canvas");m.width=u.width,m.height=u.height;const w=m.getContext("2d");return w.fillStyle="#000",w.fillRect(0,0,u.width,u.height),w.drawImage(c,a.x,a.y),m}const d=`${t.diffBase}/${n}`,l=await lr(d);if(l.naturalWidth===u.width&&l.naturalHeight===u.height)return l;throw new Error(`Diff PNG wrong size for ${n}`)})();return on.set(r,s),s}async function Mn(e,t,n,r,i,s){if(i){const{width:w,height:S}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const f=document.createElement("canvas");f.width=w,f.height=S;const E=f.getContext("2d");if(E.clearRect(0,0,w,S),E.drawImage(t,0,0,w,S),s&&!s())return;(e.width!==w||e.height!==S)&&(e.width=w,e.height=S);const D=e.getContext("2d");D.clearRect(0,0,w,S),D.drawImage(f,0,0);return}const o=await ur(),a=vn(o.viseme.atlasMeta),{width:u,height:d}=Mt(o);(e.width!==u||e.height!==d)&&(e.width=u,e.height=d);const l=[],c=e.getContext("2d");if(c.clearRect(0,0,u,d),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const w=o.sil;c.drawImage(w,0,0,u,d);return}if(l.length===0){c.drawImage(t,0,0,u,d);return}const m=cr(t,l,u,d,a);c.drawImage(m,0,0)}async function Wn(e,t,n){const r=await ur(At??void 0),i=vn(r.viseme.atlasMeta),{width:s,height:o}=Mt(r);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];if(t.mouthPath){const l=new Set(r.viseme.cellByPath.keys()),c=sr(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await cn(r,r.viseme,c))}if(t.expressionPath&&r.expression){const l=or(t.expressionPath,c=>r.expression.cellByPath.has(c));l&&a.push(await cn(r,r.expression,l))}const u=e.getContext("2d");if(u.clearRect(0,0,s,o),a.length===0){u.drawImage(r.sil,0,0,s,o);return}const d=cr(r.sil,a,s,o,i);u.drawImage(d,0,0)}async function to(e,t){const n=await ur(At??void 0),r=vn(n.viseme.atlasMeta),{width:i,height:s}=Mt(n),o=[];if(e.mouthPath){const l=new Set(n.viseme.cellByPath.keys()),c=sr(e.mouthPath,l)??(l.has(e.mouthPath)?e.mouthPath:null);c&&o.push(await cn(n,n.viseme,c))}if(e.expressionPath&&n.expression){const l=or(e.expressionPath,c=>n.expression.cellByPath.has(c));l&&o.push(await cn(n,n.expression,l))}const a=new OffscreenCanvas(i,s),u=a.getContext("2d");if(o.length===0)return u.drawImage(n.sil,0,0,i,s),a.transferToImageBitmap();const d=cr(n.sil,o,i,s,r);return u.drawImage(d,0,0),a.transferToImageBitmap()}async function no(e){await Wn(e,{mouthPath:null,expressionPath:null})}const en={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function ro(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function io(e){if(!e)return{enabled:!1,style:en};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??en.fontFamily,fontSize:t.fontSize??en.fontSize,color:t.color??en.color}}}const so={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},ao={display:"inline-block",maxWidth:"100%",padding:"0.45rem 0.85rem",borderRadius:"0.75rem",background:"rgba(0,0,0,0.55)",lineHeight:1.4,textAlign:"center"},oo={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function co({text:e,style:t}){return R.jsx("div",{style:so,"aria-live":"polite","aria-atomic":"true",children:R.jsx("div",{style:{...ao,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:R.jsx("p",{style:oo,children:e})})})}const lo={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},uo={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},fo={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function mo({thumbnailUrl:e}){const[t,n]=h.useState(!1);h.useEffect(()=>{n(!1)},[e]);const r=!!e&&t;return R.jsxs("div",{style:lo,"aria-hidden":!0,children:[e?R.jsx("img",{src:e,alt:"",style:{...uo,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,R.jsx("div",{style:{...fo,background:r?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Ji=null;function Hr(e){Ji=e}function at(){return Ji}function ho(e){return`${e.from}→${e.to}@${e.fromVtime}`}function $r(){return{rafTicksSpeaking:0,rafTicksDeduped:0,drawsRequested:0,drawsDisplayed:0,queueSuperseded:0,workerStale:0,rifeFramesOmittedByGap:0,transitionFramesSampled:0,transitionFramesDisplayed:0,transitionFramesMissed:0,bufferTicks:0,bufferHits:0,bufferUnderruns:0,bufferPrefetched:0}}function go(){let e=$r();const t=new Set,n=new Set,r=new Set;let i="",s=-1,o="";const a=()=>{e=$r(),t.clear(),n.clear(),r.clear(),i="",s=-1,o=""},u=l=>{t.add(l)},d=l=>{l&&r.add(l)};return{reset:a,onRafTickSpeaking(){e.rafTicksSpeaking+=1},onDrawDeduped(){e.rafTicksDeduped+=1},onDrawRequested(){e.drawsRequested+=1},onQueueSuperseded(){e.queueSuperseded+=1},onWorkerStale(){e.workerStale+=1},onTransitionSample(l,c){const m=ho(l);e.transitionFramesSampled+=1,m!==i&&(i=m,s=-1,o!==m&&(o=m,e.rifeFramesOmittedByGap+=l.omittedByGap)),c&&n.add(c),s>=0&&l.frameIdx>s+1&&(e.transitionFramesMissed+=l.frameIdx-s-1),s=l.frameIdx},onBufferTick(){e.bufferTicks+=1},onBufferHit(){e.bufferHits+=1},onBufferUnderrun(){e.bufferUnderruns+=1},onBufferPrefetched(){e.bufferPrefetched+=1},onBufferReset(){},onDrawDisplayed(l,c){if(e.drawsDisplayed+=1,l.transitionMeta){e.transitionFramesDisplayed+=1;const w=l.transitionMeta;u(w.fromVtime),u(w.toVtime),d(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const m=l.label.trim();if(!(!m||m==="sil")){for(const w of c)if(w.viseme===m&&l.elapsedMs>=w.vtime&&l.elapsedMs<w.vtime+w.vduration){u(w.vtime);break}}},snapshot(l,c){let m=0,w=0;for(const B of l)if(B.viseme!=="sil"){if(B.vtime>=c)break;m+=1,t.has(B.vtime)&&(w+=1)}const S=m>0?Math.round(w/m*100):100,f=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),E=m-w,D=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:D,renderLoss:f,visemeSlotsTotal:m,visemeSlotsCovered:w,visemeCoveragePct:S,transitionFramesUniqueSampled:n.size,transitionFramesUniquePainted:r.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+f,visemesShown:w,visemesSkipped:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Zi=jn,wo=200,jr=300,po=100,yo=600,es="__sil__";function Kr(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===es:!1}function dr(){return{lastDrawnKey:""}}function Oe(e){e.lastDrawnKey="",e.transitionCache=void 0}function vo(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const n=Ri(e);return t&&(t.transitionCache={queueLength:e.length,transitions:n}),n}function _o(e,t){let n="sil";for(const r of e)r.viseme!=="sil"&&(t!=null&&r.vtime>t||(n=r.viseme));return n}function bo(e,t,n,r=120){if(n!=="sil")return n;const i=Ni(e,t,r);return i!=="sil"?i:_o(e,t)}function So(e,t){return e==="sil"?!1:t?ka(e,"sil",t):ar(e,"sil").length>0}function To(){return Zi+yo}function ln(e){return e??es}function fr(e,t,n,r,i=po){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=ut(e))return{diffPath:null,label:"sil"};const s=vo(e,r),o=ia(s,t);if(o){const d=Ci(o.fromVtime,o.toVtime,o.from,o.to);if(t>=d.transStart&&t<d.transEnd){let l=ar(o.from,o.to);n&&(l=Ki(l,n));const c=xa(l,d.effectiveGapMs);if(c.length>0){const m=Ia(t,d.transStart,d.transEnd,c.length);return{diffPath:c[m]??c[c.length-1],label:`${o.from}→${o.to}`,transitionMeta:{from:o.from,to:o.to,fromVtime:o.fromVtime,toVtime:o.toVtime,frameIdx:m,frameCount:c.length,fullFrameCount:l.length,omittedByGap:Math.max(0,l.length-c.length)}}}return{diffPath:It(o.to),label:o.to}}}const a=gn(e);let u=Ii(a,t);return u==="sil"&&(u=Ni(e,t,i)),u==="sil"?{diffPath:null,label:"sil"}:{diffPath:It(u),label:u}}function Vt(e,t){const n=t??ln(e.expressionPath);return`${ln(e.mouthPath)}|${n}`}function Gr(e,t,n,r,i,s,o,a,u,d){const l=fr(t,n,u,s),c={mouthPath:l.diffPath,expressionPath:r},m=Vt(c,i),w=at();if(l.transitionMeta&&w?.onTransitionSample(l.transitionMeta,l.diffPath),m===s.lastDrawnKey){w?.onDrawDeduped();return}w?.onDrawRequested(),a(l),s.lastDrawnKey=m,o(e,c,m,S=>{S===m&&(s.lastDrawnKey=m)})}function Pn(e,t,n,r,i,s,o=null,a=null){const u={mouthPath:a,expressionPath:t},d=o!=null?`|idle@${Math.round(o*1e3)}`:"",l=Vt(u,n)+d;!(o!=null)&&l===r.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,u,l,m=>{m===l&&(r.lastDrawnKey=l)}))}function ts(e,t,n,r,i=Ot,s){if(n<=t||e.length===0)return[];const o=s??dr(),a=[];let u="";for(let d=t;d<n;d+=i){const l=fr(e,d,r,o),c=ln(l.diffPath);c!==u&&(u=c,a.push({displayAtMs:d,mouthPath:l.diffPath,mouthKey:c,label:l.label}))}return a}const ko=3;function mr(e){let t=0;const n=[];let r=!1,i=!1;const s=async()=>{if(!r){r=!0;try{for(;n.length>0;){const a=n.shift(),u=++t;await e(a.diffs,u,a)&&u===t&&a.onDisplayed?.(a.drawKey)}}finally{r=!1,n.length>0&&s()}}},o=()=>{i||(i=!0,queueMicrotask(()=>{i=!1,s()}))};return{enqueue(a,u,d){const l=n.findIndex(c=>c.drawKey===u);l>=0?n[l]={diffs:a,drawKey:u,onDisplayed:d}:(n.length>=ko&&(n.shift(),at()?.onQueueSuperseded()),n.push({diffs:a,drawKey:u,onDisplayed:d})),o()},reset(){t+=1,n.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function Eo(e,t=2){const n=[],r=new Set;let i=0,s=!1,o=0;const a=(d,l)=>`${d}|${l}`,u=async()=>{if(!s){s=!0;try{for(;i<t&&n.length>0;){const d=n.shift(),l=a(d.displayAtMs,d.drawKey);if(r.has(l))continue;r.add(l),i+=1;const c=o;try{await e(d)}finally{if(r.delete(l),i-=1,c!==o)return}}}finally{s=!1,n.length>0&&i<t&&u()}}};return{enqueue(d){const l=a(d.displayAtMs,d.drawKey);r.has(l)||n.some(c=>a(c.displayAtMs,c.drawKey)===l)||(n.push(d),u())},isQueuedOrInflight(d,l){const c=a(d,l);return r.has(c)?!0:n.some(m=>a(m.displayAtMs,m.drawKey)===c)},reset(){o+=1,n.length=0,r.clear(),i=0},pendingCount(){return n.length+i}}}function xo(){const e=new Map,t=n=>{n.bitmap.close()};return{has(n,r){return e.has(r)},markRendered(n,r,i,s,o){const a=e.get(r);a&&t(a),e.set(r,{displayAtMs:n,mouthKey:r,label:i,mouthPath:s,bitmap:o})},findForMouthKey(n){return e.get(n)??null},removeThrough(n){},pruneBefore(n){},reset(){for(const n of e.values())t(n);e.clear()},size(){return e.size}}}function Io(e,t,n,r,i,s){const o=ts(t,n,r,i,Ot,s);if(o.length===0)return{ready:0,total:0};let a=0;for(const u of o)e.has(u.displayAtMs,u.mouthKey)&&(a+=1);return{ready:a,total:o.length}}function Ao(e){const t=xo(),n=dr(),r=new Set;let i="",s=null;const o=Eo(async c=>{try{if(!e.supportsBufferedPlayback)return;const m=await e.compositePrefetchFrame(c.diffs,c.mouthKey);if(!m)return;t.markRendered(c.displayAtMs,c.mouthKey,c.label,c.mouthPath,m),at()?.onBufferPrefetched()}finally{r.delete(c.mouthKey)}},bs),a=c=>{for(const m of c)t.has(m.displayAtMs,m.mouthKey)||r.has(m.mouthKey)||o.isQueuedOrInflight(0,m.mouthKey)||(r.add(m.mouthKey),o.enqueue({...m,displayAtMs:0,drawKey:m.mouthKey,diffs:{mouthPath:m.mouthPath,expressionPath:null}}))},u=(c,m,w,S=In)=>{if(!e.supportsBufferedPlayback)return;const f=Math.max(0,m-Ot*4),E=ts(c,f,m+S,w,Ot,n);a(E)},d=(c,m)=>{i=c,s=m},l=(c,m)=>!(i!==c||s!==m);return{reset(){t.reset(),o.reset(),r.clear(),Oe(n),i="",s=null,at()?.onBufferReset()},markExternallyDisplayed(c,m){d(c.split("|")[0]??c,m)},warmupTick(c){e.supportsBufferedPlayback&&u(c.queue,0,c.availablePaths,Math.max(xr,In))},isWarmupReady(c,m=xr){if(!e.supportsBufferedPlayback)return!0;const{ready:w,total:S}=Io(t,c.queue,0,m,c.availablePaths,n);return S===0?!1:w/S>=_s},getBufferedFrameCount:()=>t.size(),tick(c){const m=at();m?.onBufferTick(),u(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-In);const w=fr(c.queue,c.elapsedMs,c.availablePaths,n),S=ln(w.diffPath),f=Vt({mouthPath:w.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),E=()=>(d(S,c.expressionPath),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(S,c.expressionPath)||c.playbackState.lastDrawnKey===f)return E();const D=t.findForMouthKey(S,c.elapsedMs,Ot);return D&&c.expressionPath!=null?(m?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):D?(e.blitBitmap(c.canvas,D.bitmap),d(D.mouthKey,c.expressionPath),c.playbackState.lastDrawnKey=f,c.onStatus({diffPath:D.mouthPath,label:D.label}),c.onDisplayed(f,D.mouthPath,D.label),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(m?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const Mo=`
6
6
  in vec2 aPosition;
7
7
  out vec2 vTextureCoord;
8
8
 
@@ -30,7 +30,7 @@ void main(void)
30
30
  gl_Position = filterVertexPosition();
31
31
  vTextureCoord = filterTextureCoord();
32
32
  }
33
- `,Ao=`
33
+ `,Po=`
34
34
  in vec2 vTextureCoord;
35
35
  out vec4 finalColor;
36
36
 
@@ -44,5 +44,5 @@ void main(void)
44
44
  float keep = step(uThreshold + 1e-6, peak);
45
45
  finalColor = vec4(color.rgb, keep);
46
46
  }
47
- `;function Gr(e=5){const t=new we.Filter({glProgram:we.GlProgram.from({vertex:Io,fragment:Ao,name:"threshold-key-filter"}),resources:{thresholdUniforms:{uThreshold:{value:e/255,type:"f32"}}}});return t.setThreshold=n=>{t.resources.thresholdUniforms.uniforms.uThreshold=n/255},t.getThreshold=()=>Math.round(t.resources.thresholdUniforms.uniforms.uThreshold*255),t}function Mo(e,t,n){return e>n||t>n}function Po(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function Co(e,t){return t!=null&&t>0?Math.floor(t):Po(e)}function Ro(e,t){const n=document.createElement("canvas");n.width=t.w,n.height=t.h;const r=n.getContext("2d");if(!r)throw new Error("Failed to acquire 2d context for atlas cell crop");return r.drawImage(e,t.x,t.y,t.w,t.h,0,0,t.w,t.h),n}function ts(e){return fetch(e).then(t=>{if(!t.ok)throw new Error(`Failed to load image: ${e}`);return t.blob()}).then(t=>createImageBitmap(t))}async function qr(e,t,n,r,i){const s=n?await Hi(e,i):await fetch(e).then(c=>{if(!c.ok)throw new Error(`Failed to load ${e}`);return c.json()}),o=s.sheets?.[0];if(!o?.path)throw new Error(`${e} has no sheets[0].path`);const a=new Map,u=async(c,m)=>{const w=Ki(t,m,n),T=n?await ha(await Mt(w,i??"")):await ts(w);if(Mo(T.width,T.height,r))return console.info(`[PixiVisemeCompositor] Sheet ${m} (${T.width}x${T.height}) exceeds MAX_TEXTURE_SIZE=${r}; using per-cell crops.`),{mode:"cells",bitmap:T};const f=we.Texture.from(T);return f.source.scaleMode="nearest",{mode:"full",texture:f}};a.set(o.index,await u(o.index,o.path));for(const c of s.sheets??[])c.index!==o.index&&c.path&&a.set(c.index,await u(c.index,c.path));const d=new Map;for(const c of s.cells??[])c.path&&d.set(c.path,c);const l=new Map;for(const c of s.sheets??[])l.set(c.index,c);return{atlasMeta:s,cellByPath:d,sheetByIndex:l,diffBase:t,sheets:a}}async function Do(e,t={}){const n=new we.Application;try{await n.init({canvas:e,width:842,height:1264,preference:"webgl",autoStart:!1,antialias:!1,resolution:1,autoDensity:!1,backgroundAlpha:1,backgroundColor:0,powerPreference:"high-performance"})}catch(p){throw n.destroy({removeView:!1}),p}if(n.renderer.type!==we.RendererType.WEBGL)throw n.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const r=Co(n.renderer.gl,t.maxTextureSize);let i=!1,s=!1,o=!1;const a=n.canvas,u=()=>{i=!0,!s&&!o&&(s=!0,t.onWebGlContextLost?.())};a.addEventListener("webglcontextlost",u);const d=new we.Sprite(we.Texture.EMPTY),l=new we.Sprite(we.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new we.Sprite(we.Texture.EMPTY),m=new we.Sprite(we.Texture.EMPTY),w=new we.Sprite(we.Texture.EMPTY);w.visible=!1;const T=Gr(5),f=Gr(5);c.filters=[T],m.filters=[f],n.stage.addChild(d),n.stage.addChild(l),n.stage.addChild(c),n.stage.addChild(m),n.stage.addChild(w);let E=null,D=null,B=null,v=null,k=null,L=null,A=null,ie=842,de=1264,I=null,V=5;const G=new Map;let ae=null,se=null,re=null;const O=fi(()=>{G.clear(),L=null,A=null,E=null,I=null}),J=(p,S)=>{ie=p,de=S,n.renderer.resize(p,S),(e.width!==p||e.height!==S)&&(e.width=p,e.height=S)},W=()=>{c.visible=!1,m.visible=!1,c.texture=we.Texture.EMPTY,m.texture=we.Texture.EMPTY,ae=null,se=null},he=()=>{k=null,l.visible=!1,l.alpha=0},K=()=>{d.visible=!0,d.width=ie,d.height=de,d.x=0,d.y=0},ee=()=>{l.width=ie,l.height=de,l.x=0,l.y=0},$=()=>{w.visible=!1,he(),E&&(d.texture=E,K())},X=()=>{!k&&!l.visible||$()},_e=p=>{if(o||i||!E){$();return}const S=Math.max(0,p);if(!D||S<=0){$();return}W(),w.visible=!1,d.texture=D,K(),l.texture=E,ee(),l.alpha=0,l.visible=!0,k={startMs:performance.now(),durationMs:S},q()},oe=(p=performance.now())=>{if(!k)return!1;if(o||i)return X(),!1;const S=(p-k.startMs)/Math.max(1,k.durationMs);if(S>=1)return $(),q(),!1;const x=Math.min(1,Math.max(0,S)),_=x*x*(3-2*x);return l.alpha=_,l.visible=!0,q(),!0},b=()=>{if(B){try{B.resource=null}catch{}B.destroy(),B=null}D&&(D.destroy(!1),D=null),v=null},P=(p,S)=>{const x=p.cellByPath.get(S);if(!x||!zi(x))return null;const _=`${p.diffBase}::${S}`;let U=G.get(_);if(!U){const Z=x.sheet??0,te=p.sheets.get(Z);if(!te)return null;let z,be=!1;if(te.mode==="full")z=new we.Texture({source:te.texture.source,frame:new we.Rectangle(x.x,x.y,x.w,x.h)});else{const Xe=Ro(te.bitmap,x);z=we.Texture.from(Xe),z.source.scaleMode="nearest",be=!0}U={texture:z,ownsSource:be},G.set(_,U)}return{texture:U.texture,cell:x}},H=(p,S,x,_)=>{if(!_||!x)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const U=P(x,_);if(!U)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const Z=Wi(x.atlasMeta,U.cell);return S.setThreshold(V),p.texture=U.texture,p.x=Z.x,p.y=Z.y,p.width=U.cell.w,p.height=U.cell.h,p.visible=!0,!0},le=p=>{if(!p||!L)return null;const S=I??new Set(L.cellByPath.keys());return ir(p,S)??(S.has(p)?p:null)},j=p=>{w.visible=!1,$();const S=le(p.mouthPath),x=p.expressionPath&&A?ar(p.expressionPath,_=>A.cellByPath.has(_)):null;S!==ae?(H(c,T,L,S),ae=S):S?c.visible=!0:c.visible=!1,x!==se?(H(m,f,A,x),se=x):x?m.visible=!0:m.visible=!1},q=()=>{if(!(o||i||document.hidden))try{n.render()}catch{}};return{async loadAssets(p){if(o)return{width:ie,height:de,visemePaths:[]};const S=Wt();if(S&&!p)throw new Error("Encrypted assets enabled but no key provided");const x=S?await wa(await Mt(sn(),p??"")):await ts(sn());E&&E.destroy(!0),E=we.Texture.from(x),E.source.scaleMode="linear";const _=mi();L=await qr(hi(),_,S,r,p);try{A=await qr(gi(),_,S,r,p)}catch(Z){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",Z),A=null}const U=Ui(L.atlasMeta,x.width,x.height);return J(U.width,U.height),V=vn(L.atlasMeta),T.setThreshold(V),f.setThreshold(V),I=new Set(L.cellByPath.keys()),G.clear(),$(),W(),q(),{width:U.width,height:U.height,visemePaths:[...L.cellByPath.keys()]}},getVisemeAtlasPaths(){return I},drawLiveFrame(p){o||i||!E||(X(),j(p),q())},drawIdleVideo(p,S){o||i||document.hidden||S&&!S()||p.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(he(),W(),w.visible=!1,!D||v!==p?(b(),B=new we.VideoSource({resource:p,autoPlay:!1,updateFPS:0}),B.autoUpdate=!1,D=new we.Texture({source:B}),v=p):D.source.update(),d.texture=D,K(),q())},beginIdleToSilCrossfade:_e,tickIdleToSilCrossfade:oe,finishIdleToSilCrossfade:X,isIdleToSilCrossfading(){return k!=null},renderSilOnly(){o||i||!E||(W(),$(),q())},blitBitmap(p){o||i||(X(),W(),re&&(re.destroy(!0),re=null),re=we.Texture.from(p),w.texture=re,w.visible=!0,w.x=0,w.y=0,w.width=ie,w.height=de,d.visible=!1,q())},async compositePrefetchFrame(p){return null},renderFrame:q,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",u),O(),b(),re&&(re.destroy(!0),re=null);for(const{texture:S,ownsSource:x}of G.values())S.destroy(x);G.clear(),E&&(E.destroy(!0),E=null);const p=S=>{S.mode==="full"?S.texture.destroy(!0):S.bitmap.close()};if(L)for(const S of L.sheets.values())p(S);if(A)for(const S of A.sheets.values())p(S);T.destroy(!0),f.destroy(!0),n.destroy({removeView:!1},{children:!0,texture:!0})}}}const Yr=-1,tn=1e5,Qr=new Map;async function Bo(e){let t=Qr.get(e);if(!t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to fetch worker script (${n.status}): ${e}`);const r=await n.blob();t=URL.createObjectURL(r),Qr.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function Fo(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function zn(e,t){(e.width!==t.width||e.height!==t.height)&&(e.width=t.width,e.height=t.height);const n=e.getContext("2d");n&&n.drawImage(t,0,0)}function Xr(e,t){let n=0,r=null;const i=fr(async(s,o)=>(await Un(),await Wn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await Un(s);return r=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return r},async renderSilOnly(){n+=1,i.reset(),await eo(e)},drawLiveFrame(s,o,a,u){i.enqueue(o,a,u)},async compositePrefetchFrame(s,o){try{return await Za(s)}catch{return null}},blitBitmap(s,o){zn(s,o)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(s,o){n+=1;const a=n;t.onStatus?.(o),await Wn(s,{mouthPath:xt(o),expressionPath:null})},dispose(){n+=1,i.reset()}}}function Lo(e,t,n){let r=null,i=1,s=0,o=!1,a=!1,u=null;const d=new Map,l=new Map;let c=tn;const m=fr(async(B,v,k)=>(d.set(v,{drawKey:k.drawKey,onDisplayed:k.onDisplayed}),await E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:v},void 0,!0),!1)),w=B=>{if(B===Yr){let L=-1,A;for(const[ie,de]of d)ie>=L&&(L=ie,A=de);L>=0&&d.delete(L),A?.onDisplayed?.(A.drawKey);return}const v=-B,k=d.get(v);d.delete(v),k?.onDisplayed?.(k.drawKey)},T=new Map,f=(B,v)=>{a||!r||r.postMessage(B,[])},E=(B,v,k=!1)=>{if(a)return Promise.resolve();const L=i++;return new Promise((A,ie)=>{T.set(L,{resolve:de=>A(de),reject:ie,generation:typeof B.generation=="number"?B.generation:void 0,expectRenderDone:k}),f({...B,requestId:L})})},D=(async()=>{r=await Bo(n),r.onmessage=B=>{if(a)return;const v=B.data;if(v.type==="status"){t.onStatus?.(v.label);return}if(v.type==="frame"){if(v.generation<=-tn){const A=-v.generation,ie=l.get(A);l.delete(A),ie?.resolve(v.bitmap);return}const L=v.generation<0;if(!L&&v.generation!==s){v.bitmap.close();return}if(L&&!(v.generation===Yr)){const ie=-v.generation;if(!m.isLatestSeq(ie)){at()?.onWorkerStale(),v.bitmap.close();return}}if(L&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){at()?.onWorkerStale(),v.bitmap.close();return}zn(e,v.bitmap),v.bitmap.close(),L&&w(v.generation);return}const k=T.get(v.requestId);if(k)switch(v.type){case"ready":T.delete(v.requestId),k.resolve();break;case"loadAssetsDone":T.delete(v.requestId),u=v.visemePaths?.length?new Set(v.visemePaths):null,k.resolve({width:v.width,height:v.height,visemePaths:v.visemePaths});break;case"renderDone":if(k.expectRenderDone&&k.generation!=null&&v.generation!==k.generation)return;T.delete(v.requestId),k.resolve();break;case"renderAborted":T.delete(v.requestId),k.resolve();break;case"error":T.delete(v.requestId),t.onError?.(v.message),k.reject(new Error(v.message));break}},r.onerror=B=>{if(a)return;const v=B.message||"Worker error";t.onError?.(v);for(const[,k]of T)k.reject(new Error(v));T.clear()},await E({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(B){if(a)return{width:842,height:1264};if(await D,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await E({type:"loadAssets",keyHex:B,urls:Bs(wt())})??{width:842,height:1264}},getVisemeAtlasPaths(){return u},async renderSilOnly(){if(a||(await D,a))return;s+=1,m.reset(),d.clear(),l.forEach(({resolve:v})=>v(null)),l.clear(),c=tn;const B=s;await E({type:"cancelLiveDraws"}),await E({type:"renderSil",generation:B},void 0,!0)},drawLiveFrame(B,v,k,L){a||D.then(()=>{a||m.enqueue(v,k,L)})},compositePrefetchFrame(B,v){return a?Promise.resolve(null):D.then(()=>{if(a)return null;const k=++c;return new Promise(L=>{l.set(k,{resolve:L}),E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:k},void 0,!0).catch(()=>{l.delete(k),L(null)})})})},blitBitmap(B,v){zn(B,v)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(B,v,k={}){if(a||(await D,a))return;s+=1,m.reset(),d.clear();const L=s;try{await E({type:"cancelLiveDraws"}),await E({type:"renderViseme",generation:L,to:v,from:k.from,transitionDurationMs:k.transitionDurationMs,gapMs:k.gapMs,threshold:k.threshold},void 0,!0)}catch(A){if(A?.name==="AbortError")return;throw A}},dispose(){if(!a){a=!0,s+=1,m.reset(),d.clear(),l.forEach(({resolve:B})=>B(null)),l.clear(),c=tn;for(const[,B]of T)B.resolve();T.clear(),r?.terminate(),r=null}}}}async function Oo(e,t){const n=await Do(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let r=0,i=null,s=!1;const o=fr(async(a,u)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(at()?.onWorkerStale(),!1):(n.drawLiveFrame(a),o.isLatestSeq(u)));return{usesWorker:!1,usesPixi:!0,async loadAssets(a){if(s)return{width:842,height:1264};const u=await n.loadAssets(a);return i=u.visemePaths?.length?new Set(u.visemePaths):null,u},getVisemeAtlasPaths(){return i},async renderSilOnly(){s||(r+=1,o.reset(),n.renderSilOnly())},drawLiveFrame(a,u,d,l){s||o.enqueue(u,d,l)},async compositePrefetchFrame(a,u){if(s)return null;try{return await n.compositePrefetchFrame(a)}catch{return null}},blitBitmap(a,u){s||t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()||n.blitBitmap(u)},drawIdleVideo(a,u){s||n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){s||n.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return s?!1:n.tickIdleToSilCrossfade(a)},finishIdleToSilCrossfade(){s||n.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return s?!1:n.isIdleToSilCrossfading()},supportsBufferedPlayback:!1,async renderViseme(a,u){if(s)return;r+=1;const d=r;o.reset(),t.onStatus?.(u),n.drawLiveFrame({mouthPath:xt(u),expressionPath:null})},dispose(){s||(s=!0,r+=1,o.reset(),n.dispose())}}}function Jr(e,t){if(!Fo())return Xr(e,t);const n=ws(t.workerScriptUrl);try{return Lo(e,t,n)}catch{return Xr(e,t)}}function No(e,t={}){if(t.preferLegacyRenderer)return Jr(e,t);let n=null,r=!1,i=null,s=!1;const o=()=>n?Promise.resolve(n):(i||(i=(async()=>{try{const a=await Oo(e,t);if(s)throw a.dispose(),new Error("Renderer disposed during Pixi init");return r=!0,n=a,a}catch(a){if(s)throw a instanceof Error?a:new Error(String(a));return console.warn("[AiTwin] Pixi WebGL renderer unavailable, using Canvas2D fallback:",a),n=Jr(e,t),r=!1,n}})()),i);return{get usesWorker(){return n?.usesWorker??!1},get usesPixi(){return r},async loadAssets(a){return(await o()).loadAssets(a)},getVisemeAtlasPaths(){return n?.getVisemeAtlasPaths()??null},async renderSilOnly(){return(await o()).renderSilOnly()},drawLiveFrame(a,u,d,l){o().then(c=>{s||c.drawLiveFrame(a,u,d,l)})},async compositePrefetchFrame(a,u){return(await o()).compositePrefetchFrame(a,u)},blitBitmap(a,u){n&&n.blitBitmap(a,u)},drawIdleVideo(a,u){n?.usesPixi&&n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){n?.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return n?.tickIdleToSilCrossfade(a)??!1},finishIdleToSilCrossfade(){n?.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return n?.isIdleToSilCrossfading()??!1},get supportsBufferedPlayback(){return n?.supportsBufferedPlayback??!1},async renderViseme(a,u,d){return(await o()).renderViseme(a,u,d)},dispose(){s=!0,i=null,n?.dispose(),n=null}}}class Vo extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function Cn(e,t,n){return new Promise((r,i)=>{const s=globalThis.setTimeout(()=>{i(new Vo(n,t))},t);e.then(o=>{globalThis.clearTimeout(s),r(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const Uo={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Wo={display:"block",maxWidth:"100%",height:"auto"},zo={position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"rgba(0,0,0,0.55)",color:"#fff",fontSize:"0.875rem",textAlign:"center"};function Rn(e){return Ss(e)?tr:oi(e)?dn:er}function Je(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const ns=h.forwardRef(function({id:t,avatarId:n,faceId:r,assets:i,authToken:s,apiBase:o,ttsEngineId:a,voiceId:u,language:d,speakingRate:l=Ht,className:c,style:m,canvasStyle:w,onStatusChange:T,onDisplayStatus:f,onError:E,onReady:D,showErrorOverlay:B=!0,loadingThumbnailUrl:v,onUserTranscript:k,onBotOutput:L,onRealtimeLipsyncDebug:A,onFrameRenderStats:ie,lipsyncBufferedPlayback:de=!0,lipsyncPlaybackWarmupMs:I=1500,idleHandoffHoldMs:V=ho,pixiMaxTextureSize:G,captions:ae},se){const re=h.useRef(null),O=h.useRef(null),J=h.useRef(null),W=h.useRef(de);W.current=de;const he=h.useRef(I);he.current=I;const K=h.useRef(V);K.current=V;const ee=h.useRef(0),$=h.useRef(ur()),X=h.useRef(Ha()),_e=h.useRef(!1),oe=h.useRef(null),b=h.useRef(null),P=h.useRef(0),H=h.useRef(0),le=h.useRef(0),j=h.useRef(null),q=h.useRef(null),p=h.useRef(!1),S=h.useRef(!1),x=h.useRef(!1),_=h.useRef(!1),U=h.useRef("sil"),Z=h.useRef(0),te=h.useRef(!1),z=h.useRef(null),be=h.useRef(!1),[Xe,Pt]=h.useState("idle"),[pt,Ct]=h.useState(null),[ot,_n]=h.useState(!1),[g,C]=h.useState(!1),[ne,ue]=h.useState(!1),[Te,ve]=h.useState(),[ke,We]=h.useState({width:842,height:1264}),[Fe,$t]=h.useState(null),[bn,Rt]=h.useState(0),yt=h.useRef(!1),Ce=h.useRef(s??null),He=o?.trim()||ht,vt=h.useRef(null),Ie=h.useRef(null),{ttsEngineId:xe,voiceId:$e}=h.useMemo(()=>{const y=et(a,u),M=y.ttsEngineId??dt;return{ttsEngineId:M,voiceId:y.voiceId??Rn(M)}},[a,u]),je=h.useRef(!1),rt=h.useRef({width:842,height:1264}),pe=h.useRef(null),Le=h.useRef("sil"),Pe=h.useRef(""),Oe=h.useMemo(()=>no(ae),[ae]),Ne=h.useCallback(()=>{Pe.current="",$t(null)},[]);h.useEffect(()=>{Oe.enabled||Ne()},[Oe.enabled,Ne]);const Dt=h.useCallback(y=>{if(!Oe.enabled)return;const M=y.isSpeaking(),N=y.isWarmingUp();if(!M||N){Pe.current&&Ne();return}const F=to(y.getWordQueue());if(!F){Pe.current&&Ne();return}F!==Pe.current&&(Pe.current=F,$t(F))},[Oe.enabled,Ne]),ct=h.useRef(void 0),Bt=h.useRef(new Map),mr=h.useRef(D),hr=h.useRef(T),ye=h.useRef(f),gr=h.useRef(E),wr=h.useRef(k),pr=h.useRef(L),jt=h.useRef(A),yr=h.useRef(ie),_t=h.useRef(mo());mr.current=D,hr.current=T,ye.current=f,gr.current=E,wr.current=k,pr.current=L,jt.current=A,yr.current=ie,h.useEffect(()=>{const y=_t.current;return zr(y),()=>zr(null)},[]);const vr=h.useCallback(y=>{const M=et(y?.ttsEngineId??a,y?.voiceId??u),N=M.ttsEngineId??Ie.current?.ttsEngineId??dt,F=M.voiceId??Ie.current?.voiceId??Rn(N);return{ttsEngineId:N,voiceId:F}},[a,u]),it=h.useCallback(y=>{Ct(y),ue(!0),gr.current?.(y)},[]),Ft=h.useCallback(y=>{Pt(y),hr.current?.(y)},[]),fe=h.useRef(Nn(Ft,He,{onLipsyncDebug:y=>jt.current?.(y)})),me=h.useRef(null),_r=h.useRef(()=>{});h.useEffect(()=>(fe.current=Nn(Ft,He,{onLipsyncDebug:y=>jt.current?.(y)}),s&&fe.current.setDeveloperToken(s),fe.current.setTtsEngineId(xe),()=>{fe.current.stop();const y=me.current;y&&(y.disconnect(),me.current=null)}),[Ft,He]);const br=h.useCallback(()=>(me.current||(me.current=Vi(Ft,{speakingRate:l,language:d,onUserTranscript:(y,M)=>wr.current?.(y,M),onBotOutput:y=>pr.current?.(y),onLipsyncDebug:y=>jt.current?.(y)}),me.current.setTtsEngineId(xe),_r.current(!0)),me.current),[Ft,l,d,xe]),Re=h.useCallback(()=>{j.current!=null&&(clearTimeout(j.current),j.current=null)},[]),De=h.useCallback(()=>{q.current!=null&&(clearTimeout(q.current),q.current=null),x.current=!1},[]),Kt=h.useCallback(()=>{if(_.current)return;const y=O.current;if(_.current=!0,De(),p.current=!1,S.current=!1,!be.current||!z.current){y?.renderSilOnly();return}z.current.setActive(!1);const M=z.current.getVideo();if(y?.usesPixi){y.drawIdleVideo(M),y.beginIdleToSilCrossfade($r);return}(async()=>{const N=re.current;N&&await Mn(N,M,null,void 0,rt.current).catch(()=>{}),await new Promise(F=>setTimeout(F,$r)),_.current&&await y?.renderSilOnly()})()},[De]),Sr=h.useCallback(()=>{!be.current||!z.current||(_.current=!1,O.current?.finishIdleToSilCrossfade(),De(),x.current=!0,q.current=setTimeout(()=>{if(q.current=null,Je(fe.current,me.current).isSpeaking()){x.current=!1;return}if(p.current){x.current=!1;return}const y=z.current;if(!y){x.current=!1;return}y.restart(),y.setActive(!0);const M=y.getVideo();let N=!1;const F=()=>{N||(N=!0,M.removeEventListener("playing",Q),x.current=!1)},Q=()=>{F()};if(M.addEventListener("playing",Q,{once:!0}),M.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!M.paused){F();return}setTimeout(F,300)},K.current))},[De]),bt=h.useCallback(()=>{if(Re(),ye.current?.("sil"),p.current=!1,_.current=!1,!be.current||!z.current){x.current=!1;return}Sr()},[Re,Sr]),Sn=h.useCallback(async y=>{const M=H.current,N=O.current,F=re.current,Q=()=>{y?.fallbackOnly||(p.current=!1)};if(!N||!F||!ot){Q();return}if(Je(fe.current,me.current).isSpeaking()){Q();return}if(y?.fallbackOnly){if(!p.current||(Be($.current),await N.renderSilOnly(),M!==H.current)||Je(fe.current,me.current).isSpeaking())return;bt();return}if(jr($.current)){Be($.current),bt();return}if(W.current&&N.supportsBufferedPlayback&&!y?.fallbackOnly){if(Be($.current),J.current?.reset(),await N.renderSilOnly(),M!==H.current||Je(fe.current,me.current).isSpeaking())return;bt();return}const Ee=vo(Je(fe.current,me.current).getVisemeQueue(),Z.current,U.current),Ve=_o(Ee,pe.current);if(Be($.current),!Ve){if(await N.renderSilOnly(),M!==H.current||Je(fe.current,me.current).isSpeaking())return;bt();return}try{await N.renderViseme(F,"sil",{from:Ee,transitionDurationMs:Ji})}catch(Me){if(Me?.name!=="AbortError")throw Me}if(M!==H.current){Q();return}if(Je(fe.current,me.current).isSpeaking()){Q();return}bt()},[ot,bt]),St=h.useCallback(()=>{if(S.current||p.current)return;S.current=!0,p.current=!0,Re();const y=H.current;Sn().finally(()=>{S.current=!1}),j.current=setTimeout(()=>{j.current=null,y===H.current&&Sn({fallbackOnly:!0})},bo())},[Re,Sn]),Tr=h.useCallback(async()=>{const y=Math.floor(Date.now()/1e3);if(vt.current&&y<vt.current.expiresAt-60)return vt.current.key;const M=Ce.current??await Nt();Ce.current=M,fe.current.setDeveloperToken(M);const N=await Ps(M,He);return vt.current={key:N.value,expiresAt:N.expiresAt},N.value},[He]);h.useEffect(()=>{s&&(Ce.current=s,fe.current.setDeveloperToken(s))},[s]),h.useEffect(()=>{fe.current.setTtsEngineId(xe),me.current?.setTtsEngineId(xe),Ie.current&&(Ie.current.ttsEngineId=xe)},[xe]),h.useEffect(()=>{Ie.current&&(Ie.current.voiceId=$e)},[$e]);const Ke=h.useMemo(()=>ui(n,r),[n,r]),os=h.useMemo(()=>i?JSON.stringify(i):Ke?`face:${Ke}`:`id:${t??""}`,[i,Ke,t]),cs=h.useMemo(()=>{const y=v?.trim();return y||(xr(Ke)??xr(Te)??ks(i))},[v,Ke,Te,i]);return h.useEffect(()=>{if(!t&&!i&&!Ke){it("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let y=!1;je.current=!1,_n(!1),C(!1),ue(!1),ve(Ke),Ct(null),Ie.current=null,z.current=null,be.current=!1;const M=re.current;if(!M)return;let N=null;return(async()=>{try{let F,Q,Se,Ee;if(i)F=i,Q=xe,Se=$e;else if(Ke)ye.current?.("loadFace"),F=Ln(Ke),Q=xe,Se=$e;else{ye.current?.("getAiTwin");const Y=await Cn(ci(t),3e4,"getAiTwin");if(y)return;if(!Y.faceId?.trim())throw new Error("getAiTwin returned no faceId");ve(Y.faceId.trim());const ce=et(a,u);Q=ce.ttsEngineId??Y.ttsEngineId,Se=ce.voiceId??Y.voiceId??Rn(Q),Ee=qn(Y),F=Ln(Y.faceId)}Ie.current={ttsEngineId:Q,voiceId:Se,brainId:Ee},di(F),z.current=$a();const Ve=!!(i&&!gt(i));N=No(M,{preferLegacyRenderer:Ve,pixiMaxTextureSize:G,onStatus:Y=>{y||ye.current?.(Y)},onError:Y=>{y||it(Y)},shouldAcceptLiveFrame:()=>{if(_e.current)return!0;if(p.current)return!1;const Y=Je(fe.current,me.current);return Y.isSpeaking()||Y.isWarmingUp()},onWebGlContextLost:()=>{y||yt.current||(yt.current=!0,queueMicrotask(()=>{y||Rt(Y=>Y+1)}))}}),O.current=N,J.current=xo(N),yt.current=!1;const Me=Y=>{const ce=()=>{if(!Y||he.current<=0)return!1;const Ae=O.current;return Ae?W.current&&Ae.supportsBufferedPlayback?!0:Ae.usesPixi:!1};fe.current.setLipsyncWarmupHold(Y,ce),me.current?.setLipsyncWarmupHold(Y,ce)};_r.current=Me,Me(!0),ye.current?.("auth");const Ge=Ce.current??s??await Cn(Nt(),3e4,"getAuthToken");if(y)return;Ce.current=Ge,fe.current.setDeveloperToken(Ge),fe.current.setTtsEngineId(Q);const Gt=Wt()?await Tr():void 0;if(y)return;ye.current?.("loadAssets");const ge=await Cn(N.loadAssets(Gt),18e4,"load face assets");if(!y&&ge.width>0&&ge.height>0&&(rt.current=ge,We(ge)),y)return;pe.current=N.getVisemeAtlasPaths(),je.current=!0,_n(!0),mr.current?.(),N.renderSilOnly().then(()=>{y||ye.current?.("sil")}),(async()=>{try{const Y=await va(Gt);if(await z.current.load(Y),y)return;be.current=!0,C(!0),Be($.current),z.current.setActive(!0);const ce=z.current.getVideo();N.usesPixi?N.drawIdleVideo(ce):await Mn(M,ce,null,void 0,rt.current)}catch(Y){if(y)return;be.current=!1,C(!1),console.warn("[AiTwin] Idle video unavailable:",Y)}finally{y||(ue(!0),ye.current?.("idle"))}})()}catch(F){if(y)return;if(F instanceof nn){it(F.message);return}it(F instanceof Error?F.message:"Failed to load AI twin")}})(),()=>{y=!0,z.current?.dispose(),N?.dispose(),O.current=null}},[os,i,Ke,t,xe,$e,a,u,s,G,Tr,it,bn]),h.useEffect(()=>{const y={current:!1},M=()=>{const N=re.current,F=O.current,Q=Je(fe.current,me.current);if(!N||!F||!ot){P.current=requestAnimationFrame(M);return}if(document.hidden){z.current?.setActive(!1),P.current=requestAnimationFrame(M);return}const Se=Q.isSpeaking(),Ee=Q.isWarmingUp(),Ve=Se&&!te.current,Me=te.current&&!Se;Ve&&(Re(),De(),p.current=!1,S.current=!1,Be($.current),J.current?.reset(),_t.current.reset(),ct.current=void 0,le.current=0,U.current="sil",Z.current=0,Kt()),Me&&(X.current.reset(),z.current?.setActive(!1),J.current?.reset(),F.finishIdleToSilCrossfade(),Ne(),St());const Ge=Me||p.current||x.current||_.current,Gt=de&&F.supportsBufferedPlayback;if(Ee){if(Kt(),be.current&&z.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()){F.tickIdleToSilCrossfade(performance.now()),Q.getVisemeQueue().length>0&&ee.current===0&&(ee.current=performance.now()),te.current=Q.isSpeaking(),P.current=requestAnimationFrame(M);return}const ge=Q.getVisemeQueue();ge.length>0&&ee.current===0&&(ee.current=performance.now()),X.current.advance(performance.now());const Y=X.current.getExpressionPath(),ce=X.current.getDrawKey(),Ae={queue:ge,elapsedMs:0,expressionPath:Y,expressionDrawKey:ce,availablePaths:pe.current};let Ue=!1;Gt&&J.current?(J.current.warmupTick(Ae),Ue=J.current.isWarmupReady(Ae,he.current)):F.usesPixi&&Kr(N,ge,0,Y,ce,$.current,(Tt,qt,Tn,Yt)=>{F.drawLiveFrame(Tt,qt,Tn,qe=>{Yt?.(qe),Q.isWarmingUp()&&qe!==""&&!jr({lastDrawnKey:qe})&&(ee.current=0,Q.releaseWarmupHold())})},Tt=>{ye.current?.(Tt.label)},pe.current);const st=ee.current>0&&performance.now()-ee.current>ys;ye.current?.(Ue?"buffer ready":"buffering lipsync…"),(Ue||st)&&(ee.current=0,Q.releaseWarmupHold()),Dt(Q),te.current=Q.isSpeaking(),P.current=requestAnimationFrame(M);return}if(Se){Kt(),be.current&&z.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()&&F.finishIdleToSilCrossfade();const ge=Q.getVisemeQueue(),Y=Q.getPlaybackElapsedMs();aa(ge,Y),Z.current=Y;const ce=ge.length>0?zt(ge,Y):"sil";ce!=="sil"&&(U.current=ce);const Ae=qa(Y,Q.getSentenceEmotions(),Q.getWordQueue(),Q.getStreamMood());X.current.setTargetEmotion(Ae),X.current.setTargetEyebrow(Wa(Y,Q.getWordQueue(),mt(Ae))),X.current.advance(performance.now());const Ue=X.current.getExpressionPath(),st=X.current.getDrawKey(),Tt=(qe,kn,Lt,En)=>{const kr={label:Le.current,elapsedMs:Y,mouthPath:kn.mouthPath,transitionMeta:ct.current};Bt.current.set(Lt,kr),J.current?.markExternallyDisplayed(Lt,Ue),F.drawLiveFrame(qe,kn,Lt,Qt=>{const ls=Bt.current.get(Qt)??kr;Bt.current.delete(Qt),_t.current.onDrawDisplayed(ls,ge),J.current?.markExternallyDisplayed(Qt,Ue),En?.(Qt)})},qt=qe=>{Le.current=qe.label,ct.current=qe.transitionMeta,ye.current?.(qe.label)},Tn=de&&F.supportsBufferedPlayback;let Yt=!1;Tn&&J.current&&(Yt=J.current.tick({canvas:N,queue:ge,elapsedMs:Y,expressionPath:Ue,expressionDrawKey:st,playbackState:$.current,availablePaths:pe.current,onStatus:qt,onDisplayed:(kn,Lt,En)=>{_t.current.onDrawDisplayed({label:En,elapsedMs:Y,mouthPath:Lt,transitionMeta:ct.current},ge)}}).usedBuffer),Yt||Kr(N,ge,Y,Ue,st,$.current,Tt,qt,pe.current),_t.current.onRafTickSpeaking(),yr.current?.(_t.current.snapshot(ge,Y))}else if(!Ge&&_e.current){z.current?.setActive(!1),X.current.advance(performance.now());const ge=X.current.getExpressionPath(),Y=X.current.getDrawKey();Pn(N,ge,Y,$.current,(ce,Ae,Ue,st)=>F.drawLiveFrame(ce,Ae,Ue,st),ce=>{if(b.current){ye.current?.(b.current);return}const Ae=X.current.getTargetEmotion();ye.current?.(ce==="sil"||ce==="blink"?`${Ae}${ce==="blink"?" · blink":""}`:ce)},null,oe.current)}else if(!Ge&&be.current&&z.current){const ge=z.current,Y=ge.getVideo();if(Y.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){ge.setActive(!0);const ce=()=>!Q.isSpeaking()&&!p.current&&!x.current&&!_e.current;F.usesPixi?(F.drawIdleVideo(Y,ce),ce()&&ye.current?.("idle")):y.current||(y.current=!0,Mn(N,Y,null,void 0,rt.current,ce).then(()=>ye.current?.("idle")).finally(()=>{y.current=!1}))}else Pn(N,null,"__sil__",$.current,(ce,Ae,Ue,st)=>F.drawLiveFrame(ce,Ae,Ue,st),ce=>ye.current?.(ce))}else Ge||Pn(N,null,"__sil__",$.current,(ge,Y,ce,Ae)=>F.drawLiveFrame(ge,Y,ce,Ae),ge=>ye.current?.(ge));Oe.enabled&&Dt(Q),te.current=Se,P.current=requestAnimationFrame(M)};return P.current=requestAnimationFrame(M),()=>{cancelAnimationFrame(P.current),Re(),De(),fe.current.stop(),me.current?.stop()}},[ot,g,St,Re,De,Kt,Dt,Ne,Oe.enabled]),h.useImperativeHandle(se,()=>({speakText:async(y,M)=>{const N=y.trim();if(!N)return;const F=O.current;if(!F||!je.current&&!ot)throw new Error("AI twin is not ready");const{ttsEngineId:Q,voiceId:Se}=vr(M);Ct(null),Ne(),H.current+=1,Re(),De(),p.current=!1,S.current=!1,U.current="sil",Z.current=0,Be($.current),_e.current=!1,oe.current=null,b.current=null,X.current.reset(),te.current=!1,_.current=!1,F.finishIdleToSilCrossfade();try{await fe.current.speak(N,{voiceId:Se,speakingRate:M?.speakingRate??l,ttsEngineId:Q,language:M?.language??d})}catch(Ee){throw _.current=!1,F.finishIdleToSilCrossfade(),St(),it(Ee instanceof Error?Ee.message:"TTS failed"),Ee}},stop:()=>{H.current+=1,Re(),De(),p.current=!1,S.current=!1,_.current=!1,O.current?.finishIdleToSilCrossfade(),fe.current.stop(),me.current?.stop(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,Ne(),St()},setTtsEngineId:y=>{fe.current.setTtsEngineId(y),me.current?.setTtsEngineId(y),Ie.current&&(Ie.current.ttsEngineId=y)},renderViseme:async(y,M)=>{const N=O.current,F=re.current;if(!N||!F||!je.current)throw new Error("AI twin is not ready");await N.renderViseme(F,y,{from:M?.from,transitionDurationMs:M?.transitionDurationMs,gapMs:M?.gapMs,onStatus:Q=>ye.current?.(Q)})},setEmotion:y=>{if(!je.current)throw new Error("AI twin is not ready");const M=O.current,N=re.current;if(!M||!N)throw new Error("AI twin is not ready");H.current+=1,Re(),De(),p.current=!1,S.current=!1,x.current=!1,_.current=!1,fe.current.stop(),me.current?.stop(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,M.finishIdleToSilCrossfade(),z.current?.setActive(!1);const F=Ze(y);_e.current=!0,oe.current=null,b.current=null,X.current.snapToEmotion(F);const Q=X.current.getExpressionPath(),Se=X.current.getDrawKey(),Ee={mouthPath:null,expressionPath:Q},Ve=Ut(Ee,Se);$.current.lastDrawnKey="",M.drawLiveFrame(N,Ee,Ve,Ge=>{Ge===Ve&&($.current.lastDrawnKey=Ve)});const Me=mt(F);ye.current?.(Q?`${F} · brow ${Me>0?"+":""}${Me}`:`${F} · brow 0 (sil base)`)},getEmotion:()=>_e.current?X.current.getTargetEmotion():null,clearEmotionPreview:()=>{_e.current=!1,oe.current=null,b.current=null,X.current.reset(),Be($.current),ye.current?.("idle")},setViseme:y=>{if(!je.current)throw new Error("AI twin is not ready");const M=O.current,N=re.current;if(!M||!N)throw new Error("AI twin is not ready");H.current+=1,Re(),De(),p.current=!1,S.current=!1,x.current=!1,_.current=!1,fe.current.stop(),me.current?.stop(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,M.finishIdleToSilCrossfade(),z.current?.setActive(!1);const F=mn(y);_e.current=!0,b.current=F,oe.current=F==="sil"?null:xt(F),X.current.snapToEmotion("neutral");const Q=X.current.getExpressionPath(),Se=X.current.getDrawKey(),Ve={mouthPath:oe.current,expressionPath:Q},Me=Ut(Ve,Se);$.current.lastDrawnKey="",M.drawLiveFrame(N,Ve,Me,Ge=>{Ge===Me&&($.current.lastDrawnKey=Me)}),ye.current?.(F)},getViseme:()=>_e.current?b.current:null,isReady:()=>je.current,getStatus:()=>Xe,connect:async(y={})=>{Ct(null);try{let M=y.authToken?.trim();M||(M=Ce.current??s??await Nt(),Ce.current=M);const N=et(y.ttsEngineId??a,y.voiceId??u),F=N.voiceId??Ie.current?.voiceId,Q=y.brainId?.trim()||y.personaId?.trim()||Ie.current?.brainId,Se=N.ttsEngineId??Ie.current?.ttsEngineId??xe,Ee=br();Se&&Ee.setTtsEngineId(Se),await Ee.unlockAudio(),await Ee.connect({...y,apiBase:y.apiBase?.trim()||He,authToken:M,voiceId:F,brainId:Q,ttsEngineId:Se,speakingRate:y.speakingRate??l,language:y.language??d})}catch(M){throw it(M instanceof Error?M.message:"Voice connect failed"),M}},disconnect:async()=>{const y=me.current;y&&(H.current+=1,Re(),De(),p.current=!1,S.current=!1,_.current=!1,O.current?.finishIdleToSilCrossfade(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,await y.disconnect(),St())},isConnected:()=>me.current?.isConnected()??!1,getVoiceStream:()=>me.current?.getVoiceStream()??fe.current?.getVoiceStream()??null,setMuted:y=>{const M=fe.current,N=me.current;M?.setMuted?.(y),N?.setMuted?.(y)},isMuted:()=>{const y=me.current,M=fe.current;return y?.isMuted?.()??M?.isMuted?.()??!1},getBrainId:()=>Ie.current?.brainId?.trim()||null,getPersonaId:()=>Ie.current?.brainId?.trim()||null}),[ot,l,d,s,xe,$e,Re,De,St,it,vr,br,Xe,He]),R.jsxs("div",{className:c,style:{...Uo,...m},children:[R.jsx("canvas",{ref:re,width:ke.width,height:ke.height,style:{...Wo,...w},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!ne&&!pt?R.jsx(uo,{thumbnailUrl:cs}):null,B&&pt?R.jsx("div",{style:zo,children:pt}):null,Oe.enabled&&Fe?R.jsx(ao,{text:Fe,style:Oe.style},Fe):null]})});async function Ho(e){try{const t=await e.json();if(typeof t.detail=="string"&&t.detail.trim())return t.detail;if(typeof t.error=="string"&&t.error.trim())return t.error}catch{}return`avatarReply failed (${e.status})`}async function rs(e){const t=e.message.trim();if(!t)throw new Error("Message is required");const n=e.authToken.trim();if(!n)throw new Error("Auth token is required");const r=(e.apiBase?.trim()||ht).replace(/\/$/,""),i=await fetch(`${r}/avatarReply`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`,Accept:"text/event-stream"},body:JSON.stringify({message:t,history:e.history??[],brainId:e.brainId?.trim()||e.personaId?.trim()||""})});if(!i.ok)throw new Error(await Ho(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",u="",d="",l="";for(;;){const{done:c,value:m}=await s.read();if(c)break;a+=o.decode(m,{stream:!0});const w=a.split(`
48
- `);a=w.pop()||"";for(const T of w){if(T.startsWith("event: ")){l=T.slice(7).trim();continue}if(!T.startsWith("data: "))continue;const f=T.slice(6).trim();if(!f)continue;let E;try{E=JSON.parse(f)}catch{continue}if(l==="spokenText")u=E.text||"",e.onSpokenText?.(u);else if(l==="displayText")d=E.text||"";else if(l==="error")throw new Error(E.error||"avatarReply stream error")}}if(!u.trim()||!d.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:d.trim(),spokenText:u.trim()}}function $o({muted:e}){return e?R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"M15.5 8.5a4.5 4.5 0 0 1 0 7M18.5 6a8 8 0 0 1 0 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}function jo(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function Ko(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Go(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:R.jsx("path",{d:"M5 6.5A2.5 2.5 0 0 1 7.5 4h9A2.5 2.5 0 0 1 19 6.5v7A2.5 2.5 0 0 1 16.5 16H10l-4 3.5V16H7.5A2.5 2.5 0 0 1 5 13.5v-7Z",stroke:"currentColor",strokeWidth:"2",strokeLinejoin:"round"})})}function is({className:e}){return R.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:R.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:R.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function qo({muted:e,onToggle:t}){return R.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:R.jsx($o,{muted:e})})}function Yo(){return R.jsxs("div",{className:"aitwin-widget__connecting",role:"status","aria-live":"polite",children:[R.jsx(is,{className:"aitwin-widget__spinner aitwin-widget__spinner--accent"}),R.jsx("span",{children:"Connecting..."})]})}function Qo(e){const t=e.connecting||e.textSending||e.status==="loading"||e.status==="speaking",n=e.connecting?"Connecting...":e.connected?"End Talk":"Talk",r=["aitwin-widget__action",e.textMode&&!e.connecting?"":"aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return R.jsxs("div",{className:"aitwin-widget__controls",children:[R.jsxs("div",{className:"aitwin-widget__actions",children:[R.jsxs("button",{type:"button",className:r,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,children:[e.connecting?R.jsx(is,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?R.jsx(Ko,{}):R.jsx(jo,{}),R.jsx("span",{children:n})]}),R.jsxs("button",{type:"button",className:e.textMode?"aitwin-widget__action aitwin-widget__action--primary":"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":e.textMode,children:[R.jsx(Go,{}),R.jsx("span",{children:"Text"})]})]}),e.textMode?R.jsxs("form",{className:"aitwin-widget__composer",onSubmit:i=>{i.preventDefault(),e.onSendText()},children:[R.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:i=>e.onTextDraftChange(i.target.value),placeholder:e.textSending?"Getting reply...":"Type a message…",autoComplete:"off",disabled:!e.ready||t}),R.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||t||!e.textDraft.trim()&&!e.textSending,"aria-busy":e.textSending,children:e.textSending?"…":"Send"})]}):null,e.error?R.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const Zr=97,Xo=3500;function Jo(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/Xo);return Math.min(Zr,Math.round(r*Zr))}function Zo(e){const[t,n]=h.useState(null),[r,i]=h.useState(()=>Date.now());return h.useEffect(()=>{if(!e){n(null);return}const s=Date.now();n(s),i(s);let o=0;const a=()=>{i(Date.now()),o=window.requestAnimationFrame(a)};return o=window.requestAnimationFrame(a),()=>{window.cancelAnimationFrame(o)}},[e]),e?t==null?0:Jo(r-t):100}const ec="M259.01,593.87v-101.49c.33-6.31,4.94-11.26,10.21-11.88,6.42-.75,13.18,4.99,13.13,12.92-.42,45.09-.83,90.17-1.25,135.26.03,1.56.56,15.43,11.95,23.2,6.18,4.21,12.57,4.6,15.42,4.58-.42-112.77-.83-225.54-1.25-338.31-.08-2.55-1.03-46.36,21.17-55.34,2.05-.83,4.42-1.41,7.17-1.56v453.42c.07,12.06,1.98,37.84,19.03,62.73,7.01,10.23,14.79,17.71,21.4,22.99V222.42c-.01-3.72.48-11.67,5.35-19.87,7-11.77,18.13-15.82,21.4-16.95,10.42-3.61,19.49-2.06,23.48-1.11v684.96c.59,4.03,1.78,9.72,4.45,16.12,1.93,4.63,8.84,20.57,26.47,31.26,13.48,8.18,26.56,9.23,32.86,9.31-1.3-256.11-2.59-512.22-3.89-768.33.76-16.43,14.57-28.94,29.73-28.34,13.53.53,25.39,11.39,27.23,25.84-1.1,264.68-2.2,529.35-3.3,794.03,4.33.92,22.38,4.25,38.94-6.53,10.26-6.68,15.24-15.72,17.09-19.17,5.55-10.36,6.42-19.98,6.53-25.01-.72-246.99-1.43-493.97-2.15-740.96,2.27-.06,34.75-.44,48.29,22.68,3.41,5.83,4.87,11.86,5.34,17.19v674.68c5.92-2.16,39.19-14.94,50.16-47.79,3.12-9.34,3.68-18.03,3.33-25.01.03-193.22.06-386.43.09-579.65,4.12,1.18,28.28,8.48,36.17,30.08,1.64,4.49,2.32,8.88,2.43,12.92.02,146.42.05,292.84.07,439.25,3.82-1.71,19.51-9.22,25.56-26.47,2.15-6.12,2.48-11.73,2.29-15.89.01-114.91.03-229.81.04-344.72,2.36-.1,7.51.02,12.74,3.13,9.1,5.4,10.87,15.35,11.12,16.88.35,11.49.69,22.97,1.04,34.46.46,37.05.93,74.1,1.39,111.15v152.69c3.39-.72,9.77-2.67,14.31-8.34,3.62-4.52,4.51-9.46,5.56-15.28.91-5.04.95-9.31.83-12.23.02-38.81.03-77.62.05-116.43";function tc({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:n=2600,delayMs:r=0,loop:i=!1}){return R.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:R.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:ec,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function nc({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return R.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:R.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[R.jsx(tc,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),R.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[R.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:R.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),R.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function ei(e){const t=e.id?.trim()||void 0,n=e.faceId?.trim()||e.avatarId?.trim()||void 0;return{id:n?void 0:t,faceId:n,authToken:e.authToken?.trim()||void 0,apiBase:e.apiBase?.trim()||void 0,voiceId:e.voiceId?.trim()||void 0,speakingRate:e.speakingRate,language:e.language}}function rc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const ti={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},ic={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},sc=h.forwardRef(function({options:t},n){const r=h.useRef(null),i=h.useRef(t);i.current={...i.current,onReady:t.onReady,onStatusChange:t.onStatusChange,onError:t.onError,onUserTranscript:t.onUserTranscript,onBotOutput:t.onBotOutput};const[s,o]=h.useState(!!t.showControls),[a,u]=h.useState(()=>ei(t)),[d,l]=h.useState(!1),[c,m]=h.useState(!1),[w,T]=h.useState(!1),[f,E]=h.useState(!1),[D,B]=h.useState("idle"),[v,k]=h.useState(null),[L,A]=h.useState(!1),[ie,de]=h.useState(!1),[I,V]=h.useState(""),[G,ae]=h.useState(!1),[se,re]=h.useState([]),[O,J]=h.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),W=h.useCallback(_=>{i.current={...i.current,..._},_.showControls!==void 0&&o(!!_.showControls),(_.brainId!==void 0||_.personaId!==void 0)&&J((_.brainId??_.personaId)?.trim()||void 0),u(U=>ei({id:_.id??U.id,faceId:_.faceId??_.avatarId??U.faceId,authToken:_.authToken??U.authToken,apiBase:_.apiBase??U.apiBase,voiceId:_.voiceId??U.voiceId,speakingRate:_.speakingRate??U.speakingRate,language:_.language??U.language}))},[]);h.useImperativeHandle(n,()=>({getTwin:()=>r.current,applyOptions:W}),[W]),h.useEffect(()=>{W(t)},[W,t.id,t.faceId,t.avatarId,t.authToken,t.apiBase,t.voiceId,t.speakingRate,t.showControls,t.brainId,t.personaId]);const he=h.useCallback(()=>{l(!0),k(null)},[]),K=h.useCallback(_=>{_==="idle"&&m(!0)},[]),ee=h.useCallback(_=>{B(_),i.current.onStatusChange?.(_)},[]),$=h.useCallback(_=>{k(_),l(!1),m(!1),E(!1),i.current.onError?.(_)},[]),X=h.useCallback((_,U)=>{i.current.onUserTranscript?.(_,U)},[]),_e=h.useCallback(_=>{i.current.onBotOutput?.(_)},[]);h.useEffect(()=>{if(!s)return;const _=window.setInterval(()=>{T(!!r.current?.isConnected())},400);return()=>window.clearInterval(_)},[s,a]);const oe=rc(a),b=!!(a.id||a.faceId),P=d&&c,H=b&&!P&&!v,le=Zo(H),j=h.useRef(oe);h.useEffect(()=>{P&&i.current.onReady?.()},[P]),h.useEffect(()=>{P&&r.current?.setMuted(L)},[P,L,a]),h.useEffect(()=>{re([])},[a.id,a.faceId]),h.useEffect(()=>{j.current!==oe&&(j.current=oe,l(!1),m(!1),k(null),E(!1),T(!1),B("idle"))},[oe]);const q=()=>{const _=r.current;if(!_?.isReady())return;if(k(null),de(!1),_.isConnected()){E(!1),_.disconnect().finally(()=>{T(!1)});return}E(!0);const U={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,apiBase:a.apiBase};_.connect(U).then(()=>{T(!!_.isConnected())}).catch(Z=>{const te=Z instanceof Error?Z.message:"Failed to connect voice.";k(te),i.current.onError?.(te)}).finally(()=>{E(!1)})},p=()=>{de(_=>!_),k(null)},S=()=>{const _=I.trim(),U=r.current;!_||!U?.isReady()||G||(k(null),V(""),ae(!0),i.current.onUserTranscript?.(_,!0),(async()=>{try{const Z=a.authToken?.trim()||await Nt(),te=O||U.getBrainId()?.trim()||void 0,z=await rs({message:_,authToken:Z,apiBase:a.apiBase||ht,brainId:te,history:se});re(be=>[...be,{role:"user",content:_},{role:"assistant",content:z.displayText}]),i.current.onBotOutput?.(z.displayText),await U.speakText(z.spokenText,{voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language})}catch(Z){const te=Z instanceof Error?Z.message:"Failed to get reply.";k(te),i.current.onError?.(te)}finally{ae(!1)}})())},x=()=>{const _=!L;A(_),r.current?.setMuted(_)};return R.jsxs("div",{className:"aitwin-widget__layout",children:[R.jsxs("div",{className:"aitwin-widget__stage",children:[b?R.jsx("div",{style:ti,children:R.jsx(ns,{ref:r,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,style:ti,canvasStyle:ic,onReady:he,onDisplayStatus:K,onStatusChange:ee,onError:$,onUserTranscript:X,onBotOutput:_e,loadingThumbnailUrl:t.loadingThumbnailUrl},oe)}):R.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),H?R.jsx(nc,{progress:le}):null,s?R.jsx(qo,{muted:L,onToggle:x}):null,s&&f?R.jsx(Yo,{}):null]}),s?R.jsx(Qo,{ready:P,connected:w,connecting:f,status:D,textMode:ie,textDraft:I,textSending:G,error:v,onTalk:q,onTextMode:p,onTextDraftChange:V,onSendText:S}):null]})}),ac=".aitwin-widget{--aitwin-border: rgba(255, 255, 255, .12);--aitwin-text: #f4f4f5;--aitwin-muted: #a1a1aa;--aitwin-accent: #f97316;--aitwin-accent-hover: #fb923c;--aitwin-font: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;--aitwin-size: 1;--aitwin-stage-width: calc(200px * var(--aitwin-size));--aitwin-stage-height: calc(267px * var(--aitwin-size));--aitwin-action-height: calc(40px * var(--aitwin-size));--aitwin-action-font: calc(13px * var(--aitwin-size));--aitwin-action-radius: calc(10px * var(--aitwin-size));--aitwin-action-gap: calc(6px * var(--aitwin-size));--aitwin-mute-size: calc(28px * var(--aitwin-size));--aitwin-layout-gap: calc(8px * var(--aitwin-size));box-sizing:border-box;color:var(--aitwin-text);font-family:var(--aitwin-font);font-size:calc(12px * var(--aitwin-size));line-height:1.45;width:fit-content;max-width:100%}.aitwin-widget *,.aitwin-widget *:before,.aitwin-widget *:after{box-sizing:border-box}.aitwin-widget__layout{display:flex;flex-direction:column;gap:var(--aitwin-layout-gap);width:fit-content;max-width:100%}.aitwin-widget__stage{align-items:center;background:#0a0a0b;border:1px solid var(--aitwin-border);border-radius:calc(10px * var(--aitwin-size));display:flex;flex-shrink:0;height:var(--aitwin-stage-height);justify-content:center;line-height:0;overflow:hidden;position:relative;width:var(--aitwin-stage-width)}.aitwin-widget__stage .aitwin-root,.aitwin-widget__stage canvas{display:block;height:100%;object-fit:cover;object-position:top;width:100%}.aitwin-widget__hint{color:var(--aitwin-muted);font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget__mute{align-items:center;background:#28282cb8;border:none;border-radius:999px;color:#fff;cursor:pointer;display:inline-flex;height:var(--aitwin-mute-size);justify-content:center;padding:0;position:absolute;right:calc(8px * var(--aitwin-size));top:calc(8px * var(--aitwin-size));width:var(--aitwin-mute-size);z-index:2}.aitwin-widget__mute:hover{background:#37373cd9}.aitwin-widget__mute svg{height:calc(15px * var(--aitwin-size));width:calc(15px * var(--aitwin-size))}.aitwin-widget__controls{display:flex;flex-direction:column;gap:var(--aitwin-action-gap);width:var(--aitwin-stage-width)}.aitwin-widget__actions{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr 1fr;width:100%}.aitwin-widget__action{align-items:center;background:transparent;border:1.5px solid var(--aitwin-accent);border-radius:999px;color:var(--aitwin-accent);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--aitwin-action-font);font-weight:600;gap:calc(6px * var(--aitwin-size));height:var(--aitwin-action-height);justify-content:center;padding:0 calc(10px * var(--aitwin-size))}.aitwin-widget__action svg{flex-shrink:0;height:calc(12px * var(--aitwin-size));width:calc(12px * var(--aitwin-size))}.aitwin-widget__action:hover:not(:disabled){background:#f973161a}.aitwin-widget__action:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__action--primary{background:var(--aitwin-accent);border-color:transparent;color:#fff}.aitwin-widget__action--primary:hover:not(:disabled){background:var(--aitwin-accent-hover)}.aitwin-widget__action--connecting:disabled{cursor:progress;opacity:1}.aitwin-widget__spinner{display:inline-flex;flex-shrink:0;height:calc(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--accent{color:var(--aitwin-accent);height:calc(16px * var(--aitwin-size));width:calc(16px * var(--aitwin-size))}.aitwin-widget__spinner--on-accent{color:#fff}@keyframes aitwin-widget-spin{to{transform:rotate(360deg)}}.aitwin-widget__connecting{align-items:center;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);background:#ffffffe0;border-radius:999px;bottom:calc(14px * var(--aitwin-size));box-shadow:0 4px 16px #0000001f;color:#3f3f46;display:inline-flex;font-size:calc(12px * var(--aitwin-size));font-weight:600;gap:calc(8px * var(--aitwin-size));left:50%;line-height:1;padding:calc(8px * var(--aitwin-size)) calc(14px * var(--aitwin-size));pointer-events:none;position:absolute;transform:translate(-50%);z-index:3}.aitwin-widget__face-loading{background:transparent;inset:0;overflow:hidden;pointer-events:none;position:absolute;z-index:4}.aitwin-widget__face-loading-content{align-items:center;display:flex;flex-direction:column;gap:calc(12px * var(--aitwin-size));inset:0;justify-content:center;padding:calc(24px * var(--aitwin-size));position:absolute;z-index:1}.aitwin-widget__logo{color:#fff;display:block;flex-shrink:0;height:calc(64px * var(--aitwin-size));margin-bottom:calc(4px * var(--aitwin-size));width:calc(64px * var(--aitwin-size))}.aitwin-widget__logo-draw{stroke-dasharray:1;stroke-dashoffset:1;animation:aitwin-widget-logo-draw 2.6s ease-in-out forwards}.aitwin-widget__logo-draw--loop{animation:aitwin-widget-logo-draw-loop 2.6s ease-in-out infinite}@keyframes aitwin-widget-logo-draw{to{stroke-dashoffset:0}}@keyframes aitwin-widget-logo-draw-loop{0%{stroke-dashoffset:1}45%{stroke-dashoffset:0}55%{stroke-dashoffset:0}to{stroke-dashoffset:-1}}@media(prefers-reduced-motion:reduce){.aitwin-widget__logo-draw,.aitwin-widget__logo-draw--loop{animation:none;stroke-dashoffset:0}}.aitwin-widget__face-loading-bar-wrap{max-width:calc(220px * var(--aitwin-size));width:100%}.aitwin-widget__face-loading-track{background:#fff3;border-radius:999px;height:calc(4px * var(--aitwin-size));overflow:hidden;width:100%}.aitwin-widget__face-loading-fill{background:var(--aitwin-accent);border-radius:999px;height:100%;transition:width .3s ease-out}.aitwin-widget__face-loading-pct{color:#ffffffbf;font-size:calc(12px * var(--aitwin-size));margin:calc(8px * var(--aitwin-size)) 0 0;text-align:center}.aitwin-widget__composer{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr auto;width:100%}.aitwin-widget__composer-input{background:#ffffff0a;border:1px solid var(--aitwin-border);border-radius:var(--aitwin-action-radius);color:var(--aitwin-text);font-family:inherit;font-size:calc(12px * var(--aitwin-size));min-width:0;outline:none;padding:calc(8px * var(--aitwin-size)) calc(10px * var(--aitwin-size))}.aitwin-widget__composer-input:focus{border-color:#f973168c}.aitwin-widget__composer-send{background:var(--aitwin-accent);border:none;border-radius:var(--aitwin-action-radius);color:#fff;cursor:pointer;font-family:inherit;font-size:calc(12px * var(--aitwin-size));font-weight:600;padding:0 calc(12px * var(--aitwin-size))}.aitwin-widget__composer-send:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__controls-error{color:#fecaca;font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget--float{bottom:20px;filter:drop-shadow(0 12px 32px rgba(0,0,0,.45));height:fit-content;margin:0;max-width:calc(100vw - 40px);position:fixed;right:20px;width:fit-content;z-index:2147483000}",ni="data-aitwin-widget-style";function ss(){if(typeof document>"u")return;const e=ac.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${ni}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const n=document.createElement("style");n.setAttribute(ni,"1"),n.textContent=e,(document.head??document.documentElement).appendChild(n)}typeof document<"u"&&ss();const oc=h.forwardRef(function(t,n){ss();const r=h.useRef(null);h.useImperativeHandle(n,()=>({speakText:async(s,o)=>{const a=r.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakText(s,o)},connect:async s=>{const o=r.current?.getTwin();if(!o)throw new Error("AiTwinWidget: twin is not mounted");return o.connect(s)},disconnect:async()=>{const s=r.current?.getTwin();if(s)return s.disconnect()},stop:()=>{r.current?.getTwin()?.stop()},isReady:()=>!!r.current?.getTwin()?.isReady(),isConnected:()=>!!r.current?.getTwin()?.isConnected(),getTwin:()=>r.current?.getTwin()??null}),[]);const i=!!t.float;return R.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:R.jsx(sc,{ref:r,options:t})})}),cc=new Set([".png",".jpg",".jpeg",".webp"]);function as(e=".png"){const t=e.toLowerCase();return cc.has(t)?`source${t}`:"source.png"}function lc(e,t=$n,n=".png"){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${as(n)}`}exports.AI_TWIN_THUMBNAIL_FILENAME=Yn;exports.AiTwin=ns;exports.AiTwinNotFoundError=nn;exports.AiTwinWidget=oc;exports.CONSONANT_SKIP_GROUP=Ti;exports.DEFAULT_TTS_ENGINE_ID=dt;exports.DEFAULT_TTS_LANGUAGE=Vs;exports.EMOTION_TO_EYEBROW=Gi;exports.EXPRESSION_ATLAS_EMOTIONS=Ra;exports.MIC_SAMPLE_RATE=nr;exports.OCULUS_VISEME_IDS=vi;exports.PLAYBACK_SAMPLE_RATE=rr;exports.SPEAKING_RATE_MAX=yn;exports.SPEAKING_RATE_MIN=pn;exports.TTS_ENGINE_CARTESIA=tt;exports.TTS_ENGINE_GOOGLE=Kn;exports.TTS_ENGINE_INWORLD=un;exports.TTS_ENGINE_VISEMETTS=nt;exports.TTS_LANGUAGE_CATALOG=ft;exports.TTS_LANGUAGE_CODES=wi;exports.VISEME_IDS=_a;exports.VISEME_SKIP_GAP_MS=On;exports.VISEME_TEST_CARTESIA_VOICE_ID=tr;exports.VISEME_TEST_SPEAKING_RATE=Ht;exports.VISEME_TEST_VISEMETTS_VOICE_ID=dn;exports.VISEME_TEST_VOICE_ID=er;exports.VISEME_VTIME_GRID_MS=Qn;exports.VOWEL_SKIP_GROUP=Si;exports.aiTwinSourceFilename=as;exports.buildPlaybackTransitions=Pi;exports.buildPlaybackVisemeSeries=gn;exports.buildRawVisemeTransitions=Mi;exports.buildVoiceWebSocketUrl=Ni;exports.compactSkippableVisemes=Jn;exports.createAvatarTtsLipsyncController=Nn;exports.createRealtimeVoiceLipsyncController=Vi;exports.emotionToEyebrow=mt;exports.faceAssetUrls=Ln;exports.fetchAiTwin=ci;exports.fetchAvatarReply=rs;exports.fetchDevAuthToken=Nt;exports.getAiTwinSourceUrl=lc;exports.getAiTwinThumbnailUrl=li;exports.isTtsLanguageCode=pi;exports.isTtsLanguageSupported=Ws;exports.listSkippedVisemeEntries=wn;exports.listSkippedVisemes=Js;exports.normalizeOculusViseme=mn;exports.normalizeStreamEmotion=Ze;exports.normalizeTtsLanguage=fn;exports.parsePackedVoiceId=si;exports.resolveDirectFaceId=ui;exports.resolveTwinBrainId=qn;exports.resolveVisemeAtTime=zt;exports.resolveVisemeFromPlaybackSeries=xi;exports.resolveWordAtTime=oa;exports.setActiveTwinAssets=di;exports.snapVisemeQueueToGrid=Xn;exports.snapVisemeVtimeToGrid=ki;exports.splitVoiceIdSpec=et;exports.ttsLanguagesForEngine=Us;
47
+ `;function qr(e=5){const t=new we.Filter({glProgram:we.GlProgram.from({vertex:Mo,fragment:Po,name:"threshold-key-filter"}),resources:{thresholdUniforms:{uThreshold:{value:e/255,type:"f32"}}}});return t.setThreshold=n=>{t.resources.thresholdUniforms.uniforms.uThreshold=n/255},t.getThreshold=()=>Math.round(t.resources.thresholdUniforms.uniforms.uThreshold*255),t}function Ro(e,t,n){return e>n||t>n}function Co(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function Do(e,t){return t!=null&&t>0?Math.floor(t):Co(e)}function Bo(e,t){const n=document.createElement("canvas");n.width=t.w,n.height=t.h;const r=n.getContext("2d");if(!r)throw new Error("Failed to acquire 2d context for atlas cell crop");return r.drawImage(e,t.x,t.y,t.w,t.h,0,0,t.w,t.h),n}function ns(e){return fetch(e).then(t=>{if(!t.ok)throw new Error(`Failed to load image: ${e}`);return t.blob()}).then(t=>createImageBitmap(t))}async function Yr(e,t,n,r,i){const s=n?await $i(e,i):await fetch(e).then(c=>{if(!c.ok)throw new Error(`Failed to load ${e}`);return c.json()}),o=s.sheets?.[0];if(!o?.path)throw new Error(`${e} has no sheets[0].path`);const a=new Map,u=async(c,m)=>{const w=Gi(t,m,n),S=n?await wa(await Pt(w,i??"")):await ns(w);if(Ro(S.width,S.height,r))return console.info(`[PixiVisemeCompositor] Sheet ${m} (${S.width}x${S.height}) exceeds MAX_TEXTURE_SIZE=${r}; using per-cell crops.`),{mode:"cells",bitmap:S};const f=we.Texture.from(S);return f.source.scaleMode="nearest",{mode:"full",texture:f}};a.set(o.index,await u(o.index,o.path));for(const c of s.sheets??[])c.index!==o.index&&c.path&&a.set(c.index,await u(c.index,c.path));const d=new Map;for(const c of s.cells??[])c.path&&d.set(c.path,c);const l=new Map;for(const c of s.sheets??[])l.set(c.index,c);return{atlasMeta:s,cellByPath:d,sheetByIndex:l,diffBase:t,sheets:a}}async function Fo(e,t={}){const n=new we.Application;try{await n.init({canvas:e,width:842,height:1264,preference:"webgl",autoStart:!1,antialias:!1,resolution:1,autoDensity:!1,backgroundAlpha:1,backgroundColor:0,powerPreference:"high-performance"})}catch(p){throw n.destroy({removeView:!1}),p}if(n.renderer.type!==we.RendererType.WEBGL)throw n.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const r=Do(n.renderer.gl,t.maxTextureSize);let i=!1,s=!1,o=!1;const a=n.canvas,u=()=>{i=!0,!s&&!o&&(s=!0,t.onWebGlContextLost?.())};a.addEventListener("webglcontextlost",u);const d=new we.Sprite(we.Texture.EMPTY),l=new we.Sprite(we.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new we.Sprite(we.Texture.EMPTY),m=new we.Sprite(we.Texture.EMPTY),w=new we.Sprite(we.Texture.EMPTY);w.visible=!1;const S=qr(5),f=qr(5);c.filters=[S],m.filters=[f],n.stage.addChild(d),n.stage.addChild(l),n.stage.addChild(c),n.stage.addChild(m),n.stage.addChild(w);let E=null,D=null,B=null,v=null,k=null,O=null,A=null,se=842,le=1264,I=null,U=5;const q=new Map;let oe=null,ae=null,ie=null;const L=mi(()=>{q.clear(),O=null,A=null,E=null,I=null}),Z=(p,b)=>{se=p,le=b,n.renderer.resize(p,b),(e.width!==p||e.height!==b)&&(e.width=p,e.height=b)},H=()=>{c.visible=!1,m.visible=!1,c.texture=we.Texture.EMPTY,m.texture=we.Texture.EMPTY,oe=null,ae=null},me=()=>{k=null,l.visible=!1,l.alpha=0},z=()=>{d.visible=!0,d.width=se,d.height=le,d.x=0,d.y=0},te=()=>{l.width=se,l.height=le,l.x=0,l.y=0},j=()=>{w.visible=!1,me(),E&&(d.texture=E,z())},J=()=>{!k&&!l.visible||j()},Se=p=>{if(o||i||!E){j();return}const b=Math.max(0,p);if(!D||b<=0){j();return}H(),w.visible=!1,d.texture=D,z(),l.texture=E,te(),l.alpha=0,l.visible=!0,k={startMs:performance.now(),durationMs:b},Y()},ue=(p=performance.now())=>{if(!k)return!1;if(o||i)return J(),!1;const b=(p-k.startMs)/Math.max(1,k.durationMs);if(b>=1)return j(),Y(),!1;const x=Math.min(1,Math.max(0,b)),W=x*x*(3-2*x);return l.alpha=W,l.visible=!0,Y(),!0},_=()=>{if(B){try{B.resource=null}catch{}B.destroy(),B=null}D&&(D.destroy(!1),D=null),v=null},C=(p,b)=>{const x=p.cellByPath.get(b);if(!x||!Hi(x))return null;const W=`${p.diffBase}::${b}`;let ee=q.get(W);if(!ee){const T=x.sheet??0,Q=p.sheets.get(T);if(!Q)return null;let V,he=!1;if(Q.mode==="full")V=new we.Texture({source:Q.texture.source,frame:new we.Rectangle(x.x,x.y,x.w,x.h)});else{const De=Bo(Q.bitmap,x);V=we.Texture.from(De),V.source.scaleMode="nearest",he=!0}ee={texture:V,ownsSource:he},q.set(W,ee)}return{texture:ee.texture,cell:x}},$=(p,b,x,W)=>{if(!W||!x)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const ee=C(x,W);if(!ee)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const T=zi(x.atlasMeta,ee.cell);return b.setThreshold(U),p.texture=ee.texture,p.x=T.x,p.y=T.y,p.width=ee.cell.w,p.height=ee.cell.h,p.visible=!0,!0},re=p=>{if(!p||!O)return null;const b=I??new Set(O.cellByPath.keys());return sr(p,b)??(b.has(p)?p:null)},K=p=>{w.visible=!1,j();const b=re(p.mouthPath),x=p.expressionPath&&A?or(p.expressionPath,W=>A.cellByPath.has(W)):null;b!==oe?($(c,S,O,b),oe=b):b?c.visible=!0:c.visible=!1,x!==ae?($(m,f,A,x),ae=x):x?m.visible=!0:m.visible=!1},Y=()=>{if(!(o||i||document.hidden))try{n.render()}catch{}};return{async loadAssets(p){if(o)return{width:se,height:le,visemePaths:[]};const b=Wt();if(b&&!p)throw new Error("Encrypted assets enabled but no key provided");const x=b?await ya(await Pt(sn(),p??"")):await ns(sn());E&&E.destroy(!0),E=we.Texture.from(x),E.source.scaleMode="linear";const W=hi();O=await Yr(gi(),W,b,r,p);try{A=await Yr(wi(),W,b,r,p)}catch(T){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",T),A=null}const ee=Wi(O.atlasMeta,x.width,x.height);return Z(ee.width,ee.height),U=vn(O.atlasMeta),S.setThreshold(U),f.setThreshold(U),I=new Set(O.cellByPath.keys()),q.clear(),j(),H(),Y(),{width:ee.width,height:ee.height,visemePaths:[...O.cellByPath.keys()]}},getVisemeAtlasPaths(){return I},drawLiveFrame(p){o||i||!E||(J(),K(p),Y())},drawIdleVideo(p,b){o||i||document.hidden||b&&!b()||p.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(me(),H(),w.visible=!1,!D||v!==p?(_(),B=new we.VideoSource({resource:p,autoPlay:!1,updateFPS:0}),B.autoUpdate=!1,D=new we.Texture({source:B}),v=p):D.source.update(),d.texture=D,z(),Y())},beginIdleToSilCrossfade:Se,tickIdleToSilCrossfade:ue,finishIdleToSilCrossfade:J,isIdleToSilCrossfading(){return k!=null},renderSilOnly(){o||i||!E||(H(),j(),Y())},blitBitmap(p){o||i||(J(),H(),ie&&(ie.destroy(!0),ie=null),ie=we.Texture.from(p),w.texture=ie,w.visible=!0,w.x=0,w.y=0,w.width=se,w.height=le,d.visible=!1,Y())},async compositePrefetchFrame(p){return null},renderFrame:Y,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",u),L(),_(),ie&&(ie.destroy(!0),ie=null);for(const{texture:b,ownsSource:x}of q.values())b.destroy(x);q.clear(),E&&(E.destroy(!0),E=null);const p=b=>{b.mode==="full"?b.texture.destroy(!0):b.bitmap.close()};if(O)for(const b of O.sheets.values())p(b);if(A)for(const b of A.sheets.values())p(b);S.destroy(!0),f.destroy(!0),n.destroy({removeView:!1},{children:!0,texture:!0})}}}const Qr=-1,tn=1e5,Xr=new Map;async function Lo(e){let t=Xr.get(e);if(!t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to fetch worker script (${n.status}): ${e}`);const r=await n.blob();t=URL.createObjectURL(r),Xr.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function Oo(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function zn(e,t){(e.width!==t.width||e.height!==t.height)&&(e.width=t.width,e.height=t.height);const n=e.getContext("2d");n&&n.drawImage(t,0,0)}function Jr(e,t){let n=0,r=null;const i=mr(async(s,o)=>(await Vn(),await Wn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await Vn(s);return r=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return r},async renderSilOnly(){n+=1,i.reset(),await no(e)},drawLiveFrame(s,o,a,u){i.enqueue(o,a,u)},async compositePrefetchFrame(s,o){try{return await to(s)}catch{return null}},blitBitmap(s,o){zn(s,o)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(s,o){n+=1;const a=n;t.onStatus?.(o),await Wn(s,{mouthPath:It(o),expressionPath:null})},dispose(){n+=1,i.reset()}}}function No(e,t,n){let r=null,i=1,s=0,o=!1,a=!1,u=null;const d=new Map,l=new Map;let c=tn;const m=mr(async(B,v,k)=>(d.set(v,{drawKey:k.drawKey,onDisplayed:k.onDisplayed}),await E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:v},void 0,!0),!1)),w=B=>{if(B===Qr){let O=-1,A;for(const[se,le]of d)se>=O&&(O=se,A=le);O>=0&&d.delete(O),A?.onDisplayed?.(A.drawKey);return}const v=-B,k=d.get(v);d.delete(v),k?.onDisplayed?.(k.drawKey)},S=new Map,f=(B,v)=>{a||!r||r.postMessage(B,[])},E=(B,v,k=!1)=>{if(a)return Promise.resolve();const O=i++;return new Promise((A,se)=>{S.set(O,{resolve:le=>A(le),reject:se,generation:typeof B.generation=="number"?B.generation:void 0,expectRenderDone:k}),f({...B,requestId:O})})},D=(async()=>{r=await Lo(n),r.onmessage=B=>{if(a)return;const v=B.data;if(v.type==="status"){t.onStatus?.(v.label);return}if(v.type==="frame"){if(v.generation<=-tn){const A=-v.generation,se=l.get(A);l.delete(A),se?.resolve(v.bitmap);return}const O=v.generation<0;if(!O&&v.generation!==s){v.bitmap.close();return}if(O&&!(v.generation===Qr)){const se=-v.generation;if(!m.isLatestSeq(se)){at()?.onWorkerStale(),v.bitmap.close();return}}if(O&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){at()?.onWorkerStale(),v.bitmap.close();return}zn(e,v.bitmap),v.bitmap.close(),O&&w(v.generation);return}const k=S.get(v.requestId);if(k)switch(v.type){case"ready":S.delete(v.requestId),k.resolve();break;case"loadAssetsDone":S.delete(v.requestId),u=v.visemePaths?.length?new Set(v.visemePaths):null,k.resolve({width:v.width,height:v.height,visemePaths:v.visemePaths});break;case"renderDone":if(k.expectRenderDone&&k.generation!=null&&v.generation!==k.generation)return;S.delete(v.requestId),k.resolve();break;case"renderAborted":S.delete(v.requestId),k.resolve();break;case"error":S.delete(v.requestId),t.onError?.(v.message),k.reject(new Error(v.message));break}},r.onerror=B=>{if(a)return;const v=B.message||"Worker error";t.onError?.(v);for(const[,k]of S)k.reject(new Error(v));S.clear()},await E({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(B){if(a)return{width:842,height:1264};if(await D,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await E({type:"loadAssets",keyHex:B,urls:Ls(pt())})??{width:842,height:1264}},getVisemeAtlasPaths(){return u},async renderSilOnly(){if(a||(await D,a))return;s+=1,m.reset(),d.clear(),l.forEach(({resolve:v})=>v(null)),l.clear(),c=tn;const B=s;await E({type:"cancelLiveDraws"}),await E({type:"renderSil",generation:B},void 0,!0)},drawLiveFrame(B,v,k,O){a||D.then(()=>{a||m.enqueue(v,k,O)})},compositePrefetchFrame(B,v){return a?Promise.resolve(null):D.then(()=>{if(a)return null;const k=++c;return new Promise(O=>{l.set(k,{resolve:O}),E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:k},void 0,!0).catch(()=>{l.delete(k),O(null)})})})},blitBitmap(B,v){zn(B,v)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(B,v,k={}){if(a||(await D,a))return;s+=1,m.reset(),d.clear();const O=s;try{await E({type:"cancelLiveDraws"}),await E({type:"renderViseme",generation:O,to:v,from:k.from,transitionDurationMs:k.transitionDurationMs,gapMs:k.gapMs,threshold:k.threshold},void 0,!0)}catch(A){if(A?.name==="AbortError")return;throw A}},dispose(){if(!a){a=!0,s+=1,m.reset(),d.clear(),l.forEach(({resolve:B})=>B(null)),l.clear(),c=tn;for(const[,B]of S)B.resolve();S.clear(),r?.terminate(),r=null}}}}async function Uo(e,t){const n=await Fo(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let r=0,i=null,s=!1;const o=mr(async(a,u)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(at()?.onWorkerStale(),!1):(n.drawLiveFrame(a),o.isLatestSeq(u)));return{usesWorker:!1,usesPixi:!0,async loadAssets(a){if(s)return{width:842,height:1264};const u=await n.loadAssets(a);return i=u.visemePaths?.length?new Set(u.visemePaths):null,u},getVisemeAtlasPaths(){return i},async renderSilOnly(){s||(r+=1,o.reset(),n.renderSilOnly())},drawLiveFrame(a,u,d,l){s||o.enqueue(u,d,l)},async compositePrefetchFrame(a,u){if(s)return null;try{return await n.compositePrefetchFrame(a)}catch{return null}},blitBitmap(a,u){s||t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()||n.blitBitmap(u)},drawIdleVideo(a,u){s||n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){s||n.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return s?!1:n.tickIdleToSilCrossfade(a)},finishIdleToSilCrossfade(){s||n.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return s?!1:n.isIdleToSilCrossfading()},supportsBufferedPlayback:!1,async renderViseme(a,u){if(s)return;r+=1;const d=r;o.reset(),t.onStatus?.(u),n.drawLiveFrame({mouthPath:It(u),expressionPath:null})},dispose(){s||(s=!0,r+=1,o.reset(),n.dispose())}}}function Zr(e,t){if(!Oo())return Jr(e,t);const n=ps(t.workerScriptUrl);try{return No(e,t,n)}catch{return Jr(e,t)}}function Vo(e,t={}){if(t.preferLegacyRenderer)return Zr(e,t);let n=null,r=!1,i=null,s=!1;const o=()=>n?Promise.resolve(n):(i||(i=(async()=>{try{const a=await Uo(e,t);if(s)throw a.dispose(),new Error("Renderer disposed during Pixi init");return r=!0,n=a,a}catch(a){if(s)throw a instanceof Error?a:new Error(String(a));return console.warn("[AiTwin] Pixi WebGL renderer unavailable, using Canvas2D fallback:",a),n=Zr(e,t),r=!1,n}})()),i);return{get usesWorker(){return n?.usesWorker??!1},get usesPixi(){return r},async loadAssets(a){return(await o()).loadAssets(a)},getVisemeAtlasPaths(){return n?.getVisemeAtlasPaths()??null},async renderSilOnly(){return(await o()).renderSilOnly()},drawLiveFrame(a,u,d,l){o().then(c=>{s||c.drawLiveFrame(a,u,d,l)})},async compositePrefetchFrame(a,u){return(await o()).compositePrefetchFrame(a,u)},blitBitmap(a,u){n&&n.blitBitmap(a,u)},drawIdleVideo(a,u){n?.usesPixi&&n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){n?.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return n?.tickIdleToSilCrossfade(a)??!1},finishIdleToSilCrossfade(){n?.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return n?.isIdleToSilCrossfading()??!1},get supportsBufferedPlayback(){return n?.supportsBufferedPlayback??!1},async renderViseme(a,u,d){return(await o()).renderViseme(a,u,d)},dispose(){s=!0,i=null,n?.dispose(),n=null}}}class Wo extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function Rn(e,t,n){return new Promise((r,i)=>{const s=globalThis.setTimeout(()=>{i(new Wo(n,t))},t);e.then(o=>{globalThis.clearTimeout(s),r(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const zo={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Ho={display:"block",maxWidth:"100%",height:"auto"},$o={position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"rgba(0,0,0,0.55)",color:"#fff",fontSize:"0.875rem",textAlign:"center"};function Cn(e){return Ts(e)?nr:ci(e)?dn:tr}function Je(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const rs=h.forwardRef(function({id:t,avatarId:n,faceId:r,assets:i,authToken:s,apiBase:o,ttsEngineId:a,voiceId:u,language:d,speakingRate:l=Ht,className:c,style:m,canvasStyle:w,onStatusChange:S,onDisplayStatus:f,onError:E,onReady:D,showErrorOverlay:B=!0,loadingThumbnailUrl:v,onUserTranscript:k,onBotOutput:O,onRealtimeLipsyncDebug:A,onFrameRenderStats:se,lipsyncBufferedPlayback:le=!0,lipsyncPlaybackWarmupMs:I=1500,idleHandoffHoldMs:U=wo,pixiMaxTextureSize:q,captions:oe},ae){const ie=h.useRef(null),L=h.useRef(null),Z=h.useRef(null),H=h.useRef(le);H.current=le;const me=h.useRef(I);me.current=I;const z=h.useRef(U);z.current=U;const te=h.useRef(0),j=h.useRef(dr()),J=h.useRef(ja()),Se=h.useRef(!1),ue=h.useRef(null),_=h.useRef(null),C=h.useRef(0),$=h.useRef(0),re=h.useRef(0),K=h.useRef(null),Y=h.useRef(null),p=h.useRef(!1),b=h.useRef(!1),x=h.useRef(!1),W=h.useRef(!1),ee=h.useRef("sil"),T=h.useRef(0),Q=h.useRef(!1),V=h.useRef(null),he=h.useRef(!1),[De,ot]=h.useState("idle"),[yt,Rt]=h.useState(null),[ct,_n]=h.useState(!1),[g,P]=h.useState(!1),[ne,ce]=h.useState(!1),[Te,be]=h.useState(),[ke,ze]=h.useState({width:842,height:1264}),[Ne,$t]=h.useState(null),[bn,Ct]=h.useState(0),vt=h.useRef(!1),Be=h.useRef(s??null),$e=o?.trim()||gt,_t=h.useRef(null),Ee=h.useRef(null),{ttsEngineId:Ie,voiceId:je}=h.useMemo(()=>{const y=et(a,u),M=y.ttsEngineId??ft;return{ttsEngineId:M,voiceId:y.voiceId??Cn(M)}},[a,u]),Ke=h.useRef(!1),rt=h.useRef({width:842,height:1264}),ye=h.useRef(null),Ue=h.useRef("sil"),Re=h.useRef(""),Ve=h.useMemo(()=>io(oe),[oe]),We=h.useCallback(()=>{Re.current="",$t(null)},[]);h.useEffect(()=>{Ve.enabled||We()},[Ve.enabled,We]);const Dt=h.useCallback(y=>{if(!Ve.enabled)return;const M=y.isSpeaking(),N=y.isWarmingUp();if(!M||N){Re.current&&We();return}const F=ro(y.getWordQueue());if(!F){Re.current&&We();return}F!==Re.current&&(Re.current=F,$t(F))},[Ve.enabled,We]),lt=h.useRef(void 0),Bt=h.useRef(new Map),hr=h.useRef(D),gr=h.useRef(S),ve=h.useRef(f),wr=h.useRef(E),pr=h.useRef(k),yr=h.useRef(O),jt=h.useRef(A),vr=h.useRef(se),bt=h.useRef(go());hr.current=D,gr.current=S,ve.current=f,wr.current=E,pr.current=k,yr.current=O,jt.current=A,vr.current=se,h.useEffect(()=>{const y=bt.current;return Hr(y),()=>Hr(null)},[]);const _r=h.useCallback(y=>{const M=et(y?.ttsEngineId??a,y?.voiceId??u),N=M.ttsEngineId??Ee.current?.ttsEngineId??ft,F=M.voiceId??Ee.current?.voiceId??Cn(N);return{ttsEngineId:N,voiceId:F}},[a,u]),it=h.useCallback(y=>{Rt(y),ce(!0),wr.current?.(y)},[]),Ft=h.useCallback(y=>{ot(y),gr.current?.(y)},[]),de=h.useRef(Nn(Ft,$e,{onLipsyncDebug:y=>jt.current?.(y)})),fe=h.useRef(null),br=h.useRef(()=>{});h.useEffect(()=>(de.current=Nn(Ft,$e,{onLipsyncDebug:y=>jt.current?.(y)}),s&&de.current.setDeveloperToken(s),de.current.setTtsEngineId(Ie),()=>{de.current.stop();const y=fe.current;y&&(y.disconnect(),fe.current=null)}),[Ft,$e]);const Sr=h.useCallback(()=>(fe.current||(fe.current=Vi(Ft,{speakingRate:l,language:d,onUserTranscript:(y,M)=>pr.current?.(y,M),onBotOutput:y=>yr.current?.(y),onLipsyncDebug:y=>jt.current?.(y)}),fe.current.setTtsEngineId(Ie),br.current(!0)),fe.current),[Ft,l,d,Ie]),Fe=h.useCallback(()=>{K.current!=null&&(clearTimeout(K.current),K.current=null)},[]),Le=h.useCallback(()=>{Y.current!=null&&(clearTimeout(Y.current),Y.current=null),x.current=!1},[]),Kt=h.useCallback(()=>{if(W.current)return;const y=L.current;if(W.current=!0,Le(),p.current=!1,b.current=!1,!he.current||!V.current){y?.renderSilOnly();return}V.current.setActive(!1);const M=V.current.getVideo();if(y?.usesPixi){y.drawIdleVideo(M),y.beginIdleToSilCrossfade(jr);return}(async()=>{const N=ie.current;N&&await Mn(N,M,null,void 0,rt.current).catch(()=>{}),await new Promise(F=>setTimeout(F,jr)),W.current&&await y?.renderSilOnly()})()},[Le]),Tr=h.useCallback(()=>{!he.current||!V.current||(W.current=!1,L.current?.finishIdleToSilCrossfade(),Le(),x.current=!0,Y.current=setTimeout(()=>{if(Y.current=null,Je(de.current,fe.current).isSpeaking()){x.current=!1;return}if(p.current){x.current=!1;return}const y=V.current;if(!y){x.current=!1;return}y.restart(),y.setActive(!0);const M=y.getVideo();let N=!1;const F=()=>{N||(N=!0,M.removeEventListener("playing",X),x.current=!1)},X=()=>{F()};if(M.addEventListener("playing",X,{once:!0}),M.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!M.paused){F();return}setTimeout(F,300)},z.current))},[Le]),St=h.useCallback(()=>{if(Fe(),ve.current?.("sil"),p.current=!1,W.current=!1,!he.current||!V.current){x.current=!1;return}Tr()},[Fe,Tr]),Sn=h.useCallback(async y=>{const M=$.current,N=L.current,F=ie.current,X=()=>{y?.fallbackOnly||(p.current=!1)};if(!N||!F||!ct){X();return}if(Je(de.current,fe.current).isSpeaking()){X();return}if(y?.fallbackOnly){if(!p.current||(Oe(j.current),await N.renderSilOnly(),M!==$.current)||Je(de.current,fe.current).isSpeaking())return;St();return}if(Kr(j.current)){Oe(j.current),St();return}if(H.current&&N.supportsBufferedPlayback&&!y?.fallbackOnly){if(Oe(j.current),Z.current?.reset(),await N.renderSilOnly(),M!==$.current||Je(de.current,fe.current).isSpeaking())return;St();return}const xe=bo(Je(de.current,fe.current).getVisemeQueue(),T.current,ee.current),Me=So(xe,ye.current);if(Oe(j.current),!Me){if(await N.renderSilOnly(),M!==$.current||Je(de.current,fe.current).isSpeaking())return;St();return}try{await N.renderViseme(F,"sil",{from:xe,transitionDurationMs:Zi})}catch(Ce){if(Ce?.name!=="AbortError")throw Ce}if(M!==$.current){X();return}if(Je(de.current,fe.current).isSpeaking()){X();return}St()},[ct,St]),Tt=h.useCallback(()=>{if(b.current||p.current)return;b.current=!0,p.current=!0,Fe();const y=$.current;Sn().finally(()=>{b.current=!1}),K.current=setTimeout(()=>{K.current=null,y===$.current&&Sn({fallbackOnly:!0})},To())},[Fe,Sn]),kr=h.useCallback(async()=>{const y=Math.floor(Date.now()/1e3);if(_t.current&&y<_t.current.expiresAt-60)return _t.current.key;const M=Be.current??await Nt();Be.current=M,de.current.setDeveloperToken(M);const N=await Cs(M,$e);return _t.current={key:N.value,expiresAt:N.expiresAt},N.value},[$e]);h.useEffect(()=>{s&&(Be.current=s,de.current.setDeveloperToken(s))},[s]),h.useEffect(()=>{de.current.setTtsEngineId(Ie),fe.current?.setTtsEngineId(Ie),Ee.current&&(Ee.current.ttsEngineId=Ie)},[Ie]),h.useEffect(()=>{Ee.current&&(Ee.current.voiceId=je)},[je]);const Ge=h.useMemo(()=>di(n,r),[n,r]),cs=h.useMemo(()=>i?JSON.stringify(i):Ge?`face:${Ge}`:`id:${t??""}`,[i,Ge,t]),ls=h.useMemo(()=>{const y=v?.trim();return y||(Ir(Ge)??Ir(Te)??xs(i))},[v,Ge,Te,i]);return h.useEffect(()=>{if(!t&&!i&&!Ge){it("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let y=!1;Ke.current=!1,_n(!1),P(!1),ce(!1),be(Ge),Rt(null),Ee.current=null,V.current=null,he.current=!1;const M=ie.current;if(!M)return;let N=null;return(async()=>{try{let F,X,Ae,xe,Me;if(i)F=i,X=Ie,Ae=je;else if(Ge)ve.current?.("loadFace"),F=Ln(Ge),X=Ie,Ae=je;else{ve.current?.("getAiTwin");const G=await Rn(li(t),3e4,"getAiTwin");if(y)return;if(!G.faceId?.trim())throw new Error("getAiTwin returned no faceId");be(G.faceId.trim());const _e=et(a,u);X=_e.ttsEngineId??G.ttsEngineId,Ae=_e.voiceId??G.voiceId??Cn(X),xe=qn(G),Me=Yn(G),F=Ln(G.faceId)}Ee.current={ttsEngineId:X,voiceId:Ae,brainId:xe,brainUrl:Me},fi(F),V.current=Ka();const Ce=!!(i&&!wt(i));N=Vo(M,{preferLegacyRenderer:Ce,pixiMaxTextureSize:q,onStatus:G=>{y||ve.current?.(G)},onError:G=>{y||it(G)},shouldAcceptLiveFrame:()=>{if(Se.current)return!0;if(p.current)return!1;const G=Je(de.current,fe.current);return G.isSpeaking()||G.isWarmingUp()},onWebGlContextLost:()=>{y||vt.current||(vt.current=!0,queueMicrotask(()=>{y||Ct(G=>G+1)}))}}),L.current=N,Z.current=Ao(N),vt.current=!1;const qe=G=>{const _e=()=>{if(!G||me.current<=0)return!1;const Pe=L.current;return Pe?H.current&&Pe.supportsBufferedPlayback?!0:Pe.usesPixi:!1};de.current.setLipsyncWarmupHold(G,_e),fe.current?.setLipsyncWarmupHold(G,_e)};br.current=qe,qe(!0),ve.current?.("auth");const Gt=Be.current??s??await Rn(Nt(),3e4,"getAuthToken");if(y)return;Be.current=Gt,de.current.setDeveloperToken(Gt),de.current.setTtsEngineId(X);const pe=Wt()?await kr():void 0;if(y)return;ve.current?.("loadAssets");const ge=await Rn(N.loadAssets(pe),18e4,"load face assets");if(!y&&ge.width>0&&ge.height>0&&(rt.current=ge,ze(ge)),y)return;ye.current=N.getVisemeAtlasPaths(),Ke.current=!0,_n(!0),hr.current?.(),N.renderSilOnly().then(()=>{y||ve.current?.("sil")}),(async()=>{try{const G=await ba(pe);if(await V.current.load(G),y)return;he.current=!0,P(!0),Oe(j.current),V.current.setActive(!0);const _e=V.current.getVideo();N.usesPixi?N.drawIdleVideo(_e):await Mn(M,_e,null,void 0,rt.current)}catch(G){if(y)return;he.current=!1,P(!1),console.warn("[AiTwin] Idle video unavailable:",G)}finally{y||(ce(!0),ve.current?.("idle"))}})()}catch(F){if(y)return;if(F instanceof nn){it(F.message);return}it(F instanceof Error?F.message:"Failed to load AI twin")}})(),()=>{y=!0,V.current?.dispose(),N?.dispose(),L.current=null}},[cs,i,Ge,t,Ie,je,a,u,s,q,kr,it,bn]),h.useEffect(()=>{const y={current:!1},M=()=>{const N=ie.current,F=L.current,X=Je(de.current,fe.current);if(!N||!F||!ct){C.current=requestAnimationFrame(M);return}if(document.hidden){V.current?.setActive(!1),C.current=requestAnimationFrame(M);return}const Ae=X.isSpeaking(),xe=X.isWarmingUp(),Me=Ae&&!Q.current,Ce=Q.current&&!Ae;Me&&(Fe(),Le(),p.current=!1,b.current=!1,Oe(j.current),Z.current?.reset(),bt.current.reset(),lt.current=void 0,re.current=0,ee.current="sil",T.current=0,Kt()),Ce&&(J.current.reset(),V.current?.setActive(!1),Z.current?.reset(),F.finishIdleToSilCrossfade(),We(),Tt());const qe=Ce||p.current||x.current||W.current,Gt=le&&F.supportsBufferedPlayback;if(xe){if(Kt(),he.current&&V.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()){F.tickIdleToSilCrossfade(performance.now()),X.getVisemeQueue().length>0&&te.current===0&&(te.current=performance.now()),Q.current=X.isSpeaking(),C.current=requestAnimationFrame(M);return}const pe=X.getVisemeQueue();pe.length>0&&te.current===0&&(te.current=performance.now()),J.current.advance(performance.now());const ge=J.current.getExpressionPath(),G=J.current.getDrawKey(),_e={queue:pe,elapsedMs:0,expressionPath:ge,expressionDrawKey:G,availablePaths:ye.current};let Pe=!1;Gt&&Z.current?(Z.current.warmupTick(_e),Pe=Z.current.isWarmupReady(_e,me.current)):F.usesPixi&&Gr(N,pe,0,ge,G,j.current,(kt,qt,Tn,Yt)=>{F.drawLiveFrame(kt,qt,Tn,Ye=>{Yt?.(Ye),X.isWarmingUp()&&Ye!==""&&!Kr({lastDrawnKey:Ye})&&(te.current=0,X.releaseWarmupHold())})},kt=>{ve.current?.(kt.label)},ye.current);const st=te.current>0&&performance.now()-te.current>vs;ve.current?.(Pe?"buffer ready":"buffering lipsync…"),(Pe||st)&&(te.current=0,X.releaseWarmupHold()),Dt(X),Q.current=X.isSpeaking(),C.current=requestAnimationFrame(M);return}if(Ae){Kt(),he.current&&V.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()&&F.finishIdleToSilCrossfade();const pe=X.getVisemeQueue(),ge=X.getPlaybackElapsedMs();ca(pe,ge),T.current=ge;const G=pe.length>0?zt(pe,ge):"sil";G!=="sil"&&(ee.current=G);const _e=Qa(ge,X.getSentenceEmotions(),X.getWordQueue(),X.getStreamMood());J.current.setTargetEmotion(_e),J.current.setTargetEyebrow(Ha(ge,X.getWordQueue(),ht(_e))),J.current.advance(performance.now());const Pe=J.current.getExpressionPath(),st=J.current.getDrawKey(),kt=(Ye,kn,Lt,En)=>{const Er={label:Ue.current,elapsedMs:ge,mouthPath:kn.mouthPath,transitionMeta:lt.current};Bt.current.set(Lt,Er),Z.current?.markExternallyDisplayed(Lt,Pe),F.drawLiveFrame(Ye,kn,Lt,Qt=>{const us=Bt.current.get(Qt)??Er;Bt.current.delete(Qt),bt.current.onDrawDisplayed(us,pe),Z.current?.markExternallyDisplayed(Qt,Pe),En?.(Qt)})},qt=Ye=>{Ue.current=Ye.label,lt.current=Ye.transitionMeta,ve.current?.(Ye.label)},Tn=le&&F.supportsBufferedPlayback;let Yt=!1;Tn&&Z.current&&(Yt=Z.current.tick({canvas:N,queue:pe,elapsedMs:ge,expressionPath:Pe,expressionDrawKey:st,playbackState:j.current,availablePaths:ye.current,onStatus:qt,onDisplayed:(kn,Lt,En)=>{bt.current.onDrawDisplayed({label:En,elapsedMs:ge,mouthPath:Lt,transitionMeta:lt.current},pe)}}).usedBuffer),Yt||Gr(N,pe,ge,Pe,st,j.current,kt,qt,ye.current),bt.current.onRafTickSpeaking(),vr.current?.(bt.current.snapshot(pe,ge))}else if(!qe&&Se.current){V.current?.setActive(!1),J.current.advance(performance.now());const pe=J.current.getExpressionPath(),ge=J.current.getDrawKey();Pn(N,pe,ge,j.current,(G,_e,Pe,st)=>F.drawLiveFrame(G,_e,Pe,st),G=>{if(_.current){ve.current?.(_.current);return}const _e=J.current.getTargetEmotion();ve.current?.(G==="sil"||G==="blink"?`${_e}${G==="blink"?" · blink":""}`:G)},null,ue.current)}else if(!qe&&he.current&&V.current){const pe=V.current,ge=pe.getVideo();if(ge.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){pe.setActive(!0);const G=()=>!X.isSpeaking()&&!p.current&&!x.current&&!Se.current;F.usesPixi?(F.drawIdleVideo(ge,G),G()&&ve.current?.("idle")):y.current||(y.current=!0,Mn(N,ge,null,void 0,rt.current,G).then(()=>ve.current?.("idle")).finally(()=>{y.current=!1}))}else Pn(N,null,"__sil__",j.current,(G,_e,Pe,st)=>F.drawLiveFrame(G,_e,Pe,st),G=>ve.current?.(G))}else qe||Pn(N,null,"__sil__",j.current,(pe,ge,G,_e)=>F.drawLiveFrame(pe,ge,G,_e),pe=>ve.current?.(pe));Ve.enabled&&Dt(X),Q.current=Ae,C.current=requestAnimationFrame(M)};return C.current=requestAnimationFrame(M),()=>{cancelAnimationFrame(C.current),Fe(),Le(),de.current.stop(),fe.current?.stop()}},[ct,g,Tt,Fe,Le,Kt,Dt,We,Ve.enabled]),h.useImperativeHandle(ae,()=>({speakText:async(y,M)=>{const N=y.trim();if(!N)return;const F=L.current;if(!F||!Ke.current&&!ct)throw new Error("AI twin is not ready");const{ttsEngineId:X,voiceId:Ae}=_r(M);Rt(null),We(),$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,ee.current="sil",T.current=0,Oe(j.current),Se.current=!1,ue.current=null,_.current=null,J.current.reset(),Q.current=!1,W.current=!1,F.finishIdleToSilCrossfade();try{await de.current.speak(N,{voiceId:Ae,speakingRate:M?.speakingRate??l,ttsEngineId:X,language:M?.language??d})}catch(xe){throw W.current=!1,F.finishIdleToSilCrossfade(),Tt(),it(xe instanceof Error?xe.message:"TTS failed"),xe}},stop:()=>{$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,W.current=!1,L.current?.finishIdleToSilCrossfade(),de.current.stop(),fe.current?.stop(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,We(),Tt()},setTtsEngineId:y=>{de.current.setTtsEngineId(y),fe.current?.setTtsEngineId(y),Ee.current&&(Ee.current.ttsEngineId=y)},renderViseme:async(y,M)=>{const N=L.current,F=ie.current;if(!N||!F||!Ke.current)throw new Error("AI twin is not ready");await N.renderViseme(F,y,{from:M?.from,transitionDurationMs:M?.transitionDurationMs,gapMs:M?.gapMs,onStatus:X=>ve.current?.(X)})},setEmotion:y=>{if(!Ke.current)throw new Error("AI twin is not ready");const M=L.current,N=ie.current;if(!M||!N)throw new Error("AI twin is not ready");$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,x.current=!1,W.current=!1,de.current.stop(),fe.current?.stop(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,M.finishIdleToSilCrossfade(),V.current?.setActive(!1);const F=Ze(y);Se.current=!0,ue.current=null,_.current=null,J.current.snapToEmotion(F);const X=J.current.getExpressionPath(),Ae=J.current.getDrawKey(),xe={mouthPath:null,expressionPath:X},Me=Vt(xe,Ae);j.current.lastDrawnKey="",M.drawLiveFrame(N,xe,Me,qe=>{qe===Me&&(j.current.lastDrawnKey=Me)});const Ce=ht(F);ve.current?.(X?`${F} · brow ${Ce>0?"+":""}${Ce}`:`${F} · brow 0 (sil base)`)},getEmotion:()=>Se.current?J.current.getTargetEmotion():null,clearEmotionPreview:()=>{Se.current=!1,ue.current=null,_.current=null,J.current.reset(),Oe(j.current),ve.current?.("idle")},setViseme:y=>{if(!Ke.current)throw new Error("AI twin is not ready");const M=L.current,N=ie.current;if(!M||!N)throw new Error("AI twin is not ready");$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,x.current=!1,W.current=!1,de.current.stop(),fe.current?.stop(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,M.finishIdleToSilCrossfade(),V.current?.setActive(!1);const F=mn(y);Se.current=!0,_.current=F,ue.current=F==="sil"?null:It(F),J.current.snapToEmotion("neutral");const X=J.current.getExpressionPath(),Ae=J.current.getDrawKey(),Me={mouthPath:ue.current,expressionPath:X},Ce=Vt(Me,Ae);j.current.lastDrawnKey="",M.drawLiveFrame(N,Me,Ce,qe=>{qe===Ce&&(j.current.lastDrawnKey=Ce)}),ve.current?.(F)},getViseme:()=>Se.current?_.current:null,isReady:()=>Ke.current,getStatus:()=>De,connect:async(y={})=>{Rt(null);try{let M=y.authToken?.trim();M||(M=Be.current??s??await Nt(),Be.current=M);const N=et(y.ttsEngineId??a,y.voiceId??u),F=N.voiceId??Ee.current?.voiceId,X=y.brainId?.trim()||y.personaId?.trim()||Ee.current?.brainId,Ae=y.brainUrl?.trim()||Ee.current?.brainUrl,xe=N.ttsEngineId??Ee.current?.ttsEngineId??Ie,Me=Sr();xe&&Me.setTtsEngineId(xe),await Me.unlockAudio(),await Me.connect({...y,apiBase:y.apiBase?.trim()||$e,authToken:M,voiceId:F,brainId:X,brainUrl:Ae,ttsEngineId:xe,speakingRate:y.speakingRate??l,language:y.language??d})}catch(M){throw it(M instanceof Error?M.message:"Voice connect failed"),M}},disconnect:async()=>{const y=fe.current;y&&($.current+=1,Fe(),Le(),p.current=!1,b.current=!1,W.current=!1,L.current?.finishIdleToSilCrossfade(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,await y.disconnect(),Tt())},isConnected:()=>fe.current?.isConnected()??!1,getVoiceStream:()=>fe.current?.getVoiceStream()??de.current?.getVoiceStream()??null,setMuted:y=>{const M=de.current,N=fe.current;M?.setMuted?.(y),N?.setMuted?.(y)},isMuted:()=>{const y=fe.current,M=de.current;return y?.isMuted?.()??M?.isMuted?.()??!1},getBrainId:()=>Ee.current?.brainId?.trim()||null,getPersonaId:()=>Ee.current?.brainId?.trim()||null,getBrainUrl:()=>Ee.current?.brainUrl?.trim()||null}),[ct,l,d,s,Ie,je,Fe,Le,Tt,it,_r,Sr,De,$e]),R.jsxs("div",{className:c,style:{...zo,...m},children:[R.jsx("canvas",{ref:ie,width:ke.width,height:ke.height,style:{...Ho,...w},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!ne&&!yt?R.jsx(mo,{thumbnailUrl:ls}):null,B&&yt?R.jsx("div",{style:$o,children:yt}):null,Ve.enabled&&Ne?R.jsx(co,{text:Ne,style:Ve.style},Ne):null]})});async function jo(e){try{const t=await e.json();if(typeof t.detail=="string"&&t.detail.trim())return t.detail;if(typeof t.error=="string"&&t.error.trim())return t.error}catch{}return`avatarReply failed (${e.status})`}async function is(e){const t=e.message.trim();if(!t)throw new Error("Message is required");const n=e.authToken.trim();if(!n)throw new Error("Auth token is required");const r=(e.apiBase?.trim()||gt).replace(/\/$/,""),i=await fetch(`${r}/avatarReply`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`,Accept:"text/event-stream"},body:JSON.stringify({message:t,history:e.history??[],brainId:e.brainId?.trim()||e.personaId?.trim()||"",tenant:"aiTwin"})});if(!i.ok)throw new Error(await jo(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",u="",d="",l="";for(;;){const{done:c,value:m}=await s.read();if(c)break;a+=o.decode(m,{stream:!0});const w=a.split(`
48
+ `);a=w.pop()||"";for(const S of w){if(S.startsWith("event: ")){l=S.slice(7).trim();continue}if(!S.startsWith("data: "))continue;const f=S.slice(6).trim();if(!f)continue;let E;try{E=JSON.parse(f)}catch{continue}if(l==="spokenText")u=E.text||"",e.onSpokenText?.(u);else if(l==="displayText")d=E.text||"";else if(l==="error")throw new Error(E.error||"avatarReply stream error")}}if(!u.trim()||!d.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:d.trim(),spokenText:u.trim()}}function Ko({muted:e}){return e?R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"M15.5 8.5a4.5 4.5 0 0 1 0 7M18.5 6a8 8 0 0 1 0 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}function Go(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function qo(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Yo(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:R.jsx("path",{d:"M5 6.5A2.5 2.5 0 0 1 7.5 4h9A2.5 2.5 0 0 1 19 6.5v7A2.5 2.5 0 0 1 16.5 16H10l-4 3.5V16H7.5A2.5 2.5 0 0 1 5 13.5v-7Z",stroke:"currentColor",strokeWidth:"2",strokeLinejoin:"round"})})}function ss({className:e}){return R.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:R.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:R.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function Qo({muted:e,onToggle:t}){return R.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:R.jsx(Ko,{muted:e})})}function Xo(){return R.jsxs("div",{className:"aitwin-widget__connecting",role:"status","aria-live":"polite",children:[R.jsx(ss,{className:"aitwin-widget__spinner aitwin-widget__spinner--accent"}),R.jsx("span",{children:"Connecting..."})]})}function Jo(e){const t=e.connecting||e.textSending||e.status==="loading"||e.status==="speaking",n=e.connecting?"Connecting...":e.connected?"End Talk":"Talk",r=["aitwin-widget__action",e.textMode&&!e.connecting?"":"aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return R.jsxs("div",{className:"aitwin-widget__controls",children:[R.jsxs("div",{className:"aitwin-widget__actions",children:[R.jsxs("button",{type:"button",className:r,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,children:[e.connecting?R.jsx(ss,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?R.jsx(qo,{}):R.jsx(Go,{}),R.jsx("span",{children:n})]}),R.jsxs("button",{type:"button",className:e.textMode?"aitwin-widget__action aitwin-widget__action--primary":"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":e.textMode,children:[R.jsx(Yo,{}),R.jsx("span",{children:"Text"})]})]}),e.textMode?R.jsxs("form",{className:"aitwin-widget__composer",onSubmit:i=>{i.preventDefault(),e.onSendText()},children:[R.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:i=>e.onTextDraftChange(i.target.value),placeholder:e.textSending?"Getting reply...":"Type a message…",autoComplete:"off",disabled:!e.ready||t}),R.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||t||!e.textDraft.trim()&&!e.textSending,"aria-busy":e.textSending,children:e.textSending?"…":"Send"})]}):null,e.error?R.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const ei=97,Zo=3500;function ec(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/Zo);return Math.min(ei,Math.round(r*ei))}function tc(e){const[t,n]=h.useState(null),[r,i]=h.useState(()=>Date.now());return h.useEffect(()=>{if(!e){n(null);return}const s=Date.now();n(s),i(s);let o=0;const a=()=>{i(Date.now()),o=window.requestAnimationFrame(a)};return o=window.requestAnimationFrame(a),()=>{window.cancelAnimationFrame(o)}},[e]),e?t==null?0:ec(r-t):100}const nc="M259.01,593.87v-101.49c.33-6.31,4.94-11.26,10.21-11.88,6.42-.75,13.18,4.99,13.13,12.92-.42,45.09-.83,90.17-1.25,135.26.03,1.56.56,15.43,11.95,23.2,6.18,4.21,12.57,4.6,15.42,4.58-.42-112.77-.83-225.54-1.25-338.31-.08-2.55-1.03-46.36,21.17-55.34,2.05-.83,4.42-1.41,7.17-1.56v453.42c.07,12.06,1.98,37.84,19.03,62.73,7.01,10.23,14.79,17.71,21.4,22.99V222.42c-.01-3.72.48-11.67,5.35-19.87,7-11.77,18.13-15.82,21.4-16.95,10.42-3.61,19.49-2.06,23.48-1.11v684.96c.59,4.03,1.78,9.72,4.45,16.12,1.93,4.63,8.84,20.57,26.47,31.26,13.48,8.18,26.56,9.23,32.86,9.31-1.3-256.11-2.59-512.22-3.89-768.33.76-16.43,14.57-28.94,29.73-28.34,13.53.53,25.39,11.39,27.23,25.84-1.1,264.68-2.2,529.35-3.3,794.03,4.33.92,22.38,4.25,38.94-6.53,10.26-6.68,15.24-15.72,17.09-19.17,5.55-10.36,6.42-19.98,6.53-25.01-.72-246.99-1.43-493.97-2.15-740.96,2.27-.06,34.75-.44,48.29,22.68,3.41,5.83,4.87,11.86,5.34,17.19v674.68c5.92-2.16,39.19-14.94,50.16-47.79,3.12-9.34,3.68-18.03,3.33-25.01.03-193.22.06-386.43.09-579.65,4.12,1.18,28.28,8.48,36.17,30.08,1.64,4.49,2.32,8.88,2.43,12.92.02,146.42.05,292.84.07,439.25,3.82-1.71,19.51-9.22,25.56-26.47,2.15-6.12,2.48-11.73,2.29-15.89.01-114.91.03-229.81.04-344.72,2.36-.1,7.51.02,12.74,3.13,9.1,5.4,10.87,15.35,11.12,16.88.35,11.49.69,22.97,1.04,34.46.46,37.05.93,74.1,1.39,111.15v152.69c3.39-.72,9.77-2.67,14.31-8.34,3.62-4.52,4.51-9.46,5.56-15.28.91-5.04.95-9.31.83-12.23.02-38.81.03-77.62.05-116.43";function rc({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:n=2600,delayMs:r=0,loop:i=!1}){return R.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:R.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:nc,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function ic({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return R.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:R.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[R.jsx(rc,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),R.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[R.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:R.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),R.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function ti(e){const t=e.id?.trim()||void 0,n=e.faceId?.trim()||e.avatarId?.trim()||void 0;return{id:n?void 0:t,faceId:n,authToken:e.authToken?.trim()||void 0,apiBase:e.apiBase?.trim()||void 0,voiceId:e.voiceId?.trim()||void 0,speakingRate:e.speakingRate,language:e.language}}function sc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const ni={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},ac={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},oc=h.forwardRef(function({options:t},n){const r=h.useRef(null),i=h.useRef(t);i.current={...i.current,onReady:t.onReady,onStatusChange:t.onStatusChange,onError:t.onError,onUserTranscript:t.onUserTranscript,onBotOutput:t.onBotOutput};const[s,o]=h.useState(!!t.showControls),[a,u]=h.useState(()=>ti(t)),[d,l]=h.useState(!1),[c,m]=h.useState(!1),[w,S]=h.useState(!1),[f,E]=h.useState(!1),[D,B]=h.useState("idle"),[v,k]=h.useState(null),[O,A]=h.useState(!1),[se,le]=h.useState(!1),[I,U]=h.useState(""),[q,oe]=h.useState(!1),[ae,ie]=h.useState([]),[L,Z]=h.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),[H,me]=h.useState(t.brainUrl?.trim()||void 0),z=h.useCallback(T=>{i.current={...i.current,...T},T.showControls!==void 0&&o(!!T.showControls),(T.brainId!==void 0||T.personaId!==void 0)&&Z((T.brainId??T.personaId)?.trim()||void 0),T.brainUrl!==void 0&&me(T.brainUrl.trim()||void 0),u(Q=>ti({id:T.id??Q.id,faceId:T.faceId??T.avatarId??Q.faceId,authToken:T.authToken??Q.authToken,apiBase:T.apiBase??Q.apiBase,voiceId:T.voiceId??Q.voiceId,speakingRate:T.speakingRate??Q.speakingRate,language:T.language??Q.language}))},[]);h.useImperativeHandle(n,()=>({getTwin:()=>r.current,applyOptions:z}),[z]),h.useEffect(()=>{z(t)},[z,t.id,t.faceId,t.avatarId,t.authToken,t.apiBase,t.voiceId,t.speakingRate,t.showControls,t.brainId,t.personaId,t.brainUrl]);const te=h.useCallback(()=>{l(!0),k(null)},[]),j=h.useCallback(T=>{T==="idle"&&m(!0)},[]),J=h.useCallback(T=>{B(T),i.current.onStatusChange?.(T)},[]),Se=h.useCallback(T=>{k(T),l(!1),m(!1),E(!1),i.current.onError?.(T)},[]),ue=h.useCallback((T,Q)=>{i.current.onUserTranscript?.(T,Q)},[]),_=h.useCallback(T=>{i.current.onBotOutput?.(T)},[]);h.useEffect(()=>{if(!s)return;const T=window.setInterval(()=>{S(!!r.current?.isConnected())},400);return()=>window.clearInterval(T)},[s,a]);const C=sc(a),$=!!(a.id||a.faceId),re=d&&c,K=$&&!re&&!v,Y=tc(K),p=h.useRef(C);h.useEffect(()=>{re&&i.current.onReady?.()},[re]),h.useEffect(()=>{re&&r.current?.setMuted(O)},[re,O,a]),h.useEffect(()=>{ie([])},[a.id,a.faceId]),h.useEffect(()=>{p.current!==C&&(p.current=C,l(!1),m(!1),k(null),E(!1),S(!1),B("idle"))},[C]);const b=()=>{const T=r.current;if(!T?.isReady())return;if(k(null),le(!1),T.isConnected()){E(!1),T.disconnect().finally(()=>{S(!1)});return}E(!0);const Q={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,apiBase:a.apiBase,...L?{brainId:L}:{},...H?{brainUrl:H}:{}};T.connect(Q).then(()=>{S(!!T.isConnected())}).catch(V=>{const he=V instanceof Error?V.message:"Failed to connect voice.";k(he),i.current.onError?.(he)}).finally(()=>{E(!1)})},x=()=>{le(T=>!T),k(null)},W=()=>{const T=I.trim(),Q=r.current;!T||!Q?.isReady()||q||(k(null),U(""),oe(!0),i.current.onUserTranscript?.(T,!0),(async()=>{try{const V=a.authToken?.trim()||await Nt(),he=L||Q.getBrainId()?.trim()||void 0,De=await is({message:T,authToken:V,apiBase:a.apiBase||gt,brainId:he,history:ae});ie(ot=>[...ot,{role:"user",content:T},{role:"assistant",content:De.displayText}]),i.current.onBotOutput?.(De.displayText),await Q.speakText(De.spokenText,{voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language})}catch(V){const he=V instanceof Error?V.message:"Failed to get reply.";k(he),i.current.onError?.(he)}finally{oe(!1)}})())},ee=()=>{const T=!O;A(T),r.current?.setMuted(T)};return R.jsxs("div",{className:"aitwin-widget__layout",children:[R.jsxs("div",{className:"aitwin-widget__stage",children:[$?R.jsx("div",{style:ni,children:R.jsx(rs,{ref:r,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,style:ni,canvasStyle:ac,onReady:te,onDisplayStatus:j,onStatusChange:J,onError:Se,onUserTranscript:ue,onBotOutput:_,loadingThumbnailUrl:t.loadingThumbnailUrl},C)}):R.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),K?R.jsx(ic,{progress:Y}):null,s?R.jsx(Qo,{muted:O,onToggle:ee}):null,s&&f?R.jsx(Xo,{}):null]}),s?R.jsx(Jo,{ready:re,connected:w,connecting:f,status:D,textMode:se,textDraft:I,textSending:q,error:v,onTalk:b,onTextMode:x,onTextDraftChange:U,onSendText:W}):null]})}),cc=".aitwin-widget{--aitwin-border: rgba(255, 255, 255, .12);--aitwin-text: #f4f4f5;--aitwin-muted: #a1a1aa;--aitwin-accent: #f97316;--aitwin-accent-hover: #fb923c;--aitwin-font: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;--aitwin-size: 1;--aitwin-stage-width: calc(200px * var(--aitwin-size));--aitwin-stage-height: calc(267px * var(--aitwin-size));--aitwin-action-height: calc(40px * var(--aitwin-size));--aitwin-action-font: calc(13px * var(--aitwin-size));--aitwin-action-radius: calc(10px * var(--aitwin-size));--aitwin-action-gap: calc(6px * var(--aitwin-size));--aitwin-mute-size: calc(28px * var(--aitwin-size));--aitwin-layout-gap: calc(8px * var(--aitwin-size));box-sizing:border-box;color:var(--aitwin-text);font-family:var(--aitwin-font);font-size:calc(12px * var(--aitwin-size));line-height:1.45;width:fit-content;max-width:100%}.aitwin-widget *,.aitwin-widget *:before,.aitwin-widget *:after{box-sizing:border-box}.aitwin-widget__layout{display:flex;flex-direction:column;gap:var(--aitwin-layout-gap);width:fit-content;max-width:100%}.aitwin-widget__stage{align-items:center;background:#0a0a0b;border:1px solid var(--aitwin-border);border-radius:calc(10px * var(--aitwin-size));display:flex;flex-shrink:0;height:var(--aitwin-stage-height);justify-content:center;line-height:0;overflow:hidden;position:relative;width:var(--aitwin-stage-width)}.aitwin-widget__stage .aitwin-root,.aitwin-widget__stage canvas{display:block;height:100%;object-fit:cover;object-position:top;width:100%}.aitwin-widget__hint{color:var(--aitwin-muted);font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget__mute{align-items:center;background:#28282cb8;border:none;border-radius:999px;color:#fff;cursor:pointer;display:inline-flex;height:var(--aitwin-mute-size);justify-content:center;padding:0;position:absolute;right:calc(8px * var(--aitwin-size));top:calc(8px * var(--aitwin-size));width:var(--aitwin-mute-size);z-index:2}.aitwin-widget__mute:hover{background:#37373cd9}.aitwin-widget__mute svg{height:calc(15px * var(--aitwin-size));width:calc(15px * var(--aitwin-size))}.aitwin-widget__controls{display:flex;flex-direction:column;gap:var(--aitwin-action-gap);width:var(--aitwin-stage-width)}.aitwin-widget__actions{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr 1fr;width:100%}.aitwin-widget__action{align-items:center;background:transparent;border:1.5px solid var(--aitwin-accent);border-radius:999px;color:var(--aitwin-accent);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--aitwin-action-font);font-weight:600;gap:calc(6px * var(--aitwin-size));height:var(--aitwin-action-height);justify-content:center;padding:0 calc(10px * var(--aitwin-size))}.aitwin-widget__action svg{flex-shrink:0;height:calc(12px * var(--aitwin-size));width:calc(12px * var(--aitwin-size))}.aitwin-widget__action:hover:not(:disabled){background:#f973161a}.aitwin-widget__action:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__action--primary{background:var(--aitwin-accent);border-color:transparent;color:#fff}.aitwin-widget__action--primary:hover:not(:disabled){background:var(--aitwin-accent-hover)}.aitwin-widget__action--connecting:disabled{cursor:progress;opacity:1}.aitwin-widget__spinner{display:inline-flex;flex-shrink:0;height:calc(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--accent{color:var(--aitwin-accent);height:calc(16px * var(--aitwin-size));width:calc(16px * var(--aitwin-size))}.aitwin-widget__spinner--on-accent{color:#fff}@keyframes aitwin-widget-spin{to{transform:rotate(360deg)}}.aitwin-widget__connecting{align-items:center;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);background:#ffffffe0;border-radius:999px;bottom:calc(14px * var(--aitwin-size));box-shadow:0 4px 16px #0000001f;color:#3f3f46;display:inline-flex;font-size:calc(12px * var(--aitwin-size));font-weight:600;gap:calc(8px * var(--aitwin-size));left:50%;line-height:1;padding:calc(8px * var(--aitwin-size)) calc(14px * var(--aitwin-size));pointer-events:none;position:absolute;transform:translate(-50%);z-index:3}.aitwin-widget__face-loading{background:transparent;inset:0;overflow:hidden;pointer-events:none;position:absolute;z-index:4}.aitwin-widget__face-loading-content{align-items:center;display:flex;flex-direction:column;gap:calc(12px * var(--aitwin-size));inset:0;justify-content:center;padding:calc(24px * var(--aitwin-size));position:absolute;z-index:1}.aitwin-widget__logo{color:#fff;display:block;flex-shrink:0;height:calc(64px * var(--aitwin-size));margin-bottom:calc(4px * var(--aitwin-size));width:calc(64px * var(--aitwin-size))}.aitwin-widget__logo-draw{stroke-dasharray:1;stroke-dashoffset:1;animation:aitwin-widget-logo-draw 2.6s ease-in-out forwards}.aitwin-widget__logo-draw--loop{animation:aitwin-widget-logo-draw-loop 2.6s ease-in-out infinite}@keyframes aitwin-widget-logo-draw{to{stroke-dashoffset:0}}@keyframes aitwin-widget-logo-draw-loop{0%{stroke-dashoffset:1}45%{stroke-dashoffset:0}55%{stroke-dashoffset:0}to{stroke-dashoffset:-1}}@media(prefers-reduced-motion:reduce){.aitwin-widget__logo-draw,.aitwin-widget__logo-draw--loop{animation:none;stroke-dashoffset:0}}.aitwin-widget__face-loading-bar-wrap{max-width:calc(220px * var(--aitwin-size));width:100%}.aitwin-widget__face-loading-track{background:#fff3;border-radius:999px;height:calc(4px * var(--aitwin-size));overflow:hidden;width:100%}.aitwin-widget__face-loading-fill{background:var(--aitwin-accent);border-radius:999px;height:100%;transition:width .3s ease-out}.aitwin-widget__face-loading-pct{color:#ffffffbf;font-size:calc(12px * var(--aitwin-size));margin:calc(8px * var(--aitwin-size)) 0 0;text-align:center}.aitwin-widget__composer{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr auto;width:100%}.aitwin-widget__composer-input{background:#ffffff0a;border:1px solid var(--aitwin-border);border-radius:var(--aitwin-action-radius);color:var(--aitwin-text);font-family:inherit;font-size:calc(12px * var(--aitwin-size));min-width:0;outline:none;padding:calc(8px * var(--aitwin-size)) calc(10px * var(--aitwin-size))}.aitwin-widget__composer-input:focus{border-color:#f973168c}.aitwin-widget__composer-send{background:var(--aitwin-accent);border:none;border-radius:var(--aitwin-action-radius);color:#fff;cursor:pointer;font-family:inherit;font-size:calc(12px * var(--aitwin-size));font-weight:600;padding:0 calc(12px * var(--aitwin-size))}.aitwin-widget__composer-send:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__controls-error{color:#fecaca;font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget--float{bottom:20px;filter:drop-shadow(0 12px 32px rgba(0,0,0,.45));height:fit-content;margin:0;max-width:calc(100vw - 40px);position:fixed;right:20px;width:fit-content;z-index:2147483000}",ri="data-aitwin-widget-style";function as(){if(typeof document>"u")return;const e=cc.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${ri}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const n=document.createElement("style");n.setAttribute(ri,"1"),n.textContent=e,(document.head??document.documentElement).appendChild(n)}typeof document<"u"&&as();const lc=h.forwardRef(function(t,n){as();const r=h.useRef(null);h.useImperativeHandle(n,()=>({speakText:async(s,o)=>{const a=r.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakText(s,o)},connect:async s=>{const o=r.current?.getTwin();if(!o)throw new Error("AiTwinWidget: twin is not mounted");return o.connect(s)},disconnect:async()=>{const s=r.current?.getTwin();if(s)return s.disconnect()},stop:()=>{r.current?.getTwin()?.stop()},isReady:()=>!!r.current?.getTwin()?.isReady(),isConnected:()=>!!r.current?.getTwin()?.isConnected(),getTwin:()=>r.current?.getTwin()??null}),[]);const i=!!t.float;return R.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:R.jsx(oc,{ref:r,options:t})})}),uc=new Set([".png",".jpg",".jpeg",".webp"]);function os(e=".png"){const t=e.toLowerCase();return uc.has(t)?`source${t}`:"source.png"}function dc(e,t=$n,n=".png"){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${os(n)}`}exports.AI_TWIN_THUMBNAIL_FILENAME=Qn;exports.AiTwin=rs;exports.AiTwinNotFoundError=nn;exports.AiTwinWidget=lc;exports.CONSONANT_SKIP_GROUP=ki;exports.DEFAULT_TTS_ENGINE_ID=ft;exports.DEFAULT_TTS_LANGUAGE=Ws;exports.EMOTION_TO_EYEBROW=qi;exports.EXPRESSION_ATLAS_EMOTIONS=Ba;exports.MIC_SAMPLE_RATE=rr;exports.OCULUS_VISEME_IDS=_i;exports.PLAYBACK_SAMPLE_RATE=ir;exports.SPEAKING_RATE_MAX=yn;exports.SPEAKING_RATE_MIN=pn;exports.TTS_ENGINE_CARTESIA=tt;exports.TTS_ENGINE_GOOGLE=Kn;exports.TTS_ENGINE_INWORLD=un;exports.TTS_ENGINE_VISEMETTS=nt;exports.TTS_LANGUAGE_CATALOG=mt;exports.TTS_LANGUAGE_CODES=pi;exports.VISEME_IDS=Sa;exports.VISEME_SKIP_GAP_MS=On;exports.VISEME_TEST_CARTESIA_VOICE_ID=nr;exports.VISEME_TEST_SPEAKING_RATE=Ht;exports.VISEME_TEST_VISEMETTS_VOICE_ID=dn;exports.VISEME_TEST_VOICE_ID=tr;exports.VISEME_VTIME_GRID_MS=Xn;exports.VOWEL_SKIP_GROUP=Ti;exports.aiTwinSourceFilename=os;exports.buildPlaybackTransitions=Ri;exports.buildPlaybackVisemeSeries=gn;exports.buildRawVisemeTransitions=Pi;exports.buildVoiceWebSocketUrl=Ui;exports.compactSkippableVisemes=Zn;exports.createAvatarTtsLipsyncController=Nn;exports.createRealtimeVoiceLipsyncController=Vi;exports.emotionToEyebrow=ht;exports.faceAssetUrls=Ln;exports.fetchAiTwin=li;exports.fetchAvatarReply=is;exports.fetchDevAuthToken=Nt;exports.getAiTwinSourceUrl=dc;exports.getAiTwinThumbnailUrl=ui;exports.isTtsLanguageCode=yi;exports.isTtsLanguageSupported=Hs;exports.listSkippedVisemeEntries=wn;exports.listSkippedVisemes=ea;exports.normalizeOculusViseme=mn;exports.normalizeStreamEmotion=Ze;exports.normalizeTtsLanguage=fn;exports.parsePackedVoiceId=ai;exports.parseTwinBrainUrl=Es;exports.resolveDirectFaceId=di;exports.resolveTwinBrainId=qn;exports.resolveTwinBrainUrl=Yn;exports.resolveVisemeAtTime=zt;exports.resolveVisemeFromPlaybackSeries=Ii;exports.resolveWordAtTime=la;exports.setActiveTwinAssets=fi;exports.snapVisemeQueueToGrid=Jn;exports.snapVisemeVtimeToGrid=Ei;exports.splitVoiceIdSpec=et;exports.ttsLanguagesForEngine=zs;