hanc-webrtc-widgets 2.5.1 → 2.5.2
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.
|
@@ -55548,7 +55548,7 @@ const Ca = vF(), Lr = {
|
|
|
55548
55548
|
theme: "default",
|
|
55549
55549
|
allow_all_domains: !0,
|
|
55550
55550
|
allowed_domains: []
|
|
55551
|
-
}, Ts = /* @__PURE__ */ new Map(), LF =
|
|
55551
|
+
}, Ts = /* @__PURE__ */ new Map(), LF = 1e3;
|
|
55552
55552
|
async function xC(i, A = Ca) {
|
|
55553
55553
|
if (!i)
|
|
55554
55554
|
return console.warn("[hanc-widget] No agentId provided, using default config"), Lr;
|
|
@@ -4568,7 +4568,7 @@ void main() {
|
|
|
4568
4568
|
// Softer alpha for more diffuse appearance
|
|
4569
4569
|
gl_FragColor = vec4(glowColor, glow * 0.4);
|
|
4570
4570
|
}
|
|
4571
|
-
`,Kn={primary:"#6366f1",secondary:"#8b5cf6",accent:"#06b6d4",glow:"#818cf8",atmosphere:"#c4b5fd",depth:"#312e81",highlight:"#e0e7ff"},qG={size:1,segments:128,colors:Kn,morphStrength:1,noiseScale:1.5,noiseSpeed:.3,glowIntensity:.8,idleGlowMultiplier:.4,fresnelPower:2.5,rotationSpeed:.1,audioReactivity:3,audioSmoothing:.9,idleMorphMultiplier:.25,colorContrast:1.5};class sC{constructor(A,e={}){this.orb=null,this.glowMesh=null,this.orbMaterial=null,this.glowMaterial=null,this.animationId=null,this.isActive=!1,this.targetRotation={x:0,y:0},this.currentRotation={x:0,y:0},this.audioValues={bass:0,mid:0,treble:0,level:0},this.resizeObserver=null,this.resizeTimeoutId=null,this.isContextLost=!1,this.animate=()=>{if(this.isContextLost)return;this.animationId=requestAnimationFrame(this.animate);const r=this.clock.getElapsedTime();if(this.clock.getDelta(),this.orbMaterial){this.orbMaterial.uniforms.uTime.value=r,this.orbMaterial.uniforms.uAudioBass.value=this.audioValues.bass,this.orbMaterial.uniforms.uAudioMid.value=this.audioValues.mid,this.orbMaterial.uniforms.uAudioTreble.value=this.audioValues.treble,this.orbMaterial.uniforms.uAudioLevel.value=this.audioValues.level;const Q=this.isActive?this.config.morphStrength*1.5:this.config.morphStrength*this.config.idleMorphMultiplier,B=this.orbMaterial.uniforms.uMorphStrength.value;this.orbMaterial.uniforms.uMorphStrength.value+=(Q-B)*.05}if(this.glowMaterial){this.glowMaterial.uniforms.uTime.value=r,this.glowMaterial.uniforms.uAudioLevel.value=this.audioValues.level;const Q=this.isActive?this.config.glowIntensity*1.5:this.config.glowIntensity*this.config.idleGlowMultiplier,B=this.glowMaterial.uniforms.uGlowIntensity.value;this.glowMaterial.uniforms.uGlowIntensity.value+=(Q-B)*.05}this.currentRotation.x+=(this.targetRotation.x-this.currentRotation.x)*.05,this.currentRotation.y+=(this.targetRotation.y-this.currentRotation.y)*.05,this.orb&&(this.orb.rotation.x=this.currentRotation.x+r*this.config.rotationSpeed*.3,this.orb.rotation.y=this.currentRotation.y+r*this.config.rotationSpeed),this.glowMesh&&(this.glowMesh.rotation.x=this.currentRotation.x+r*this.config.rotationSpeed*.3,this.glowMesh.rotation.y=this.currentRotation.y+r*this.config.rotationSpeed),this.renderer.render(this.scene,this.camera)},this.handleResize=()=>{this.resizeTimeoutId!==null&&clearTimeout(this.resizeTimeoutId),this.resizeTimeoutId=setTimeout(()=>{this.resizeTimeoutId=null;const r=this.container.clientWidth,Q=this.container.clientHeight;if(r===0||Q===0)return;const B=r*this.canvasPadding,d=Q*this.canvasPadding;this.camera.aspect=B/d,this.camera.updateProjectionMatrix(),this.renderer.setSize(B,d)},100)},this.handleMouseMove=r=>{const Q=this.container.getBoundingClientRect(),B=(r.clientX-Q.left)/Q.width*2-1,d=-((r.clientY-Q.top)/Q.height)*2+1;this.targetRotation.x=d*.3,this.targetRotation.y=B*.3},this.handleMouseLeave=()=>{this.targetRotation.x=0,this.targetRotation.y=0},this.container=A,this.config={...qG,...e},this.clock=new DR;const t=/iPhone|iPad|iPod/i.test(navigator.userAgent),g=/Android/i.test(navigator.userAgent);this.canvasPadding=t?1.5:g?2:3,this.boundHandleContextLost=this.handleContextLost.bind(this),this.boundHandleContextRestored=this.handleContextRestored.bind(this),this.scene=new QR;const n=A.clientWidth*this.canvasPadding,o=A.clientHeight*this.canvasPadding,a=n/o;this.camera=new Ii(45,a,.1,100);const I=3,s=9;this.camera.position.z=s*(this.canvasPadding/I),this.renderer=new UG({antialias:!0,alpha:!0,powerPreference:"high-performance"}),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.renderer.setSize(n,o),this.renderer.setClearColor(0,0);const C=this.renderer.domElement;C.style.position="absolute",C.style.left="50%",C.style.top="50%",C.style.transform="translate(-50%, -50%)",C.style.pointerEvents="none",A.appendChild(C),C.addEventListener("webglcontextlost",this.boundHandleContextLost),C.addEventListener("webglcontextrestored",this.boundHandleContextRestored),this.createOrb(),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(this.handleResize),this.resizeObserver.observe(A),A.addEventListener("mousemove",this.handleMouseMove),A.addEventListener("mouseleave",this.handleMouseLeave)}handleContextLost(A){A.preventDefault(),this.isContextLost=!0,this.stop()}handleContextRestored(A){this.isContextLost=!1,this.recreateAfterContextLoss(),this.start()}recreateAfterContextLoss(){this.orb&&(this.orb.geometry.dispose(),this.scene.remove(this.orb),this.orb=null),this.glowMesh&&(this.glowMesh.geometry.dispose(),this.scene.remove(this.glowMesh),this.glowMesh=null),this.orbMaterial&&(this.orbMaterial.dispose(),this.orbMaterial=null),this.glowMaterial&&(this.glowMaterial.dispose(),this.glowMaterial=null),this.createOrb()}createOrb(){const A={...Kn,...this.config.colors},e=new kE(this.config.size,this.config.segments/4);this.orbMaterial=new ai({vertexShader:TG,fragmentShader:KG,uniforms:{uTime:{value:0},uAudioBass:{value:0},uAudioMid:{value:0},uAudioTreble:{value:0},uAudioLevel:{value:0},uMorphStrength:{value:this.config.morphStrength},uNoiseScale:{value:this.config.noiseScale},uNoiseSpeed:{value:this.config.noiseSpeed},uAudioReactivity:{value:this.config.audioReactivity},uColorPrimary:{value:new re(A.primary)},uColorSecondary:{value:new re(A.secondary)},uColorAccent:{value:new re(A.accent)},uColorDepth:{value:new re(A.depth||Kn.depth)},uColorHighlight:{value:new re(A.highlight||Kn.highlight)},uFresnelPower:{value:this.config.fresnelPower},uGlowIntensity:{value:this.config.glowIntensity},uColorContrast:{value:this.config.colorContrast}},transparent:!0,side:lg}),this.orb=new Ni(e,this.orbMaterial),this.scene.add(this.orb);const t=new yE(this.config.size,64,64);this.glowMaterial=new ai({vertexShader:JG,fragmentShader:YG,uniforms:{uTime:{value:0},uAudioLevel:{value:0},uGlowColor:{value:new re(A.glow)},uGlowIntensity:{value:this.config.glowIntensity*.6},uPulseSpeed:{value:2}},transparent:!0,side:St,blending:zQ,depthWrite:!1}),this.glowMesh=new Ni(t,this.glowMaterial),this.scene.add(this.glowMesh)}updateAudio(A){const e=this.config.audioSmoothing;this.audioValues.bass+=(A.bass-this.audioValues.bass)*e,this.audioValues.mid+=(A.mid-this.audioValues.mid)*e,this.audioValues.treble+=(A.treble-this.audioValues.treble)*e,this.audioValues.level+=(A.level-this.audioValues.level)*e}setSimulatedAudio(A,e,t,g){const n=this.config.audioSmoothing;this.audioValues.bass+=(A-this.audioValues.bass)*n,this.audioValues.mid+=(e-this.audioValues.mid)*n,this.audioValues.treble+=(t-this.audioValues.treble)*n,this.audioValues.level+=(g-this.audioValues.level)*n}setActive(A){this.isActive=A}setColors(A){const e={...Kn,...this.config.colors,...A};this.orbMaterial&&(this.orbMaterial.uniforms.uColorPrimary.value.set(e.primary),this.orbMaterial.uniforms.uColorSecondary.value.set(e.secondary),this.orbMaterial.uniforms.uColorAccent.value.set(e.accent),this.orbMaterial.uniforms.uColorDepth.value.set(e.depth||Kn.depth),this.orbMaterial.uniforms.uColorHighlight.value.set(e.highlight||Kn.highlight)),this.glowMaterial&&this.glowMaterial.uniforms.uGlowColor.value.set(e.glow)}setGlowSettings(A,e){this.config.glowIntensity=A,this.config.idleGlowMultiplier=e}start(){this.animationId===null&&(this.clock.start(),this.animate())}stop(){this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null)}getCanvas(){return this.renderer.domElement}destroy(){this.stop(),this.resizeTimeoutId!==null&&(clearTimeout(this.resizeTimeoutId),this.resizeTimeoutId=null),window.removeEventListener("resize",this.handleResize),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.container.removeEventListener("mousemove",this.handleMouseMove),this.container.removeEventListener("mouseleave",this.handleMouseLeave);const A=this.renderer.domElement;A.removeEventListener("webglcontextlost",this.boundHandleContextLost),A.removeEventListener("webglcontextrestored",this.boundHandleContextRestored),this.orb&&(this.orb.geometry.dispose(),this.scene.remove(this.orb),this.orb=null),this.glowMesh&&(this.glowMesh.geometry.dispose(),this.scene.remove(this.glowMesh),this.glowMesh=null),this.orbMaterial&&(this.orbMaterial.dispose(),this.orbMaterial=null),this.glowMaterial&&(this.glowMaterial.dispose(),this.glowMaterial=null),this.renderer.dispose(),A.parentNode&&A.parentNode.removeChild(A)}}class Po{constructor(){this.audioContext=null,this.refCount=0,this.resumePromise=null}static getInstance(){return Po.instance||(Po.instance=new Po),Po.instance}async acquire(){if(this.refCount++,!this.audioContext)try{const A=window.AudioContext||window.webkitAudioContext;if(!A)return console.warn("[SharedAudioContext] Web Audio API not supported"),null;this.audioContext=new A,console.log("[SharedAudioContext] Created shared AudioContext")}catch(A){return console.warn("[SharedAudioContext] Failed to create AudioContext:",A),null}return await this.ensureResumed(),this.audioContext}release(){this.refCount=Math.max(0,this.refCount-1),this.refCount===0&&console.log("[SharedAudioContext] All references released, context kept alive for reuse")}forceClose(){if(this.audioContext){try{this.audioContext.close()}catch{}this.audioContext=null,this.refCount=0,console.log("[SharedAudioContext] Force closed")}}getContext(){return this.audioContext}async ensureResumed(){if(!this.audioContext)return!1;if(this.audioContext.state==="suspended"){this.resumePromise||(this.resumePromise=this.audioContext.resume().finally(()=>{this.resumePromise=null}));try{await this.resumePromise}catch{return!1}}return this.audioContext.state==="running"}isRunning(){return this.audioContext!==null&&this.audioContext.state==="running"}getState(){var A;return((A=this.audioContext)==null?void 0:A.state)??null}getSampleRate(){var A;return((A=this.audioContext)==null?void 0:A.sampleRate)??44100}getCurrentTime(){var A;return((A=this.audioContext)==null?void 0:A.currentTime)??0}getDestination(){var A;return((A=this.audioContext)==null?void 0:A.destination)??null}}const Oo=Po.getInstance();typeof window<"u"&&window.addEventListener("pagehide",()=>{Oo.forceClose()});class CC{constructor(A={}){this.audioContext=null,this.analyser=null,this.source=null,this.localSource=null,this.mixer=null,this.frequencyData=new Uint8Array(0),this.waveformData=new Float32Array(0),this.hasAcquiredContext=!1,this.smoothedBass=0,this.smoothedMid=0,this.smoothedTreble=0,this.smoothedLevel=0,this.smoothingFactor=.3,this.options={fftSize:A.fftSize??2048,smoothingTimeConstant:A.smoothingTimeConstant??.8,minDecibels:A.minDecibels??-90,maxDecibels:A.maxDecibels??-10}}async ensureAudioContext(){if(!this.audioContext)this.audioContext=await Oo.acquire(),this.audioContext&&(this.hasAcquiredContext=!0);else if(!await Oo.ensureResumed())return null;return this.audioContext}async connectStream(A){const e=await this.ensureAudioContext();if(!e){console.warn("[AudioAnalyzer] Could not acquire AudioContext");return}if(this.source)try{this.source.disconnect()}catch{}this.source=e.createMediaStreamSource(A),this.setupMixerAndAnalyser(),this.mixer&&this.source.connect(this.mixer)}async connectLocalStream(A){const e=await this.ensureAudioContext();if(!e){console.warn("[AudioAnalyzer] Could not acquire AudioContext");return}if(this.localSource)try{this.localSource.disconnect()}catch{}this.localSource=e.createMediaStreamSource(A),this.setupMixerAndAnalyser(),this.mixer&&this.localSource.connect(this.mixer)}setupMixerAndAnalyser(){this.audioContext&&(this.mixer||(this.mixer=this.audioContext.createGain(),this.mixer.gain.value=1),this.analyser||(this.analyser=this.audioContext.createAnalyser()),this.analyser.fftSize=this.options.fftSize,this.analyser.smoothingTimeConstant=this.options.smoothingTimeConstant,this.analyser.minDecibels=this.options.minDecibels,this.analyser.maxDecibels=this.options.maxDecibels,this.mixer.disconnect(),this.mixer.connect(this.analyser),this.frequencyData=new Uint8Array(this.analyser.frequencyBinCount),this.waveformData=new Float32Array(this.analyser.fftSize))}async connectAudioElement(A){const e=await this.ensureAudioContext();if(!e){console.warn("[AudioAnalyzer] Could not acquire AudioContext");return}if(this.source)try{this.source.disconnect()}catch{}const t=e.createMediaElementSource(A);this.analyser||(this.analyser=e.createAnalyser()),this.analyser.fftSize=this.options.fftSize,this.analyser.smoothingTimeConstant=this.options.smoothingTimeConstant,this.analyser.minDecibels=this.options.minDecibels,this.analyser.maxDecibels=this.options.maxDecibels,t.connect(this.analyser),this.analyser.connect(e.destination),this.frequencyData=new Uint8Array(this.analyser.frequencyBinCount),this.waveformData=new Float32Array(this.analyser.fftSize)}getAudioData(){if(!this.analyser)return{bass:0,mid:0,treble:0,level:0,waveform:new Float32Array(0),frequency:new Uint8Array(0)};this.analyser.getByteFrequencyData(this.frequencyData),this.analyser.getFloatTimeDomainData(this.waveformData);const{bass:A,mid:e,treble:t}=this.calculateFrequencyBands(),g=this.calculateOverallLevel();return this.smoothedBass+=(A-this.smoothedBass)*this.smoothingFactor,this.smoothedMid+=(e-this.smoothedMid)*this.smoothingFactor,this.smoothedTreble+=(t-this.smoothedTreble)*this.smoothingFactor,this.smoothedLevel+=(g-this.smoothedLevel)*this.smoothingFactor,{bass:this.smoothedBass,mid:this.smoothedMid,treble:this.smoothedTreble,level:this.smoothedLevel,waveform:this.waveformData,frequency:this.frequencyData}}calculateFrequencyBands(){if(!this.audioContext||this.frequencyData.length===0)return{bass:0,mid:0,treble:0};const A=this.audioContext.sampleRate,e=this.frequencyData.length,t=A/(e*2),g=Math.floor(250/t),n=Math.floor(2e3/t);let o=0,a=0,I=0;for(let Q=0;Q<e;Q++){const B=this.frequencyData[Q]/255;Q<g?o+=B:Q<n?a+=B:I+=B}const s=g>0?o/g:0,C=n-g>0?a/(n-g):0,r=e-n>0?I/(e-n):0;return{bass:Math.pow(s,.8),mid:Math.pow(C,.9),treble:Math.pow(r,1.1)}}calculateOverallLevel(){if(this.frequencyData.length===0)return 0;let A=0;for(let t=0;t<this.frequencyData.length;t++)A+=this.frequencyData[t];const e=A/this.frequencyData.length/255;return Math.pow(e,.8)}getPeakLevel(){if(this.frequencyData.length===0)return 0;let A=0;for(let e=0;e<this.frequencyData.length;e++)this.frequencyData[e]>A&&(A=this.frequencyData[e]);return A/255}isActive(){return this.audioContext!==null&&this.audioContext.state==="running"}disconnect(){if(this.source){try{this.source.disconnect()}catch{}this.source=null}if(this.localSource){try{this.localSource.disconnect()}catch{}this.localSource=null}if(this.mixer){try{this.mixer.disconnect()}catch{}this.mixer=null}if(this.analyser){try{this.analyser.disconnect()}catch{}this.analyser=null}this.hasAcquiredContext&&(Oo.release(),this.hasAcquiredContext=!1),this.audioContext=null,this.smoothedBass=0,this.smoothedMid=0,this.smoothedTreble=0,this.smoothedLevel=0}getAudioContext(){return this.audioContext}getAnalyser(){return this.analyser}}class aI{constructor(A={}){this.hasAcquired=!1,this.config={enabled:!0,volume:.3,preset:"1",...A}}async ensureContext(){if(!this.config.enabled||this.config.preset==="none")return null;const A=await Oo.acquire();return A&&(this.hasAcquired=!0),A}async prewarm(){await this.ensureContext()}async playDrop(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=A?900:700,o=A?500:400,a=e.createOscillator(),I=e.createGain();a.type="sine",a.frequency.setValueAtTime(n,t),a.frequency.exponentialRampToValueAtTime(o,t+.15),I.gain.setValueAtTime(0,t),I.gain.linearRampToValueAtTime(g*.3,t+.015),I.gain.linearRampToValueAtTime(g*.2,t+.1),I.gain.exponentialRampToValueAtTime(.001,t+.35),a.connect(I).connect(e.destination),a.start(t),a.stop(t+.4)}async playGlassTap(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=A?2200:1760,o=e.createOscillator(),a=e.createGain();o.type="sine",o.frequency.setValueAtTime(n,t),a.gain.setValueAtTime(0,t),a.gain.linearRampToValueAtTime(g*.25,t+.002),a.gain.exponentialRampToValueAtTime(g*.1,t+.08),a.gain.exponentialRampToValueAtTime(.001,t+.3),o.connect(a).connect(e.destination),o.start(t),o.stop(t+.35);const I=e.createOscillator(),s=e.createGain();I.type="sine",I.frequency.setValueAtTime(n*2.5,t),s.gain.setValueAtTime(0,t),s.gain.linearRampToValueAtTime(g*.08,t+.001),s.gain.exponentialRampToValueAtTime(.001,t+.12),I.connect(s).connect(e.destination),I.start(t),I.stop(t+.15)}async playWhoosh(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=e.sampleRate*.5,o=e.createBuffer(1,n,e.sampleRate),a=o.getChannelData(0);for(let B=0;B<n;B++)a[B]=Math.random()*2-1;const I=e.createBufferSource();I.buffer=o;const s=e.createBiquadFilter();s.type="bandpass",s.Q.setValueAtTime(2,t);const C=e.createGain();A?(s.frequency.setValueAtTime(300,t),s.frequency.exponentialRampToValueAtTime(2e3,t+.15),s.frequency.exponentialRampToValueAtTime(800,t+.35),C.gain.setValueAtTime(0,t),C.gain.linearRampToValueAtTime(g*.3,t+.05),C.gain.linearRampToValueAtTime(g*.4,t+.15),C.gain.exponentialRampToValueAtTime(.001,t+.4)):(s.frequency.setValueAtTime(1500,t),s.frequency.exponentialRampToValueAtTime(200,t+.3),C.gain.setValueAtTime(0,t),C.gain.linearRampToValueAtTime(g*.35,t+.05),C.gain.exponentialRampToValueAtTime(.001,t+.35));const r=e.createOscillator(),Q=e.createGain();r.type="sine",A?(r.frequency.setValueAtTime(300,t),r.frequency.linearRampToValueAtTime(500,t+.2)):(r.frequency.setValueAtTime(400,t),r.frequency.linearRampToValueAtTime(200,t+.25)),Q.gain.setValueAtTime(0,t),Q.gain.linearRampToValueAtTime(g*.15,t+.05),Q.gain.exponentialRampToValueAtTime(.001,t+.35),I.connect(s).connect(C).connect(e.destination),r.connect(Q).connect(e.destination),I.start(t),I.stop(t+.5),r.start(t),r.stop(t+.4)}async playGentleNote(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=A?659.25:523.25,o=e.createOscillator(),a=e.createGain();o.type="sine",o.frequency.setValueAtTime(n,t),a.gain.setValueAtTime(0,t),a.gain.linearRampToValueAtTime(g*.3,t+.02),a.gain.linearRampToValueAtTime(g*.25,t+.1),a.gain.exponentialRampToValueAtTime(g*.08,t+.3),a.gain.exponentialRampToValueAtTime(.001,t+.5),o.connect(a).connect(e.destination),o.start(t),o.stop(t+.55);const I=e.createOscillator(),s=e.createGain();I.type="sine",I.frequency.setValueAtTime(n*2,t),s.gain.setValueAtTime(0,t),s.gain.linearRampToValueAtTime(g*.06,t+.02),s.gain.exponentialRampToValueAtTime(.001,t+.2),I.connect(s).connect(e.destination),I.start(t),I.stop(t+.25)}async playCallStartSound(){if(!(!this.config.enabled||this.config.preset==="none"))switch(this.config.preset){case"1":await this.playDrop(!0);break;case"2":await this.playGlassTap(!0);break;case"3":await this.playWhoosh(!0);break;case"4":await this.playGentleNote(!0);break}}async playCallEndSound(){if(!(!this.config.enabled||this.config.preset==="none"))switch(this.config.preset){case"1":await this.playDrop(!1);break;case"2":await this.playGlassTap(!1);break;case"3":await this.playWhoosh(!1);break;case"4":await this.playGentleNote(!1);break}}setConfig(A){this.config={...this.config,...A}}setEnabled(A){this.config.enabled=A}setVolume(A){this.config.volume=Math.max(0,Math.min(1,A))}setPreset(A){this.config.preset=A}getConfig(){return{...this.config}}isEnabled(){return this.config.enabled&&this.config.preset!=="none"}destroy(){this.hasAcquired&&(Oo.release(),this.hasAcquired=!1)}}const $i={default:{primary:"#6366f1",secondary:"#8b5cf6",accent:"#06b6d4",glow:"#818cf8",atmosphere:"#c4b5fd",depth:"#312e81",highlight:"#e0e7ff"},emerald:{primary:"#10b981",secondary:"#34d399",accent:"#6ee7b7",glow:"#34d399",atmosphere:"#a7f3d0",depth:"#064e3b",highlight:"#d1fae5"},rose:{primary:"#f43f5e",secondary:"#fb7185",accent:"#fda4af",glow:"#fb7185",atmosphere:"#fecdd3",depth:"#881337",highlight:"#ffe4e6"},amber:{primary:"#f59e0b",secondary:"#fbbf24",accent:"#fcd34d",glow:"#fbbf24",atmosphere:"#fde68a",depth:"#78350f",highlight:"#fef3c7"},cyan:{primary:"#06b6d4",secondary:"#22d3ee",accent:"#67e8f9",glow:"#22d3ee",atmosphere:"#a5f3fc",depth:"#164e63",highlight:"#cffafe"},purple:{primary:"#9333ea",secondary:"#a855f7",accent:"#c084fc",glow:"#a855f7",atmosphere:"#d8b4fe",depth:"#581c87",highlight:"#f3e8ff"},blue:{primary:"#2563eb",secondary:"#3b82f6",accent:"#60a5fa",glow:"#3b82f6",atmosphere:"#93c5fd",depth:"#1e3a8a",highlight:"#dbeafe"}},Ag={indigo:{primary:"#3730a3",secondary:"#4338ca",accent:"#4f46e5",glow:"#3730a3",atmosphere:"#4338ca",depth:"#1e1b4b",highlight:"#a5b4fc"},violet:{primary:"#5b21b6",secondary:"#6d28d9",accent:"#7c3aed",glow:"#5b21b6",atmosphere:"#6d28d9",depth:"#2e1065",highlight:"#c4b5fd"},teal:{primary:"#0f766e",secondary:"#0d9488",accent:"#14b8a6",glow:"#0f766e",atmosphere:"#0d9488",depth:"#042f2e",highlight:"#5eead4"},orange:{primary:"#c2410c",secondary:"#ea580c",accent:"#f97316",glow:"#c2410c",atmosphere:"#ea580c",depth:"#431407",highlight:"#fed7aa"},blue:{primary:"#1d4ed8",secondary:"#2563eb",accent:"#3b82f6",glow:"#1d4ed8",atmosphere:"#2563eb",depth:"#1e3a8a",highlight:"#93c5fd"},pink:{primary:"#be185d",secondary:"#db2777",accent:"#ec4899",glow:"#be185d",atmosphere:"#db2777",depth:"#500724",highlight:"#f9a8d4"}};function HG(i,A="dark"){const e=A==="dark"?$i:Ag;return e[i]||e[Object.keys(e)[0]]}function PG(i="dark"){return Object.keys(i==="dark"?$i:Ag)}const Vo={default:{dark:{colors:$i.default,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.indigo,glowIntensity:1.8,idleGlowMultiplier:1.2}},emerald:{dark:{colors:$i.emerald,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.teal,glowIntensity:1.8,idleGlowMultiplier:1.2}},rose:{dark:{colors:$i.rose,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.pink,glowIntensity:1.8,idleGlowMultiplier:1.2}},amber:{dark:{colors:$i.amber,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.orange,glowIntensity:1.8,idleGlowMultiplier:1.2}},cyan:{dark:{colors:$i.cyan,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.blue,glowIntensity:1.8,idleGlowMultiplier:1.2}},purple:{dark:{colors:$i.purple,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.violet,glowIntensity:1.8,idleGlowMultiplier:1.2}},blue:{dark:{colors:$i.blue,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.blue,glowIntensity:1.8,idleGlowMultiplier:1.2}}},OG=Object.fromEntries(Object.entries(Vo).map(([i,A])=>[i,A.dark])),VG=Object.fromEntries(Object.entries(Vo).map(([i,A])=>[i,A.light]));function Sf(){return typeof window>"u"||window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function jo(i,A="auto"){const e=Vo[i]||Vo.default,t=A==="auto"?Sf():A;return e[t]}function jG(){return Object.keys(Vo)}function Rf(i,A,e="auto"){const t=jo(A,e);i.orbColors=t.colors,i.glowIntensity=t.glowIntensity,i.idleGlowMultiplier=t.idleGlowMultiplier}function WG(i,A){if(typeof window>"u")return()=>{};const e=window.matchMedia("(prefers-color-scheme: dark)"),t=()=>{const g=e.matches?"dark":"light";Rf(i,A,g)};return t(),e.addEventListener("change",t),()=>{e.removeEventListener("change",t)}}const bf="privacy_accepted",LE="user_identity";function rC(){try{return localStorage.getItem(bf)==="true"}catch{return!1}}function QC(){try{localStorage.setItem(bf,"true")}catch{}}function BC(){try{let i=localStorage.getItem(LE);return i||(i=crypto.randomUUID(),localStorage.setItem(LE,i)),i}catch{return crypto.randomUUID()}}function EC(){try{return localStorage.getItem(LE)}catch{return null}}function ZG(){if(typeof window>"u")return"https://api.hanc.ai";const i=window.location.hostname;return i.endsWith(".hanc.me")||i==="hanc.me"||i==="localhost"?"https://api.hanc.me":"https://api.hanc.ai"}const II=ZG(),UE={terms_enabled:!1,terms_content:"",terms_url:"https://hanc.ai/terms",privacy_url:"https://hanc.ai/privacy",theme:"default",allow_all_domains:!0,allowed_domains:[]},cC=new Map,XG=1*60*1e3;async function sI(i,A=II){if(!i)return console.warn("[hanc-widget] No agentId provided, using default config"),UE;const e=cC.get(i);if(e&&Date.now()-e.timestamp<XG)return e.config;try{const t=await fetch(`${A}/v1/site/widget-config/${i}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok){if(t.status===404)return console.warn(`[hanc-widget] Agent ${i} not found, using default config`),UE;throw new Error(`HTTP ${t.status}: ${t.statusText}`)}const g=await t.json();return cC.set(i,{config:g,timestamp:Date.now()}),g}catch(t){return console.error("[hanc-widget] Failed to fetch widget config:",t),UE}}const zG=["hanc.ai","hanc.me","localhost"];function CI(i){const A=window.location.hostname;return zG.some(t=>A===t||A.endsWith(`.${t}`))||i.allow_all_domains||!i.allowed_domains||i.allowed_domains.length===0?!0:i.allowed_domains.some(t=>A===t||A.endsWith(`.${t}`))}function $G(i){i?cC.delete(i):cC.clear()}var AF=Object.defineProperty,eF=Object.getOwnPropertyDescriptor,rI=(i,A,e,t)=>{for(var g=t>1?void 0:t?eF(A,e):A,n=i.length-1,o;n>=0;n--)(o=i[n])&&(g=(t?o(A,e,g):o(g))||g);return t&&g&&AF(A,e,g),g};let Jn=class extends tg{constructor(){super(...arguments),this.privacyUrl="https://hanc.ai/privacy",this.termsUrl="https://hanc.ai/terms",this.termsContent="",this.modalTitle="Before we start",this.modalContainer=null}connectedCallback(){super.connectedCallback(),this.createModal()}disconnectedCallback(){super.disconnectedCallback(),this.removeModal()}createModal(){this.modalContainer=document.createElement("div"),this.modalContainer.innerHTML=this.getModalHTML(),document.body.appendChild(this.modalContainer);const i=this.modalContainer.querySelector(".hanc-privacy-overlay"),A=this.modalContainer.querySelector(".hanc-btn-accept"),e=this.modalContainer.querySelector(".hanc-btn-decline");i==null||i.addEventListener("click",t=>{t.target===i&&this.handleDecline()}),A==null||A.addEventListener("click",()=>this.handleAccept()),e==null||e.addEventListener("click",()=>this.handleDecline())}removeModal(){this.modalContainer&&(this.modalContainer.remove(),this.modalContainer=null)}renderMarkdown(i){if(!i)return"";let e=(t=>t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"))(i);return e=e.replace(/^#### (.+)$/gm,"<h4>$1</h4>"),e=e.replace(/^### (.+)$/gm,"<h3>$1</h3>"),e=e.replace(/^## (.+)$/gm,"<h2>$1</h2>"),e=e.replace(/^# (.+)$/gm,"<h1>$1</h1>"),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/__(.+?)__/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/_(.+?)_/g,"<em>$1</em>"),e=e.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),e=e.replace(/^\- (.+)$/gm,"<li>$1</li>"),e=e.replace(/(<li>.*<\/li>\n?)+/g,"<ul>$&</ul>"),e=e.replace(/\n\n/g,"</p><p>"),e="<p>"+e+"</p>",e=e.replace(/<p><\/p>/g,""),e=e.replace(/<p>(<h[1-4]>)/g,"$1"),e=e.replace(/(<\/h[1-4]>)<\/p>/g,"$1"),e=e.replace(/<p>(<ul>)/g,"$1"),e=e.replace(/(<\/ul>)<\/p>/g,"$1"),e=e.replace(/\n/g,"<br>"),e}getModalHTML(){const i=this.termsContent&&this.termsContent.trim().length>0,A=i?this.renderMarkdown(this.termsContent):"By starting this call, you agree to our Terms of Service and Privacy Policy.";return`
|
|
4571
|
+
`,Kn={primary:"#6366f1",secondary:"#8b5cf6",accent:"#06b6d4",glow:"#818cf8",atmosphere:"#c4b5fd",depth:"#312e81",highlight:"#e0e7ff"},qG={size:1,segments:128,colors:Kn,morphStrength:1,noiseScale:1.5,noiseSpeed:.3,glowIntensity:.8,idleGlowMultiplier:.4,fresnelPower:2.5,rotationSpeed:.1,audioReactivity:3,audioSmoothing:.9,idleMorphMultiplier:.25,colorContrast:1.5};class sC{constructor(A,e={}){this.orb=null,this.glowMesh=null,this.orbMaterial=null,this.glowMaterial=null,this.animationId=null,this.isActive=!1,this.targetRotation={x:0,y:0},this.currentRotation={x:0,y:0},this.audioValues={bass:0,mid:0,treble:0,level:0},this.resizeObserver=null,this.resizeTimeoutId=null,this.isContextLost=!1,this.animate=()=>{if(this.isContextLost)return;this.animationId=requestAnimationFrame(this.animate);const r=this.clock.getElapsedTime();if(this.clock.getDelta(),this.orbMaterial){this.orbMaterial.uniforms.uTime.value=r,this.orbMaterial.uniforms.uAudioBass.value=this.audioValues.bass,this.orbMaterial.uniforms.uAudioMid.value=this.audioValues.mid,this.orbMaterial.uniforms.uAudioTreble.value=this.audioValues.treble,this.orbMaterial.uniforms.uAudioLevel.value=this.audioValues.level;const Q=this.isActive?this.config.morphStrength*1.5:this.config.morphStrength*this.config.idleMorphMultiplier,B=this.orbMaterial.uniforms.uMorphStrength.value;this.orbMaterial.uniforms.uMorphStrength.value+=(Q-B)*.05}if(this.glowMaterial){this.glowMaterial.uniforms.uTime.value=r,this.glowMaterial.uniforms.uAudioLevel.value=this.audioValues.level;const Q=this.isActive?this.config.glowIntensity*1.5:this.config.glowIntensity*this.config.idleGlowMultiplier,B=this.glowMaterial.uniforms.uGlowIntensity.value;this.glowMaterial.uniforms.uGlowIntensity.value+=(Q-B)*.05}this.currentRotation.x+=(this.targetRotation.x-this.currentRotation.x)*.05,this.currentRotation.y+=(this.targetRotation.y-this.currentRotation.y)*.05,this.orb&&(this.orb.rotation.x=this.currentRotation.x+r*this.config.rotationSpeed*.3,this.orb.rotation.y=this.currentRotation.y+r*this.config.rotationSpeed),this.glowMesh&&(this.glowMesh.rotation.x=this.currentRotation.x+r*this.config.rotationSpeed*.3,this.glowMesh.rotation.y=this.currentRotation.y+r*this.config.rotationSpeed),this.renderer.render(this.scene,this.camera)},this.handleResize=()=>{this.resizeTimeoutId!==null&&clearTimeout(this.resizeTimeoutId),this.resizeTimeoutId=setTimeout(()=>{this.resizeTimeoutId=null;const r=this.container.clientWidth,Q=this.container.clientHeight;if(r===0||Q===0)return;const B=r*this.canvasPadding,d=Q*this.canvasPadding;this.camera.aspect=B/d,this.camera.updateProjectionMatrix(),this.renderer.setSize(B,d)},100)},this.handleMouseMove=r=>{const Q=this.container.getBoundingClientRect(),B=(r.clientX-Q.left)/Q.width*2-1,d=-((r.clientY-Q.top)/Q.height)*2+1;this.targetRotation.x=d*.3,this.targetRotation.y=B*.3},this.handleMouseLeave=()=>{this.targetRotation.x=0,this.targetRotation.y=0},this.container=A,this.config={...qG,...e},this.clock=new DR;const t=/iPhone|iPad|iPod/i.test(navigator.userAgent),g=/Android/i.test(navigator.userAgent);this.canvasPadding=t?1.5:g?2:3,this.boundHandleContextLost=this.handleContextLost.bind(this),this.boundHandleContextRestored=this.handleContextRestored.bind(this),this.scene=new QR;const n=A.clientWidth*this.canvasPadding,o=A.clientHeight*this.canvasPadding,a=n/o;this.camera=new Ii(45,a,.1,100);const I=3,s=9;this.camera.position.z=s*(this.canvasPadding/I),this.renderer=new UG({antialias:!0,alpha:!0,powerPreference:"high-performance"}),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.renderer.setSize(n,o),this.renderer.setClearColor(0,0);const C=this.renderer.domElement;C.style.position="absolute",C.style.left="50%",C.style.top="50%",C.style.transform="translate(-50%, -50%)",C.style.pointerEvents="none",A.appendChild(C),C.addEventListener("webglcontextlost",this.boundHandleContextLost),C.addEventListener("webglcontextrestored",this.boundHandleContextRestored),this.createOrb(),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(this.handleResize),this.resizeObserver.observe(A),A.addEventListener("mousemove",this.handleMouseMove),A.addEventListener("mouseleave",this.handleMouseLeave)}handleContextLost(A){A.preventDefault(),this.isContextLost=!0,this.stop()}handleContextRestored(A){this.isContextLost=!1,this.recreateAfterContextLoss(),this.start()}recreateAfterContextLoss(){this.orb&&(this.orb.geometry.dispose(),this.scene.remove(this.orb),this.orb=null),this.glowMesh&&(this.glowMesh.geometry.dispose(),this.scene.remove(this.glowMesh),this.glowMesh=null),this.orbMaterial&&(this.orbMaterial.dispose(),this.orbMaterial=null),this.glowMaterial&&(this.glowMaterial.dispose(),this.glowMaterial=null),this.createOrb()}createOrb(){const A={...Kn,...this.config.colors},e=new kE(this.config.size,this.config.segments/4);this.orbMaterial=new ai({vertexShader:TG,fragmentShader:KG,uniforms:{uTime:{value:0},uAudioBass:{value:0},uAudioMid:{value:0},uAudioTreble:{value:0},uAudioLevel:{value:0},uMorphStrength:{value:this.config.morphStrength},uNoiseScale:{value:this.config.noiseScale},uNoiseSpeed:{value:this.config.noiseSpeed},uAudioReactivity:{value:this.config.audioReactivity},uColorPrimary:{value:new re(A.primary)},uColorSecondary:{value:new re(A.secondary)},uColorAccent:{value:new re(A.accent)},uColorDepth:{value:new re(A.depth||Kn.depth)},uColorHighlight:{value:new re(A.highlight||Kn.highlight)},uFresnelPower:{value:this.config.fresnelPower},uGlowIntensity:{value:this.config.glowIntensity},uColorContrast:{value:this.config.colorContrast}},transparent:!0,side:lg}),this.orb=new Ni(e,this.orbMaterial),this.scene.add(this.orb);const t=new yE(this.config.size,64,64);this.glowMaterial=new ai({vertexShader:JG,fragmentShader:YG,uniforms:{uTime:{value:0},uAudioLevel:{value:0},uGlowColor:{value:new re(A.glow)},uGlowIntensity:{value:this.config.glowIntensity*.6},uPulseSpeed:{value:2}},transparent:!0,side:St,blending:zQ,depthWrite:!1}),this.glowMesh=new Ni(t,this.glowMaterial),this.scene.add(this.glowMesh)}updateAudio(A){const e=this.config.audioSmoothing;this.audioValues.bass+=(A.bass-this.audioValues.bass)*e,this.audioValues.mid+=(A.mid-this.audioValues.mid)*e,this.audioValues.treble+=(A.treble-this.audioValues.treble)*e,this.audioValues.level+=(A.level-this.audioValues.level)*e}setSimulatedAudio(A,e,t,g){const n=this.config.audioSmoothing;this.audioValues.bass+=(A-this.audioValues.bass)*n,this.audioValues.mid+=(e-this.audioValues.mid)*n,this.audioValues.treble+=(t-this.audioValues.treble)*n,this.audioValues.level+=(g-this.audioValues.level)*n}setActive(A){this.isActive=A}setColors(A){const e={...Kn,...this.config.colors,...A};this.orbMaterial&&(this.orbMaterial.uniforms.uColorPrimary.value.set(e.primary),this.orbMaterial.uniforms.uColorSecondary.value.set(e.secondary),this.orbMaterial.uniforms.uColorAccent.value.set(e.accent),this.orbMaterial.uniforms.uColorDepth.value.set(e.depth||Kn.depth),this.orbMaterial.uniforms.uColorHighlight.value.set(e.highlight||Kn.highlight)),this.glowMaterial&&this.glowMaterial.uniforms.uGlowColor.value.set(e.glow)}setGlowSettings(A,e){this.config.glowIntensity=A,this.config.idleGlowMultiplier=e}start(){this.animationId===null&&(this.clock.start(),this.animate())}stop(){this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null)}getCanvas(){return this.renderer.domElement}destroy(){this.stop(),this.resizeTimeoutId!==null&&(clearTimeout(this.resizeTimeoutId),this.resizeTimeoutId=null),window.removeEventListener("resize",this.handleResize),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.container.removeEventListener("mousemove",this.handleMouseMove),this.container.removeEventListener("mouseleave",this.handleMouseLeave);const A=this.renderer.domElement;A.removeEventListener("webglcontextlost",this.boundHandleContextLost),A.removeEventListener("webglcontextrestored",this.boundHandleContextRestored),this.orb&&(this.orb.geometry.dispose(),this.scene.remove(this.orb),this.orb=null),this.glowMesh&&(this.glowMesh.geometry.dispose(),this.scene.remove(this.glowMesh),this.glowMesh=null),this.orbMaterial&&(this.orbMaterial.dispose(),this.orbMaterial=null),this.glowMaterial&&(this.glowMaterial.dispose(),this.glowMaterial=null),this.renderer.dispose(),A.parentNode&&A.parentNode.removeChild(A)}}class Po{constructor(){this.audioContext=null,this.refCount=0,this.resumePromise=null}static getInstance(){return Po.instance||(Po.instance=new Po),Po.instance}async acquire(){if(this.refCount++,!this.audioContext)try{const A=window.AudioContext||window.webkitAudioContext;if(!A)return console.warn("[SharedAudioContext] Web Audio API not supported"),null;this.audioContext=new A,console.log("[SharedAudioContext] Created shared AudioContext")}catch(A){return console.warn("[SharedAudioContext] Failed to create AudioContext:",A),null}return await this.ensureResumed(),this.audioContext}release(){this.refCount=Math.max(0,this.refCount-1),this.refCount===0&&console.log("[SharedAudioContext] All references released, context kept alive for reuse")}forceClose(){if(this.audioContext){try{this.audioContext.close()}catch{}this.audioContext=null,this.refCount=0,console.log("[SharedAudioContext] Force closed")}}getContext(){return this.audioContext}async ensureResumed(){if(!this.audioContext)return!1;if(this.audioContext.state==="suspended"){this.resumePromise||(this.resumePromise=this.audioContext.resume().finally(()=>{this.resumePromise=null}));try{await this.resumePromise}catch{return!1}}return this.audioContext.state==="running"}isRunning(){return this.audioContext!==null&&this.audioContext.state==="running"}getState(){var A;return((A=this.audioContext)==null?void 0:A.state)??null}getSampleRate(){var A;return((A=this.audioContext)==null?void 0:A.sampleRate)??44100}getCurrentTime(){var A;return((A=this.audioContext)==null?void 0:A.currentTime)??0}getDestination(){var A;return((A=this.audioContext)==null?void 0:A.destination)??null}}const Oo=Po.getInstance();typeof window<"u"&&window.addEventListener("pagehide",()=>{Oo.forceClose()});class CC{constructor(A={}){this.audioContext=null,this.analyser=null,this.source=null,this.localSource=null,this.mixer=null,this.frequencyData=new Uint8Array(0),this.waveformData=new Float32Array(0),this.hasAcquiredContext=!1,this.smoothedBass=0,this.smoothedMid=0,this.smoothedTreble=0,this.smoothedLevel=0,this.smoothingFactor=.3,this.options={fftSize:A.fftSize??2048,smoothingTimeConstant:A.smoothingTimeConstant??.8,minDecibels:A.minDecibels??-90,maxDecibels:A.maxDecibels??-10}}async ensureAudioContext(){if(!this.audioContext)this.audioContext=await Oo.acquire(),this.audioContext&&(this.hasAcquiredContext=!0);else if(!await Oo.ensureResumed())return null;return this.audioContext}async connectStream(A){const e=await this.ensureAudioContext();if(!e){console.warn("[AudioAnalyzer] Could not acquire AudioContext");return}if(this.source)try{this.source.disconnect()}catch{}this.source=e.createMediaStreamSource(A),this.setupMixerAndAnalyser(),this.mixer&&this.source.connect(this.mixer)}async connectLocalStream(A){const e=await this.ensureAudioContext();if(!e){console.warn("[AudioAnalyzer] Could not acquire AudioContext");return}if(this.localSource)try{this.localSource.disconnect()}catch{}this.localSource=e.createMediaStreamSource(A),this.setupMixerAndAnalyser(),this.mixer&&this.localSource.connect(this.mixer)}setupMixerAndAnalyser(){this.audioContext&&(this.mixer||(this.mixer=this.audioContext.createGain(),this.mixer.gain.value=1),this.analyser||(this.analyser=this.audioContext.createAnalyser()),this.analyser.fftSize=this.options.fftSize,this.analyser.smoothingTimeConstant=this.options.smoothingTimeConstant,this.analyser.minDecibels=this.options.minDecibels,this.analyser.maxDecibels=this.options.maxDecibels,this.mixer.disconnect(),this.mixer.connect(this.analyser),this.frequencyData=new Uint8Array(this.analyser.frequencyBinCount),this.waveformData=new Float32Array(this.analyser.fftSize))}async connectAudioElement(A){const e=await this.ensureAudioContext();if(!e){console.warn("[AudioAnalyzer] Could not acquire AudioContext");return}if(this.source)try{this.source.disconnect()}catch{}const t=e.createMediaElementSource(A);this.analyser||(this.analyser=e.createAnalyser()),this.analyser.fftSize=this.options.fftSize,this.analyser.smoothingTimeConstant=this.options.smoothingTimeConstant,this.analyser.minDecibels=this.options.minDecibels,this.analyser.maxDecibels=this.options.maxDecibels,t.connect(this.analyser),this.analyser.connect(e.destination),this.frequencyData=new Uint8Array(this.analyser.frequencyBinCount),this.waveformData=new Float32Array(this.analyser.fftSize)}getAudioData(){if(!this.analyser)return{bass:0,mid:0,treble:0,level:0,waveform:new Float32Array(0),frequency:new Uint8Array(0)};this.analyser.getByteFrequencyData(this.frequencyData),this.analyser.getFloatTimeDomainData(this.waveformData);const{bass:A,mid:e,treble:t}=this.calculateFrequencyBands(),g=this.calculateOverallLevel();return this.smoothedBass+=(A-this.smoothedBass)*this.smoothingFactor,this.smoothedMid+=(e-this.smoothedMid)*this.smoothingFactor,this.smoothedTreble+=(t-this.smoothedTreble)*this.smoothingFactor,this.smoothedLevel+=(g-this.smoothedLevel)*this.smoothingFactor,{bass:this.smoothedBass,mid:this.smoothedMid,treble:this.smoothedTreble,level:this.smoothedLevel,waveform:this.waveformData,frequency:this.frequencyData}}calculateFrequencyBands(){if(!this.audioContext||this.frequencyData.length===0)return{bass:0,mid:0,treble:0};const A=this.audioContext.sampleRate,e=this.frequencyData.length,t=A/(e*2),g=Math.floor(250/t),n=Math.floor(2e3/t);let o=0,a=0,I=0;for(let Q=0;Q<e;Q++){const B=this.frequencyData[Q]/255;Q<g?o+=B:Q<n?a+=B:I+=B}const s=g>0?o/g:0,C=n-g>0?a/(n-g):0,r=e-n>0?I/(e-n):0;return{bass:Math.pow(s,.8),mid:Math.pow(C,.9),treble:Math.pow(r,1.1)}}calculateOverallLevel(){if(this.frequencyData.length===0)return 0;let A=0;for(let t=0;t<this.frequencyData.length;t++)A+=this.frequencyData[t];const e=A/this.frequencyData.length/255;return Math.pow(e,.8)}getPeakLevel(){if(this.frequencyData.length===0)return 0;let A=0;for(let e=0;e<this.frequencyData.length;e++)this.frequencyData[e]>A&&(A=this.frequencyData[e]);return A/255}isActive(){return this.audioContext!==null&&this.audioContext.state==="running"}disconnect(){if(this.source){try{this.source.disconnect()}catch{}this.source=null}if(this.localSource){try{this.localSource.disconnect()}catch{}this.localSource=null}if(this.mixer){try{this.mixer.disconnect()}catch{}this.mixer=null}if(this.analyser){try{this.analyser.disconnect()}catch{}this.analyser=null}this.hasAcquiredContext&&(Oo.release(),this.hasAcquiredContext=!1),this.audioContext=null,this.smoothedBass=0,this.smoothedMid=0,this.smoothedTreble=0,this.smoothedLevel=0}getAudioContext(){return this.audioContext}getAnalyser(){return this.analyser}}class aI{constructor(A={}){this.hasAcquired=!1,this.config={enabled:!0,volume:.3,preset:"1",...A}}async ensureContext(){if(!this.config.enabled||this.config.preset==="none")return null;const A=await Oo.acquire();return A&&(this.hasAcquired=!0),A}async prewarm(){await this.ensureContext()}async playDrop(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=A?900:700,o=A?500:400,a=e.createOscillator(),I=e.createGain();a.type="sine",a.frequency.setValueAtTime(n,t),a.frequency.exponentialRampToValueAtTime(o,t+.15),I.gain.setValueAtTime(0,t),I.gain.linearRampToValueAtTime(g*.3,t+.015),I.gain.linearRampToValueAtTime(g*.2,t+.1),I.gain.exponentialRampToValueAtTime(.001,t+.35),a.connect(I).connect(e.destination),a.start(t),a.stop(t+.4)}async playGlassTap(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=A?2200:1760,o=e.createOscillator(),a=e.createGain();o.type="sine",o.frequency.setValueAtTime(n,t),a.gain.setValueAtTime(0,t),a.gain.linearRampToValueAtTime(g*.25,t+.002),a.gain.exponentialRampToValueAtTime(g*.1,t+.08),a.gain.exponentialRampToValueAtTime(.001,t+.3),o.connect(a).connect(e.destination),o.start(t),o.stop(t+.35);const I=e.createOscillator(),s=e.createGain();I.type="sine",I.frequency.setValueAtTime(n*2.5,t),s.gain.setValueAtTime(0,t),s.gain.linearRampToValueAtTime(g*.08,t+.001),s.gain.exponentialRampToValueAtTime(.001,t+.12),I.connect(s).connect(e.destination),I.start(t),I.stop(t+.15)}async playWhoosh(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=e.sampleRate*.5,o=e.createBuffer(1,n,e.sampleRate),a=o.getChannelData(0);for(let B=0;B<n;B++)a[B]=Math.random()*2-1;const I=e.createBufferSource();I.buffer=o;const s=e.createBiquadFilter();s.type="bandpass",s.Q.setValueAtTime(2,t);const C=e.createGain();A?(s.frequency.setValueAtTime(300,t),s.frequency.exponentialRampToValueAtTime(2e3,t+.15),s.frequency.exponentialRampToValueAtTime(800,t+.35),C.gain.setValueAtTime(0,t),C.gain.linearRampToValueAtTime(g*.3,t+.05),C.gain.linearRampToValueAtTime(g*.4,t+.15),C.gain.exponentialRampToValueAtTime(.001,t+.4)):(s.frequency.setValueAtTime(1500,t),s.frequency.exponentialRampToValueAtTime(200,t+.3),C.gain.setValueAtTime(0,t),C.gain.linearRampToValueAtTime(g*.35,t+.05),C.gain.exponentialRampToValueAtTime(.001,t+.35));const r=e.createOscillator(),Q=e.createGain();r.type="sine",A?(r.frequency.setValueAtTime(300,t),r.frequency.linearRampToValueAtTime(500,t+.2)):(r.frequency.setValueAtTime(400,t),r.frequency.linearRampToValueAtTime(200,t+.25)),Q.gain.setValueAtTime(0,t),Q.gain.linearRampToValueAtTime(g*.15,t+.05),Q.gain.exponentialRampToValueAtTime(.001,t+.35),I.connect(s).connect(C).connect(e.destination),r.connect(Q).connect(e.destination),I.start(t),I.stop(t+.5),r.start(t),r.stop(t+.4)}async playGentleNote(A){const e=await this.ensureContext();if(!e)return;const t=e.currentTime,g=this.config.volume,n=A?659.25:523.25,o=e.createOscillator(),a=e.createGain();o.type="sine",o.frequency.setValueAtTime(n,t),a.gain.setValueAtTime(0,t),a.gain.linearRampToValueAtTime(g*.3,t+.02),a.gain.linearRampToValueAtTime(g*.25,t+.1),a.gain.exponentialRampToValueAtTime(g*.08,t+.3),a.gain.exponentialRampToValueAtTime(.001,t+.5),o.connect(a).connect(e.destination),o.start(t),o.stop(t+.55);const I=e.createOscillator(),s=e.createGain();I.type="sine",I.frequency.setValueAtTime(n*2,t),s.gain.setValueAtTime(0,t),s.gain.linearRampToValueAtTime(g*.06,t+.02),s.gain.exponentialRampToValueAtTime(.001,t+.2),I.connect(s).connect(e.destination),I.start(t),I.stop(t+.25)}async playCallStartSound(){if(!(!this.config.enabled||this.config.preset==="none"))switch(this.config.preset){case"1":await this.playDrop(!0);break;case"2":await this.playGlassTap(!0);break;case"3":await this.playWhoosh(!0);break;case"4":await this.playGentleNote(!0);break}}async playCallEndSound(){if(!(!this.config.enabled||this.config.preset==="none"))switch(this.config.preset){case"1":await this.playDrop(!1);break;case"2":await this.playGlassTap(!1);break;case"3":await this.playWhoosh(!1);break;case"4":await this.playGentleNote(!1);break}}setConfig(A){this.config={...this.config,...A}}setEnabled(A){this.config.enabled=A}setVolume(A){this.config.volume=Math.max(0,Math.min(1,A))}setPreset(A){this.config.preset=A}getConfig(){return{...this.config}}isEnabled(){return this.config.enabled&&this.config.preset!=="none"}destroy(){this.hasAcquired&&(Oo.release(),this.hasAcquired=!1)}}const $i={default:{primary:"#6366f1",secondary:"#8b5cf6",accent:"#06b6d4",glow:"#818cf8",atmosphere:"#c4b5fd",depth:"#312e81",highlight:"#e0e7ff"},emerald:{primary:"#10b981",secondary:"#34d399",accent:"#6ee7b7",glow:"#34d399",atmosphere:"#a7f3d0",depth:"#064e3b",highlight:"#d1fae5"},rose:{primary:"#f43f5e",secondary:"#fb7185",accent:"#fda4af",glow:"#fb7185",atmosphere:"#fecdd3",depth:"#881337",highlight:"#ffe4e6"},amber:{primary:"#f59e0b",secondary:"#fbbf24",accent:"#fcd34d",glow:"#fbbf24",atmosphere:"#fde68a",depth:"#78350f",highlight:"#fef3c7"},cyan:{primary:"#06b6d4",secondary:"#22d3ee",accent:"#67e8f9",glow:"#22d3ee",atmosphere:"#a5f3fc",depth:"#164e63",highlight:"#cffafe"},purple:{primary:"#9333ea",secondary:"#a855f7",accent:"#c084fc",glow:"#a855f7",atmosphere:"#d8b4fe",depth:"#581c87",highlight:"#f3e8ff"},blue:{primary:"#2563eb",secondary:"#3b82f6",accent:"#60a5fa",glow:"#3b82f6",atmosphere:"#93c5fd",depth:"#1e3a8a",highlight:"#dbeafe"}},Ag={indigo:{primary:"#3730a3",secondary:"#4338ca",accent:"#4f46e5",glow:"#3730a3",atmosphere:"#4338ca",depth:"#1e1b4b",highlight:"#a5b4fc"},violet:{primary:"#5b21b6",secondary:"#6d28d9",accent:"#7c3aed",glow:"#5b21b6",atmosphere:"#6d28d9",depth:"#2e1065",highlight:"#c4b5fd"},teal:{primary:"#0f766e",secondary:"#0d9488",accent:"#14b8a6",glow:"#0f766e",atmosphere:"#0d9488",depth:"#042f2e",highlight:"#5eead4"},orange:{primary:"#c2410c",secondary:"#ea580c",accent:"#f97316",glow:"#c2410c",atmosphere:"#ea580c",depth:"#431407",highlight:"#fed7aa"},blue:{primary:"#1d4ed8",secondary:"#2563eb",accent:"#3b82f6",glow:"#1d4ed8",atmosphere:"#2563eb",depth:"#1e3a8a",highlight:"#93c5fd"},pink:{primary:"#be185d",secondary:"#db2777",accent:"#ec4899",glow:"#be185d",atmosphere:"#db2777",depth:"#500724",highlight:"#f9a8d4"}};function HG(i,A="dark"){const e=A==="dark"?$i:Ag;return e[i]||e[Object.keys(e)[0]]}function PG(i="dark"){return Object.keys(i==="dark"?$i:Ag)}const Vo={default:{dark:{colors:$i.default,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.indigo,glowIntensity:1.8,idleGlowMultiplier:1.2}},emerald:{dark:{colors:$i.emerald,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.teal,glowIntensity:1.8,idleGlowMultiplier:1.2}},rose:{dark:{colors:$i.rose,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.pink,glowIntensity:1.8,idleGlowMultiplier:1.2}},amber:{dark:{colors:$i.amber,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.orange,glowIntensity:1.8,idleGlowMultiplier:1.2}},cyan:{dark:{colors:$i.cyan,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.blue,glowIntensity:1.8,idleGlowMultiplier:1.2}},purple:{dark:{colors:$i.purple,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.violet,glowIntensity:1.8,idleGlowMultiplier:1.2}},blue:{dark:{colors:$i.blue,glowIntensity:1.2,idleGlowMultiplier:.6},light:{colors:Ag.blue,glowIntensity:1.8,idleGlowMultiplier:1.2}}},OG=Object.fromEntries(Object.entries(Vo).map(([i,A])=>[i,A.dark])),VG=Object.fromEntries(Object.entries(Vo).map(([i,A])=>[i,A.light]));function Sf(){return typeof window>"u"||window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function jo(i,A="auto"){const e=Vo[i]||Vo.default,t=A==="auto"?Sf():A;return e[t]}function jG(){return Object.keys(Vo)}function Rf(i,A,e="auto"){const t=jo(A,e);i.orbColors=t.colors,i.glowIntensity=t.glowIntensity,i.idleGlowMultiplier=t.idleGlowMultiplier}function WG(i,A){if(typeof window>"u")return()=>{};const e=window.matchMedia("(prefers-color-scheme: dark)"),t=()=>{const g=e.matches?"dark":"light";Rf(i,A,g)};return t(),e.addEventListener("change",t),()=>{e.removeEventListener("change",t)}}const bf="privacy_accepted",LE="user_identity";function rC(){try{return localStorage.getItem(bf)==="true"}catch{return!1}}function QC(){try{localStorage.setItem(bf,"true")}catch{}}function BC(){try{let i=localStorage.getItem(LE);return i||(i=crypto.randomUUID(),localStorage.setItem(LE,i)),i}catch{return crypto.randomUUID()}}function EC(){try{return localStorage.getItem(LE)}catch{return null}}function ZG(){if(typeof window>"u")return"https://api.hanc.ai";const i=window.location.hostname;return i.endsWith(".hanc.me")||i==="hanc.me"||i==="localhost"?"https://api.hanc.me":"https://api.hanc.ai"}const II=ZG(),UE={terms_enabled:!1,terms_content:"",terms_url:"https://hanc.ai/terms",privacy_url:"https://hanc.ai/privacy",theme:"default",allow_all_domains:!0,allowed_domains:[]},cC=new Map,XG=1e3;async function sI(i,A=II){if(!i)return console.warn("[hanc-widget] No agentId provided, using default config"),UE;const e=cC.get(i);if(e&&Date.now()-e.timestamp<XG)return e.config;try{const t=await fetch(`${A}/v1/site/widget-config/${i}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok){if(t.status===404)return console.warn(`[hanc-widget] Agent ${i} not found, using default config`),UE;throw new Error(`HTTP ${t.status}: ${t.statusText}`)}const g=await t.json();return cC.set(i,{config:g,timestamp:Date.now()}),g}catch(t){return console.error("[hanc-widget] Failed to fetch widget config:",t),UE}}const zG=["hanc.ai","hanc.me","localhost"];function CI(i){const A=window.location.hostname;return zG.some(t=>A===t||A.endsWith(`.${t}`))||i.allow_all_domains||!i.allowed_domains||i.allowed_domains.length===0?!0:i.allowed_domains.some(t=>A===t||A.endsWith(`.${t}`))}function $G(i){i?cC.delete(i):cC.clear()}var AF=Object.defineProperty,eF=Object.getOwnPropertyDescriptor,rI=(i,A,e,t)=>{for(var g=t>1?void 0:t?eF(A,e):A,n=i.length-1,o;n>=0;n--)(o=i[n])&&(g=(t?o(A,e,g):o(g))||g);return t&&g&&AF(A,e,g),g};let Jn=class extends tg{constructor(){super(...arguments),this.privacyUrl="https://hanc.ai/privacy",this.termsUrl="https://hanc.ai/terms",this.termsContent="",this.modalTitle="Before we start",this.modalContainer=null}connectedCallback(){super.connectedCallback(),this.createModal()}disconnectedCallback(){super.disconnectedCallback(),this.removeModal()}createModal(){this.modalContainer=document.createElement("div"),this.modalContainer.innerHTML=this.getModalHTML(),document.body.appendChild(this.modalContainer);const i=this.modalContainer.querySelector(".hanc-privacy-overlay"),A=this.modalContainer.querySelector(".hanc-btn-accept"),e=this.modalContainer.querySelector(".hanc-btn-decline");i==null||i.addEventListener("click",t=>{t.target===i&&this.handleDecline()}),A==null||A.addEventListener("click",()=>this.handleAccept()),e==null||e.addEventListener("click",()=>this.handleDecline())}removeModal(){this.modalContainer&&(this.modalContainer.remove(),this.modalContainer=null)}renderMarkdown(i){if(!i)return"";let e=(t=>t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"))(i);return e=e.replace(/^#### (.+)$/gm,"<h4>$1</h4>"),e=e.replace(/^### (.+)$/gm,"<h3>$1</h3>"),e=e.replace(/^## (.+)$/gm,"<h2>$1</h2>"),e=e.replace(/^# (.+)$/gm,"<h1>$1</h1>"),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/__(.+?)__/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/_(.+?)_/g,"<em>$1</em>"),e=e.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),e=e.replace(/^\- (.+)$/gm,"<li>$1</li>"),e=e.replace(/(<li>.*<\/li>\n?)+/g,"<ul>$&</ul>"),e=e.replace(/\n\n/g,"</p><p>"),e="<p>"+e+"</p>",e=e.replace(/<p><\/p>/g,""),e=e.replace(/<p>(<h[1-4]>)/g,"$1"),e=e.replace(/(<\/h[1-4]>)<\/p>/g,"$1"),e=e.replace(/<p>(<ul>)/g,"$1"),e=e.replace(/(<\/ul>)<\/p>/g,"$1"),e=e.replace(/\n/g,"<br>"),e}getModalHTML(){const i=this.termsContent&&this.termsContent.trim().length>0,A=i?this.renderMarkdown(this.termsContent):"By starting this call, you agree to our Terms of Service and Privacy Policy.";return`
|
|
4572
4572
|
<style>
|
|
4573
4573
|
.hanc-privacy-overlay {
|
|
4574
4574
|
position: fixed;
|