@streamoji/aitwin 0.7.4 → 0.7.5

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