@streamoji/avatar-widget 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),We=require("@react-three/drei"),Xe=require("@react-three/fiber"),t=require("react"),kt=require("three"),At=require("three/examples/jsm/loaders/GLTFLoader.js");function Lt(c){const w=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(c){for(const m in c)if(m!=="default"){const h=Object.getOwnPropertyDescriptor(c,m);Object.defineProperty(w,m,h.get?h:{enumerable:!0,get:()=>c[m]})}}return w.default=c,Object.freeze(w)}const Ce=Lt(kt),W=(...c)=>{},Et=(...c)=>{},ot=({analyser:c})=>{const w=t.useRef(null),m=t.useRef(null);return t.useEffect(()=>{const h=w.current;if(!h)return;const C=h.getContext("2d",{alpha:!0});if(!C)return;let E,A=null;c&&(c.fftSize=128,A=new Uint8Array(c.frequencyBinCount));const le=()=>{E=requestAnimationFrame(le),(h.width!==h.offsetWidth||h.height!==h.offsetHeight)&&(h.width=h.offsetWidth,h.height=h.offsetHeight);const ee=h.width,O=h.height;if(ee===0||O===0)return;const y=O/2;C.clearRect(0,0,ee,O),C.fillStyle="#1e293b";const X=2,L=X+2,ie=ee*.95,b=Math.floor(ie/L);(!m.current||m.current.length!==b)&&(m.current=new Float32Array(b).fill(2));const xe=b*L,K=(ee-xe)/2;c&&A&&c.getByteFrequencyData(A);const de=A?A.length:0,H=Math.floor(de*.7)/b,M=new Float32Array(b);for(let g=0;g<b;g++){let V=0;if(A&&H>0){const _=Math.floor(g*H),Y=Math.floor((g+1)*H);for(let q=_;q<Y;q++){const oe=A[q]||0;oe>V&&(V=oe)}}V<10&&(V=0);const R=V/255,x=V>0?Math.max(2,Math.pow(R,1.4)*O*.25):2;M[g]=x}for(let g=0;g<b;g++){const V=b-1-g,R=Math.max(M[g],M[V]),x=m.current[g]+(R-m.current[g])*.3;m.current[g]=x;const _=K+g*L,Y=y-x/2;C.beginPath(),C.roundRect?C.roundRect(_,Y,X,x,4):C.fillRect(_,Y,X,x),C.fill()}};return le(),()=>{cancelAnimationFrame(E)}},[c]),o.jsx("canvas",{ref:w,style:{width:"100%",height:"100%",display:"block"}})},at="https://ai.streamoji.com",Tt="https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev",ct="https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";async function Mt(c){const w=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(c));return Array.from(new Uint8Array(w)).map(m=>m.toString(16).padStart(2,"0")).join("")}function It(c){const[w,m]=t.useState(null);return t.useEffect(()=>{if(!c){m(null);return}let h=!1;return Mt(c).then(C=>{if(h)return;const E=`${Tt}/${C}.glb`;fetch(E,{method:"HEAD"}).then(A=>{h||m(A.ok?E:ct)}).catch(()=>{h||m(ct)})}),()=>{h=!0}},[c]),w}const Ct=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_001.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_005.glb"],Ot=[{id:"m_expr_01",name:"Friendly Wave",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_001.glb"},{id:"m_expr_02",name:"You There",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_002.glb"},{id:"m_expr_04",name:"Awkward Agreement",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_004.glb"},{id:"m_expr_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_005.glb"},{id:"m_expr_06",name:"Tired Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_006.glb"},{id:"m_expr_07",name:"Conceilied Laughter",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_007.glb"},{id:"m_expr_08",name:"You Come Here",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_008.glb"},{id:"m_expr_09",name:"Come Here Kid",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_009.glb"},{id:"m_expr_10",name:"Come Here Everyone",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_010.glb"},{id:"m_expr_11",name:"No Freaking Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_011.glb"},{id:"m_expr_12",name:"Cheerful Approval",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_012.glb"},{id:"m_expr_13",name:"Waving Hello",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_013.glb"},{id:"m_expr_14",name:"Checking Surroundings",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_014.glb"},{id:"m_expr_15",name:"Referee Warning",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_015.glb"},{id:"m_expr_16",name:"You Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_016.glb"},{id:"m_expr_17",name:"Side Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_017.glb"},{id:"m_expr_18",name:"You're Finished",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_018.glb"},{id:"m_talk_01",name:"Oh God, Why Me?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_001.glb"},{id:"m_talk_02",name:"What Are You Doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_002.glb"},{id:"m_talk_03",name:"What Am I doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_003.glb"},{id:"m_talk_04",name:"No Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_004.glb"},{id:"m_talk_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb"},{id:"m_talk_06",name:"I have no idea",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_006.glb"},{id:"m_talk_07",name:"What's going on here?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"},{id:"m_talk_08",name:"Let's stop",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_008.glb"},{id:"m_talk_09",name:"Fed Up Moment",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_009.glb"},{id:"m_talk_10",name:"What's This? Hold On",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_010.glb"},{id:"f_talk_01",name:"Great Job Clap",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_001.glb"},{id:"f_talk_02",name:"Chill Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_002.glb"},{id:"f_talk_03",name:"This Is Me",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_003.glb"},{id:"f_talk_04",name:"Empathize",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_004.glb"},{id:"f_talk_05",name:"Loose Hands Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_005.glb"},{id:"f_talk_06",name:"Take It Easy",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_006.glb"}],Dt=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"],Ft={zoom:.85,position:[.15,-.8,0],scale:1.5,rotation:[.15,.02,0]},Ut=[-.45,1.9,.1],Nt={browInnerUp:.2},Ye=.18,jt=1,Pe={neutral:{eyeLookDownLeft:.1,eyeLookDownRight:.1},happy:{mouthSmileLeft:.2,mouthSmileRight:.2,eyeLookDownLeft:.1,eyeLookDownRight:.1},sad:{eyeLookDownLeft:.2,eyeLookDownRight:.2,browDownRight:.1,browInnerUp:.6,browOuterUpRight:.2,eyeSquintLeft:.7,eyeSquintRight:.7,mouthFrownLeft:.8,mouthFrownRight:.8,mouthLeft:.2,mouthPucker:.5,mouthRollLower:.2,mouthRollUpper:.2,mouthShrugLower:.2,mouthShrugUpper:.2,mouthStretchLeft:.4},angry:{eyeLookDownLeft:.1,eyeLookDownRight:.1,browDownLeft:.6,browDownRight:.6,jawForward:.3,mouthFrownLeft:.7,mouthFrownRight:.7,mouthRollLower:.2,mouthShrugLower:.3},fear:{browInnerUp:.7,eyeSquintLeft:.5,eyeSquintRight:.5,eyeWideLeft:.6,eyeWideRight:.6,mouthClose:.1,mouthFunnel:.3,mouthShrugLower:.5,mouthShrugUpper:.5},disgust:{browDownLeft:.7,browDownRight:.1,browInnerUp:.3,eyeSquintLeft:1,eyeSquintRight:1,eyeWideLeft:.5,eyeWideRight:.5,mouthLeft:.4,mouthPressLeft:.3,mouthRollLower:.3,mouthShrugLower:.3,mouthShrugUpper:.8,mouthUpperUpLeft:.3,noseSneerLeft:1,noseSneerRight:.7},love:{browInnerUp:.4,browOuterUpLeft:.2,browOuterUpRight:.2,mouthSmileLeft:.2,mouthSmileRight:.2,eyeBlinkLeft:.6,eyeBlinkRight:.6,eyeWideLeft:.7,eyeWideRight:.7,mouthDimpleLeft:.1,mouthDimpleRight:.1,mouthPressLeft:.2,mouthShrugUpper:.2,mouthUpperUpLeft:.1,mouthUpperUpRight:.1}},Pt=[{key:"viseme_aa",mix:{jawOpen:.6}},{key:"viseme_E",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthDimpleLeft:1,mouthDimpleRight:1,jawOpen:.3}},{key:"viseme_I",mix:{mouthPressLeft:.6,mouthPressRight:.6,mouthDimpleLeft:.6,mouthDimpleRight:.6,jawOpen:.2}},{key:"viseme_O",mix:{mouthPucker:1,jawForward:.6,jawOpen:.2}},{key:"viseme_U",mix:{mouthFunnel:1}},{key:"viseme_PP",mix:{mouthRollLower:.3,mouthRollUpper:.3,mouthUpperUpLeft:.3,mouthUpperUpRight:.3}},{key:"viseme_FF",mix:{mouthPucker:1,mouthShrugUpper:1,mouthLowerDownLeft:.2,mouthLowerDownRight:.2,mouthDimpleLeft:1,mouthDimpleRight:1,mouthRollLower:.3}},{key:"viseme_DD",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthFunnel:.5,jawOpen:.2}},{key:"viseme_SS",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthLowerDownLeft:.5,mouthLowerDownRight:.5,jawOpen:.1}},{key:"viseme_TH",mix:{mouthRollUpper:.3,jawOpen:.2,tongueOut:.4}},{key:"viseme_CH",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_RR",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_kk",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15}},{key:"viseme_nn",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15,tongueOut:.2}},{key:"viseme_sil",mix:{}}],Wt={aei:[{v:"E",w:.8},{v:"I",w:.2}],ee:[{v:"I",w:1}],oo:[{v:"O",w:1}],u:[{v:"U",w:1}],aa:[{v:"aa",w:1}],ah:[{v:"aa",w:.7},{v:"O",w:.3}],bmp:[{v:"PP",w:1}],fv:[{v:"FF",w:1}],th:[{v:"TH",w:1}],l:[{v:"nn",w:1}],r:[{v:"RR",w:1}],qw:[{v:"U",w:.6},{v:"O",w:.4}],chjsh:[{v:"CH",w:1}],cdgknstxyz:[{v:"DD",w:.6},{v:"SS",w:.4}],sil:[{v:"sil",w:1}]};function Vt(c){if(!c)return[{v:"sil",w:1}];const w=c.toLowerCase();return Wt[w]??[{v:"sil",w:1}]}function Bt({target:c}){const{camera:w}=Xe.useThree();return t.useEffect(()=>{w.lookAt(...c)},[w,c]),null}function J(c,w,m){if(!c||!c.morphTargetDictionary)return;const h=c,C=h.morphTargetDictionary,E=h.morphTargetInfluences;if(E)for(const A in C)A.toLowerCase()===w.toLowerCase()&&(E[C[A]]=m)}function ut(c,w=.97){if(!c)return;const m=c;if(m.morphTargetInfluences)for(let h=0;h<m.morphTargetInfluences.length;h++)m.morphTargetInfluences[h]*=w}const $t=t.memo(({avatarUrl:c,isPlayingRef:w,visemeQueueRef:m,audioContextRef:h,responseAudioStartTimeRef:C,adjustments:E,mood:A,expression:le,agentResponse:ee,isSpeaking:O,nextStartTimeRef:y,stopPlayback:X,setIsSpeaking:F,expressionUrl:L,onExpressionFinished:ie})=>{const{scene:b}=We.useGLTF(c),xe=We.useGLTF(Ct),K=t.useMemo(()=>xe.flatMap(f=>f.animations),[xe]),de=We.useGLTF(Dt),te=t.useMemo(()=>de.flatMap(f=>f.animations),[de]),H=t.useRef(null),M=t.useRef(null),g=t.useRef(null),V=t.useRef([]),[R]=t.useState(()=>new Ce.AnimationMixer(b)),x=t.useRef({}),_=t.useRef(null),Y=t.useRef(0),q=t.useRef(!1),oe=t.useRef(0),Q=t.useRef(null);t.useEffect(()=>{if(!(!K||!b)){if(K.forEach((f,l)=>{const i=`idle_${l}`;if(!x.current[i]){const r=R.clipAction(f,b);r.name=i,r.setLoop(Ce.LoopOnce,1),r.clampWhenFinished=!0,x.current[i]=r}}),te.forEach((f,l)=>{const i=`talk_${l}`;if(!x.current[i]){const r=R.clipAction(f,b);r.name=i,r.setLoop(Ce.LoopOnce,1),r.clampWhenFinished=!0,x.current[i]=r}}),K.length>0){const f=x.current.idle_0,l=_.current&&R.existingAction(_.current.getClip());f&&!l&&(f.reset().fadeIn(.5).play(),_.current=f)}return()=>{R.stopAllAction(),x.current={},_.current=null}}},[K,te,b,R]);const ve=t.useRef("");t.useEffect(()=>{if(!L||!b||L===ve.current)return;ve.current=L,Q.current=L,new At.GLTFLoader().load(L,l=>{if(l.animations&&l.animations.length>0){const i=l.animations[0],r=R.clipAction(i,b);if(r.name=`EXPR_${L}`,r.setLoop(Ce.LoopOnce,1),r.clampWhenFinished=!0,x.current[`EXPR_${L}`]=r,O&&Q.current===L){const p=_.current;r.reset().fadeIn(.3).play(),p&&p!==r&&p.crossFadeTo(r,.3,!0),_.current=r,Q.current=null}}},void 0,l=>{console.error(`[ANIMATION] Failed to load ${L}`,l)})},[L,b,R,O]),t.useEffect(()=>{const f=l=>{const i=l.action,r=i.name||"";if(r.startsWith("idle_")){const B=(parseInt(r.split("_")[1])+1)%K.length,G=x.current[`idle_${B}`];G&&(G.reset().fadeIn(.5).play(),i.crossFadeTo(G,.5,!0),_.current=G)}else if(r.startsWith("EXPR_")){if(O){const p=x.current.talk_0;p&&(p.reset().fadeIn(.5).play(),i.crossFadeTo(p,.5,!0),_.current=p)}else{const p=x.current.idle_0;p&&(p.reset().fadeIn(.5).play(),i.crossFadeTo(p,.5,!0),_.current=p)}ie&&ie()}else if(r.startsWith("talk_"))if(O){const B=(parseInt(r.split("_")[1])+1)%te.length,G=x.current[`talk_${B}`];G&&(G.reset().fadeIn(.3).play(),i.crossFadeTo(G,.3,!0),_.current=G)}else{const p=x.current.idle_0;p&&(p.reset().fadeIn(.5).play(),i.crossFadeTo(p,.5,!0),_.current=p)}};return R.addEventListener("finished",f),()=>R.removeEventListener("finished",f)},[R,K,te,O,ie]),t.useEffect(()=>{if(O&&b){const f=_.current,l=f?.name||"";if(l.startsWith("idle_")||l.startsWith("talk_")||l===""){const i=Q.current;if(i){const r=x.current[`EXPR_${i}`];if(r){r.reset().fadeIn(.3).play(),f&&f!==r&&f.crossFadeTo(r,.3,!0),_.current=r,Q.current=null;return}}if(l.startsWith("idle_")||l===""){const r=x.current.talk_0;r&&(r.reset().fadeIn(.5).play(),f&&f.crossFadeTo(r,.5,!0),_.current=r)}}}else if(!O&&b){const f=_.current,l=f?.name||"";if(l.startsWith("talk_")||l.startsWith("EXPR_")){const i=x.current.idle_0;i&&(i.reset().fadeIn(.5).play(),f&&f.crossFadeTo(i,.5,!0),_.current=i)}}},[O,b,L]),t.useEffect(()=>{if(!b)return;b.traverse(i=>{if(i.isMesh&&i.morphTargetDictionary){const r=i.name.toLowerCase();(r.includes("head")||r.includes("avatar"))&&(M.current=i,W(`[ANIMATION] Found head mesh: ${i.name}`)),r.includes("teeth")&&(g.current=i,W(`[ANIMATION] Found teeth mesh: ${i.name}`))}});const f=M.current?.morphTargetDictionary;f&&Object.keys(f).filter(i=>i.toLowerCase().includes("brow"));const l=[];b.traverse(i=>{if(i.isMesh){const p=i.morphTargetDictionary;p&&Object.keys(p).some(B=>B.toLowerCase().includes("brow"))&&l.push(i)}}),V.current=l,l.length>0&&W("[ANIMATION] Meshes with brow morphs:",l.length)},[b]);const Oe=(f,l=1)=>{const i=`viseme_${f}`.toLowerCase(),r=Pt.find(p=>p.key.toLowerCase()===i);if(r)for(const p in r.mix){const B=r.mix[p]*l;J(M.current,p,B),J(g.current,p,B)}},Te=f=>{const l=Pe[f]??Pe.neutral;for(const i in l)J(M.current,i,l[i]),J(g.current,i,l[i])};return Xe.useFrame((f,l)=>{const i=Math.pow(.88,60*l);ut(M.current,i),ut(g.current,i),Te(A);const r=f.clock.elapsedTime;let p=0;if(Math.floor(r)%5===0&&Math.floor((r-l)%5)!==0){let $=null;b.traverse(N=>{N.name.toLowerCase().includes("hips")&&($=N)});const ne=$?`Hips Y: ${$.position.y.toFixed(4)}`:"Hips not found";W(`[ANIMATION] Mixer Time: ${R.time.toFixed(2)}, ${ne}`)}if(R.update(l),r>Y.current&&!q.current&&(q.current=!0,oe.current=r),q.current){const ne=(r-oe.current)/.3;if(ne>=1)q.current=!1,Y.current=r+2+Math.random()*5;else{const N=ne<.5?ne*2:(1-ne)*2;J(M.current,"eyeBlinkLeft",N),J(M.current,"eyeBlinkRight",N),J(g.current,"eyeBlinkLeft",N),J(g.current,"eyeBlinkRight",N),p=N*Nt.browInnerUp}}const B=Pe[A]??Pe.neutral,G=B.browInnerUp??0,pe=B.browOuterUpLeft??0,fe=B.browOuterUpRight??0,ye=r*jt,he=Ye*Math.sin(ye),me=Ye*.7*Math.sin(ye+.7),Me=Ye*.7*Math.sin(ye+1.3),ge=$=>Math.max(0,Math.min(1,$)),Ie=ge(G+he),Re=ge(pe+me),Ve=ge(fe+Me),De=ge(Ie+p);if(J(M.current,"browInnerUp",De),J(g.current,"browInnerUp",De),J(M.current,"browOuterUpLeft",Re),J(g.current,"browOuterUpLeft",Re),J(M.current,"browOuterUpRight",Ve),J(g.current,"browOuterUpRight",Ve),H.current){const $=w.current?0:E.rotation[1];H.current.rotation.y=Ce.MathUtils.lerp(H.current.rotation.y,$,.1),H.current.position.set(...E.position),H.current.scale.setScalar(E.scale),H.current.rotation.x=E.rotation[0],H.current.rotation.z=E.rotation[2]}if(w.current&&h.current){const $=h.current.currentTime,be=($-C.current)*1e3- -150;for(let ke=0;ke<m.current.length;ke++){const _e=m.current[ke];be>=_e.vtime&&be<_e.vtime+_e.vduration&&Oe(_e.viseme,_e.weight??1)}$>y.current+.5&&(X(),F(!1))}}),o.jsx("group",{ref:H,children:o.jsx("primitive",{object:b})})});function Ht(c){return c?c.charAt(0).toUpperCase()+c.slice(1).toLowerCase():""}const qt=({token:c,agentToken:w,onNavigationRequested:m}={})=>{const h=c??w??"",C=It(h||void 0),[E,A]=t.useState(""),[le,ee]=t.useState(""),[O,y]=t.useState("Ready"),[X,F]=t.useState(!1),[L,ie]=t.useState(!1),[b,xe]=t.useState(()=>typeof window<"u"?window.matchMedia("(max-width: 480px)").matches:!1);t.useEffect(()=>{const e=window.matchMedia("(max-width: 480px)"),n=()=>xe(e.matches);return e.addEventListener("change",n),()=>e.removeEventListener("change",n)},[]);const K=b?80:600,de=t.useRef(!1),te=t.useRef([]),H=t.useRef(0),M=t.useRef(!1),g=t.useRef([]),V=t.useRef(null),R=t.useRef([]);t.useRef([]);const x=t.useRef([]),_=t.useRef(0),Y=t.useRef(0),q=t.useRef(0),oe=t.useRef(0),Q=t.useRef(!1),[ve,Oe]=t.useState(null),Te=t.useRef(null),[f,l]=t.useState("neutral"),[i,r]=t.useState(""),[p,B]=t.useState(""),[G,pe]=t.useState("Chat with us"),[fe,ye]=t.useState(null),[he,me]=t.useState("hidden"),[Me,ge]=t.useState(""),Ie=t.useRef(null),Re=t.useRef(he);Re.current=he;const[Ve,De]=t.useState(null),$=t.useRef(null),ne=t.useRef(null),[N,be]=t.useState("hidden"),[ke,_e]=t.useState(""),Be=t.useRef(N);Be.current=N;const ae=t.useRef(""),Ae=t.useRef(!1),Le=t.useRef(""),Ee=t.useMemo(()=>O==="Thinking..."||O==="Processing Voice..."?O:fe!=null&&fe!==""&&fe!=="none"&&fe!=="<none>"?`Enter ${Ht(fe)}`:null,[O,fe]),Fe=Ee!=null&&Ee!=="";t.useEffect(()=>{const e=Re.current;if(!(e==="exiting"||e==="entering")){if(e==="hidden"){Fe&&(ge(Ee??""),me("entering"));return}e==="visible"&&(!Fe||Ee!==Me)&&(Ie.current=Fe?Ee:null,me("exiting"))}},[Fe,Ee,he,Me]);const lt=t.useCallback(()=>{const e=Re.current;if(e==="exiting"){me("hidden");const n=Ie.current;Ie.current=null,n!=null&&n!==""&&(ge(n),me("entering"))}else e==="entering"&&me("visible")},[]),dt=e=>{if(!e)return;if(e.mood!=null){const s=String(e.mood).toLowerCase();l(s)}if(e.expression!=null){const s=String(e.expression).trim();r(s);const d=Ot.find(S=>S.name.toLowerCase()===s.toLowerCase());W(`[STREAM] Animation match for "${s}": ${d?d.name:"NONE"}`),B(d?.url??"")}if(e.navigation!=null){const s=String(e.navigation).trim();s!==""&&(m?m(s):window.open(s,"_blank"))}const n=e.ask_for||e.lead_capture?.ask_for,a=n?String(n).trim().toLowerCase():"",u=a==="none"||a==="<none>";if(n&&!u){const s=a;ye(s||null),pe(s==="email"?"Enter your email":s==="name"?"Enter your name":s==="phone"?"Enter your phone number":"Chat with us")}else(u||e.ask_for===null||e.lead_capture&&e.lead_capture.ask_for===null||e.ask_for==="none")&&(ye(null),G!=="Chat with us"&&pe("Chat with us"));e.collected,e.valid},ft=e=>{const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{return JSON.parse(n)}catch{return null}if(n.includes(":")){const a=n.split(":"),u=a[0].trim().toLowerCase(),s=a.slice(1).join(":").trim();return{[u]:s}}return null},ht=t.useCallback(()=>{},[]),Ke=e=>{if(Ae.current)e==="§"?Ae.current=!1:(Le.current+=e,ee(n=>n+e));else if(e==="§"){Ae.current=!0;return}else for(ae.current+=e;ae.current.includes(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),We=require("@react-three/drei"),Xe=require("@react-three/fiber"),t=require("react"),kt=require("three"),At=require("three/examples/jsm/loaders/GLTFLoader.js");function Lt(c){const w=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(c){for(const m in c)if(m!=="default"){const h=Object.getOwnPropertyDescriptor(c,m);Object.defineProperty(w,m,h.get?h:{enumerable:!0,get:()=>c[m]})}}return w.default=c,Object.freeze(w)}const Ce=Lt(kt),W=(...c)=>{},Et=(...c)=>{},ot=({analyser:c})=>{const w=t.useRef(null),m=t.useRef(null);return t.useEffect(()=>{const h=w.current;if(!h)return;const C=h.getContext("2d",{alpha:!0});if(!C)return;let E,A=null;c&&(c.fftSize=128,A=new Uint8Array(c.frequencyBinCount));const le=()=>{E=requestAnimationFrame(le),(h.width!==h.offsetWidth||h.height!==h.offsetHeight)&&(h.width=h.offsetWidth,h.height=h.offsetHeight);const ee=h.width,O=h.height;if(ee===0||O===0)return;const y=O/2;C.clearRect(0,0,ee,O),C.fillStyle="#1e293b";const X=2,L=X+2,ie=ee*.95,b=Math.floor(ie/L);(!m.current||m.current.length!==b)&&(m.current=new Float32Array(b).fill(2));const xe=b*L,K=(ee-xe)/2;c&&A&&c.getByteFrequencyData(A);const de=A?A.length:0,$=Math.floor(de*.7)/b,T=new Float32Array(b);for(let g=0;g<b;g++){let V=0;if(A&&$>0){const _=Math.floor(g*$),Y=Math.floor((g+1)*$);for(let q=_;q<Y;q++){const oe=A[q]||0;oe>V&&(V=oe)}}V<10&&(V=0);const R=V/255,x=V>0?Math.max(2,Math.pow(R,1.4)*O*.25):2;T[g]=x}for(let g=0;g<b;g++){const V=b-1-g,R=Math.max(T[g],T[V]),x=m.current[g]+(R-m.current[g])*.3;m.current[g]=x;const _=K+g*L,Y=y-x/2;C.beginPath(),C.roundRect?C.roundRect(_,Y,X,x,4):C.fillRect(_,Y,X,x),C.fill()}};return le(),()=>{cancelAnimationFrame(E)}},[c]),o.jsx("canvas",{ref:w,style:{width:"100%",height:"100%",display:"block"}})},at="https://ai.streamoji.com",Mt="https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev",ct="https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";async function Tt(c){const w=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(c));return Array.from(new Uint8Array(w)).map(m=>m.toString(16).padStart(2,"0")).join("")}function It(c){const[w,m]=t.useState(null);return t.useEffect(()=>{if(!c){m(null);return}let h=!1;return Tt(c).then(C=>{if(h)return;const E=`${Mt}/${C}.glb`;fetch(E,{method:"HEAD"}).then(A=>{h||m(A.ok?E:ct)}).catch(()=>{h||m(ct)})}),()=>{h=!0}},[c]),w}const Ct=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_001.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_005.glb"],Ot=[{id:"m_expr_01",name:"Friendly Wave",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_001.glb"},{id:"m_expr_02",name:"You There",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_002.glb"},{id:"m_expr_04",name:"Awkward Agreement",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_004.glb"},{id:"m_expr_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_005.glb"},{id:"m_expr_06",name:"Tired Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_006.glb"},{id:"m_expr_07",name:"Conceilied Laughter",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_007.glb"},{id:"m_expr_08",name:"You Come Here",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_008.glb"},{id:"m_expr_09",name:"Come Here Kid",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_009.glb"},{id:"m_expr_10",name:"Come Here Everyone",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_010.glb"},{id:"m_expr_11",name:"No Freaking Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_011.glb"},{id:"m_expr_12",name:"Cheerful Approval",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_012.glb"},{id:"m_expr_13",name:"Waving Hello",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_013.glb"},{id:"m_expr_14",name:"Checking Surroundings",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_014.glb"},{id:"m_expr_15",name:"Referee Warning",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_015.glb"},{id:"m_expr_16",name:"You Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_016.glb"},{id:"m_expr_17",name:"Side Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_017.glb"},{id:"m_expr_18",name:"You're Finished",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_018.glb"},{id:"m_talk_01",name:"Oh God, Why Me?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_001.glb"},{id:"m_talk_02",name:"What Are You Doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_002.glb"},{id:"m_talk_03",name:"What Am I doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_003.glb"},{id:"m_talk_04",name:"No Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_004.glb"},{id:"m_talk_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb"},{id:"m_talk_06",name:"I have no idea",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_006.glb"},{id:"m_talk_07",name:"What's going on here?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"},{id:"m_talk_08",name:"Let's stop",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_008.glb"},{id:"m_talk_09",name:"Fed Up Moment",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_009.glb"},{id:"m_talk_10",name:"What's This? Hold On",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_010.glb"},{id:"f_talk_01",name:"Great Job Clap",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_001.glb"},{id:"f_talk_02",name:"Chill Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_002.glb"},{id:"f_talk_03",name:"This Is Me",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_003.glb"},{id:"f_talk_04",name:"Empathize",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_004.glb"},{id:"f_talk_05",name:"Loose Hands Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_005.glb"},{id:"f_talk_06",name:"Take It Easy",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_006.glb"}],Dt=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"],Ft={zoom:.85,position:[.15,-.8,0],scale:1.5,rotation:[.15,.02,0]},Ut=[-.45,1.9,.1],jt={browInnerUp:.2},Ye=.18,Nt=1,Pe={neutral:{eyeLookDownLeft:.1,eyeLookDownRight:.1},happy:{mouthSmileLeft:.2,mouthSmileRight:.2,eyeLookDownLeft:.1,eyeLookDownRight:.1},sad:{eyeLookDownLeft:.2,eyeLookDownRight:.2,browDownRight:.1,browInnerUp:.6,browOuterUpRight:.2,eyeSquintLeft:.7,eyeSquintRight:.7,mouthFrownLeft:.8,mouthFrownRight:.8,mouthLeft:.2,mouthPucker:.5,mouthRollLower:.2,mouthRollUpper:.2,mouthShrugLower:.2,mouthShrugUpper:.2,mouthStretchLeft:.4},angry:{eyeLookDownLeft:.1,eyeLookDownRight:.1,browDownLeft:.6,browDownRight:.6,jawForward:.3,mouthFrownLeft:.7,mouthFrownRight:.7,mouthRollLower:.2,mouthShrugLower:.3},fear:{browInnerUp:.7,eyeSquintLeft:.5,eyeSquintRight:.5,eyeWideLeft:.6,eyeWideRight:.6,mouthClose:.1,mouthFunnel:.3,mouthShrugLower:.5,mouthShrugUpper:.5},disgust:{browDownLeft:.7,browDownRight:.1,browInnerUp:.3,eyeSquintLeft:1,eyeSquintRight:1,eyeWideLeft:.5,eyeWideRight:.5,mouthLeft:.4,mouthPressLeft:.3,mouthRollLower:.3,mouthShrugLower:.3,mouthShrugUpper:.8,mouthUpperUpLeft:.3,noseSneerLeft:1,noseSneerRight:.7},love:{browInnerUp:.4,browOuterUpLeft:.2,browOuterUpRight:.2,mouthSmileLeft:.2,mouthSmileRight:.2,eyeBlinkLeft:.6,eyeBlinkRight:.6,eyeWideLeft:.7,eyeWideRight:.7,mouthDimpleLeft:.1,mouthDimpleRight:.1,mouthPressLeft:.2,mouthShrugUpper:.2,mouthUpperUpLeft:.1,mouthUpperUpRight:.1}},Pt=[{key:"viseme_aa",mix:{jawOpen:.6}},{key:"viseme_E",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthDimpleLeft:1,mouthDimpleRight:1,jawOpen:.3}},{key:"viseme_I",mix:{mouthPressLeft:.6,mouthPressRight:.6,mouthDimpleLeft:.6,mouthDimpleRight:.6,jawOpen:.2}},{key:"viseme_O",mix:{mouthPucker:1,jawForward:.6,jawOpen:.2}},{key:"viseme_U",mix:{mouthFunnel:1}},{key:"viseme_PP",mix:{mouthRollLower:.3,mouthRollUpper:.3,mouthUpperUpLeft:.3,mouthUpperUpRight:.3}},{key:"viseme_FF",mix:{mouthPucker:1,mouthShrugUpper:1,mouthLowerDownLeft:.2,mouthLowerDownRight:.2,mouthDimpleLeft:1,mouthDimpleRight:1,mouthRollLower:.3}},{key:"viseme_DD",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthFunnel:.5,jawOpen:.2}},{key:"viseme_SS",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthLowerDownLeft:.5,mouthLowerDownRight:.5,jawOpen:.1}},{key:"viseme_TH",mix:{mouthRollUpper:.3,jawOpen:.2,tongueOut:.4}},{key:"viseme_CH",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_RR",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_kk",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15}},{key:"viseme_nn",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15,tongueOut:.2}},{key:"viseme_sil",mix:{}}],Wt={aei:[{v:"E",w:.8},{v:"I",w:.2}],ee:[{v:"I",w:1}],oo:[{v:"O",w:1}],u:[{v:"U",w:1}],aa:[{v:"aa",w:1}],ah:[{v:"aa",w:.7},{v:"O",w:.3}],bmp:[{v:"PP",w:1}],fv:[{v:"FF",w:1}],th:[{v:"TH",w:1}],l:[{v:"nn",w:1}],r:[{v:"RR",w:1}],qw:[{v:"U",w:.6},{v:"O",w:.4}],chjsh:[{v:"CH",w:1}],cdgknstxyz:[{v:"DD",w:.6},{v:"SS",w:.4}],sil:[{v:"sil",w:1}]};function Vt(c){if(!c)return[{v:"sil",w:1}];const w=c.toLowerCase();return Wt[w]??[{v:"sil",w:1}]}function Bt({target:c}){const{camera:w}=Xe.useThree();return t.useEffect(()=>{w.lookAt(...c)},[w,c]),null}function J(c,w,m){if(!c||!c.morphTargetDictionary)return;const h=c,C=h.morphTargetDictionary,E=h.morphTargetInfluences;if(E)for(const A in C)A.toLowerCase()===w.toLowerCase()&&(E[C[A]]=m)}function ut(c,w=.97){if(!c)return;const m=c;if(m.morphTargetInfluences)for(let h=0;h<m.morphTargetInfluences.length;h++)m.morphTargetInfluences[h]*=w}const Ht=t.memo(({avatarUrl:c,isPlayingRef:w,visemeQueueRef:m,audioContextRef:h,responseAudioStartTimeRef:C,adjustments:E,mood:A,expression:le,agentResponse:ee,isSpeaking:O,nextStartTimeRef:y,stopPlayback:X,setIsSpeaking:F,expressionUrl:L,onExpressionFinished:ie})=>{const{scene:b}=We.useGLTF(c),xe=We.useGLTF(Ct),K=t.useMemo(()=>xe.flatMap(f=>f.animations),[xe]),de=We.useGLTF(Dt),te=t.useMemo(()=>de.flatMap(f=>f.animations),[de]),$=t.useRef(null),T=t.useRef(null),g=t.useRef(null),V=t.useRef([]),[R]=t.useState(()=>new Ce.AnimationMixer(b)),x=t.useRef({}),_=t.useRef(null),Y=t.useRef(0),q=t.useRef(!1),oe=t.useRef(0),Q=t.useRef(null);t.useEffect(()=>{if(!(!K||!b)){if(K.forEach((f,l)=>{const i=`idle_${l}`;if(!x.current[i]){const r=R.clipAction(f,b);r.name=i,r.setLoop(Ce.LoopOnce,1),r.clampWhenFinished=!0,x.current[i]=r}}),te.forEach((f,l)=>{const i=`talk_${l}`;if(!x.current[i]){const r=R.clipAction(f,b);r.name=i,r.setLoop(Ce.LoopOnce,1),r.clampWhenFinished=!0,x.current[i]=r}}),K.length>0){const f=x.current.idle_0,l=_.current&&R.existingAction(_.current.getClip());f&&!l&&(f.reset().fadeIn(.5).play(),_.current=f)}return()=>{R.stopAllAction(),x.current={},_.current=null}}},[K,te,b,R]);const ve=t.useRef("");t.useEffect(()=>{if(!L||!b||L===ve.current)return;ve.current=L,Q.current=L,new At.GLTFLoader().load(L,l=>{if(l.animations&&l.animations.length>0){const i=l.animations[0],r=R.clipAction(i,b);if(r.name=`EXPR_${L}`,r.setLoop(Ce.LoopOnce,1),r.clampWhenFinished=!0,x.current[`EXPR_${L}`]=r,O&&Q.current===L){const p=_.current;r.reset().fadeIn(.3).play(),p&&p!==r&&p.crossFadeTo(r,.3,!0),_.current=r,Q.current=null}}},void 0,l=>{console.error(`[ANIMATION] Failed to load ${L}`,l)})},[L,b,R,O]),t.useEffect(()=>{const f=l=>{const i=l.action,r=i.name||"";if(r.startsWith("idle_")){const B=(parseInt(r.split("_")[1])+1)%K.length,G=x.current[`idle_${B}`];G&&(G.reset().fadeIn(.5).play(),i.crossFadeTo(G,.5,!0),_.current=G)}else if(r.startsWith("EXPR_")){if(O){const p=x.current.talk_0;p&&(p.reset().fadeIn(.5).play(),i.crossFadeTo(p,.5,!0),_.current=p)}else{const p=x.current.idle_0;p&&(p.reset().fadeIn(.5).play(),i.crossFadeTo(p,.5,!0),_.current=p)}ie&&ie()}else if(r.startsWith("talk_"))if(O){const B=(parseInt(r.split("_")[1])+1)%te.length,G=x.current[`talk_${B}`];G&&(G.reset().fadeIn(.3).play(),i.crossFadeTo(G,.3,!0),_.current=G)}else{const p=x.current.idle_0;p&&(p.reset().fadeIn(.5).play(),i.crossFadeTo(p,.5,!0),_.current=p)}};return R.addEventListener("finished",f),()=>R.removeEventListener("finished",f)},[R,K,te,O,ie]),t.useEffect(()=>{if(O&&b){const f=_.current,l=f?.name||"";if(l.startsWith("idle_")||l.startsWith("talk_")||l===""){const i=Q.current;if(i){const r=x.current[`EXPR_${i}`];if(r){r.reset().fadeIn(.3).play(),f&&f!==r&&f.crossFadeTo(r,.3,!0),_.current=r,Q.current=null;return}}if(l.startsWith("idle_")||l===""){const r=x.current.talk_0;r&&(r.reset().fadeIn(.5).play(),f&&f.crossFadeTo(r,.5,!0),_.current=r)}}}else if(!O&&b){const f=_.current,l=f?.name||"";if(l.startsWith("talk_")||l.startsWith("EXPR_")){const i=x.current.idle_0;i&&(i.reset().fadeIn(.5).play(),f&&f.crossFadeTo(i,.5,!0),_.current=i)}}},[O,b,L]),t.useEffect(()=>{if(!b)return;b.traverse(i=>{if(i.isMesh&&i.morphTargetDictionary){const r=i.name.toLowerCase();(r.includes("head")||r.includes("avatar"))&&(T.current=i,W(`[ANIMATION] Found head mesh: ${i.name}`)),r.includes("teeth")&&(g.current=i,W(`[ANIMATION] Found teeth mesh: ${i.name}`))}});const f=T.current?.morphTargetDictionary;f&&Object.keys(f).filter(i=>i.toLowerCase().includes("brow"));const l=[];b.traverse(i=>{if(i.isMesh){const p=i.morphTargetDictionary;p&&Object.keys(p).some(B=>B.toLowerCase().includes("brow"))&&l.push(i)}}),V.current=l,l.length>0&&W("[ANIMATION] Meshes with brow morphs:",l.length)},[b]);const Oe=(f,l=1)=>{const i=`viseme_${f}`.toLowerCase(),r=Pt.find(p=>p.key.toLowerCase()===i);if(r)for(const p in r.mix){const B=r.mix[p]*l;J(T.current,p,B),J(g.current,p,B)}},Me=f=>{const l=Pe[f]??Pe.neutral;for(const i in l)J(T.current,i,l[i]),J(g.current,i,l[i])};return Xe.useFrame((f,l)=>{const i=Math.pow(.88,60*l);ut(T.current,i),ut(g.current,i),Me(A);const r=f.clock.elapsedTime;let p=0;if(Math.floor(r)%5===0&&Math.floor((r-l)%5)!==0){let H=null;b.traverse(j=>{j.name.toLowerCase().includes("hips")&&(H=j)});const ne=H?`Hips Y: ${H.position.y.toFixed(4)}`:"Hips not found";W(`[ANIMATION] Mixer Time: ${R.time.toFixed(2)}, ${ne}`)}if(R.update(l),r>Y.current&&!q.current&&(q.current=!0,oe.current=r),q.current){const ne=(r-oe.current)/.3;if(ne>=1)q.current=!1,Y.current=r+2+Math.random()*5;else{const j=ne<.5?ne*2:(1-ne)*2;J(T.current,"eyeBlinkLeft",j),J(T.current,"eyeBlinkRight",j),J(g.current,"eyeBlinkLeft",j),J(g.current,"eyeBlinkRight",j),p=j*jt.browInnerUp}}const B=Pe[A]??Pe.neutral,G=B.browInnerUp??0,pe=B.browOuterUpLeft??0,fe=B.browOuterUpRight??0,ye=r*Nt,he=Ye*Math.sin(ye),me=Ye*.7*Math.sin(ye+.7),Te=Ye*.7*Math.sin(ye+1.3),ge=H=>Math.max(0,Math.min(1,H)),Ie=ge(G+he),Re=ge(pe+me),Ve=ge(fe+Te),De=ge(Ie+p);if(J(T.current,"browInnerUp",De),J(g.current,"browInnerUp",De),J(T.current,"browOuterUpLeft",Re),J(g.current,"browOuterUpLeft",Re),J(T.current,"browOuterUpRight",Ve),J(g.current,"browOuterUpRight",Ve),$.current){const H=w.current?0:E.rotation[1];$.current.rotation.y=Ce.MathUtils.lerp($.current.rotation.y,H,.1),$.current.position.set(...E.position),$.current.scale.setScalar(E.scale),$.current.rotation.x=E.rotation[0],$.current.rotation.z=E.rotation[2]}if(w.current&&h.current){const H=h.current.currentTime,be=(H-C.current)*1e3- -150;for(let ke=0;ke<m.current.length;ke++){const _e=m.current[ke];be>=_e.vtime&&be<_e.vtime+_e.vduration&&Oe(_e.viseme,_e.weight??1)}H>y.current+.5&&(X(),F(!1))}}),o.jsx("group",{ref:$,children:o.jsx("primitive",{object:b})})});function $t(c){return c?c.charAt(0).toUpperCase()+c.slice(1).toLowerCase():""}const qt=({token:c,agentToken:w,onNavigationRequested:m}={})=>{const h=c??w??"",C=It(h||void 0),[E,A]=t.useState(""),[le,ee]=t.useState(""),[O,y]=t.useState("Ready"),[X,F]=t.useState(!1),[L,ie]=t.useState(!1),[b,xe]=t.useState(()=>typeof window<"u"?window.matchMedia("(max-width: 480px)").matches:!1);t.useEffect(()=>{const e=window.matchMedia("(max-width: 480px)"),n=()=>xe(e.matches);return e.addEventListener("change",n),()=>e.removeEventListener("change",n)},[]);const K=b?80:600,de=t.useRef(!1),te=t.useRef([]),$=t.useRef(0),T=t.useRef(!1),g=t.useRef([]),V=t.useRef(null),R=t.useRef([]);t.useRef([]);const x=t.useRef([]),_=t.useRef(0),Y=t.useRef(0),q=t.useRef(0),oe=t.useRef(0),Q=t.useRef(!1),[ve,Oe]=t.useState(null),Me=t.useRef(null),[f,l]=t.useState("neutral"),[i,r]=t.useState(""),[p,B]=t.useState(""),[G,pe]=t.useState("Chat with us"),[fe,ye]=t.useState(null),[he,me]=t.useState("hidden"),[Te,ge]=t.useState(""),Ie=t.useRef(null),Re=t.useRef(he);Re.current=he;const[Ve,De]=t.useState(null),H=t.useRef(null),ne=t.useRef(null),[j,be]=t.useState("hidden"),[ke,_e]=t.useState(""),Be=t.useRef(j);Be.current=j;const ae=t.useRef(""),Ae=t.useRef(!1),Le=t.useRef(""),Ee=t.useMemo(()=>O==="Thinking..."||O==="Processing Voice..."?O:fe!=null&&fe!==""&&fe!=="none"&&fe!=="<none>"?`Enter ${$t(fe)}`:null,[O,fe]),Fe=Ee!=null&&Ee!=="";t.useEffect(()=>{const e=Re.current;if(!(e==="exiting"||e==="entering")){if(e==="hidden"){Fe&&(ge(Ee??""),me("entering"));return}e==="visible"&&(!Fe||Ee!==Te)&&(Ie.current=Fe?Ee:null,me("exiting"))}},[Fe,Ee,he,Te]);const lt=t.useCallback(()=>{const e=Re.current;if(e==="exiting"){me("hidden");const n=Ie.current;Ie.current=null,n!=null&&n!==""&&(ge(n),me("entering"))}else e==="entering"&&me("visible")},[]),dt=e=>{if(!e)return;if(e.mood!=null){const s=String(e.mood).toLowerCase();l(s)}if(e.expression!=null){const s=String(e.expression).trim();r(s);const d=Ot.find(S=>S.name.toLowerCase()===s.toLowerCase());W(`[STREAM] Animation match for "${s}": ${d?d.name:"NONE"}`),B(d?.url??"")}if(e.navigation!=null){const s=String(e.navigation).trim();s!==""&&(m?m(s):window.open(s,"_blank"))}const n=e.ask_for||e.lead_capture?.ask_for,a=n?String(n).trim().toLowerCase():"",u=a==="none"||a==="<none>";if(n&&!u){const s=a;ye(s||null),pe(s==="email"?"Enter your email":s==="name"?"Enter your name":s==="phone"?"Enter your phone number":"Chat with us")}else(u||e.ask_for===null||e.lead_capture&&e.lead_capture.ask_for===null||e.ask_for==="none")&&(ye(null),G!=="Chat with us"&&pe("Chat with us"));e.collected,e.valid},ft=e=>{const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{return JSON.parse(n)}catch{return null}if(n.includes(":")){const a=n.split(":"),u=a[0].trim().toLowerCase(),s=a.slice(1).join(":").trim();return{[u]:s}}return null},ht=t.useCallback(()=>{},[]),Ke=e=>{if(Ae.current)e==="§"?Ae.current=!1:(Le.current+=e,ee(n=>n+e));else if(e==="§"){Ae.current=!0;return}else for(ae.current+=e;ae.current.includes(`
2
2
  `);){const n=ae.current.indexOf(`
3
- `),a=ae.current.slice(0,n).trim();ae.current=ae.current.slice(n+1);const u=ft(a);u&&dt(u)}};t.useEffect(()=>{(async()=>{if(!sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID")){const a="secret",u=Math.floor(Date.now()/1e3).toString();try{const s=new TextEncoder,d=await crypto.subtle.importKey("raw",s.encode(a),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),S=await crypto.subtle.sign("HMAC",d,s.encode(u)),j=Array.from(new Uint8Array(S)).map(v=>v.toString(16).padStart(2,"0")).join("");sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",j),W("[SESSION] New HMAC UID generated and saved:",j)}catch(s){console.error("[SESSION] HMAC generation failed:",s);const d=Math.random().toString(36)+Date.now().toString();sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",d)}}sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")||sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify([]))})()},[]);const Qe=()=>{try{return JSON.parse(sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")||"[]")}catch{return[]}},pt=e=>{sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify(e))},[$e,He]=t.useState(!1),[Ze,qe]=t.useState(0),re=t.useRef(null),Ue=t.useRef([]),et=t.useRef(0),[tt,mt]=t.useState(null),[gt,Je]=t.useState(null),ce=t.useRef(null),we=t.useRef(null),Ne=t.useCallback((e=!1)=>{e&&(Q.current=!0,F(!1),y("Ready")),g.current=[],te.current=[],M.current=!1,ie(!1),_.current=0,Y.current=0,q.current=0,R.current.forEach(n=>{try{n.stop()}catch{}}),$.current&&(clearTimeout($.current),$.current=null),De(null),B(""),R.current=[]},[]),bt=async()=>{try{const e=await navigator.mediaDevices.getUserMedia({audio:!0}),n=window.AudioContext||window.webkitAudioContext,a=new n,u=a.createMediaStreamSource(e),s=a.createAnalyser();s.fftSize=64,u.connect(s),ce.current=a,we.current=u,Je(s);const d=new MediaRecorder(e);re.current=d,Ue.current=[],d.ondataavailable=S=>{S.data.size>0&&Ue.current.push(S.data)},d.onstop=async()=>{const S=Date.now()-et.current;if(Je(null),we.current&&(we.current.disconnect(),we.current=null),ce.current&&ce.current.state!=="closed"&&(ce.current.close(),ce.current=null),S<1e3){y("Recording too short. Hold or click longer."),F(!1);return}const k=new Blob(Ue.current,{type:"audio/wav"});await xt(k)},et.current=Date.now(),d.start(100),He(!0),y("Listening...")}catch(e){console.error("Error accessing microphone:",e),y("Mic Access Error")}},_t=()=>{re.current&&re.current.state!=="inactive"&&(re.current.stop(),re.current.stream.getTracks().forEach(e=>e.stop()),He(!1))},wt=()=>{re.current&&re.current.state!=="inactive"&&(re.current.onstop=null,re.current.stop(),re.current.stream.getTracks().forEach(e=>e.stop()),Je(null),we.current&&(we.current.disconnect(),we.current=null),ce.current&&ce.current.state!=="closed"&&(ce.current.close(),ce.current=null),He(!1),Ue.current=[],y("Ready"))};t.useEffect(()=>{if(!L)return;const e=()=>{const n=q.current;if(n<=0)return;const a=V.current,u=_.current;if(!a)return;const s=a.currentTime-u,d=Math.min(Math.max(0,s),n),S=le.trim().length;if(S<=0)return;const k=Math.min(Math.round(d/n*S),S);Oe(k)};return clearInterval(Te.current??void 0),Te.current=setInterval(e,90),()=>clearInterval(Te.current??void 0)},[L,le,q.current]),t.useEffect(()=>{let e;return $e?(qe(0),e=window.setInterval(()=>{qe(n=>n+1)},1e3)):qe(0),()=>clearInterval(e)},[$e]);const St=e=>{const n=e.numberOfChannels,a=e.length*n*2+44,u=new ArrayBuffer(a),s=new DataView(u);let d=0;const S=D=>{s.setUint16(d,D,!0),d+=2},k=D=>{s.setUint32(d,D,!0),d+=4};k(1179011410),k(a-8),k(1163280727),k(544501094),k(16),S(1),S(n),k(e.sampleRate),k(e.sampleRate*2*n),S(n*2),S(16),k(1635017060),k(a-d-4);const j=[];for(let D=0;D<n;D++)j.push(e.getChannelData(D));let v=0;for(;d<a;){for(let D=0;D<n;D++){let U=Math.max(-1,Math.min(1,j[D][v]));U=U<0?U*32768:U*32767,s.setInt16(d,U,!0),d+=2}v++}return new Blob([u],{type:"audio/wav"})},Ge=async(e,n,a=!1)=>{if(!Q.current){if(de.current){te.current.push({audio:e,visemes:n,isNewSegment:a});return}de.current=!0;try{const u=window.AudioContext||window.webkitAudioContext,s=V.current??new u;s.state==="suspended"&&await s.resume(),V.current=s;const d=window.atob(e),S=new Uint8Array(d.length);for(let T=0;T<d.length;T++)S[T]=d.charCodeAt(T);const k=await s.decodeAudioData(S.buffer.slice(0));q.current+=k.duration;const j=s.currentTime;let v=Y.current;const D=!M.current;v<j&&(v=j+.1),Y.current=v+k.duration;const U=s.createBufferSource();U.buffer=k;let P=tt;if((!P||P.context!==s)&&(P=s.createAnalyser(),P.fftSize=64,P.connect(s.destination),mt(P)),U.connect(P),R.current.push(U),Q.current){R.current=R.current.filter(T=>T!==U);return}if(D){M.current=!0,ie(!0),W(`[AUDIO] setIsSpeaking(true) - First chunk starting at ${v.toFixed(3)}`),_.current=v;const T=(v-j)*1e3;H.current=performance.now()+T,W(`[AUDIO] Response started. Initial startTime: ${v.toFixed(3)}, CT: ${j.toFixed(3)}`)}U.start(v);const z=(v-_.current)*1e3;a&&(oe.current=z,W(`[AUDIO] New segment detected at +${z.toFixed(0)}ms. Resetting segment offset.`)),n.forEach((T,ue)=>{const I=T.symbol??"";if(I){const Z=Vt(I),se=Math.round(T.start*1e3),Se=Math.round((T.duration??0)*1e3),st=oe.current+se;ue<3&&W(`[AUDIO] Viseme "${I}": segment_relative=${se}ms, segment_offset=${oe.current.toFixed(0)}ms => vtime=${st}ms`),Z.forEach(it=>{g.current.push({viseme:it.v,weight:it.w,vtime:st,vduration:Se})})}}),y("Speaking...")}finally{if(de.current=!1,te.current.length>0){const u=te.current.shift();u&&Ge(u.audio,u.visemes,u.isNewSegment)}}}},xt=async e=>{try{F(!0),Le.current="",ee(""),y("Processing Voice...");const n=await e.arrayBuffer(),u=await new(window.AudioContext||window.webkitAudioContext)().decodeAudioData(n),s=St(u),d=new FileReader;d.readAsDataURL(s),d.onloadend=async()=>{const S=d.result.split(",")[1];Ne(),A(""),ae.current="",Ae.current=!1;const k=`${at}/stt?token=${encodeURIComponent(h)}`,j=await fetch(k,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({audio_base64:S,audio_format:"wav"})});if(!j.ok){const ue=await j.text();let I="STT Failed";try{I=JSON.parse(ue).error||I}catch{ue&&(I=ue.slice(0,200))}throw new Error(I)}const v=j.body;if(W("this is body"+v),!v){y("STT Failed"),F(!1);return}const D=v.getReader();Q.current=!1;const U=new TextDecoder;let P="",z=!1;const T=async(ue,I)=>{switch(ue){case"transcript":I.transcript!=null&&A(String(I.transcript));break;case"text":{const Z=I.delta??I.text??"";Z&&Ke(Z);break}case"audio":{const Z=I.chunk,se=I.visemes??[],Se=!!I.is_new_segment;Z&&await Ge(Z,se,Se);break}case"done":{z=!0,y("Ready"),F(!1);break}case"error":{z=!0,y("STT Failed"),F(!1);break}default:break}};for(;;){const{done:ue,value:I}=await D.read();I&&(P+=U.decode(I,{stream:!0}));const Z=P.split(`
3
+ `),a=ae.current.slice(0,n).trim();ae.current=ae.current.slice(n+1);const u=ft(a);u&&dt(u)}};t.useEffect(()=>{(async()=>{if(!sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID")){const a="secret",u=Math.floor(Date.now()/1e3).toString();try{const s=new TextEncoder,d=await crypto.subtle.importKey("raw",s.encode(a),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),S=await crypto.subtle.sign("HMAC",d,s.encode(u)),N=Array.from(new Uint8Array(S)).map(v=>v.toString(16).padStart(2,"0")).join("");sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",N),W("[SESSION] New HMAC UID generated and saved:",N)}catch(s){console.error("[SESSION] HMAC generation failed:",s);const d=Math.random().toString(36)+Date.now().toString();sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",d)}}sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")||sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify([]))})()},[]);const Qe=()=>{try{return JSON.parse(sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")||"[]")}catch{return[]}},pt=e=>{sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify(e))},[He,$e]=t.useState(!1),[Ze,qe]=t.useState(0),re=t.useRef(null),Ue=t.useRef([]),et=t.useRef(0),[tt,mt]=t.useState(null),[gt,Je]=t.useState(null),ce=t.useRef(null),we=t.useRef(null),je=t.useCallback((e=!1)=>{e&&(Q.current=!0,F(!1),y("Ready")),g.current=[],te.current=[],T.current=!1,ie(!1),_.current=0,Y.current=0,q.current=0,R.current.forEach(n=>{try{n.stop()}catch{}}),H.current&&(clearTimeout(H.current),H.current=null),De(null),B(""),R.current=[]},[]),bt=async()=>{try{const e=await navigator.mediaDevices.getUserMedia({audio:!0}),n=window.AudioContext||window.webkitAudioContext,a=new n,u=a.createMediaStreamSource(e),s=a.createAnalyser();s.fftSize=64,u.connect(s),ce.current=a,we.current=u,Je(s);const d=new MediaRecorder(e);re.current=d,Ue.current=[],d.ondataavailable=S=>{S.data.size>0&&Ue.current.push(S.data)},d.onstop=async()=>{const S=Date.now()-et.current;if(Je(null),we.current&&(we.current.disconnect(),we.current=null),ce.current&&ce.current.state!=="closed"&&(ce.current.close(),ce.current=null),S<1e3){y("Recording too short. Hold or click longer."),F(!1);return}const k=new Blob(Ue.current,{type:"audio/wav"});await xt(k)},et.current=Date.now(),d.start(100),$e(!0),y("Listening...")}catch(e){console.error("Error accessing microphone:",e),y("Mic Access Error")}},_t=()=>{re.current&&re.current.state!=="inactive"&&(re.current.stop(),re.current.stream.getTracks().forEach(e=>e.stop()),$e(!1))},wt=()=>{re.current&&re.current.state!=="inactive"&&(re.current.onstop=null,re.current.stop(),re.current.stream.getTracks().forEach(e=>e.stop()),Je(null),we.current&&(we.current.disconnect(),we.current=null),ce.current&&ce.current.state!=="closed"&&(ce.current.close(),ce.current=null),$e(!1),Ue.current=[],y("Ready"))};t.useEffect(()=>{if(!L)return;const e=()=>{const n=q.current;if(n<=0)return;const a=V.current,u=_.current;if(!a)return;const s=a.currentTime-u,d=Math.min(Math.max(0,s),n),S=le.trim().length;if(S<=0)return;const k=Math.min(Math.round(d/n*S),S);Oe(k)};return clearInterval(Me.current??void 0),Me.current=setInterval(e,90),()=>clearInterval(Me.current??void 0)},[L,le,q.current]),t.useEffect(()=>{let e;return He?(qe(0),e=window.setInterval(()=>{qe(n=>n+1)},1e3)):qe(0),()=>clearInterval(e)},[He]);const St=e=>{const n=e.numberOfChannels,a=e.length*n*2+44,u=new ArrayBuffer(a),s=new DataView(u);let d=0;const S=D=>{s.setUint16(d,D,!0),d+=2},k=D=>{s.setUint32(d,D,!0),d+=4};k(1179011410),k(a-8),k(1163280727),k(544501094),k(16),S(1),S(n),k(e.sampleRate),k(e.sampleRate*2*n),S(n*2),S(16),k(1635017060),k(a-d-4);const N=[];for(let D=0;D<n;D++)N.push(e.getChannelData(D));let v=0;for(;d<a;){for(let D=0;D<n;D++){let U=Math.max(-1,Math.min(1,N[D][v]));U=U<0?U*32768:U*32767,s.setInt16(d,U,!0),d+=2}v++}return new Blob([u],{type:"audio/wav"})},Ge=async(e,n,a=!1)=>{if(!Q.current){if(de.current){te.current.push({audio:e,visemes:n,isNewSegment:a});return}de.current=!0;try{const u=window.AudioContext||window.webkitAudioContext,s=V.current??new u;s.state==="suspended"&&await s.resume(),V.current=s;const d=window.atob(e),S=new Uint8Array(d.length);for(let M=0;M<d.length;M++)S[M]=d.charCodeAt(M);const k=await s.decodeAudioData(S.buffer.slice(0));q.current+=k.duration;const N=s.currentTime;let v=Y.current;const D=!T.current;v<N&&(v=N+.1),Y.current=v+k.duration;const U=s.createBufferSource();U.buffer=k;let P=tt;if((!P||P.context!==s)&&(P=s.createAnalyser(),P.fftSize=64,P.connect(s.destination),mt(P)),U.connect(P),R.current.push(U),Q.current){R.current=R.current.filter(M=>M!==U);return}if(D){T.current=!0,ie(!0),W(`[AUDIO] setIsSpeaking(true) - First chunk starting at ${v.toFixed(3)}`),_.current=v;const M=(v-N)*1e3;$.current=performance.now()+M,W(`[AUDIO] Response started. Initial startTime: ${v.toFixed(3)}, CT: ${N.toFixed(3)}`)}U.start(v);const z=(v-_.current)*1e3;a&&(oe.current=z,W(`[AUDIO] New segment detected at +${z.toFixed(0)}ms. Resetting segment offset.`)),n.forEach((M,ue)=>{const I=M.symbol??"";if(I){const Z=Vt(I),se=Math.round(M.start*1e3),Se=Math.round((M.duration??0)*1e3),st=oe.current+se;ue<3&&W(`[AUDIO] Viseme "${I}": segment_relative=${se}ms, segment_offset=${oe.current.toFixed(0)}ms => vtime=${st}ms`),Z.forEach(it=>{g.current.push({viseme:it.v,weight:it.w,vtime:st,vduration:Se})})}}),y("Speaking...")}finally{if(de.current=!1,te.current.length>0){const u=te.current.shift();u&&Ge(u.audio,u.visemes,u.isNewSegment)}}}},xt=async e=>{try{F(!0),Le.current="",ee(""),y("Processing Voice...");const n=await e.arrayBuffer(),u=await new(window.AudioContext||window.webkitAudioContext)().decodeAudioData(n),s=St(u),d=new FileReader;d.readAsDataURL(s),d.onloadend=async()=>{const S=d.result.split(",")[1];je(),A(""),ae.current="",Ae.current=!1;const k=`${at}/stt?token=${encodeURIComponent(h)}`,N=await fetch(k,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({audio_base64:S,audio_format:"wav"})});if(!N.ok){const ue=await N.text();let I="STT Failed";try{I=JSON.parse(ue).error||I}catch{ue&&(I=ue.slice(0,200))}throw new Error(I)}const v=N.body;if(W("this is body"+v),!v){y("STT Failed"),F(!1);return}const D=v.getReader();Q.current=!1;const U=new TextDecoder;let P="",z=!1;const M=async(ue,I)=>{switch(ue){case"transcript":I.transcript!=null&&A(String(I.transcript));break;case"text":{const Z=I.delta??I.text??"";Z&&Ke(Z);break}case"audio":{const Z=I.chunk,se=I.visemes??[],Se=!!I.is_new_segment;Z&&await Ge(Z,se,Se);break}case"done":{z=!0,y("Ready"),F(!1);break}case"error":{z=!0,y("STT Failed"),F(!1);break}default:break}};for(;;){const{done:ue,value:I}=await D.read();I&&(P+=U.decode(I,{stream:!0}));const Z=P.split(`
4
4
 
5
- `);P=Z.pop()??"";for(const se of Z){const Se=je(se);Se&&await T(Se.event,Se.data)}if(ue){if(P.trim()){const se=je(P.trim());se&&await T(se.event,se.data)}z||(y("Ready"),F(!1));break}}}}catch(n){console.error("Audio Submission Error:",n),y("STT Failed"),F(!1)}},vt=async e=>{e&&e.preventDefault(),Le.current="",ee(""),!(!E||X)&&await yt(E)},je=e=>{const n=e.split(/\r?\n/);let a="",u="";for(const d of n)d.startsWith("event:")?a=d.slice(6).trim():d.startsWith("data:")&&(u=d.slice(5).trim());if(!a)return null;let s={};if(u)try{s=JSON.parse(u)}catch{s={raw:u}}return{event:a,data:s}},nt=(e,n)=>{switch(e){case"connected":ae.current="",Ae.current=!1;break;case"text":{const a=n.delta??"";a&&Ke(a);break}case"audio":{const a=n.chunk,u=n.visemes??[];a&&Ge(a,u);break}case"done":{const a=Qe(),u=Le.current.trim(),s=[...a,{role:"user",content:E||"..."},{role:"assistant",content:u}];pt(s),x.current=[...g.current],y("Ready"),F(!1),A("");break}case"error":{const a=n.message??"Unknown error";Le.current=a,ee(a),y("Agent Failed"),F(!1);break}}},yt=async e=>{F(!0),y("Thinking..."),Le.current="",ae.current="",Ae.current=!1,Ne(),q.current=0,Oe(0);const n=`${at}/agent/chat?token=${encodeURIComponent(h)}`;try{const a=Qe();let u=sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");u||(Et("[CHAT] Session UID missing at send time! Generating emergency backup."),u="emergency-"+Math.random().toString(36).substring(7),sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",u));const s={history:a,question:e,lead_id:u};W("[CHAT] Sending payload:",s);const d=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),cache:"default"});if(!d.ok)throw new Error("Agent request failed");const S=d.body;if(!S){y("Agent Failed"),F(!1);return}const k=S.getReader();Q.current=!1;const j=new TextDecoder;let v="";for(;;){const{done:D,value:U}=await k.read();W(`[SSE] Chunk received. done=${D}, length=${U?.length||0}`),U&&(v+=j.decode(U,{stream:!0}));const P=v.split(`
5
+ `);P=Z.pop()??"";for(const se of Z){const Se=Ne(se);Se&&await M(Se.event,Se.data)}if(ue){if(P.trim()){const se=Ne(P.trim());se&&await M(se.event,se.data)}z||(y("Ready"),F(!1));break}}}}catch(n){console.error("Audio Submission Error:",n),y("STT Failed"),F(!1)}},vt=async e=>{e&&e.preventDefault(),Le.current="",ee(""),!(!E||X)&&await yt(E)},Ne=e=>{const n=e.split(/\r?\n/);let a="",u="";for(const d of n)d.startsWith("event:")?a=d.slice(6).trim():d.startsWith("data:")&&(u=d.slice(5).trim());if(!a)return null;let s={};if(u)try{s=JSON.parse(u)}catch{s={raw:u}}return{event:a,data:s}},nt=(e,n)=>{switch(e){case"connected":ae.current="",Ae.current=!1;break;case"text":{const a=n.delta??"";a&&Ke(a);break}case"audio":{const a=n.chunk,u=n.visemes??[];a&&Ge(a,u);break}case"done":{const a=Qe(),u=Le.current.trim(),s=[...a,{role:"user",content:E||"..."},{role:"assistant",content:u}];pt(s),x.current=[...g.current],y("Ready"),F(!1),A("");break}case"error":{const a=n.message??"Unknown error";Le.current=a,ee(a),y("Agent Failed"),F(!1);break}}},yt=async e=>{F(!0),y("Thinking..."),Le.current="",ae.current="",Ae.current=!1,je(),q.current=0,Oe(0);const n=`${at}/agent/chat?token=${encodeURIComponent(h)}`;try{const a=Qe();let u=sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");u||(Et("[CHAT] Session UID missing at send time! Generating emergency backup."),u="emergency-"+Math.random().toString(36).substring(7),sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",u));const s={history:a,question:e,lead_id:u};W("[CHAT] Sending payload:",s);const d=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),cache:"default"});if(!d.ok)throw new Error("Agent request failed");const S=d.body;if(!S){y("Agent Failed"),F(!1);return}const k=S.getReader();Q.current=!1;const N=new TextDecoder;let v="";for(;;){const{done:D,value:U}=await k.read();W(`[SSE] Chunk received. done=${D}, length=${U?.length||0}`),U&&(v+=N.decode(U,{stream:!0}));const P=v.split(`
6
6
 
7
- `);v=P.pop()??"";for(const z of P){W(`[SSE] Processing block: ${z.slice(0,50)}...`);const T=je(z);T&&(W(`[SSE] Event: ${T.event}`),nt(T.event,T.data))}if(D){if(W("[SSE] Stream finished"),v.trim()){const z=je(v.trim());z&&nt(z.event,z.data)}y("Ready"),F(!1),A("");break}}}catch(a){console.error("Chat Error:",a),y("Agent Failed"),F(!1)}},rt=le.trim(),ze=rt&&L?rt.slice(0,ve!=null&&ve>0?ve:0):"";t.useEffect(()=>{const e=Be.current;e!=="exiting"&&(ze?(_e(ze),e==="hidden"&&be("entering")):(e==="visible"||e==="entering")&&be("exiting"))},[ze,N]);const Rt=t.useCallback(()=>{const e=Be.current;e==="entering"?be("visible"):e==="exiting"&&be("hidden")},[]);return t.useLayoutEffect(()=>{const e=ne.current;e&&(e.scrollTop=e.scrollHeight)},[ke]),o.jsxs("div",{className:"avatar-widget-container",children:[o.jsxs("div",{className:"avatar-input-area",children:[he!=="hidden"?o.jsx("div",{className:`avatar-thinking-tab${he==="exiting"?" avatar-thinking-tab--exiting":he==="entering"?" avatar-thinking-tab--entering":""}`,onAnimationEnd:lt,children:Me}):null,o.jsx("div",{className:"avatar-input-container",children:o.jsx("div",{style:{display:"flex",alignItems:"center",width:"100%",height:"100%"},children:$e?o.jsxs("div",{className:"avatar-input-recording",children:[o.jsx("button",{type:"button",className:"avatar-recording-cancel",onClick:wt,title:"Cancel",children:o.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:[o.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),o.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}),o.jsxs("div",{style:{flex:1,height:"100%",position:"relative",display:"flex",alignItems:"center",minWidth:0},children:[o.jsx("div",{style:{flex:1,height:"100%"},children:o.jsx(ot,{analyser:gt})}),o.jsxs("span",{style:{fontSize:"0.75rem",color:"#64748b",fontWeight:500,marginLeft:"4px",minWidth:"32px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:[Math.floor(Ze/60),":",String(Ze%60).padStart(2,"0")]})]}),o.jsx("button",{type:"button",className:"avatar-recording-confirm",onClick:_t,title:"Send",children:o.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:o.jsx("polyline",{points:"20 6 9 17 4 12"})})})]}):L?o.jsxs("div",{className:"avatar-input-speaking",children:[o.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",paddingRight:"8px"},children:o.jsx(ot,{analyser:tt})}),o.jsx("button",{type:"button",className:"avatar-speaking-stop",onClick:()=>Ne(!0),title:"Stop",children:o.jsx("span",{className:"avatar-speaking-stop__icon","aria-hidden":!0})})]}):X?o.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",justifyContent:"center"},children:o.jsx("div",{className:"avatar-input-loader"})}):o.jsxs("form",{onSubmit:vt,style:{flex:1,display:"flex",height:"100%",alignItems:"center"},children:[o.jsx("input",{id:"avatar-text-input",type:"text",value:E,onChange:e=>A(e.target.value),placeholder:"Ask me anything",disabled:X,autoComplete:"off",style:{width:"100%",height:"100%"}}),E.trim()===""?o.jsx("button",{type:"button",className:"mic-button",onClick:bt,disabled:X,style:{backgroundColor:"#1e4a5e"},children:o.jsxs("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[o.jsx("path",{d:"M12 14C13.66 14 15 12.66 15 11V5C15 3.34 13.66 2 12 2C10.34 2 9 3.34 9 5V11C9 12.66 10.34 14 12 14Z",fill:"white"}),o.jsx("path",{d:"M17 11C17 13.76 14.76 16 12 16C9.24 16 7 13.76 7 11H5C5 14.53 7.61 17.43 11 17.93V21H13V17.93C16.39 17.43 19 14.53 19 11H17Z",fill:"white"})]})}):o.jsx("button",{type:"submit",className:"mic-button",disabled:X,style:{backgroundColor:"#1e4a5e"},title:"Send",children:o.jsx("img",{src:"/assets/leadmoji-logo-send.png",alt:"Send",width:24,height:24})})]})})})]}),o.jsx("div",{className:"avatar-wrapper",children:o.jsxs("div",{className:"avatar-scene-wrapper",children:[N!=="hidden"&&o.jsx("div",{className:`avatar-bubble${N==="entering"?" avatar-bubble--entering":N==="exiting"?" avatar-bubble--exiting":""}`,onAnimationEnd:Rt,children:o.jsx("div",{ref:ne,className:"avatar-bubble__content",children:ke})}),o.jsx("div",{className:"avatar-canvas-layer",style:{width:K,height:K},children:o.jsxs(Xe.Canvas,{shadows:!0,camera:{position:[.2,1.4,3],fov:42},gl:{alpha:!0},dpr:1.8,style:{pointerEvents:"none",width:"100%",height:"100%"},children:[o.jsx(Bt,{target:Ut}),o.jsx("ambientLight",{intensity:.7}),o.jsx("directionalLight",{position:[0,2,2],intensity:1}),o.jsx(We.Environment,{preset:"city"}),o.jsx(t.Suspense,{fallback:null,children:C!==null&&o.jsx($t,{avatarUrl:C,isPlayingRef:M,visemeQueueRef:g,audioContextRef:V,responseAudioStartTimeRef:_,adjustments:Ft,mood:f,expression:i,agentResponse:le,isSpeaking:L,nextStartTimeRef:Y,stopPlayback:Ne,setIsSpeaking:ie,expressionUrl:p,onExpressionFinished:ht})})]})})]})})]})},Jt=({token:c,onNavigationRequested:w})=>o.jsx(qt,{token:c,onNavigationRequested:w});exports.AvatarWidget=Jt;
7
+ `);v=P.pop()??"";for(const z of P){W(`[SSE] Processing block: ${z.slice(0,50)}...`);const M=Ne(z);M&&(W(`[SSE] Event: ${M.event}`),nt(M.event,M.data))}if(D){if(W("[SSE] Stream finished"),v.trim()){const z=Ne(v.trim());z&&nt(z.event,z.data)}y("Ready"),F(!1),A("");break}}}catch(a){console.error("Chat Error:",a),y("Agent Failed"),F(!1)}},rt=le.trim(),ze=rt&&L?rt.slice(0,ve!=null&&ve>0?ve:0):"";t.useEffect(()=>{const e=Be.current;e!=="exiting"&&(ze?(_e(ze),e==="hidden"&&be("entering")):(e==="visible"||e==="entering")&&be("exiting"))},[ze,j]);const Rt=t.useCallback(()=>{const e=Be.current;e==="entering"?be("visible"):e==="exiting"&&be("hidden")},[]);return t.useLayoutEffect(()=>{const e=ne.current;e&&(e.scrollTop=e.scrollHeight)},[ke]),o.jsxs("div",{className:"avatar-widget-container",children:[o.jsxs("div",{className:"avatar-input-area",children:[he!=="hidden"?o.jsx("div",{className:`avatar-thinking-tab${he==="exiting"?" avatar-thinking-tab--exiting":he==="entering"?" avatar-thinking-tab--entering":""}`,onAnimationEnd:lt,children:Te}):null,o.jsx("div",{className:"avatar-input-container",children:o.jsx("div",{style:{display:"flex",alignItems:"center",width:"100%",height:"100%"},children:He?o.jsxs("div",{className:"avatar-input-recording",children:[o.jsx("button",{type:"button",className:"avatar-recording-cancel",onClick:wt,title:"Cancel",children:o.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:[o.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),o.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}),o.jsxs("div",{style:{flex:1,height:"100%",position:"relative",display:"flex",alignItems:"center",minWidth:0},children:[o.jsx("div",{style:{flex:1,height:"100%"},children:o.jsx(ot,{analyser:gt})}),o.jsxs("span",{style:{fontSize:"0.75rem",color:"#64748b",fontWeight:500,marginLeft:"4px",minWidth:"32px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:[Math.floor(Ze/60),":",String(Ze%60).padStart(2,"0")]})]}),o.jsx("button",{type:"button",className:"avatar-recording-confirm",onClick:_t,title:"Send",children:o.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:o.jsx("polyline",{points:"20 6 9 17 4 12"})})})]}):L?o.jsxs("div",{className:"avatar-input-speaking",children:[o.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",paddingRight:"8px"},children:o.jsx(ot,{analyser:tt})}),o.jsx("button",{type:"button",className:"avatar-speaking-stop",onClick:()=>je(!0),title:"Stop",children:o.jsx("span",{className:"avatar-speaking-stop__icon","aria-hidden":!0})})]}):X?o.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",justifyContent:"center"},children:o.jsx("div",{className:"avatar-input-loader"})}):o.jsxs("form",{onSubmit:vt,style:{flex:1,display:"flex",height:"100%",alignItems:"center"},children:[o.jsx("input",{id:"avatar-text-input",type:"text",value:E,onChange:e=>A(e.target.value),placeholder:"Ask me anything",disabled:X,autoComplete:"off",style:{width:"100%",height:"100%"}}),E.trim()===""?o.jsx("button",{type:"button",className:"mic-button",onClick:bt,disabled:X,style:{backgroundColor:"#1e4a5e"},children:o.jsxs("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[o.jsx("path",{d:"M12 14C13.66 14 15 12.66 15 11V5C15 3.34 13.66 2 12 2C10.34 2 9 3.34 9 5V11C9 12.66 10.34 14 12 14Z",fill:"white"}),o.jsx("path",{d:"M17 11C17 13.76 14.76 16 12 16C9.24 16 7 13.76 7 11H5C5 14.53 7.61 17.43 11 17.93V21H13V17.93C16.39 17.43 19 14.53 19 11H17Z",fill:"white"})]})}):o.jsx("button",{type:"submit",className:"mic-button",disabled:X,style:{backgroundColor:"#1e4a5e"},title:"Send",children:o.jsx("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:o.jsx("path",{d:"M19 12H5M19 12L14 17M19 12L14 7",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})})})]}),o.jsx("div",{className:"avatar-wrapper",children:o.jsxs("div",{className:"avatar-scene-wrapper",children:[j!=="hidden"&&o.jsx("div",{className:`avatar-bubble${j==="entering"?" avatar-bubble--entering":j==="exiting"?" avatar-bubble--exiting":""}`,onAnimationEnd:Rt,children:o.jsx("div",{ref:ne,className:"avatar-bubble__content",children:ke})}),o.jsx("div",{className:"avatar-canvas-layer",style:{width:K,height:K},children:o.jsxs(Xe.Canvas,{shadows:!0,camera:{position:[.2,1.4,3],fov:42},gl:{alpha:!0},dpr:1.8,style:{pointerEvents:"none",width:"100%",height:"100%"},children:[o.jsx(Bt,{target:Ut}),o.jsx("ambientLight",{intensity:.7}),o.jsx("directionalLight",{position:[0,2,2],intensity:1}),o.jsx(We.Environment,{preset:"city"}),o.jsx(t.Suspense,{fallback:null,children:C!==null&&o.jsx(Ht,{avatarUrl:C,isPlayingRef:T,visemeQueueRef:g,audioContextRef:V,responseAudioStartTimeRef:_,adjustments:Ft,mood:f,expression:i,agentResponse:le,isSpeaking:L,nextStartTimeRef:Y,stopPlayback:je,setIsSpeaking:ie,expressionUrl:p,onExpressionFinished:ht})})]})})]})})]})},Jt=({token:c,onNavigationRequested:w})=>o.jsx(qt,{token:c,onNavigationRequested:w});exports.AvatarWidget=Jt;
8
8
  //# sourceMappingURL=avatar-widget.cjs.map