@streamoji/aitwin 0.6.1 → 0.6.3

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 M=require("react/jsx-runtime"),h=require("react"),es=require("@pipecat-ai/client-js"),Ln=require("@pipecat-ai/websocket-transport"),we=require("pixi.js");var Sn=typeof document<"u"?document.currentScript:null;const ts="https://aitwin.bubu.social",Yr={publicBase:ts},ns="0.6.1",rs={version:ns},is={},ct="https://ai.aitwin.me",On=`${Yr.publicBase}/custom-faces`,ss=`${Yr.publicBase}/aitwin-workers/v${rs.version}/visemeDiffPreview.worker.js`;function as(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:Sn&&Sn.tagName.toUpperCase()==="SCRIPT"&&Sn.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?is?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():ss}const os="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",bn=3e3,Rt=16,pr=3e3,cs=4e3,ls=.85,us=8,Nn=400,Vn="eng_a7f2b9c1",an="eng_d4e8f3a2",lt="eng_c9b1e6d4",ut="visemetts",at=lt,on="eve",Qr=new Set([an,lt,ut]),Xr={[Vn]:"oculus_direct",[lt]:"oculus_direct",[ut]:"oculus_direct",[an]:"inworld_word"},gr={google:Vn,inworld:an,cartesia:lt,visemetts:ut};function Jr(e){return Xr[e]}function fs(e){return e===lt}function Zr(e){return e===ut}function ds(e){if(e.ttsEngineId&&e.ttsEngineId in Xr)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in gr?gr[t]:at}class Jt extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}async function ei(e,t=os){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new Jt;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const i=await r.json();if(!i.success)throw new Jt(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,u=String(a.authToken??o??"").trim()||void 0;return{...a,ttsEngineId:ds(i.data),authToken:u}}const Un="thumbnail.webp";function ti(e,t=On){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${Un}`}function yr(e){const t=e?.trim();if(!t)return null;try{return ti(t)}catch{return null}}function ms(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${Un}`:null}const hs="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",ws="client_6TNvp3SCs4Og0a1ijm9TommXLql1",ps="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",gs="6TNvp3SCs4Og0a1ijm9TommXLql1",ys="Swaraj Mali";async function Ct(){const e=await fetch(hs,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":ws,"Client-Secret":ps},body:JSON.stringify({userId:gs,userName:ys})});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 _s(e,t=ct){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 vs(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 qt(e){return Uint8Array.from(e)}function Ss(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function bs(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=qt(n.subarray(0,12)),i=qt(n.subarray(12,28)),s=qt(n.subarray(28)),o=qt(Ss(s,i)),a=await crypto.subtle.importKey("raw",vs(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},a,o)}let In=null;const An=new Set;function Gt(e){return e.includes("/custom-faces/")}function Zt(e){const t=e.binBase.trim().replace(/\/$/,""),n=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||Gt(t)||Gt(n)))return{twinBase:n,binBase:t,encrypted:!1};const i=Gt(t)?t:Gt(n)?n:t;return{twinBase:i,binBase:i,encrypted:!0}}function ft(e){return Zt(e).encrypted}function Mn(e,t=On){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function ni(e,t){return(e??t)?.trim()||void 0}function ri(e){In=Zt(e);for(const t of An)t()}function Ts(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return Zt(e);const r=i=>{try{return new URL(i,n).href.replace(/\/$/,"")}catch{return i}};return Zt({twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted})}function dt(){if(!In)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return In}function ii(e){return An.add(e),()=>An.delete(e)}function en(){const e=dt();return ft(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function ks(){const e=dt();return ft(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function si(){const e=dt();return ft(e)?e.binBase:e.twinBase}function Ft(){return ft(dt())}function ai(){const e=dt();return ft(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function oi(){const e=dt();return ft(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}function ci(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 li=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],xs=new Map(li.map(e=>[e.toLowerCase(),e]));function cn(e){const t=(e??"").trim();return t?xs.get(t.toLowerCase())??"sil":"sil"}const Es={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 Is(e){if(!e)return["sil"];const t=e.toLowerCase();return Es[t]??["sil"]}function ui(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 bt(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function ln(e,t){const n=e.toLowerCase().replace(/[^a-z']/g,"");return!n||bt(n,t)!=="w"||t>0&&bt(n,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(n)}function As(e,t){const n=e.toLowerCase(),r=bt(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 Ms(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(ln(n,t))return"FF";const i=bt(n,t);return i==="u"||i==="w"?"U":"O"}function Ps(e,t){const n=e.toLowerCase();if(ln(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)||bt(n,t)==="o"?"O":"U"}const Yt={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function Rs(e,t){const n=e.toLowerCase(),r=bt(n,t);if(Yt[r])return Yt[r];for(let i=0;i<n.length;i++){const s=n[i];if(Yt[s])return Yt[s]}return"DD"}function fi(e,t,n){const r=Is(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 As(i,o);case"o":return Ms(i,o);case"qw":return Ps(i,o);case"cdgknstxyz":return Rs(i,o);default:return r[0]}}const Wn=16,Pn=47,di=new Set(["aa","E","I"]),mi=new Set(["DD","SS","kk","CH"]),Cs=[di,mi];function Ds(e){for(const t of Cs)if(t.has(e))return t;return null}function Bs(e){return Ds(e)!=null}function hi(e,t=Wn){return t<=0?e:Math.round(e/t)*t}function zn(e,t=Wn){return e.map(n=>({...n,vtime:hi(n.vtime,t)}))}function wi(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 $n(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(!Bs(r.viseme)){t.push(r);continue}const o=r.vtime-s.vtime,a=i.vtime-r.vtime;o<Pn||a<Pn||t.push(r)}return t.push(e[e.length-1]),t}function un(e){return $n(wi(zn(e)))}function pi(e,t){let n="sil";for(const r of e){if(r.vtime>t)break;r.viseme!=="sil"&&(n=r.viseme)}return n}function fn(e){const t=wi(zn(e)),n=$n(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 Fs(e){return fn(e).map(t=>t.viseme)}const Ls=32,_r=48;function gi(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}function yi(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 Os(e){return un(e).find(n=>n.viseme!=="sil")??null}function it(e){const t=gi(e);return yi(e)?t+Nn:t}function Ns(e){const t=[],n=Os(e);n&&n.vtime>0&&t.push({from:"sil",to:n.viseme,fromVtime:0,toVtime:n.vtime});const r=yi(e),i=gi(e);return r&&t.push({from:r.viseme,to:"sil",fromVtime:i,toVtime:i+Nn}),t}function _i(e){const t=un(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 vi(e){return e.length===0?[]:[...Ns(e),..._i(e)]}function Vs(e,t){let n=null;for(const r of e){const{transStart:i,transEnd:s}=Si(r.fromVtime,r.toVtime,r.from,r.to);t>=i&&t<s&&(n=r)}return n}function Si(e,t,n,r){const i=Math.max(0,t-e);if((n==="PP"||r==="PP")&&i>_r){const f=_r,l=t,c=l-f;return{gapMs:i,effectiveGapMs:f,holdEnd:c,transStart:c,transEnd:l}}const o=i>0?Math.max(i,Ls):0,a=e,u=e+o;return{gapMs:i,effectiveGapMs:o,holdEnd:e,transStart:a,transEnd:u}}function bi(e,t,n,r,i,s){r.forEach(o=>{const u=String(o.word??"").trim();if(!u)return;const f=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+f,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),f=Math.max(1,Math.round((o.duration??0)*1e3)),l=i+u,c=xi(t,l),d=c?ui(c,l):0;let p;Jr(s)==="oculus_direct"?(p=cn(a),p==="U"&&c&&ln(c.word,d)&&(p="FF")):p=fi(a,c?.word??"",d),e.push({viseme:p,weight:1,vtime:l,vduration:f})})}function Ti(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 Hn=16e3;function ki(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:Hn}function Us(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 Ws(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function vr(e,t,n=Hn){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 zs(e){const t=Us(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 Sr(e,t,n=Hn){const r=zs(t),i=ki(n);if(Ws(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 vr(e,r,i);try{const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return await e.decodeAudioData(s)}catch{return vr(e,r,i)}}function xi(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Ei(e,t){const n=[],r=[];let i=null,s=!1,o=!1,a=!1,u=!1,f=0,l=0,c=0,d=null,p=1,T=t,m=!1,E=null,C=0,P=!1,_=!1,x=0,N=null,A=null,ie=null;const me=()=>({visemes:[],words:[],segmentOffsetMs:0}),I=()=>{_=!1,x=0},V=()=>{d!=null&&(clearTimeout(d),d=null)},q=()=>{for(const S of r){try{S.onended=null,S.stop(0)}catch{}try{S.disconnect()}catch{}}r.length=0},se=()=>{for(const S of r)S.playbackRate.value=p},J=()=>{if(!(m||!u||s||_||r.length>0||n.length>0)){if(a&&i&&l>0){const S=(i.currentTime-l)*1e3;if(S<C){V();const R=p>0?(C-S)/p:C-S;d=setTimeout(()=>{m||(o=!1,d=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,R));return}}o=!1,V(),e.onSpeakingDone(),e.onNotify()}},Z=S=>{const R=it(S);if(R<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,f=performance.now(),e.onSpeakingStart(),e.onNotify(),V();const re=p>0?R/p:R;d=setTimeout(()=>{m||(o=!1,d=null,e.onSpeakingDone(),e.onNotify())},re)},O=(S,R,re,ne)=>{R.length!==0&&(c=re,R.forEach(H=>{const v=String(H.word??"").trim();if(!v)return;const y=Math.round((H.start??0)*1e3),k=H.duration!=null?Math.round(H.duration*1e3):H.end!=null?Math.max(1,Math.round((H.end-(H.start??0))*1e3)):0;S.push({word:v,wtime:c+y,wduration:k,queueIndex:S.length,gesture:H.gesture??null,emphasis:H.emphasis===!0})}))},le=(S,R,re,ne,H,W)=>{re.length!==0&&(c=ne,re.forEach(v=>{const y=String(v.symbol??v.viseme??"").trim();if(!y)return;const k=Math.round((v.start??0)*1e3),b=Math.max(1,Math.round((v.duration??0)*1e3)),$=c+k,G=xi(R,$),X=G?ui(G,$):0;let oe;Jr(W)==="oculus_direct"?(oe=cn(y),oe==="U"&&G&&ln(G.word,X)&&(oe="FF")):oe=fi(y,G?.word??"",X),S.push({viseme:oe,weight:1,vtime:$,vduration:b})}),e.onNotify())},z=(S,R,re,ne,H,W,v)=>{O(R,ne,H),le(S,R,re,H,W,v)},pe=(S,R,re)=>{ie===S&&S.visemes===R||(R.length=0,re.length=0,S.visemes=R,S.words=re,S.segmentOffsetMs=0,ie=S,c=0,C=0)},L=async()=>{const S=window.AudioContext||window.webkitAudioContext;return i||(i=new S),i.state==="suspended"&&await i.resume(),E||(E=i.createMediaStreamDestination()),i},Q=(S,R)=>{if(!i)return 0;const re=i,ne=re.currentTime,H=ne+.02;if(R.isFirstAudio){l<=0&&(l=H);const v=(H-ne)*1e3;f=performance.now()+v}R.onBeforeStart?.(H);const W=re.createBufferSource();return W.buffer=S,W.playbackRate.value=p,W.connect(re.destination),E&&W.connect(E),r.push(W),m?(r.pop(),H):(R.isFirstAudio&&(o=!0,e.onSpeakingStart()),W.onended=()=>{const v=r.indexOf(W);v>=0&&r.splice(v,1),e.onNotify(),!m&&(N&&A?K(N,A):J())},W.start(H),H)},K=async(S,R)=>{if(m||s||r.length>0)return;if(n.length===0){J();return}s=!0;let re=!1;try{const ne=await L();if(m)return;const H=n[0];if(!H)return;const W=!o;if(P&&(e.shouldHoldForWarmup?.()??!1)&&(_||W&&H.newStream)||_){pe(H.utterance,S,R);for(const k of n){if(m)return;k.audioBuffer||(k.audioBuffer=await Sr(ne,k.audio,k.sampleRate)),a=!0,_||(_=!0,x=0,k.newStream&&k.onNewStream?.()),k.visemesQueued||(z(S,R,k.visemes,k.words,x,!0,T),k.visemesQueued=!0,x+=Math.round(k.audioBuffer.duration*1e3),C=Math.max(C,it(S)))}e.onNotify();return}const y=n.shift();if(!y||(y.audioBuffer||(y.audioBuffer=await Sr(ne,y.audio,y.sampleRate)),m))return;a=!0,V(),pe(y.utterance,S,R),y.visemesQueued=!1,y.newStream&&y.onNewStream?.(),Q(y.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:k=>{l=k,c=0,f=performance.now()+(k-ne.currentTime)*1e3,S.length=0,R.length=0,z(S,R,y.visemes,y.words,0,!0,T),y.visemesQueued=!0,y.utterance.segmentOffsetMs=0}}),re=r.length>0,C=it(S),e.onNotify()}catch(ne){console.error("[avatarChunkPlayback] audio chunk failed:",ne)}finally{if(s=!1,m)return;if(_){n.some(H=>!H.audioBuffer||!H.visemesQueued)&&K(S,R);return}!re&&r.length===0&&n.length>0?K(S,R):r.length===0&&n.length===0&&J()}};return{setStreamTtsEngineId:S=>{T=S},setPlaybackSpeed:S=>{p=Math.max(.1,Math.min(1,S)),se()},getPlaybackSpeed:()=>p,setLipsyncWarmupHoldEnabled:S=>{P=S,S||I()},isWarmingUp:()=>_,releaseWarmupHold:()=>{if(_){_=!1,x=0;for(const S of n)S.newStream=!1;N&&A&&K(N,A),e.onNotify()}},resetForNewStream:S=>{m=!1,u=!1,T=S,C=0},resumeBotStream:()=>{m=!1,u=!1},clearAborted:()=>{m=!1},primeAudioContext:async()=>{const S=window.AudioContext||window.webkitAudioContext;i||(i=new S),i.state==="suspended"&&await i.resume(),i&&!E&&(E=i.createMediaStreamDestination())},stop:()=>{m=!0,V(),q(),n.length=0,s=!1,o=!1,a=!1,u=!1,c=0,l=0,f=0,C=0,N=null,A=null,ie=null,I()},markStreamComplete:S=>{if(C=Math.max(C,it(S)),u=!0,!a&&S.length>0){Z(S);return}J()},playAudioChunk:async(S,R,re,ne,H,W,v)=>{if(m)return;N=S,A=R;const y=ki(v?.sampleRate),k=v?.newStream===!0,b=me();if(!re?.trim()){if(ne.length===0&&H.length===0)return;pe(b,S,R),k&&v?.onNewStream?.(),z(S,R,ne,H,0,!0,T),C=it(S),!o&&C>0&&Z(S),e.onNotify();return}n.push({audio:re,audioBuffer:null,utterance:b,visemes:ne,words:H,isNewSegment:W,sampleRate:y,newStream:k,onNewStream:v?.onNewStream,visemesQueued:!1}),await K(S,R)},queueTimingsOnly:(S,R,re,ne,H,W)=>{if(m)return;const v=me();pe(v,S,R),z(S,R,re,ne,0,!0,T),v.segmentOffsetMs=0,C=it(S)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*p):o?Math.max(0,(performance.now()-f)*p):0,isSpeaking:()=>o?!0:!a||!i||l<=0?!1:(i.currentTime-l)*1e3<C,getVoiceStream:()=>E?E.stream:null,getPlaybackStartPerf:()=>f,bargeIn:()=>{m=!0,u=!1,V(),q(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,f=0,C=0,N=null,A=null,ie=null,I()},interrupt:()=>{m=!0,u=!1,V(),q(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,f=0,C=0,N=null,A=null,ie=null,I()}}}function Lt(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 Ii(e,t,n=120){const r=Lt(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 $s(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 Hs(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function br(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 dn=.5,mn=1.5,jn="Olivia",Kn="f786b574-daa5-4673-aa0c-cbe3e8534c02",Ot=.85;function Rn(e,t=ct,n={}){const r=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let u=0;const f=[],l=[];let c="",d="neutral",p="",T=at;const m=new Set;let E=0,C=null,P=0,_=null;const x=()=>m.forEach(O=>O());let N=()=>!1;const A=Ei({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:x,shouldHoldForWarmup:()=>N()},at),ie=()=>A.getPlaybackElapsedMs(),me=(O,le=c)=>{if(!n.onLipsyncDebug)return;const z=ie(),pe=i,L=fn(o).map(Q=>({viseme:Q.viseme,vtimeMs:Q.vtime}));n.onLipsyncDebug({event:O,spokenText:le,mood:d,playbackAnchorPerf:A.getPlaybackStartPerf(),playbackElapsedMs:z,queueLength:pe.length,activeViseme:Lt(pe,z),segments:l.map(Q=>({...Q,visemes:[...Q.visemes]})),fullQueueLength:o.length,compactionSkipped:L})},I=(O,le)=>{n.onLipsyncDebug&&(C={event:O,spokenText:le},E===0&&(E=requestAnimationFrame(()=>{E=0;const z=C;C=null,z&&me(z.event,z.spokenText)})))},V=(O,le,z,pe,L)=>{if(!n.onLipsyncDebug)return;const Q=i.slice(le),K=z.filter(ae=>String(ae.symbol??ae.viseme??"").trim());l.push({spokenText:O,audioOffsetMs:Q[0]?.vtime??0,isNewSegment:pe,chunkDurationMs:L,receivedAtMs:performance.now(),visemes:Q.map((ae,be)=>{const te=K[be];return{rawSymbol:String(te?.symbol??te?.viseme??ae.viseme).trim(),viseme:ae.viseme,startSec:Number(te?.start??0),durationSec:Number(te?.duration??0),vtimeMs:ae.vtime,vdurationMs:ae.vduration}})})},q=()=>{o.length=0,a.length=0,u=0},se=(O,le,z,pe,L)=>{if(O.length===0&&le.length===0)return;bi(o,a,O,le,u,L);const Q=Ti(O,u),K=z?br(z,pe):null;u=Math.max(Q,K!=null?u+K:u)},J=()=>{P+=1,_?.abort(),_=null,A.stop(),i.length=0,s.length=0,q(),f.length=0,d="neutral",l.length=0,c="",e("idle"),I("reset"),x()};return{setDeveloperToken:O=>{p=O},setTtsEngineId:O=>{T=O},getTtsEngineId:()=>T,speak:async(O,le)=>{J();const z=P;_=new AbortController,e("loading"),c=O,l.length=0,q();const pe=p.trim();if(!pe)throw new Error("Developer token required for avatar_ttsWithPoses");const L=le?.ttsEngineId??T??at;A.resetForNewStream(L),A.setStreamTtsEngineId(L);const Q=le?.voiceId??(L===ut?on:jn),K=le?.speakingRate??Ot,ae=Math.max(dn,Math.min(mn,K)),be={user_query:O,ttsEngineId:L,speakingRate:ae,tenant:"aiTwin"};Qr.has(L)&&(be.voice_id=Q);try{const te=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${pe}`},body:JSON.stringify(be),signal:_.signal});if(!te.ok)throw new Error(`avatar_ttsWithPoses failed (${te.status})`);const S=te.body;if(!S)throw new Error("No response body");const R=S.getReader(),re=new TextDecoder;let ne="",H=!0;const W=async v=>{if(z!==P)return;const y=ci(v);if(y){if(y.event==="audio"){const k=y.data.chunk,b=y.data.visemes??[],$=y.data.words??[],G=y.data.is_new_segment??!1,X=y.data.sample_rate,oe=Number(y.data.audio_offset_ms??0),Be=i.length;if(se(b,$,k,X,L),k){const tt=H;H=!1,await A.playAudioChunk(i,s,k,b,$,G,{sampleRate:X,newStream:tt,audioOffsetMs:oe}),V(O,Be,b,G,br(k,X)),I("audio_chunk",O)}else(b.length>0||$.length>0)&&(A.queueTimingsOnly(i,s,b,$,G,{audioOffsetMs:oe,newStream:H}),V(O,Be,b,G,null),I("audio_chunk",O))}else if(y.event==="metadata"){const k=y.data.mood;typeof k=="string"&&k.trim()&&(d=k.trim());const b=y.data.sentence_emotions;if(Array.isArray(b)){f.length=0;for(const $ of b){if(!$||typeof $!="object")continue;const G=$;f.push({sentence_index:Number(G.sentence_index??0),text:String(G.text??""),sentiment:typeof G.sentiment=="string"?G.sentiment:void 0,emotion:String(G.emotion??d),start_word:Number(G.start_word??0),end_word:Number(G.end_word??0)})}}x(),I("metadata",O)}else if(y.event==="error")throw new Error(String(y.data.message??"avatar_ttsWithPoses stream error"))}};for(;z===P;){const{done:v,value:y}=await R.read();y&&(ne+=re.decode(y,{stream:!0}));const k=ne.split(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("react/jsx-runtime"),h=require("react"),ls=require("@pipecat-ai/client-js"),Hn=require("@pipecat-ai/websocket-transport"),pe=require("pixi.js");var xn=typeof document<"u"?document.currentScript:null;const us="https://aitwin.bubu.social",ni={publicBase:us},ds="0.6.3",fs={version:ds},ms={},ht="https://ai.aitwin.me",$n=`${ni.publicBase}/custom-faces`,hs=`${ni.publicBase}/aitwin-workers/v${fs.version}/visemeDiffPreview.worker.js`;function gs(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"?ms?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():hs}const ps="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",In=3e3,Ot=16,kr=3e3,ws=4e3,ys=.85,vs=8,jn=400,Kn="eng_a7f2b9c1",un="eng_d4e8f3a2",tt="eng_c9b1e6d4",nt="visemetts",dt=tt,dn="eve",ri=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 _s(e){const t=e.trim();if(t)return t in Gn?t:Dn[t.toLowerCase()]}function ii(e){const t=e?.trim();if(!t)return{};const n=t.indexOf(":");if(n<=0)return{voiceId:t};const r=_s(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=ii(t);return{ttsEngineId:e??n.ttsEngineId,voiceId:n.voiceId}}function si(e){return Gn[e]}function bs(e){return e===tt}function ai(e){return e===nt}function Ss(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"}}async function oi(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;return{...a,ttsEngineId:Ss(i.data),authToken:u}}const qn="thumbnail.webp";function ci(e,t=$n){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${qn}`}function Er(e){const t=e?.trim();if(!t)return null;try{return ci(t)}catch{return null}}function Ts(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${qn}`:null}const ks="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",Es="client_6TNvp3SCs4Og0a1ijm9TommXLql1",xs="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",Is="6TNvp3SCs4Og0a1ijm9TommXLql1",As="Swaraj Mali";async function Nt(){const e=await fetch(ks,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":Es,"Client-Secret":xs},body:JSON.stringify({userId:Is,userName:As})});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 Ms(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 Ps(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 Cs(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Rs(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(Cs(s,i)),a=await crypto.subtle.importKey("raw",Ps(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 li(e,t){return(e??t)?.trim()||void 0}function ui(e){Bn=rn(e);for(const t of Fn)t()}function Ds(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 di(e){return Fn.add(e),()=>Fn.delete(e)}function sn(){const e=pt();return gt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function Bs(){const e=pt();return gt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function fi(){const e=pt();return gt(e)?e.binBase:e.twinBase}function Wt(){return gt(pt())}function mi(){const e=pt();return gt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function hi(){const e=pt();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}],gi=ft.map(e=>e.code),Fs=new Set(gi),Ls=new Set(ft.filter(e=>e.visemetts).map(e=>e.code)),Os=new Set(ft.filter(e=>e.cartesia).map(e=>e.code)),Ns="en";function pi(e){return Fs.has(e)}function fn(e){const t=e?.trim();if(t)return t}function Vs(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 Us(e,t){const n=t.trim();return n?e===nt?Ls.has(n):e===tt?Os.has(n):pi(n):!1}function wi(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 yi=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],Ws=new Map(yi.map(e=>[e.toLowerCase(),e]));function mn(e){const t=(e??"").trim();return t?Ws.get(t.toLowerCase())??"sil":"sil"}const zs={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 Hs(e){if(!e)return["sil"];const t=e.toLowerCase();return zs[t]??["sil"]}function vi(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 $s(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 js(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 Ks(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 Gs(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 _i(e,t,n){const r=Hs(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 $s(i,o);case"o":return js(i,o);case"qw":return Ks(i,o);case"cdgknstxyz":return Gs(i,o);default:return r[0]}}const Yn=16,On=47,bi=new Set(["aa","E","I"]),Si=new Set(["DD","SS","kk","CH"]),qs=[bi,Si];function Ys(e){for(const t of qs)if(t.has(e))return t;return null}function Qs(e){return Ys(e)!=null}function Ti(e,t=Yn){return t<=0?e:Math.round(e/t)*t}function Qn(e,t=Yn){return e.map(n=>({...n,vtime:Ti(n.vtime,t)}))}function ki(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 Xn(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(!Qs(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 Xn(ki(Qn(e)))}function Ei(e,t){let n="sil";for(const r of e){if(r.vtime>t)break;r.viseme!=="sil"&&(n=r.viseme)}return n}function pn(e){const t=ki(Qn(e)),n=Xn(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 Xs(e){return pn(e).map(t=>t.viseme)}const Js=32,xr=48;function xi(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}function Ii(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 Zs(e){return gn(e).find(n=>n.viseme!=="sil")??null}function lt(e){const t=xi(e);return Ii(e)?t+jn:t}function ea(e){const t=[],n=Zs(e);n&&n.vtime>0&&t.push({from:"sil",to:n.viseme,fromVtime:0,toVtime:n.vtime});const r=Ii(e),i=xi(e);return r&&t.push({from:r.viseme,to:"sil",fromVtime:i,toVtime:i+jn}),t}function Ai(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 Mi(e){return e.length===0?[]:[...ea(e),...Ai(e)]}function ta(e,t){let n=null;for(const r of e){const{transStart:i,transEnd:s}=Pi(r.fromVtime,r.toVtime,r.from,r.to);t>=i&&t<s&&(n=r)}return n}function Pi(e,t,n,r){const i=Math.max(0,t-e);if((n==="PP"||r==="PP")&&i>xr){const d=xr,l=t,c=l-d;return{gapMs:i,effectiveGapMs:d,holdEnd:c,transStart:c,transEnd:l}}const o=i>0?Math.max(i,Js):0,a=e,u=e+o;return{gapMs:i,effectiveGapMs:o,holdEnd:e,transStart:a,transEnd:u}}function Ci(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=Bi(t,l),m=c?vi(c,l):0;let p;si(s)==="oculus_direct"?(p=mn(a),p==="U"&&c&&hn(c.word,m)&&(p="FF")):p=_i(a,c?.word??"",m),e.push({viseme:p,weight:1,vtime:l,vduration:d})})}function Ri(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 Jn=16e3;function Di(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:Jn}function na(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 ra(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function Ir(e,t,n=Jn){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 ia(e){const t=na(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 Ar(e,t,n=Jn){const r=ia(t),i=Di(n);if(ra(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 Ir(e,r,i);try{const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return await e.decodeAudioData(s)}catch{return Ir(e,r,i)}}function Bi(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Fi(e,t){const n=[],r=[];let i=null,s=!1,o=!1,a=!1,u=!1,d=0,l=0,c=0,m=null,p=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=p},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=p>0?(D-b)/p: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=p>0?P/p: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 w=String(j.word??"").trim();if(!w)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:w,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(w=>{const S=String(w.symbol??w.viseme??"").trim();if(!S)return;const x=Math.round((w.start??0)*1e3),_=Math.max(1,Math.round((w.duration??0)*1e3)),U=c+x,Z=Bi(P,U),te=Z?vi(Z,U):0;let z;si(q)==="oculus_direct"?(z=mn(S),z==="U"&&Z&&hn(Z.word,te)&&(z="FF")):z=_i(S,Z?.word??"",te),b.push({viseme:z,weight:1,vtime:U,vduration:_})}),e.onNotify())},W=(b,P,H,le,j,q,w)=>{O(P,le,j),J(b,P,H,j,q,w)},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 w=(j-le)*1e3;d=performance.now()+w}P.onBeforeStart?.(j);const q=H.createBufferSource();return q.buffer=b,q.playbackRate.value=p,q.connect(H.destination),E&&q.connect(E),r.push(q),f?(r.pop(),j):(P.isFirstAudio&&(o=!0,e.onSpeakingStart()),q.onended=()=>{const w=r.indexOf(q);w>=0&&r.splice(w,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 Ar(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 Ar(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=>{p=Math.max(.1,Math.min(1,b)),ae()},getPlaybackSpeed:()=>p,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,w)=>{if(f)return;L=b,A=P;const S=Di(w?.sampleRate),x=w?.newStream===!0,_=de();if(!H?.trim()){if(le.length===0&&j.length===0)return;he(_,b,P),x&&w?.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:w?.onNewStream,visemesQueued:!1}),await $(b,P)},queueTimingsOnly:(b,P,H,le,j,q)=>{if(f)return;const w=de();he(w,b,P),W(b,P,H,le,0,!0,T),w.segmentOffsetMs=0,D=lt(b)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*p):o?Math.max(0,(performance.now()-d)*p):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 Li(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 sa(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 aa(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Mr(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 wn=.5,yn=1.5,Zn="Olivia",er="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",p="",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=Fi({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=pn(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;Ci(o,a,O,J,u,K);const ee=Ri(O,u),$=W?Mr(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=>{p=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=p.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:Zn),X=J?.speakingRate??Ht,_e=Math.max(wn,Math.min(yn,X)),oe={user_query:O,ttsEngineId:ee,speakingRate:_e,tenant:"aiTwin"};ri.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="",w=!0;const S=async x=>{if(W!==B)return;const _=wi(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 wt=w;w=!1,await A.playAudioChunk(i,s,U,Z,te,z,{sampleRate:be,newStream:wt,audioOffsetMs:Xe}),V(O,Pt,Z,z,Mr(U,be)),I("audio_chunk",O)}else(Z.length>0||te.length>0)&&(A.queueTimingsOnly(i,s,Z,te,z,{audioOffsetMs:Xe,newStream:w}),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(`
2
2
 
3
- `);ne=k.pop()??"";for(const b of k)await W(b);if(v){ne.trim()&&await W(ne.trim()),A.markStreamComplete(i),I("bot_stopped",O);break}}}catch(te){if(z!==P||te instanceof DOMException&&te.name==="AbortError")return;throw console.error("[avatarTtsLipsync]",te),J(),e("error"),te}},stop:J,getVisemeQueue:()=>i,getWordQueue:()=>s,getFullVisemeQueue:()=>o,getFullWordQueue:()=>a,getSentenceEmotions:()=>f,getStreamMood:()=>d,getPlaybackElapsedMs:()=>A.getPlaybackElapsedMs(),isSpeaking:()=>A.isSpeaking(),isWarmingUp:()=>A.isWarmingUp(),releaseWarmupHold:()=>A.releaseWarmupHold(),setLipsyncWarmupHold:(O,le)=>{le&&(N=le),A.setLipsyncWarmupHoldEnabled(O)},getVoiceStream:()=>A.getVoiceStream(),setPlaybackSpeed:O=>{A.setPlaybackSpeed(O)},getPlaybackSpeed:()=>A.getPlaybackSpeed(),subscribe:O=>(m.add(O),()=>m.delete(O))}}const qn=16e3,Gn=16e3;class js extends Ln.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 Ks extends Ln.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,qn,Gn)}bufferBotAudio(t,n){}}const qs=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Tr(e){return qs.test(e.trim())}function Gs(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function Ai(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??ct,r=new URL(`${Gs(n)}/ws/voice`);r.searchParams.set("authToken",t),r.searchParams.set("tenant","aiTwin");const i=e.ttsEngineId;i&&r.searchParams.set("ttsEngineId",i);const s=e.voiceId?.trim();s&&(i&&Zr(i)?Tr(s)||r.searchParams.set("voiceId",s):Tr(s)&&r.searchParams.set("voiceId",s));const o=e.personaId?.trim();o&&r.searchParams.set("personaId",o);const a=e.speakingRate??Ot;r.searchParams.set("speaking_rate",String(Math.max(dn,Math.min(mn,a)))),e.ttsStream===!1?r.searchParams.set("tts_stream","false"):r.searchParams.set("tts_stream","true"),e.speakOnlyWhenSpokenTo&&r.searchParams.set("speakOnlyWhenSpokenTo","true");const u=e.avatarName?.trim();return u&&r.searchParams.set("avatarName",u),r.toString()}function Tn(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 Ys(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 kr(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function Qs(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function Mi(e,t={}){const n=[],r=[],i=[],s=[];let o=0;const a=[],u=[];let f="",l="neutral",c=lt,d=!1,p=null,T=null,m={...t},E=0,C=null;const P=new Set,_=[];let x=!1,N=null,A=!0,ie="default";const me=new Set;let I=null,V=0,q=!1,se=!1,J=null,Z=!1;const O=()=>{J!=null&&(clearTimeout(J),J=null)},le=()=>{O(),J=setTimeout(()=>{J=null,A&&(L.markStreamComplete(n),te("bot_stopped"))},450)},z=()=>P.forEach(w=>w());let pe=()=>!1;const L=Ei({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{Z=!1,se=!1,e("done")},onNotify:z,shouldHoldForWarmup:()=>pe()},c),Q=()=>{if(N)return N;const w=new MessageChannel;return w.port1.onmessage=()=>{const B=_.shift();B!==void 0&&Be(B),_.length>0?w.port2.postMessage(null):x=!1},N=w,w},K=w=>{_.push(w),!x&&(x=!0,Q().port2.postMessage(null))},ae=()=>L.getPlaybackElapsedMs(),be=(w,B=f)=>{if(!m.onLipsyncDebug)return;const ee=ae(),ue=n,Te=fn(i).map(ve=>({viseme:ve.viseme,vtimeMs:ve.vtime}));m.onLipsyncDebug({event:w,spokenText:B,mood:l,playbackAnchorPerf:L.getPlaybackStartPerf(),playbackElapsedMs:ee,queueLength:ue.length,activeViseme:Lt(ue,ee),segments:u.map(ve=>({...ve,visemes:[...ve.visemes]})),fullQueueLength:i.length,compactionSkipped:Te})},te=(w,B)=>{m.onLipsyncDebug&&(C={event:w,spokenText:B},E===0&&(E=requestAnimationFrame(()=>{E=0;const ee=C;C=null,ee&&be(ee.event,ee.spokenText)})))},S=()=>{A=!0,me.clear(),L.clearAborted()},R=()=>{const w=Qs(p);if(w){ie=`bot-${Date.now()}`,w.interruptedTrackIds={[ie]:!0};try{w.interrupt?.()}catch{}}const B=T;try{B?.interrupt?.()}catch{}},re=w=>{if(Z&&L.isSpeaking())return!0;const B=w.context_id?.trim();return B&&me.has(B)?!0:A?!1:!(w.type==="avatar_metadata"||kr(w))},ne=w=>{A=!1,Z=!1;const B=w.context_id?.trim();B&&me.add(B),O(),q=!1,se=!1,_.length=0,x=!1,I?.abort(),I=null,V+=1,R(),L.bargeIn(),H(),e("idle"),te("interrupt"),z()},H=()=>{n.length=0,r.length=0,i.length=0,s.length=0,o=0,u.length=0,f="",l="neutral",a.length=0},W=()=>{O(),se=!1,q=!1,L.stop(),H(),te("reset"),z()},v=()=>{W(),e("idle"),z()},y=(w,B)=>{typeof w.mood=="string"&&w.mood.trim()&&(l=w.mood.trim()),Array.isArray(w.sentence_emotions)&&w.sentence_emotions.length>0&&(B&&(a.length=0),a.push(...Tn(w.sentence_emotions,l)))},k=w=>{if(re({...w,type:"avatar_metadata"}))return;S(),q=!0;const B=String(w.spoken_text??w.text??"").trim();B&&(f=B),L.resetForNewStream(c),typeof w.mood=="string"&&w.mood.trim()&&(l=w.mood.trim()),a.length=0,a.push(...Tn(w.sentence_emotions,l)),Array.isArray(w.gestures)&&w.gestures,te("metadata",B),z()},b=(w,B,ee,ue)=>{if(!m.onLipsyncDebug)return;const Te=n.slice(ee),ve=ue.filter(ke=>String(ke.symbol??ke.viseme??"").trim());u.push({spokenText:B,audioOffsetMs:Te[0]?.vtime??0,isNewSegment:!!w.is_new_segment,chunkDurationMs:w.chunk_duration_ms!=null?Number(w.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:Te.map((ke,Oe)=>{const Ne=ve[Oe];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}})})},$=(w,B,ee,ue)=>{if(w.length===0&&B.length===0)return;bi(i,s,w,B,o,c);const Te=Ti(w,o);let ve=null;const ke=ee.trim();if(ke)try{const Oe=atob(ke.replace(/\s+/g,"")).length,Ne=Number.isFinite(ue)&&(ue??0)>0?Number(ue):16e3;ve=Oe/2/Ne*1e3}catch{ve=null}o=Math.max(Te,ve!=null?o+ve:o)},G=w=>{if(re(w))return;const B=kr(w);B&&(O(),S());const ee=String(w.spoken_text??w.text??"").trim(),ue=w.visemes??[],Te=w.words??[],ve=String(w.chunk??"").trim(),ke=q||B||!se;q&&(q=!1),ke&&(se=!0),ee&&(f=ee),y(w,B),ke?(L.resetForNewStream(c),i.length=0,s.length=0,o=0):B&&L.resumeBotStream(),$(ue,Te,ve,w.sample_rate);const Oe=n.length;L.playAudioChunk(n,r,ve,ue,Te,B,{sampleRate:w.sample_rate,newStream:ke,audioOffsetMs:Number(w.audio_offset_ms??0),onNewStream:()=>{u.length=0}}).then(()=>{b(w,ee,Oe,ue),te("audio_chunk",ee),le()})},X=w=>{if(re(w))return;(w.is_new_segment||Number(w.audio_offset_ms??-1)===0)&&S(),console.warn("[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk");const B=String(w.spoken_text??w.text??"").trim();B&&(f=B),y(w,!!w.is_new_segment),$(w.visemes??[],w.words??[],"",void 0);const ee=n.length;L.queueTimingsOnly(n,r,w.visemes??[],w.words??[],!!w.is_new_segment,{audioOffsetMs:Number(w.audio_offset_ms??0)}),b(w,B,ee,w.visemes??[]),te("lipsync",B),z()},oe=async w=>{const B=String(w.text??"").trim();if(!B)return;const ee=m.authToken?.trim();if(!ee){console.error("[realtimeVoice] avatar_speak requires authToken");return}I?.abort();const ue=new AbortController;I=ue;const Te=++V;S(),L.resetForNewStream(c),f=B;const ke=`${(m.apiBase??ct).replace(/\/$/,"")}/avatar_ttsWithPoses`,Oe=m.voiceId?.trim()||(c===ut?on:Kn),Ne=m.speakingRate??Ot,pn=Math.max(dn,Math.min(mn,Ne)),Vt={user_query:B,ttsEngineId:c,speakingRate:pn,tenant:"aiTwin"};Qr.has(c)&&(Vt.voice_id=Oe);try{const Ge=await fetch(ke,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${ee}`},body:JSON.stringify(Vt),signal:ue.signal});if(!Ge.ok)throw new Error(`avatar_ttsWithPoses failed (${Ge.status})`);const We=Ge.body;if(!We)throw new Error("No response body");const Ye=We.getReader(),mt=new TextDecoder;let ye="",Ve=!0;const rt=async ze=>{if(Te!==V||ue.signal.aborted||!A)return;const Se=ci(ze);if(Se){if(Se.event==="audio"){const Ie=Se.data.chunk,xe=Se.data.visemes??[],Pe=Se.data.words??[],ht=Se.data.is_new_segment??!1,wt=Se.data.sample_rate,pt=Number(Se.data.audio_offset_ms??0);if(Ie){const Ut=Ve;Ve=!1,await L.playAudioChunk(n,r,Ie,xe,Pe,ht,{sampleRate:wt,newStream:Ut,audioOffsetMs:pt})}else(xe.length>0||Pe.length>0)&&L.queueTimingsOnly(n,r,xe,Pe,ht,{audioOffsetMs:pt,newStream:Ve})}else if(Se.event==="metadata"){const Ie=Se.data.mood;typeof Ie=="string"&&Ie.trim()&&(l=Ie.trim());const xe=Se.data.sentence_emotions;Array.isArray(xe)&&(a.length=0,a.push(...Tn(xe,l))),z()}else if(Se.event==="error")throw new Error(String(Se.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(Te!==V||ue.signal.aborted||!A);){const{done:ze,value:Se}=await Ye.read();Se&&(ye+=mt.decode(Se,{stream:!0}));const Ie=ye.split(`
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 tr=16e3,nr=16e3;class oa 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 ca extends Hn.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,tr,nr)}bufferBotAudio(t,n){}}const la=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Pr(e){return la.test(e.trim())}function ua(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function Oi(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(`${ua(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&&ai(s)?Pr(o)||r.searchParams.set("voiceId",o):Pr(o)&&r.searchParams.set("voiceId",o));const a=fn(e.language);a&&r.searchParams.set("language",a);const u=e.personaId?.trim();u&&r.searchParams.set("personaId",u);const d=e.speakingRate??Ht;r.searchParams.set("speaking_rate",String(Math.max(wn,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 da(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 Cr(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function fa(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function Ni(e,t={}){const n=[],r=[],i=[],s=[];let o=0;const a=[],u=[];let d="",l="neutral",c=tt,m=!1,p=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=Fi({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=pn(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=fa(p);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"||Cr(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()},w=()=>{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;Ci(i,s,g,C,o,c);const Te=Ri(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=Cr(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:er),$t=f.speakingRate??Ht,bn=Math.max(wn,Math.min(yn,$t)),Rt={user_query:C,ttsEngineId:c,speakingRate:bn,tenant:"aiTwin"};ri.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(),Ae=new TextDecoder;let xe="",$e=!0;const je=async rt=>{if(Te!==V||ue.signal.aborted||!A)return;const we=wi(rt);if(we){if(we.event==="audio"){const Le=we.data.chunk,Pe=we.data.visemes??[],Oe=we.data.words??[],Ne=we.data.is_new_segment??!1,Dt=we.data.sample_rate,ct=Number(we.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(we.event==="metadata"){const Le=we.data.mood;typeof Le=="string"&&Le.trim()&&(l=Le.trim());const Pe=we.data.sentence_emotions;Array.isArray(Pe)&&(a.length=0,a.push(...An(Pe,l))),W()}else if(we.event==="error")throw new Error(String(we.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(Te!==V||ue.signal.aborted||!A);){const{done:rt,value:we}=await vt.read();we&&(xe+=Ae.decode(we,{stream:!0}));const Le=xe.split(`
4
4
 
5
- `);ye=Ie.pop()??"";for(const xe of Ie)await rt(xe);if(ze){ye.trim()&&await rt(ye.trim()),Te===V&&!ue.signal.aborted&&A&&L.markStreamComplete(n);break}}}catch(Ge){if(ue.signal.aborted||!A)return;console.error("[realtimeVoice] avatar_speak failed:",Ge),e("error"),z()}finally{I===ue&&(I=null)}},Be=w=>{const B=Ys(w);if(!B){console.warn("[realtimeVoice] server message with no payload",w);return}const ee=String(B.type??"unknown");switch(ee!=="avatar_metadata"&&ee!=="avatar_audio_chunk"&&ee!=="avatar_lipsync"&&ee!=="avatar_interrupt"&&ee!=="error"&&console.debug("[realtimeVoice] server message",ee,B),ee){case"avatar_metadata":k(B);break;case"avatar_audio_chunk":G(B);break;case"avatar_lipsync":X(B);break;case"avatar_interrupt":ne(B);break;case"error":{const ue=String(B.message??"Voice session error");console.error("[realtimeVoice] server error:",ue),e("error"),z();break}case"avatar_speak":oe(B);break}},tt=()=>p||(T=new Ks,p=new es.PipecatClient({transport:new Ln.WebSocketTransport({mediaManager:T,serializer:new js,recorderSampleRate:qn,playerSampleRate:Gn}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{d=!0,e("idle"),z()},onDisconnected:()=>{d=!1,v()},onError:w=>{const B=typeof w=="object"&&w!==null&&"data"in w?String(w.data??w):String(w);console.error("[realtimeVoice]",B,w),e("error"),z()},onTransportStateChanged:w=>{w==="error"&&(e("error"),z())},onServerMessage:w=>{K(w)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{S(),te("bot_started")},onBotStoppedSpeaking:()=>{A&&le()},onUserTranscript:w=>{String(w.text??""),m.onUserTranscript?.(w.text,!!w.final)},onBotOutput:w=>{m.onBotOutput?.(w.text)}}}),p);return{setDeveloperToken:w=>{},setTtsEngineId:w=>{c=w,L.setStreamTtsEngineId(w)},getTtsEngineId:()=>c,speak:async(w,B)=>{const ee=w.trim();if(ee){if(!p||!d)throw new Error("Realtime voice is not connected. Call connect() first.");W(),await p.sendText(ee)}},stop:()=>{I?.abort(),I=null,V+=1,S(),W(),e("idle"),z()},connect:async w=>{if(w&&(m={...m,...w}),m.ttsEngineId&&(c=m.ttsEngineId,L.setStreamTtsEngineId(c)),!m.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const B=tt();await B.initDevices();const ee=Ai({...m,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",ee);try{await B.connect({wsUrl:ee})}catch(ue){d=!1,e("error"),z();const Te=ue instanceof Error?ue.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${Te} — ${ee}`)}d=!0,e("idle"),z()},disconnect:async()=>{if(O(),q=!1,se=!1,_.length=0,x=!1,I?.abort(),I=null,V+=1,S(),p)try{await p.disconnect()}catch(w){console.error("[realtimeVoice] disconnect failed:",w)}d=!1,v()},isConnected:()=>d,unlockAudio:async()=>{await L.primeAudioContext()},getVisemeQueue:()=>n,getWordQueue:()=>r,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:ae,isSpeaking:()=>L.isSpeaking(),isWarmingUp:()=>L.isWarmingUp(),releaseWarmupHold:()=>L.releaseWarmupHold(),setLipsyncWarmupHold:(w,B)=>{B&&(pe=B),L.setLipsyncWarmupHoldEnabled(w)},getVoiceStream:()=>L.getVoiceStream(),setPlaybackSpeed:w=>{L.setPlaybackSpeed(w)},getPlaybackSpeed:()=>L.getPlaybackSpeed(),subscribe:w=>(P.add(w),()=>P.delete(w))}}function Pi(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function Ri(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 Ci(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Et(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 bs(r,t)}async function Di(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Et(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function Xs(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function Js(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 Zs(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function ea(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 ta(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function na(e){const t=ks();if(!Ft())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Et(t,e);return ta(n)}function St(e,t){return`${e}/${t}_minus_sil.png`}const Bi=5;function hn(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:Bi}const ra=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Cn=["t01_0.25","t02_0.50","t03_0.75"],ia=Cn.length,xr=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 Er(e,t){return`${e}__${t}`}function Ir(e,t){return`pairs/${e}/${t}_minus_sil.png`}function Tt(e){return`${e}_minus_sil.png`}function Yn(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=Tt(r);return t.has(i)?i:null}function Fi(e,t){return e.filter(n=>t.has(n))}function sa(e,t,n){const r=Qn(e,t);return Fi(r,n).length>0}function Qn(e,t){if(e===t)return[];const n=[],r=Er(e,t);if(xr.has(r)){for(const s of Cn)n.push(Ir(r,s));return n}const i=Er(t,e);if(xr.has(i)){for(let s=ia-1;s>=0;s--)n.push(Ir(i,Cn[s]));return n}return[]}function aa(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function oa(e,t){return aa(t).map(r=>e[r]).filter(r=>r!=null)}function ca(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 Li(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 la=[.32,.24,.16,.08,0],ua=la.map(e=>`eyes_${e.toFixed(2)}`),fa=["eyes_0.32","eyes_0.16","eyes_0.00"],da=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],Ue=2,ma=-20,tn=16,Oi={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function Dt(e){return`brow_${e}`}function ot(e){return Oi[e]}function qe(e){return Math.max(ma,Math.min(tn,e))}function ha(e,t){if(e===t)return[];const n=e<t,r=n?Ue:-Ue,i=[];let s=e;if(s%Ue!==0){const o=n?Math.ceil(s/Ue)*Ue:Math.floor(s/Ue)*Ue,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 Ar(e){const t=qe(e);if(t%Ue===0)return[t];const n=Math.floor(t/Ue)*Ue,r=Math.min(tn,n+Ue),i=qe(n);return t-i<=r-t?i===r?[i]:[i,r]:i===r?[r]:[r,i]}const wa=["fear","anger","sad","neutral","love","happy","disgust"],pa={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 Xe(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?pa[n]??t:t}function Ni(e){return e===0?null:St(Dt(e),"eyes_standard")}function Vi(e){return Ni(ot(e))}const ga={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function Xn(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 Ar(i)){if(a===i)continue;const u=St(Dt(a),s);if(t(u))return u}const o=ga[i];if(o){const a=St(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=ot(i);for(const a of[o,...Ar(o)]){const u=St(Dt(a),s);if(t(u))return u}}return null}function Mr(e,t){const n=Dt(ot(e));return!t||t==="eyes_standard"?Vi(e):e==="neutral"&&t==="eyes_standard"?null:St(n,t)}function ya(e,t){const n=[];for(const r of t)n.push(Mr(e,r));for(let r=t.length-2;r>=0;r--)n.push(Mr(e,t[r]));return n.push(Vi(e)),n}function _a(e){return St(Dt(e),"eyes_standard")}function va(e,t){return ha(e,t).map(_a)}const Sa=6;function ba(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Ta(e){const t=qe(e);return t>=tn?tn:qe(t+Sa)}function ka(e,t,n){const r=qe(n);return ba(t,e)?.emphasis?Ta(r):r}function Pr(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 Ke(e,t){return e+Math.random()*(t-e)}function Rr(){return Ke(14,32)}function xa(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:Ke(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:Ke(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?Ke(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function Cr(e,t){const n=Ke(e.holdMinMs,e.holdMaxMs);return t?n+e.closedExtraMs:n}function Ea(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:f=550}=e;let l="neutral",c="neutral",d=0,p=0,T=0,m={kind:"idle",nextBlinkAt:performance.now()+t},E=null,C="__eyes_open__|neutral|brow:0";function P(I=l){C=`${E??"__eyes_open__"}|${I}|brow:${p}`}function _(I,V=l){E=I;const q=Pr(I);q!=null?p=q:I==null&&(p=0),P(V)}function x(I){return Ni(I)}function N(I,V,q){const se=qe(V),J=qe(q);if(d=J,se===J){_(x(J));return}const Z=[...va(se,J),x(J)];m={kind:"browBlend",paths:Z,index:0,holdUntil:I+Rr(),targetBrow:J},_(Z[0]??null)}function A(I,V){m={kind:"idle",nextBlinkAt:I+Ke(n,r)},c=V,_(x(d),V)}function ie(I,V,q){const se=q?fa:Math.random()<a?ua:da,J=xa(q),Z=se.length-1;m={kind:"playing",paths:ya(V,se),index:0,holdUntil:I+Cr(J,Z===0),after:"idle",blinkEmotion:V,pace:J,closedFrameIndex:Z},c=V,_(m.paths[0]??null,V)}function me(I){if(m.kind==="browBlend"){for(;I>=m.holdUntil&&m.index<m.paths.length-1;)m.index+=1,m.holdUntil=I+Rr();const V=m.paths[m.index]??null;_(V),I>=m.holdUntil&&m.index>=m.paths.length-1&&(p=m.targetBrow,d=m.targetBrow,_(x(m.targetBrow)),m={kind:"idle",nextBlinkAt:I+u});return}if(m.kind==="idle"){_(x(d),c),I>=m.nextBlinkAt&&ie(I,c,!1);return}if(m.kind==="doublePause"){_(x(d),m.blinkEmotion),I>=m.resumeAt&&ie(I,m.blinkEmotion,!0);return}if(m.kind==="playing"){for(;I>=m.holdUntil&&m.index<m.paths.length-1;)m.index+=1,m.holdUntil=I+Cr(m.pace,m.index===m.closedFrameIndex);if(_(m.paths[m.index]??null,m.blinkEmotion),I>=m.holdUntil&&m.index>=m.paths.length-1){if(m.after==="resumeIdle"){A(I+u,l);return}if(m.after==="doublePause"){m={kind:"doublePause",resumeAt:I+Ke(s,o),blinkEmotion:m.blinkEmotion},_(x(d),m.blinkEmotion);return}if(m.after==="idle"&&Math.random()<i){m={kind:"doublePause",resumeAt:I+Ke(s,o),blinkEmotion:m.blinkEmotion},_(x(d),m.blinkEmotion);return}A(I,m.blinkEmotion)}}}return{advance:me,setTargetEmotion(I,V){const q=Xe(I,l);if(q===l)return;const se=performance.now();!V?.force&&f>0&&!(l==="neutral"&&q!=="neutral")&&se-T<f||(l=q,c=q,T=se)},setTargetEyebrow(I){const V=qe(I);if(V===d)return;const q=performance.now(),se=m.kind==="browBlend"?Pr(E)??p:p;d=V,!(V===se&&m.kind!=="browBlend")&&(m.kind==="playing"||m.kind==="doublePause"||N(q,se,V))},snapToEmotion(I){const V=Xe(I),q=ot(V);l=V,c=V,d=q,p=q,T=performance.now(),m={kind:"idle",nextBlinkAt:performance.now()+Ke(4e3,7e3)},_(x(q),V)},getTargetEmotion:()=>l,getTargetEyebrow:()=>d,getExpressionPath:()=>E,getDrawKey:()=>C,reset(){l="neutral",c="neutral",d=0,p=0,T=0,A(performance.now()+Ke(n,r),"neutral")}}}function Ia(){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 f=e.duration;if(!Number.isFinite(f)||f<=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 Aa=50,Ui=400;function Ma(e,t,n){return e.filter(r=>{const i=r.queueIndex??-1;return i>=t&&i<=n})}function Pa(e,t){const n=[];for(const r of e){const i=Ma(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-Aa),endMs:o.wtime+o.wduration+Ui})}return n.sort((r,i)=>r.startMs-i.startMs)}function Ra(e,t,n,r="neutral"){const i=Xe(r);if(t.length===0)return i;if(n.length===0||e<n[0].wtime)return Xe(t[0]?.emotion,i);const s=Pa(t,n);let o=null;for(const f of s)e>=f.startMs&&e<=f.endMs&&(o=f);if(o)return Xe(o.sentence.emotion,i);const a=n[n.length-1],u=a.wtime+a.wduration;return e>u+Ui?Xe(t[t.length-1]?.emotion,i):i}function Jn(e,t,n,r,i=Bi){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 d=l.getImageData(0,0,n,r);for(let p=0;p<u.data.length;p+=4){const T=d.data[p],m=d.data[p+1],E=d.data[p+2];Math.max(T,m,E)>i&&(u.data[p]=T,u.data[p+1]=m,u.data[p+2]=E,u.data[p+3]=255)}}return o.putImageData(u,0,0),s}let st=null,kt=null;const nn=new Map;function Ca(){st=null,kt=null,nn.clear()}ii(Ca);function Da(e){return e??kt??void 0}function Zn(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 Ba(e){return Ft()?ea(await Et(en(),e??"")):Zn(en())}async function Dr(e,t,n,r){const i=n?await Di(e,r):await fetch(e).then(f=>{if(!f.ok)throw new Error(`Failed to load ${e}`);return f.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=n?await Js(await Et(Li(t,s.path,n),r??"")):await Zn(`${t}/${s.path}`),a=new Map;for(const f of i.cells??[])f.path&&a.set(f.path,f);const u=new Map;for(const f of i.sheets??[])u.set(f.index,f);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:u,diffBase:t}}async function Dn(e){const t=Da(e),n=Ft();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(st&&(!n||kt===(t??null))){const s=await st;return{...xt(s),visemePaths:[...s.viseme.cellByPath.keys()]}}kt=t??null,nn.clear();const r=si();st=(async()=>{const s=await Ba(t),o=await Dr(ai(),r,n,t);let a=null;try{a=await Dr(oi(),r,n,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await st;return{...xt(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function er(e){if(await Dn(e),!st)throw new Error("Assets not loaded");return st}function xt(e){return Pi(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Fa(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 rn(e,t,n){const r=`${t.diffBase}::${n}`,i=nn.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=Ri(t.atlasMeta,o),u=xt(e);if(Ci(o)){const c=Fa(t,o),d=document.createElement("canvas");d.width=u.width,d.height=u.height;const p=d.getContext("2d");return p.fillStyle="#000",p.fillRect(0,0,u.width,u.height),p.drawImage(c,a.x,a.y),d}const f=`${t.diffBase}/${n}`,l=await Zn(f);if(l.naturalWidth===u.width&&l.naturalHeight===u.height)return l;throw new Error(`Diff PNG wrong size for ${n}`)})();return nn.set(r,s),s}async function kn(e,t,n,r,i,s){if(i){const{width:p,height:T}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const m=document.createElement("canvas");m.width=p,m.height=T;const E=m.getContext("2d");if(E.clearRect(0,0,p,T),E.drawImage(t,0,0,p,T),s&&!s())return;(e.width!==p||e.height!==T)&&(e.width=p,e.height=T);const C=e.getContext("2d");C.clearRect(0,0,p,T),C.drawImage(m,0,0);return}const o=await er(),a=hn(o.viseme.atlasMeta),{width:u,height:f}=xt(o);(e.width!==u||e.height!==f)&&(e.width=u,e.height=f);const l=[],c=e.getContext("2d");if(c.clearRect(0,0,u,f),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const p=o.sil;c.drawImage(p,0,0,u,f);return}if(l.length===0){c.drawImage(t,0,0,u,f);return}const d=Jn(t,l,u,f,a);c.drawImage(d,0,0)}async function Bn(e,t,n){const r=await er(kt??void 0),i=hn(r.viseme.atlasMeta),{width:s,height:o}=xt(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=Yn(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await rn(r,r.viseme,c))}if(t.expressionPath&&r.expression){const l=Xn(t.expressionPath,c=>r.expression.cellByPath.has(c));l&&a.push(await rn(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 f=Jn(r.sil,a,s,o,i);u.drawImage(f,0,0)}async function La(e,t){const n=await er(kt??void 0),r=hn(n.viseme.atlasMeta),{width:i,height:s}=xt(n),o=[];if(e.mouthPath){const l=new Set(n.viseme.cellByPath.keys()),c=Yn(e.mouthPath,l)??(l.has(e.mouthPath)?e.mouthPath:null);c&&o.push(await rn(n,n.viseme,c))}if(e.expressionPath&&n.expression){const l=Xn(e.expressionPath,c=>n.expression.cellByPath.has(c));l&&o.push(await rn(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 f=Jn(n.sil,o,i,s,r);return u.drawImage(f,0,0),a.transferToImageBitmap()}async function Oa(e){await Bn(e,{mouthPath:null,expressionPath:null})}const Qt={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function Na(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function Va(e){if(!e)return{enabled:!1,style:Qt};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??Qt.fontFamily,fontSize:t.fontSize??Qt.fontSize,color:t.color??Qt.color}}}const Ua={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},Wa={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"},za={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function $a({text:e,style:t}){return M.jsx("div",{style:Ua,"aria-live":"polite","aria-atomic":"true",children:M.jsx("div",{style:{...Wa,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:M.jsx("p",{style:za,children:e})})})}const Ha={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},ja={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},Ka={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function qa({thumbnailUrl:e}){const[t,n]=h.useState(!1);h.useEffect(()=>{n(!1)},[e]);const r=!!e&&t;return M.jsxs("div",{style:Ha,"aria-hidden":!0,children:[e?M.jsx("img",{src:e,alt:"",style:{...ja,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,M.jsx("div",{style:{...Ka,background:r?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Wi=null;function Br(e){Wi=e}function et(){return Wi}function Ga(e){return`${e.from}→${e.to}@${e.fromVtime}`}function Fr(){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 Ya(){let e=Fr();const t=new Set,n=new Set,r=new Set;let i="",s=-1,o="";const a=()=>{e=Fr(),t.clear(),n.clear(),r.clear(),i="",s=-1,o=""},u=l=>{t.add(l)},f=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 d=Ga(l);e.transitionFramesSampled+=1,d!==i&&(i=d,s=-1,o!==d&&(o=d,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 p=l.transitionMeta;u(p.fromVtime),u(p.toVtime),f(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const d=l.label.trim();if(!(!d||d==="sil")){for(const p of c)if(p.viseme===d&&l.elapsedMs>=p.vtime&&l.elapsedMs<p.vtime+p.vduration){u(p.vtime);break}}},snapshot(l,c){let d=0,p=0;for(const P of l)if(P.viseme!=="sil"){if(P.vtime>=c)break;d+=1,t.has(P.vtime)&&(p+=1)}const T=d>0?Math.round(p/d*100):100,m=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),E=d-p,C=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:C,renderLoss:m,visemeSlotsTotal:d,visemeSlotsCovered:p,visemeCoveragePct:T,transitionFramesUniqueSampled:n.size,transitionFramesUniquePainted:r.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+m,visemesShown:p,visemesSkipped:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const zi=Nn,Qa=200,Lr=300,Xa=100,Ja=600,$i="__sil__";function Or(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===$i:!1}function tr(){return{lastDrawnKey:""}}function De(e){e.lastDrawnKey="",e.transitionCache=void 0}function Za(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const n=vi(e);return t&&(t.transitionCache={queueLength:e.length,transitions:n}),n}function eo(e,t){let n="sil";for(const r of e)r.viseme!=="sil"&&(t!=null&&r.vtime>t||(n=r.viseme));return n}function to(e,t,n,r=120){if(n!=="sil")return n;const i=Ii(e,t,r);return i!=="sil"?i:eo(e,t)}function no(e,t){return e==="sil"?!1:t?sa(e,"sil",t):Qn(e,"sil").length>0}function ro(){return zi+Ja}function sn(e){return e??$i}function nr(e,t,n,r,i=Xa){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=it(e))return{diffPath:null,label:"sil"};const s=Za(e,r),o=Vs(s,t);if(o){const f=Si(o.fromVtime,o.toVtime,o.from,o.to);if(t>=f.transStart&&t<f.transEnd){let l=Qn(o.from,o.to);n&&(l=Fi(l,n));const c=oa(l,f.effectiveGapMs);if(c.length>0){const d=ca(t,f.transStart,f.transEnd,c.length);return{diffPath:c[d]??c[c.length-1],label:`${o.from}→${o.to}`,transitionMeta:{from:o.from,to:o.to,fromVtime:o.fromVtime,toVtime:o.toVtime,frameIdx:d,frameCount:c.length,fullFrameCount:l.length,omittedByGap:Math.max(0,l.length-c.length)}}}return{diffPath:Tt(o.to),label:o.to}}}const a=un(e);let u=pi(a,t);return u==="sil"&&(u=Ii(e,t,i)),u==="sil"?{diffPath:null,label:"sil"}:{diffPath:Tt(u),label:u}}function Bt(e,t){const n=t??sn(e.expressionPath);return`${sn(e.mouthPath)}|${n}`}function Nr(e,t,n,r,i,s,o,a,u,f){const l=nr(t,n,u,s),c={mouthPath:l.diffPath,expressionPath:r},d=Bt(c,i),p=et();if(l.transitionMeta&&p?.onTransitionSample(l.transitionMeta,l.diffPath),d===s.lastDrawnKey){p?.onDrawDeduped();return}p?.onDrawRequested(),a(l),s.lastDrawnKey=d,o(e,c,d,T=>{T===d&&(s.lastDrawnKey=d)})}function xn(e,t,n,r,i,s,o=null,a=null){const u={mouthPath:a,expressionPath:t},f=o!=null?`|idle@${Math.round(o*1e3)}`:"",l=Bt(u,n)+f;!(o!=null)&&l===r.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,u,l,d=>{d===l&&(r.lastDrawnKey=l)}))}function Hi(e,t,n,r,i=Rt,s){if(n<=t||e.length===0)return[];const o=s??tr(),a=[];let u="";for(let f=t;f<n;f+=i){const l=nr(e,f,r,o),c=sn(l.diffPath);c!==u&&(u=c,a.push({displayAtMs:f,mouthPath:l.diffPath,mouthKey:c,label:l.label}))}return a}const io=3;function rr(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,f){const l=n.findIndex(c=>c.drawKey===u);l>=0?n[l]={diffs:a,drawKey:u,onDisplayed:f}:(n.length>=io&&(n.shift(),et()?.onQueueSuperseded()),n.push({diffs:a,drawKey:u,onDisplayed:f})),o()},reset(){t+=1,n.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function so(e,t=2){const n=[],r=new Set;let i=0,s=!1,o=0;const a=(f,l)=>`${f}|${l}`,u=async()=>{if(!s){s=!0;try{for(;i<t&&n.length>0;){const f=n.shift(),l=a(f.displayAtMs,f.drawKey);if(r.has(l))continue;r.add(l),i+=1;const c=o;try{await e(f)}finally{if(r.delete(l),i-=1,c!==o)return}}}finally{s=!1,n.length>0&&i<t&&u()}}};return{enqueue(f){const l=a(f.displayAtMs,f.drawKey);r.has(l)||n.some(c=>a(c.displayAtMs,c.drawKey)===l)||(n.push(f),u())},isQueuedOrInflight(f,l){const c=a(f,l);return r.has(c)?!0:n.some(d=>a(d.displayAtMs,d.drawKey)===c)},reset(){o+=1,n.length=0,r.clear(),i=0},pendingCount(){return n.length+i}}}function ao(){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 oo(e,t,n,r,i,s){const o=Hi(t,n,r,i,Rt,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 co(e){const t=ao(),n=tr(),r=new Set;let i="",s=null;const o=so(async c=>{try{if(!e.supportsBufferedPlayback)return;const d=await e.compositePrefetchFrame(c.diffs,c.mouthKey);if(!d)return;t.markRendered(c.displayAtMs,c.mouthKey,c.label,c.mouthPath,d),et()?.onBufferPrefetched()}finally{r.delete(c.mouthKey)}},us),a=c=>{for(const d of c)t.has(d.displayAtMs,d.mouthKey)||r.has(d.mouthKey)||o.isQueuedOrInflight(0,d.mouthKey)||(r.add(d.mouthKey),o.enqueue({...d,displayAtMs:0,drawKey:d.mouthKey,diffs:{mouthPath:d.mouthPath,expressionPath:null}}))},u=(c,d,p,T=bn)=>{if(!e.supportsBufferedPlayback)return;const m=Math.max(0,d-Rt*4),E=Hi(c,m,d+T,p,Rt,n);a(E)},f=(c,d)=>{i=c,s=d},l=(c,d)=>!(i!==c||s!==d);return{reset(){t.reset(),o.reset(),r.clear(),De(n),i="",s=null,et()?.onBufferReset()},markExternallyDisplayed(c,d){f(c.split("|")[0]??c,d)},warmupTick(c){e.supportsBufferedPlayback&&u(c.queue,0,c.availablePaths,Math.max(pr,bn))},isWarmupReady(c,d=pr){if(!e.supportsBufferedPlayback)return!0;const{ready:p,total:T}=oo(t,c.queue,0,d,c.availablePaths,n);return T===0?!1:p/T>=ls},getBufferedFrameCount:()=>t.size(),tick(c){const d=et();d?.onBufferTick(),u(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-bn);const p=nr(c.queue,c.elapsedMs,c.availablePaths,n),T=sn(p.diffPath),m=Bt({mouthPath:p.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),E=()=>(f(T,c.expressionPath),d?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(T,c.expressionPath)||c.playbackState.lastDrawnKey===m)return E();const C=t.findForMouthKey(T,c.elapsedMs,Rt);return C&&c.expressionPath!=null?(d?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):C?(e.blitBitmap(c.canvas,C.bitmap),f(C.mouthKey,c.expressionPath),c.playbackState.lastDrawnKey=m,c.onStatus({diffPath:C.mouthPath,label:C.label}),c.onDisplayed(m,C.mouthPath,C.label),d?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(d?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const lo=`
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=da(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=()=>p||(T=new ca,p=new ls.PipecatClient({transport:new Hn.WebSocketTransport({mediaManager:T,serializer:new oa,recorderSampleRate:tr,playerSampleRate:nr}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{m=!0,e("idle"),W()},onDisconnected:()=>{m=!1,w()},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)}}}),p);return{setDeveloperToken:g=>{},setTtsEngineId:g=>{c=g,K.setStreamTtsEngineId(g)},getTtsEngineId:()=>c,speak:async(g,C)=>{const ne=g.trim();if(ne){if(!p||!m)throw new Error("Realtime voice is not connected. Call connect() first.");q(),await p.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=Oi({...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(),p)try{await p.disconnect()}catch(g){console.error("[realtimeVoice] disconnect failed:",g)}m=!1,w()},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 Vi(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function Ui(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 Wi(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 Rs(r,t)}async function zi(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 ma(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function ha(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 ga(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 wa(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function ya(e){const t=Bs();if(!Wt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Mt(t,e);return wa(n)}function kt(e,t){return`${e}/${t}_minus_sil.png`}const Hi=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:Hi}const va=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Vn=["t01_0.25","t02_0.50","t03_0.75"],_a=Vn.length,Rr=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 Dr(e,t){return`${e}__${t}`}function Br(e,t){return`pairs/${e}/${t}_minus_sil.png`}function xt(e){return`${e}_minus_sil.png`}function rr(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 $i(e,t){return e.filter(n=>t.has(n))}function ba(e,t,n){const r=ir(e,t);return $i(r,n).length>0}function ir(e,t){if(e===t)return[];const n=[],r=Dr(e,t);if(Rr.has(r)){for(const s of Vn)n.push(Br(r,s));return n}const i=Dr(t,e);if(Rr.has(i)){for(let s=_a-1;s>=0;s--)n.push(Br(i,Vn[s]));return n}return[]}function Sa(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function Ta(e,t){return Sa(t).map(r=>e[r]).filter(r=>r!=null)}function ka(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 ji(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 Ea=[.32,.24,.16,.08,0],xa=Ea.map(e=>`eyes_${e.toFixed(2)}`),Ia=["eyes_0.32","eyes_0.16","eyes_0.00"],Aa=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],ze=2,Ma=-20,an=16,Ki={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function Vt(e){return`brow_${e}`}function mt(e){return Ki[e]}function Qe(e){return Math.max(Ma,Math.min(an,e))}function Pa(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 Fr(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 Ca=["fear","anger","sad","neutral","love","happy","disgust"],Ra={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?Ra[n]??t:t}function Gi(e){return e===0?null:kt(Vt(e),"eyes_standard")}function qi(e){return Gi(mt(e))}const Da={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function sr(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 Fr(i)){if(a===i)continue;const u=kt(Vt(a),s);if(t(u))return u}const o=Da[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,...Fr(o)]){const u=kt(Vt(a),s);if(t(u))return u}}return null}function Lr(e,t){const n=Vt(mt(e));return!t||t==="eyes_standard"?qi(e):e==="neutral"&&t==="eyes_standard"?null:kt(n,t)}function Ba(e,t){const n=[];for(const r of t)n.push(Lr(e,r));for(let r=t.length-2;r>=0;r--)n.push(Lr(e,t[r]));return n.push(qi(e)),n}function Fa(e){return kt(Vt(e),"eyes_standard")}function La(e,t){return Pa(e,t).map(Fa)}const Oa=6;function Na(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Va(e){const t=Qe(e);return t>=an?an:Qe(t+Oa)}function Ua(e,t,n){const r=Qe(n);return Na(t,e)?.emphasis?Va(r):r}function Or(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 Nr(){return Ye(14,32)}function Wa(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 Vr(e,t){const n=Ye(e.holdMinMs,e.holdMaxMs);return t?n+e.closedExtraMs:n}function za(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,p=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:${p}`}function v(I,V=l){E=I;const G=Or(I);G!=null?p=G:I==null&&(p=0),B(V)}function k(I){return Gi(I)}function L(I,V,G){const ae=Qe(V),se=Qe(G);if(m=se,ae===se){v(k(se));return}const re=[...La(ae,se),k(se)];f={kind:"browBlend",paths:re,index:0,holdUntil:I+Nr(),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?Ia:Math.random()<a?xa:Aa,se=Wa(G),re=ae.length-1;f={kind:"playing",paths:Ba(V,ae),index:0,holdUntil:I+Vr(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+Nr();const V=f.paths[f.index]??null;v(V),I>=f.holdUntil&&f.index>=f.paths.length-1&&(p=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+Vr(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"?Or(E)??p:p;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,p=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,p=0,T=0,A(performance.now()+Ye(n,r),"neutral")}}}function Ha(){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 $a=50,Yi=400;function ja(e,t,n){return e.filter(r=>{const i=r.queueIndex??-1;return i>=t&&i<=n})}function Ka(e,t){const n=[];for(const r of e){const i=ja(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-$a),endMs:o.wtime+o.wduration+Yi})}return n.sort((r,i)=>r.startMs-i.startMs)}function Ga(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=Ka(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+Yi?Ze(t[t.length-1]?.emotion,i):i}function ar(e,t,n,r,i=Hi){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 p=0;p<u.data.length;p+=4){const T=m.data[p],f=m.data[p+1],E=m.data[p+2];Math.max(T,f,E)>i&&(u.data[p]=T,u.data[p+1]=f,u.data[p+2]=E,u.data[p+3]=255)}}return o.putImageData(u,0,0),s}let ut=null,It=null;const on=new Map;function qa(){ut=null,It=null,on.clear()}di(qa);function Ya(e){return e??It??void 0}function or(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 Qa(e){return Wt()?pa(await Mt(sn(),e??"")):or(sn())}async function Ur(e,t,n,r){const i=n?await zi(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 ha(await Mt(ji(t,s.path,n),r??"")):await or(`${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=Ya(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=fi();ut=(async()=>{const s=await Qa(t),o=await Ur(mi(),r,n,t);let a=null;try{a=await Ur(hi(),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 cr(e){if(await Un(e),!ut)throw new Error("Assets not loaded");return ut}function At(e){return Vi(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Xa(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=Ui(t.atlasMeta,o),u=At(e);if(Wi(o)){const c=Xa(t,o),m=document.createElement("canvas");m.width=u.width,m.height=u.height;const p=m.getContext("2d");return p.fillStyle="#000",p.fillRect(0,0,u.width,u.height),p.drawImage(c,a.x,a.y),m}const d=`${t.diffBase}/${n}`,l=await or(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:p,height:T}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const f=document.createElement("canvas");f.width=p,f.height=T;const E=f.getContext("2d");if(E.clearRect(0,0,p,T),E.drawImage(t,0,0,p,T),s&&!s())return;(e.width!==p||e.height!==T)&&(e.width=p,e.height=T);const D=e.getContext("2d");D.clearRect(0,0,p,T),D.drawImage(f,0,0);return}const o=await cr(),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 p=o.sil;c.drawImage(p,0,0,u,d);return}if(l.length===0){c.drawImage(t,0,0,u,d);return}const m=ar(t,l,u,d,a);c.drawImage(m,0,0)}async function Wn(e,t,n){const r=await cr(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=rr(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=sr(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=ar(r.sil,a,s,o,i);u.drawImage(d,0,0)}async function Ja(e,t){const n=await cr(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=rr(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=sr(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=ar(n.sil,o,i,s,r);return u.drawImage(d,0,0),a.transferToImageBitmap()}async function Za(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 eo(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function to(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 no={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},ro={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"},io={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function so({text:e,style:t}){return R.jsx("div",{style:no,"aria-live":"polite","aria-atomic":"true",children:R.jsx("div",{style:{...ro,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:R.jsx("p",{style:io,children:e})})})}const ao={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},oo={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},co={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function lo({thumbnailUrl:e}){const[t,n]=h.useState(!1);h.useEffect(()=>{n(!1)},[e]);const r=!!e&&t;return R.jsxs("div",{style:ao,"aria-hidden":!0,children:[e?R.jsx("img",{src:e,alt:"",style:{...oo,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,R.jsx("div",{style:{...co,background:r?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Qi=null;function Wr(e){Qi=e}function at(){return Qi}function uo(e){return`${e.from}→${e.to}@${e.fromVtime}`}function zr(){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 fo(){let e=zr();const t=new Set,n=new Set,r=new Set;let i="",s=-1,o="";const a=()=>{e=zr(),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=uo(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 p=l.transitionMeta;u(p.fromVtime),u(p.toVtime),d(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const m=l.label.trim();if(!(!m||m==="sil")){for(const p of c)if(p.viseme===m&&l.elapsedMs>=p.vtime&&l.elapsedMs<p.vtime+p.vduration){u(p.vtime);break}}},snapshot(l,c){let m=0,p=0;for(const B of l)if(B.viseme!=="sil"){if(B.vtime>=c)break;m+=1,t.has(B.vtime)&&(p+=1)}const T=m>0?Math.round(p/m*100):100,f=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),E=m-p,D=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:D,renderLoss:f,visemeSlotsTotal:m,visemeSlotsCovered:p,visemeCoveragePct:T,transitionFramesUniqueSampled:n.size,transitionFramesUniquePainted:r.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+f,visemesShown:p,visemesSkipped:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Xi=jn,mo=200,Hr=300,ho=100,go=600,Ji="__sil__";function $r(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===Ji:!1}function lr(){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=Mi(e);return t&&(t.transitionCache={queueLength:e.length,transitions:n}),n}function wo(e,t){let n="sil";for(const r of e)r.viseme!=="sil"&&(t!=null&&r.vtime>t||(n=r.viseme));return n}function yo(e,t,n,r=120){if(n!=="sil")return n;const i=Li(e,t,r);return i!=="sil"?i:wo(e,t)}function vo(e,t){return e==="sil"?!1:t?ba(e,"sil",t):ir(e,"sil").length>0}function _o(){return Xi+go}function ln(e){return e??Ji}function ur(e,t,n,r,i=ho){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=lt(e))return{diffPath:null,label:"sil"};const s=po(e,r),o=ta(s,t);if(o){const d=Pi(o.fromVtime,o.toVtime,o.from,o.to);if(t>=d.transStart&&t<d.transEnd){let l=ir(o.from,o.to);n&&(l=$i(l,n));const c=Ta(l,d.effectiveGapMs);if(c.length>0){const m=ka(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=Ei(a,t);return u==="sil"&&(u=Li(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 jr(e,t,n,r,i,s,o,a,u,d){const l=ur(t,n,u,s),c={mouthPath:l.diffPath,expressionPath:r},m=Ut(c,i),p=at();if(l.transitionMeta&&p?.onTransitionSample(l.transitionMeta,l.diffPath),m===s.lastDrawnKey){p?.onDrawDeduped();return}p?.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 Zi(e,t,n,r,i=Ot,s){if(n<=t||e.length===0)return[];const o=s??lr(),a=[];let u="";for(let d=t;d<n;d+=i){const l=ur(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 bo=3;function dr(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>=bo&&(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 So(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 To(){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 ko(e,t,n,r,i,s){const o=Zi(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 Eo(e){const t=To(),n=lr(),r=new Set;let i="",s=null;const o=So(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)}},vs),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,p,T=In)=>{if(!e.supportsBufferedPlayback)return;const f=Math.max(0,m-Ot*4),E=Zi(c,f,m+T,p,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(kr,In))},isWarmupReady(c,m=kr){if(!e.supportsBufferedPlayback)return!0;const{ready:p,total:T}=ko(t,c.queue,0,m,c.availablePaths,n);return T===0?!1:p/T>=ys},getBufferedFrameCount:()=>t.size(),tick(c){const m=at();m?.onBufferTick(),u(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-In);const p=ur(c.queue,c.elapsedMs,c.availablePaths,n),T=ln(p.diffPath),f=Ut({mouthPath:p.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 xo=`
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
- `,uo=`
33
+ `,Io=`
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 Vr(e=5){const t=new we.Filter({glProgram:we.GlProgram.from({vertex:lo,fragment:uo,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 fo(e,t,n){return e>n||t>n}function mo(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function ho(e,t){return t!=null&&t>0?Math.floor(t):mo(e)}function wo(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 ji(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 Ur(e,t,n,r,i){const s=n?await Di(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,d)=>{const p=Li(t,d,n),T=n?await Xs(await Et(p,i??"")):await ji(p);if(fo(T.width,T.height,r))return console.info(`[PixiVisemeCompositor] Sheet ${d} (${T.width}x${T.height}) exceeds MAX_TEXTURE_SIZE=${r}; using per-cell crops.`),{mode:"cells",bitmap:T};const m=we.Texture.from(T);return m.source.scaleMode="nearest",{mode:"full",texture:m}};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 f=new Map;for(const c of s.cells??[])c.path&&f.set(c.path,c);const l=new Map;for(const c of s.sheets??[])l.set(c.index,c);return{atlasMeta:s,cellByPath:f,sheetByIndex:l,diffBase:t,sheets:a}}async function po(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(v){throw n.destroy({removeView:!1}),v}if(n.renderer.type!==we.RendererType.WEBGL)throw n.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const r=ho(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 f=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),d=new we.Sprite(we.Texture.EMPTY),p=new we.Sprite(we.Texture.EMPTY);p.visible=!1;const T=Vr(5),m=Vr(5);c.filters=[T],d.filters=[m],n.stage.addChild(f),n.stage.addChild(l),n.stage.addChild(c),n.stage.addChild(d),n.stage.addChild(p);let E=null,C=null,P=null,_=null,x=null,N=null,A=null,ie=842,me=1264,I=null,V=5;const q=new Map;let se=null,J=null,Z=null;const O=ii(()=>{q.clear(),N=null,A=null,E=null,I=null}),le=(v,y)=>{ie=v,me=y,n.renderer.resize(v,y),(e.width!==v||e.height!==y)&&(e.width=v,e.height=y)},z=()=>{c.visible=!1,d.visible=!1,c.texture=we.Texture.EMPTY,d.texture=we.Texture.EMPTY,se=null,J=null},pe=()=>{x=null,l.visible=!1,l.alpha=0},L=()=>{f.visible=!0,f.width=ie,f.height=me,f.x=0,f.y=0},Q=()=>{l.width=ie,l.height=me,l.x=0,l.y=0},K=()=>{p.visible=!1,pe(),E&&(f.texture=E,L())},ae=()=>{!x&&!l.visible||K()},be=v=>{if(o||i||!E){K();return}const y=Math.max(0,v);if(!C||y<=0){K();return}z(),p.visible=!1,f.texture=C,L(),l.texture=E,Q(),l.alpha=0,l.visible=!0,x={startMs:performance.now(),durationMs:y},W()},te=(v=performance.now())=>{if(!x)return!1;if(o||i)return ae(),!1;const y=(v-x.startMs)/Math.max(1,x.durationMs);if(y>=1)return K(),W(),!1;const k=Math.min(1,Math.max(0,y)),b=k*k*(3-2*k);return l.alpha=b,l.visible=!0,W(),!0},S=()=>{if(P){try{P.resource=null}catch{}P.destroy(),P=null}C&&(C.destroy(!1),C=null),_=null},R=(v,y)=>{const k=v.cellByPath.get(y);if(!k||!Ci(k))return null;const b=`${v.diffBase}::${y}`;let $=q.get(b);if(!$){const G=k.sheet??0,X=v.sheets.get(G);if(!X)return null;let oe,Be=!1;if(X.mode==="full")oe=new we.Texture({source:X.texture.source,frame:new we.Rectangle(k.x,k.y,k.w,k.h)});else{const tt=wo(X.bitmap,k);oe=we.Texture.from(tt),oe.source.scaleMode="nearest",Be=!0}$={texture:oe,ownsSource:Be},q.set(b,$)}return{texture:$.texture,cell:k}},re=(v,y,k,b)=>{if(!b||!k)return v.visible=!1,v.texture=we.Texture.EMPTY,!1;const $=R(k,b);if(!$)return v.visible=!1,v.texture=we.Texture.EMPTY,!1;const G=Ri(k.atlasMeta,$.cell);return y.setThreshold(V),v.texture=$.texture,v.x=G.x,v.y=G.y,v.width=$.cell.w,v.height=$.cell.h,v.visible=!0,!0},ne=v=>{if(!v||!N)return null;const y=I??new Set(N.cellByPath.keys());return Yn(v,y)??(y.has(v)?v:null)},H=v=>{p.visible=!1,K();const y=ne(v.mouthPath),k=v.expressionPath&&A?Xn(v.expressionPath,b=>A.cellByPath.has(b)):null;y!==se?(re(c,T,N,y),se=y):y?c.visible=!0:c.visible=!1,k!==J?(re(d,m,A,k),J=k):k?d.visible=!0:d.visible=!1},W=()=>{if(!(o||i||document.hidden))try{n.render()}catch{}};return{async loadAssets(v){if(o)return{width:ie,height:me,visemePaths:[]};const y=Ft();if(y&&!v)throw new Error("Encrypted assets enabled but no key provided");const k=y?await Zs(await Et(en(),v??"")):await ji(en());E&&E.destroy(!0),E=we.Texture.from(k),E.source.scaleMode="linear";const b=si();N=await Ur(ai(),b,y,r,v);try{A=await Ur(oi(),b,y,r,v)}catch(G){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",G),A=null}const $=Pi(N.atlasMeta,k.width,k.height);return le($.width,$.height),V=hn(N.atlasMeta),T.setThreshold(V),m.setThreshold(V),I=new Set(N.cellByPath.keys()),q.clear(),K(),z(),W(),{width:$.width,height:$.height,visemePaths:[...N.cellByPath.keys()]}},getVisemeAtlasPaths(){return I},drawLiveFrame(v){o||i||!E||(ae(),H(v),W())},drawIdleVideo(v,y){o||i||document.hidden||y&&!y()||v.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(pe(),z(),p.visible=!1,!C||_!==v?(S(),P=new we.VideoSource({resource:v,autoPlay:!1,updateFPS:0}),P.autoUpdate=!1,C=new we.Texture({source:P}),_=v):C.source.update(),f.texture=C,L(),W())},beginIdleToSilCrossfade:be,tickIdleToSilCrossfade:te,finishIdleToSilCrossfade:ae,isIdleToSilCrossfading(){return x!=null},renderSilOnly(){o||i||!E||(z(),K(),W())},blitBitmap(v){o||i||(ae(),z(),Z&&(Z.destroy(!0),Z=null),Z=we.Texture.from(v),p.texture=Z,p.visible=!0,p.x=0,p.y=0,p.width=ie,p.height=me,f.visible=!1,W())},async compositePrefetchFrame(v){return null},renderFrame:W,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",u),O(),S(),Z&&(Z.destroy(!0),Z=null);for(const{texture:y,ownsSource:k}of q.values())y.destroy(k);q.clear(),E&&(E.destroy(!0),E=null);const v=y=>{y.mode==="full"?y.texture.destroy(!0):y.bitmap.close()};if(N)for(const y of N.sheets.values())v(y);if(A)for(const y of A.sheets.values())v(y);T.destroy(!0),m.destroy(!0),n.destroy({removeView:!1},{children:!0,texture:!0})}}}const Wr=-1,Xt=1e5,zr=new Map;async function go(e){let t=zr.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),zr.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function yo(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function Fn(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 $r(e,t){let n=0,r=null;const i=rr(async(s,o)=>(await Dn(),await Bn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await Dn(s);return r=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return r},async renderSilOnly(){n+=1,i.reset(),await Oa(e)},drawLiveFrame(s,o,a,u){i.enqueue(o,a,u)},async compositePrefetchFrame(s,o){try{return await La(s)}catch{return null}},blitBitmap(s,o){Fn(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 Bn(s,{mouthPath:Tt(o),expressionPath:null})},dispose(){n+=1,i.reset()}}}function _o(e,t,n){let r=null,i=1,s=0,o=!1,a=!1,u=null;const f=new Map,l=new Map;let c=Xt;const d=rr(async(P,_,x)=>(f.set(_,{drawKey:x.drawKey,onDisplayed:x.onDisplayed}),await E({type:"drawFrame",diffPath:P.mouthPath,expressionDiffPath:P.expressionPath,liveSeq:_},void 0,!0),!1)),p=P=>{if(P===Wr){let N=-1,A;for(const[ie,me]of f)ie>=N&&(N=ie,A=me);N>=0&&f.delete(N),A?.onDisplayed?.(A.drawKey);return}const _=-P,x=f.get(_);f.delete(_),x?.onDisplayed?.(x.drawKey)},T=new Map,m=(P,_)=>{a||!r||r.postMessage(P,[])},E=(P,_,x=!1)=>{if(a)return Promise.resolve();const N=i++;return new Promise((A,ie)=>{T.set(N,{resolve:me=>A(me),reject:ie,generation:typeof P.generation=="number"?P.generation:void 0,expectRenderDone:x}),m({...P,requestId:N})})},C=(async()=>{r=await go(n),r.onmessage=P=>{if(a)return;const _=P.data;if(_.type==="status"){t.onStatus?.(_.label);return}if(_.type==="frame"){if(_.generation<=-Xt){const A=-_.generation,ie=l.get(A);l.delete(A),ie?.resolve(_.bitmap);return}const N=_.generation<0;if(!N&&_.generation!==s){_.bitmap.close();return}if(N&&!(_.generation===Wr)){const ie=-_.generation;if(!d.isLatestSeq(ie)){et()?.onWorkerStale(),_.bitmap.close();return}}if(N&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){et()?.onWorkerStale(),_.bitmap.close();return}Fn(e,_.bitmap),_.bitmap.close(),N&&p(_.generation);return}const x=T.get(_.requestId);if(x)switch(_.type){case"ready":T.delete(_.requestId),x.resolve();break;case"loadAssetsDone":T.delete(_.requestId),u=_.visemePaths?.length?new Set(_.visemePaths):null,x.resolve({width:_.width,height:_.height,visemePaths:_.visemePaths});break;case"renderDone":if(x.expectRenderDone&&x.generation!=null&&_.generation!==x.generation)return;T.delete(_.requestId),x.resolve();break;case"renderAborted":T.delete(_.requestId),x.resolve();break;case"error":T.delete(_.requestId),t.onError?.(_.message),x.reject(new Error(_.message));break}},r.onerror=P=>{if(a)return;const _=P.message||"Worker error";t.onError?.(_);for(const[,x]of T)x.reject(new Error(_));T.clear()},await E({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(P){if(a)return{width:842,height:1264};if(await C,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await E({type:"loadAssets",keyHex:P,urls:Ts(dt())})??{width:842,height:1264}},getVisemeAtlasPaths(){return u},async renderSilOnly(){if(a||(await C,a))return;s+=1,d.reset(),f.clear(),l.forEach(({resolve:_})=>_(null)),l.clear(),c=Xt;const P=s;await E({type:"cancelLiveDraws"}),await E({type:"renderSil",generation:P},void 0,!0)},drawLiveFrame(P,_,x,N){a||C.then(()=>{a||d.enqueue(_,x,N)})},compositePrefetchFrame(P,_){return a?Promise.resolve(null):C.then(()=>{if(a)return null;const x=++c;return new Promise(N=>{l.set(x,{resolve:N}),E({type:"drawFrame",diffPath:P.mouthPath,expressionDiffPath:P.expressionPath,liveSeq:x},void 0,!0).catch(()=>{l.delete(x),N(null)})})})},blitBitmap(P,_){Fn(P,_)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(P,_,x={}){if(a||(await C,a))return;s+=1,d.reset(),f.clear();const N=s;try{await E({type:"cancelLiveDraws"}),await E({type:"renderViseme",generation:N,to:_,from:x.from,transitionDurationMs:x.transitionDurationMs,gapMs:x.gapMs,threshold:x.threshold},void 0,!0)}catch(A){if(A?.name==="AbortError")return;throw A}},dispose(){if(!a){a=!0,s+=1,d.reset(),f.clear(),l.forEach(({resolve:P})=>P(null)),l.clear(),c=Xt;for(const[,P]of T)P.resolve();T.clear(),r?.terminate(),r=null}}}}async function vo(e,t){const n=await po(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let r=0,i=null,s=!1;const o=rr(async(a,u)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(et()?.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,f,l){s||o.enqueue(u,f,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 f=r;o.reset(),t.onStatus?.(u),n.drawLiveFrame({mouthPath:Tt(u),expressionPath:null})},dispose(){s||(s=!0,r+=1,o.reset(),n.dispose())}}}function Hr(e,t){if(!yo())return $r(e,t);const n=as(t.workerScriptUrl);try{return _o(e,t,n)}catch{return $r(e,t)}}function So(e,t={}){if(t.preferLegacyRenderer)return Hr(e,t);let n=null,r=!1,i=null,s=!1;const o=()=>n?Promise.resolve(n):(i||(i=(async()=>{try{const a=await vo(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=Hr(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,f,l){o().then(c=>{s||c.drawLiveFrame(a,u,f,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,f){return(await o()).renderViseme(a,u,f)},dispose(){s=!0,i=null,n?.dispose(),n=null}}}class bo extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function En(e,t,n){return new Promise((r,i)=>{const s=globalThis.setTimeout(()=>{i(new bo(n,t))},t);e.then(o=>{globalThis.clearTimeout(s),r(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const To={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},ko={display:"block",maxWidth:"100%",height:"auto"},xo={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 Pt(e){return fs(e)?Kn:Zr(e)?on:jn}function Qe(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const Ki=h.forwardRef(function({id:t,avatarId:n,faceId:r,assets:i,authToken:s,apiBase:o,ttsEngineId:a=at,voiceId:u,speakingRate:f=Ot,className:l,style:c,canvasStyle:d,onStatusChange:p,onDisplayStatus:T,onError:m,onReady:E,showErrorOverlay:C=!0,loadingThumbnailUrl:P,onUserTranscript:_,onBotOutput:x,onRealtimeLipsyncDebug:N,onFrameRenderStats:A,lipsyncBufferedPlayback:ie=!0,lipsyncPlaybackWarmupMs:me=1500,idleHandoffHoldMs:I=Qa,pixiMaxTextureSize:V,captions:q},se){const J=h.useRef(null),Z=h.useRef(null),O=h.useRef(null),le=h.useRef(ie);le.current=ie;const z=h.useRef(me);z.current=me;const pe=h.useRef(I);pe.current=I;const L=h.useRef(0),Q=h.useRef(tr()),K=h.useRef(Ea()),ae=h.useRef(!1),be=h.useRef(null),te=h.useRef(null),S=h.useRef(0),R=h.useRef(0),re=h.useRef(0),ne=h.useRef(null),H=h.useRef(null),W=h.useRef(!1),v=h.useRef(!1),y=h.useRef(!1),k=h.useRef(!1),b=h.useRef("sil"),$=h.useRef(0),G=h.useRef(!1),X=h.useRef(null),oe=h.useRef(!1),[Be,tt]=h.useState("idle"),[Nt,It]=h.useState(null),[nt,wn]=h.useState(!1),[ir,w]=h.useState(!1),[B,ee]=h.useState(!1),[ue,Te]=h.useState(),[ve,ke]=h.useState({width:842,height:1264}),[Oe,Ne]=h.useState(null),[pn,Vt]=h.useState(0),Ge=h.useRef(!1),We=h.useRef(s??null),Ye=o?.trim()||ct,mt=h.useRef(null),ye=h.useRef(null),Ve=h.useRef(!1),rt=h.useRef({width:842,height:1264}),ze=h.useRef(null),Se=h.useRef("sil"),Ie=h.useRef(""),xe=h.useMemo(()=>Va(q),[q]),Pe=h.useCallback(()=>{Ie.current="",Ne(null)},[]);h.useEffect(()=>{xe.enabled||Pe()},[xe.enabled,Pe]);const ht=h.useCallback(g=>{if(!xe.enabled)return;const D=g.isSpeaking(),U=g.isWarmingUp();if(!D||U){Ie.current&&Pe();return}const F=Na(g.getWordQueue());if(!F){Ie.current&&Pe();return}F!==Ie.current&&(Ie.current=F,Ne(F))},[xe.enabled,Pe]),wt=h.useRef(void 0),pt=h.useRef(new Map),Ut=h.useRef(E),sr=h.useRef(p),ge=h.useRef(T),ar=h.useRef(m),or=h.useRef(_),cr=h.useRef(x),Wt=h.useRef(N),lr=h.useRef(A),gt=h.useRef(Ya());Ut.current=E,sr.current=p,ge.current=T,ar.current=m,or.current=_,cr.current=x,Wt.current=N,lr.current=A,h.useEffect(()=>{const g=gt.current;return Br(g),()=>Br(null)},[]);const ur=h.useCallback(g=>{const D=g?.ttsEngineId??a??ye.current?.ttsEngineId??at,U=g?.voiceId??u??ye.current?.voiceId??Pt(D);return{ttsEngineId:D,voiceId:U}},[a,u]),Je=h.useCallback(g=>{It(g),ee(!0),ar.current?.(g)},[]),At=h.useCallback(g=>{tt(g),sr.current?.(g)},[]),fe=h.useRef(Rn(At,Ye,{onLipsyncDebug:g=>Wt.current?.(g)})),de=h.useRef(null),fr=h.useRef(()=>{});h.useEffect(()=>(fe.current=Rn(At,Ye,{onLipsyncDebug:g=>Wt.current?.(g)}),s&&fe.current.setDeveloperToken(s),fe.current.setTtsEngineId(a),()=>{fe.current.stop();const g=de.current;g&&(g.disconnect(),de.current=null)}),[At,Ye]);const dr=h.useCallback(()=>(de.current||(de.current=Mi(At,{speakingRate:f,onUserTranscript:(g,D)=>or.current?.(g,D),onBotOutput:g=>cr.current?.(g),onLipsyncDebug:g=>Wt.current?.(g)}),de.current.setTtsEngineId(a),fr.current(!0)),de.current),[At,f,a]),Re=h.useCallback(()=>{ne.current!=null&&(clearTimeout(ne.current),ne.current=null)},[]),Ce=h.useCallback(()=>{H.current!=null&&(clearTimeout(H.current),H.current=null),y.current=!1},[]),zt=h.useCallback(()=>{if(k.current)return;const g=Z.current;if(k.current=!0,Ce(),W.current=!1,v.current=!1,!oe.current||!X.current){g?.renderSilOnly();return}X.current.setActive(!1);const D=X.current.getVideo();if(g?.usesPixi){g.drawIdleVideo(D),g.beginIdleToSilCrossfade(Lr);return}(async()=>{const U=J.current;U&&await kn(U,D,null,void 0,rt.current).catch(()=>{}),await new Promise(F=>setTimeout(F,Lr)),k.current&&await g?.renderSilOnly()})()},[Ce]),mr=h.useCallback(()=>{!oe.current||!X.current||(k.current=!1,Z.current?.finishIdleToSilCrossfade(),Ce(),y.current=!0,H.current=setTimeout(()=>{if(H.current=null,Qe(fe.current,de.current).isSpeaking()){y.current=!1;return}if(W.current){y.current=!1;return}const g=X.current;if(!g){y.current=!1;return}g.restart(),g.setActive(!0);const D=g.getVideo();let U=!1;const F=()=>{U||(U=!0,D.removeEventListener("playing",j),y.current=!1)},j=()=>{F()};if(D.addEventListener("playing",j,{once:!0}),D.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!D.paused){F();return}setTimeout(F,300)},pe.current))},[Ce]),yt=h.useCallback(()=>{if(Re(),ge.current?.("sil"),W.current=!1,k.current=!1,!oe.current||!X.current){y.current=!1;return}mr()},[Re,mr]),gn=h.useCallback(async g=>{const D=R.current,U=Z.current,F=J.current,j=()=>{g?.fallbackOnly||(W.current=!1)};if(!U||!F||!nt){j();return}if(Qe(fe.current,de.current).isSpeaking()){j();return}if(g?.fallbackOnly){if(!W.current||(De(Q.current),await U.renderSilOnly(),D!==R.current)||Qe(fe.current,de.current).isSpeaking())return;yt();return}if(Or(Q.current)){De(Q.current),yt();return}if(le.current&&U.supportsBufferedPlayback&&!g?.fallbackOnly){if(De(Q.current),O.current?.reset(),await U.renderSilOnly(),D!==R.current||Qe(fe.current,de.current).isSpeaking())return;yt();return}const Ae=to(Qe(fe.current,de.current).getVisemeQueue(),$.current,b.current),Fe=no(Ae,ze.current);if(De(Q.current),!Fe){if(await U.renderSilOnly(),D!==R.current||Qe(fe.current,de.current).isSpeaking())return;yt();return}try{await U.renderViseme(F,"sil",{from:Ae,transitionDurationMs:zi})}catch(Me){if(Me?.name!=="AbortError")throw Me}if(D!==R.current){j();return}if(Qe(fe.current,de.current).isSpeaking()){j();return}yt()},[nt,yt]),_t=h.useCallback(()=>{if(v.current||W.current)return;v.current=!0,W.current=!0,Re();const g=R.current;gn().finally(()=>{v.current=!1}),ne.current=setTimeout(()=>{ne.current=null,g===R.current&&gn({fallbackOnly:!0})},ro())},[Re,gn]),hr=h.useCallback(async()=>{const g=Math.floor(Date.now()/1e3);if(mt.current&&g<mt.current.expiresAt-60)return mt.current.key;const D=We.current??await Ct();We.current=D,fe.current.setDeveloperToken(D);const U=await _s(D,Ye);return mt.current={key:U.value,expiresAt:U.expiresAt},U.value},[Ye]);h.useEffect(()=>{s&&(We.current=s,fe.current.setDeveloperToken(s))},[s]),h.useEffect(()=>{fe.current.setTtsEngineId(a),de.current?.setTtsEngineId(a),ye.current&&(ye.current.ttsEngineId=a)},[a]),h.useEffect(()=>{const g=u??Pt(a);ye.current&&(ye.current.voiceId=g)},[u,a]);const $e=h.useMemo(()=>ni(n,r),[n,r]),Xi=h.useMemo(()=>i?JSON.stringify(i):$e?`face:${$e}`:`id:${t??""}`,[i,$e,t]),Ji=h.useMemo(()=>{const g=P?.trim();return g||(yr($e)??yr(ue)??ms(i))},[P,$e,ue,i]);return h.useEffect(()=>{if(!t&&!i&&!$e){Je("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let g=!1;Ve.current=!1,wn(!1),w(!1),ee(!1),Te($e),It(null),ye.current=null,X.current=null,oe.current=!1;const D=J.current;if(!D)return;let U=null;return(async()=>{try{let F,j,_e,Ae;if(i)F=i,j=a,_e=u??Pt(j);else if($e)ge.current?.("loadFace"),F=Mn($e),j=a,_e=u??Pt(j);else{ge.current?.("getAiTwin");const Y=await En(ei(t),3e4,"getAiTwin");if(g)return;if(!Y.faceId?.trim())throw new Error("getAiTwin returned no faceId");Te(Y.faceId.trim()),j=Y.ttsEngineId,_e=u??Y.voiceId??Pt(j),Ae=Y.knowledgeContextId?.trim()||void 0,F=Mn(Y.faceId)}ye.current={ttsEngineId:j,voiceId:_e,personaId:Ae},ri(F),X.current=Ia();const Fe=!!(i&&!ft(i));U=So(D,{preferLegacyRenderer:Fe,pixiMaxTextureSize:V,onStatus:Y=>{g||ge.current?.(Y)},onError:Y=>{g||Je(Y)},shouldAcceptLiveFrame:()=>{if(ae.current)return!0;if(W.current)return!1;const Y=Qe(fe.current,de.current);return Y.isSpeaking()||Y.isWarmingUp()},onWebGlContextLost:()=>{g||Ge.current||(Ge.current=!0,queueMicrotask(()=>{g||Vt(Y=>Y+1)}))}}),Z.current=U,O.current=co(U),Ge.current=!1;const Me=Y=>{const ce=()=>{if(!Y||z.current<=0)return!1;const Ee=Z.current;return Ee?le.current&&Ee.supportsBufferedPlayback?!0:Ee.usesPixi:!1};fe.current.setLipsyncWarmupHold(Y,ce),de.current?.setLipsyncWarmupHold(Y,ce)};fr.current=Me,Me(!0),ge.current?.("auth");const He=We.current??s??await En(Ct(),3e4,"getAuthToken");if(g)return;We.current=He,fe.current.setDeveloperToken(He),fe.current.setTtsEngineId(j);const $t=Ft()?await hr():void 0;if(g)return;ge.current?.("loadAssets");const he=await En(U.loadAssets($t),18e4,"load face assets");if(!g&&he.width>0&&he.height>0&&(rt.current=he,ke(he)),g)return;ze.current=U.getVisemeAtlasPaths(),Ve.current=!0,wn(!0),Ut.current?.(),U.renderSilOnly().then(()=>{g||ge.current?.("sil")}),(async()=>{try{const Y=await na($t);if(await X.current.load(Y),g)return;oe.current=!0,w(!0),De(Q.current),X.current.setActive(!0);const ce=X.current.getVideo();U.usesPixi?U.drawIdleVideo(ce):await kn(D,ce,null,void 0,rt.current)}catch(Y){if(g)return;oe.current=!1,w(!1),console.warn("[AiTwin] Idle video unavailable:",Y)}finally{g||(ee(!0),ge.current?.("idle"))}})()}catch(F){if(g)return;if(F instanceof Jt){Je(F.message);return}Je(F instanceof Error?F.message:"Failed to load AI twin")}})(),()=>{g=!0,X.current?.dispose(),U?.dispose(),Z.current=null}},[Xi,i,$e,t,a,u,s,V,hr,Je,pn]),h.useEffect(()=>{const g={current:!1},D=()=>{const U=J.current,F=Z.current,j=Qe(fe.current,de.current);if(!U||!F||!nt){S.current=requestAnimationFrame(D);return}if(document.hidden){X.current?.setActive(!1),S.current=requestAnimationFrame(D);return}const _e=j.isSpeaking(),Ae=j.isWarmingUp(),Fe=_e&&!G.current,Me=G.current&&!_e;Fe&&(Re(),Ce(),W.current=!1,v.current=!1,De(Q.current),O.current?.reset(),gt.current.reset(),wt.current=void 0,re.current=0,b.current="sil",$.current=0,zt()),Me&&(K.current.reset(),X.current?.setActive(!1),O.current?.reset(),F.finishIdleToSilCrossfade(),Pe(),_t());const He=Me||W.current||y.current||k.current,$t=ie&&F.supportsBufferedPlayback;if(Ae){if(zt(),oe.current&&X.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()){F.tickIdleToSilCrossfade(performance.now()),j.getVisemeQueue().length>0&&L.current===0&&(L.current=performance.now()),G.current=j.isSpeaking(),S.current=requestAnimationFrame(D);return}const he=j.getVisemeQueue();he.length>0&&L.current===0&&(L.current=performance.now()),K.current.advance(performance.now());const Y=K.current.getExpressionPath(),ce=K.current.getDrawKey(),Ee={queue:he,elapsedMs:0,expressionPath:Y,expressionDrawKey:ce,availablePaths:ze.current};let Le=!1;$t&&O.current?(O.current.warmupTick(Ee),Le=O.current.isWarmupReady(Ee,z.current)):F.usesPixi&&Nr(U,he,0,Y,ce,Q.current,(vt,Ht,yn,jt)=>{F.drawLiveFrame(vt,Ht,yn,je=>{jt?.(je),j.isWarmingUp()&&je!==""&&!Or({lastDrawnKey:je})&&(L.current=0,j.releaseWarmupHold())})},vt=>{ge.current?.(vt.label)},ze.current);const Ze=L.current>0&&performance.now()-L.current>cs;ge.current?.(Le?"buffer ready":"buffering lipsync…"),(Le||Ze)&&(L.current=0,j.releaseWarmupHold()),ht(j),G.current=j.isSpeaking(),S.current=requestAnimationFrame(D);return}if(_e){zt(),oe.current&&X.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()&&F.finishIdleToSilCrossfade();const he=j.getVisemeQueue(),Y=j.getPlaybackElapsedMs();$s(he,Y),$.current=Y;const ce=he.length>0?Lt(he,Y):"sil";ce!=="sil"&&(b.current=ce);const Ee=Ra(Y,j.getSentenceEmotions(),j.getWordQueue(),j.getStreamMood());K.current.setTargetEmotion(Ee),K.current.setTargetEyebrow(ka(Y,j.getWordQueue(),ot(Ee))),K.current.advance(performance.now());const Le=K.current.getExpressionPath(),Ze=K.current.getDrawKey(),vt=(je,_n,Mt,vn)=>{const wr={label:Se.current,elapsedMs:Y,mouthPath:_n.mouthPath,transitionMeta:wt.current};pt.current.set(Mt,wr),O.current?.markExternallyDisplayed(Mt,Le),F.drawLiveFrame(je,_n,Mt,Kt=>{const Zi=pt.current.get(Kt)??wr;pt.current.delete(Kt),gt.current.onDrawDisplayed(Zi,he),O.current?.markExternallyDisplayed(Kt,Le),vn?.(Kt)})},Ht=je=>{Se.current=je.label,wt.current=je.transitionMeta,ge.current?.(je.label)},yn=ie&&F.supportsBufferedPlayback;let jt=!1;yn&&O.current&&(jt=O.current.tick({canvas:U,queue:he,elapsedMs:Y,expressionPath:Le,expressionDrawKey:Ze,playbackState:Q.current,availablePaths:ze.current,onStatus:Ht,onDisplayed:(_n,Mt,vn)=>{gt.current.onDrawDisplayed({label:vn,elapsedMs:Y,mouthPath:Mt,transitionMeta:wt.current},he)}}).usedBuffer),jt||Nr(U,he,Y,Le,Ze,Q.current,vt,Ht,ze.current),gt.current.onRafTickSpeaking(),lr.current?.(gt.current.snapshot(he,Y))}else if(!He&&ae.current){X.current?.setActive(!1),K.current.advance(performance.now());const he=K.current.getExpressionPath(),Y=K.current.getDrawKey();xn(U,he,Y,Q.current,(ce,Ee,Le,Ze)=>F.drawLiveFrame(ce,Ee,Le,Ze),ce=>{if(te.current){ge.current?.(te.current);return}const Ee=K.current.getTargetEmotion();ge.current?.(ce==="sil"||ce==="blink"?`${Ee}${ce==="blink"?" · blink":""}`:ce)},null,be.current)}else if(!He&&oe.current&&X.current){const he=X.current,Y=he.getVideo();if(Y.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){he.setActive(!0);const ce=()=>!j.isSpeaking()&&!W.current&&!y.current&&!ae.current;F.usesPixi?(F.drawIdleVideo(Y,ce),ce()&&ge.current?.("idle")):g.current||(g.current=!0,kn(U,Y,null,void 0,rt.current,ce).then(()=>ge.current?.("idle")).finally(()=>{g.current=!1}))}else xn(U,null,"__sil__",Q.current,(ce,Ee,Le,Ze)=>F.drawLiveFrame(ce,Ee,Le,Ze),ce=>ge.current?.(ce))}else He||xn(U,null,"__sil__",Q.current,(he,Y,ce,Ee)=>F.drawLiveFrame(he,Y,ce,Ee),he=>ge.current?.(he));xe.enabled&&ht(j),G.current=_e,S.current=requestAnimationFrame(D)};return S.current=requestAnimationFrame(D),()=>{cancelAnimationFrame(S.current),Re(),Ce(),fe.current.stop(),de.current?.stop()}},[nt,ir,_t,Re,Ce,zt,ht,Pe,xe.enabled]),h.useImperativeHandle(se,()=>({speakText:async(g,D)=>{const U=g.trim();if(!U)return;const F=Z.current;if(!F||!Ve.current&&!nt)throw new Error("AI twin is not ready");const{ttsEngineId:j,voiceId:_e}=ur(D);It(null),Pe(),R.current+=1,Re(),Ce(),W.current=!1,v.current=!1,b.current="sil",$.current=0,De(Q.current),ae.current=!1,be.current=null,te.current=null,K.current.reset(),G.current=!1,k.current=!1,F.finishIdleToSilCrossfade();try{await fe.current.speak(U,{voiceId:_e,speakingRate:D?.speakingRate??f,ttsEngineId:j})}catch(Ae){throw k.current=!1,F.finishIdleToSilCrossfade(),_t(),Je(Ae instanceof Error?Ae.message:"TTS failed"),Ae}},stop:()=>{R.current+=1,Re(),Ce(),W.current=!1,v.current=!1,k.current=!1,Z.current?.finishIdleToSilCrossfade(),fe.current.stop(),de.current?.stop(),De(Q.current),O.current?.reset(),L.current=0,G.current=!1,Pe(),_t()},setTtsEngineId:g=>{fe.current.setTtsEngineId(g),de.current?.setTtsEngineId(g),ye.current&&(ye.current.ttsEngineId=g)},renderViseme:async(g,D)=>{const U=Z.current,F=J.current;if(!U||!F||!Ve.current)throw new Error("AI twin is not ready");await U.renderViseme(F,g,{from:D?.from,transitionDurationMs:D?.transitionDurationMs,gapMs:D?.gapMs,onStatus:j=>ge.current?.(j)})},setEmotion:g=>{if(!Ve.current)throw new Error("AI twin is not ready");const D=Z.current,U=J.current;if(!D||!U)throw new Error("AI twin is not ready");R.current+=1,Re(),Ce(),W.current=!1,v.current=!1,y.current=!1,k.current=!1,fe.current.stop(),de.current?.stop(),De(Q.current),O.current?.reset(),L.current=0,G.current=!1,D.finishIdleToSilCrossfade(),X.current?.setActive(!1);const F=Xe(g);ae.current=!0,be.current=null,te.current=null,K.current.snapToEmotion(F);const j=K.current.getExpressionPath(),_e=K.current.getDrawKey(),Ae={mouthPath:null,expressionPath:j},Fe=Bt(Ae,_e);Q.current.lastDrawnKey="",D.drawLiveFrame(U,Ae,Fe,He=>{He===Fe&&(Q.current.lastDrawnKey=Fe)});const Me=ot(F);ge.current?.(j?`${F} · brow ${Me>0?"+":""}${Me}`:`${F} · brow 0 (sil base)`)},getEmotion:()=>ae.current?K.current.getTargetEmotion():null,clearEmotionPreview:()=>{ae.current=!1,be.current=null,te.current=null,K.current.reset(),De(Q.current),ge.current?.("idle")},setViseme:g=>{if(!Ve.current)throw new Error("AI twin is not ready");const D=Z.current,U=J.current;if(!D||!U)throw new Error("AI twin is not ready");R.current+=1,Re(),Ce(),W.current=!1,v.current=!1,y.current=!1,k.current=!1,fe.current.stop(),de.current?.stop(),De(Q.current),O.current?.reset(),L.current=0,G.current=!1,D.finishIdleToSilCrossfade(),X.current?.setActive(!1);const F=cn(g);ae.current=!0,te.current=F,be.current=F==="sil"?null:Tt(F),K.current.snapToEmotion("neutral");const j=K.current.getExpressionPath(),_e=K.current.getDrawKey(),Fe={mouthPath:be.current,expressionPath:j},Me=Bt(Fe,_e);Q.current.lastDrawnKey="",D.drawLiveFrame(U,Fe,Me,He=>{He===Me&&(Q.current.lastDrawnKey=Me)}),ge.current?.(F)},getViseme:()=>ae.current?te.current:null,isReady:()=>Ve.current,getStatus:()=>Be,connect:async(g={})=>{It(null);try{let D=g.authToken?.trim();D||(D=We.current??s??await Ct(),We.current=D);const U=g.voiceId?.trim()??u??ye.current?.voiceId,F=g.personaId?.trim()??ye.current?.personaId,j=g.ttsEngineId??a??ye.current?.ttsEngineId,_e=dr();j&&_e.setTtsEngineId(j),await _e.unlockAudio(),await _e.connect({...g,apiBase:g.apiBase?.trim()||Ye,authToken:D,voiceId:U,personaId:F,ttsEngineId:j,speakingRate:g.speakingRate??f})}catch(D){throw Je(D instanceof Error?D.message:"Voice connect failed"),D}},disconnect:async()=>{const g=de.current;g&&(R.current+=1,Re(),Ce(),W.current=!1,v.current=!1,k.current=!1,Z.current?.finishIdleToSilCrossfade(),De(Q.current),O.current?.reset(),L.current=0,G.current=!1,await g.disconnect(),_t())},isConnected:()=>de.current?.isConnected()??!1,getVoiceStream:()=>de.current?.getVoiceStream()??fe.current?.getVoiceStream()??null,setMuted:g=>{const D=fe.current,U=de.current;D?.setMuted?.(g),U?.setMuted?.(g)},isMuted:()=>{const g=de.current,D=fe.current;return g?.isMuted?.()??D?.isMuted?.()??!1},getPersonaId:()=>ye.current?.personaId?.trim()||null}),[nt,f,s,u,Re,Ce,_t,Je,ur,dr,Be,Ye]),M.jsxs("div",{className:l,style:{...To,...c},children:[M.jsx("canvas",{ref:J,width:ve.width,height:ve.height,style:{...ko,...d},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!B&&!Nt?M.jsx(qa,{thumbnailUrl:Ji}):null,C&&Nt?M.jsx("div",{style:xo,children:Nt}):null,xe.enabled&&Oe?M.jsx($a,{text:Oe,style:xe.style},Oe):null]})});async function Eo(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 qi(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()||ct).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??[],persona_id:e.personaId?.trim()||""})});if(!i.ok)throw new Error(await Eo(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",u="",f="",l="";for(;;){const{done:c,value:d}=await s.read();if(c)break;a+=o.decode(d,{stream:!0});const p=a.split(`
48
- `);a=p.pop()||"";for(const T of p){if(T.startsWith("event: ")){l=T.slice(7).trim();continue}if(!T.startsWith("data: "))continue;const m=T.slice(6).trim();if(!m)continue;let E;try{E=JSON.parse(m)}catch{continue}if(l==="spokenText")u=E.text||"",e.onSpokenText?.(u);else if(l==="displayText")f=E.text||"";else if(l==="error")throw new Error(E.error||"avatarReply stream error")}}if(!u.trim()||!f.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:f.trim(),spokenText:u.trim()}}function Io({muted:e}){return e?M.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[M.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),M.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):M.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[M.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),M.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 Ao(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:M.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function Mo(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:M.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Po(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:M.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 Gi({className:e}){return M.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:M.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:M.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function Ro({muted:e,onToggle:t}){return M.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:M.jsx(Io,{muted:e})})}function Co(){return M.jsxs("div",{className:"aitwin-widget__connecting",role:"status","aria-live":"polite",children:[M.jsx(Gi,{className:"aitwin-widget__spinner aitwin-widget__spinner--accent"}),M.jsx("span",{children:"Connecting..."})]})}function Do(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 M.jsxs("div",{className:"aitwin-widget__controls",children:[M.jsxs("div",{className:"aitwin-widget__actions",children:[M.jsxs("button",{type:"button",className:r,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,children:[e.connecting?M.jsx(Gi,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?M.jsx(Mo,{}):M.jsx(Ao,{}),M.jsx("span",{children:n})]}),M.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:[M.jsx(Po,{}),M.jsx("span",{children:"Text"})]})]}),e.textMode?M.jsxs("form",{className:"aitwin-widget__composer",onSubmit:i=>{i.preventDefault(),e.onSendText()},children:[M.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}),M.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?M.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const jr=97,Bo=3500;function Fo(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/Bo);return Math.min(jr,Math.round(r*jr))}function Lo(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:Fo(r-t):100}const Oo="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 No({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:n=2600,delayMs:r=0,loop:i=!1}){return M.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:M.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:Oo,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function Vo({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return M.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:M.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[M.jsx(No,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),M.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[M.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:M.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),M.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function Kr(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}}function Uo(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const qr={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},Wo={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},zo=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(()=>Kr(t)),[f,l]=h.useState(!1),[c,d]=h.useState(!1),[p,T]=h.useState(!1),[m,E]=h.useState(!1),[C,P]=h.useState("idle"),[_,x]=h.useState(null),[N,A]=h.useState(!1),[ie,me]=h.useState(!1),[I,V]=h.useState(""),[q,se]=h.useState(!1),[J,Z]=h.useState([]),[O,le]=h.useState(t.personaId?.trim()||void 0),z=h.useCallback(b=>{i.current={...i.current,...b},b.showControls!==void 0&&o(!!b.showControls),b.personaId!==void 0&&le(b.personaId.trim()||void 0),u($=>Kr({id:b.id??$.id,faceId:b.faceId??b.avatarId??$.faceId,authToken:b.authToken??$.authToken,apiBase:b.apiBase??$.apiBase,voiceId:b.voiceId??$.voiceId,speakingRate:b.speakingRate??$.speakingRate}))},[]);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.personaId]);const pe=h.useCallback(()=>{l(!0),x(null)},[]),L=h.useCallback(b=>{b==="idle"&&d(!0)},[]),Q=h.useCallback(b=>{P(b),i.current.onStatusChange?.(b)},[]),K=h.useCallback(b=>{x(b),l(!1),d(!1),E(!1),i.current.onError?.(b)},[]),ae=h.useCallback((b,$)=>{i.current.onUserTranscript?.(b,$)},[]),be=h.useCallback(b=>{i.current.onBotOutput?.(b)},[]);h.useEffect(()=>{if(!s)return;const b=window.setInterval(()=>{T(!!r.current?.isConnected())},400);return()=>window.clearInterval(b)},[s,a]);const te=Uo(a),S=!!(a.id||a.faceId),R=f&&c,re=S&&!R&&!_,ne=Lo(re),H=h.useRef(te);h.useEffect(()=>{R&&i.current.onReady?.()},[R]),h.useEffect(()=>{R&&r.current?.setMuted(N)},[R,N,a]),h.useEffect(()=>{Z([])},[a.id,a.faceId]),h.useEffect(()=>{H.current!==te&&(H.current=te,l(!1),d(!1),x(null),E(!1),T(!1),P("idle"))},[te]);const W=()=>{const b=r.current;if(!b?.isReady())return;if(x(null),me(!1),b.isConnected()){E(!1),b.disconnect().finally(()=>{T(!1)});return}E(!0);const $={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,apiBase:a.apiBase};b.connect($).then(()=>{T(!!b.isConnected())}).catch(G=>{const X=G instanceof Error?G.message:"Failed to connect voice.";x(X),i.current.onError?.(X)}).finally(()=>{E(!1)})},v=()=>{me(b=>!b),x(null)},y=()=>{const b=I.trim(),$=r.current;!b||!$?.isReady()||q||(x(null),V(""),se(!0),i.current.onUserTranscript?.(b,!0),(async()=>{try{const G=a.authToken?.trim()||await Ct(),X=O||$.getPersonaId()?.trim()||void 0,oe=await qi({message:b,authToken:G,apiBase:a.apiBase||ct,personaId:X,history:J});Z(Be=>[...Be,{role:"user",content:b},{role:"assistant",content:oe.displayText}]),i.current.onBotOutput?.(oe.displayText),await $.speakText(oe.spokenText,{voiceId:a.voiceId,speakingRate:a.speakingRate})}catch(G){const X=G instanceof Error?G.message:"Failed to get reply.";x(X),i.current.onError?.(X)}finally{se(!1)}})())},k=()=>{const b=!N;A(b),r.current?.setMuted(b)};return M.jsxs("div",{className:"aitwin-widget__layout",children:[M.jsxs("div",{className:"aitwin-widget__stage",children:[S?M.jsx("div",{style:qr,children:M.jsx(Ki,{ref:r,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,style:qr,canvasStyle:Wo,onReady:pe,onDisplayStatus:L,onStatusChange:Q,onError:K,onUserTranscript:ae,onBotOutput:be,loadingThumbnailUrl:t.loadingThumbnailUrl},te)}):M.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),re?M.jsx(Vo,{progress:ne}):null,s?M.jsx(Ro,{muted:N,onToggle:k}):null,s&&m?M.jsx(Co,{}):null]}),s?M.jsx(Do,{ready:R,connected:p,connecting:m,status:C,textMode:ie,textDraft:I,textSending:q,error:_,onTalk:W,onTextMode:v,onTextDraftChange:V,onSendText:y}):null]})}),$o=".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}",Gr="data-aitwin-widget-style";function Yi(){if(typeof document>"u")return;const e=$o.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${Gr}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const n=document.createElement("style");n.setAttribute(Gr,"1"),n.textContent=e,(document.head??document.documentElement).appendChild(n)}typeof document<"u"&&Yi();const Ho=h.forwardRef(function(t,n){Yi();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 M.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:M.jsx(zo,{ref:r,options:t})})}),jo=new Set([".png",".jpg",".jpeg",".webp"]);function Qi(e=".png"){const t=e.toLowerCase();return jo.has(t)?`source${t}`:"source.png"}function Ko(e,t=On,n=".png"){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${Qi(n)}`}exports.AI_TWIN_THUMBNAIL_FILENAME=Un;exports.AiTwin=Ki;exports.AiTwinNotFoundError=Jt;exports.AiTwinWidget=Ho;exports.CONSONANT_SKIP_GROUP=mi;exports.DEFAULT_TTS_ENGINE_ID=at;exports.EMOTION_TO_EYEBROW=Oi;exports.EXPRESSION_ATLAS_EMOTIONS=wa;exports.MIC_SAMPLE_RATE=qn;exports.OCULUS_VISEME_IDS=li;exports.PLAYBACK_SAMPLE_RATE=Gn;exports.SPEAKING_RATE_MAX=mn;exports.SPEAKING_RATE_MIN=dn;exports.TTS_ENGINE_CARTESIA=lt;exports.TTS_ENGINE_GOOGLE=Vn;exports.TTS_ENGINE_INWORLD=an;exports.TTS_ENGINE_VISEMETTS=ut;exports.VISEME_IDS=ra;exports.VISEME_SKIP_GAP_MS=Pn;exports.VISEME_TEST_CARTESIA_VOICE_ID=Kn;exports.VISEME_TEST_SPEAKING_RATE=Ot;exports.VISEME_TEST_VISEMETTS_VOICE_ID=on;exports.VISEME_TEST_VOICE_ID=jn;exports.VISEME_VTIME_GRID_MS=Wn;exports.VOWEL_SKIP_GROUP=di;exports.aiTwinSourceFilename=Qi;exports.buildPlaybackTransitions=vi;exports.buildPlaybackVisemeSeries=un;exports.buildRawVisemeTransitions=_i;exports.buildVoiceWebSocketUrl=Ai;exports.compactSkippableVisemes=$n;exports.createAvatarTtsLipsyncController=Rn;exports.createRealtimeVoiceLipsyncController=Mi;exports.emotionToEyebrow=ot;exports.faceAssetUrls=Mn;exports.fetchAiTwin=ei;exports.fetchAvatarReply=qi;exports.fetchDevAuthToken=Ct;exports.getAiTwinSourceUrl=Ko;exports.getAiTwinThumbnailUrl=ti;exports.listSkippedVisemeEntries=fn;exports.listSkippedVisemes=Fs;exports.normalizeOculusViseme=cn;exports.normalizeStreamEmotion=Xe;exports.resolveDirectFaceId=ni;exports.resolveVisemeAtTime=Lt;exports.resolveVisemeFromPlaybackSeries=pi;exports.resolveWordAtTime=Hs;exports.setActiveTwinAssets=ri;exports.snapVisemeQueueToGrid=zn;exports.snapVisemeVtimeToGrid=hi;
47
+ `;function Kr(e=5){const t=new pe.Filter({glProgram:pe.GlProgram.from({vertex:xo,fragment:Io,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 Ao(e,t,n){return e>n||t>n}function Mo(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function Po(e,t){return t!=null&&t>0?Math.floor(t):Mo(e)}function Co(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 es(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 Gr(e,t,n,r,i){const s=n?await zi(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 p=ji(t,m,n),T=n?await ma(await Mt(p,i??"")):await es(p);if(Ao(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=pe.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 Ro(e,t={}){const n=new pe.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(w){throw n.destroy({removeView:!1}),w}if(n.renderer.type!==pe.RendererType.WEBGL)throw n.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const r=Po(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 pe.Sprite(pe.Texture.EMPTY),l=new pe.Sprite(pe.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new pe.Sprite(pe.Texture.EMPTY),m=new pe.Sprite(pe.Texture.EMPTY),p=new pe.Sprite(pe.Texture.EMPTY);p.visible=!1;const T=Kr(5),f=Kr(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(p);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=di(()=>{G.clear(),L=null,A=null,E=null,I=null}),J=(w,S)=>{ie=w,de=S,n.renderer.resize(w,S),(e.width!==w||e.height!==S)&&(e.width=w,e.height=S)},W=()=>{c.visible=!1,m.visible=!1,c.texture=pe.Texture.EMPTY,m.texture=pe.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},$=()=>{p.visible=!1,he(),E&&(d.texture=E,K())},X=()=>{!k&&!l.visible||$()},_e=w=>{if(o||i||!E){$();return}const S=Math.max(0,w);if(!D||S<=0){$();return}W(),p.visible=!1,d.texture=D,K(),l.texture=E,ee(),l.alpha=0,l.visible=!0,k={startMs:performance.now(),durationMs:S},q()},oe=(w=performance.now())=>{if(!k)return!1;if(o||i)return X(),!1;const S=(w-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=(w,S)=>{const x=w.cellByPath.get(S);if(!x||!Wi(x))return null;const _=`${w.diffBase}::${S}`;let U=G.get(_);if(!U){const Z=x.sheet??0,te=w.sheets.get(Z);if(!te)return null;let z,be=!1;if(te.mode==="full")z=new pe.Texture({source:te.texture.source,frame:new pe.Rectangle(x.x,x.y,x.w,x.h)});else{const Xe=Co(te.bitmap,x);z=pe.Texture.from(Xe),z.source.scaleMode="nearest",be=!0}U={texture:z,ownsSource:be},G.set(_,U)}return{texture:U.texture,cell:x}},H=(w,S,x,_)=>{if(!_||!x)return w.visible=!1,w.texture=pe.Texture.EMPTY,!1;const U=P(x,_);if(!U)return w.visible=!1,w.texture=pe.Texture.EMPTY,!1;const Z=Ui(x.atlasMeta,U.cell);return S.setThreshold(V),w.texture=U.texture,w.x=Z.x,w.y=Z.y,w.width=U.cell.w,w.height=U.cell.h,w.visible=!0,!0},le=w=>{if(!w||!L)return null;const S=I??new Set(L.cellByPath.keys());return rr(w,S)??(S.has(w)?w:null)},j=w=>{p.visible=!1,$();const S=le(w.mouthPath),x=w.expressionPath&&A?sr(w.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(w){if(o)return{width:ie,height:de,visemePaths:[]};const S=Wt();if(S&&!w)throw new Error("Encrypted assets enabled but no key provided");const x=S?await ga(await Mt(sn(),w??"")):await es(sn());E&&E.destroy(!0),E=pe.Texture.from(x),E.source.scaleMode="linear";const _=fi();L=await Gr(mi(),_,S,r,w);try{A=await Gr(hi(),_,S,r,w)}catch(Z){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",Z),A=null}const U=Vi(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(w){o||i||!E||(X(),j(w),q())},drawIdleVideo(w,S){o||i||document.hidden||S&&!S()||w.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(he(),W(),p.visible=!1,!D||v!==w?(b(),B=new pe.VideoSource({resource:w,autoPlay:!1,updateFPS:0}),B.autoUpdate=!1,D=new pe.Texture({source:B}),v=w):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(w){o||i||(X(),W(),re&&(re.destroy(!0),re=null),re=pe.Texture.from(w),p.texture=re,p.visible=!0,p.x=0,p.y=0,p.width=ie,p.height=de,d.visible=!1,q())},async compositePrefetchFrame(w){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 w=S=>{S.mode==="full"?S.texture.destroy(!0):S.bitmap.close()};if(L)for(const S of L.sheets.values())w(S);if(A)for(const S of A.sheets.values())w(S);T.destroy(!0),f.destroy(!0),n.destroy({removeView:!1},{children:!0,texture:!0})}}}const qr=-1,tn=1e5,Yr=new Map;async function Do(e){let t=Yr.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),Yr.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function Bo(){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 Qr(e,t){let n=0,r=null;const i=dr(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 Za(e)},drawLiveFrame(s,o,a,u){i.enqueue(o,a,u)},async compositePrefetchFrame(s,o){try{return await Ja(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 Fo(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=dr(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)),p=B=>{if(B===qr){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 Do(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===qr)){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&&p(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:Ds(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,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 Lo(e,t){const n=await Ro(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let r=0,i=null,s=!1;const o=dr(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 Xr(e,t){if(!Bo())return Qr(e,t);const n=gs(t.workerScriptUrl);try{return Fo(e,t,n)}catch{return Qr(e,t)}}function Oo(e,t={}){if(t.preferLegacyRenderer)return Xr(e,t);let n=null,r=!1,i=null,s=!1;const o=()=>n?Promise.resolve(n):(i||(i=(async()=>{try{const a=await Lo(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=Xr(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 No 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 No(n,t))},t);e.then(o=>{globalThis.clearTimeout(s),r(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const Vo={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Uo={display:"block",maxWidth:"100%",height:"auto"},Wo={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 bs(e)?er:ai(e)?dn:Zn}function Je(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const ts=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:p,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=mo,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(lr()),X=h.useRef(za()),_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),w=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"),[wt,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),Ae=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}),we=h.useRef(null),Le=h.useRef("sil"),Pe=h.useRef(""),Oe=h.useMemo(()=>to(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=eo(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),fr=h.useRef(D),mr=h.useRef(T),ye=h.useRef(f),hr=h.useRef(E),gr=h.useRef(k),pr=h.useRef(L),jt=h.useRef(A),wr=h.useRef(ie),_t=h.useRef(fo());fr.current=D,mr.current=T,ye.current=f,hr.current=E,gr.current=k,pr.current=L,jt.current=A,wr.current=ie,h.useEffect(()=>{const y=_t.current;return Wr(y),()=>Wr(null)},[]);const yr=h.useCallback(y=>{const M=et(y?.ttsEngineId??a,y?.voiceId??u),N=M.ttsEngineId??Ae.current?.ttsEngineId??dt,F=M.voiceId??Ae.current?.voiceId??Rn(N);return{ttsEngineId:N,voiceId:F}},[a,u]),it=h.useCallback(y=>{Ct(y),ue(!0),hr.current?.(y)},[]),Ft=h.useCallback(y=>{Pt(y),mr.current?.(y)},[]),fe=h.useRef(Nn(Ft,He,{onLipsyncDebug:y=>jt.current?.(y)})),me=h.useRef(null),vr=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 _r=h.useCallback(()=>(me.current||(me.current=Ni(Ft,{speakingRate:l,language:d,onUserTranscript:(y,M)=>gr.current?.(y,M),onBotOutput:y=>pr.current?.(y),onLipsyncDebug:y=>jt.current?.(y)}),me.current.setTtsEngineId(xe),vr.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(),w.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(Hr);return}(async()=>{const N=re.current;N&&await Mn(N,M,null,void 0,rt.current).catch(()=>{}),await new Promise(F=>setTimeout(F,Hr)),_.current&&await y?.renderSilOnly()})()},[De]),br=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(w.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"),w.current=!1,_.current=!1,!be.current||!z.current){x.current=!1;return}br()},[Re,br]),Sn=h.useCallback(async y=>{const M=H.current,N=O.current,F=re.current,Q=()=>{y?.fallbackOnly||(w.current=!1)};if(!N||!F||!ot){Q();return}if(Je(fe.current,me.current).isSpeaking()){Q();return}if(y?.fallbackOnly){if(!w.current||(Be($.current),await N.renderSilOnly(),M!==H.current)||Je(fe.current,me.current).isSpeaking())return;bt();return}if($r($.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=yo(Je(fe.current,me.current).getVisemeQueue(),Z.current,U.current),Ve=vo(Ee,we.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:Xi})}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||w.current)return;S.current=!0,w.current=!0,Re();const y=H.current;Sn().finally(()=>{S.current=!1}),j.current=setTimeout(()=>{j.current=null,y===H.current&&Sn({fallbackOnly:!0})},_o())},[Re,Sn]),Sr=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 Ms(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),Ae.current&&(Ae.current.ttsEngineId=xe)},[xe]),h.useEffect(()=>{Ae.current&&(Ae.current.voiceId=$e)},[$e]);const Ke=h.useMemo(()=>li(n,r),[n,r]),as=h.useMemo(()=>i?JSON.stringify(i):Ke?`face:${Ke}`:`id:${t??""}`,[i,Ke,t]),os=h.useMemo(()=>{const y=v?.trim();return y||(Er(Ke)??Er(Te)??Ts(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),Ae.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(oi(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=Y.knowledgeContextId?.trim()||void 0,F=Ln(Y.faceId)}Ae.current={ttsEngineId:Q,voiceId:Se,personaId:Ee},ui(F),z.current=Ha();const Ve=!!(i&&!gt(i));N=Oo(M,{preferLegacyRenderer:Ve,pixiMaxTextureSize:G,onStatus:Y=>{y||ye.current?.(Y)},onError:Y=>{y||it(Y)},shouldAcceptLiveFrame:()=>{if(_e.current)return!0;if(w.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=Eo(N),yt.current=!1;const Me=Y=>{const ce=()=>{if(!Y||he.current<=0)return!1;const Ie=O.current;return Ie?W.current&&Ie.supportsBufferedPlayback?!0:Ie.usesPixi:!1};fe.current.setLipsyncWarmupHold(Y,ce),me.current?.setLipsyncWarmupHold(Y,ce)};vr.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 Sr():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;we.current=N.getVisemeAtlasPaths(),je.current=!0,_n(!0),fr.current?.(),N.renderSilOnly().then(()=>{y||ye.current?.("sil")}),(async()=>{try{const Y=await ya(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}},[as,i,Ke,t,xe,$e,a,u,s,G,Sr,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(),w.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||w.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(),Ie={queue:ge,elapsedMs:0,expressionPath:Y,expressionDrawKey:ce,availablePaths:we.current};let Ue=!1;Gt&&J.current?(J.current.warmupTick(Ie),Ue=J.current.isWarmupReady(Ie,he.current)):F.usesPixi&&jr(N,ge,0,Y,ce,$.current,(Tt,qt,Tn,Yt)=>{F.drawLiveFrame(Tt,qt,Tn,qe=>{Yt?.(qe),Q.isWarmingUp()&&qe!==""&&!$r({lastDrawnKey:qe})&&(ee.current=0,Q.releaseWarmupHold())})},Tt=>{ye.current?.(Tt.label)},we.current);const st=ee.current>0&&performance.now()-ee.current>ws;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();sa(ge,Y),Z.current=Y;const ce=ge.length>0?zt(ge,Y):"sil";ce!=="sil"&&(U.current=ce);const Ie=Ga(Y,Q.getSentenceEmotions(),Q.getWordQueue(),Q.getStreamMood());X.current.setTargetEmotion(Ie),X.current.setTargetEyebrow(Ua(Y,Q.getWordQueue(),mt(Ie))),X.current.advance(performance.now());const Ue=X.current.getExpressionPath(),st=X.current.getDrawKey(),Tt=(qe,kn,Lt,En)=>{const Tr={label:Le.current,elapsedMs:Y,mouthPath:kn.mouthPath,transitionMeta:ct.current};Bt.current.set(Lt,Tr),J.current?.markExternallyDisplayed(Lt,Ue),F.drawLiveFrame(qe,kn,Lt,Qt=>{const cs=Bt.current.get(Qt)??Tr;Bt.current.delete(Qt),_t.current.onDrawDisplayed(cs,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:we.current,onStatus:qt,onDisplayed:(kn,Lt,En)=>{_t.current.onDrawDisplayed({label:En,elapsedMs:Y,mouthPath:Lt,transitionMeta:ct.current},ge)}}).usedBuffer),Yt||jr(N,ge,Y,Ue,st,$.current,Tt,qt,we.current),_t.current.onRafTickSpeaking(),wr.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,Ie,Ue,st)=>F.drawLiveFrame(ce,Ie,Ue,st),ce=>{if(b.current){ye.current?.(b.current);return}const Ie=X.current.getTargetEmotion();ye.current?.(ce==="sil"||ce==="blink"?`${Ie}${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()&&!w.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,Ie,Ue,st)=>F.drawLiveFrame(ce,Ie,Ue,st),ce=>ye.current?.(ce))}else Ge||Pn(N,null,"__sil__",$.current,(ge,Y,ce,Ie)=>F.drawLiveFrame(ge,Y,ce,Ie),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}=yr(M);Ct(null),Ne(),H.current+=1,Re(),De(),w.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(),w.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),Ae.current&&(Ae.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(),w.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(),w.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??Ae.current?.voiceId,Q=y.personaId?.trim()??Ae.current?.personaId,Se=N.ttsEngineId??Ae.current?.ttsEngineId??xe,Ee=_r();Se&&Ee.setTtsEngineId(Se),await Ee.unlockAudio(),await Ee.connect({...y,apiBase:y.apiBase?.trim()||He,authToken:M,voiceId:F,personaId: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(),w.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},getPersonaId:()=>Ae.current?.personaId?.trim()||null}),[ot,l,d,s,xe,$e,Re,De,St,it,yr,_r,Xe,He]),R.jsxs("div",{className:c,style:{...Vo,...m},children:[R.jsx("canvas",{ref:re,width:ke.width,height:ke.height,style:{...Uo,...p},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!ne&&!wt?R.jsx(lo,{thumbnailUrl:os}):null,B&&wt?R.jsx("div",{style:Wo,children:wt}):null,Oe.enabled&&Fe?R.jsx(so,{text:Fe,style:Oe.style},Fe):null]})});async function zo(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 ns(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??[],persona_id:e.personaId?.trim()||""})});if(!i.ok)throw new Error(await zo(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 p=a.split(`
48
+ `);a=p.pop()||"";for(const T of p){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 Ho({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 $o(){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 jo(){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 Ko(){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 rs({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 Go({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(Ho,{muted:e})})}function qo(){return R.jsxs("div",{className:"aitwin-widget__connecting",role:"status","aria-live":"polite",children:[R.jsx(rs,{className:"aitwin-widget__spinner aitwin-widget__spinner--accent"}),R.jsx("span",{children:"Connecting..."})]})}function Yo(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(rs,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?R.jsx(jo,{}):R.jsx($o,{}),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(Ko,{}),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 Jr=97,Qo=3500;function Xo(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/Qo);return Math.min(Jr,Math.round(r*Jr))}function Jo(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:Xo(r-t):100}const Zo="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 ec({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:Zo,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function tc({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(ec,{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 Zr(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 nc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const ei={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},rc={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},ic=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(()=>Zr(t)),[d,l]=h.useState(!1),[c,m]=h.useState(!1),[p,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.personaId?.trim()||void 0),W=h.useCallback(_=>{i.current={...i.current,..._},_.showControls!==void 0&&o(!!_.showControls),_.personaId!==void 0&&J(_.personaId.trim()||void 0),u(U=>Zr({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.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=nc(a),b=!!(a.id||a.faceId),P=d&&c,H=b&&!P&&!v,le=Jo(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)})},w=()=>{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.getPersonaId()?.trim()||void 0,z=await ns({message:_,authToken:Z,apiBase:a.apiBase||ht,personaId: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:ei,children:R.jsx(ts,{ref:r,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,style:ei,canvasStyle:rc,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(tc,{progress:le}):null,s?R.jsx(Go,{muted:L,onToggle:x}):null,s&&f?R.jsx(qo,{}):null]}),s?R.jsx(Yo,{ready:P,connected:p,connecting:f,status:D,textMode:ie,textDraft:I,textSending:G,error:v,onTalk:q,onTextMode:w,onTextDraftChange:V,onSendText:S}):null]})}),sc=".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}",ti="data-aitwin-widget-style";function is(){if(typeof document>"u")return;const e=sc.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${ti}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const n=document.createElement("style");n.setAttribute(ti,"1"),n.textContent=e,(document.head??document.documentElement).appendChild(n)}typeof document<"u"&&is();const ac=h.forwardRef(function(t,n){is();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(ic,{ref:r,options:t})})}),oc=new Set([".png",".jpg",".jpeg",".webp"]);function ss(e=".png"){const t=e.toLowerCase();return oc.has(t)?`source${t}`:"source.png"}function cc(e,t=$n,n=".png"){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${ss(n)}`}exports.AI_TWIN_THUMBNAIL_FILENAME=qn;exports.AiTwin=ts;exports.AiTwinNotFoundError=nn;exports.AiTwinWidget=ac;exports.CONSONANT_SKIP_GROUP=Si;exports.DEFAULT_TTS_ENGINE_ID=dt;exports.DEFAULT_TTS_LANGUAGE=Ns;exports.EMOTION_TO_EYEBROW=Ki;exports.EXPRESSION_ATLAS_EMOTIONS=Ca;exports.MIC_SAMPLE_RATE=tr;exports.OCULUS_VISEME_IDS=yi;exports.PLAYBACK_SAMPLE_RATE=nr;exports.SPEAKING_RATE_MAX=yn;exports.SPEAKING_RATE_MIN=wn;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=gi;exports.VISEME_IDS=va;exports.VISEME_SKIP_GAP_MS=On;exports.VISEME_TEST_CARTESIA_VOICE_ID=er;exports.VISEME_TEST_SPEAKING_RATE=Ht;exports.VISEME_TEST_VISEMETTS_VOICE_ID=dn;exports.VISEME_TEST_VOICE_ID=Zn;exports.VISEME_VTIME_GRID_MS=Yn;exports.VOWEL_SKIP_GROUP=bi;exports.aiTwinSourceFilename=ss;exports.buildPlaybackTransitions=Mi;exports.buildPlaybackVisemeSeries=gn;exports.buildRawVisemeTransitions=Ai;exports.buildVoiceWebSocketUrl=Oi;exports.compactSkippableVisemes=Xn;exports.createAvatarTtsLipsyncController=Nn;exports.createRealtimeVoiceLipsyncController=Ni;exports.emotionToEyebrow=mt;exports.faceAssetUrls=Ln;exports.fetchAiTwin=oi;exports.fetchAvatarReply=ns;exports.fetchDevAuthToken=Nt;exports.getAiTwinSourceUrl=cc;exports.getAiTwinThumbnailUrl=ci;exports.isTtsLanguageCode=pi;exports.isTtsLanguageSupported=Us;exports.listSkippedVisemeEntries=pn;exports.listSkippedVisemes=Xs;exports.normalizeOculusViseme=mn;exports.normalizeStreamEmotion=Ze;exports.normalizeTtsLanguage=fn;exports.parsePackedVoiceId=ii;exports.resolveDirectFaceId=li;exports.resolveVisemeAtTime=zt;exports.resolveVisemeFromPlaybackSeries=Ei;exports.resolveWordAtTime=aa;exports.setActiveTwinAssets=ui;exports.snapVisemeQueueToGrid=Qn;exports.snapVisemeVtimeToGrid=Ti;exports.splitVoiceIdSpec=et;exports.ttsLanguagesForEngine=Vs;