@mihe-dev/js 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands.d.ts +4 -3
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +9 -6
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mihe.d.ts +60 -1
- package/dist/mihe.d.ts.map +1 -1
- package/dist/mihe.iife.min.js +25 -10
- package/dist/mihe.iife.min.js.map +3 -3
- package/dist/mihe.js +83 -4
- package/dist/mihe.js.map +1 -1
- package/dist/mihe.min.js +25 -10
- package/dist/mihe.min.js.map +3 -3
- package/dist/widget/panel.d.ts +6 -0
- package/dist/widget/panel.d.ts.map +1 -1
- package/dist/widget/panel.js +52 -5
- package/dist/widget/panel.js.map +1 -1
- package/dist/widget/styles.d.ts +1 -1
- package/dist/widget/styles.d.ts.map +1 -1
- package/dist/widget/styles.js +13 -0
- package/dist/widget/styles.js.map +1 -1
- package/package.json +1 -1
package/dist/mihe.iife.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @mihe-dev/js 0.2.
|
|
2
|
-
"use strict";var Mihe=(()=>{var q=Object.defineProperty;var Je=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Ze=Object.prototype.hasOwnProperty;var et=(n,e,t)=>e in n?q(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var tt=(n,e)=>{for(var t in e)q(n,t,{get:e[t],enumerable:!0})},it=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Xe(e))!Ze.call(n,r)&&r!==t&&q(n,r,{get:()=>e[r],enumerable:!(i=Je(e,r))||i.enumerable});return n};var nt=n=>it(q({},"__esModule",{value:!0}),n);var o=(n,e,t)=>et(n,typeof e!="symbol"?e+"":e,t);var $t={};tt($t,{ASSISTANT_PANEL_ID:()=>K,AssistantClient:()=>I,AssistantStore:()=>R,COMPONENT_ATTRIBUTE:()=>M,DESCRIBE_TIMEOUT_MS:()=>z,ELEMENT_NAME:()=>B,HighlightEngine:()=>L,MicrophoneCapture:()=>P,Mihe:()=>F,PROTOCOL_VERSION:()=>E,SDK_VERSION:()=>me,SpeakerQueue:()=>O,VOICE_SAMPLE_RATE:()=>b,VoiceSession:()=>V,appView:()=>W,chartDeclaration:()=>H,chartSignature:()=>Z,createMihe:()=>Ve,defineMiheAssistant:()=>we,executeCommand:()=>j,fillSummary:()=>pe,formatContextReport:()=>Q,formatField:()=>T,formatValue:()=>v,fromPcm16:()=>ee,hintedView:()=>C,humanizeKey:()=>S,mountWidget:()=>Ge,parseInline:()=>_,parseMarkdown:()=>le,safeHref:()=>ve,tableDeclaration:()=>X,tableSignature:()=>J,tabsDeclaration:()=>G,tabsSignature:()=>Y,toPcm16:()=>fe,voiceUrl:()=>ie});var E=1,b=24e3;var rt=3e4,I=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"attempt",0);o(this,"reconnectTimer",null);o(this,"heartbeatTimer",null);o(this,"stopped",!1);o(this,"conversationId",null);o(this,"lastScreen",null)}get connectionState(){return this.state}async connect(){this.state==="connecting"||this.state==="open"||(this.stopped=!1,await this.open())}close(){this.stopped=!0,this.clearTimers(),this.socket?.close(),this.socket=null,this.setState("closed")}sendMessage(e,t){this.send({type:"message",data:{text:e,clientMsgId:t}})}updateScreen(e){this.lastScreen=e,this.send({type:"screen_update",data:{screen:e}})}ackCommand(e,t,i,r){this.send({type:"command_result",data:{commandId:e,ok:t,result:i??null,error:r??null}})}confirmAction(e,t,i){this.send({type:"action_confirm",data:{proposalId:e,confirmed:t,editedInput:i??null}})}cancelTurn(e){this.send({type:"cancel",data:{turnId:e}})}requestVoiceToken(){this.send({type:"voice_token_request"})}async open(){this.setState(this.attempt===0?"connecting":"reconnecting");let e;try{e=await this.options.getUserToken()}catch{if(this.stopped)return;this.emit({type:"error",code:"user_token_unavailable",message:"Could not get a session token from the app.",recoverable:!0}),this.scheduleReconnect();return}if(this.stopped)return;let i=(this.options.socketFactory??(r=>new WebSocket(r)))(this.options.url);this.socket=i,i.onopen=()=>{let r={type:"auth",data:{publicKey:this.options.publicKey,userToken:e,sdkVersion:this.options.sdkVersion,protocolVersion:1,conversationId:this.conversationId,...this.options.debug?{debug:!0}:{}}};i.send(JSON.stringify(r))},i.onmessage=r=>{if(typeof r.data!="string")return;let s;try{s=JSON.parse(r.data)}catch{return}this.handle(s)},i.onclose=()=>{if(this.clearTimers(),this.stopped){this.setState("closed");return}this.scheduleReconnect()},i.onerror=()=>{}}handle(e){switch(e.type){case"auth_ok":{this.attempt=0,this.conversationId=e.data.conversationId,this.emit({type:"voice_available",available:e.data.voiceAvailable??!1}),e.data.assistantName&&this.emit({type:"assistant_name",name:e.data.assistantName}),this.emit({type:"launcher_icon",url:e.data.launcherIconUrl??null}),this.emit({type:"widget_settings",settings:e.data.widget??null}),this.setState("open"),this.startHeartbeat(e.data.heartbeatIntervalMs),this.lastScreen&&this.updateScreen(this.lastScreen);break}case"auth_error":{this.emit({type:"error",code:e.data.code,message:e.data.message,recoverable:!1}),this.stopped=!0;break}case"auth_expired":{this.options.getUserToken().then(t=>this.send({type:"auth",data:{publicKey:this.options.publicKey,userToken:t,sdkVersion:this.options.sdkVersion,protocolVersion:1,conversationId:this.conversationId,...this.options.debug?{debug:!0}:{}}})).catch(()=>this.socket?.close());break}case"turn_start":this.emit({type:"turn_start",turnId:e.data.turnId});break;case"delta":this.emit({type:"delta",turnId:e.data.turnId,text:e.data.text});break;case"complete":this.emit({type:"complete",turnId:e.data.turnId,message:e.data.message,sources:e.data.sources??[]});break;case"command":this.emit({type:"command",commandId:e.data.commandId,command:e.data.command});break;case"action_proposal":this.emit({type:"proposal",proposal:e.data});break;case"action_status":this.emit({type:"action_status",proposalId:e.data.proposalId,status:e.data.status,result:e.data.result??void 0,error:e.data.error??void 0});break;case"error":this.emit({type:"error",code:e.data.code,message:e.data.message,recoverable:e.data.recoverable});break;case"voice_token":this.emit({type:"voice_token",token:e.data.token,expiresAt:e.data.expiresAt});break;case"context_report":this.emit({type:"context_report",report:e.data});break;case"pong":break}}send(e){if(!(this.state!=="open"&&e.type!=="auth"))try{this.socket?.send(JSON.stringify(e))}catch{}}scheduleReconnect(){this.setState("reconnecting");let e=this.options.reconnectDelay?.(this.attempt)??st(this.attempt);this.attempt+=1,this.reconnectTimer=setTimeout(()=>{this.open()},e)}startHeartbeat(e){this.clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.send({type:"ping"})},e)}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}clearTimers(){this.clearHeartbeat(),this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}setState(e){this.state!==e&&(this.state=e,this.emit({type:"state",state:e}))}emit(e){this.options.onEvent(e)}};function st(n){let e=Math.min(1e3*2**n,rt);return e/2+Math.random()*(e/2)}function v(n){if(n==null)return"\u2014";if(typeof n=="string")return n;if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return n.map(v).join(", ")||"\u2014";if(typeof n=="object"){let e=Object.entries(n),t=e.find(([r])=>/^(quantity|qty|count)$/i.test(r)),i=e.find(([r,s])=>/(?:name|title|label)$|^(?:product|item)$/i.test(r)&&typeof s=="string");if(t&&i){let r=e.filter(([s])=>s!==t[0]&&s!==i[0]).map(([s,a])=>`${S(s)}: ${v(a)}`);return[`${v(t[1])} \xD7 ${v(i[1])}`,...r].join("; ")}return e.map(([r,s])=>`${S(r)}: ${v(s)}`).join(", ")}return String(n)}function S(n){let e=n.replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").trim();return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}var k=n=>n&&typeof n=="object"?n:{},he=n=>n["x-mihe-hidden"]===!0,Se=(n,e)=>typeof e.title=="string"&&e.title.trim()?e.title:S(n);function T(n,e){let t=k(e),i=t["x-mihe-format"];if(i==="yesno"&&typeof n=="boolean")return n?"Yes":"No";if(i==="money"&&typeof n=="number")return n.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2});if(i==="date"&&typeof n=="string"&&!Number.isNaN(Date.parse(n)))return new Date(n).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"});if(Array.isArray(n))return n.map(r=>T(r,t.items)).join(", ")||"\u2014";if(n&&typeof n=="object"){let r=t.properties??{},a=[...Object.keys(r).filter(l=>l in n),...Object.keys(n).filter(l=>!(l in r))].filter(l=>!he(k(r[l])));return Object.keys(r).length?a.map(l=>l===a[0]&&typeof n[l]=="string"?String(n[l]):`${Se(l,k(r[l]))} ${T(n[l],r[l])}`).join(" \xB7 "):v(n)}return v(n)}function pe(n,e,t){if(typeof n!="string"||!n.trim())return null;let i=!1,r=n.replace(/\{([A-Za-z0-9_]+)\}/g,(s,a)=>{let l=e[a];return l==null||l===""?(i=!0,""):Array.isArray(l)?String(l.length):T(l,t.properties?.[a])});return i?null:r}function C(n){let e=k(n.inputSchema),t=e.properties??{},i=n.input??{},r=!!e["x-mihe-summary"]||Object.values(t).some(d=>{let h=k(d);return typeof h.title=="string"||he(h)||h["x-mihe-format"]!==void 0}),a=[...Object.keys(t).filter(d=>d in i),...Object.keys(i).filter(d=>!(d in t))].filter(d=>!he(k(t[d]))).map(d=>{let h=i[d],p=r?Se(d,k(t[d])):S(d);return Array.isArray(h)&&h.length>0?{label:p,items:h.map(u=>T(u,k(t[d]).items))}:{label:p,text:T(h,t[d])}}),l=pe(e["x-mihe-summary"],i,e)??void 0;return{source:r?"hints":"plain",...l?{summary:l}:{},lines:a}}var ot=/^(https?:|blob:|data:image\/)/i;function W(n){let e=t=>typeof t=="string"?t:t==null?void 0:String(t);return{source:"app",...e(n.summary)?{summary:e(n.summary)}:{},...e(n.note)?{note:e(n.note)}:{},...e(n.confirmLabel)?{confirmLabel:e(n.confirmLabel)}:{},lines:(Array.isArray(n.lines)?n.lines:[]).map(t=>({...e(t.label)?{label:e(t.label)}:{},...e(t.text)!==void 0?{text:e(t.text)}:{},...e(t.before)!==void 0?{before:e(t.before)}:{},...Array.isArray(t.items)?{items:t.items.map(i=>String(i))}:{},...Array.isArray(t.images)?{images:t.images.filter(i=>i&&typeof i.src=="string"&&ot.test(i.src)).slice(0,12).map(i=>({src:i.src,...e(i.alt)?{alt:e(i.alt)}:{}}))}:{}}))}}var z=4e3;var M="data-mihe-component",at="mihe-highlight";function lt(n){return n?!!n.closest("button, a[href], [role='button'], [role='link']"):!1}function $(n){return document.querySelector(`[${M}="${CSS.escape(n)}"]`)}var L=class{constructor(){o(this,"overlay",null);o(this,"caption",null);o(this,"target",null);o(this,"tracking",!1);o(this,"observer",null);o(this,"frame",0);o(this,"position",()=>{if(!this.overlay||!this.target)return;if(!this.target.isConnected){this.clear();return}let e=this.target.getBoundingClientRect();Object.assign(this.overlay.style,{top:`${e.top-6}px`,left:`${e.left-6}px`,width:`${e.width+12}px`,height:`${e.height+12}px`})});o(this,"reposition",()=>{this.frame||(this.frame=requestAnimationFrame(()=>{this.frame=0,this.position()}))});o(this,"onKeyDown",e=>{e.key==="Escape"&&this.clear()});o(this,"onPointerDown",e=>{let t=e.target;t instanceof Node&&this.target?.contains(t)&&!lt(this.target)||this.clear()})}highlight(e,t){let i=$(e);return i?(this.target=i,this.ensureOverlay(),this.setCaption(t),this.position(),this.startTracking(),i.scrollIntoView({behavior:"smooth",block:"center"}),!0):!1}focus(e,t){let i=$(e);return i?(this.highlight(e,t),(i.matches("input, textarea, select, button, [tabindex]")?i:i.querySelector("input, textarea, select, button, [tabindex]"))?.focus(),!0):!1}scrollTo(e){let t=$(e);return t?(t.scrollIntoView({behavior:"smooth",block:"center"}),!0):!1}clear(){this.stopTracking(),this.overlay?.remove(),this.overlay=null,this.caption=null,this.target=null}ensureOverlay(){if(this.overlay)return;let e=document.createElement("div");e.id=at,Object.assign(e.style,{position:"fixed",zIndex:"2147483000",pointerEvents:"none",border:"2px solid #4f7cff",borderRadius:"8px",boxShadow:"0 0 0 9999px rgba(15, 23, 42, 0.45)",transition:"top 120ms ease, left 120ms ease, width 120ms ease, height 120ms ease"});let t=document.createElement("div");Object.assign(t.style,{position:"absolute",left:"0",top:"100%",marginTop:"8px",maxWidth:"260px",padding:"8px 10px",borderRadius:"8px",background:"#0f172a",color:"#f8fafc",font:"500 13px/1.4 system-ui, -apple-system, sans-serif",display:"none"}),e.appendChild(t),document.body.appendChild(e),this.overlay=e,this.caption=t}setCaption(e){this.caption&&(e?(this.caption.textContent=e,this.caption.style.display="block"):(this.caption.textContent="",this.caption.style.display="none"))}startTracking(){this.tracking||(this.tracking=!0,window.addEventListener("scroll",this.position,{passive:!0,capture:!0}),window.addEventListener("resize",this.position,{passive:!0}),window.addEventListener("keydown",this.onKeyDown),window.addEventListener("pointerdown",this.onPointerDown,{capture:!0}),this.observer=new MutationObserver(this.reposition),this.observer.observe(document.body,{childList:!0,subtree:!0}))}stopTracking(){this.tracking&&(this.tracking=!1,window.removeEventListener("scroll",this.position,{capture:!0}),window.removeEventListener("resize",this.position),window.removeEventListener("keydown",this.onKeyDown),window.removeEventListener("pointerdown",this.onPointerDown,{capture:!0}),this.observer?.disconnect(),this.observer=null,this.frame&&(cancelAnimationFrame(this.frame),this.frame=0))}};var Te=5e3,Ce=1e4;function ct(n,e){for(let[t,i]of Object.entries(e)){let r=n.find(s=>s.key===t);if(!r)return`"${t}" is not something this table can be searched by.`;if(typeof i!="string")return`The value for "${t}" must be a string.`;if(r.kind==="enum"&&!r.values.includes(i))return`"${i}" is not one of "${t}"'s values.`;if(r.kind==="date"&&!ht(i))return`"${i}" is not a date in YYYY-MM-DD form.`;if(r.kind==="text"&&(i.length>dt||/[\u0000-\u001f\u007f]/.test(i)))return`The search for "${t}" is too long or contains control characters.`}return null}var dt=100;function ht(n){if(!/^\d{4}-\d{2}-\d{2}$/.test(n))return!1;let e=new Date(`${n}T00:00:00Z`);return!Number.isNaN(e.getTime())&&e.toISOString().slice(0,10)===n}function pt(){return typeof window>"u"?null:window.location.pathname}function ut(){return typeof window>"u"?null:window.location.pathname+window.location.search}async function j(n,e){switch(n.type){case"navigate":{let{route:t}=n.data,i=t.includes("?")&&ut()!==t;return e.navigate(t),await e.screenPublished?.(t,{fresh:i})??!0?{ok:!0,result:{route:t}}:{ok:!0,result:{route:t,note:"Navigation started, but the destination has not reported its context yet. Anything scoped to that screen may not be available for another moment."}}}case"highlight":{let{componentKey:t,message:i}=n.data;return e.highlighter.highlight(t,i??void 0)?{ok:!0}:{ok:!1,error:ue(t)}}case"focus":{let{componentKey:t,message:i}=n.data;return e.highlighter.focus(t,i??void 0)?{ok:!0}:{ok:!1,error:ue(t)}}case"scroll_to":{let{componentKey:t}=n.data;return e.highlighter.scrollTo(t)?{ok:!0}:{ok:!1,error:ue(t)}}case"open_modal":{let{modalKey:t}=n.data;return e.openModal?e.openModal(t)===!1?{ok:!1,error:`There is no \`${t}\` dialog on this screen. It may belong to a different one.`}:{ok:!0}:{ok:!1,error:"This app has not wired up modal opening, so that modal cannot be opened."}}case"run_frontend_action":{let{actionName:t,input:i}=n.data,r=e.store.getAction(t);if(!r)return{ok:!1,error:`No handler is currently mounted for "${t}".`};let s=Date.now(),a=setTimeout(()=>{console.warn(`[mihe] The "${t}" handler has run for ${Te/1e3}s. The runtime waits ${Ce/1e3}s, then tells the assistant it failed. If it is waiting for the user, open the UI they need and return at once (say what you opened); they finish it there.`)},Te),l=()=>{Date.now()-s>Ce&&console.warn(`[mihe] The "${t}" handler finished after the runtime stopped waiting, so the assistant was told it failed whatever the outcome. Return before the user acts; see the warning above.`)};try{let d=await r.handler(i??{});return l(),{ok:!0,result:d??{done:!0}}}catch(d){return l(),{ok:!1,error:D(d)}}finally{clearTimeout(a)}}case"set_view":{let{controlKey:t,value:i}=n.data,r=e.store.getControl(t);if(!r)return{ok:!1,error:`"${t}" is not on the page right now.`};if(!r.options.some(a=>a.value===i))return{ok:!1,error:`"${i}" is not one of "${t}"'s options.`};try{await r.onChange(i)}catch(a){return{ok:!1,error:D(a)}}return await e.viewPublished?.(t,i)??!0?{ok:!0,result:{showing:i}}:{ok:!1,error:`The app was asked to show "${i}", but "${t}" still reports another tab.`}}case"read_table":{let{tableKey:t,offset:i,limit:r}=n.data,s=e.store.getTable(t);if(!s)return{ok:!1,error:`"${t}" is not on the page right now.`};try{return{ok:!0,result:{rows:s.read(i,r),offset:i,loaded:s.loadedRows,...s.total===void 0?{}:{total:s.total}}}}catch(a){return{ok:!1,error:D(a)}}}case"query_table":{let{tableKey:t,params:i,limit:r,show:s}=n.data,a=e.store.getTable(t);if(!a)return{ok:!1,error:`"${t}" is not on the page right now.`};if(!a.query)return{ok:!1,error:`"${t}" cannot be searched.`};let l=ct(a.query.params,i);if(l)return{ok:!1,error:l};let d;try{d=await a.query.run(i)}catch(p){return{ok:!1,error:D(p)}}let h=!1;if(s&&a.query.show)try{await a.query.show(i),h=await e.screenPublished?.(pt()??"",{fresh:!0})??!0}catch(p){return{ok:!1,error:D(p)}}return{ok:!0,result:{rows:d.rows.slice(0,r),...d.total===void 0?{}:{total:d.total},shown:h}}}case"read_chart":{let{chartKey:t,series:i,limit:r}=n.data,s=e.store.getChart(t);if(!s)return{ok:!1,error:`"${t}" is not on the page right now.`};try{return{ok:!0,result:{series:s.read(i??void 0,r)}}}catch(a){return{ok:!1,error:D(a)}}}case"clear_highlight":return e.highlighter.clear(),{ok:!0};default:return{ok:!1,error:`This app's SDK does not understand the "${n.type}" command. It may need updating.`}}}function ue(n){return!!$(n)?`"${n}" is on the page but not visible.`:`"${n}" is not on the page right now.`}function D(n){return n instanceof Error?n.message:typeof n=="string"?n:"The action failed."}function Q(n){let t=[`[mihe] Each answer on ${n.screenId?`\`${n.screenId}\``:"an unregistered page"} re-sends about:`];t.push(` typed: ${Me(n.chat)}`),n.voice&&t.push(` voice: ${Me(n.voice)}`);let i=(n.voice??n.chat).tools.slice(0,5);return i.length>0&&t.push(` largest tools: ${i.map(r=>`${r.name} ${r.tokens}`).join(", ")}`),t.join(`
|
|
3
|
-
`)}function
|
|
1
|
+
/*! @mihe-dev/js 0.2.5 | MIT © Neek Digital Solutions Ltd | https://mihe.dev */
|
|
2
|
+
"use strict";var Mihe=(()=>{var W=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var it=Object.prototype.hasOwnProperty;var nt=(n,e,t)=>e in n?W(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var rt=(n,e)=>{for(var t in e)W(n,t,{get:e[t],enumerable:!0})},st=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of tt(e))!it.call(n,r)&&r!==t&&W(n,r,{get:()=>e[r],enumerable:!(i=et(e,r))||i.enumerable});return n};var ot=n=>st(W({},"__esModule",{value:!0}),n);var o=(n,e,t)=>nt(n,typeof e!="symbol"?e+"":e,t);var Ut={};rt(Ut,{ASSISTANT_PANEL_ID:()=>U,ATTACHMENT_TIMEOUT_MS:()=>ye,AssistantClient:()=>I,AssistantStore:()=>D,COMPONENT_ATTRIBUTE:()=>M,DESCRIBE_TIMEOUT_MS:()=>j,ELEMENT_NAME:()=>K,HighlightEngine:()=>L,MAX_ATTACHMENTS:()=>ne,MicrophoneCapture:()=>P,Mihe:()=>F,PROTOCOL_VERSION:()=>E,SDK_VERSION:()=>ve,SpeakerQueue:()=>O,VOICE_SAMPLE_RATE:()=>b,VoiceSession:()=>_,acceptsFile:()=>xe,appView:()=>q,chartDeclaration:()=>H,chartSignature:()=>Z,createMihe:()=>$e,defineMiheAssistant:()=>Me,executeCommand:()=>z,fillSummary:()=>ue,formatContextReport:()=>Q,formatField:()=>T,formatValue:()=>v,fromPcm16:()=>ee,hintedView:()=>C,humanizeKey:()=>S,mountWidget:()=>Xe,parseInline:()=>V,parseMarkdown:()=>ce,safeHref:()=>Se,tableDeclaration:()=>X,tableSignature:()=>J,tabsDeclaration:()=>G,tabsSignature:()=>Y,toPcm16:()=>ge,voiceUrl:()=>ie});var E=1,b=24e3;var at=3e4,I=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"attempt",0);o(this,"reconnectTimer",null);o(this,"heartbeatTimer",null);o(this,"stopped",!1);o(this,"conversationId",null);o(this,"lastScreen",null)}get connectionState(){return this.state}async connect(){this.state==="connecting"||this.state==="open"||(this.stopped=!1,await this.open())}close(){this.stopped=!0,this.clearTimers(),this.socket?.close(),this.socket=null,this.setState("closed")}sendMessage(e,t){this.send({type:"message",data:{text:e,clientMsgId:t}})}updateScreen(e){this.lastScreen=e,this.send({type:"screen_update",data:{screen:e}})}ackCommand(e,t,i,r){this.send({type:"command_result",data:{commandId:e,ok:t,result:i??null,error:r??null}})}confirmAction(e,t,i){this.send({type:"action_confirm",data:{proposalId:e,confirmed:t,editedInput:i??null}})}cancelTurn(e){this.send({type:"cancel",data:{turnId:e}})}requestVoiceToken(){this.send({type:"voice_token_request"})}async open(){this.setState(this.attempt===0?"connecting":"reconnecting");let e;try{e=await this.options.getUserToken()}catch{if(this.stopped)return;this.emit({type:"error",code:"user_token_unavailable",message:"Could not get a session token from the app.",recoverable:!0}),this.scheduleReconnect();return}if(this.stopped)return;let i=(this.options.socketFactory??(r=>new WebSocket(r)))(this.options.url);this.socket=i,i.onopen=()=>{let r={type:"auth",data:{publicKey:this.options.publicKey,userToken:e,sdkVersion:this.options.sdkVersion,protocolVersion:1,conversationId:this.conversationId,...this.options.debug?{debug:!0}:{}}};i.send(JSON.stringify(r))},i.onmessage=r=>{if(typeof r.data!="string")return;let s;try{s=JSON.parse(r.data)}catch{return}this.handle(s)},i.onclose=()=>{if(this.clearTimers(),this.stopped){this.setState("closed");return}this.scheduleReconnect()},i.onerror=()=>{}}handle(e){switch(e.type){case"auth_ok":{this.attempt=0,this.conversationId=e.data.conversationId,this.emit({type:"voice_available",available:e.data.voiceAvailable??!1}),e.data.assistantName&&this.emit({type:"assistant_name",name:e.data.assistantName}),this.emit({type:"launcher_icon",url:e.data.launcherIconUrl??null}),this.emit({type:"widget_settings",settings:e.data.widget??null}),this.setState("open"),this.startHeartbeat(e.data.heartbeatIntervalMs),this.lastScreen&&this.updateScreen(this.lastScreen);break}case"auth_error":{this.emit({type:"error",code:e.data.code,message:e.data.message,recoverable:!1}),this.stopped=!0;break}case"auth_expired":{this.options.getUserToken().then(t=>this.send({type:"auth",data:{publicKey:this.options.publicKey,userToken:t,sdkVersion:this.options.sdkVersion,protocolVersion:1,conversationId:this.conversationId,...this.options.debug?{debug:!0}:{}}})).catch(()=>this.socket?.close());break}case"turn_start":this.emit({type:"turn_start",turnId:e.data.turnId});break;case"delta":this.emit({type:"delta",turnId:e.data.turnId,text:e.data.text});break;case"complete":this.emit({type:"complete",turnId:e.data.turnId,message:e.data.message,sources:e.data.sources??[]});break;case"command":this.emit({type:"command",commandId:e.data.commandId,command:e.data.command});break;case"action_proposal":this.emit({type:"proposal",proposal:e.data});break;case"action_status":this.emit({type:"action_status",proposalId:e.data.proposalId,status:e.data.status,result:e.data.result??void 0,error:e.data.error??void 0});break;case"error":this.emit({type:"error",code:e.data.code,message:e.data.message,recoverable:e.data.recoverable});break;case"voice_token":this.emit({type:"voice_token",token:e.data.token,expiresAt:e.data.expiresAt});break;case"context_report":this.emit({type:"context_report",report:e.data});break;case"pong":break}}send(e){if(!(this.state!=="open"&&e.type!=="auth"))try{this.socket?.send(JSON.stringify(e))}catch{}}scheduleReconnect(){this.setState("reconnecting");let e=this.options.reconnectDelay?.(this.attempt)??lt(this.attempt);this.attempt+=1,this.reconnectTimer=setTimeout(()=>{this.open()},e)}startHeartbeat(e){this.clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.send({type:"ping"})},e)}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}clearTimers(){this.clearHeartbeat(),this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}setState(e){this.state!==e&&(this.state=e,this.emit({type:"state",state:e}))}emit(e){this.options.onEvent(e)}};function lt(n){let e=Math.min(1e3*2**n,at);return e/2+Math.random()*(e/2)}function v(n){if(n==null)return"\u2014";if(typeof n=="string")return n;if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return n.map(v).join(", ")||"\u2014";if(typeof n=="object"){let e=Object.entries(n),t=e.find(([r])=>/^(quantity|qty|count)$/i.test(r)),i=e.find(([r,s])=>/(?:name|title|label)$|^(?:product|item)$/i.test(r)&&typeof s=="string");if(t&&i){let r=e.filter(([s])=>s!==t[0]&&s!==i[0]).map(([s,l])=>`${S(s)}: ${v(l)}`);return[`${v(t[1])} \xD7 ${v(i[1])}`,...r].join("; ")}return e.map(([r,s])=>`${S(r)}: ${v(s)}`).join(", ")}return String(n)}function S(n){let e=n.replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").trim();return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}var k=n=>n&&typeof n=="object"?n:{},pe=n=>n["x-mihe-hidden"]===!0,Ee=(n,e)=>typeof e.title=="string"&&e.title.trim()?e.title:S(n);function T(n,e){let t=k(e),i=t["x-mihe-format"];if(i==="yesno"&&typeof n=="boolean")return n?"Yes":"No";if(i==="money"&&typeof n=="number")return n.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2});if(i==="date"&&typeof n=="string"&&!Number.isNaN(Date.parse(n)))return new Date(n).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"});if(Array.isArray(n))return n.map(r=>T(r,t.items)).join(", ")||"\u2014";if(n&&typeof n=="object"){let r=t.properties??{},l=[...Object.keys(r).filter(a=>a in n),...Object.keys(n).filter(a=>!(a in r))].filter(a=>!pe(k(r[a])));return Object.keys(r).length?l.map(a=>a===l[0]&&typeof n[a]=="string"?String(n[a]):`${Ee(a,k(r[a]))} ${T(n[a],r[a])}`).join(" \xB7 "):v(n)}return v(n)}function ue(n,e,t){if(typeof n!="string"||!n.trim())return null;let i=!1,r=n.replace(/\{([A-Za-z0-9_]+)\}/g,(s,l)=>{let a=e[l];return a==null||a===""?(i=!0,""):Array.isArray(a)?String(a.length):T(a,t.properties?.[l])});return i?null:r}function C(n){let e=k(n.inputSchema),t=e.properties??{},i=n.input??{},r=!!e["x-mihe-summary"]||Object.values(t).some(d=>{let h=k(d);return typeof h.title=="string"||pe(h)||h["x-mihe-format"]!==void 0}),l=[...Object.keys(t).filter(d=>d in i),...Object.keys(i).filter(d=>!(d in t))].filter(d=>!pe(k(t[d]))).map(d=>{let h=i[d],p=r?Ee(d,k(t[d])):S(d);return Array.isArray(h)&&h.length>0?{label:p,items:h.map(u=>T(u,k(t[d]).items))}:{label:p,text:T(h,t[d])}}),a=ue(e["x-mihe-summary"],i,e)??void 0;return{source:r?"hints":"plain",...a?{summary:a}:{},lines:l}}var ct=/^(https?:|blob:|data:image\/)/i;function q(n){let e=t=>typeof t=="string"?t:t==null?void 0:String(t);return{source:"app",...e(n.summary)?{summary:e(n.summary)}:{},...e(n.note)?{note:e(n.note)}:{},...e(n.confirmLabel)?{confirmLabel:e(n.confirmLabel)}:{},lines:(Array.isArray(n.lines)?n.lines:[]).map(t=>({...e(t.label)?{label:e(t.label)}:{},...e(t.text)!==void 0?{text:e(t.text)}:{},...e(t.before)!==void 0?{before:e(t.before)}:{},...Array.isArray(t.items)?{items:t.items.map(i=>String(i))}:{},...Array.isArray(t.images)?{images:t.images.filter(i=>i&&typeof i.src=="string"&&ct.test(i.src)).slice(0,12).map(i=>({src:i.src,...e(i.alt)?{alt:e(i.alt)}:{}}))}:{}}))}}var j=4e3;var M="data-mihe-component",dt="mihe-highlight";function ht(n){return n?!!n.closest("button, a[href], [role='button'], [role='link']"):!1}function $(n){return document.querySelector(`[${M}="${CSS.escape(n)}"]`)}var L=class{constructor(){o(this,"overlay",null);o(this,"caption",null);o(this,"target",null);o(this,"tracking",!1);o(this,"observer",null);o(this,"frame",0);o(this,"position",()=>{if(!this.overlay||!this.target)return;if(!this.target.isConnected){this.clear();return}let e=this.target.getBoundingClientRect();Object.assign(this.overlay.style,{top:`${e.top-6}px`,left:`${e.left-6}px`,width:`${e.width+12}px`,height:`${e.height+12}px`})});o(this,"reposition",()=>{this.frame||(this.frame=requestAnimationFrame(()=>{this.frame=0,this.position()}))});o(this,"onKeyDown",e=>{e.key==="Escape"&&this.clear()});o(this,"onPointerDown",e=>{let t=e.target;t instanceof Node&&this.target?.contains(t)&&!ht(this.target)||this.clear()})}highlight(e,t){let i=$(e);return i?(this.target=i,this.ensureOverlay(),this.setCaption(t),this.position(),this.startTracking(),i.scrollIntoView({behavior:"smooth",block:"center"}),!0):!1}focus(e,t){let i=$(e);return i?(this.highlight(e,t),(i.matches("input, textarea, select, button, [tabindex]")?i:i.querySelector("input, textarea, select, button, [tabindex]"))?.focus(),!0):!1}scrollTo(e){let t=$(e);return t?(t.scrollIntoView({behavior:"smooth",block:"center"}),!0):!1}clear(){this.stopTracking(),this.overlay?.remove(),this.overlay=null,this.caption=null,this.target=null}ensureOverlay(){if(this.overlay)return;let e=document.createElement("div");e.id=dt,Object.assign(e.style,{position:"fixed",zIndex:"2147483000",pointerEvents:"none",border:"2px solid #4f7cff",borderRadius:"8px",boxShadow:"0 0 0 9999px rgba(15, 23, 42, 0.45)",transition:"top 120ms ease, left 120ms ease, width 120ms ease, height 120ms ease"});let t=document.createElement("div");Object.assign(t.style,{position:"absolute",left:"0",top:"100%",marginTop:"8px",maxWidth:"260px",padding:"8px 10px",borderRadius:"8px",background:"#0f172a",color:"#f8fafc",font:"500 13px/1.4 system-ui, -apple-system, sans-serif",display:"none"}),e.appendChild(t),document.body.appendChild(e),this.overlay=e,this.caption=t}setCaption(e){this.caption&&(e?(this.caption.textContent=e,this.caption.style.display="block"):(this.caption.textContent="",this.caption.style.display="none"))}startTracking(){this.tracking||(this.tracking=!0,window.addEventListener("scroll",this.position,{passive:!0,capture:!0}),window.addEventListener("resize",this.position,{passive:!0}),window.addEventListener("keydown",this.onKeyDown),window.addEventListener("pointerdown",this.onPointerDown,{capture:!0}),this.observer=new MutationObserver(this.reposition),this.observer.observe(document.body,{childList:!0,subtree:!0}))}stopTracking(){this.tracking&&(this.tracking=!1,window.removeEventListener("scroll",this.position,{capture:!0}),window.removeEventListener("resize",this.position),window.removeEventListener("keydown",this.onKeyDown),window.removeEventListener("pointerdown",this.onPointerDown,{capture:!0}),this.observer?.disconnect(),this.observer=null,this.frame&&(cancelAnimationFrame(this.frame),this.frame=0))}};var Ie=5e3,fe=1e4;function pt(n,e){for(let[t,i]of Object.entries(e)){let r=n.find(s=>s.key===t);if(!r)return`"${t}" is not something this table can be searched by.`;if(typeof i!="string")return`The value for "${t}" must be a string.`;if(r.kind==="enum"&&!r.values.includes(i))return`"${i}" is not one of "${t}"'s values.`;if(r.kind==="date"&&!ft(i))return`"${i}" is not a date in YYYY-MM-DD form.`;if(r.kind==="text"&&(i.length>ut||/[\u0000-\u001f\u007f]/.test(i)))return`The search for "${t}" is too long or contains control characters.`}return null}var ut=100;function ft(n){if(!/^\d{4}-\d{2}-\d{2}$/.test(n))return!1;let e=new Date(`${n}T00:00:00Z`);return!Number.isNaN(e.getTime())&&e.toISOString().slice(0,10)===n}function mt(){return typeof window>"u"?null:window.location.pathname}function gt(){return typeof window>"u"?null:window.location.pathname+window.location.search}async function z(n,e){switch(n.type){case"navigate":{let{route:t}=n.data,i=t.includes("?")&>()!==t;return e.navigate(t),await e.screenPublished?.(t,{fresh:i})??!0?{ok:!0,result:{route:t}}:{ok:!0,result:{route:t,note:"Navigation started, but the destination has not reported its context yet. Anything scoped to that screen may not be available for another moment."}}}case"highlight":{let{componentKey:t,message:i}=n.data;return e.highlighter.highlight(t,i??void 0)?{ok:!0}:{ok:!1,error:me(t)}}case"focus":{let{componentKey:t,message:i}=n.data;return e.highlighter.focus(t,i??void 0)?{ok:!0}:{ok:!1,error:me(t)}}case"scroll_to":{let{componentKey:t}=n.data;return e.highlighter.scrollTo(t)?{ok:!0}:{ok:!1,error:me(t)}}case"open_modal":{let{modalKey:t}=n.data;return e.openModal?e.openModal(t)===!1?{ok:!1,error:`There is no \`${t}\` dialog on this screen. It may belong to a different one.`}:{ok:!0}:{ok:!1,error:"This app has not wired up modal opening, so that modal cannot be opened."}}case"run_frontend_action":{let{actionName:t,input:i}=n.data,r=e.store.getAction(t);if(!r)return{ok:!1,error:`No handler is currently mounted for "${t}".`};let s=Date.now(),l=setTimeout(()=>{console.warn(`[mihe] The "${t}" handler has run for ${Ie/1e3}s. The runtime waits ${fe/1e3}s unless the action (timeoutSeconds) or the app sets longer, then tells the assistant it failed. If it is waiting for the user, open the UI they need and return at once (say what you opened); they finish it there.`)},Ie),a=()=>{Date.now()-s>fe&&console.warn(`[mihe] The "${t}" handler finished after ${Math.round((Date.now()-s)/1e3)}s. If that was past its time limit (${fe/1e3}s unless the action sets timeoutSeconds or the app sets longer), the assistant was told it failed whatever the outcome. If it waits on the user, return before they act; if it is slow by nature, give it timeoutSeconds.`)};try{let d=await r.handler(i??{});return a(),{ok:!0,result:d??{done:!0}}}catch(d){return a(),{ok:!1,error:R(d)}}finally{clearTimeout(l)}}case"set_view":{let{controlKey:t,value:i}=n.data,r=e.store.getControl(t);if(!r)return{ok:!1,error:`"${t}" is not on the page right now.`};if(!r.options.some(l=>l.value===i))return{ok:!1,error:`"${i}" is not one of "${t}"'s options.`};try{await r.onChange(i)}catch(l){return{ok:!1,error:R(l)}}return await e.viewPublished?.(t,i)??!0?{ok:!0,result:{showing:i}}:{ok:!1,error:`The app was asked to show "${i}", but "${t}" still reports another tab.`}}case"read_table":{let{tableKey:t,offset:i,limit:r}=n.data,s=e.store.getTable(t);if(!s)return{ok:!1,error:`"${t}" is not on the page right now.`};try{return{ok:!0,result:{rows:s.read(i,r),offset:i,loaded:s.loadedRows,...s.total===void 0?{}:{total:s.total}}}}catch(l){return{ok:!1,error:R(l)}}}case"query_table":{let{tableKey:t,params:i,limit:r,show:s}=n.data,l=e.store.getTable(t);if(!l)return{ok:!1,error:`"${t}" is not on the page right now.`};if(!l.query)return{ok:!1,error:`"${t}" cannot be searched.`};let a=pt(l.query.params,i);if(a)return{ok:!1,error:a};let d;try{d=await l.query.run(i)}catch(p){return{ok:!1,error:R(p)}}let h=!1;if(s&&l.query.show)try{await l.query.show(i),h=await e.screenPublished?.(mt()??"",{fresh:!0})??!0}catch(p){return{ok:!1,error:R(p)}}return{ok:!0,result:{rows:d.rows.slice(0,r),...d.total===void 0?{}:{total:d.total},shown:h}}}case"read_chart":{let{chartKey:t,series:i,limit:r}=n.data,s=e.store.getChart(t);if(!s)return{ok:!1,error:`"${t}" is not on the page right now.`};try{return{ok:!0,result:{series:s.read(i??void 0,r)}}}catch(l){return{ok:!1,error:R(l)}}}case"clear_highlight":return e.highlighter.clear(),{ok:!0};default:return{ok:!1,error:`This app's SDK does not understand the "${n.type}" command. It may need updating.`}}}function me(n){return!!$(n)?`"${n}" is on the page but not visible.`:`"${n}" is not on the page right now.`}function R(n){return n instanceof Error?n.message:typeof n=="string"?n:"The action failed."}function Q(n){let t=[`[mihe] Each answer on ${n.screenId?`\`${n.screenId}\``:"an unregistered page"} re-sends about:`];t.push(` typed: ${Le(n.chat)}`),n.voice&&t.push(` voice: ${Le(n.voice)}`);let i=(n.voice??n.chat).tools.slice(0,5);return i.length>0&&t.push(` largest tools: ${i.map(r=>`${r.name} ${r.tokens}`).join(", ")}`),t.join(`
|
|
3
|
+
`)}function Le(n){return`${(n.instructionTokens+n.toolTokens+n.screenTokens).toLocaleString("en")} tokens \u2014 instructions ${n.instructionTokens}, ${n.tools.length} tools ${n.toolTokens}, this screen ${n.screenTokens}`}function Re(n,e){let[t]=n;if(!t)return;let i=n[n.length-1],r=t,s=t,l=0,a,d;return n.forEach((h,p)=>{if(l+=h.y,h.y<r.y&&(r=h),h.y>s.y&&(s=h),!e||p===0)return;let u=n[p-1],m=h.y-u.y;m>0&&(!a||m>a.change)&&(a={from:u.x,to:h.x,change:m}),m<0&&(!d||m<d.change)&&(d={from:u.x,to:h.x,change:m})}),{points:n.length,first:t,last:i,min:r,max:s,total:Math.round(l*100)/100,...a?{largestRise:a}:{},...d?{largestFall:d}:{}}}function De(n,e){if(n.length<=e)return n;if(e<=1)return n.slice(0,1);let t=(n.length-1)/(e-1);return Array.from({length:e},(i,r)=>n[Math.round(r*t)])}var Pe=200;function bt(n){if(n==null)return null;if(typeof n=="number"||typeof n=="boolean")return n;let e=n instanceof Date?n.toISOString():typeof n=="string"?n:JSON.stringify(n);return e.length>Pe?`${e.slice(0,Pe)}\u2026`:e}function G(n){let e=n();return{kind:"tabs",label:e.label,options:e.tabs.map(({value:t,label:i})=>({value:t,label:i})),value:e.value,onChange:t=>n().onChange(t)}}function Y(n){return JSON.stringify({label:n.label,tabs:n.tabs.map(({value:e,label:t})=>({value:e,label:t})),value:n.value})}function _e(n){return Object.entries(n.params).map(([e,t])=>({key:e,kind:t.kind,values:t.kind==="enum"?[...t.values]:[],description:t.description??""}))}function J(n){return JSON.stringify({label:n.label,columns:n.columns.map(({key:e,label:t})=>({key:e,label:t})),rowIdName:n.rowIdName,opens:n.opens?.screenId,total:n.total,loaded:n.rows.length,query:n.query?{params:_e(n.query),canShow:n.query.show!==void 0}:void 0})}function X(n){let e=n(),t=i=>{let{rowId:r,columns:s,opens:l}=n(),a={};for(let d of s){let h=d.value?d.value(i):i[d.key];a[d.label]=bt(h)}return{id:r(i),...l?{open:l.params(i)}:{},...a}};return{label:e.label,columns:e.columns.map(({key:i,label:r})=>({key:i,label:r})),rowIdName:e.rowIdName,opens:e.opens?.screenId,total:e.total,loadedRows:e.rows.length,read:(i,r)=>n().rows.slice(i,i+r).map(t),...e.query?{query:{params:_e(e.query),run:async i=>{let r=n().query;if(!r)throw new Error("This table can no longer be searched.");let s=await r.run(i);return{rows:s.rows.map(t),...s.total===void 0?{}:{total:s.total}}},...e.query.show?{show:i=>n().query?.show?.(i)}:{}}}:{}}}function Oe(n,e){let t=n.x.format;return n.data.flatMap(i=>{let r=i[e],s=typeof r=="number"?r:r==null?NaN:Number(r);if(!Number.isFinite(s))return[];let l=i[n.x.key];return[{x:t?t(l):String(l),y:s}]})}function H(n){let e=n(),t=e.x.kind!=="category";return{title:e.title,xLabel:e.x.label,xKind:t?"ordered":"category",series:e.series.map(i=>{let r=Re(Oe(e,i.key),t);return{name:i.name,...i.unit?{unit:i.unit}:{},...r?{summary:r}:{}}}),read:(i,r)=>{let s=n();return s.series.filter(l=>i===void 0||l.name===i).map(l=>({name:l.name,points:De(Oe(s,l.key),r)}))}}}function Z(n){let{read:e,...t}=H(()=>n);return JSON.stringify(t)}var D=class{constructor(){o(this,"screen",null);o(this,"components",new Map);o(this,"controls",new Map);o(this,"tables",new Map);o(this,"charts",new Map);o(this,"values",new Map);o(this,"actions",new Map);o(this,"listeners",new Set);o(this,"snapshot",null);o(this,"snapshotDirty",!0);o(this,"subscribe",e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}));o(this,"getScreenContext",()=>this.snapshotDirty?(this.snapshot=this.screen?{screenId:this.screen.screenId,route:this.screen.route,title:this.screen.title,description:this.screen.description??"",keywords:this.screen.keywords??[],visibleData:this.screen.loading?{}:{...this.screen.visibleData??{},...Object.fromEntries(this.values)},components:[...this.components.entries()].map(([e,t])=>({componentKey:e,type:t.type,label:t.label,description:t.description??"",actions:t.actions??[]})),controls:[...this.controls.entries()].map(([e,t])=>({controlKey:e,kind:t.kind,label:t.label,options:t.options.map(({value:i,label:r})=>({value:i,label:r})),...t.value===void 0?{}:{value:t.value}})),tables:[...this.tables.entries()].map(([e,t])=>({tableKey:e,label:t.label,columns:t.columns.map(({key:i,label:r})=>({key:i,label:r})),loadedRows:t.loadedRows,...t.rowIdName?{rowId:t.rowIdName}:{},...t.opens?{opens:t.opens}:{},...t.total===void 0?{}:{totalRows:t.total},...t.query?{query:{params:t.query.params.map(({key:i,kind:r,values:s,description:l})=>({key:i,kind:r,values:s,description:l})),canShow:t.query.show!==void 0}}:{}})),charts:[...this.charts.entries()].map(([e,t])=>({chartKey:e,title:t.title,xLabel:t.xLabel,xKind:t.xKind,series:t.series}))}:null,this.snapshotDirty=!1,this.snapshot):this.snapshot)}setScreen(e){let t=this.screen;this.screen=e,t&&t.screenId!==e.screenId&&(this.components.clear(),this.controls.clear(),this.tables.clear(),this.charts.clear(),this.values.clear()),this.invalidate()}clearScreen(e){this.screen?.screenId===e&&(this.screen=null,this.components.clear(),this.controls.clear(),this.tables.clear(),this.charts.clear(),this.values.clear(),this.invalidate())}registerComponent(e,t){this.components.set(e,t),this.invalidate()}unregisterComponent(e){this.components.delete(e)&&this.invalidate()}registerControl(e,t){this.controls.set(e,t),this.invalidate()}unregisterControl(e){this.controls.delete(e)&&this.invalidate()}getControl(e){return this.controls.get(e)}registerTable(e,t){this.tables.set(e,t),this.invalidate()}unregisterTable(e){this.tables.delete(e)&&this.invalidate()}getTable(e){return this.tables.get(e)}setValues(e,t){this.values.set(e,t),this.invalidate()}clearValues(e){this.values.delete(e)&&this.invalidate()}registerChart(e,t){this.charts.set(e,t),this.invalidate()}unregisterChart(e){this.charts.delete(e)&&this.invalidate()}getChart(e){return this.charts.get(e)}registerAction(e){this.actions.has(e.name)&&console.warn(`[assistant] Two handlers registered for action "${e.name}". The most recent one wins; the earlier one will never run.`),this.actions.set(e.name,e)}unregisterAction(e){this.actions.delete(e)}getAction(e){return this.actions.get(e)}isScreenLoading(){return this.screen?.loading===!0}hasComponent(e){return this.components.has(e)}invalidate(){this.snapshotDirty=!0;for(let e of this.listeners)e()}};var Ve=20,vt=200,yt=`
|
|
4
4
|
class MiheCapture extends AudioWorkletProcessor {
|
|
5
5
|
constructor(options) {
|
|
6
6
|
super();
|
|
@@ -43,7 +43,9 @@ class MiheCapture extends AudioWorkletProcessor {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
registerProcessor('mihe-capture', MiheCapture);
|
|
46
|
-
`;function fe(n){let e=new ArrayBuffer(n.length*2),t=new DataView(e);for(let i=0;i<n.length;i+=1){let r=Math.max(-1,Math.min(1,n[i]??0));t.setInt16(i*2,r*32767,!0)}return e}function ee(n){let e=new DataView(n),t=new Float32Array(n.byteLength/2);for(let i=0;i<t.length;i+=1)t[i]=e.getInt16(i*2,!0)/32767;return t}function te(n){let e=ee(n);if(e.length===0)return 0;let t=0;for(let r of e)t+=r*r;let i=Math.sqrt(t/e.length);return Math.min(1,Math.sqrt(i)*1.8)}function bt(n,e,t){if(e===t)return n;let i=e/t,r=Math.floor(n.length/i),s=new Float32Array(r);for(let a=0;a<r;a+=1){let l=a*i,d=Math.floor(l),h=Math.min(d+1,n.length-1),p=l-d;s[a]=(n[d]??0)*(1-p)+(n[h]??0)*p}return s}var P=class{constructor(e){o(this,"onFrame",e);o(this,"context",null);o(this,"stream",null);o(this,"node",null);o(this,"source",null);o(this,"open",!1)}get capturing(){return this.open}async start(){if(this.context){await this.context.resume();return}this.stream=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}});let e=new AudioContext({sampleRate:24e3});this.context=e,this.source=e.createMediaStreamSource(this.stream);let t=i=>{this.open&&this.onFrame(fe(bt(i,e.sampleRate,24e3)))};try{let i=URL.createObjectURL(new Blob([gt],{type:"application/javascript"}));await e.audioWorklet.addModule(i),URL.revokeObjectURL(i);let r=new AudioWorkletNode(e,"mihe-capture",{processorOptions:{frameSamples:Math.round(e.sampleRate*Re/1e3)}});r.port.onmessage=a=>t(a.data),this.source.connect(r);let s=e.createGain();s.gain.value=0,r.connect(s).connect(e.destination),this.node=r}catch{let i=Math.max(256,2**Math.round(Math.log2(e.sampleRate*Re/1e3))),r=e.createScriptProcessor(i,1,1);r.onaudioprocess=s=>t(new Float32Array(s.inputBuffer.getChannelData(0))),this.source.connect(r),r.connect(e.destination),this.node=r}await e.resume()}unmute(){this.open=!0}mute(){this.open=!1}async stop(){this.open=!1,this.node?.disconnect(),this.source?.disconnect(),this.stream?.getTracks().forEach(e=>e.stop()),await this.context?.close().catch(()=>{}),this.node=null,this.source=null,this.stream=null,this.context=null}},O=class{constructor(e){o(this,"onLevel",e);o(this,"levelTimers",new Set);o(this,"context",null);o(this,"gain",null);o(this,"sources",new Set);o(this,"nextStart",0);o(this,"startedAt",0)}async start(){if(this.context){await this.context.resume();return}let e=new AudioContext({sampleRate:24e3});this.gain=e.createGain(),this.gain.connect(e.destination),this.context=e,await e.resume()}enqueue(e){let t=this.context;if(!t||!this.gain)return;let i=ee(e);if(i.length===0)return;let r=t.createBuffer(1,i.length,24e3);r.getChannelData(0).set(i);let s=t.createBufferSource();s.buffer=r,s.connect(this.gain);let a=t.currentTime;if(this.nextStart<a&&(this.nextStart=a+mt/1e3,this.startedAt=this.nextStart),s.start(this.nextStart),this.onLevel){let l=te(e),d=this.onLevel,h=setTimeout(()=>{this.levelTimers.delete(h),d(l)},Math.max(0,(this.nextStart-a)*1e3));this.levelTimers.add(h)}this.nextStart+=r.duration,this.sources.add(s),s.onended=()=>this.sources.delete(s)}heardMs(){if(!this.context||this.startedAt===0)return 0;let e=this.context.currentTime-this.startedAt;return Math.max(0,Math.round(e*1e3))}get speaking(){return this.sources.size>0}flush(){for(let e of this.sources)try{e.stop()}catch{}this.sources.clear(),this.nextStart=0,this.startedAt=0;for(let e of this.levelTimers)clearTimeout(e);this.levelTimers.clear(),this.onLevel?.(0)}async stop(){this.flush(),this.gain?.disconnect(),await this.context?.close().catch(()=>{}),this.gain=null,this.context=null}};var V=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"mic");o(this,"speaker");o(this,"held",null);o(this,"stopped",!1);o(this,"utteranceMs",0);o(this,"assistantLine","");o(this,"playbackTimer",null);o(this,"minUtteranceMs",150);this.speaker=new O(t=>e.onLevel?.("assistant",t)),this.mic=new P(t=>this.sendAudio(t))}get currentState(){return this.state}async start(){if(this.socket)return;this.stopped=!1,this.setState("connecting");try{await this.mic.start(),await this.speaker.start()}catch(i){this.emit({type:"error",code:"microphone_unavailable",message:i instanceof Error&&i.name==="NotAllowedError"?"Microphone access was declined, so voice cannot start.":"No microphone is available.",recoverable:!1,fallbackToChat:!0}),this.setState("error");return}let t=(this.options.socketFactory??(i=>new WebSocket(i)))(this.options.url);t.binaryType="arraybuffer",this.socket=t,t.onmessage=i=>{typeof i.data=="string"?this.handleControl(i.data):i.data instanceof ArrayBuffer&&(this.speaker.enqueue(i.data),this.state==="thinking"&&this.setState("speaking"))},t.onclose=()=>{this.stop()},t.onerror=()=>{}}beginUtterance(e){if(!this.options.handsFree&&!(this.state!=="listening"&&this.state!=="speaking")){if(this.utteranceMs=0,e?.hold){this.held=[],this.mic.unmute(),this.setState("recording");return}this.interruptPlayback(),this.mic.unmute(),this.setState("recording")}}confirmUtterance(){let e=this.held;if(e){this.held=null,this.interruptPlayback();for(let t of e)this.sendAudio(t)}}discardUtterance(){this.held&&(this.held=null,this.mic.mute(),this.utteranceMs=0,this.options.onLevel?.("user",0),this.setState(this.speaker.speaking?"speaking":"listening"))}interruptPlayback(){this.speaker.speaking&&(this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}}),this.speaker.flush())}endUtterance(){if(!this.options.handsFree&&this.state==="recording"){if(this.confirmUtterance(),this.mic.mute(),this.options.onLevel?.("user",0),this.utteranceMs<this.minUtteranceMs){this.emit({type:"error",code:"utterance_too_short",message:"Hold the button while you speak.",recoverable:!0,fallbackToChat:!1}),this.setState("listening");return}this.sendControl({type:"commit"}),this.setState("thinking")}}async stop(){this.stopped||(this.stopped=!0,this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null),this.sendControl({type:"end"}),this.socket?.close(),this.socket=null,await Promise.all([this.mic.stop(),this.speaker.stop()]),this.setState("idle"))}handleControl(e){let t;try{t=JSON.parse(e)}catch{return}switch(t.type){case"ready":this.minUtteranceMs=t.data.minUtteranceMs??this.minUtteranceMs,this.options.handsFree&&this.mic.unmute(),this.setState("listening");break;case"transcript":{let i=t.data.text;t.data.role==="assistant"&&(t.data.final?this.assistantLine="":(this.assistantLine+=i,i=this.assistantLine)),this.emit({type:"transcript",role:t.data.role,text:i,final:t.data.final});break}case"status":t.data.state==="listening"&&this.speaker.speaking&&this.speaker.flush(),t.data.state==="listening"&&(this.assistantLine=""),this.state!=="recording"&&this.setState(t.data.state==="reconnecting"?"connecting":t.data.state);break;case"speech_done":(this.state==="speaking"||this.state==="thinking")&&this.setState("listening");break;case"ending_soon":this.emit({type:"ending_soon",secondsRemaining:t.data.secondsRemaining});break;case"ended":this.emit({type:"ended",reason:t.data.reason,message:t.data.message}),this.stop();break;case"error":this.emit({type:"error",code:t.data.code,message:t.data.message,recoverable:t.data.recoverable,fallbackToChat:t.data.fallbackToChat}),t.data.recoverable||(this.setState("error"),this.stop());break}}sendAudio(e){if(!(!this.options.handsFree&&this.state!=="recording")){if(this.held){this.held.push(e),this.options.onLevel?.("user",te(e));return}this.options.onLevel?.("user",te(e)),this.utteranceMs+=e.byteLength*1e3/(2*24e3);try{this.socket?.send(e)}catch{}}}sendControl(e){try{this.socket?.send(JSON.stringify(e))}catch{}}setState(e){this.state!==e&&(this.state=e,this.reportPlaybackWhileSpeaking(),this.options.onEvent({type:"state",state:e}))}reportPlaybackWhileSpeaking(){if(!(!!this.options.handsFree&&this.state==="speaking")){this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null);return}this.playbackTimer===null&&(this.playbackTimer=setInterval(()=>{this.speaker.speaking&&this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}})},250))}emit(e){this.options.onEvent(e)}};function ie(n,e,t=!1){let i=n.replace(/\/v1\/ws\/?$/,"/v1/voice"),r=i.includes("?")?"&":"?",s=t?"&handsFree=true":"";return`${i}${r}token=${encodeURIComponent(e)}${s}`}var vt=60,Pe=2500,me="0.2.3",K="mihe-panel";function yt(n){return`About ${Math.max(5,Math.round(n/5)*5)} seconds left of voice. The conversation carries on in text.`}function Oe(n){return`${n}_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function Ve(n){let e=new F(n);return e.connect(),e}var F=class{constructor(e){o(this,"store",new R);o(this,"highlighter",new L);o(this,"options");o(this,"state");o(this,"listeners",new Set);o(this,"client",null);o(this,"voiceSession",null);o(this,"voiceRequested",!1);o(this,"requestedHandsFree",!1);o(this,"requestedOpenPanel",!0);o(this,"levelListeners",new Set);o(this,"publishedRoute",null);o(this,"publishedScreen",null);o(this,"publishedSettled",!1);o(this,"screenWaiters",new Set);o(this,"publishTimer",null);o(this,"unsubscribeStore",null);o(this,"tabs",new Map);o(this,"tables",new Map);o(this,"charts",new Map);o(this,"actions",new Map);o(this,"lastScreen",null);o(this,"getState",()=>this.state);o(this,"subscribe",e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}));o(this,"send",e=>{let t=e.trim();if(!t)return;let i=Oe("msg");this.setState({isOpen:!0,messages:[...this.state.messages,{id:i,role:"user",text:t}],lastError:null}),this.client?.sendMessage(t,i)});o(this,"respondToProposal",(e,t)=>{this.client?.confirmAction(e,t),t||this.setState({proposals:this.state.proposals.filter(i=>i.proposalId!==e)})});o(this,"open",()=>{this.state.isOpen||this.setState({isOpen:!0})});o(this,"close",()=>{this.state.isOpen&&this.setState({isOpen:!1})});o(this,"toggle",()=>{this.setState({isOpen:!this.state.isOpen})});o(this,"handleEvent",e=>{switch(e.type){case"state":this.setState({connection:e.state}),this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=null,this.publish();break;case"turn_start":this.setState({busy:!0,messages:[...this.state.messages,{id:e.turnId,role:"assistant",text:"",streaming:!0}]});break;case"delta":this.setMessages(t=>t.map(i=>i.id===e.turnId?{...i,text:i.text+e.text}:i));break;case"complete":this.setState({busy:!1,messages:this.state.messages.map(t=>t.id===e.turnId?{...t,text:e.message,streaming:!1,sources:e.sources.length?e.sources:void 0}:t)});break;case"command":{let t={store:this.store,highlighter:this.highlighter,navigate:this.options.navigate??(r=>{window.location.assign(r)}),screenPublished:this.awaitScreenPublished,viewPublished:this.awaitViewPublished,openModal:this.options.openModal},i=this.client;j(e.command,t).then(r=>i?.ackCommand(e.commandId,r.ok,r.result,r.error)).catch(r=>i?.ackCommand(e.commandId,!1,void 0,r instanceof Error?r.message:"The command failed."));break}case"proposal":this.setState({proposals:[...this.state.proposals,e.proposal]}),this.describe(e.proposal);break;case"action_status":{if(e.status==="executing")break;let t=this.state.proposals.find(i=>i.proposalId===e.proposalId);if(t){let i=`status_${e.proposalId}`;if(e.status!=="rejected"&&!this.state.messages.some(r=>r.id===i)){let r=e.status==="executed"?`${t.label} \u2014 done.`:`${t.label} \u2014 ${e.error??"that did not work."}`;this.setMessages(s=>[...s,{id:i,role:"assistant",text:r}])}this.options.onActionComplete?.({actionName:t.actionName,status:e.status,result:e.result})}this.setState({proposals:this.state.proposals.filter(i=>i.proposalId!==e.proposalId),...e.error?{lastError:e.error}:{}});break}case"voice_available":this.setVoice({available:e.available});break;case"assistant_name":this.setState({assistantName:e.name});break;case"launcher_icon":this.setState({launcherIconUrl:e.url});break;case"widget_settings":this.setState({widgetSettings:e.settings});break;case"context_report":console.info(Q(e.report));break;case"voice_token":if(!this.voiceRequested)break;this.voiceRequested=!1,this.startVoice(e.token);break;case"error":if(e.code.startsWith("voice_")){this.voiceRequested=!1,this.setState({busy:!1,voice:{...this.state.voice,available:!1}});break}this.setState({busy:!1,lastError:e.message});break}});o(this,"publish",()=>{this.publishTimer=null;let e=this.store.getScreenContext();if(!(!e&&this.publishedRoute===null)&&(this.client?.updateScreen(e),this.publishedRoute=e?.route??null,this.publishedScreen=e,this.publishedSettled=!this.store.isScreenLoading(),!(!e||!this.publishedSettled)))for(let t of[...this.screenWaiters])t(e)});o(this,"awaitScreenPublished",(e,t)=>new Promise(i=>{let r=e.split("?")[0];if(!t?.fresh&&this.publishedRoute===r&&this.publishedSettled)return i(!0);let s=d=>{this.screenWaiters.delete(a),clearTimeout(l),i(d)},a=d=>{d.route===r&&s(!0)},l=setTimeout(()=>s(!1),Pe);this.screenWaiters.add(a)}));o(this,"awaitViewPublished",(e,t)=>new Promise(i=>{let r=d=>d?.controls.some(h=>h.controlKey===e&&h.value===t)??!1;if(this.publishedSettled&&r(this.publishedScreen))return i(!0);let s=d=>{this.screenWaiters.delete(a),clearTimeout(l),i(d)},a=d=>{r(d)&&s(!0)},l=setTimeout(()=>s(!1),Pe);this.screenWaiters.add(a)}));o(this,"startVoiceRequest",e=>{this.setVoice({notice:null}),this.requestedHandsFree=!!e?.handsFree,this.requestedOpenPanel=e?.openPanel??!0,this.voiceRequested=!0,this.client?.requestVoiceToken()});o(this,"stopVoice",()=>{this.voiceRequested=!1,this.voiceSession?.stop(),this.voiceSession=null,this.setVoice({handsFree:!1,notice:null})});o(this,"handleVoiceEvent",e=>{switch(e.type){case"state":this.setVoice({state:e.state,...e.state==="idle"||e.state==="error"?{caption:""}:{}});break;case"transcript":e.final?this.setState({voice:{...this.state.voice,caption:""},messages:[...this.state.messages,{id:Oe("voice"),role:e.role,text:e.text}]}):this.setVoice({caption:e.text});break;case"ending_soon":this.setVoice({notice:yt(e.secondsRemaining)});break;case"ended":this.setVoice({caption:"",notice:e.message,handsFree:!1});break;case"error":this.setState({lastError:e.message});break}});this.options={...e},this.state={connection:"idle",messages:[],proposals:[],cardViews:{},busy:!1,lastError:null,isOpen:!1,assistantName:null,launcherIconUrl:null,widgetSettings:null,voice:{available:!1,state:"idle",handsFree:!1,caption:"",notice:null,start:this.startVoiceRequest,stop:this.stopVoice,press:t=>this.voiceSession?.beginUtterance(t),release:()=>this.voiceSession?.endUtterance(),confirm:()=>this.voiceSession?.confirmUtterance(),discard:()=>this.voiceSession?.discardUtterance(),onLevel:t=>(this.levelListeners.add(t),()=>{this.levelListeners.delete(t)})}}}get voice(){return this.state.voice}setState(e){this.state={...this.state,...e};for(let t of[...this.listeners])t()}setVoice(e){this.setState({voice:{...this.state.voice,...e}})}setMessages(e){this.setState({messages:e(this.state.messages)})}update(e){let t=this.options;this.options={...t,...e},(this.options.url!==t.url||this.options.publicKey!==t.publicKey||!!this.options.debug!=!!t.debug)&&this.client&&(this.disconnect(),this.connect())}connect(){if(this.client)return;let e=new I({url:this.options.url,publicKey:this.options.publicKey,getUserToken:()=>this.options.getUserToken(),sdkVersion:me,onEvent:this.handleEvent,debug:this.options.debug??!1});this.client=e,this.unsubscribeStore=this.store.subscribe(()=>{this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=setTimeout(this.publish,vt)}),this.publish(),e.connect()}disconnect(){this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=null,this.unsubscribeStore?.(),this.unsubscribeStore=null,this.client?.close(),this.client=null,this.voiceSession?.stop(),this.voiceSession=null,this.highlighter.clear()}destroy(){this.disconnect(),this.listeners.clear(),this.levelListeners.clear()}describe(e){let t=l=>{l!=="pending"&&!this.state.proposals.some(d=>d.proposalId===e.proposalId)||this.setState({cardViews:{...this.state.cardViews,[e.proposalId]:l}})},i=this.options.describeProposal;if(!i){t(C(e));return}t("pending");let r=!1,s=l=>{r||(r=!0,t(l&&Array.isArray(l.lines)?W(l):C(e)))},a=setTimeout(()=>s(null),z);Promise.resolve().then(()=>i(e)).then(l=>{clearTimeout(a),s(l)}).catch(l=>{clearTimeout(a),console.warn("[mihe] describeProposal failed; the card uses the registry's hints.",l),s(null)})}prompt(e){return()=>this.send(e)}setScreen(e){let t=JSON.stringify(e);return(t!==this.lastScreen||this.store.getScreenContext()?.screenId!==e.screenId)&&(this.lastScreen=t,this.store.setScreen(JSON.parse(t))),()=>{this.store.clearScreen(e.screenId),this.store.getScreenContext()===null&&(this.lastScreen=null)}}registerComponent(e,t,i){return e?.setAttribute(M,t),this.store.registerComponent(t,{...i}),()=>{this.store.unregisterComponent(t),e?.getAttribute(M)===t&&e.removeAttribute(M)}}registerAction(e,t){let i=this.actions.get(e);if(i&&this.store.getAction(e)===i.declaration)return i.latest=t,()=>this.undoAction(e,i);let r={latest:t,signature:e,declaration:{name:e,handler:s=>r.latest(s)}};return this.actions.set(e,r),this.store.registerAction(r.declaration),()=>this.undoAction(e,r)}undoAction(e,t){this.actions.get(e)===t&&(this.actions.delete(e),this.store.getAction(e)===t.declaration&&this.store.unregisterAction(e))}registerTabs(e){return this.declare(this.tabs,e.id,e,Y(e),t=>G(t),t=>this.store.getControl(t),(t,i)=>this.store.registerControl(t,i),t=>this.store.unregisterControl(t))}registerTable(e){return this.declare(this.tables,e.id,e,J(e),t=>X(t),t=>this.store.getTable(t),(t,i)=>this.store.registerTable(t,i),t=>this.store.unregisterTable(t))}registerChart(e){return this.declare(this.charts,e.id,e,Z(e),t=>H(t),t=>this.store.getChart(t),(t,i)=>this.store.registerChart(t,i),t=>this.store.unregisterChart(t))}setValues(e,t){return this.store.setValues(e,JSON.parse(JSON.stringify(t))),()=>this.store.clearValues(e)}declare(e,t,i,r,s,a,l,d){let h=e.get(t);if(h&&a(t)===h.declaration){if(h.latest=i,h.signature!==r){let u=h;h.signature=r,h.declaration=s(()=>u.latest),l(t,h.declaration)}}else{let u={latest:i,signature:r};u.declaration=s(()=>u.latest),e.set(t,u),l(t,u.declaration),h=u}let p=h;return()=>{e.get(t)===p&&(e.delete(t),a(t)===p.declaration&&d(t))}}bindTrigger(e){let t=e instanceof HTMLButtonElement,i=["aria-expanded","aria-controls","aria-haspopup"];t||(e.setAttribute("role","button"),i.push("role"),e.hasAttribute("tabindex")||(e.setAttribute("tabindex","0"),i.push("tabindex"))),e.setAttribute("aria-controls",K),e.setAttribute("aria-haspopup","dialog");let r=()=>e.setAttribute("aria-expanded",String(this.state.isOpen)),s=()=>this.toggle(),a=d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),this.toggle())};r();let l=this.subscribe(r);return e.addEventListener("click",s),t||e.addEventListener("keydown",a),()=>{l(),e.removeEventListener("click",s),e.removeEventListener("keydown",a);for(let d of i)e.removeAttribute(d)}}async startVoice(e){let t=this.requestedHandsFree;this.setVoice({handsFree:t});let i=new V({url:ie(this.options.url,e,t),handsFree:t,onEvent:this.handleVoiceEvent,onLevel:(r,s)=>{for(let a of this.levelListeners)a(r,s)}});this.voiceSession=i,this.requestedOpenPanel&&this.open(),await i.start()}};function c(n,e={},...t){let i=document.createElement(n);e.class&&(i.className=e.class),A(i,e.attrs??{});for(let[r,s]of Object.entries(e.on??{}))i.addEventListener(r,s);return _e(i,t),i}var xt="http://www.w3.org/2000/svg";function y(n,e,...t){let i=document.createElementNS(xt,n);for(let[r,s]of Object.entries(e))i.setAttribute(r,String(s));for(let r of t)i.appendChild(r);return i}function A(n,e){for(let[t,i]of Object.entries(e))i===void 0||i===!1?n.removeAttribute(t):n.setAttribute(t,i===!0?"":String(i))}function _e(n,e){for(let t of e)t==null||t===!1||n.appendChild(typeof t=="string"?document.createTextNode(t):t)}function x(n,...e){for(;n.firstChild;)n.removeChild(n.firstChild);_e(n,e)}var Ne="translate(0.000000,1760.000000) scale(0.100000,-0.100000)",wt="M8165 16868 c-450 -31 -1057 -131 -1495 -248 -76 -20 -156 -42 -180 -50 -14 -5 -50 -15 -80 -24 -146 -41 -273 -82 -360 -117 -25 -9 -74 -27 -110 -39 -36 -12 -74 -25 -85 -30 -11 -4 -40 -15 -65 -25 -25 -10 -54 -21 -65 -26 -11 -4 -85 -35 -165 -67 -218 -90 -530 -238 -715 -340 -38 -21 -106 -58 -150 -82 -44 -24 -108 -61 -143 -82 -34 -21 -65 -38 -68 -38 -2 0 -17 -8 -32 -19 -15 -10 -52 -34 -82 -53 -1161 -733 -2106 -1735 -2771 -2935 -74 -134 -219 -425 -219 -440 0 -4 -10 -24 -23 -43 -13 -19 -34 -60 -46 -90 -13 -30 -35 -80 -48 -110 -49 -112 -56 -127 -91 -220 -16 -41 -32 -84 -37 -95 -45 -114 -195 -563 -238 -715 -26 -88 -58 -212 -67 -255 -5 -22 -16 -69 -25 -105 -19 -78 -66 -317 -89 -455 -140 -836 -144 -1701 -11 -2525 9 -52 20 -122 25 -155 9 -53 17 -97 51 -262 16 -78 80 -337 105 -423 74 -256 219 -700 264 -810 26 -63 55 -135 79 -192 6 -13 24 -54 40 -91 17 -38 31 -70 31 -72 0 -3 105 -221 203 -425 39 -79 80 -154 128 -233 16 -26 29 -50 29 -52 0 -3 37 -65 82 -138 45 -72 88 -143 95 -157 64 -113 285 -440 339 -500 12 -14 43 -56 70 -95 42 -63 164 -220 221 -285 12 -14 36 -43 55 -66 250 -310 644 -706 1038 -1045 68 -59 396 -310 514 -395 88 -63 522 -341 596 -382 19 -10 80 -45 135 -77 120 -69 571 -298 670 -339 39 -16 107 -47 153 -68 46 -21 87 -38 93 -38 5 0 17 -4 27 -10 25 -13 78 -35 157 -63 39 -14 120 -43 180 -65 222 -82 417 -145 565 -183 41 -10 91 -23 110 -29 134 -37 514 -119 645 -139 836 -130 1685 -150 2385 -57 63 8 151 20 195 26 44 6 100 15 125 20 25 5 88 17 140 25 286 49 729 160 1015 256 198 67 349 119 370 129 11 6 72 30 135 54 63 24 142 56 175 71 103 46 118 52 183 79 53 22 224 108 572 287 750 385 1586 1059 2290 1844 219 244 499 612 666 873 32 52 91 144 131 205 91 141 268 456 366 652 87 172 167 341 167 350 0 4 6 21 14 38 56 124 212 529 241 627 9 30 21 64 26 75 4 11 16 45 25 75 9 30 25 82 36 115 54 166 146 535 178 710 82 461 106 640 137 1030 20 252 23 814 5 1015 -6 74 -17 191 -23 260 -12 141 -34 328 -49 410 -5 30 -16 100 -25 155 -9 55 -26 145 -37 200 -11 55 -24 118 -28 140 -4 22 -16 72 -25 110 -9 39 -20 86 -24 105 -203 889 -617 1816 -1181 2640 -141 205 -236 333 -350 470 -52 63 -113 138 -135 165 -203 255 -745 786 -1035 1016 -58 45 -138 109 -179 142 -228 181 -749 524 -1006 662 -49 26 -115 62 -145 78 -71 38 -346 176 -430 215 -138 64 -201 92 -206 92 -3 0 -35 14 -71 30 -35 17 -70 30 -77 30 -6 0 -16 4 -21 8 -9 8 -216 87 -387 148 -38 13 -98 35 -135 49 -38 13 -102 34 -143 45 -41 12 -97 28 -125 36 -180 53 -464 125 -610 154 -165 33 -214 43 -240 47 -16 2 -66 10 -110 18 -328 56 -573 84 -755 88 l-125 2 0 -515 0 -515 190 -21 c105 -12 242 -29 305 -39 63 -10 138 -21 165 -26 123 -18 192 -30 225 -39 19 -5 62 -14 95 -20 233 -44 615 -154 905 -260 47 -17 105 -38 130 -47 25 -8 59 -21 75 -28 17 -7 93 -39 170 -71 418 -173 867 -425 1345 -757 747 -518 1525 -1379 1970 -2182 18 -33 41 -73 50 -90 64 -116 84 -152 123 -231 25 -49 57 -118 72 -154 15 -36 36 -85 47 -110 42 -93 56 -127 78 -180 12 -30 26 -64 31 -75 61 -146 144 -376 194 -540 15 -49 31 -101 36 -115 9 -26 46 -175 74 -295 8 -38 20 -86 25 -105 15 -58 45 -214 80 -425 24 -141 62 -499 79 -745 34 -482 -17 -1111 -134 -1655 -14 -66 -30 -140 -35 -165 -8 -38 -22 -93 -65 -260 -28 -107 -86 -292 -127 -405 -59 -164 -118 -318 -128 -337 -6 -10 -10 -22 -10 -27 0 -6 -18 -49 -40 -96 -22 -47 -40 -88 -40 -90 0 -27 -247 -518 -314 -624 -14 -22 -26 -43 -26 -45 0 -37 -381 -596 -565 -829 -225 -283 -622 -706 -875 -929 -155 -137 -228 -198 -237 -198 -9 0 -127 185 -183 285 -12 22 -28 47 -35 55 -7 8 -32 49 -55 90 -24 41 -76 125 -115 185 -40 61 -123 195 -186 298 -63 103 -126 207 -141 230 -15 23 -31 49 -35 57 -3 8 -16 29 -27 45 -12 17 -26 39 -33 50 -7 11 -33 54 -59 95 -67 106 -620 996 -1072 1725 -58 94 -129 206 -158 251 -29 45 -65 103 -80 130 -15 27 -55 92 -89 144 -88 134 -280 445 -400 645 -56 94 -163 269 -239 389 -75 121 -135 224 -134 228 2 5 35 54 73 109 403 577 447 641 713 1032 134 197 262 399 262 413 0 8 -36 85 -79 172 -44 86 -142 285 -219 442 -77 157 -244 497 -372 755 -128 259 -297 601 -375 760 -78 160 -220 448 -315 640 -95 193 -264 535 -376 760 -400 810 -543 1101 -566 1155 -14 30 -33 74 -43 98 -17 39 -55 61 -55 31 0 -6 -35 -83 -79 -172 -43 -89 -106 -218 -139 -287 -68 -142 -323 -661 -607 -1235 -106 -214 -271 -550 -368 -745 -225 -457 -457 -927 -747 -1515 -363 -735 -420 -852 -420 -862 0 -10 166 -267 241 -373 21 -30 95 -138 164 -240 68 -102 160 -237 204 -300 80 -115 147 -212 296 -430 43 -63 93 -135 112 -159 42 -56 42 -57 -11 -134 -24 -35 -58 -90 -76 -122 -29 -52 -66 -114 -107 -180 -7 -11 -20 -33 -29 -50 -9 -16 -45 -73 -79 -125 -34 -52 -74 -117 -89 -145 -16 -27 -34 -57 -42 -66 -8 -8 -14 -19 -14 -23 0 -4 -10 -22 -23 -39 -12 -18 -28 -41 -34 -52 -7 -11 -33 -54 -59 -95 -26 -41 -58 -95 -72 -120 -13 -25 -35 -58 -47 -75 -21 -29 -238 -378 -619 -995 -96 -157 -210 -339 -252 -405 -104 -164 -269 -429 -343 -550 -33 -55 -92 -149 -131 -210 -38 -60 -78 -126 -90 -145 -11 -19 -25 -42 -30 -50 -5 -8 -44 -71 -86 -140 -42 -69 -104 -168 -138 -220 -34 -53 -66 -104 -73 -115 -6 -11 -76 -123 -155 -249 -79 -126 -145 -234 -147 -240 -2 -6 -21 -36 -41 -66 -76 -112 -170 -260 -170 -267 0 -5 -14 -24 -30 -43 -29 -35 -29 -35 -82 16 -29 28 -91 84 -138 124 -567 490 -1171 1224 -1508 1832 -47 85 -232 451 -274 543 -20 44 -53 115 -72 158 -20 42 -36 80 -36 83 0 3 -6 20 -14 37 -20 47 -40 99 -85 222 -79 217 -90 252 -140 420 -49 167 -85 311 -141 558 -120 534 -163 1390 -99 1962 41 369 37 343 84 595 48 260 75 373 159 683 39 143 224 654 286 792 110 242 174 371 314 630 563 1039 1532 2008 2644 2642 68 38 455 233 532 267 131 58 397 168 465 192 108 39 384 130 445 148 30 8 87 25 125 36 316 96 789 185 1190 225 94 9 176 20 183 24 12 5 16 287 12 1022 0 13 -27 15 -135 7z m660 -4508 c4 -16 11 -32 16 -35 5 -4 9 -12 9 -20 0 -8 19 -53 41 -102 71 -151 106 -226 129 -278 12 -27 39 -86 60 -130 21 -44 52 -111 70 -150 17 -38 44 -97 60 -130 15 -33 35 -76 43 -95 8 -19 31 -69 50 -110 62 -134 89 -194 107 -240 10 -25 46 -103 80 -175 90 -190 106 -224 133 -285 49 -108 70 -156 97 -215 15 -33 37 -82 50 -110 12 -27 40 -87 61 -133 40 -83 40 -83 6 -140 -19 -31 -50 -86 -69 -122 -65 -120 -91 -165 -140 -242 -26 -43 -48 -80 -48 -83 0 -2 -17 -33 -38 -67 -21 -35 -41 -70 -45 -78 -4 -8 -11 -22 -17 -30 -34 -54 -110 -181 -110 -185 0 -3 -11 -23 -25 -45 -14 -22 -46 -80 -72 -128 -25 -48 -54 -98 -63 -112 -41 -58 -150 -263 -150 -280 0 -10 15 -47 33 -82 62 -117 120 -223 128 -234 5 -6 48 -87 95 -180 47 -93 90 -173 94 -179 4 -5 27 -46 50 -90 23 -44 67 -127 98 -185 30 -58 59 -110 63 -116 11 -14 72 -130 111 -209 37 -77 56 -114 103 -200 142 -264 186 -348 323 -615 63 -124 128 -250 145 -280 33 -59 82 -154 250 -480 58 -113 129 -250 157 -305 96 -182 151 -288 268 -515 63 -124 135 -263 160 -310 24 -47 118 -229 207 -405 170 -333 225 -440 277 -534 17 -31 112 -216 211 -411 99 -195 188 -372 199 -393 11 -22 18 -40 16 -42 -10 -11 -431 -215 -443 -215 -2 0 -36 -15 -77 -34 -40 -18 -109 -48 -153 -66 -44 -18 -93 -38 -110 -45 -16 -7 -75 -29 -130 -50 -55 -20 -116 -43 -135 -50 -39 -14 -282 -90 -345 -107 -22 -6 -60 -16 -85 -24 -61 -17 -216 -55 -265 -64 -22 -4 -85 -17 -140 -28 -165 -33 -277 -52 -513 -87 -183 -27 -182 -27 -182 78 0 34 -4 98 -10 142 -5 44 -14 141 -20 215 -24 285 -30 360 -45 530 -9 96 -20 229 -25 295 -5 66 -17 206 -25 310 -9 105 -20 249 -25 320 -5 72 -12 148 -15 170 -3 22 -10 105 -15 185 -5 80 -17 228 -25 330 -9 102 -20 237 -24 300 -5 63 -19 225 -30 360 -11 135 -27 335 -36 445 -30 392 -37 461 -50 510 -8 28 -26 97 -41 155 -14 58 -37 146 -50 195 -41 154 -55 209 -64 245 -9 33 -23 89 -55 205 -7 28 -25 100 -40 160 -24 98 -49 196 -61 233 -8 27 -28 5 -40 -44 -6 -27 -24 -94 -38 -149 -15 -55 -43 -161 -62 -235 -20 -74 -49 -187 -65 -250 -17 -63 -39 -151 -50 -195 -23 -92 -39 -157 -69 -270 -30 -113 -36 -170 -75 -720 -8 -110 -21 -276 -30 -370 -8 -93 -19 -226 -25 -295 -5 -69 -12 -143 -15 -165 -3 -22 -10 -105 -16 -185 -24 -330 -41 -552 -59 -745 -22 -237 -31 -345 -40 -460 -5 -66 -16 -201 -25 -300 -8 -99 -19 -234 -25 -300 -15 -193 -40 -482 -50 -590 -5 -55 -9 -106 -10 -112 0 -18 -71 -17 -184 2 -50 9 -122 20 -161 26 -108 16 -241 39 -345 61 -52 11 -113 24 -135 28 -52 11 -235 56 -300 75 -27 7 -75 20 -106 29 -62 17 -397 127 -444 146 -16 7 -39 16 -50 21 -11 5 -56 22 -100 39 -214 82 -663 292 -724 339 -23 18 -23 18 62 182 46 90 130 252 185 359 55 107 121 236 147 285 26 50 100 194 165 320 64 127 146 286 182 355 36 69 100 193 143 275 43 83 106 204 140 270 34 66 109 210 165 320 108 211 202 391 280 540 26 50 70 133 97 185 28 52 112 217 188 365 76 149 141 275 145 280 4 6 54 100 110 210 57 110 123 238 148 285 25 47 63 119 85 160 22 41 71 133 110 205 39 71 107 202 152 290 45 88 91 177 103 197 12 21 37 66 55 100 19 35 51 95 72 133 238 435 243 447 218 497 -34 66 -100 186 -137 247 -19 31 -43 72 -53 91 -65 116 -87 155 -142 248 -34 57 -61 106 -61 108 0 2 -10 21 -23 42 -13 20 -44 75 -69 122 -25 47 -73 132 -107 188 -33 57 -61 106 -61 108 0 2 -29 52 -65 110 -68 111 -74 132 -51 180 26 52 103 218 126 269 13 28 41 88 62 135 22 47 54 114 70 150 48 104 78 169 124 267 24 51 44 98 44 103 0 6 4 18 10 28 13 22 90 192 90 198 0 2 23 52 51 112 54 112 81 171 205 440 19 41 34 76 34 78 0 3 15 37 34 77 18 40 43 95 56 122 12 28 43 93 67 145 25 52 49 105 54 117 12 32 36 28 44 -7z",kt="M4399 12732 c-37 -42 -101 -117 -143 -166 -123 -145 -496 -679 -496 -712 0 -2 -18 -34 -41 -71 -100 -164 -271 -530 -369 -793 -17 -47 -36 -96 -42 -110 -35 -86 -134 -426 -172 -595 -50 -218 -49 -218 -81 -445 -85 -598 -74 -1269 30 -1820 8 -47 20 -107 24 -135 11 -60 68 -292 87 -355 8 -25 21 -67 29 -95 23 -79 72 -227 85 -260 7 -16 16 -39 20 -50 34 -90 73 -186 108 -265 11 -25 30 -70 43 -100 45 -106 197 -400 256 -493 14 -22 36 -60 50 -85 97 -175 409 -612 437 -612 6 0 85 66 176 147 91 80 199 176 240 212 41 36 100 89 130 117 30 29 73 67 95 86 123 107 120 82 23 209 -209 275 -459 726 -589 1064 -112 292 -165 474 -219 750 -19 96 -26 136 -50 287 -70 444 -45 1047 65 1543 9 39 20 88 24 110 149 680 553 1448 1043 1980 15 17 28 33 28 36 0 11 -703 699 -714 699 -6 0 -41 -35 -77 -78z M12835 12532 c-154 -152 -313 -307 -354 -344 -84 -76 -85 -63 16 -174 227 -250 460 -601 637 -959 70 -144 93 -192 130 -280 10 -22 21 -49 26 -60 5 -11 16 -42 25 -70 10 -27 21 -59 26 -70 23 -55 77 -234 112 -370 45 -175 56 -227 78 -345 24 -127 27 -151 58 -425 26 -231 28 -544 6 -780 -17 -180 -30 -267 -85 -570 -9 -47 -39 -165 -89 -350 -23 -83 -54 -178 -76 -230 -7 -16 -19 -48 -28 -70 -144 -374 -335 -726 -576 -1060 -56 -77 -100 -145 -99 -151 2 -5 68 -68 148 -140 80 -71 172 -154 205 -185 138 -128 375 -329 388 -329 23 0 437 582 437 614 0 3 16 30 35 60 62 98 305 576 305 601 0 3 14 35 31 72 54 117 135 338 174 478 124 434 155 590 214 1065 67 536 5 1382 -141 1930 -11 41 -24 89 -28 105 -24 91 -128 414 -175 543 -34 95 -127 306 -196 447 -145 295 -273 511 -475 795 -154 217 -416 530 -443 530 -3 0 -132 -125 -286 -278z";function $e(n,e,t){let i=y("svg",{viewBox:"0 0 1760 1760",width:n,height:n,"aria-hidden":"true",focusable:"false"},y("path",{fill:e,"fill-rule":"evenodd",transform:Ne,d:wt}),y("path",{fill:t,"fill-rule":"evenodd",transform:Ne,d:kt}));return i.style.display="block",i}var ge="#221f1b",ne="#eae7e4",re="#5ac8cd",He=`
|
|
46
|
+
`;function ge(n){let e=new ArrayBuffer(n.length*2),t=new DataView(e);for(let i=0;i<n.length;i+=1){let r=Math.max(-1,Math.min(1,n[i]??0));t.setInt16(i*2,r*32767,!0)}return e}function ee(n){let e=new DataView(n),t=new Float32Array(n.byteLength/2);for(let i=0;i<t.length;i+=1)t[i]=e.getInt16(i*2,!0)/32767;return t}function te(n){let e=ee(n);if(e.length===0)return 0;let t=0;for(let r of e)t+=r*r;let i=Math.sqrt(t/e.length);return Math.min(1,Math.sqrt(i)*1.8)}function xt(n,e,t){if(e===t)return n;let i=e/t,r=Math.floor(n.length/i),s=new Float32Array(r);for(let l=0;l<r;l+=1){let a=l*i,d=Math.floor(a),h=Math.min(d+1,n.length-1),p=a-d;s[l]=(n[d]??0)*(1-p)+(n[h]??0)*p}return s}var P=class{constructor(e){o(this,"onFrame",e);o(this,"context",null);o(this,"stream",null);o(this,"node",null);o(this,"source",null);o(this,"open",!1)}get capturing(){return this.open}async start(){if(this.context){await this.context.resume();return}this.stream=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}});let e=new AudioContext({sampleRate:24e3});this.context=e,this.source=e.createMediaStreamSource(this.stream);let t=i=>{this.open&&this.onFrame(ge(xt(i,e.sampleRate,24e3)))};try{let i=URL.createObjectURL(new Blob([yt],{type:"application/javascript"}));await e.audioWorklet.addModule(i),URL.revokeObjectURL(i);let r=new AudioWorkletNode(e,"mihe-capture",{processorOptions:{frameSamples:Math.round(e.sampleRate*Ve/1e3)}});r.port.onmessage=l=>t(l.data),this.source.connect(r);let s=e.createGain();s.gain.value=0,r.connect(s).connect(e.destination),this.node=r}catch{let i=Math.max(256,2**Math.round(Math.log2(e.sampleRate*Ve/1e3))),r=e.createScriptProcessor(i,1,1);r.onaudioprocess=s=>t(new Float32Array(s.inputBuffer.getChannelData(0))),this.source.connect(r),r.connect(e.destination),this.node=r}await e.resume()}unmute(){this.open=!0}mute(){this.open=!1}async stop(){this.open=!1,this.node?.disconnect(),this.source?.disconnect(),this.stream?.getTracks().forEach(e=>e.stop()),await this.context?.close().catch(()=>{}),this.node=null,this.source=null,this.stream=null,this.context=null}},O=class{constructor(e){o(this,"onLevel",e);o(this,"levelTimers",new Set);o(this,"context",null);o(this,"gain",null);o(this,"sources",new Set);o(this,"nextStart",0);o(this,"startedAt",0)}async start(){if(this.context){await this.context.resume();return}let e=new AudioContext({sampleRate:24e3});this.gain=e.createGain(),this.gain.connect(e.destination),this.context=e,await e.resume()}enqueue(e){let t=this.context;if(!t||!this.gain)return;let i=ee(e);if(i.length===0)return;let r=t.createBuffer(1,i.length,24e3);r.getChannelData(0).set(i);let s=t.createBufferSource();s.buffer=r,s.connect(this.gain);let l=t.currentTime;if(this.nextStart<l&&(this.nextStart=l+vt/1e3,this.startedAt=this.nextStart),s.start(this.nextStart),this.onLevel){let a=te(e),d=this.onLevel,h=setTimeout(()=>{this.levelTimers.delete(h),d(a)},Math.max(0,(this.nextStart-l)*1e3));this.levelTimers.add(h)}this.nextStart+=r.duration,this.sources.add(s),s.onended=()=>this.sources.delete(s)}heardMs(){if(!this.context||this.startedAt===0)return 0;let e=this.context.currentTime-this.startedAt;return Math.max(0,Math.round(e*1e3))}get speaking(){return this.sources.size>0}flush(){for(let e of this.sources)try{e.stop()}catch{}this.sources.clear(),this.nextStart=0,this.startedAt=0;for(let e of this.levelTimers)clearTimeout(e);this.levelTimers.clear(),this.onLevel?.(0)}async stop(){this.flush(),this.gain?.disconnect(),await this.context?.close().catch(()=>{}),this.gain=null,this.context=null}};var _=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"mic");o(this,"speaker");o(this,"held",null);o(this,"stopped",!1);o(this,"utteranceMs",0);o(this,"assistantLine","");o(this,"playbackTimer",null);o(this,"minUtteranceMs",150);this.speaker=new O(t=>e.onLevel?.("assistant",t)),this.mic=new P(t=>this.sendAudio(t))}get currentState(){return this.state}async start(){if(this.socket)return;this.stopped=!1,this.setState("connecting");try{await this.mic.start(),await this.speaker.start()}catch(i){this.emit({type:"error",code:"microphone_unavailable",message:i instanceof Error&&i.name==="NotAllowedError"?"Microphone access was declined, so voice cannot start.":"No microphone is available.",recoverable:!1,fallbackToChat:!0}),this.setState("error");return}let t=(this.options.socketFactory??(i=>new WebSocket(i)))(this.options.url);t.binaryType="arraybuffer",this.socket=t,t.onmessage=i=>{typeof i.data=="string"?this.handleControl(i.data):i.data instanceof ArrayBuffer&&(this.speaker.enqueue(i.data),this.state==="thinking"&&this.setState("speaking"))},t.onclose=()=>{this.stop()},t.onerror=()=>{}}beginUtterance(e){if(!this.options.handsFree&&!(this.state!=="listening"&&this.state!=="speaking")){if(this.utteranceMs=0,e?.hold){this.held=[],this.mic.unmute(),this.setState("recording");return}this.interruptPlayback(),this.mic.unmute(),this.setState("recording")}}confirmUtterance(){let e=this.held;if(e){this.held=null,this.interruptPlayback();for(let t of e)this.sendAudio(t)}}discardUtterance(){this.held&&(this.held=null,this.mic.mute(),this.utteranceMs=0,this.options.onLevel?.("user",0),this.setState(this.speaker.speaking?"speaking":"listening"))}interruptPlayback(){this.speaker.speaking&&(this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}}),this.speaker.flush())}endUtterance(){if(!this.options.handsFree&&this.state==="recording"){if(this.confirmUtterance(),this.mic.mute(),this.options.onLevel?.("user",0),this.utteranceMs<this.minUtteranceMs){this.emit({type:"error",code:"utterance_too_short",message:"Hold the button while you speak.",recoverable:!0,fallbackToChat:!1}),this.setState("listening");return}this.sendControl({type:"commit"}),this.setState("thinking")}}async stop(){this.stopped||(this.stopped=!0,this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null),this.sendControl({type:"end"}),this.socket?.close(),this.socket=null,await Promise.all([this.mic.stop(),this.speaker.stop()]),this.setState("idle"))}handleControl(e){let t;try{t=JSON.parse(e)}catch{return}switch(t.type){case"ready":this.minUtteranceMs=t.data.minUtteranceMs??this.minUtteranceMs,this.options.handsFree&&this.mic.unmute(),this.setState("listening");break;case"transcript":{let i=t.data.text;t.data.role==="assistant"&&(t.data.final?this.assistantLine="":(this.assistantLine+=i,i=this.assistantLine)),this.emit({type:"transcript",role:t.data.role,text:i,final:t.data.final});break}case"status":t.data.state==="listening"&&this.speaker.speaking&&this.speaker.flush(),t.data.state==="listening"&&(this.assistantLine=""),this.state!=="recording"&&this.setState(t.data.state==="reconnecting"?"connecting":t.data.state);break;case"speech_done":(this.state==="speaking"||this.state==="thinking")&&this.setState("listening");break;case"ending_soon":this.emit({type:"ending_soon",secondsRemaining:t.data.secondsRemaining});break;case"ended":this.emit({type:"ended",reason:t.data.reason,message:t.data.message}),this.stop();break;case"error":this.emit({type:"error",code:t.data.code,message:t.data.message,recoverable:t.data.recoverable,fallbackToChat:t.data.fallbackToChat}),t.data.recoverable||(this.setState("error"),this.stop());break}}sendAudio(e){if(!(!this.options.handsFree&&this.state!=="recording")){if(this.held){this.held.push(e),this.options.onLevel?.("user",te(e));return}this.options.onLevel?.("user",te(e)),this.utteranceMs+=e.byteLength*1e3/(2*24e3);try{this.socket?.send(e)}catch{}}}sendControl(e){try{this.socket?.send(JSON.stringify(e))}catch{}}setState(e){this.state!==e&&(this.state=e,this.reportPlaybackWhileSpeaking(),this.options.onEvent({type:"state",state:e}))}reportPlaybackWhileSpeaking(){if(!(!!this.options.handsFree&&this.state==="speaking")){this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null);return}this.playbackTimer===null&&(this.playbackTimer=setInterval(()=>{this.speaker.speaking&&this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}})},250))}emit(e){this.options.onEvent(e)}};function ie(n,e,t=!1){let i=n.replace(/\/v1\/ws\/?$/,"/v1/voice"),r=i.includes("?")?"&":"?",s=t?"&handsFree=true":"";return`${i}${r}token=${encodeURIComponent(e)}${s}`}var wt=60,Ne=2500,ve="0.2.5",U="mihe-panel",ne=4,ye=9e4;function kt(n){return`About ${Math.max(5,Math.round(n/5)*5)} seconds left of voice. The conversation carries on in text.`}function be(n){return`${n}_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function $e(n){let e=new F(n);return e.connect(),e}var F=class{constructor(e){o(this,"store",new D);o(this,"highlighter",new L);o(this,"options");o(this,"state");o(this,"listeners",new Set);o(this,"client",null);o(this,"voiceSession",null);o(this,"voiceRequested",!1);o(this,"requestedHandsFree",!1);o(this,"requestedOpenPanel",!0);o(this,"levelListeners",new Set);o(this,"publishedRoute",null);o(this,"publishedScreen",null);o(this,"publishedSettled",!1);o(this,"screenWaiters",new Set);o(this,"publishTimer",null);o(this,"unsubscribeStore",null);o(this,"tabs",new Map);o(this,"tables",new Map);o(this,"charts",new Map);o(this,"actions",new Map);o(this,"lastScreen",null);o(this,"getState",()=>this.state);o(this,"subscribe",e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}));o(this,"send",e=>{let t=e.trim(),i=this.state.attachments.filter(a=>a.status==="ready");if(this.state.attachments.some(a=>a.status==="reading")||!t&&!i.length)return;let r=[t||"(See the attached picture.)",...i.map(a=>`[Attached picture "${a.name}", as the app describes it: ${a.text}]`)].join(`
|
|
47
|
+
|
|
48
|
+
`),s=be("msg"),l={id:s,role:"user",text:t,...i.length?{attachments:i.map(a=>({name:a.name,...a.previewUrl?{previewUrl:a.previewUrl}:{}}))}:{}};for(let a of this.state.attachments)a.status==="failed"&&a.previewUrl&&URL.revokeObjectURL(a.previewUrl);this.setState({isOpen:!0,messages:[...this.state.messages,l],attachments:[],lastError:null}),this.client?.sendMessage(r,s)});o(this,"attach",e=>{let t=this.options.describeAttachment;if(!t)return;let i=(a,d)=>this.setState({attachments:this.state.attachments.map(h=>h.id===a?{...h,...d}:h)});if(this.state.attachments.length>=ne){this.setState({lastError:`Up to ${ne} pictures at a time.`});return}if(!xe(this.state.attachAccept??"",e)){this.setState({lastError:`"${e.name}" isn't a kind of file this can read.`});return}let r=be("att"),s=e.type.startsWith("image/")&&typeof URL.createObjectURL=="function"?URL.createObjectURL(e):void 0;this.setState({attachments:[...this.state.attachments,{id:r,name:e.name||"picture",status:"reading",...s?{previewUrl:s}:{}}],lastError:null});let l;Promise.race([Promise.resolve().then(()=>t(e)),new Promise((a,d)=>{l=setTimeout(()=>d(new Error("It took too long to read.")),ye)})]).then(a=>{let d=typeof a=="string"?a.trim():"";i(r,d?{status:"ready",text:d}:{status:"failed",error:"Nothing could be read from it."}),d&&this.onCall()&&!this.state.attachments.some(h=>h.status==="reading")&&this.send("")}).catch(a=>i(r,{status:"failed",error:a instanceof Error&&a.message?a.message:"It couldn't be read."})).finally(()=>clearTimeout(l))});o(this,"removeAttachment",e=>{let t=this.state.attachments.find(i=>i.id===e);t&&(t.previewUrl&&URL.revokeObjectURL(t.previewUrl),this.setState({attachments:this.state.attachments.filter(i=>i.id!==e)}))});o(this,"respondToProposal",(e,t)=>{this.client?.confirmAction(e,t),t||this.setState({proposals:this.state.proposals.filter(i=>i.proposalId!==e)})});o(this,"open",()=>{this.state.isOpen||this.setState({isOpen:!0})});o(this,"close",()=>{this.state.isOpen&&this.setState({isOpen:!1})});o(this,"toggle",()=>{this.setState({isOpen:!this.state.isOpen})});o(this,"handleEvent",e=>{switch(e.type){case"state":this.setState({connection:e.state}),this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=null,this.publish();break;case"turn_start":this.setState({busy:!0,messages:[...this.state.messages,{id:e.turnId,role:"assistant",text:"",streaming:!0}]});break;case"delta":this.setMessages(t=>t.map(i=>i.id===e.turnId?{...i,text:i.text+e.text}:i));break;case"complete":this.setState({busy:!1,messages:this.state.messages.map(t=>t.id===e.turnId?{...t,text:e.message,streaming:!1,sources:e.sources.length?e.sources:void 0}:t)});break;case"command":{let t={store:this.store,highlighter:this.highlighter,navigate:this.options.navigate??(r=>{window.location.assign(r)}),screenPublished:this.awaitScreenPublished,viewPublished:this.awaitViewPublished,openModal:this.options.openModal},i=this.client;z(e.command,t).then(r=>i?.ackCommand(e.commandId,r.ok,r.result,r.error)).catch(r=>i?.ackCommand(e.commandId,!1,void 0,r instanceof Error?r.message:"The command failed."));break}case"proposal":this.setState({proposals:[...this.state.proposals,e.proposal]}),this.describe(e.proposal);break;case"action_status":{if(e.status==="executing")break;let t=this.state.proposals.find(i=>i.proposalId===e.proposalId);if(t){let i=`status_${e.proposalId}`;if(e.status!=="rejected"&&!this.state.messages.some(r=>r.id===i)){let r=e.status==="executed"?`${t.label} \u2014 done.`:`${t.label} \u2014 ${e.error??"that did not work."}`;this.setMessages(s=>[...s,{id:i,role:"assistant",text:r}])}this.options.onActionComplete?.({actionName:t.actionName,status:e.status,result:e.result})}this.setState({proposals:this.state.proposals.filter(i=>i.proposalId!==e.proposalId),...e.error?{lastError:e.error}:{}});break}case"voice_available":this.setVoice({available:e.available});break;case"assistant_name":this.setState({assistantName:e.name});break;case"launcher_icon":this.setState({launcherIconUrl:e.url});break;case"widget_settings":this.setState({widgetSettings:e.settings});break;case"context_report":console.info(Q(e.report));break;case"voice_token":if(!this.voiceRequested)break;this.voiceRequested=!1,this.startVoice(e.token);break;case"error":if(e.code.startsWith("voice_")){this.voiceRequested=!1,this.setState({busy:!1,voice:{...this.state.voice,available:!1}});break}this.setState({busy:!1,lastError:e.message});break}});o(this,"publish",()=>{this.publishTimer=null;let e=this.store.getScreenContext();if(!(!e&&this.publishedRoute===null)&&(this.client?.updateScreen(e),this.publishedRoute=e?.route??null,this.publishedScreen=e,this.publishedSettled=!this.store.isScreenLoading(),!(!e||!this.publishedSettled)))for(let t of[...this.screenWaiters])t(e)});o(this,"awaitScreenPublished",(e,t)=>new Promise(i=>{let r=e.split("?")[0];if(!t?.fresh&&this.publishedRoute===r&&this.publishedSettled)return i(!0);let s=d=>{this.screenWaiters.delete(l),clearTimeout(a),i(d)},l=d=>{d.route===r&&s(!0)},a=setTimeout(()=>s(!1),Ne);this.screenWaiters.add(l)}));o(this,"awaitViewPublished",(e,t)=>new Promise(i=>{let r=d=>d?.controls.some(h=>h.controlKey===e&&h.value===t)??!1;if(this.publishedSettled&&r(this.publishedScreen))return i(!0);let s=d=>{this.screenWaiters.delete(l),clearTimeout(a),i(d)},l=d=>{r(d)&&s(!0)},a=setTimeout(()=>s(!1),Ne);this.screenWaiters.add(l)}));o(this,"startVoiceRequest",e=>{this.setVoice({notice:null}),this.requestedHandsFree=!!e?.handsFree,this.requestedOpenPanel=e?.openPanel??!0,this.voiceRequested=!0,this.client?.requestVoiceToken()});o(this,"stopVoice",()=>{this.voiceRequested=!1,this.voiceSession?.stop(),this.voiceSession=null,this.setVoice({handsFree:!1,notice:null})});o(this,"handleVoiceEvent",e=>{switch(e.type){case"state":this.setVoice({state:e.state,...e.state==="idle"||e.state==="error"?{caption:""}:{}});break;case"transcript":e.final?this.setState({voice:{...this.state.voice,caption:""},messages:[...this.state.messages,{id:be("voice"),role:e.role,text:e.text}]}):this.setVoice({caption:e.text});break;case"ending_soon":this.setVoice({notice:kt(e.secondsRemaining)});break;case"ended":this.setVoice({caption:"",notice:e.message,handsFree:!1});break;case"error":this.setState({lastError:e.message});break}});this.options={...e},this.state={connection:"idle",messages:[],proposals:[],cardViews:{},busy:!1,lastError:null,isOpen:!1,assistantName:null,launcherIconUrl:null,widgetSettings:null,attachAccept:e.describeAttachment?e.attachmentAccept??"image/*":null,attachments:[],voice:{available:!1,state:"idle",handsFree:!1,caption:"",notice:null,start:this.startVoiceRequest,stop:this.stopVoice,press:t=>this.voiceSession?.beginUtterance(t),release:()=>this.voiceSession?.endUtterance(),confirm:()=>this.voiceSession?.confirmUtterance(),discard:()=>this.voiceSession?.discardUtterance(),onLevel:t=>(this.levelListeners.add(t),()=>{this.levelListeners.delete(t)})}}}get voice(){return this.state.voice}setState(e){this.state={...this.state,...e};for(let t of[...this.listeners])t()}setVoice(e){this.setState({voice:{...this.state.voice,...e}})}setMessages(e){this.setState({messages:e(this.state.messages)})}update(e){let t=this.options;this.options={...t,...e};let i=this.options.describeAttachment?this.options.attachmentAccept??"image/*":null;i!==this.state.attachAccept&&this.setState({attachAccept:i}),(this.options.url!==t.url||this.options.publicKey!==t.publicKey||!!this.options.debug!=!!t.debug)&&this.client&&(this.disconnect(),this.connect())}connect(){if(this.client)return;let e=new I({url:this.options.url,publicKey:this.options.publicKey,getUserToken:()=>this.options.getUserToken(),sdkVersion:ve,onEvent:this.handleEvent,debug:this.options.debug??!1});this.client=e,this.unsubscribeStore=this.store.subscribe(()=>{this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=setTimeout(this.publish,wt)}),this.publish(),e.connect()}disconnect(){this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=null,this.unsubscribeStore?.(),this.unsubscribeStore=null,this.client?.close(),this.client=null,this.voiceSession?.stop(),this.voiceSession=null,this.highlighter.clear()}destroy(){this.disconnect(),this.listeners.clear(),this.levelListeners.clear()}onCall(){return!["idle","connecting","error"].includes(this.state.voice.state)}describe(e){let t=a=>{a!=="pending"&&!this.state.proposals.some(d=>d.proposalId===e.proposalId)||this.setState({cardViews:{...this.state.cardViews,[e.proposalId]:a}})},i=this.options.describeProposal;if(!i){t(C(e));return}t("pending");let r=!1,s=a=>{r||(r=!0,t(a&&Array.isArray(a.lines)?q(a):C(e)))},l=setTimeout(()=>s(null),j);Promise.resolve().then(()=>i(e)).then(a=>{clearTimeout(l),s(a)}).catch(a=>{clearTimeout(l),console.warn("[mihe] describeProposal failed; the card uses the registry's hints.",a),s(null)})}prompt(e){return()=>this.send(e)}setScreen(e){let t=JSON.stringify(e);return(t!==this.lastScreen||this.store.getScreenContext()?.screenId!==e.screenId)&&(this.lastScreen=t,this.store.setScreen(JSON.parse(t))),()=>{this.store.clearScreen(e.screenId),this.store.getScreenContext()===null&&(this.lastScreen=null)}}registerComponent(e,t,i){return e?.setAttribute(M,t),this.store.registerComponent(t,{...i}),()=>{this.store.unregisterComponent(t),e?.getAttribute(M)===t&&e.removeAttribute(M)}}registerAction(e,t){let i=this.actions.get(e);if(i&&this.store.getAction(e)===i.declaration)return i.latest=t,()=>this.undoAction(e,i);let r={latest:t,signature:e,declaration:{name:e,handler:s=>r.latest(s)}};return this.actions.set(e,r),this.store.registerAction(r.declaration),()=>this.undoAction(e,r)}undoAction(e,t){this.actions.get(e)===t&&(this.actions.delete(e),this.store.getAction(e)===t.declaration&&this.store.unregisterAction(e))}registerTabs(e){return this.declare(this.tabs,e.id,e,Y(e),t=>G(t),t=>this.store.getControl(t),(t,i)=>this.store.registerControl(t,i),t=>this.store.unregisterControl(t))}registerTable(e){return this.declare(this.tables,e.id,e,J(e),t=>X(t),t=>this.store.getTable(t),(t,i)=>this.store.registerTable(t,i),t=>this.store.unregisterTable(t))}registerChart(e){return this.declare(this.charts,e.id,e,Z(e),t=>H(t),t=>this.store.getChart(t),(t,i)=>this.store.registerChart(t,i),t=>this.store.unregisterChart(t))}setValues(e,t){return this.store.setValues(e,JSON.parse(JSON.stringify(t))),()=>this.store.clearValues(e)}declare(e,t,i,r,s,l,a,d){let h=e.get(t);if(h&&l(t)===h.declaration){if(h.latest=i,h.signature!==r){let u=h;h.signature=r,h.declaration=s(()=>u.latest),a(t,h.declaration)}}else{let u={latest:i,signature:r};u.declaration=s(()=>u.latest),e.set(t,u),a(t,u.declaration),h=u}let p=h;return()=>{e.get(t)===p&&(e.delete(t),l(t)===p.declaration&&d(t))}}bindTrigger(e){let t=e instanceof HTMLButtonElement,i=["aria-expanded","aria-controls","aria-haspopup"];t||(e.setAttribute("role","button"),i.push("role"),e.hasAttribute("tabindex")||(e.setAttribute("tabindex","0"),i.push("tabindex"))),e.setAttribute("aria-controls",U),e.setAttribute("aria-haspopup","dialog");let r=()=>e.setAttribute("aria-expanded",String(this.state.isOpen)),s=()=>this.toggle(),l=d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),this.toggle())};r();let a=this.subscribe(r);return e.addEventListener("click",s),t||e.addEventListener("keydown",l),()=>{a(),e.removeEventListener("click",s),e.removeEventListener("keydown",l);for(let d of i)e.removeAttribute(d)}}async startVoice(e){let t=this.requestedHandsFree;this.setVoice({handsFree:t});let i=new _({url:ie(this.options.url,e,t),handsFree:t,onEvent:this.handleVoiceEvent,onLevel:(r,s)=>{for(let l of this.levelListeners)l(r,s)}});this.voiceSession=i,this.requestedOpenPanel&&this.open(),await i.start()}};function xe(n,e){let t=e.name.toLowerCase();return n.split(",").map(i=>i.trim().toLowerCase()).filter(Boolean).some(i=>i.startsWith(".")?t.endsWith(i):i.endsWith("/*")?e.type.toLowerCase().startsWith(i.slice(0,-1)):e.type.toLowerCase()===i)}function c(n,e={},...t){let i=document.createElement(n);e.class&&(i.className=e.class),A(i,e.attrs??{});for(let[r,s]of Object.entries(e.on??{}))i.addEventListener(r,s);return He(i,t),i}var St="http://www.w3.org/2000/svg";function y(n,e,...t){let i=document.createElementNS(St,n);for(let[r,s]of Object.entries(e))i.setAttribute(r,String(s));for(let r of t)i.appendChild(r);return i}function A(n,e){for(let[t,i]of Object.entries(e))i===void 0||i===!1?n.removeAttribute(t):n.setAttribute(t,i===!0?"":String(i))}function He(n,e){for(let t of e)t==null||t===!1||n.appendChild(typeof t=="string"?document.createTextNode(t):t)}function x(n,...e){for(;n.firstChild;)n.removeChild(n.firstChild);He(n,e)}var Fe="translate(0.000000,1760.000000) scale(0.100000,-0.100000)",Tt="M8165 16868 c-450 -31 -1057 -131 -1495 -248 -76 -20 -156 -42 -180 -50 -14 -5 -50 -15 -80 -24 -146 -41 -273 -82 -360 -117 -25 -9 -74 -27 -110 -39 -36 -12 -74 -25 -85 -30 -11 -4 -40 -15 -65 -25 -25 -10 -54 -21 -65 -26 -11 -4 -85 -35 -165 -67 -218 -90 -530 -238 -715 -340 -38 -21 -106 -58 -150 -82 -44 -24 -108 -61 -143 -82 -34 -21 -65 -38 -68 -38 -2 0 -17 -8 -32 -19 -15 -10 -52 -34 -82 -53 -1161 -733 -2106 -1735 -2771 -2935 -74 -134 -219 -425 -219 -440 0 -4 -10 -24 -23 -43 -13 -19 -34 -60 -46 -90 -13 -30 -35 -80 -48 -110 -49 -112 -56 -127 -91 -220 -16 -41 -32 -84 -37 -95 -45 -114 -195 -563 -238 -715 -26 -88 -58 -212 -67 -255 -5 -22 -16 -69 -25 -105 -19 -78 -66 -317 -89 -455 -140 -836 -144 -1701 -11 -2525 9 -52 20 -122 25 -155 9 -53 17 -97 51 -262 16 -78 80 -337 105 -423 74 -256 219 -700 264 -810 26 -63 55 -135 79 -192 6 -13 24 -54 40 -91 17 -38 31 -70 31 -72 0 -3 105 -221 203 -425 39 -79 80 -154 128 -233 16 -26 29 -50 29 -52 0 -3 37 -65 82 -138 45 -72 88 -143 95 -157 64 -113 285 -440 339 -500 12 -14 43 -56 70 -95 42 -63 164 -220 221 -285 12 -14 36 -43 55 -66 250 -310 644 -706 1038 -1045 68 -59 396 -310 514 -395 88 -63 522 -341 596 -382 19 -10 80 -45 135 -77 120 -69 571 -298 670 -339 39 -16 107 -47 153 -68 46 -21 87 -38 93 -38 5 0 17 -4 27 -10 25 -13 78 -35 157 -63 39 -14 120 -43 180 -65 222 -82 417 -145 565 -183 41 -10 91 -23 110 -29 134 -37 514 -119 645 -139 836 -130 1685 -150 2385 -57 63 8 151 20 195 26 44 6 100 15 125 20 25 5 88 17 140 25 286 49 729 160 1015 256 198 67 349 119 370 129 11 6 72 30 135 54 63 24 142 56 175 71 103 46 118 52 183 79 53 22 224 108 572 287 750 385 1586 1059 2290 1844 219 244 499 612 666 873 32 52 91 144 131 205 91 141 268 456 366 652 87 172 167 341 167 350 0 4 6 21 14 38 56 124 212 529 241 627 9 30 21 64 26 75 4 11 16 45 25 75 9 30 25 82 36 115 54 166 146 535 178 710 82 461 106 640 137 1030 20 252 23 814 5 1015 -6 74 -17 191 -23 260 -12 141 -34 328 -49 410 -5 30 -16 100 -25 155 -9 55 -26 145 -37 200 -11 55 -24 118 -28 140 -4 22 -16 72 -25 110 -9 39 -20 86 -24 105 -203 889 -617 1816 -1181 2640 -141 205 -236 333 -350 470 -52 63 -113 138 -135 165 -203 255 -745 786 -1035 1016 -58 45 -138 109 -179 142 -228 181 -749 524 -1006 662 -49 26 -115 62 -145 78 -71 38 -346 176 -430 215 -138 64 -201 92 -206 92 -3 0 -35 14 -71 30 -35 17 -70 30 -77 30 -6 0 -16 4 -21 8 -9 8 -216 87 -387 148 -38 13 -98 35 -135 49 -38 13 -102 34 -143 45 -41 12 -97 28 -125 36 -180 53 -464 125 -610 154 -165 33 -214 43 -240 47 -16 2 -66 10 -110 18 -328 56 -573 84 -755 88 l-125 2 0 -515 0 -515 190 -21 c105 -12 242 -29 305 -39 63 -10 138 -21 165 -26 123 -18 192 -30 225 -39 19 -5 62 -14 95 -20 233 -44 615 -154 905 -260 47 -17 105 -38 130 -47 25 -8 59 -21 75 -28 17 -7 93 -39 170 -71 418 -173 867 -425 1345 -757 747 -518 1525 -1379 1970 -2182 18 -33 41 -73 50 -90 64 -116 84 -152 123 -231 25 -49 57 -118 72 -154 15 -36 36 -85 47 -110 42 -93 56 -127 78 -180 12 -30 26 -64 31 -75 61 -146 144 -376 194 -540 15 -49 31 -101 36 -115 9 -26 46 -175 74 -295 8 -38 20 -86 25 -105 15 -58 45 -214 80 -425 24 -141 62 -499 79 -745 34 -482 -17 -1111 -134 -1655 -14 -66 -30 -140 -35 -165 -8 -38 -22 -93 -65 -260 -28 -107 -86 -292 -127 -405 -59 -164 -118 -318 -128 -337 -6 -10 -10 -22 -10 -27 0 -6 -18 -49 -40 -96 -22 -47 -40 -88 -40 -90 0 -27 -247 -518 -314 -624 -14 -22 -26 -43 -26 -45 0 -37 -381 -596 -565 -829 -225 -283 -622 -706 -875 -929 -155 -137 -228 -198 -237 -198 -9 0 -127 185 -183 285 -12 22 -28 47 -35 55 -7 8 -32 49 -55 90 -24 41 -76 125 -115 185 -40 61 -123 195 -186 298 -63 103 -126 207 -141 230 -15 23 -31 49 -35 57 -3 8 -16 29 -27 45 -12 17 -26 39 -33 50 -7 11 -33 54 -59 95 -67 106 -620 996 -1072 1725 -58 94 -129 206 -158 251 -29 45 -65 103 -80 130 -15 27 -55 92 -89 144 -88 134 -280 445 -400 645 -56 94 -163 269 -239 389 -75 121 -135 224 -134 228 2 5 35 54 73 109 403 577 447 641 713 1032 134 197 262 399 262 413 0 8 -36 85 -79 172 -44 86 -142 285 -219 442 -77 157 -244 497 -372 755 -128 259 -297 601 -375 760 -78 160 -220 448 -315 640 -95 193 -264 535 -376 760 -400 810 -543 1101 -566 1155 -14 30 -33 74 -43 98 -17 39 -55 61 -55 31 0 -6 -35 -83 -79 -172 -43 -89 -106 -218 -139 -287 -68 -142 -323 -661 -607 -1235 -106 -214 -271 -550 -368 -745 -225 -457 -457 -927 -747 -1515 -363 -735 -420 -852 -420 -862 0 -10 166 -267 241 -373 21 -30 95 -138 164 -240 68 -102 160 -237 204 -300 80 -115 147 -212 296 -430 43 -63 93 -135 112 -159 42 -56 42 -57 -11 -134 -24 -35 -58 -90 -76 -122 -29 -52 -66 -114 -107 -180 -7 -11 -20 -33 -29 -50 -9 -16 -45 -73 -79 -125 -34 -52 -74 -117 -89 -145 -16 -27 -34 -57 -42 -66 -8 -8 -14 -19 -14 -23 0 -4 -10 -22 -23 -39 -12 -18 -28 -41 -34 -52 -7 -11 -33 -54 -59 -95 -26 -41 -58 -95 -72 -120 -13 -25 -35 -58 -47 -75 -21 -29 -238 -378 -619 -995 -96 -157 -210 -339 -252 -405 -104 -164 -269 -429 -343 -550 -33 -55 -92 -149 -131 -210 -38 -60 -78 -126 -90 -145 -11 -19 -25 -42 -30 -50 -5 -8 -44 -71 -86 -140 -42 -69 -104 -168 -138 -220 -34 -53 -66 -104 -73 -115 -6 -11 -76 -123 -155 -249 -79 -126 -145 -234 -147 -240 -2 -6 -21 -36 -41 -66 -76 -112 -170 -260 -170 -267 0 -5 -14 -24 -30 -43 -29 -35 -29 -35 -82 16 -29 28 -91 84 -138 124 -567 490 -1171 1224 -1508 1832 -47 85 -232 451 -274 543 -20 44 -53 115 -72 158 -20 42 -36 80 -36 83 0 3 -6 20 -14 37 -20 47 -40 99 -85 222 -79 217 -90 252 -140 420 -49 167 -85 311 -141 558 -120 534 -163 1390 -99 1962 41 369 37 343 84 595 48 260 75 373 159 683 39 143 224 654 286 792 110 242 174 371 314 630 563 1039 1532 2008 2644 2642 68 38 455 233 532 267 131 58 397 168 465 192 108 39 384 130 445 148 30 8 87 25 125 36 316 96 789 185 1190 225 94 9 176 20 183 24 12 5 16 287 12 1022 0 13 -27 15 -135 7z m660 -4508 c4 -16 11 -32 16 -35 5 -4 9 -12 9 -20 0 -8 19 -53 41 -102 71 -151 106 -226 129 -278 12 -27 39 -86 60 -130 21 -44 52 -111 70 -150 17 -38 44 -97 60 -130 15 -33 35 -76 43 -95 8 -19 31 -69 50 -110 62 -134 89 -194 107 -240 10 -25 46 -103 80 -175 90 -190 106 -224 133 -285 49 -108 70 -156 97 -215 15 -33 37 -82 50 -110 12 -27 40 -87 61 -133 40 -83 40 -83 6 -140 -19 -31 -50 -86 -69 -122 -65 -120 -91 -165 -140 -242 -26 -43 -48 -80 -48 -83 0 -2 -17 -33 -38 -67 -21 -35 -41 -70 -45 -78 -4 -8 -11 -22 -17 -30 -34 -54 -110 -181 -110 -185 0 -3 -11 -23 -25 -45 -14 -22 -46 -80 -72 -128 -25 -48 -54 -98 -63 -112 -41 -58 -150 -263 -150 -280 0 -10 15 -47 33 -82 62 -117 120 -223 128 -234 5 -6 48 -87 95 -180 47 -93 90 -173 94 -179 4 -5 27 -46 50 -90 23 -44 67 -127 98 -185 30 -58 59 -110 63 -116 11 -14 72 -130 111 -209 37 -77 56 -114 103 -200 142 -264 186 -348 323 -615 63 -124 128 -250 145 -280 33 -59 82 -154 250 -480 58 -113 129 -250 157 -305 96 -182 151 -288 268 -515 63 -124 135 -263 160 -310 24 -47 118 -229 207 -405 170 -333 225 -440 277 -534 17 -31 112 -216 211 -411 99 -195 188 -372 199 -393 11 -22 18 -40 16 -42 -10 -11 -431 -215 -443 -215 -2 0 -36 -15 -77 -34 -40 -18 -109 -48 -153 -66 -44 -18 -93 -38 -110 -45 -16 -7 -75 -29 -130 -50 -55 -20 -116 -43 -135 -50 -39 -14 -282 -90 -345 -107 -22 -6 -60 -16 -85 -24 -61 -17 -216 -55 -265 -64 -22 -4 -85 -17 -140 -28 -165 -33 -277 -52 -513 -87 -183 -27 -182 -27 -182 78 0 34 -4 98 -10 142 -5 44 -14 141 -20 215 -24 285 -30 360 -45 530 -9 96 -20 229 -25 295 -5 66 -17 206 -25 310 -9 105 -20 249 -25 320 -5 72 -12 148 -15 170 -3 22 -10 105 -15 185 -5 80 -17 228 -25 330 -9 102 -20 237 -24 300 -5 63 -19 225 -30 360 -11 135 -27 335 -36 445 -30 392 -37 461 -50 510 -8 28 -26 97 -41 155 -14 58 -37 146 -50 195 -41 154 -55 209 -64 245 -9 33 -23 89 -55 205 -7 28 -25 100 -40 160 -24 98 -49 196 -61 233 -8 27 -28 5 -40 -44 -6 -27 -24 -94 -38 -149 -15 -55 -43 -161 -62 -235 -20 -74 -49 -187 -65 -250 -17 -63 -39 -151 -50 -195 -23 -92 -39 -157 -69 -270 -30 -113 -36 -170 -75 -720 -8 -110 -21 -276 -30 -370 -8 -93 -19 -226 -25 -295 -5 -69 -12 -143 -15 -165 -3 -22 -10 -105 -16 -185 -24 -330 -41 -552 -59 -745 -22 -237 -31 -345 -40 -460 -5 -66 -16 -201 -25 -300 -8 -99 -19 -234 -25 -300 -15 -193 -40 -482 -50 -590 -5 -55 -9 -106 -10 -112 0 -18 -71 -17 -184 2 -50 9 -122 20 -161 26 -108 16 -241 39 -345 61 -52 11 -113 24 -135 28 -52 11 -235 56 -300 75 -27 7 -75 20 -106 29 -62 17 -397 127 -444 146 -16 7 -39 16 -50 21 -11 5 -56 22 -100 39 -214 82 -663 292 -724 339 -23 18 -23 18 62 182 46 90 130 252 185 359 55 107 121 236 147 285 26 50 100 194 165 320 64 127 146 286 182 355 36 69 100 193 143 275 43 83 106 204 140 270 34 66 109 210 165 320 108 211 202 391 280 540 26 50 70 133 97 185 28 52 112 217 188 365 76 149 141 275 145 280 4 6 54 100 110 210 57 110 123 238 148 285 25 47 63 119 85 160 22 41 71 133 110 205 39 71 107 202 152 290 45 88 91 177 103 197 12 21 37 66 55 100 19 35 51 95 72 133 238 435 243 447 218 497 -34 66 -100 186 -137 247 -19 31 -43 72 -53 91 -65 116 -87 155 -142 248 -34 57 -61 106 -61 108 0 2 -10 21 -23 42 -13 20 -44 75 -69 122 -25 47 -73 132 -107 188 -33 57 -61 106 -61 108 0 2 -29 52 -65 110 -68 111 -74 132 -51 180 26 52 103 218 126 269 13 28 41 88 62 135 22 47 54 114 70 150 48 104 78 169 124 267 24 51 44 98 44 103 0 6 4 18 10 28 13 22 90 192 90 198 0 2 23 52 51 112 54 112 81 171 205 440 19 41 34 76 34 78 0 3 15 37 34 77 18 40 43 95 56 122 12 28 43 93 67 145 25 52 49 105 54 117 12 32 36 28 44 -7z",Ct="M4399 12732 c-37 -42 -101 -117 -143 -166 -123 -145 -496 -679 -496 -712 0 -2 -18 -34 -41 -71 -100 -164 -271 -530 -369 -793 -17 -47 -36 -96 -42 -110 -35 -86 -134 -426 -172 -595 -50 -218 -49 -218 -81 -445 -85 -598 -74 -1269 30 -1820 8 -47 20 -107 24 -135 11 -60 68 -292 87 -355 8 -25 21 -67 29 -95 23 -79 72 -227 85 -260 7 -16 16 -39 20 -50 34 -90 73 -186 108 -265 11 -25 30 -70 43 -100 45 -106 197 -400 256 -493 14 -22 36 -60 50 -85 97 -175 409 -612 437 -612 6 0 85 66 176 147 91 80 199 176 240 212 41 36 100 89 130 117 30 29 73 67 95 86 123 107 120 82 23 209 -209 275 -459 726 -589 1064 -112 292 -165 474 -219 750 -19 96 -26 136 -50 287 -70 444 -45 1047 65 1543 9 39 20 88 24 110 149 680 553 1448 1043 1980 15 17 28 33 28 36 0 11 -703 699 -714 699 -6 0 -41 -35 -77 -78z M12835 12532 c-154 -152 -313 -307 -354 -344 -84 -76 -85 -63 16 -174 227 -250 460 -601 637 -959 70 -144 93 -192 130 -280 10 -22 21 -49 26 -60 5 -11 16 -42 25 -70 10 -27 21 -59 26 -70 23 -55 77 -234 112 -370 45 -175 56 -227 78 -345 24 -127 27 -151 58 -425 26 -231 28 -544 6 -780 -17 -180 -30 -267 -85 -570 -9 -47 -39 -165 -89 -350 -23 -83 -54 -178 -76 -230 -7 -16 -19 -48 -28 -70 -144 -374 -335 -726 -576 -1060 -56 -77 -100 -145 -99 -151 2 -5 68 -68 148 -140 80 -71 172 -154 205 -185 138 -128 375 -329 388 -329 23 0 437 582 437 614 0 3 16 30 35 60 62 98 305 576 305 601 0 3 14 35 31 72 54 117 135 338 174 478 124 434 155 590 214 1065 67 536 5 1382 -141 1930 -11 41 -24 89 -28 105 -24 91 -128 414 -175 543 -34 95 -127 306 -196 447 -145 295 -273 511 -475 795 -154 217 -416 530 -443 530 -3 0 -132 -125 -286 -278z";function Ue(n,e,t){let i=y("svg",{viewBox:"0 0 1760 1760",width:n,height:n,"aria-hidden":"true",focusable:"false"},y("path",{fill:e,"fill-rule":"evenodd",transform:Fe,d:Tt}),y("path",{fill:t,"fill-rule":"evenodd",transform:Fe,d:Ct}));return i.style.display="block",i}var we="#221f1b",re="#eae7e4",se="#5ac8cd",Ke=`
|
|
47
49
|
:host {
|
|
48
50
|
all: initial;
|
|
49
51
|
--mihe-accent: #4f7cff;
|
|
@@ -99,6 +101,19 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
99
101
|
.notice { color: #64748b; font-size: 13px; text-align: center; }
|
|
100
102
|
.voice-notice { background: #f1f5f9; color: #475569; padding: 8px 10px; border-radius: 8px; font-size: 13px; }
|
|
101
103
|
.composer { display: flex; gap: 8px; padding: 12px; border-top: 1px solid #e2e8f0; }
|
|
104
|
+
.clip { width: 38px; border-radius: 8px; border: 1px solid #cbd5e1; background: #fff; cursor: pointer; font-size: 16px; }
|
|
105
|
+
.clip[hidden], .chips[hidden] { display: none; }
|
|
106
|
+
.chips { list-style: none; margin: 0; padding: 8px 12px 0; display: flex; flex-wrap: wrap; gap: 6px; border-top: 1px solid #e2e8f0; }
|
|
107
|
+
.chip { display: flex; align-items: center; gap: 6px; padding: 4px 4px 4px 6px; border-radius: 8px; background: #f1f5f9; max-width: 100%; font-size: 12px; }
|
|
108
|
+
.chip.failed { background: #fef2f2; color: #991b1b; }
|
|
109
|
+
.chip img { width: 28px; height: 28px; border-radius: 4px; object-fit: cover; flex: none; }
|
|
110
|
+
.chip-text { display: flex; flex-direction: column; min-width: 0; }
|
|
111
|
+
.chip-name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
|
|
112
|
+
.chip-status { opacity: 0.75; }
|
|
113
|
+
.chip-remove { border: none; background: transparent; cursor: pointer; width: 28px; height: 28px; border-radius: 6px; color: inherit; font-size: 12px; }
|
|
114
|
+
.sent-pictures { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
|
|
115
|
+
.sent-pictures img { width: 64px; height: 64px; border-radius: 6px; object-fit: cover; display: block; }
|
|
116
|
+
.sent-name { font-size: 12px; opacity: 0.85; }
|
|
102
117
|
.input {
|
|
103
118
|
flex: 1; min-width: 0; padding: 9px 12px; border-radius: 8px; border: 1px solid #cbd5e1;
|
|
104
119
|
font: 14px var(--mihe-font); color: #0f172a; background: #fff; outline: none;
|
|
@@ -170,14 +185,14 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
170
185
|
.launcher {
|
|
171
186
|
position: fixed; right: 20px; bottom: 20px; width: 52px; height: 52px; border-radius: 50%;
|
|
172
187
|
border: none; padding: 0; display: grid; place-items: center; overflow: hidden;
|
|
173
|
-
background: ${
|
|
188
|
+
background: ${we}; color: ${re}; cursor: pointer;
|
|
174
189
|
box-shadow: 0 8px 24px rgba(15,23,42,0.25); z-index: var(--mihe-z);
|
|
175
190
|
}
|
|
176
191
|
.launcher-image { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
177
192
|
|
|
178
193
|
.orb {
|
|
179
194
|
position: fixed; width: 56px; height: 56px; padding: 0; border: none; border-radius: 50%;
|
|
180
|
-
background: ${
|
|
195
|
+
background: ${we}; color: ${re}; box-shadow: 0 8px 24px rgba(15,23,42,0.25);
|
|
181
196
|
z-index: var(--mihe-z); cursor: pointer; transition: left 180ms ease, top 180ms ease;
|
|
182
197
|
touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
|
|
183
198
|
-webkit-tap-highlight-color: transparent;
|
|
@@ -186,7 +201,7 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
186
201
|
.orb:disabled { cursor: default; }
|
|
187
202
|
.face { position: absolute; inset: 0; display: grid; place-items: center; border-radius: 50%; overflow: hidden; pointer-events: none; }
|
|
188
203
|
.ring {
|
|
189
|
-
position: absolute; inset: -6px; border-radius: 50%; border: 2px solid ${
|
|
204
|
+
position: absolute; inset: -6px; border-radius: 50%; border: 2px solid ${se};
|
|
190
205
|
pointer-events: none; transform-origin: center; will-change: transform;
|
|
191
206
|
}
|
|
192
207
|
.ring.idle { border-color: transparent; }
|
|
@@ -215,7 +230,7 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
215
230
|
}
|
|
216
231
|
.menu-icon {
|
|
217
232
|
display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
|
|
218
|
-
background: ${
|
|
233
|
+
background: ${we}; color: ${se};
|
|
219
234
|
}
|
|
220
235
|
.orb-bubble {
|
|
221
236
|
padding: 8px 12px; border-radius: 12px; background: #fff; color: #0f172a;
|
|
@@ -228,7 +243,7 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
228
243
|
.ring { transform: none !important; }
|
|
229
244
|
.orb { transition: none; }
|
|
230
245
|
}
|
|
231
|
-
`;function se(n,e,t,i){return n?n.cloneNode(!0):e&&e!==t?c("img",{class:"launcher-image",attrs:{src:e,alt:"",draggable:"false"},on:{error:()=>i(e)}}):$e(34,ne,re)}function oe(n,e,t=C(n)){let i=n.risk==="high",r=t==="pending",s=r?null:t,a=s&&s.source!=="plain"?c("details",{class:"card-more"},c("summary",{},"More about this"),c("p",{class:"card-description"},n.description)):c("p",{class:"card-description"},n.description);return c("div",{class:"card",attrs:{role:"group","aria-label":`Confirm: ${n.label}`,"aria-busy":r?"true":void 0}},c("div",{class:"card-header"},c("strong",{},n.label),c("span",{class:i?"risk risk-high":"risk"},i?"Needs care":"Confirm")),r&&c("p",{class:"card-description"},"Checking the details\u2026"),s?.summary&&c("p",{class:"card-summary"},s.summary),s&&s.source==="plain"&&a,s&&s.lines.length>0&&c("dl",{class:"card-input"},...s.lines.map(St)),s?.note&&c("p",{class:"card-note"},s.note),s&&s.source!=="plain"&&a,c("div",{class:"card-actions"},c("button",{class:"button-secondary",attrs:{type:"button"},on:{click:()=>e(n.proposalId,!1)}},"Cancel"),c("button",{class:i?"button-primary button-danger":"button-primary",attrs:{type:"button",disabled:r?"":void 0},on:{click:()=>{r||e(n.proposalId,!0)}}},s?.confirmLabel??"Confirm")))}function St(n){if(n.images?.length)return c("div",{class:"card-media-row"},c("span",{class:"card-images"},...n.images.map(t=>c("img",{attrs:{src:t.src,alt:t.alt??"",loading:"lazy",referrerpolicy:"no-referrer"}}))),c("span",{class:"card-media-text"},n.label&&c("dt",{class:"card-media-label"},n.label),c("dd",{class:n.label?"card-media-value":"card-media-value card-media-strong"},...Fe(n))));let e=c("dd",{class:n.label?"card-value":"card-value card-value-wide"},...Fe(n));return c("div",{class:"card-row"},n.label&&c("dt",{class:"card-key"},n.label),e)}function Fe(n){return[n.before!==void 0&&c("s",{class:"card-before"},n.before),n.before!==void 0&&c("span",{class:"card-arrow",attrs:{"aria-label":"becomes"}}," \u2192 "),n.text!==void 0&&c("span",{class:"input-text"},n.text),!!n.items?.length&&c("ol",{class:"input-list"},...n.items.map(e=>c("li",{},c("span",{class:"input-text"},e))))]}function be(...n){return y("svg",{viewBox:"0 0 20 20",width:18,height:18,fill:"none",stroke:"currentColor","stroke-width":1.7,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},...n)}var Ke=()=>be(y("path",{d:"M4 4.5h12a1.5 1.5 0 0 1 1.5 1.5v7a1.5 1.5 0 0 1-1.5 1.5H9l-4 3v-3H4A1.5 1.5 0 0 1 2.5 13V6A1.5 1.5 0 0 1 4 4.5Z"})),Be=()=>be(y("rect",{x:7,y:2.5,width:6,height:10,rx:3}),y("path",{d:"M4.5 9.5a5.5 5.5 0 0 0 11 0M10 15v2.5"})),Ue=()=>be(y("path",{d:"M3 10v0M6.5 7v6M10 4v12M13.5 7v6M17 10v0"}));var g=56,qe=20,Tt=8,Ct=150,We="mihe:orb-position",ze="mihe:hold-hint-done";function Mt(){try{let n=window.localStorage.getItem(We);if(!n)return null;let e=JSON.parse(n);if((e.side==="left"||e.side==="right")&&typeof e.y=="number")return e}catch{}return null}function At(n){try{window.localStorage.setItem(We,JSON.stringify(n))}catch{}}function Et(){try{return window.localStorage.getItem(ze)==="1"}catch{return!1}}function It(){try{window.localStorage.setItem(ze,"1")}catch{}}var ae=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"button");o(this,"ring");o(this,"face");o(this,"stop");o(this,"menu");o(this,"cards");o(this,"bubble");o(this,"options");o(this,"state");o(this,"menuOpen",!1);o(this,"rest",null);o(this,"drag",null);o(this,"showHint",!Et());o(this,"press",null);o(this,"previousVoiceState","idle");o(this,"faceKey");o(this,"drawnProposals");o(this,"drawnViews");o(this,"failedIcon",null);o(this,"ringFrame",0);o(this,"stopLevel",null);o(this,"reducedMotion",typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches===!0);o(this,"cleanups",[]);this.ring=c("span",{class:"ring idle",attrs:{"aria-hidden":"true"}}),this.face=c("span",{class:"face"}),this.button=c("button",{class:"orb",attrs:{type:"button"},on:{pointerdown:r=>this.onPointerDown(r),pointermove:r=>this.onPointerMove(r),pointerup:()=>this.finish(!1),pointercancel:()=>this.finish(!0),keydown:r=>this.onKeyDown(r),keyup:r=>this.onKeyUp(r),contextmenu:r=>r.preventDefault()}},this.ring,this.face),this.stop=c("button",{class:"stop",attrs:{type:"button","aria-label":"End voice"},on:{click:()=>this.mihe.voice.stop()}},c("span",{class:"stop-square",attrs:{"aria-hidden":"true"}})),this.menu=c("div",{class:"popover",attrs:{role:"menu"},on:{keydown:r=>this.onMenuKeyDown(r)}}),this.cards=c("div",{class:"popover cards"}),this.bubble=c("div",{class:"popover orb-bubble",attrs:{role:"status","aria-live":"polite"}}),this.root=c("div",{},this.menu,this.cards,this.bubble,this.button,this.stop);let t=()=>this.render();window.addEventListener("resize",t),this.cleanups.push(()=>window.removeEventListener("resize",t));let i=r=>{if(!this.menuOpen)return;let s=r.composedPath();!s.includes(this.menu)&&!s.includes(this.button)&&this.setMenu(!1)};document.addEventListener("pointerdown",i),this.cleanups.push(()=>document.removeEventListener("pointerdown",i))}update(e,t){this.options?.draggable!==t.draggable&&(this.rest=t.draggable?Mt():null),this.previousVoiceState==="recording"&&e.voice.state==="thinking"&&(It(),this.showHint=!1),this.previousVoiceState=e.voice.state,this.state=e,this.options=t,this.render()}destroy(){this.stopRing(),this.press?.timer&&clearTimeout(this.press.timer);for(let e of this.cleanups)e()}get voiceLive(){let e=this.state.voice.state;return e!=="idle"&&e!=="error"}get handsFree(){return this.voiceLive&&this.state.voice.handsFree}get holdToTalk(){return this.voiceLive&&!this.state.voice.handsFree}menuItems(){let e=this.state.voice.available?this.options.voiceModes:[];return[{key:"chat",label:"Chat"},...e.includes("hands-free")?[{key:"hands-free",label:"Talk"}]:[],...e.includes("hold")?[{key:"hold",label:"Hold to talk"}]:[]]}viewport(){return{width:window.innerWidth,height:window.innerHeight}}clampTop(e){let{height:t}=this.viewport(),i=t-this.options.offset.bottom-g;return Math.min(Math.max(qe,e),Math.max(qe,i))}side(){let{width:e}=this.viewport();return this.drag?this.drag.left+g/2<e/2?"left":"right":this.rest?.side??(this.options?.corner==="bottom-left"?"left":"right")}position(){let{width:e,height:t}=this.viewport(),i=this.side(),r=this.options.offset.side,s=this.drag?this.drag.left:i==="left"?r:e-r-g,a=this.drag?this.drag.top:this.clampTop(this.rest?this.rest.y*t:t-this.options.offset.bottom-g);return{side:i,left:s,top:a,above:a+g/2>t/2}}render(){if(!this.state)return;let{voice:e,proposals:t,lastError:i,connection:r}=this.state,{heading:s}=this.options,{side:a,left:l,top:d,above:h}=this.position(),p=this.menuItems(),u=this.voiceLive,m=this.handsFree?`Stop talking to ${s}`:this.holdToTalk?e.state==="recording"?"Release to send":"Hold to talk":p.length===1?`Open ${s}`:`${s}: choose chat or voice`,N=p.length>1&&!u;A(this.button,{"aria-label":m,"aria-haspopup":N?"menu":void 0,"aria-expanded":N?String(this.menuOpen):void 0,"aria-pressed":this.holdToTalk?String(e.state==="recording"):void 0,"aria-busy":String(e.state==="connecting")}),this.button.disabled=r!=="open"&&!u,this.button.style.left=`${l}px`,this.button.style.top=`${d}px`,this.button.classList.toggle("dragging",this.drag!==null);let w=u?["connecting","thinking","recording","speaking"].find(f=>f===e.state)??"listening":"idle";this.ring.className=`ring ${w}`,this.syncRing();let ke=[this.options.launcherIcon,this.state.launcherIconUrl,this.failedIcon];Lt(ke,this.faceKey)||(this.faceKey=ke,x(this.face,se(this.options.launcherIcon,this.state.launcherIconUrl,this.failedIcon,f=>{this.failedIcon=f,this.render()}))),this.stop.hidden=!u,this.stop.style.left=`${l+(a==="right"?-52:g+8)}px`,this.stop.style.top=`${d+(g-44)/2}px`;let{height:Ye}=this.viewport();for(let f of[this.menu,this.cards,this.bubble])f.style.left=a==="left"?`${this.options.offset.side}px`:"",f.style.right=a==="right"?`${this.options.offset.side}px`:"",f.style.bottom=h?`${Ye-d+12}px`:"",f.style.top=h?"":`${d+g+12}px`;this.menu.hidden=!this.menuOpen,this.menu.setAttribute("aria-label",s),this.menu.style.flexDirection=h?"column-reverse":"column",this.menu.style.alignItems=a==="right"?"flex-end":"flex-start",this.menuOpen&&this.menu.childElementCount!==p.length&&x(this.menu,...p.map(f=>c("button",{class:"menu-item",attrs:{type:"button",role:"menuitem"},on:{click:()=>this.choose(f.key)}},c("span",{class:"menu-icon",attrs:{"aria-hidden":"true"}},f.key==="chat"?Ke():f.key==="hold"?Be():Ue()),f.label))),this.cards.hidden=this.menuOpen||t.length===0,(t!==this.drawnProposals||this.state.cardViews!==this.drawnViews)&&(this.drawnProposals=t,this.drawnViews=this.state.cardViews,x(this.cards,...t.map(f=>oe(f,this.mihe.respondToProposal,this.state.cardViews[f.proposalId]))));let U=e.state==="connecting"?{text:"Setting up the microphone\u2026",tone:"quiet"}:i&&(u||e.state==="error")?{text:i,tone:"error"}:e.notice?{text:e.notice,tone:"quiet"}:this.holdToTalk&&this.showHint&&e.state==="listening"?{text:"Hold to talk",tone:"quiet"}:null;this.bubble.hidden=this.menuOpen||t.length>0||U===null,this.bubble.classList.toggle("error",U?.tone==="error"),this.bubble.textContent!==(U?.text??"")&&(this.bubble.textContent=U?.text??"")}syncRing(){let e=this.voiceLive&&!this.reducedMotion;if(e===(this.stopLevel!==null))return;if(!e){this.stopRing();return}let t=0,i=0;this.stopLevel=this.mihe.voice.onLevel((s,a)=>{let l=this.mihe.getState().voice;s==="user"&&(l.state==="recording"||l.handsFree)&&(t=a),s==="assistant"&&(t=a)});let r=()=>{i+=(t-i)*(t>i?.45:.12),t*=.92,this.ring.style.transform=`scale(${1+i*.38})`,this.ringFrame=requestAnimationFrame(r)};this.ringFrame=requestAnimationFrame(r)}stopRing(){this.stopLevel?.(),this.stopLevel=null,cancelAnimationFrame(this.ringFrame),this.ring.style.transform="scale(1)"}setMenu(e){this.menuOpen=e,e||x(this.menu),this.render(),e&&this.menu.querySelector("button")?.focus()}choose(e){this.setMenu(!1),e==="chat"?this.mihe.open():this.mihe.voice.start({handsFree:e==="hands-free",openPanel:!1})}onMenuKeyDown(e){let t=Array.from(this.menu.querySelectorAll("button")),i=this.root.getRootNode().activeElement,r=t.indexOf(i);e.key==="Escape"?(e.preventDefault(),this.setMenu(!1),this.button.focus()):e.key==="ArrowDown"||e.key==="ArrowRight"?(e.preventDefault(),t[(r+1)%t.length]?.focus()):(e.key==="ArrowUp"||e.key==="ArrowLeft")&&(e.preventDefault(),t[(r-1+t.length)%t.length]?.focus())}tap(){if(this.menuOpen){this.setMenu(!1);return}if(this.handsFree){this.mihe.voice.stop();return}this.holdToTalk||(this.menuItems().length===1?this.mihe.open():this.setMenu(!0))}onPointerDown(e){if(e.button!==0)return;this.button.setPointerCapture?.(e.pointerId);let{left:t,top:i}=this.position(),r={x:e.clientX,y:e.clientY,offsetX:e.clientX-t,offsetY:e.clientY-i,dragging:!1,recording:null,timer:null};this.press=r;let s=this.mihe.getState().voice;this.holdToTalk&&(s.state==="listening"||s.state==="speaking")&&(this.options.draggable?(s.press({hold:!0}),r.recording="held",r.timer=setTimeout(()=>{this.press===r&&!r.dragging&&(this.mihe.voice.confirm(),r.recording="live")},Ct)):(s.press(),r.recording="live"))}onPointerMove(e){let t=this.press;if(!t||!this.options.draggable||this.menuOpen||t.recording==="live")return;let i=Math.hypot(e.clientX-t.x,e.clientY-t.y);if(!t.dragging&&i>Tt&&(t.dragging=!0,t.recording==="held"&&(t.timer&&clearTimeout(t.timer),this.mihe.voice.discard(),t.recording=null)),t.dragging){let{width:r,height:s}=this.viewport();this.drag={left:Math.min(Math.max(0,e.clientX-t.offsetX),r-g),top:Math.min(Math.max(0,e.clientY-t.offsetY),s-g)},this.render()}}finish(e){let t=this.press;if(this.press=null,!!t){if(t.timer&&clearTimeout(t.timer),t.dragging&&this.drag){let{width:i,height:r}=this.viewport();this.rest={side:this.drag.left+g/2<i/2?"left":"right",y:this.clampTop(this.drag.top)/r},At(this.rest),this.drag=null,this.render();return}if(this.drag=null,t.recording){this.mihe.voice.release();return}e||this.tap()}}onKeyDown(e){if(e.repeat)return;let t=this.mihe.getState().voice;if(this.holdToTalk&&e.key===" "){e.preventDefault(),(t.state==="listening"||t.state==="speaking")&&t.press();return}(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.tap()),e.key==="Escape"&&this.voiceLive&&(e.preventDefault(),t.stop())}onKeyUp(e){this.holdToTalk&&e.key===" "&&(e.preventDefault(),this.mihe.voice.release())}};function Lt(n,e){return Array.isArray(n)&&Array.isArray(e)&&n.length===e.length&&n.every((t,i)=>t===e[i])}var Dt=/^\s*[-*•]\s+(.*)$/,Rt=/^\s*(\d{1,3})[.)]\s+(.*)$/,Pt=/^\s{0,3}#{1,6}\s+(.*?)\s*#*\s*$/;function le(n){let e=[],t=[],i=null,r=()=>{t.length&&e.push({kind:"paragraph",lines:t.map(_)}),i&&e.push({kind:"list",ordered:i.ordered,start:i.start,items:i.items.map(_)}),t=[],i=null};for(let s of n.replace(/\r\n?/g,`
|
|
246
|
+
`;function oe(n,e,t,i){return n?n.cloneNode(!0):e&&e!==t?c("img",{class:"launcher-image",attrs:{src:e,alt:"",draggable:"false"},on:{error:()=>i(e)}}):Ue(34,re,se)}function ae(n,e,t=C(n)){let i=n.risk==="high",r=t==="pending",s=r?null:t,l=s&&s.source!=="plain"?c("details",{class:"card-more"},c("summary",{},"More about this"),c("p",{class:"card-description"},n.description)):c("p",{class:"card-description"},n.description);return c("div",{class:"card",attrs:{role:"group","aria-label":`Confirm: ${n.label}`,"aria-busy":r?"true":void 0}},c("div",{class:"card-header"},c("strong",{},n.label),c("span",{class:i?"risk risk-high":"risk"},i?"Needs care":"Confirm")),r&&c("p",{class:"card-description"},"Checking the details\u2026"),s?.summary&&c("p",{class:"card-summary"},s.summary),s&&s.source==="plain"&&l,s&&s.lines.length>0&&c("dl",{class:"card-input"},...s.lines.map(Mt)),s?.note&&c("p",{class:"card-note"},s.note),s&&s.source!=="plain"&&l,c("div",{class:"card-actions"},c("button",{class:"button-secondary",attrs:{type:"button"},on:{click:()=>e(n.proposalId,!1)}},"Cancel"),c("button",{class:i?"button-primary button-danger":"button-primary",attrs:{type:"button",disabled:r?"":void 0},on:{click:()=>{r||e(n.proposalId,!0)}}},s?.confirmLabel??"Confirm")))}function Mt(n){if(n.images?.length)return c("div",{class:"card-media-row"},c("span",{class:"card-images"},...n.images.map(t=>c("img",{attrs:{src:t.src,alt:t.alt??"",loading:"lazy",referrerpolicy:"no-referrer"}}))),c("span",{class:"card-media-text"},n.label&&c("dt",{class:"card-media-label"},n.label),c("dd",{class:n.label?"card-media-value":"card-media-value card-media-strong"},...Be(n))));let e=c("dd",{class:n.label?"card-value":"card-value card-value-wide"},...Be(n));return c("div",{class:"card-row"},n.label&&c("dt",{class:"card-key"},n.label),e)}function Be(n){return[n.before!==void 0&&c("s",{class:"card-before"},n.before),n.before!==void 0&&c("span",{class:"card-arrow",attrs:{"aria-label":"becomes"}}," \u2192 "),n.text!==void 0&&c("span",{class:"input-text"},n.text),!!n.items?.length&&c("ol",{class:"input-list"},...n.items.map(e=>c("li",{},c("span",{class:"input-text"},e))))]}function ke(...n){return y("svg",{viewBox:"0 0 20 20",width:18,height:18,fill:"none",stroke:"currentColor","stroke-width":1.7,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},...n)}var We=()=>ke(y("path",{d:"M4 4.5h12a1.5 1.5 0 0 1 1.5 1.5v7a1.5 1.5 0 0 1-1.5 1.5H9l-4 3v-3H4A1.5 1.5 0 0 1 2.5 13V6A1.5 1.5 0 0 1 4 4.5Z"})),qe=()=>ke(y("rect",{x:7,y:2.5,width:6,height:10,rx:3}),y("path",{d:"M4.5 9.5a5.5 5.5 0 0 0 11 0M10 15v2.5"})),je=()=>ke(y("path",{d:"M3 10v0M6.5 7v6M10 4v12M13.5 7v6M17 10v0"}));var g=56,ze=20,At=8,Et=150,Qe="mihe:orb-position",Ge="mihe:hold-hint-done";function It(){try{let n=window.localStorage.getItem(Qe);if(!n)return null;let e=JSON.parse(n);if((e.side==="left"||e.side==="right")&&typeof e.y=="number")return e}catch{}return null}function Lt(n){try{window.localStorage.setItem(Qe,JSON.stringify(n))}catch{}}function Rt(){try{return window.localStorage.getItem(Ge)==="1"}catch{return!1}}function Dt(){try{window.localStorage.setItem(Ge,"1")}catch{}}var le=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"button");o(this,"ring");o(this,"face");o(this,"stop");o(this,"menu");o(this,"cards");o(this,"bubble");o(this,"options");o(this,"state");o(this,"menuOpen",!1);o(this,"rest",null);o(this,"drag",null);o(this,"showHint",!Rt());o(this,"press",null);o(this,"previousVoiceState","idle");o(this,"faceKey");o(this,"drawnProposals");o(this,"drawnViews");o(this,"failedIcon",null);o(this,"ringFrame",0);o(this,"stopLevel",null);o(this,"reducedMotion",typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches===!0);o(this,"cleanups",[]);this.ring=c("span",{class:"ring idle",attrs:{"aria-hidden":"true"}}),this.face=c("span",{class:"face"}),this.button=c("button",{class:"orb",attrs:{type:"button"},on:{pointerdown:r=>this.onPointerDown(r),pointermove:r=>this.onPointerMove(r),pointerup:()=>this.finish(!1),pointercancel:()=>this.finish(!0),keydown:r=>this.onKeyDown(r),keyup:r=>this.onKeyUp(r),contextmenu:r=>r.preventDefault()}},this.ring,this.face),this.stop=c("button",{class:"stop",attrs:{type:"button","aria-label":"End voice"},on:{click:()=>this.mihe.voice.stop()}},c("span",{class:"stop-square",attrs:{"aria-hidden":"true"}})),this.menu=c("div",{class:"popover",attrs:{role:"menu"},on:{keydown:r=>this.onMenuKeyDown(r)}}),this.cards=c("div",{class:"popover cards"}),this.bubble=c("div",{class:"popover orb-bubble",attrs:{role:"status","aria-live":"polite"}}),this.root=c("div",{},this.menu,this.cards,this.bubble,this.button,this.stop);let t=()=>this.render();window.addEventListener("resize",t),this.cleanups.push(()=>window.removeEventListener("resize",t));let i=r=>{if(!this.menuOpen)return;let s=r.composedPath();!s.includes(this.menu)&&!s.includes(this.button)&&this.setMenu(!1)};document.addEventListener("pointerdown",i),this.cleanups.push(()=>document.removeEventListener("pointerdown",i))}update(e,t){this.options?.draggable!==t.draggable&&(this.rest=t.draggable?It():null),this.previousVoiceState==="recording"&&e.voice.state==="thinking"&&(Dt(),this.showHint=!1),this.previousVoiceState=e.voice.state,this.state=e,this.options=t,this.render()}destroy(){this.stopRing(),this.press?.timer&&clearTimeout(this.press.timer);for(let e of this.cleanups)e()}get voiceLive(){let e=this.state.voice.state;return e!=="idle"&&e!=="error"}get handsFree(){return this.voiceLive&&this.state.voice.handsFree}get holdToTalk(){return this.voiceLive&&!this.state.voice.handsFree}menuItems(){let e=this.state.voice.available?this.options.voiceModes:[];return[{key:"chat",label:"Chat"},...e.includes("hands-free")?[{key:"hands-free",label:"Talk"}]:[],...e.includes("hold")?[{key:"hold",label:"Hold to talk"}]:[]]}viewport(){return{width:window.innerWidth,height:window.innerHeight}}clampTop(e){let{height:t}=this.viewport(),i=t-this.options.offset.bottom-g;return Math.min(Math.max(ze,e),Math.max(ze,i))}side(){let{width:e}=this.viewport();return this.drag?this.drag.left+g/2<e/2?"left":"right":this.rest?.side??(this.options?.corner==="bottom-left"?"left":"right")}position(){let{width:e,height:t}=this.viewport(),i=this.side(),r=this.options.offset.side,s=this.drag?this.drag.left:i==="left"?r:e-r-g,l=this.drag?this.drag.top:this.clampTop(this.rest?this.rest.y*t:t-this.options.offset.bottom-g);return{side:i,left:s,top:l,above:l+g/2>t/2}}render(){if(!this.state)return;let{voice:e,proposals:t,lastError:i,connection:r}=this.state,{heading:s}=this.options,{side:l,left:a,top:d,above:h}=this.position(),p=this.menuItems(),u=this.voiceLive,m=this.handsFree?`Stop talking to ${s}`:this.holdToTalk?e.state==="recording"?"Release to send":"Hold to talk":p.length===1?`Open ${s}`:`${s}: choose chat or voice`,N=p.length>1&&!u;A(this.button,{"aria-label":m,"aria-haspopup":N?"menu":void 0,"aria-expanded":N?String(this.menuOpen):void 0,"aria-pressed":this.holdToTalk?String(e.state==="recording"):void 0,"aria-busy":String(e.state==="connecting")}),this.button.disabled=r!=="open"&&!u,this.button.style.left=`${a}px`,this.button.style.top=`${d}px`,this.button.classList.toggle("dragging",this.drag!==null);let w=u?["connecting","thinking","recording","speaking"].find(f=>f===e.state)??"listening":"idle";this.ring.className=`ring ${w}`,this.syncRing();let Ae=[this.options.launcherIcon,this.state.launcherIconUrl,this.failedIcon];Pt(Ae,this.faceKey)||(this.faceKey=Ae,x(this.face,oe(this.options.launcherIcon,this.state.launcherIconUrl,this.failedIcon,f=>{this.failedIcon=f,this.render()}))),this.stop.hidden=!u,this.stop.style.left=`${a+(l==="right"?-52:g+8)}px`,this.stop.style.top=`${d+(g-44)/2}px`;let{height:Ze}=this.viewport();for(let f of[this.menu,this.cards,this.bubble])f.style.left=l==="left"?`${this.options.offset.side}px`:"",f.style.right=l==="right"?`${this.options.offset.side}px`:"",f.style.bottom=h?`${Ze-d+12}px`:"",f.style.top=h?"":`${d+g+12}px`;this.menu.hidden=!this.menuOpen,this.menu.setAttribute("aria-label",s),this.menu.style.flexDirection=h?"column-reverse":"column",this.menu.style.alignItems=l==="right"?"flex-end":"flex-start",this.menuOpen&&this.menu.childElementCount!==p.length&&x(this.menu,...p.map(f=>c("button",{class:"menu-item",attrs:{type:"button",role:"menuitem"},on:{click:()=>this.choose(f.key)}},c("span",{class:"menu-icon",attrs:{"aria-hidden":"true"}},f.key==="chat"?We():f.key==="hold"?qe():je()),f.label))),this.cards.hidden=this.menuOpen||t.length===0,(t!==this.drawnProposals||this.state.cardViews!==this.drawnViews)&&(this.drawnProposals=t,this.drawnViews=this.state.cardViews,x(this.cards,...t.map(f=>ae(f,this.mihe.respondToProposal,this.state.cardViews[f.proposalId]))));let B=e.state==="connecting"?{text:"Setting up the microphone\u2026",tone:"quiet"}:i&&(u||e.state==="error")?{text:i,tone:"error"}:e.notice?{text:e.notice,tone:"quiet"}:this.holdToTalk&&this.showHint&&e.state==="listening"?{text:"Hold to talk",tone:"quiet"}:null;this.bubble.hidden=this.menuOpen||t.length>0||B===null,this.bubble.classList.toggle("error",B?.tone==="error"),this.bubble.textContent!==(B?.text??"")&&(this.bubble.textContent=B?.text??"")}syncRing(){let e=this.voiceLive&&!this.reducedMotion;if(e===(this.stopLevel!==null))return;if(!e){this.stopRing();return}let t=0,i=0;this.stopLevel=this.mihe.voice.onLevel((s,l)=>{let a=this.mihe.getState().voice;s==="user"&&(a.state==="recording"||a.handsFree)&&(t=l),s==="assistant"&&(t=l)});let r=()=>{i+=(t-i)*(t>i?.45:.12),t*=.92,this.ring.style.transform=`scale(${1+i*.38})`,this.ringFrame=requestAnimationFrame(r)};this.ringFrame=requestAnimationFrame(r)}stopRing(){this.stopLevel?.(),this.stopLevel=null,cancelAnimationFrame(this.ringFrame),this.ring.style.transform="scale(1)"}setMenu(e){this.menuOpen=e,e||x(this.menu),this.render(),e&&this.menu.querySelector("button")?.focus()}choose(e){this.setMenu(!1),e==="chat"?this.mihe.open():this.mihe.voice.start({handsFree:e==="hands-free",openPanel:!1})}onMenuKeyDown(e){let t=Array.from(this.menu.querySelectorAll("button")),i=this.root.getRootNode().activeElement,r=t.indexOf(i);e.key==="Escape"?(e.preventDefault(),this.setMenu(!1),this.button.focus()):e.key==="ArrowDown"||e.key==="ArrowRight"?(e.preventDefault(),t[(r+1)%t.length]?.focus()):(e.key==="ArrowUp"||e.key==="ArrowLeft")&&(e.preventDefault(),t[(r-1+t.length)%t.length]?.focus())}tap(){if(this.menuOpen){this.setMenu(!1);return}if(this.handsFree){this.mihe.voice.stop();return}this.holdToTalk||(this.menuItems().length===1?this.mihe.open():this.setMenu(!0))}onPointerDown(e){if(e.button!==0)return;this.button.setPointerCapture?.(e.pointerId);let{left:t,top:i}=this.position(),r={x:e.clientX,y:e.clientY,offsetX:e.clientX-t,offsetY:e.clientY-i,dragging:!1,recording:null,timer:null};this.press=r;let s=this.mihe.getState().voice;this.holdToTalk&&(s.state==="listening"||s.state==="speaking")&&(this.options.draggable?(s.press({hold:!0}),r.recording="held",r.timer=setTimeout(()=>{this.press===r&&!r.dragging&&(this.mihe.voice.confirm(),r.recording="live")},Et)):(s.press(),r.recording="live"))}onPointerMove(e){let t=this.press;if(!t||!this.options.draggable||this.menuOpen||t.recording==="live")return;let i=Math.hypot(e.clientX-t.x,e.clientY-t.y);if(!t.dragging&&i>At&&(t.dragging=!0,t.recording==="held"&&(t.timer&&clearTimeout(t.timer),this.mihe.voice.discard(),t.recording=null)),t.dragging){let{width:r,height:s}=this.viewport();this.drag={left:Math.min(Math.max(0,e.clientX-t.offsetX),r-g),top:Math.min(Math.max(0,e.clientY-t.offsetY),s-g)},this.render()}}finish(e){let t=this.press;if(this.press=null,!!t){if(t.timer&&clearTimeout(t.timer),t.dragging&&this.drag){let{width:i,height:r}=this.viewport();this.rest={side:this.drag.left+g/2<i/2?"left":"right",y:this.clampTop(this.drag.top)/r},Lt(this.rest),this.drag=null,this.render();return}if(this.drag=null,t.recording){this.mihe.voice.release();return}e||this.tap()}}onKeyDown(e){if(e.repeat)return;let t=this.mihe.getState().voice;if(this.holdToTalk&&e.key===" "){e.preventDefault(),(t.state==="listening"||t.state==="speaking")&&t.press();return}(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.tap()),e.key==="Escape"&&this.voiceLive&&(e.preventDefault(),t.stop())}onKeyUp(e){this.holdToTalk&&e.key===" "&&(e.preventDefault(),this.mihe.voice.release())}};function Pt(n,e){return Array.isArray(n)&&Array.isArray(e)&&n.length===e.length&&n.every((t,i)=>t===e[i])}var Ot=/^\s*[-*•]\s+(.*)$/,_t=/^\s*(\d{1,3})[.)]\s+(.*)$/,Vt=/^\s{0,3}#{1,6}\s+(.*?)\s*#*\s*$/;function ce(n){let e=[],t=[],i=null,r=()=>{t.length&&e.push({kind:"paragraph",lines:t.map(V)}),i&&e.push({kind:"list",ordered:i.ordered,start:i.start,items:i.items.map(V)}),t=[],i=null};for(let s of n.replace(/\r\n?/g,`
|
|
232
247
|
`).split(`
|
|
233
|
-
`)){let a=s.trimEnd();if(a.trim()===""){r();continue}let l=Pt.exec(a);if(l){r(),e.push({kind:"heading",inline:_(l[1]??"")});continue}let d=Dt.exec(a),h=d?null:Rt.exec(a);if(d||h){let p=!!h;(t.length||i&&i.ordered!==p)&&r(),i||(i={ordered:p,start:h?Number(h[1]):1,items:[]}),i.items.push((d?d[1]:h[2])??"");continue}if(i&&/^\s+/.test(s)){i.items[i.items.length-1]+=` ${a.trim()}`;continue}i&&r(),t.push(a)}return r(),e}function ve(n){let e=n.trim();return/^(https?:\/\/|mailto:)/i.test(e)?e:null}var Ot=/`([^`\n]+)`|\[([^\]\n]+)\]\(([^)\s]+)\)|\*\*(?=\S)([^*\n]*?\S)\*\*|__(?=\S)([^_\n]*?\S)__|(?<![\w*])\*(?=[^\s*])([^*\n]*?[^\s*])\*(?![\w*])|(?<![\w_])_(?=[^\s_])([^_\n]*?[^\s_])_(?![\w_])/g;function _(n){let e=[],t=r=>{let s=e[e.length-1];r.kind==="text"&&s?.kind==="text"&&!s.bold==!r.bold&&!s.italic==!r.italic?s.text+=r.text:e.push(r)},i=0;for(let r of n.matchAll(Ot)){let s=r.index??0;s>i&&t({kind:"text",text:n.slice(i,s)});let[a,l,d,h,p,u,m,N]=r;if(l!==void 0)t({kind:"code",text:l});else if(d!==void 0){let w=ve(h??"");t(w?{kind:"link",text:d,href:w}:{kind:"text",text:d})}else if(p!==void 0||u!==void 0)for(let w of _(p??u??""))t(w.kind==="text"?{...w,bold:!0}:w);else t(m!==void 0||N!==void 0?{kind:"text",text:m??N??"",italic:!0}:{kind:"text",text:a});i=s+a.length}return i<n.length&&t({kind:"text",text:n.slice(i)}),e}function ce(n){return n.map(e=>{if(e.kind==="code")return c("code",{},e.text);if(e.kind==="link")return c("a",{attrs:{href:e.href,target:"_blank",rel:"noreferrer"}},e.text);let t=document.createTextNode(e.text);return e.italic&&(t=c("em",{},t)),e.bold&&(t=c("strong",{},t)),t})}function je(n){return c("div",{class:"md"},...le(n).map(e=>{if(e.kind==="heading")return c("p",{},c("strong",{},...ce(e.inline)));if(e.kind==="list"){let t=e.items.map(i=>c("li",{},...ce(i)));return e.ordered?c("ol",{attrs:{start:e.start===1?void 0:e.start}},...t):c("ul",{},...t)}return c("p",{},...e.lines.flatMap((t,i)=>i?[c("br"),...ce(t)]:ce(t)))}))}var xe=["hands-free","hold"],de=class{constructor(e,t){o(this,"mihe",e);o(this,"options",t);o(this,"root");o(this,"heading");o(this,"dot");o(this,"closeButton");o(this,"transcript");o(this,"input");o(this,"sendButton");o(this,"voiceControl");o(this,"drawn",[]);this.heading=document.createTextNode(""),this.dot=c("span",{class:"status-dot",attrs:{"aria-hidden":"true"}}),this.closeButton=c("button",{class:"icon-button",attrs:{type:"button","aria-label":"Close assistant"},on:{click:()=>this.mihe.close()}},"\u2715"),this.transcript=c("div",{class:"transcript"}),this.input=c("input",{class:"input",attrs:{"aria-label":"Message"},on:{input:()=>this.syncSend(this.mihe.getState())}}),this.sendButton=c("button",{class:"send",attrs:{type:"submit"}},"Send"),this.voiceControl=new ye(e);let i=c("form",{class:"composer",on:{submit:r=>{r.preventDefault(),this.mihe.send(this.input.value),this.input.value="",this.syncSend(this.mihe.getState())}}},this.voiceControl.root,this.input,this.sendButton);this.root=c("section",{class:"panel",attrs:{id:K}},c("header",{class:"header"},c("div",{class:"header-title"},this.dot,this.heading),this.closeButton),this.transcript,i)}setOptions(e){this.options=e}update(e){let t=this.options.title??e.assistantName??"Assistant";this.heading.data=t,this.root.setAttribute("aria-label",t),this.dot.classList.toggle("open",e.connection==="open"),this.closeButton.hidden=!this.options.showClose,this.input.placeholder=this.options.placeholder??"Ask me anything about this app\u2026",this.input.disabled=e.connection!=="open",this.syncSend(e);let i=e.widgetSettings?.voiceModes??xe,r=this.options.showVoice&&e.voice.available&&i.length>0;this.voiceControl.root.hidden=!r,r&&this.voiceControl.update(e.voice,e.connection!=="open",i);let s=[e.messages,e.proposals,e.cardViews,e.voice.state==="connecting",e.voice.notice,e.lastError,e.connection];s.every((a,l)=>a===this.drawn[l])||(this.drawn=s,this.drawTranscript(e))}syncSend(e){this.sendButton.disabled=e.busy||!this.input.value.trim()||e.connection!=="open"}drawTranscript(e){x(this.transcript,e.messages.length===0&&c("p",{class:"empty"},"Ask where something is, what a screen does, or for help getting something done."),...e.messages.map(t=>c("div",{class:t.role==="user"?"bubble-user":"bubble-assistant"},t.role==="user"?t.text:je(t.text),t.streaming&&t.text===""&&c("span",{class:"thinking"},"thinking\u2026"),t.sources&&t.sources.length>0&&c("div",{class:"sources"},...t.sources.map(i=>c("span",{class:"source"},i.url&&/^https?:\/\//i.test(i.url)?c("a",{attrs:{href:i.url,target:"_blank",rel:"noreferrer noopener"}},i.title):i.title))))),...e.proposals.map(t=>oe(t,this.mihe.respondToProposal,e.cardViews[t.proposalId])),e.voice.state==="connecting"&&c("div",{class:"voice-notice"},"Setting up the microphone\u2026"),e.voice.notice&&c("div",{class:"voice-notice"},e.voice.notice),e.lastError&&c("div",{class:"error"},e.lastError),e.connection!=="open"&&c("div",{class:"notice"},e.connection==="closed"?"Disconnected.":"Connecting\u2026")),this.transcript.scrollTo?.({top:this.transcript.scrollHeight,behavior:"smooth"})}},ye=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"hold");o(this,"handsFree");o(this,"stopHandsFree");o(this,"pulse");this.hold=Vt(e),this.handsFree=c("button",{class:"hands-free",attrs:{type:"button","aria-label":"Start hands-free voice",title:"Hands-free \u2014 talk without holding anything"},on:{click:()=>this.mihe.voice.start({handsFree:!0})}},"\u221E"),this.pulse=c("span",{class:"pulse"}),this.stopHandsFree=c("button",{class:"mic live",attrs:{type:"button","aria-label":"Stop hands-free voice","aria-pressed":"true"},on:{click:()=>this.mihe.voice.stop()}},this.pulse),this.root=c("span",{attrs:{style:"display: contents"}},this.hold,this.handsFree,this.stopHandsFree)}update(e,t,i){let r=e.state!=="idle"&&e.state!=="error"&&e.state!=="connecting",s=r&&e.handsFree;this.stopHandsFree.hidden=!s,this.hold.hidden=s||!r&&!i.includes("hold"),this.handsFree.hidden=r||!i.includes("hands-free"),this.stopHandsFree.disabled=t,this.handsFree.disabled=t,this.stopHandsFree.title=e.state==="speaking"?"Speaking \u2014 just talk to interrupt":"Listening \u2014 say anything",this.pulse.classList.toggle("fast",e.state==="speaking");let a=e.state==="connecting",l=e.state==="recording";A(this.hold,{"aria-label":a?"Setting up the microphone":r?l?"Release to send":"Hold to speak":"Start voice","aria-busy":a?"true":void 0,"aria-pressed":l?"true":"false",title:e.state==="thinking"?"Thinking\u2026":e.state==="speaking"?"Speaking \u2014 press to interrupt":void 0}),this.hold.disabled=t||a,this.hold.classList.toggle("recording",l),this.hold.classList.toggle("live",r&&!l),this.hold.textContent=e.state==="thinking"?"\u2026":"\u{1F399}"}};function Vt(n){let e=()=>{let s=n.getState().voice.state,a=s==="connecting";return{connecting:a,live:s!=="idle"&&s!=="error"&&!a}},t=(s,a)=>{let{connecting:l,live:d}=e();if(!l){if(!d){n.voice.start();return}a!==void 0&&s.setPointerCapture?.(a),n.voice.press()}},i=()=>{e().live&&n.voice.release()},r=c("button",{class:"mic",attrs:{type:"button"},on:{pointerdown:s=>t(r,s.pointerId),pointerup:i,pointercancel:i,keydown:s=>{s.repeat||(s.key===" "||s.key==="Enter")&&(s.preventDefault(),t(r))},keyup:s=>{(s.key===" "||s.key==="Enter")&&(s.preventDefault(),i())}}},"\u{1F399}");return r}var B="mihe-assistant";function _t(n,e){let t=e?.voiceModes??xe;return{form:n.form??e?.form??"orb",draggable:n.draggable??e?.draggable??!1,corner:n.corner??e?.corner??"bottom-right",voiceModes:n.voiceModes?n.voiceModes.filter(i=>t.includes(i)):t}}function Nt(n){let e=r=>n.getAttribute(r)??void 0,t=r=>n.hasAttribute(r)?e(r)!=="false":void 0,i=e("voice-modes");return{layout:e("layout"),title:e("heading"),placeholder:e("placeholder"),showLauncher:t("show-launcher"),defaultOpen:t("default-open"),showClose:t("show-close"),form:e("form"),draggable:t("draggable"),corner:e("corner"),offset:e("offset-bottom")===void 0&&e("offset-side")===void 0?void 0:{bottom:e("offset-bottom")===void 0?void 0:Number(e("offset-bottom")),side:e("offset-side")===void 0?void 0:Number(e("offset-side"))},voiceModes:i===void 0?void 0:i.split(/[\s,]+/).filter(Boolean)}}function Qe(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}function we(){if(typeof customElements>"u"||customElements.get(B))return;class n extends HTMLElement{constructor(){super(...arguments);o(this,"assistant",null);o(this,"ownOptions",{});o(this,"unsubscribe",null);o(this,"shadow",null);o(this,"panel",null);o(this,"orb",null);o(this,"launcher",null);o(this,"launcherKey",[]);o(this,"failedIcon",null);o(this,"openedByDefault",!1)}get mihe(){return this.assistant}set mihe(i){i!==this.assistant&&(this.disconnectAssistant(),this.assistant=i,this.isConnected&&this.connectAssistant())}get options(){return this.ownOptions}set options(i){this.ownOptions={...i},this.render()}connectedCallback(){this.shadow||(this.shadow=this.attachShadow({mode:"open"}),this.shadow.appendChild(c("style",{},He))),this.connectAssistant()}disconnectedCallback(){this.disconnectAssistant()}attributeChangedCallback(){this.render()}connectAssistant(){if(!this.assistant||this.unsubscribe||!this.shadow)return;let i=this.assistant;this.panel=new de(i,{showClose:!0,showVoice:!0}),this.shadow.appendChild(this.panel.root),this.unsubscribe=i.subscribe(()=>this.render()),this.resolved().defaultOpen&&!this.openedByDefault&&(this.openedByDefault=!0,i.open()),this.render()}disconnectAssistant(){this.unsubscribe?.(),this.unsubscribe=null,this.orb?.destroy();for(let i of[this.panel?.root,this.orb?.root,this.launcher])i?.remove();this.panel=null,this.orb=null,this.launcher=null,this.launcherKey=[]}resolved(){return{...Qe(Nt(this)),...Qe(this.ownOptions)}}render(){let i=this.assistant;if(!i||!this.shadow||!this.panel)return;let r=i.getState(),s=this.resolved(),a=_t(s,r.widgetSettings),l=s.title??r.assistantName??"Assistant",d={bottom:s.offset?.bottom??20,side:s.offset?.side??20},h=s.showLauncher??!0,p=this.panel;if(s.layout==="inline"){this.getAttribute("layout")!=="inline"&&this.setAttribute("layout","inline"),p.setOptions({title:s.title,placeholder:s.placeholder,showClose:s.showClose??!1,showVoice:!0}),p.root.classList.remove("floating","left","right"),p.root.removeAttribute("style"),p.root.hidden=!1,p.update(r),this.hideOrb(),this.launcher&&(this.launcher.hidden=!0);return}if(a.form==="orb"){this.launcher&&(this.launcher.hidden=!0),this.orb||(this.orb=new ae(i),this.shadow.appendChild(this.orb.root)),this.orb.update(r,{heading:l,draggable:a.draggable,corner:a.corner,voiceModes:a.voiceModes,launcherIcon:s.launcherIcon,offset:d}),this.orb.root.hidden=r.isOpen||!h,this.showPanel(r.isOpen,this.orb.side(),d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!1});return}this.hideOrb(),this.showPanel(r.isOpen,"right",d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!0});let u=this.drawLauncher(l,s.launcherIcon,r.launcherIconUrl);u.hidden=r.isOpen||!h,u.style.bottom=`${d.bottom}px`,u.style.right=`${d.side}px`}showPanel(i,r,s,a){let l=this.panel;l.root.hidden=!i,l.root.classList.add("floating"),l.root.style.bottom=`${s.bottom}px`,l.root.style.left=r==="left"?`${s.side}px`:"",l.root.style.right=r==="right"?`${s.side}px`:"",l.root.style.height=`min(560px, calc(100vh - ${s.bottom+20}px))`,l.setOptions(a),l.update(this.assistant.getState())}hideOrb(){this.orb&&(this.orb.root.hidden=!0)}drawLauncher(i,r,s){this.launcher||(this.launcher=c("button",{class:"launcher",attrs:{type:"button","aria-controls":"mihe-panel","aria-expanded":"false"},on:{click:()=>this.assistant?.open()}}),this.shadow.appendChild(this.launcher)),A(this.launcher,{"aria-label":`Open ${i}`});let a=[r,s,this.failedIcon];return a.some((l,d)=>l!==this.launcherKey[d])&&(this.launcherKey=a,x(this.launcher,se(r,s,this.failedIcon,l=>{this.failedIcon=l,this.render()}))),this.launcher}}o(n,"observedAttributes",["layout","heading","placeholder","show-launcher","default-open","show-close","form","draggable","corner","voice-modes","offset-bottom","offset-side"]),customElements.define(B,n)}function Ge(n,e={}){we();let{container:t,...i}=e,r=document.createElement(B);return r.options=i,r.mihe=n,(t??document.body).appendChild(r),{element:r,unmount:()=>r.remove()}}return nt($t);})();
|
|
248
|
+
`)){let l=s.trimEnd();if(l.trim()===""){r();continue}let a=Vt.exec(l);if(a){r(),e.push({kind:"heading",inline:V(a[1]??"")});continue}let d=Ot.exec(l),h=d?null:_t.exec(l);if(d||h){let p=!!h;(t.length||i&&i.ordered!==p)&&r(),i||(i={ordered:p,start:h?Number(h[1]):1,items:[]}),i.items.push((d?d[1]:h[2])??"");continue}if(i&&/^\s+/.test(s)){i.items[i.items.length-1]+=` ${l.trim()}`;continue}i&&r(),t.push(l)}return r(),e}function Se(n){let e=n.trim();return/^(https?:\/\/|mailto:)/i.test(e)?e:null}var Nt=/`([^`\n]+)`|\[([^\]\n]+)\]\(([^)\s]+)\)|\*\*(?=\S)([^*\n]*?\S)\*\*|__(?=\S)([^_\n]*?\S)__|(?<![\w*])\*(?=[^\s*])([^*\n]*?[^\s*])\*(?![\w*])|(?<![\w_])_(?=[^\s_])([^_\n]*?[^\s_])_(?![\w_])/g;function V(n){let e=[],t=r=>{let s=e[e.length-1];r.kind==="text"&&s?.kind==="text"&&!s.bold==!r.bold&&!s.italic==!r.italic?s.text+=r.text:e.push(r)},i=0;for(let r of n.matchAll(Nt)){let s=r.index??0;s>i&&t({kind:"text",text:n.slice(i,s)});let[l,a,d,h,p,u,m,N]=r;if(a!==void 0)t({kind:"code",text:a});else if(d!==void 0){let w=Se(h??"");t(w?{kind:"link",text:d,href:w}:{kind:"text",text:d})}else if(p!==void 0||u!==void 0)for(let w of V(p??u??""))t(w.kind==="text"?{...w,bold:!0}:w);else t(m!==void 0||N!==void 0?{kind:"text",text:m??N??"",italic:!0}:{kind:"text",text:l});i=s+l.length}return i<n.length&&t({kind:"text",text:n.slice(i)}),e}function de(n){return n.map(e=>{if(e.kind==="code")return c("code",{},e.text);if(e.kind==="link")return c("a",{attrs:{href:e.href,target:"_blank",rel:"noreferrer"}},e.text);let t=document.createTextNode(e.text);return e.italic&&(t=c("em",{},t)),e.bold&&(t=c("strong",{},t)),t})}function Ye(n){return c("div",{class:"md"},...ce(n).map(e=>{if(e.kind==="heading")return c("p",{},c("strong",{},...de(e.inline)));if(e.kind==="list"){let t=e.items.map(i=>c("li",{},...de(i)));return e.ordered?c("ol",{attrs:{start:e.start===1?void 0:e.start}},...t):c("ul",{},...t)}return c("p",{},...e.lines.flatMap((t,i)=>i?[c("br"),...de(t)]:de(t)))}))}var Ce=["hands-free","hold"],he=class{constructor(e,t){o(this,"mihe",e);o(this,"options",t);o(this,"root");o(this,"heading");o(this,"dot");o(this,"closeButton");o(this,"transcript");o(this,"input");o(this,"sendButton");o(this,"clip");o(this,"fileInput");o(this,"chips");o(this,"drawnAttachments",null);o(this,"voiceControl");o(this,"drawn",[]);this.heading=document.createTextNode(""),this.dot=c("span",{class:"status-dot",attrs:{"aria-hidden":"true"}}),this.closeButton=c("button",{class:"icon-button",attrs:{type:"button","aria-label":"Close assistant"},on:{click:()=>this.mihe.close()}},"\u2715"),this.transcript=c("div",{class:"transcript"}),this.input=c("input",{class:"input",attrs:{"aria-label":"Message"},on:{input:()=>this.syncSend(this.mihe.getState()),paste:r=>{if(!this.mihe.getState().attachAccept)return;let s=Array.from(r.clipboardData?.files??[]);if(s.length){r.preventDefault();for(let l of s)this.mihe.attach(l)}}}}),this.fileInput=c("input",{attrs:{type:"file",multiple:!0,hidden:!0},on:{change:()=>{for(let r of Array.from(this.fileInput.files??[]))this.mihe.attach(r);this.fileInput.value=""}}}),this.clip=c("button",{class:"clip",attrs:{type:"button","aria-label":"Attach a picture",title:"Attach a picture"},on:{click:()=>this.fileInput.click()}},"\u{1F4CE}"),this.chips=c("ul",{class:"chips",attrs:{"aria-label":"Attached pictures"}}),this.sendButton=c("button",{class:"send",attrs:{type:"submit"}},"Send"),this.voiceControl=new Te(e);let i=c("form",{class:"composer",on:{submit:r=>{r.preventDefault(),this.mihe.send(this.input.value),this.input.value="",this.syncSend(this.mihe.getState())}}},this.voiceControl.root,this.clip,this.input,this.sendButton,this.fileInput);this.root=c("section",{class:"panel",attrs:{id:U}},c("header",{class:"header"},c("div",{class:"header-title"},this.dot,this.heading),this.closeButton),this.transcript,this.chips,i)}setOptions(e){this.options=e}update(e){let t=this.options.title??e.assistantName??"Assistant";this.heading.data=t,this.root.setAttribute("aria-label",t),this.dot.classList.toggle("open",e.connection==="open"),this.closeButton.hidden=!this.options.showClose,this.input.placeholder=this.options.placeholder??"Ask me anything about this app\u2026",this.input.disabled=e.connection!=="open",this.clip.hidden=!e.attachAccept,this.clip.disabled=e.connection!=="open",e.attachAccept&&(this.fileInput.accept=e.attachAccept),e.attachments!==this.drawnAttachments&&(this.drawnAttachments=e.attachments,this.drawChips(e)),this.syncSend(e);let i=e.widgetSettings?.voiceModes??Ce,r=this.options.showVoice&&e.voice.available&&i.length>0;this.voiceControl.root.hidden=!r,r&&this.voiceControl.update(e.voice,e.connection!=="open",i);let s=[e.messages,e.proposals,e.cardViews,e.voice.state==="connecting",e.voice.notice,e.lastError,e.connection];s.every((l,a)=>l===this.drawn[a])||(this.drawn=s,this.drawTranscript(e))}syncSend(e){let t=e.attachments.some(r=>r.status==="reading"),i=e.attachments.some(r=>r.status==="ready");this.sendButton.disabled=e.busy||e.connection!=="open"||t||!this.input.value.trim()&&!i}drawChips(e){this.chips.hidden=e.attachments.length===0,x(this.chips,...e.attachments.map(t=>c("li",{class:t.status==="failed"?"chip failed":"chip"},t.previewUrl&&c("img",{attrs:{src:t.previewUrl,alt:""}}),c("span",{class:"chip-text"},c("span",{class:"chip-name"},t.name),c("span",{class:"chip-status",attrs:t.status==="failed"?{role:"alert"}:{}},t.status==="reading"?"Reading\u2026":t.status==="ready"?"Ready":t.error??"Couldn't read it")),c("button",{class:"chip-remove",attrs:{type:"button","aria-label":`Remove ${t.name}`},on:{click:()=>this.mihe.removeAttachment(t.id)}},"\u2715"))))}drawTranscript(e){x(this.transcript,e.messages.length===0&&c("p",{class:"empty"},"Ask where something is, what a screen does, or for help getting something done."),...e.messages.map(t=>c("div",{class:t.role==="user"?"bubble-user":"bubble-assistant"},t.attachments&&t.attachments.length>0&&c("div",{class:"sent-pictures"},...t.attachments.map(i=>i.previewUrl?c("img",{attrs:{src:i.previewUrl,alt:i.name,title:i.name}}):c("span",{class:"sent-name"},`\u{1F4CE} ${i.name}`))),t.role==="user"?t.text:Ye(t.text),t.streaming&&t.text===""&&c("span",{class:"thinking"},"thinking\u2026"),t.sources&&t.sources.length>0&&c("div",{class:"sources"},...t.sources.map(i=>c("span",{class:"source"},i.url&&/^https?:\/\//i.test(i.url)?c("a",{attrs:{href:i.url,target:"_blank",rel:"noreferrer noopener"}},i.title):i.title))))),...e.proposals.map(t=>ae(t,this.mihe.respondToProposal,e.cardViews[t.proposalId])),e.voice.state==="connecting"&&c("div",{class:"voice-notice"},"Setting up the microphone\u2026"),e.voice.notice&&c("div",{class:"voice-notice"},e.voice.notice),e.lastError&&c("div",{class:"error"},e.lastError),e.connection!=="open"&&c("div",{class:"notice"},e.connection==="closed"?"Disconnected.":"Connecting\u2026")),this.transcript.scrollTo?.({top:this.transcript.scrollHeight,behavior:"smooth"})}},Te=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"hold");o(this,"handsFree");o(this,"stopHandsFree");o(this,"pulse");this.hold=$t(e),this.handsFree=c("button",{class:"hands-free",attrs:{type:"button","aria-label":"Start hands-free voice",title:"Hands-free \u2014 talk without holding anything"},on:{click:()=>this.mihe.voice.start({handsFree:!0})}},"\u221E"),this.pulse=c("span",{class:"pulse"}),this.stopHandsFree=c("button",{class:"mic live",attrs:{type:"button","aria-label":"Stop hands-free voice","aria-pressed":"true"},on:{click:()=>this.mihe.voice.stop()}},this.pulse),this.root=c("span",{attrs:{style:"display: contents"}},this.hold,this.handsFree,this.stopHandsFree)}update(e,t,i){let r=e.state!=="idle"&&e.state!=="error"&&e.state!=="connecting",s=r&&e.handsFree;this.stopHandsFree.hidden=!s,this.hold.hidden=s||!r&&!i.includes("hold"),this.handsFree.hidden=r||!i.includes("hands-free"),this.stopHandsFree.disabled=t,this.handsFree.disabled=t,this.stopHandsFree.title=e.state==="speaking"?"Speaking \u2014 just talk to interrupt":"Listening \u2014 say anything",this.pulse.classList.toggle("fast",e.state==="speaking");let l=e.state==="connecting",a=e.state==="recording";A(this.hold,{"aria-label":l?"Setting up the microphone":r?a?"Release to send":"Hold to speak":"Start voice","aria-busy":l?"true":void 0,"aria-pressed":a?"true":"false",title:e.state==="thinking"?"Thinking\u2026":e.state==="speaking"?"Speaking \u2014 press to interrupt":void 0}),this.hold.disabled=t||l,this.hold.classList.toggle("recording",a),this.hold.classList.toggle("live",r&&!a),this.hold.textContent=e.state==="thinking"?"\u2026":"\u{1F399}"}};function $t(n){let e=()=>{let s=n.getState().voice.state,l=s==="connecting";return{connecting:l,live:s!=="idle"&&s!=="error"&&!l}},t=(s,l)=>{let{connecting:a,live:d}=e();if(!a){if(!d){n.voice.start();return}l!==void 0&&s.setPointerCapture?.(l),n.voice.press()}},i=()=>{e().live&&n.voice.release()},r=c("button",{class:"mic",attrs:{type:"button"},on:{pointerdown:s=>t(r,s.pointerId),pointerup:i,pointercancel:i,keydown:s=>{s.repeat||(s.key===" "||s.key==="Enter")&&(s.preventDefault(),t(r))},keyup:s=>{(s.key===" "||s.key==="Enter")&&(s.preventDefault(),i())}}},"\u{1F399}");return r}var K="mihe-assistant";function Ht(n,e){let t=e?.voiceModes??Ce;return{form:n.form??e?.form??"orb",draggable:n.draggable??e?.draggable??!1,corner:n.corner??e?.corner??"bottom-right",voiceModes:n.voiceModes?n.voiceModes.filter(i=>t.includes(i)):t}}function Ft(n){let e=r=>n.getAttribute(r)??void 0,t=r=>n.hasAttribute(r)?e(r)!=="false":void 0,i=e("voice-modes");return{layout:e("layout"),title:e("heading"),placeholder:e("placeholder"),showLauncher:t("show-launcher"),defaultOpen:t("default-open"),showClose:t("show-close"),form:e("form"),draggable:t("draggable"),corner:e("corner"),offset:e("offset-bottom")===void 0&&e("offset-side")===void 0?void 0:{bottom:e("offset-bottom")===void 0?void 0:Number(e("offset-bottom")),side:e("offset-side")===void 0?void 0:Number(e("offset-side"))},voiceModes:i===void 0?void 0:i.split(/[\s,]+/).filter(Boolean)}}function Je(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}function Me(){if(typeof customElements>"u"||customElements.get(K))return;class n extends HTMLElement{constructor(){super(...arguments);o(this,"assistant",null);o(this,"ownOptions",{});o(this,"unsubscribe",null);o(this,"shadow",null);o(this,"panel",null);o(this,"orb",null);o(this,"launcher",null);o(this,"launcherKey",[]);o(this,"failedIcon",null);o(this,"openedByDefault",!1)}get mihe(){return this.assistant}set mihe(i){i!==this.assistant&&(this.disconnectAssistant(),this.assistant=i,this.isConnected&&this.connectAssistant())}get options(){return this.ownOptions}set options(i){this.ownOptions={...i},this.render()}connectedCallback(){this.shadow||(this.shadow=this.attachShadow({mode:"open"}),this.shadow.appendChild(c("style",{},Ke))),this.connectAssistant()}disconnectedCallback(){this.disconnectAssistant()}attributeChangedCallback(){this.render()}connectAssistant(){if(!this.assistant||this.unsubscribe||!this.shadow)return;let i=this.assistant;this.panel=new he(i,{showClose:!0,showVoice:!0}),this.shadow.appendChild(this.panel.root),this.unsubscribe=i.subscribe(()=>this.render()),this.resolved().defaultOpen&&!this.openedByDefault&&(this.openedByDefault=!0,i.open()),this.render()}disconnectAssistant(){this.unsubscribe?.(),this.unsubscribe=null,this.orb?.destroy();for(let i of[this.panel?.root,this.orb?.root,this.launcher])i?.remove();this.panel=null,this.orb=null,this.launcher=null,this.launcherKey=[]}resolved(){return{...Je(Ft(this)),...Je(this.ownOptions)}}render(){let i=this.assistant;if(!i||!this.shadow||!this.panel)return;let r=i.getState(),s=this.resolved(),l=Ht(s,r.widgetSettings),a=s.title??r.assistantName??"Assistant",d={bottom:s.offset?.bottom??20,side:s.offset?.side??20},h=s.showLauncher??!0,p=this.panel;if(s.layout==="inline"){this.getAttribute("layout")!=="inline"&&this.setAttribute("layout","inline"),p.setOptions({title:s.title,placeholder:s.placeholder,showClose:s.showClose??!1,showVoice:!0}),p.root.classList.remove("floating","left","right"),p.root.removeAttribute("style"),p.root.hidden=!1,p.update(r),this.hideOrb(),this.launcher&&(this.launcher.hidden=!0);return}if(l.form==="orb"){this.launcher&&(this.launcher.hidden=!0),this.orb||(this.orb=new le(i),this.shadow.appendChild(this.orb.root)),this.orb.update(r,{heading:a,draggable:l.draggable,corner:l.corner,voiceModes:l.voiceModes,launcherIcon:s.launcherIcon,offset:d}),this.orb.root.hidden=r.isOpen||!h,this.showPanel(r.isOpen,this.orb.side(),d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!1});return}this.hideOrb(),this.showPanel(r.isOpen,"right",d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!0});let u=this.drawLauncher(a,s.launcherIcon,r.launcherIconUrl);u.hidden=r.isOpen||!h,u.style.bottom=`${d.bottom}px`,u.style.right=`${d.side}px`}showPanel(i,r,s,l){let a=this.panel;a.root.hidden=!i,a.root.classList.add("floating"),a.root.style.bottom=`${s.bottom}px`,a.root.style.left=r==="left"?`${s.side}px`:"",a.root.style.right=r==="right"?`${s.side}px`:"",a.root.style.height=`min(560px, calc(100vh - ${s.bottom+20}px))`,a.setOptions(l),a.update(this.assistant.getState())}hideOrb(){this.orb&&(this.orb.root.hidden=!0)}drawLauncher(i,r,s){this.launcher||(this.launcher=c("button",{class:"launcher",attrs:{type:"button","aria-controls":"mihe-panel","aria-expanded":"false"},on:{click:()=>this.assistant?.open()}}),this.shadow.appendChild(this.launcher)),A(this.launcher,{"aria-label":`Open ${i}`});let l=[r,s,this.failedIcon];return l.some((a,d)=>a!==this.launcherKey[d])&&(this.launcherKey=l,x(this.launcher,oe(r,s,this.failedIcon,a=>{this.failedIcon=a,this.render()}))),this.launcher}}o(n,"observedAttributes",["layout","heading","placeholder","show-launcher","default-open","show-close","form","draggable","corner","voice-modes","offset-bottom","offset-side"]),customElements.define(K,n)}function Xe(n,e={}){Me();let{container:t,...i}=e,r=document.createElement(K);return r.options=i,r.mihe=n,(t??document.body).appendChild(r),{element:r,unmount:()=>r.remove()}}return ot(Ut);})();
|
|
234
249
|
//# sourceMappingURL=mihe.iife.min.js.map
|