@streamoji/aitwin 0.7.2 → 0.7.4
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 +5 -5
- package/dist/aitwin.js +1387 -1362
- package/package.json +1 -1
package/dist/aitwin.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("react/jsx-runtime"),m=require("react"),ys=require("@pipecat-ai/client-js"),Zn=require("@pipecat-ai/websocket-transport"),ye=require("pixi.js");var Bn=typeof document<"u"?document.currentScript:null;const vs="https://aitwin.bubu.social",mi={publicBase:vs},_s="0.7.2",bs={version:_s},Ss={},Dt="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 Es="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",Fn=3e3,Vt=16,Br=3e3,xs=4e3,Is=.85,As=8,tr=400,nr="eng_a7f2b9c1",hn="eng_d4e8f3a2",at="eng_c9b1e6d4",ot="visemetts",ht=at,pn="eve",zn=new Set([hn,at,ot]),rr={[nr]:"oculus_direct",[at]:"oculus_direct",[ot]:"oculus_direct",[hn]:"inworld_word"},jn={google:nr,inworld:hn,cartesia:at,visemetts:ot};function Ms(e){const t=e.trim();if(t)return t in rr?t:jn[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 st(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===at}function gi(e){return e===ot}function Rs(e){if(e.ttsEngineId&&e.ttsEngineId in rr)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in jn?jn[t]:ht}class on 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=Es){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new on;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const i=await r.json();if(!i.success)throw new on(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 an(){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=Dt){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 en(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=en(n.subarray(0,12)),i=en(n.subarray(12,28)),s=en(n.subarray(28)),o=en(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 tn(e){return e.includes("/custom-faces/")}function cn(e){const t=e.binBase.trim().replace(/\/$/,""),n=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||tn(t)||tn(n)))return{twinBase:n,binBase:t,encrypted:!1};const i=tn(t)?t:tn(n)?n:t;return{twinBase:i,binBase:i,encrypted:!0}}function gt(e){return cn(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=cn(e);for(const t of $n)t()}function zs(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return cn(e);const r=i=>{try{return new URL(i,n).href.replace(/\/$/,"")}catch{return i}};return cn({twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted})}function yt(){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 ln(){const e=yt();return gt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function js(){const e=yt();return gt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function Ti(){const e=yt();return gt(e)?e.binBase:e.twinBase}function Ht(){return gt(yt())}function ki(){const e=yt();return gt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function Ei(){const e=yt();return gt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}const pt=[{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}],xi=pt.map(e=>e.code),Hs=new Set(xi),$s=new Set(pt.filter(e=>e.visemetts).map(e=>e.code)),Ks=new Set(pt.filter(e=>e.cartesia).map(e=>e.code)),Gs="en";function Ii(e){return Hs.has(e)}function wn(e){const t=e?.trim();if(t)return t}function qs(e){return e===ot?pt.filter(t=>t.visemetts).map(t=>t.code):e===at?pt.filter(t=>t.cartesia).map(t=>t.code):pt.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Ys(e,t){const n=t.trim();return n?e===ot?$s.has(n):e===at?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 gn(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 Mt(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function yn(e,t){const n=e.toLowerCase().replace(/[^a-z']/g,"");return!n||Mt(n,t)!=="w"||t>0&&Mt(n,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(n)}function Zs(e,t){const n=e.toLowerCase(),r=Mt(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(yn(n,t))return"FF";const i=Mt(n,t);return i==="u"||i==="w"?"U":"O"}function ta(e,t){const n=e.toLowerCase();if(yn(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)||Mt(n,t)==="o"?"O":"U"}const nn={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=Mt(n,t);if(nn[r])return nn[r];for(let i=0;i<n.length;i++){const s=n[i];if(nn[s])return nn[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 vn(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 _n(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 _n(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 vn(e).find(n=>n.viseme!=="sil")??null}function ft(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=vn(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 zi(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=gn(a),g==="U"&&c&&yn(c.word,f)&&(g="FF")):g=Pi(a,c?.word??"",f),e.push({viseme:g,weight:1,vtime:l,vduration:d})})}function ji(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,E=null,W=null,N=!1,v=0,k=!1,O=!1,F=0,ie=null,re=null,P=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()}},we=b=>{const U=ft(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 R=String(w.word??"").trim();if(!R)return;const V=Math.round((w.start??0)*1e3),X=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:R,wtime:c+V,wduration:X,queueIndex:b.length,gesture:w.gesture??null,emphasis:w.emphasis===!0})}))},z=(b,U,Y,_,w,S)=>{Y.length!==0&&(c=_,Y.forEach(R=>{const V=String(R.symbol??R.viseme??"").trim();if(!V)return;const X=Math.round((R.start??0)*1e3),ue=Math.max(1,Math.round((R.duration??0)*1e3)),I=c+X,j=$i(U,I),de=j?Ri(j,I):0;let Re;pi(S)==="oculus_direct"?(Re=gn(V),Re==="U"&&j&&yn(j.word,de)&&(Re="FF")):Re=Pi(V,j?.word??"",de),b.push({viseme:Re,weight:1,vtime:I,vduration:ue})}),e.onNotify())},A=(b,U,Y,_,w,S,R)=>{ce(U,_,w),z(b,U,Y,w,S,R)},q=(b,U,Y)=>{P===b&&b.visemes===U||(U.length=0,Y.length=0,b.visemes=U,b.words=Y,b.segmentOffsetMs=0,P=b,c=0,v=0)},D=b=>(W||(W=b.createGain(),W.gain.value=N?0:1,W.connect(b.destination)),W),H=async()=>{const b=window.AudioContext||window.webkitAudioContext;return i||(i=new b,W=null,E=null),i.state==="suspended"&&await i.resume(),D(i),E||(E=i.createMediaStreamDestination()),i},J=(b,U)=>{if(!i)return 0;const Y=i,_=Y.currentTime,w=_+.02;if(U.isFirstAudio){l<=0&&(l=w);const R=(w-_)*1e3;d=performance.now()+R}U.onBeforeStart?.(w);const S=Y.createBufferSource();return S.buffer=b,S.playbackRate.value=g,S.connect(D(Y)),E&&S.connect(E),r.push(S),h?(r.pop(),w):(U.isFirstAudio&&(o=!0,e.onSpeakingStart()),S.onended=()=>{const R=r.indexOf(S);R>=0&&r.splice(R,1),e.onNotify(),!h&&(ie&&re?ee(ie,re):oe())},S.start(w),w)},ee=async(b,U)=>{if(h||s||r.length>0)return;if(n.length===0){oe();return}s=!0;let Y=!1;try{const _=await H();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 X of n){if(h)return;X.audioBuffer||(X.audioBuffer=await Or(_,X.audio,X.sampleRate)),a=!0,O||(O=!0,F=0,X.newStream&&X.onNewStream?.()),X.visemesQueued||(A(b,U,X.visemes,X.words,F,!0,T),X.visemesQueued=!0,F+=Math.round(X.audioBuffer.duration*1e3),v=Math.max(v,ft(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?.(),J(V.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:X=>{l=X,c=0,d=performance.now()+(X-_.currentTime)*1e3,b.length=0,U.length=0,A(b,U,V.visemes,V.words,0,!0,T),V.visemesQueued=!0,V.utterance.segmentOffsetMs=0}}),Y=r.length>0,v=ft(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)&&ee(b,U);return}!Y&&r.length===0&&n.length>0?ee(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&&ee(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,E=null),i.state==="suspended"&&await i.resume(),D(i),E||(E=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,P=null,Q()},markStreamComplete:b=>{if(v=Math.max(v,ft(b)),u=!0,!a&&b.length>0){we(b);return}oe()},playAudioChunk:async(b,U,Y,_,w,S,R)=>{if(h)return;ie=b,re=U;const V=Hi(R?.sampleRate),X=R?.newStream===!0,ue=G();if(!Y?.trim()){if(_.length===0&&w.length===0)return;q(ue,b,U),X&&R?.onNewStream?.(),A(b,U,_,w,0,!0,T),v=ft(b),!o&&v>0&&we(b),e.onNotify();return}n.push({audio:Y,audioBuffer:null,utterance:ue,visemes:_,words:w,isNewSegment:S,sampleRate:V,newStream:X,onNewStream:R?.onNewStream,visemesQueued:!1}),await ee(b,U)},queueTimingsOnly:(b,U,Y,_,w,S)=>{if(h)return;const R=G();q(R,b,U),A(b,U,Y,_,0,!0,T),R.segmentOffsetMs=0,v=ft(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:()=>E?E.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,P=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,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 Gi(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 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 bn=.5,Sn=1.5,dr="Olivia",fr="f786b574-daa5-4673-aa0c-cbe3e8534c02",Kt=.85;function qn(e,t=Dt,n={}){const r=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let u=0;const d=[],l=[];let c="",f="neutral",g="",T=ht;const h=new Set;let E=0,W=null,N=0,v=null;const k=()=>h.forEach(z=>z());let O=()=>!1;const F=Ki({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:k,shouldHoldForWarmup:()=>O()},ht),ie=()=>F.getPlaybackElapsedMs(),re=(z,A=c)=>{if(!n.onLipsyncDebug)return;const q=ie(),D=i,H=_n(o).map(J=>({viseme:J.viseme,vtimeMs:J.vtime}));n.onLipsyncDebug({event:z,spokenText:A,mood:f,playbackAnchorPerf:F.getPlaybackStartPerf(),playbackElapsedMs:q,queueLength:D.length,activeViseme:$t(D,q),segments:l.map(J=>({...J,visemes:[...J.visemes]})),fullQueueLength:o.length,compactionSkipped:H})},P=(z,A)=>{n.onLipsyncDebug&&(W={event:z,spokenText:A},E===0&&(E=requestAnimationFrame(()=>{E=0;const q=W;W=null,q&&re(q.event,q.spokenText)})))},G=(z,A,q,D,H)=>{if(!n.onLipsyncDebug)return;const J=i.slice(A),ee=q.filter(ne=>String(ne.symbol??ne.viseme??"").trim());l.push({spokenText:z,audioOffsetMs:J[0]?.vtime??0,isNewSegment:D,chunkDurationMs:H,receivedAtMs:performance.now(),visemes:J.map((ne,Te)=>{const Z=ee[Te];return{rawSymbol:String(Z?.symbol??Z?.viseme??ne.viseme).trim(),viseme:ne.viseme,startSec:Number(Z?.start??0),durationSec:Number(Z?.duration??0),vtimeMs:ne.vtime,vdurationMs:ne.vduration}})})},Q=()=>{o.length=0,a.length=0,u=0},te=(z,A,q,D,H)=>{if(z.length===0&&A.length===0)return;zi(o,a,z,A,u,H);const J=ji(z,u),ee=q?Ur(q,D):null;u=Math.max(J,ee!=null?u+ee: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"),P("reset"),k()},ae=z=>{const A=st(z?.ttsEngineId,z?.voiceId),q=A.ttsEngineId??T??ht,D=A.voiceId??(q===ot?pn:dr),H=z?.speakingRate??Kt,J=Math.max(bn,Math.min(Sn,H));return{engineId:q,voiceId:D,speakingRate:J,language:wn(z?.language)}},oe=async z=>{le();const A=N;v=new AbortController,e("loading"),c=z.debugSpokenFallback,l.length=0,Q();const q=g.trim();if(!q)throw new Error("Developer token required for avatar_ttsWithPoses");F.resetForNewStream(z.engineId),F.setStreamTtsEngineId(z.engineId);let D="",H="";try{const J=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${q}`,Accept:"text/event-stream"},body:JSON.stringify(z.requestBody),signal:v.signal});if(!J.ok)throw new Error(`avatar_ttsWithPoses failed (${J.status})`);const ee=J.body;if(!ee)throw new Error("No response body");const ne=ee.getReader(),Te=new TextDecoder;let Z="",b=!0;const U=()=>D||z.debugSpokenFallback,Y=async _=>{if(A!==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,z.onSpokenText?.(S),k());return}if(w.event==="displayText"){const S=typeof w.data.text=="string"?w.data.text.trim():"";S&&(H=S,z.onDisplayText?.(S),k());return}if(w.event!=="done"){if(w.event==="audio"){const S=w.data.chunk,R=w.data.visemes??[],V=w.data.words??[],X=w.data.is_new_segment??!1,ue=w.data.sample_rate,I=Number(w.data.audio_offset_ms??0),j=i.length,de=U();if(te(R,V,S,ue,z.engineId),S){const Re=b;b=!1,await F.playAudioChunk(i,s,S,R,V,X,{sampleRate:ue,newStream:Re,audioOffsetMs:I}),G(de,j,R,X,Ur(S,ue)),P("audio_chunk",de)}else(R.length>0||V.length>0)&&(F.queueTimingsOnly(i,s,R,V,X,{audioOffsetMs:I,newStream:b}),G(de,j,R,X,null),P("audio_chunk",de))}else if(w.event==="metadata"){const S=w.data.mood;typeof S=="string"&&S.trim()&&(f=S.trim());const R=w.data.spoken_text??w.data.text;typeof R=="string"&&R.trim()&&!D&&(D=R.trim(),c=D);const V=w.data.sentence_emotions;if(Array.isArray(V)){d.length=0;for(const X of V){if(!X||typeof X!="object")continue;const ue=X;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(),P("metadata",U())}else if(w.event==="error")throw new Error(String(w.data.message??"avatar_ttsWithPoses stream error"))}}};for(;;){if(A!==N)return{displayText:H,spokenText:D,aborted:!0};const{done:_,value:w}=await ne.read();w&&(Z+=Te.decode(w,{stream:!0}));const S=Z.split(`
|
|
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(`
|
|
2
2
|
|
|
3
|
-
`);Z=S.pop()??"";for(const R of S)await Y(R);if(_){Z.trim()&&await Y(Z.trim()),F.markStreamComplete(i),P("bot_stopped",U());break}}}catch(J){if(A!==N)return{displayText:H,spokenText:D,aborted:!0};if(J instanceof DOMException&&J.name==="AbortError")return{displayText:H,spokenText:D,aborted:!0};throw console.error("[avatarTtsLipsync]",J),le(),e("error"),J}return{displayText:H,spokenText:D}};return{setDeveloperToken:z=>{g=z},setTtsEngineId:z=>{T=z},getTtsEngineId:()=>T,speak:async(z,A)=>{const{engineId:q,voiceId:D,speakingRate:H,language:J}=ae(A),ee={user_query:z,ttsEngineId:q,speakingRate:H,tenant:"aiTwin"};zn.has(q)&&(ee.voice_id=D),J&&(ee.language=J),await oe({requestBody:ee,engineId:q,debugSpokenFallback:z})},speakWithReply:async(z,A)=>{const q=z.trim();if(!q)throw new Error("Message is required");const{engineId:D,voiceId:H,speakingRate:J,language:ee}=ae(A),ne={generateReply:!0,message:q,ttsEngineId:D,speakingRate:J,tenant:"aiTwin",history:A?.history??[]};zn.has(D)&&(ne.voice_id=H),ee&&(ne.language=ee);const Te=A?.brainId?.trim();Te&&(ne.brainId=Te);const Z=A?.brainUrl?.trim();Z&&(ne.brainUrl=Z);const b=await oe({requestBody:ne,engineId:D,debugSpokenFallback:q,onSpokenText:A?.onSpokenText,onDisplayText:A?.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:(z,A)=>{A&&(O=A),F.setLipsyncWarmupHoldEnabled(z)},getVoiceStream:()=>F.getVoiceStream(),setMuted:z=>{F.setMuted(z)},isMuted:()=>F.isMuted(),setPlaybackSpeed:z=>{F.setPlaybackSpeed(z)},getPlaybackSpeed:()=>F.getPlaybackSpeed(),subscribe:z=>(h.add(z),()=>h.delete(z))}}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 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??Dt,r=new URL(`${_a(n)}/ws/voice`);r.searchParams.set("authToken",t),r.searchParams.set("tenant","aiTwin");const i=st(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=wn(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(bn,Math.min(Sn,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=at,f=!1,g=null,T=null,h={...t},E=0,W=null;const N=new Set,v=[];let k=!1,O=null,F=!0,ie="default";const re=new Set;let P=null,G=0,Q=!1,te=!1,le=null,ae=!1;const oe=()=>{le!=null&&(clearTimeout(le),le=null)},we=()=>{oe(),le=setTimeout(()=>{le=null,F&&(A.markStreamComplete(n),ee("bot_stopped"))},450)},ce=()=>N.forEach(p=>p());let z=()=>!1;const A=Ki({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{ae=!1,te=!1,e("done")},onNotify:ce,shouldHoldForWarmup:()=>z()},c),q=()=>{if(O)return O;const p=new MessageChannel;return p.port1.onmessage=()=>{const B=v.shift();B!==void 0&&j(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))},H=()=>A.getPlaybackElapsedMs(),J=(p,B=d)=>{if(!h.onLipsyncDebug)return;const se=H(),fe=n,_e=_n(i).map(xe=>({viseme:xe.viseme,vtimeMs:xe.vtime}));h.onLipsyncDebug({event:p,spokenText:B,mood:l,playbackAnchorPerf:A.getPlaybackStartPerf(),playbackElapsedMs:se,queueLength:fe.length,activeViseme:$t(fe,se),segments:u.map(xe=>({...xe,visemes:[...xe.visemes]})),fullQueueLength:i.length,compactionSkipped:_e})},ee=(p,B)=>{h.onLipsyncDebug&&(W={event:p,spokenText:B},E===0&&(E=requestAnimationFrame(()=>{E=0;const se=W;W=null,se&&J(se.event,se.spokenText)})))},ne=()=>{F=!0,re.clear(),A.clearAborted()},Te=()=>{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{}},Z=p=>{if(ae&&A.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,P?.abort(),P=null,G+=1,Te(),A.bargeIn(),U(),e("idle"),ee("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,A.stop(),U(),ee("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(Z({...p,type:"avatar_metadata"}))return;ne(),Q=!0;const B=String(p.spoken_text??p.text??"").trim();B&&(d=B),A.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,ee("metadata",B),ce()},R=(p,B,se,fe)=>{if(!h.onLipsyncDebug)return;const _e=n.slice(se),xe=fe.filter(Pe=>String(Pe.symbol??Pe.viseme??"").trim());u.push({spokenText:B,audioOffsetMs:_e[0]?.vtime??0,isNewSegment:!!p.is_new_segment,chunkDurationMs:p.chunk_duration_ms!=null?Number(p.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:_e.map((Pe,je)=>{const Ue=xe[je];return{rawSymbol:String(Ue?.symbol??Ue?.viseme??Pe.viseme).trim(),viseme:Pe.viseme,startSec:Number(Ue?.start??0),durationSec:Number(Ue?.duration??0),vtimeMs:Pe.vtime,vdurationMs:Pe.vduration}})})},V=(p,B,se,fe)=>{if(p.length===0&&B.length===0)return;zi(i,s,p,B,o,c);const _e=ji(p,o);let xe=null;const Pe=se.trim();if(Pe)try{const je=atob(Pe.replace(/\s+/g,"")).length,Ue=Number.isFinite(fe)&&(fe??0)>0?Number(fe):16e3;xe=je/2/Ue*1e3}catch{xe=null}o=Math.max(_e,xe!=null?o+xe:o)},X=p=>{if(Z(p))return;const B=Wr(p);B&&(oe(),ne());const se=String(p.spoken_text??p.text??"").trim(),fe=p.visemes??[],_e=p.words??[],xe=String(p.chunk??"").trim(),Pe=Q||B||!te;Q&&(Q=!1),Pe&&(te=!0),se&&(d=se),w(p,B),Pe?(A.resetForNewStream(c),i.length=0,s.length=0,o=0):B&&A.resumeBotStream(),V(fe,_e,xe,p.sample_rate);const je=n.length;A.playAudioChunk(n,r,xe,fe,_e,B,{sampleRate:p.sample_rate,newStream:Pe,audioOffsetMs:Number(p.audio_offset_ms??0),onNewStream:()=>{u.length=0}}).then(()=>{R(p,se,je,fe),ee("audio_chunk",se),we()})},ue=p=>{if(Z(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;A.queueTimingsOnly(n,r,p.visemes??[],p.words??[],!!p.is_new_segment,{audioOffsetMs:Number(p.audio_offset_ms??0)}),R(p,B,se,p.visemes??[]),ee("lipsync",B),ce()},I=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}P?.abort();const fe=new AbortController;P=fe;const _e=++G;ne(),A.resetForNewStream(c),d=B;const Pe=`${(h.apiBase??Dt).replace(/\/$/,"")}/avatar_ttsWithPoses`,je=st(c,h.voiceId);je.ttsEngineId&&(c=je.ttsEngineId,A.setStreamTtsEngineId(c));const Ue=je.voiceId?.trim()||(c===ot?pn:fr),Gt=h.speakingRate??Kt,En=Math.max(bn,Math.min(Sn,Gt)),Lt={user_query:B,ttsEngineId:c,speakingRate:En,tenant:"aiTwin"};zn.has(c)&&(Lt.voice_id=Ue);const bt=wn(h.language);bt&&(Lt.language=bt);try{const Oe=await fetch(Pe,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${se}`},body:JSON.stringify(Lt),signal:fe.signal});if(!Oe.ok)throw new Error(`avatar_ttsWithPoses failed (${Oe.status})`);const qe=Oe.body;if(!qe)throw new Error("No response body");const St=qe.getReader(),Ie=new TextDecoder;let Ce="",Ye=!0;const Ve=async We=>{if(_e!==G||fe.signal.aborted||!F)return;const Ae=Ai(We);if(Ae){if(Ae.event==="audio"){const Be=Ae.data.chunk,He=Ae.data.visemes??[],tt=Ae.data.words??[],$e=Ae.data.is_new_segment??!1,ze=Ae.data.sample_rate,Tt=Number(Ae.data.audio_offset_ms??0);if(Be){const kt=Ye;Ye=!1,await A.playAudioChunk(n,r,Be,He,tt,$e,{sampleRate:ze,newStream:kt,audioOffsetMs:Tt})}else(He.length>0||tt.length>0)&&A.queueTimingsOnly(n,r,He,tt,$e,{audioOffsetMs:Tt,newStream:Ye})}else if(Ae.event==="metadata"){const Be=Ae.data.mood;typeof Be=="string"&&Be.trim()&&(l=Be.trim());const He=Ae.data.sentence_emotions;Array.isArray(He)&&(a.length=0,a.push(...Ln(He,l))),ce()}else if(Ae.event==="error")throw new Error(String(Ae.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(_e!==G||fe.signal.aborted||!F);){const{done:We,value:Ae}=await St.read();Ae&&(Ce+=Ie.decode(Ae,{stream:!0}));const Be=Ce.split(`
|
|
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(`
|
|
4
4
|
|
|
5
|
-
`);Ce=Be.pop()??"";for(const He of Be)await Ve(He);if(We){Ce.trim()&&await Ve(Ce.trim()),_e===G&&!fe.signal.aborted&&F&&A.markStreamComplete(n);break}}}catch(Oe){if(fe.signal.aborted||!F)return;console.error("[realtimeVoice] avatar_speak failed:",Oe),e("error"),ce()}finally{P===fe&&(P=null)}},j=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":X(B);break;case"avatar_lipsync":ue(B);break;case"avatar_interrupt":b(B);break;case"error":{const fe=String(B.message??"Voice session error");console.error("[realtimeVoice] server error:",fe),e("error"),ce();break}case"avatar_speak":I(B);break}},de=()=>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(),ee("bot_started")},onBotStoppedSpeaking:()=>{F&&we()},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,A.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:()=>{P?.abort(),P=null,G+=1,ne(),Y(),e("idle"),ce()},connect:async p=>{p&&(h={...h,...p});const B=st(h.ttsEngineId,h.voiceId);if(B.ttsEngineId&&(c=B.ttsEngineId,A.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=de();try{await se.initDevices()}catch(_e){throw f=!1,e("idle"),ce(),Wt(_e)?new Error("Microphone access denied"):_e instanceof Error?_e:new Error("Failed to initialize microphone")}const fe=qi({...h,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",fe);try{await se.connect({wsUrl:fe})}catch(_e){if(f=!1,e("error"),ce(),Wt(_e))throw e("idle"),new Error("Microphone access denied");const xe=_e instanceof Error?_e.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${xe} — ${fe}`)}f=!0,e("idle"),ce()},disconnect:async()=>{if(oe(),Q=!1,te=!1,v.length=0,k=!1,P?.abort(),P=null,G+=1,ne(),g)try{await g.disconnect()}catch(p){console.error("[realtimeVoice] disconnect failed:",p)}f=!1,_()},isConnected:()=>f,unlockAudio:async()=>{await A.primeAudioContext()},getVisemeQueue:()=>n,getWordQueue:()=>r,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:H,isSpeaking:()=>A.isSpeaking(),isWarmingUp:()=>A.isWarmingUp(),releaseWarmupHold:()=>A.releaseWarmupHold(),setLipsyncWarmupHold:(p,B)=>{B&&(z=B),A.setLipsyncWarmupHoldEnabled(p)},getVoiceStream:()=>A.getVoiceStream(),setMuted:p=>{A.setMuted(p)},isMuted:()=>A.isMuted(),setPlaybackSpeed:p=>{A.setPlaybackSpeed(p)},getPlaybackSpeed:()=>A.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 Bt(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 Bt(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 Ea(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function xa(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=js();if(!Ht())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Bt(t,e);return Ia(n)}function At(e,t){return`${e}/${t}_minus_sil.png`}const es=5;function Tn(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,zr=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 jr(e,t){return`${e}__${t}`}function Hr(e,t){return`pairs/${e}/${t}_minus_sil.png`}function Rt(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=Rt(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=jr(e,t);if(zr.has(r)){for(const s of Yn)n.push(Hr(r,s));return n}const i=jr(t,e);if(zr.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"],Ge=2,Ua=-20,un=16,rs={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function zt(e){return`brow_${e}`}function wt(e){return rs[e]}function et(e){return Math.max(Ua,Math.min(un,e))}function Va(e,t){if(e===t)return[];const n=e<t,r=n?Ge:-Ge,i=[];let s=e;if(s%Ge!==0){const o=n?Math.ceil(s/Ge)*Ge:Math.floor(s/Ge)*Ge,a=et(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=et(e);if(t%Ge===0)return[t];const n=Math.floor(t/Ge)*Ge,r=Math.min(un,n+Ge),i=et(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"],za={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 it(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?za[n]??t:t}function is(e){return e===0?null:At(zt(e),"eyes_standard")}function ss(e){return is(wt(e))}const ja={[-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=At(zt(a),s);if(t(u))return u}const o=ja[i];if(o){const a=At(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=wt(i);for(const a of[o,...$r(o)]){const u=At(zt(a),s);if(t(u))return u}}return null}function Kr(e,t){const n=zt(wt(e));return!t||t==="eyes_standard"?ss(e):e==="neutral"&&t==="eyes_standard"?null:At(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 At(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=et(e);return t>=un?un:et(t+Ga)}function Qa(e,t,n){const r=et(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)?et(n):null}function Ze(e,t){return e+Math.random()*(t-e)}function qr(){return Ze(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:Ze(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:Ze(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?Ze(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function Yr(e,t){const n=Ze(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},E=null,W="__eyes_open__|neutral|brow:0";function N(P=l){W=`${E??"__eyes_open__"}|${P}|brow:${g}`}function v(P,G=l){E=P;const Q=Gr(P);Q!=null?g=Q:P==null&&(g=0),N(G)}function k(P){return is(P)}function O(P,G,Q){const te=et(G),le=et(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:P+qr(),targetBrow:le},v(ae[0]??null)}function F(P,G){h={kind:"idle",nextBlinkAt:P+Ze(n,r)},c=G,v(k(f),G)}function ie(P,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:P+Yr(le,ae===0),after:"idle",blinkEmotion:G,pace:le,closedFrameIndex:ae},c=G,v(h.paths[0]??null,G)}function re(P){if(h.kind==="browBlend"){for(;P>=h.holdUntil&&h.index<h.paths.length-1;)h.index+=1,h.holdUntil=P+qr();const G=h.paths[h.index]??null;v(G),P>=h.holdUntil&&h.index>=h.paths.length-1&&(g=h.targetBrow,f=h.targetBrow,v(k(h.targetBrow)),h={kind:"idle",nextBlinkAt:P+u});return}if(h.kind==="idle"){v(k(f),c),P>=h.nextBlinkAt&&ie(P,c,!1);return}if(h.kind==="doublePause"){v(k(f),h.blinkEmotion),P>=h.resumeAt&&ie(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+Yr(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"){F(P+u,l);return}if(h.after==="doublePause"){h={kind:"doublePause",resumeAt:P+Ze(s,o),blinkEmotion:h.blinkEmotion},v(k(f),h.blinkEmotion);return}if(h.after==="idle"&&Math.random()<i){h={kind:"doublePause",resumeAt:P+Ze(s,o),blinkEmotion:h.blinkEmotion},v(k(f),h.blinkEmotion);return}F(P,h.blinkEmotion)}}}return{advance:re,setTargetEmotion(P,G){const Q=it(P,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(P){const G=et(P);if(G===f)return;const Q=performance.now(),te=h.kind==="browBlend"?Gr(E)??g:g;f=G,!(G===te&&h.kind!=="browBlend")&&(h.kind==="playing"||h.kind==="doublePause"||O(Q,te,G))},snapToEmotion(P){const G=it(P),Q=wt(G);l=G,c=G,f=Q,g=Q,T=performance.now(),h={kind:"idle",nextBlinkAt:performance.now()+Ze(4e3,7e3)},v(k(Q),G)},getTargetEmotion:()=>l,getTargetEyebrow:()=>f,getExpressionPath:()=>E,getDrawKey:()=>W,reset(){l="neutral",c="neutral",f=0,g=0,T=0,F(performance.now()+Ze(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=it(r);if(t.length===0)return i;if(n.length===0||e<n[0].wtime)return it(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 it(o.sentence.emotion,i);const a=n[n.length-1],u=a.wtime+a.wduration;return e>u+as?it(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],E=f.data[g+2];f.data[g+3]>0&&Math.max(T,h,E)>i&&(u.data[g]=T,u.data[g+1]=h,u.data[g+2]=E,u.data[g+3]=255)}}return o.putImageData(u,0,0),s}let mt=null,Pt=null;const dn=new Map;function io(){mt=null,Pt=null,dn.clear()}Si(io);function so(e){return e??Pt??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 Ht()?xa(await Bt(ln(),e??"")):vr(ln())}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 Bt(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=Ht();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(mt&&(!n||Pt===(t??null))){const s=await mt;return{...Ct(s),visemePaths:[...s.viseme.cellByPath.keys()]}}Pt=t??null,dn.clear();const r=Ti();mt=(async()=>{const s=await ao(t),o=await Qr(ki(),r,n,t);let a=null;try{a=await Qr(Ei(),r,n,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await mt;return{...Ct(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function _r(e){if(await Qn(e),!mt)throw new Error("Assets not loaded");return mt}function Ct(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 fn(e,t,n){const r=`${t.diffBase}::${n}`,i=dn.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=Ct(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 dn.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 E=h.getContext("2d");if(E.clearRect(0,0,g,T),E.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=Tn(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 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(Pt??void 0),i=Tn(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=pr(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await fn(r,r.viseme,c))}if(t.expressionPath&&r.expression){const l=gr(t.expressionPath,c=>r.expression.cellByPath.has(c));l&&a.push(await fn(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(Pt??void 0),r=Tn(n.viseme.atlasMeta),{width:i,height:s}=Ct(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 fn(n,n.viseme,c))}if(e.expressionPath&&n.expression){const l=gr(e.expressionPath,c=>n.expression.cellByPath.has(c));l&&o.push(await fn(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 rn={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:rn};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??rn.fontFamily,fontSize:t.fontSize??rn.fontSize,color:t.color??rn.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 C.jsx("div",{style:mo,"aria-live":"polite","aria-atomic":"true",children:C.jsx("div",{style:{...ho,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:C.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 C.jsxs("div",{style:go,"aria-hidden":!0,children:[e?C.jsx("img",{src:e,alt:"",style:{...yo,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,C.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 ut(){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),E=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:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const cs=tr,To=500,Zr=500,ko=450,On=.05,Eo=100,xo=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+xo}function mn(e){return e??ls}function Sr(e,t,n,r,i=Eo){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=ft(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:Rt(a.to),label:a.to}}}const u=vn(e);let d=Li(u,t);return d==="sil"&&(d=Gi(e,t,i)),d==="sil"?{diffPath:null,label:"sil"}:{diffPath:Rt(d),label:d}}function jt(e,t){const n=t??mn(e.expressionPath);return`${mn(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=jt(c,i),g=ut();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=jt(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=Vt,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=mn(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(),ut()?.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,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 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),ut()?.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-Vt*4),E=us(c,h,f+T,g,Vt,n);a(E)},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,ut()?.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=ut();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=mn(g.diffPath),h=jt({mouthPath:g.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),E=()=>(d(T,c.expressionPath),f?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(T,c.expressionPath)||c.playbackState.lastDrawnKey===h)return E();const W=t.findForMouthKey(T,c.elapsedMs,Vt);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
|
+
`);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=`
|
|
6
6
|
in vec2 aPosition;
|
|
7
7
|
out vec2 vTextureCoord;
|
|
8
8
|
|
|
@@ -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 ye.Filter({glProgram:ye.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 zo(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 Bt(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=ye.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 jo(e,t={}){const n=new ye.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!==ye.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 ye.Sprite(ye.Texture.EMPTY),l=new ye.Sprite(ye.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new ye.Sprite(ye.Texture.EMPTY),f=new ye.Sprite(ye.Texture.EMPTY),g=new ye.Sprite(ye.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 E=null,W=null,N=null,v=null,k=null,O=null,F=null,ie=842,re=1264,P=null,G=5;const Q=new Map;let te=null,le=null,ae=null;const oe=Si(()=>{Q.clear(),O=null,F=null,E=null,P=null}),we=(_,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=ye.Texture.EMPTY,f.texture=ye.Texture.EMPTY,te=null,le=null},z=()=>{k=null,l.visible=!1,l.alpha=0},A=()=>{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,z(),E&&(d.texture=E,A())},H=()=>{k&&D()},J=_=>{if(o||i||!E){D();return}const w=Math.max(0,_);if(!W||w<=0){D();return}ce(),g.visible=!1,d.texture=E,A(),l.texture=W,q(),l.alpha=1,l.visible=!0,k={startMs:performance.now(),durationMs:w},Y()},ee=(_=performance.now())=>{if(!k)return!1;if(o||i)return H(),!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)),R=S*S*(3-2*S);return l.alpha=1-R,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},Te=(_,w)=>{const S=_.cellByPath.get(w);if(!S||!Ji(S))return null;const R=`${_.diffBase}::${w}`;let V=Q.get(R);if(!V){const X=S.sheet??0,ue=_.sheets.get(X);if(!ue)return null;let I,j=!1;if(ue.mode==="full")I=new ye.Texture({source:ue.texture.source,frame:new ye.Rectangle(S.x,S.y,S.w,S.h)});else{const de=zo(ue.bitmap,S);I=ye.Texture.from(de),I.source.scaleMode="nearest",j=!0}V={texture:I,ownsSource:j},Q.set(R,V)}return{texture:V.texture,cell:S}},Z=(_,w,S,R)=>{if(!R||!S)return _.visible=!1,_.texture=ye.Texture.EMPTY,!1;const V=Te(S,R);if(!V)return _.visible=!1,_.texture=ye.Texture.EMPTY,!1;const X=Xi(S.atlasMeta,V.cell);return w.setThreshold(G),_.texture=V.texture,_.x=X.x,_.y=X.y,_.width=V.cell.w,_.height=V.cell.h,_.visible=!0,!0},b=_=>{if(!_||!O)return null;const w=P??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,R=>F.cellByPath.has(R)):null;w!==te?(Z(c,T,O,w),te=w):w?c.visible=!0:c.visible=!1,S!==le?(Z(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=Ht();if(w&&!_)throw new Error("Encrypted assets enabled but no key provided");const S=w?await Ea(await Bt(ln(),_??"")):await ds(ln());E&&E.destroy(!0),E=ye.Texture.from(S),E.source.scaleMode="linear";const R=Ti();O=await ri(ki(),R,w,r,_);try{F=await ri(Ei(),R,w,r,_)}catch(X){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",X),F=null}const V=Qi(O.atlasMeta,S.width,S.height);return we(V.width,V.height),G=Tn(O.atlasMeta),T.setThreshold(G),h.setThreshold(G),P=new Set(O.cellByPath.keys()),Q.clear(),D(),ce(),Y(),{width:V.width,height:V.height,visemePaths:[...O.cellByPath.keys()]}},getVisemeAtlasPaths(){return P},drawLiveFrame(_){o||i||!E||(H(),U(_),Y())},drawIdleVideo(_,w){o||i||document.hidden||w&&!w()||_.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(k=null,ce(),g.visible=!1,E&&(d.texture=E,A()),!W||v!==_?(ne(),N=new ye.VideoSource({resource:_,autoPlay:!1,updateFPS:0}),N.autoUpdate=!1,W=new ye.Texture({source:N}),v=_):W.source.update(),l.texture=W,q(),l.alpha=1,l.visible=!0,Y())},beginIdleToSilCrossfade:J,tickIdleToSilCrossfade:ee,finishIdleToSilCrossfade:H,isIdleToSilCrossfading(){return k!=null},renderSilOnly(){o||i||!E||(ce(),D(),Y())},blitBitmap(_){o||i||(H(),ce(),ae&&(ae.destroy(!0),ae=null),ae=ye.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(),E&&(E.destroy(!0),E=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,sn=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:Rt(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=sn;const f=Tr(async(N,v,k)=>(d.set(v,{drawKey:k.drawKey,onDisplayed:k.onDisplayed}),await E({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,[])},E=(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<=-sn){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)){ut()?.onWorkerStale(),v.bitmap.close();return}}if(O&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){ut()?.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 E({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 E({type:"loadAssets",keyHex:N,urls:zs(yt())})??{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=sn;const N=s;await E({type:"cancelLiveDraws"}),await E({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}),E({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 E({type:"cancelLiveDraws"}),await E({type:"renderViseme",generation:O,to:v,from:k.from,transitionDurationMs:k.transitionDurationMs,gapMs:k.gapMs,threshold:k.threshold},void 0,!0)}catch(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=sn;for(const[,N]of T)N.resolve();T.clear(),r?.terminate(),r=null}}}}async function Go(e,t){const n=await jo(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()?(ut()?.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:Rt(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)?pn:dr}function rt(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=Kt,className:c,style:f,canvasStyle:g,onStatusChange:T,onDisplayStatus:h,onError:E,onReady:W,showErrorOverlay:N=!0,loadingThumbnailUrl:v,onUserTranscript:k,onBotOutput:O,onRealtimeLipsyncDebug:F,onFrameRenderStats:ie,lipsyncBufferedPlayback:re=!0,lipsyncPlaybackWarmupMs:P=1500,idleHandoffHoldMs:G=To,pixiMaxTextureSize:Q,captions:te},le){const ae=m.useRef(null),oe=m.useRef(null),we=m.useRef(null),ce=m.useRef(re);ce.current=re;const z=m.useRef(P);z.current=P;const A=m.useRef(G);A.current=G;const q=m.useRef(0),D=m.useRef(br()),H=m.useRef(Ja()),J=m.useRef(!1),ee=m.useRef(null),ne=m.useRef(null),Te=m.useRef(0),Z=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),R=m.useRef(!1),V=m.useRef(!1),X=m.useRef("sil"),ue=m.useRef(0),I=m.useRef(!1),j=m.useRef(null),de=m.useRef(!1),[Re,Ft]=m.useState("idle"),[vt,_t]=m.useState(null),[ct,kn]=m.useState(!1),[p,B]=m.useState(!1),[se,fe]=m.useState(!1),[_e,xe]=m.useState(),[Pe,je]=m.useState({width:842,height:1264}),[Ue,Gt]=m.useState(null),[En,Lt]=m.useState(0),bt=m.useRef(!1),Oe=m.useRef(s??null),qe=o?.trim()||Dt,St=m.useRef(null),Ie=m.useRef(null),{ttsEngineId:Ce,voiceId:Ye}=m.useMemo(()=>{const y=st(a,u),x=y.ttsEngineId??ht;return{ttsEngineId:x,voiceId:y.voiceId??Wn(x)}},[a,u]),Ve=m.useCallback(y=>{const x=wi(y);D.current.holdPp=x,we.current?.setHoldPp(x)},[]),We=m.useRef(!1),Ae=m.useRef({width:842,height:1264}),Be=m.useRef(null),He=m.useRef("sil"),tt=m.useRef(""),$e=m.useMemo(()=>fo(te),[te]),ze=m.useCallback(()=>{tt.current="",Gt(null)},[]);m.useEffect(()=>{$e.enabled||ze()},[$e.enabled,ze]);const Tt=m.useCallback(y=>{if(!$e.enabled)return;const x=y.isSpeaking(),L=y.isWarmingUp();if(!x||L){tt.current&&ze();return}const M=uo(y.getWordQueue());if(!M){tt.current&&ze();return}M!==tt.current&&(tt.current=M,Gt(M))},[$e.enabled,ze]),kt=m.useRef(void 0),xn=m.useRef(new Map),kr=m.useRef(W),Er=m.useRef(T),ke=m.useRef(h),xr=m.useRef(E),Ir=m.useRef(k),In=m.useRef(O),qt=m.useRef(F),Ar=m.useRef(ie),Et=m.useRef(So());kr.current=W,Er.current=T,ke.current=h,xr.current=E,Ir.current=k,In.current=O,qt.current=F,Ar.current=ie,m.useEffect(()=>{const y=Et.current;return Xr(y),()=>Xr(null)},[]);const An=m.useCallback(y=>{const x=st(y?.ttsEngineId??a,y?.voiceId??u),L=x.ttsEngineId??Ie.current?.ttsEngineId??ht,M=x.voiceId??Ie.current?.voiceId??Wn(L);return{ttsEngineId:L,voiceId:M}},[a,u]),nt=m.useCallback(y=>{_t(y),fe(!0),xr.current?.(y)},[]),Nt=m.useCallback(y=>{Ft(y),Er.current?.(y)},[]),he=m.useRef(qn(Nt,qe,{onLipsyncDebug:y=>qt.current?.(y)})),ge=m.useRef(null),Yt=m.useRef(!1),Mr=m.useRef(()=>{});m.useEffect(()=>(he.current=qn(Nt,qe,{onLipsyncDebug:y=>qt.current?.(y)}),s&&he.current.setDeveloperToken(s),he.current.setTtsEngineId(Ce),he.current.setMuted(Yt.current),()=>{he.current.stop();const y=ge.current;y&&(y.disconnect(),ge.current=null)}),[Nt,qe]);const Rr=m.useCallback(()=>(ge.current||(ge.current=Yi(Nt,{speakingRate:l,language:d,onUserTranscript:(y,x)=>Ir.current?.(y,x),onBotOutput:y=>In.current?.(y),onLipsyncDebug:y=>qt.current?.(y)}),ge.current.setTtsEngineId(Ce),ge.current.setMuted(Yt.current),Mr.current(!0)),ge.current),[Nt,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(),j.current?.setLooping(!1)},[Fe]),Ke=m.useCallback(()=>{V.current=!1,j.current?.setLooping(!0)},[]),Ot=m.useCallback(()=>{if(R.current)return;const y=oe.current;if(R.current=!0,V.current=!0,Fe(),_.current=!1,w.current=!1,!de.current||!j.current){y?.renderSilOnly();return}const x=j.current;x.setLooping(!1),x.setActive(!1);const L=x.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 $=ae.current;$&&await Nn($,L,null,void 0,Ae.current).catch(()=>{}),await new Promise(ve=>setTimeout(ve,Zr)),R.current&&await y?.renderSilOnly()})()},[Fe]),Pr=m.useCallback(()=>{if(!(!de.current||!j.current)){if(R.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,rt(he.current,ge.current).isSpeaking()){S.current=!1;return}if(_.current){S.current=!1;return}if(V.current){S.current=!1;return}const y=j.current;if(!y){S.current=!1;return}Ke(),y.setLooping(!0),y.restart(),y.setActive(!0);const x=y.getVideo();let L=!1;const M=()=>{L||(L=!0,x.removeEventListener("playing",$),S.current=!1)},$=()=>{M()};if(x.addEventListener("playing",$,{once:!0}),x.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!x.paused){M();return}setTimeout(M,300)},A.current)}},[Fe,Ke]),xt=m.useCallback(()=>{if(Le(),ke.current?.("sil"),_.current=!1,R.current=!1,!de.current||!j.current){S.current=!1,Ke();return}Pr()},[Le,Pr,Ke]),Rn=m.useCallback(async y=>{const x=Z.current,L=oe.current,M=ae.current,$=()=>{y?.fallbackOnly||(_.current=!1)};if(!L||!M||!ct){$();return}if(rt(he.current,ge.current).isSpeaking()){$();return}if(y?.fallbackOnly){if(!_.current||(Ne(D.current),await L.renderSilOnly(),x!==Z.current)||rt(he.current,ge.current).isSpeaking())return;xt();return}if(ei(D.current)){Ne(D.current),xt();return}if(ce.current&&L.supportsBufferedPlayback&&!y?.fallbackOnly){if(Ne(D.current),we.current?.reset(),await L.renderSilOnly(),x!==Z.current||rt(he.current,ge.current).isSpeaking())return;xt();return}const be=Mo(rt(he.current,ge.current).getVisemeQueue(),ue.current,X.current),De=Ro(be,Be.current);if(Ne(D.current),!De){if(await L.renderSilOnly(),x!==Z.current||rt(he.current,ge.current).isSpeaking())return;xt();return}try{await L.renderViseme(M,"sil",{from:be,transitionDurationMs:cs})}catch(Ee){if(Ee?.name!=="AbortError")throw Ee}if(x!==Z.current){$();return}if(rt(he.current,ge.current).isSpeaking()){$();return}xt()},[ct,xt]),dt=m.useCallback(()=>{if(w.current||_.current)return;w.current=!0,_.current=!0,Le();const y=Z.current;Rn().finally(()=>{w.current=!1}),U.current=setTimeout(()=>{U.current=null,y===Z.current&&Rn({fallbackOnly:!0})},Po())},[Le,Rn]),Cr=m.useCallback(async()=>{const y=Math.floor(Date.now()/1e3);if(St.current&&y<St.current.expiresAt-60)return St.current.key;const x=Oe.current??await an();Oe.current=x,he.current.setDeveloperToken(x);const L=await Os(x,qe);return St.current={key:L.value,expiresAt:L.expiresAt},L.value},[qe]);m.useEffect(()=>{s&&(Oe.current=s,he.current.setDeveloperToken(s))},[s]),m.useEffect(()=>{he.current.setTtsEngineId(Ce),ge.current?.setTtsEngineId(Ce),Ie.current&&(Ie.current.ttsEngineId=Ce),Ve(Ce)},[Ce,Ve]),m.useEffect(()=>{Ie.current&&(Ie.current.voiceId=Ye)},[Ye]);const Qe=m.useMemo(()=>_i(n,r),[n,r]),ps=m.useMemo(()=>i?JSON.stringify(i):Qe?`face:${Qe}`:`id:${t??""}`,[i,Qe,t]),ws=m.useMemo(()=>{const y=v?.trim();return y||(Fr(Qe)??Fr(_e)??Cs(i))},[v,Qe,_e,i]);return m.useEffect(()=>{if(!t&&!i&&!Qe){nt("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let y=!1;We.current=!1,kn(!1),B(!1),fe(!1),xe(Qe),_t(null),Ie.current=null,j.current=null,de.current=!1;const x=ae.current;if(!x)return;let L=null;return(async()=>{try{let M,$,ve,be,De;if(i)M=i,$=Ce,ve=Ye;else if(Qe)ke.current?.("loadFace"),M=Kn(Qe),$=Ce,ve=Ye;else{ke.current?.("getAiTwin");const K=await Vn(yi(t),3e4,"getAiTwin");if(y)return;if(!K.faceId?.trim())throw new Error("getAiTwin returned no faceId");xe(K.faceId.trim());const Se=st(a,u);$=Se.ttsEngineId??K.ttsEngineId,ve=Se.voiceId??K.voiceId??Wn($),be=ir(K),De=sr(K),M=Kn(K.faceId)}Ie.current={ttsEngineId:$,voiceId:ve,brainId:be,brainUrl:De},bi(M),j.current=Za();const Ee=!!(i&&!gt(i));L=qo(x,{preferLegacyRenderer:Ee,pixiMaxTextureSize:Q,onStatus:K=>{y||ke.current?.(K)},onError:K=>{y||nt(K)},shouldAcceptLiveFrame:()=>{if(J.current)return!0;if(_.current)return!1;const K=rt(he.current,ge.current);return K.isSpeaking()||K.isWarmingUp()},onWebGlContextLost:()=>{y||bt.current||(bt.current=!0,queueMicrotask(()=>{y||Lt(K=>K+1)}))}}),oe.current=L,we.current=Lo(L),Ve($),bt.current=!1;const Xe=K=>{const Se=()=>{if(!K||z.current<=0)return!1;const Me=oe.current;return Me?ce.current&&Me.supportsBufferedPlayback?!0:Me.usesPixi:!1};he.current.setLipsyncWarmupHold(K,Se),ge.current?.setLipsyncWarmupHold(K,Se)};Mr.current=Xe,Xe(!0),ke.current?.("auth");const Qt=Oe.current??s??await Vn(an(),3e4,"getAuthToken");if(y)return;Oe.current=Qt,he.current.setDeveloperToken(Qt),he.current.setTtsEngineId($);const pe=Ht()?await Cr():void 0;if(y)return;ke.current?.("loadAssets");const me=await Vn(L.loadAssets(pe),18e4,"load face assets");if(!y&&me.width>0&&me.height>0&&(Ae.current=me,je(me)),y)return;Be.current=L.getVisemeAtlasPaths(),We.current=!0,kn(!0),kr.current?.(),L.renderSilOnly().then(()=>{y||ke.current?.("sil")}),(async()=>{try{const K=await Aa(pe);if(await j.current.load(K),y||(de.current=!0,B(!0),Ne(D.current),await L.renderSilOnly(),y)||(await new Promise(Me=>setTimeout(Me,A.current)),y))return;j.current.setActive(!0);const Se=j.current.getVideo();L.usesPixi?L.drawIdleVideo(Se):await Nn(x,Se,null,void 0,Ae.current)}catch(K){if(y)return;de.current=!1,B(!1),console.warn("[AiTwin] Idle video unavailable:",K)}finally{y||(fe(!0),ke.current?.("idle"))}})()}catch(M){if(y)return;if(M instanceof on){nt(M.message);return}nt(M instanceof Error?M.message:"Failed to load AI twin")}})(),()=>{y=!0,j.current?.dispose(),L?.dispose(),oe.current=null}},[ps,i,Qe,t,Ce,Ye,a,u,s,Q,Cr,nt,En,Ve]),m.useEffect(()=>{const y={current:!1},x=()=>{const L=ae.current,M=oe.current,$=rt(he.current,ge.current);if(!L||!M||!ct){Te.current=requestAnimationFrame(x);return}if(document.hidden){j.current?.setActive(!1),Te.current=requestAnimationFrame(x);return}const ve=$.isSpeaking(),be=$.isWarmingUp(),De=ve&&!I.current,Ee=I.current&&!ve;De&&(Le(),Fe(),_.current=!1,w.current=!1,Ne(D.current),we.current?.reset(),Et.current.reset(),kt.current=void 0,b.current=0,X.current="sil",ue.current=0,Ot()),Ee&&(H.current.reset(),j.current?.setActive(!1),we.current?.reset(),M.finishIdleToSilCrossfade(),ze(),V.current=!1,dt());const Xe=Ee||_.current||S.current||R.current,Qt=re&&M.supportsBufferedPlayback;if(V.current&&!ve&&!be&&!Ee&&!_.current&&!S.current){if(R.current){M.usesPixi&&M.isIdleToSilCrossfading()&&M.tickIdleToSilCrossfade(performance.now()),I.current=ve,Te.current=requestAnimationFrame(x);return}if(de.current&&j.current){const pe=j.current.getVideo();if(pe.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){const me=pe.duration,K=pe.currentTime,Se=pe.ended||Number.isFinite(K)&&K<=On,Me=Number.isFinite(me)&&me>0&&Number.isFinite(K)?Math.max(0,(me-K)*1e3):Number.POSITIVE_INFINITY;if(Se||Me<=ko){Ot(),M.usesPixi&&M.isIdleToSilCrossfading()&&M.tickIdleToSilCrossfade(performance.now()),I.current=ve,Te.current=requestAnimationFrame(x);return}}}}if(be){if(Ot(),de.current&&j.current?.setActive(!1),M.usesPixi&&M.isIdleToSilCrossfading()){M.tickIdleToSilCrossfade(performance.now()),$.getVisemeQueue().length>0&&q.current===0&&(q.current=performance.now()),I.current=$.isSpeaking(),Te.current=requestAnimationFrame(x);return}const pe=$.getVisemeQueue();pe.length>0&&q.current===0&&(q.current=performance.now()),H.current.advance(performance.now());const me=H.current.getExpressionPath(),K=H.current.getDrawKey(),Se={queue:pe,elapsedMs:0,expressionPath:me,expressionDrawKey:K,availablePaths:Be.current};let Me=!1;Qt&&we.current?(we.current.warmupTick(Se),Me=we.current.isWarmupReady(Se,z.current)):M.usesPixi&&ti(L,pe,0,me,K,D.current,(It,Xt,Pn,Jt)=>{M.drawLiveFrame(It,Xt,Pn,Je=>{Jt?.(Je),$.isWarmingUp()&&Je!==""&&!ei({lastDrawnKey:Je})&&(q.current=0,$.releaseWarmupHold())})},It=>{ke.current?.(It.label)},Be.current);const lt=q.current>0&&performance.now()-q.current>xs;ke.current?.(Me?"buffer ready":"buffering lipsync…"),(Me||lt)&&(q.current=0,$.releaseWarmupHold()),Tt($),I.current=$.isSpeaking(),Te.current=requestAnimationFrame(x);return}if(ve){Ot(),de.current&&j.current?.setActive(!1),M.usesPixi&&M.isIdleToSilCrossfading()&&M.finishIdleToSilCrossfade();const pe=$.getVisemeQueue(),me=$.getPlaybackElapsedMs();ha(pe,me),ue.current=me;const K=pe.length>0?$t(pe,me):"sil";K!=="sil"&&(X.current=K);const Se=ro(me,$.getSentenceEmotions(),$.getWordQueue(),$.getStreamMood());H.current.setTargetEmotion(Se),H.current.setTargetEyebrow(Qa(me,$.getWordQueue(),wt(Se))),H.current.advance(performance.now());const Me=H.current.getExpressionPath(),lt=H.current.getDrawKey(),It=(Je,Cn,Ut,Dn)=>{const Dr={label:He.current,elapsedMs:me,mouthPath:Cn.mouthPath,transitionMeta:kt.current};xn.current.set(Ut,Dr),we.current?.markExternallyDisplayed(Ut,Me),M.drawLiveFrame(Je,Cn,Ut,Zt=>{const gs=xn.current.get(Zt)??Dr;xn.current.delete(Zt),Et.current.onDrawDisplayed(gs,pe),we.current?.markExternallyDisplayed(Zt,Me),Dn?.(Zt)})},Xt=Je=>{He.current=Je.label,kt.current=Je.transitionMeta,ke.current?.(Je.label)},Pn=re&&M.supportsBufferedPlayback;let Jt=!1;Pn&&we.current&&(Jt=we.current.tick({canvas:L,queue:pe,elapsedMs:me,expressionPath:Me,expressionDrawKey:lt,playbackState:D.current,availablePaths:Be.current,onStatus:Xt,onDisplayed:(Cn,Ut,Dn)=>{Et.current.onDrawDisplayed({label:Dn,elapsedMs:me,mouthPath:Ut,transitionMeta:kt.current},pe)}}).usedBuffer),Jt||ti(L,pe,me,Me,lt,D.current,It,Xt,Be.current),Et.current.onRafTickSpeaking(),Ar.current?.(Et.current.snapshot(pe,me))}else if(!Xe&&J.current){j.current?.setActive(!1),H.current.advance(performance.now());const pe=H.current.getExpressionPath(),me=H.current.getDrawKey();Un(L,pe,me,D.current,(K,Se,Me,lt)=>M.drawLiveFrame(K,Se,Me,lt),K=>{if(ne.current){ke.current?.(ne.current);return}const Se=H.current.getTargetEmotion();ke.current?.(K==="sil"||K==="blink"?`${Se}${K==="blink"?" · blink":""}`:K)},null,ee.current)}else if(!Xe&&de.current&&j.current){const pe=j.current,me=pe.getVideo();if(me.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){pe.setActive(!0);const K=()=>!$.isSpeaking()&&!_.current&&!S.current&&!J.current;M.usesPixi?(M.drawIdleVideo(me,K),K()&&ke.current?.("idle")):y.current||(y.current=!0,Nn(L,me,null,void 0,Ae.current,K).then(()=>ke.current?.("idle")).finally(()=>{y.current=!1}))}else Un(L,null,"__sil__",D.current,(K,Se,Me,lt)=>M.drawLiveFrame(K,Se,Me,lt),K=>ke.current?.(K))}else Xe||Un(L,null,"__sil__",D.current,(pe,me,K,Se)=>M.drawLiveFrame(pe,me,K,Se),pe=>ke.current?.(pe));$e.enabled&&Tt($),I.current=ve,Te.current=requestAnimationFrame(x)};return Te.current=requestAnimationFrame(x),()=>{cancelAnimationFrame(Te.current),Le(),Fe(),he.current.stop(),ge.current?.stop()}},[ct,p,dt,Le,Fe,Ot,Tt,ze,$e.enabled]),m.useImperativeHandle(le,()=>({speakText:async(y,x)=>{const L=y.trim();if(!L)return;const M=oe.current;if(!M||!We.current&&!ct)throw new Error("AI twin is not ready");const{ttsEngineId:$,voiceId:ve}=An(x);_t(null),ze(),Z.current+=1,Le(),Fe(),_.current=!1,w.current=!1,X.current="sil",ue.current=0,Ne(D.current),Ve($),J.current=!1,ee.current=null,ne.current=null,H.current.reset(),I.current=!1,Mn(),R.current=!1,M.finishIdleToSilCrossfade();try{await he.current.speak(L,{voiceId:ve,speakingRate:x?.speakingRate??l,ttsEngineId:$,language:x?.language??d})}catch(be){throw Ke(),R.current=!1,M.finishIdleToSilCrossfade(),dt(),nt(be instanceof Error?be.message:"TTS failed"),be}},speakWithReply:async(y,x)=>{const L=y.trim();if(!L)return{displayText:"",spokenText:""};const M=oe.current;if(!M||!We.current&&!ct)throw new Error("AI twin is not ready");const{ttsEngineId:$,voiceId:ve}=An(x);_t(null),ze(),Z.current+=1,Le(),Fe(),_.current=!1,w.current=!1,X.current="sil",ue.current=0,Ne(D.current),Ve($),J.current=!1,ee.current=null,ne.current=null,H.current.reset(),I.current=!1,Mn(),R.current=!1,M.finishIdleToSilCrossfade();const be=x?.brainId?.trim()||Ie.current?.brainId?.trim()||void 0,De=x?.brainUrl?.trim()||Ie.current?.brainUrl?.trim()||void 0;try{return await he.current.speakWithReply(L,{...x,voiceId:ve,speakingRate:x?.speakingRate??l,ttsEngineId:$,language:x?.language??d,brainId:be,brainUrl:De,onDisplayText:Ee=>{x?.onDisplayText?.(Ee),In.current?.(Ee)}})}catch(Ee){throw Ke(),R.current=!1,M.finishIdleToSilCrossfade(),dt(),nt(Ee instanceof Error?Ee.message:"speakWithReply failed"),Ee}},stop:()=>{Z.current+=1,Le(),Fe(),_.current=!1,w.current=!1,R.current=!1,Ke(),oe.current?.finishIdleToSilCrossfade(),he.current.stop(),ge.current?.stop(),Ne(D.current),we.current?.reset(),q.current=0,I.current=!1,ze(),dt()},setTtsEngineId:y=>{he.current.setTtsEngineId(y),ge.current?.setTtsEngineId(y),Ie.current&&(Ie.current.ttsEngineId=y),Ve(y)},renderViseme:async(y,x)=>{const L=oe.current,M=ae.current;if(!L||!M||!We.current)throw new Error("AI twin is not ready");await L.renderViseme(M,y,{from:x?.from,transitionDurationMs:x?.transitionDurationMs,gapMs:x?.gapMs,onStatus:$=>ke.current?.($)})},setEmotion:y=>{if(!We.current)throw new Error("AI twin is not ready");const x=oe.current,L=ae.current;if(!x||!L)throw new Error("AI twin is not ready");Z.current+=1,Le(),Fe(),_.current=!1,w.current=!1,S.current=!1,R.current=!1,Ke(),he.current.stop(),ge.current?.stop(),Ne(D.current),we.current?.reset(),q.current=0,I.current=!1,x.finishIdleToSilCrossfade(),j.current?.setActive(!1);const M=it(y);J.current=!0,ee.current=null,ne.current=null,H.current.snapToEmotion(M);const $=H.current.getExpressionPath(),ve=H.current.getDrawKey(),be={mouthPath:null,expressionPath:$},De=jt(be,ve);D.current.lastDrawnKey="",x.drawLiveFrame(L,be,De,Xe=>{Xe===De&&(D.current.lastDrawnKey=De)});const Ee=wt(M);ke.current?.($?`${M} · brow ${Ee>0?"+":""}${Ee}`:`${M} · brow 0 (sil base)`)},getEmotion:()=>J.current?H.current.getTargetEmotion():null,clearEmotionPreview:()=>{J.current=!1,ee.current=null,ne.current=null,H.current.reset(),Ne(D.current),ke.current?.("idle")},setViseme:y=>{if(!We.current)throw new Error("AI twin is not ready");const x=oe.current,L=ae.current;if(!x||!L)throw new Error("AI twin is not ready");Z.current+=1,Le(),Fe(),_.current=!1,w.current=!1,S.current=!1,R.current=!1,Ke(),he.current.stop(),ge.current?.stop(),Ne(D.current),we.current?.reset(),q.current=0,I.current=!1,x.finishIdleToSilCrossfade(),j.current?.setActive(!1);const M=gn(y);J.current=!0,ne.current=M,ee.current=M==="sil"?null:Rt(M),H.current.snapToEmotion("neutral");const $=H.current.getExpressionPath(),ve=H.current.getDrawKey(),De={mouthPath:ee.current,expressionPath:$},Ee=jt(De,ve);D.current.lastDrawnKey="",x.drawLiveFrame(L,De,Ee,Xe=>{Xe===Ee&&(D.current.lastDrawnKey=Ee)}),ke.current?.(M)},getViseme:()=>J.current?ne.current:null,isReady:()=>We.current,getStatus:()=>Re,connect:async(y={})=>{_t(null);try{let x=y.authToken?.trim();x||(x=Oe.current??s??await an(),Oe.current=x);const L=st(y.ttsEngineId??a,y.voiceId??u),M=L.voiceId??Ie.current?.voiceId,$=y.brainId?.trim()||y.personaId?.trim()||Ie.current?.brainId,ve=y.brainUrl?.trim()||Ie.current?.brainUrl,be=L.ttsEngineId??Ie.current?.ttsEngineId??Ce,De=Rr();be&&De.setTtsEngineId(be),be&&Ve(be),await De.unlockAudio(),await De.connect({...y,apiBase:y.apiBase?.trim()||qe,authToken:x,voiceId:M,brainId:$,brainUrl:ve,ttsEngineId:be,speakingRate:y.speakingRate??l,language:y.language??d})}catch(x){throw Wt(x)||nt(x instanceof Error?x.message:"Voice connect failed"),x}},disconnect:async()=>{const y=ge.current;y&&(Z.current+=1,Le(),Fe(),_.current=!1,w.current=!1,R.current=!1,Ke(),oe.current?.finishIdleToSilCrossfade(),Ne(D.current),we.current?.reset(),q.current=0,I.current=!1,await y.disconnect(),dt())},isConnected:()=>ge.current?.isConnected()??!1,getVoiceStream:()=>ge.current?.getVoiceStream()??he.current?.getVoiceStream()??null,setMuted:y=>{Yt.current=y,he.current?.setMuted(y),ge.current?.setMuted(y)},isMuted:()=>Yt.current,getBrainId:()=>Ie.current?.brainId?.trim()||null,getPersonaId:()=>Ie.current?.brainId?.trim()||null,getBrainUrl:()=>Ie.current?.brainUrl?.trim()||null}),[ct,l,d,s,Ce,Ye,Le,Fe,dt,Mn,Ke,nt,An,Rr,Ve,Re,qe]),C.jsxs("div",{className:c,style:{...Qo,...f},children:[C.jsx("canvas",{ref:ae,width:Pe.width,height:Pe.height,style:{...Xo,...g},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!se&&!vt?C.jsx(_o,{thumbnailUrl:ws}):null,N&&vt?C.jsx("div",{style:Jo,children:vt}):null,$e.enabled&&Ue?C.jsx(wo,{text:Ue,style:$e.style},Ue):null]})});function Zo({muted:e}){return e?C.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[C.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),C.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):C.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[C.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),C.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 C.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:C.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function tc(){return C.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:C.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function nc(){return C.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:C.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 C.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:C.jsx("path",{d:"M15 6 9 12l6 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function ic(){return C.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:C.jsx("path",{d:"M12 19V5m0 0-6 6m6-6 6 6",stroke:"currentColor",strokeWidth:"2.25",strokeLinecap:"round",strokeLinejoin:"round"})})}function ci({className:e}){return C.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:C.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:C.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function sc({muted:e,onToggle:t}){return C.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:C.jsx(Zo,{muted:e})})}function ac(e){const t=e.connecting||e.textSending||e.status==="loading"||e.status==="speaking",n=e.connecting?"Connecting...":e.connected?"End":"Talk",r=["aitwin-widget__action","aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return C.jsxs("div",{className:e.textMode?"aitwin-widget__controls aitwin-widget__controls--text":"aitwin-widget__controls",children:[e.textMode?C.jsxs("form",{className:"aitwin-widget__composer",onSubmit:i=>{i.preventDefault(),e.onSendText()},children:[C.jsx("button",{type:"button",className:"aitwin-widget__composer-back",onClick:e.onTextMode,disabled:e.textSending,"aria-label":"Back",children:C.jsx(rc,{})}),C.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:i=>e.onTextDraftChange(i.target.value),placeholder:e.textSending?"Getting reply...":"Type a message...",autoComplete:"off",disabled:!e.ready||t,autoFocus:!0}),C.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||t||!e.textDraft.trim()&&!e.textSending,"aria-label":"Send","aria-busy":e.textSending,children:e.textSending?C.jsx(ci,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):C.jsx(ic,{})})]}):C.jsxs("div",{className:"aitwin-widget__actions",children:[C.jsxs("button",{type:"button",className:r,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,children:[e.connecting?C.jsx(ci,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?C.jsx(tc,{}):C.jsx(ec,{}),C.jsx("span",{children:n})]}),C.jsxs("button",{type:"button",className:"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":!1,children:[C.jsx(nc,{}),C.jsx("span",{children:"Text"})]})]}),e.error?C.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const li=97,oc=3500;function cc(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/oc);return Math.min(li,Math.round(r*li))}function lc(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:cc(r-t):100}const uc="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 dc({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:n=2600,delayMs:r=0,loop:i=!1}){return C.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:C.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:uc,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function fc({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return C.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:C.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[C.jsx(dc,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),C.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[C.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:C.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),C.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 mc(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},hc={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},pc=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,E]=m.useState(!1),[W,N]=m.useState("idle"),[v,k]=m.useState(null),[O,F]=m.useState(!1),[ie,re]=m.useState(!1),[P,G]=m.useState(""),[Q,te]=m.useState(!1),[le,ae]=m.useState([]),[oe,we]=m.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),[ce,z]=m.useState(t.brainUrl?.trim()||void 0),A=m.useCallback(I=>{i.current={...i.current,...I},I.showControls!==void 0&&o(!!I.showControls),(I.brainId!==void 0||I.personaId!==void 0)&&we((I.brainId??I.personaId)?.trim()||void 0),I.brainUrl!==void 0&&z(I.brainUrl.trim()||void 0),u(j=>ui({id:I.id??j.id,faceId:I.faceId??I.avatarId??j.faceId,authToken:I.authToken??j.authToken,apiBase:I.apiBase??j.apiBase,voiceId:I.voiceId??j.voiceId,speakingRate:I.speakingRate??j.speakingRate,language:I.language??j.language}))},[]);m.useImperativeHandle(n,()=>({getTwin:()=>r.current,applyOptions:A}),[A]),m.useEffect(()=>{A(t)},[A,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(I=>{I==="idle"&&f(!0)},[]),H=m.useCallback(I=>{N(I),i.current.onStatusChange?.(I)},[]),J=m.useRef(!1);J.current=d&&c;const ee=m.useCallback(I=>{if(E(!1),Wt(I)){re(!0),k(null);return}k(I),J.current||(l(!1),f(!1)),i.current.onError?.(I)},[]),ne=m.useCallback((I,j)=>{i.current.onUserTranscript?.(I,j)},[]),Te=m.useCallback(I=>{i.current.onBotOutput?.(I)},[]);m.useEffect(()=>{if(!s)return;const I=window.setInterval(()=>{T(!!r.current?.isConnected())},400);return()=>window.clearInterval(I)},[s,a]);const Z=mc(a),b=!!(a.id||a.faceId),U=d&&c,Y=b&&!U&&!v,_=lc(Y),w=m.useRef(Z);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!==Z&&(w.current=Z,l(!1),f(!1),k(null),E(!1),T(!1),N("idle"))},[Z]);const S=m.useCallback(()=>{re(!0),k(null),E(!1),T(!1)},[]),R=()=>{const I=r.current;if(!I?.isReady())return;if(k(null),I.isConnected()){E(!1),re(!1),I.disconnect().finally(()=>{T(!1)});return}E(!0);const j={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 I.connect(j),T(!!I.isConnected())}catch(de){if(Wt(de)){S();return}const Re=de instanceof Error?de.message:"Failed to connect voice.";k(Re),i.current.onError?.(Re)}finally{E(!1)}})()},V=()=>{re(I=>!I),k(null)},X=()=>{const I=P.trim(),j=r.current;!I||!j?.isReady()||Q||(k(null),G(""),te(!0),i.current.onUserTranscript?.(I,!0),(async()=>{try{const de=oe||j.getBrainId()?.trim()||void 0,Re=ce||j.getBrainUrl()?.trim()||void 0,Ft=await j.speakWithReply(I,{brainId:de,brainUrl:Re,history:le,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language});Ft.displayText&&ae(vt=>[...vt,{role:"user",content:I},{role:"assistant",content:Ft.displayText}])}catch(de){const Re=de instanceof Error?de.message:"Failed to get reply.";k(Re),i.current.onError?.(Re)}finally{te(!1)}})())},ue=()=>{const I=!O;F(I),r.current?.setMuted(I)};return C.jsxs("div",{className:"aitwin-widget__layout",children:[C.jsxs("div",{className:"aitwin-widget__stage",children:[b?C.jsx("div",{style:di,children:C.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:hc,onReady:q,onDisplayStatus:D,onStatusChange:H,onError:ee,onUserTranscript:ne,onBotOutput:Te,loadingThumbnailUrl:t.loadingThumbnailUrl},Z)}):C.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),Y?C.jsx(fc,{progress:_}):null,s?C.jsx(sc,{muted:O,onToggle:ue}):null]}),s?C.jsx(ac,{ready:U,connected:g,connecting:h,status:W,textMode:ie,textDraft:P,textSending:Q,error:v,onTalk:R,onTextMode:V,onTextDraftChange:G,onSendText:X}):null]})}),wc=".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;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(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--on-accent{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 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=wc.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 gc=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 C.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:C.jsx(pc,{ref:r,options:t})})}),yc=new Set([".png",".jpg",".jpeg",".webp"]);function hs(e=".png"){const t=e.toLowerCase();return yc.has(t)?`source${t}`:"source.png"}function vc(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 _c(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 bc(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()||Dt).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 _c(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
|
|
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;
|